mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-23 20:17:03 +01:00
Merge branch 'dev' of github.com:gogits/gogs into dev
This commit is contained in:
commit
57ad8d50b7
10 changed files with 95 additions and 39 deletions
|
@ -161,6 +161,13 @@ func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// .___ ____ ___
|
||||||
|
// | | ______ ________ __ ____ | | \______ ___________
|
||||||
|
// | |/ ___// ___/ | \_/ __ \| | / ___// __ \_ __ \
|
||||||
|
// | |\___ \ \___ \| | /\ ___/| | /\___ \\ ___/| | \/
|
||||||
|
// |___/____ >____ >____/ \___ >______//____ >\___ >__|
|
||||||
|
// \/ \/ \/ \/ \/
|
||||||
|
|
||||||
// IssueUser represents an issue-user relation.
|
// IssueUser represents an issue-user relation.
|
||||||
type IssueUser struct {
|
type IssueUser struct {
|
||||||
Id int64
|
Id int64
|
||||||
|
@ -404,6 +411,13 @@ type Label struct {
|
||||||
NumOpenIssues int `xorm:"-"`
|
NumOpenIssues int `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _____ .__.__ __
|
||||||
|
// / \ |__| | ____ _______/ |_ ____ ____ ____
|
||||||
|
// / \ / \| | | _/ __ \ / ___/\ __\/ _ \ / \_/ __ \
|
||||||
|
// / Y \ | |_\ ___/ \___ \ | | ( <_> ) | \ ___/
|
||||||
|
// \____|__ /__|____/\___ >____ > |__| \____/|___| /\___ >
|
||||||
|
// \/ \/ \/ \/ \/
|
||||||
|
|
||||||
// Milestone represents a milestone of repository.
|
// Milestone represents a milestone of repository.
|
||||||
type Milestone struct {
|
type Milestone struct {
|
||||||
Id int64
|
Id int64
|
||||||
|
@ -517,7 +531,7 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeMilestoneAssign changes assignment of milestone for issue.
|
// ChangeMilestoneAssign changes assignment of milestone for issue.
|
||||||
func ChangeMilestoneAssign(oldMid, mid int64, isIssueClosed bool) (err error) {
|
func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) {
|
||||||
sess := orm.NewSession()
|
sess := orm.NewSession()
|
||||||
defer sess.Close()
|
defer sess.Close()
|
||||||
if err = sess.Begin(); err != nil {
|
if err = sess.Begin(); err != nil {
|
||||||
|
@ -531,7 +545,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, isIssueClosed bool) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
m.NumIssues--
|
m.NumIssues--
|
||||||
if isIssueClosed {
|
if issue.IsClosed {
|
||||||
m.NumClosedIssues--
|
m.NumClosedIssues--
|
||||||
}
|
}
|
||||||
if m.NumIssues > 0 {
|
if m.NumIssues > 0 {
|
||||||
|
@ -543,6 +557,12 @@ func ChangeMilestoneAssign(oldMid, mid int64, isIssueClosed bool) (err error) {
|
||||||
sess.Rollback()
|
sess.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawSql := "UPDATE `issue_user` SET milestone_id = 0 WHERE issue_id = ?"
|
||||||
|
if _, err = sess.Exec(rawSql, issue.Id); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if mid > 0 {
|
if mid > 0 {
|
||||||
|
@ -551,7 +571,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, isIssueClosed bool) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.NumIssues++
|
m.NumIssues++
|
||||||
if isIssueClosed {
|
if issue.IsClosed {
|
||||||
m.NumClosedIssues++
|
m.NumClosedIssues++
|
||||||
}
|
}
|
||||||
m.Completeness = m.NumClosedIssues * 100 / m.NumIssues
|
m.Completeness = m.NumClosedIssues * 100 / m.NumIssues
|
||||||
|
@ -559,6 +579,12 @@ func ChangeMilestoneAssign(oldMid, mid int64, isIssueClosed bool) (err error) {
|
||||||
sess.Rollback()
|
sess.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawSql := "UPDATE `issue_user` SET milestone_id = ? WHERE issue_id = ?"
|
||||||
|
if _, err = sess.Exec(rawSql, m.Id, issue.Id); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
}
|
}
|
||||||
|
@ -587,9 +613,22 @@ func DeleteMilestone(m *Milestone) (err error) {
|
||||||
sess.Rollback()
|
sess.Rollback()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rawSql = "UPDATE `issue_user` SET milestone_id = 0 WHERE milestone_id = ?"
|
||||||
|
if _, err = sess.Exec(rawSql, m.Id); err != nil {
|
||||||
|
sess.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
return sess.Commit()
|
return sess.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _________ __
|
||||||
|
// \_ ___ \ ____ _____ _____ ____ _____/ |_
|
||||||
|
// / \ \/ / _ \ / \ / \_/ __ \ / \ __\
|
||||||
|
// \ \___( <_> ) Y Y \ Y Y \ ___/| | \ |
|
||||||
|
// \______ /\____/|__|_| /__|_| /\___ >___| /__|
|
||||||
|
// \/ \/ \/ \/ \/
|
||||||
|
|
||||||
// Issue types.
|
// Issue types.
|
||||||
const (
|
const (
|
||||||
IT_PLAIN = iota // Pure comment.
|
IT_PLAIN = iota // Pure comment.
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -133,7 +134,7 @@ func AddSource(source *LoginSource) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateSource(source *LoginSource) error {
|
func UpdateSource(source *LoginSource) error {
|
||||||
_, err := orm.AllCols().Id(source.Id).Update(source)
|
_, err := orm.Id(source.Id).AllCols().Update(source)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ func LoginUser(uname, passwd string) (*User, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return u, nil
|
return u, nil
|
||||||
} else {
|
} else {
|
||||||
log.Warn("try ldap login", source.Name, "by", uname, "error:", err)
|
log.Warn("Fail to login(%s) by LDAP(%s): %v", uname, source.Name, err)
|
||||||
}
|
}
|
||||||
} else if source.Type == LT_SMTP {
|
} else if source.Type == LT_SMTP {
|
||||||
u, err := LoginUserSMTPSource(nil, uname, passwd,
|
u, err := LoginUserSMTPSource(nil, uname, passwd,
|
||||||
|
@ -205,7 +206,7 @@ func LoginUser(uname, passwd string) (*User, error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return u, nil
|
return u, nil
|
||||||
} else {
|
} else {
|
||||||
log.Warn("try smtp login", source.Name, "by", uname, "error:", err)
|
log.Warn("Fail to login(%s) by SMTP(%s): %v", uname, source.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,12 +218,9 @@ func LoginUser(uname, passwd string) (*User, error) {
|
||||||
hasSource, err := orm.Id(u.LoginSource).Get(&source)
|
hasSource, err := orm.Id(u.LoginSource).Get(&source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
} else if !hasSource {
|
||||||
if !hasSource {
|
|
||||||
return nil, ErrLoginSourceNotExist
|
return nil, ErrLoginSourceNotExist
|
||||||
}
|
} else if !source.IsActived {
|
||||||
|
|
||||||
if !source.IsActived {
|
|
||||||
return nil, ErrLoginSourceNotActived
|
return nil, ErrLoginSourceNotActived
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,20 +294,25 @@ var (
|
||||||
SMTPAuths = []string{SMTP_PLAIN, SMTP_LOGIN}
|
SMTPAuths = []string{SMTP_PLAIN, SMTP_LOGIN}
|
||||||
)
|
)
|
||||||
|
|
||||||
func SmtpAuth(addr string, a smtp.Auth, tls bool) error {
|
func SmtpAuth(host string, port int, a smtp.Auth, useTls bool) error {
|
||||||
c, err := smtp.Dial(addr)
|
c, err := smtp.Dial(fmt.Sprintf("%s:%d", host, port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
if tls {
|
if err = c.Hello("gogs"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if useTls {
|
||||||
if ok, _ := c.Extension("STARTTLS"); ok {
|
if ok, _ := c.Extension("STARTTLS"); ok {
|
||||||
if err = c.StartTLS(nil); err != nil {
|
config := &tls.Config{ServerName: host}
|
||||||
|
if err = c.StartTLS(config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return errors.New("smtp server unsupported tls")
|
return errors.New("SMTP server unsupported TLS")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,11 +336,13 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S
|
||||||
} else if cfg.Auth == SMTP_LOGIN {
|
} else if cfg.Auth == SMTP_LOGIN {
|
||||||
auth = LoginAuth(name, passwd)
|
auth = LoginAuth(name, passwd)
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.New("Unsupported smtp auth type")
|
return nil, errors.New("Unsupported SMTP auth type")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := SmtpAuth(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port), auth, cfg.TLS)
|
if err := SmtpAuth(cfg.Host, cfg.Port, auth, cfg.TLS); err != nil {
|
||||||
if err != nil {
|
if strings.Contains(err.Error(), "Username and Password not accepted") {
|
||||||
|
return nil, ErrUserNotExist
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ var (
|
||||||
ErrUserNameIllegal = errors.New("User name contains illegal characters")
|
ErrUserNameIllegal = errors.New("User name contains illegal characters")
|
||||||
ErrLoginSourceNotExist = errors.New("Login source does not exist")
|
ErrLoginSourceNotExist = errors.New("Login source does not exist")
|
||||||
ErrLoginSourceNotActived = errors.New("Login source is not actived")
|
ErrLoginSourceNotActived = errors.New("Login source is not actived")
|
||||||
ErrUnsupportedLoginType = errors.New("Login source is unknow")
|
ErrUnsupportedLoginType = errors.New("Login source is unknown")
|
||||||
)
|
)
|
||||||
|
|
||||||
// User represents the object of individual and member of organization.
|
// User represents the object of individual and member of organization.
|
||||||
|
|
|
@ -72,16 +72,14 @@ func Send(msg *Message) (int, error) {
|
||||||
// get message body
|
// get message body
|
||||||
content := msg.Content()
|
content := msg.Content()
|
||||||
|
|
||||||
auth := smtp.PlainAuth("", base.MailService.User, base.MailService.Passwd, host[0])
|
|
||||||
|
|
||||||
if len(msg.To) == 0 {
|
if len(msg.To) == 0 {
|
||||||
return 0, fmt.Errorf("empty receive emails")
|
return 0, fmt.Errorf("empty receive emails")
|
||||||
}
|
} else if len(msg.Body) == 0 {
|
||||||
|
|
||||||
if len(msg.Body) == 0 {
|
|
||||||
return 0, fmt.Errorf("empty email body")
|
return 0, fmt.Errorf("empty email body")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth := smtp.PlainAuth("", base.MailService.User, base.MailService.Passwd, host[0])
|
||||||
|
|
||||||
if msg.Massive {
|
if msg.Massive {
|
||||||
// send mail to multiple emails one by one
|
// send mail to multiple emails one by one
|
||||||
num := 0
|
num := 0
|
||||||
|
|
|
@ -158,7 +158,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI,
|
log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI,
|
||||||
ctx.User.LowerName, strings.ToLower(form.AuthName))
|
ctx.User.LowerName, form.AuthName)
|
||||||
|
|
||||||
ctx.Redirect("/admin/auths")
|
ctx.Redirect("/admin/auths")
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,7 +426,7 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
|
||||||
|
|
||||||
// Not check for invalid milestone id and give responsibility to owners.
|
// Not check for invalid milestone id and give responsibility to owners.
|
||||||
issue.MilestoneId = mid
|
issue.MilestoneId = mid
|
||||||
if err = models.ChangeMilestoneAssign(oldMid, mid, issue.IsClosed); err != nil {
|
if err = models.ChangeMilestoneAssign(oldMid, mid, issue); err != nil {
|
||||||
ctx.Handle(500, "issue.UpdateIssueMilestone(ChangeMilestoneAssign)", err)
|
ctx.Handle(500, "issue.UpdateIssueMilestone(ChangeMilestoneAssign)", err)
|
||||||
return
|
return
|
||||||
} else if err = models.UpdateIssue(issue); err != nil {
|
} else if err = models.UpdateIssue(issue); err != nil {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<th>Actived</th>
|
<th>Actived</th>
|
||||||
<th>Updated</th>
|
<th>Updated</th>
|
||||||
<th>Created</th>
|
<th>Created</th>
|
||||||
<th>Operation</th>
|
<th>Edit</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -115,16 +115,20 @@
|
||||||
<input name="smtpport" class="form-control" placeholder="Type port number" value="{{.Source.SMTP.Port}}">
|
<input name="smtpport" class="form-control" placeholder="Type port number" value="{{.Source.SMTP.Port}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="form-group {{if .Err_TLS}}has-error has-feedback{{end}}">
|
|
||||||
<label class="col-md-3 control-label">TLS: </label>
|
|
||||||
<div class="col-md-7">
|
|
||||||
<input name="tls" type="checkbox" class="form-control" {{if .Source.SMTP.TLS}}checked{{end}}>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
{{if eq $type 3}}
|
||||||
|
<div class="col-md-offset-3 col-md-7">
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input name="tls" type="checkbox" class="form-control" {{if .Source.SMTP.TLS}}checked{{end}}>
|
||||||
|
<strong>Enable TLS Encryption</strong>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
<div class="col-md-offset-3 col-md-7">
|
<div class="col-md-offset-3 col-md-7">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
|
|
|
@ -114,16 +114,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- <div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-offset-3 col-md-7">
|
<div class="col-md-offset-3 col-md-7">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
|
<input name="tls" type="checkbox" {{if .tls}}checked{{end}}>
|
||||||
<strong>Enable Register Confirmation</strong>
|
<strong>Enable TLS Encryption</strong>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -148,6 +148,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-info">
|
||||||
|
<div class="panel-heading">
|
||||||
|
Tips
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<h5>GMail Setting:</h5>
|
||||||
|
<p>Host: smtp.gmail.com, Post: 587, Enable TLS Encryption: true</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-3 control-label">Auth Login Name: </label>
|
<label class="col-md-3 control-label">Auth Login Name: </label>
|
||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
<input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.loginname}}">
|
<input name="loginname" class="form-control" placeholder="Type auth login's username" value="{{.User.LoginName}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue