From e07674bff19dcc321a1611a3598d69c418ac8642 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 12 Jun 2014 17:47:23 -0400 Subject: Support edit release and save as draft --- modules/middleware/repo.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'modules/middleware') diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index c1acc827..6c77ed2a 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -21,21 +21,17 @@ import ( func RepoAssignment(redirect bool, args ...bool) martini.Handler { return func(ctx *Context, params martini.Params) { - log.Trace(fmt.Sprint(args)) // valid brachname var validBranch bool // display bare quick start if it is a bare repo var displayBare bool if len(args) >= 1 { - // Note: argument has wrong value in Go1.3 martini. - // validBranch = args[0] - validBranch = true + validBranch = args[0] } if len(args) >= 2 { - // displayBare = args[1] - displayBare = true + displayBare = args[1] } var ( -- cgit v1.2.3 From ad5ec45dd63aa2563d113e6a9ce31180246aa5f2 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 21 Jun 2014 00:51:41 -0400 Subject: Fix #165 --- .gopmfile | 1 - conf/app.ini | 4 + gogs.go | 2 +- models/access.go | 8 +- models/action.go | 2 +- models/issue.go | 84 ++++---- models/login.go | 18 +- models/models.go | 48 ++--- models/oauth2.go | 32 +-- models/publickey.go | 12 +- models/release.go | 10 +- models/repo.go | 64 +++--- models/user.go | 54 ++--- models/webhook.go | 18 +- modules/auth/user.go | 42 ++-- modules/bin/conf.go | 462 +++++++++++++++++++++-------------------- modules/middleware/context.go | 2 +- modules/setting/setting.go | 32 +-- modules/social/social.go | 10 +- routers/admin/admin.go | 13 +- routers/repo/issue.go | 4 +- routers/repo/setting.go | 2 +- templates/VERSION | 2 +- templates/admin/config.tmpl | 4 +- templates/admin/dashboard.tmpl | 4 + 25 files changed, 484 insertions(+), 450 deletions(-) (limited to 'modules/middleware') diff --git a/.gopmfile b/.gopmfile index 3a0f3fc2..b8aa0237 100644 --- a/.gopmfile +++ b/.gopmfile @@ -19,7 +19,6 @@ github.com/gogits/session = `commit:7ab78d4` github.com/juju2013/goldap = `commit:f4a7f67` github.com/lib/pq = `commit:529edd9` github.com/nfnt/resize = `commit:8aee0d9` -github.com/qiniu/log = `commit:891d1cb` [res] include = templates|public diff --git a/conf/app.ini b/conf/app.ini index 52f0c7ed..111261db 100644 --- a/conf/app.ini +++ b/conf/app.ini @@ -51,6 +51,8 @@ SECRET_KEY = !#@FDEWREWR&*( LOGIN_REMEMBER_DAYS = 7 COOKIE_USERNAME = gogs_awesome COOKIE_REMEMBER_NAME = gogs_incredible +; Reverse proxy authentication header name of user ID +REVERSE_PROXY_AUTHENTICATION_UID = X-WEBAUTH-UID [service] ACTIVE_CODE_LIVE_MINUTES = 180 @@ -65,6 +67,8 @@ REQUIRE_SIGNIN_VIEW = false ENABLE_CACHE_AVATAR = false ; Mail notification ENABLE_NOTIFY_MAIL = false +; More detail: https://github.com/gogits/gogs/issues/165 +ENABLE_REVERSE_PROXY_AUTHENTICATION = false [webhook] ; Cron task interval in minutes diff --git a/gogs.go b/gogs.go index f8b31c9f..7719ee0a 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.4.0620 Alpha" +const APP_VER = "0.4.5.0621 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/access.go b/models/access.go index 4a202dc6..cf31fc13 100644 --- a/models/access.go +++ b/models/access.go @@ -30,7 +30,7 @@ type Access struct { func AddAccess(access *Access) error { access.UserName = strings.ToLower(access.UserName) access.RepoName = strings.ToLower(access.RepoName) - _, err := orm.Insert(access) + _, err := x.Insert(access) return err } @@ -38,13 +38,13 @@ func AddAccess(access *Access) error { func UpdateAccess(access *Access) error { access.UserName = strings.ToLower(access.UserName) access.RepoName = strings.ToLower(access.RepoName) - _, err := orm.Id(access.Id).Update(access) + _, err := x.Id(access.Id).Update(access) return err } // DeleteAccess deletes access record. func DeleteAccess(access *Access) error { - _, err := orm.Delete(access) + _, err := x.Delete(access) return err } @@ -67,7 +67,7 @@ func HasAccess(uname, repoName string, mode int) (bool, error) { UserName: strings.ToLower(uname), RepoName: strings.ToLower(repoName), } - has, err := orm.Get(access) + has, err := x.Get(access) if err != nil { return false, err } else if !has { diff --git a/models/action.go b/models/action.go index 28468233..8ecdf1de 100644 --- a/models/action.go +++ b/models/action.go @@ -209,7 +209,7 @@ func TransferRepoAction(user, newUser *User, repo *Repository) (err error) { // GetFeeds returns action list of given user in given context. func GetFeeds(userid, offset int64, isProfile bool) ([]*Action, error) { actions := make([]*Action, 0, 20) - sess := orm.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid) + sess := x.Limit(20, int(offset)).Desc("id").Where("user_id=?", userid) if isProfile { sess.Where("is_private=?", false).And("act_user_id=?", userid) } else { diff --git a/models/issue.go b/models/issue.go index 7db728ec..11f6dd4e 100644 --- a/models/issue.go +++ b/models/issue.go @@ -92,7 +92,7 @@ func (i *Issue) GetAssignee() (err error) { // CreateIssue creates new issue for repository. func NewIssue(issue *Issue) (err error) { - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -114,7 +114,7 @@ func NewIssue(issue *Issue) (err error) { // GetIssueByIndex returns issue by given index in repository. func GetIssueByIndex(rid, index int64) (*Issue, error) { issue := &Issue{RepoId: rid, Index: index} - has, err := orm.Get(issue) + has, err := x.Get(issue) if err != nil { return nil, err } else if !has { @@ -126,7 +126,7 @@ func GetIssueByIndex(rid, index int64) (*Issue, error) { // GetIssueById returns an issue by ID. func GetIssueById(id int64) (*Issue, error) { issue := &Issue{Id: id} - has, err := orm.Get(issue) + has, err := x.Get(issue) if err != nil { return nil, err } else if !has { @@ -137,7 +137,7 @@ func GetIssueById(id int64) (*Issue, error) { // GetIssues returns a list of issues by given conditions. func GetIssues(uid, rid, pid, mid int64, page int, isClosed bool, labelIds, sortType string) ([]Issue, error) { - sess := orm.Limit(20, (page-1)*20) + sess := x.Limit(20, (page-1)*20) if rid > 0 { sess.Where("repo_id=?", rid).And("is_closed=?", isClosed) @@ -193,13 +193,13 @@ const ( // GetIssuesByLabel returns a list of issues by given label and repository. func GetIssuesByLabel(repoId int64, label string) ([]*Issue, error) { issues := make([]*Issue, 0, 10) - err := orm.Where("repo_id=?", repoId).And("label_ids like '%$" + label + "|%'").Find(&issues) + err := x.Where("repo_id=?", repoId).And("label_ids like '%$" + label + "|%'").Find(&issues) return issues, err } // GetIssueCountByPoster returns number of issues of repository by poster. func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 { - count, _ := orm.Where("repo_id=?", rid).And("poster_id=?", uid).And("is_closed=?", isClosed).Count(new(Issue)) + count, _ := x.Where("repo_id=?", rid).And("poster_id=?", uid).And("is_closed=?", isClosed).Count(new(Issue)) return count } @@ -241,7 +241,7 @@ func NewIssueUserPairs(rid, iid, oid, pid, aid int64, repoName string) (err erro isNeedAddPoster = false } iu.IsAssigned = iu.Uid == aid - if _, err = orm.Insert(iu); err != nil { + if _, err = x.Insert(iu); err != nil { return err } } @@ -249,7 +249,7 @@ func NewIssueUserPairs(rid, iid, oid, pid, aid int64, repoName string) (err erro iu.Uid = pid iu.IsPoster = true iu.IsAssigned = iu.Uid == aid - if _, err = orm.Insert(iu); err != nil { + if _, err = x.Insert(iu); err != nil { return err } } @@ -270,7 +270,7 @@ func PairsContains(ius []*IssueUser, issueId int64) int { // GetIssueUserPairs returns issue-user pairs by given repository and user. func GetIssueUserPairs(rid, uid int64, isClosed bool) ([]*IssueUser, error) { ius := make([]*IssueUser, 0, 10) - err := orm.Where("is_closed=?", isClosed).Find(&ius, &IssueUser{RepoId: rid, Uid: uid}) + err := x.Where("is_closed=?", isClosed).Find(&ius, &IssueUser{RepoId: rid, Uid: uid}) return ius, err } @@ -285,7 +285,7 @@ func GetIssueUserPairsByRepoIds(rids []int64, isClosed bool, page int) ([]*Issue cond := strings.TrimSuffix(buf.String(), " OR ") ius := make([]*IssueUser, 0, 10) - sess := orm.Limit(20, (page-1)*20).Where("is_closed=?", isClosed) + sess := x.Limit(20, (page-1)*20).Where("is_closed=?", isClosed) if len(cond) > 0 { sess.And(cond) } @@ -296,7 +296,7 @@ func GetIssueUserPairsByRepoIds(rids []int64, isClosed bool, page int) ([]*Issue // GetIssueUserPairsByMode returns issue-user pairs by given repository and user. func GetIssueUserPairsByMode(uid, rid int64, isClosed bool, page, filterMode int) ([]*IssueUser, error) { ius := make([]*IssueUser, 0, 10) - sess := orm.Limit(20, (page-1)*20).Where("uid=?", uid).And("is_closed=?", isClosed) + sess := x.Limit(20, (page-1)*20).Where("uid=?", uid).And("is_closed=?", isClosed) if rid > 0 { sess.And("repo_id=?", rid) } @@ -335,7 +335,7 @@ func GetIssueStats(rid, uid int64, isShowClosed bool, filterMode int) *IssueStat issue := new(Issue) tmpSess := &xorm.Session{} - sess := orm.Where("repo_id=?", rid) + sess := x.Where("repo_id=?", rid) *tmpSess = *sess stats.OpenCount, _ = tmpSess.And("is_closed=?", false).Count(issue) *tmpSess = *sess @@ -347,7 +347,7 @@ func GetIssueStats(rid, uid int64, isShowClosed bool, filterMode int) *IssueStat } if filterMode != FM_MENTION { - sess = orm.Where("repo_id=?", rid) + sess = x.Where("repo_id=?", rid) switch filterMode { case FM_ASSIGN: sess.And("assignee_id=?", uid) @@ -361,16 +361,16 @@ func GetIssueStats(rid, uid int64, isShowClosed bool, filterMode int) *IssueStat *tmpSess = *sess stats.ClosedCount, _ = tmpSess.And("is_closed=?", true).Count(issue) } else { - sess := orm.Where("repo_id=?", rid).And("uid=?", uid).And("is_mentioned=?", true) + sess := x.Where("repo_id=?", rid).And("uid=?", uid).And("is_mentioned=?", true) *tmpSess = *sess stats.OpenCount, _ = tmpSess.And("is_closed=?", false).Count(new(IssueUser)) *tmpSess = *sess stats.ClosedCount, _ = tmpSess.And("is_closed=?", true).Count(new(IssueUser)) } nofilter: - stats.AssignCount, _ = orm.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("assignee_id=?", uid).Count(issue) - stats.CreateCount, _ = orm.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("poster_id=?", uid).Count(issue) - stats.MentionCount, _ = orm.Where("repo_id=?", rid).And("uid=?", uid).And("is_closed=?", isShowClosed).And("is_mentioned=?", true).Count(new(IssueUser)) + stats.AssignCount, _ = x.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("assignee_id=?", uid).Count(issue) + stats.CreateCount, _ = x.Where("repo_id=?", rid).And("is_closed=?", isShowClosed).And("poster_id=?", uid).Count(issue) + stats.MentionCount, _ = x.Where("repo_id=?", rid).And("uid=?", uid).And("is_closed=?", isShowClosed).And("is_mentioned=?", true).Count(new(IssueUser)) return stats } @@ -378,28 +378,28 @@ nofilter: func GetUserIssueStats(uid int64, filterMode int) *IssueStats { stats := &IssueStats{} issue := new(Issue) - stats.AssignCount, _ = orm.Where("assignee_id=?", uid).And("is_closed=?", false).Count(issue) - stats.CreateCount, _ = orm.Where("poster_id=?", uid).And("is_closed=?", false).Count(issue) + stats.AssignCount, _ = x.Where("assignee_id=?", uid).And("is_closed=?", false).Count(issue) + stats.CreateCount, _ = x.Where("poster_id=?", uid).And("is_closed=?", false).Count(issue) return stats } // UpdateIssue updates information of issue. func UpdateIssue(issue *Issue) error { - _, err := orm.Id(issue.Id).AllCols().Update(issue) + _, err := x.Id(issue.Id).AllCols().Update(issue) return err } // UpdateIssueUserByStatus updates issue-user pairs by issue status. func UpdateIssueUserPairsByStatus(iid int64, isClosed bool) error { rawSql := "UPDATE `issue_user` SET is_closed = ? WHERE issue_id = ?" - _, err := orm.Exec(rawSql, isClosed, iid) + _, err := x.Exec(rawSql, isClosed, iid) return err } // UpdateIssueUserPairByAssignee updates issue-user pair for assigning. func UpdateIssueUserPairByAssignee(aid, iid int64) error { rawSql := "UPDATE `issue_user` SET is_assigned = ? WHERE issue_id = ?" - if _, err := orm.Exec(rawSql, false, iid); err != nil { + if _, err := x.Exec(rawSql, false, iid); err != nil { return err } @@ -408,14 +408,14 @@ func UpdateIssueUserPairByAssignee(aid, iid int64) error { return nil } rawSql = "UPDATE `issue_user` SET is_assigned = true WHERE uid = ? AND issue_id = ?" - _, err := orm.Exec(rawSql, aid, iid) + _, err := x.Exec(rawSql, aid, iid) return err } // UpdateIssueUserPairByRead updates issue-user pair for reading. func UpdateIssueUserPairByRead(uid, iid int64) error { rawSql := "UPDATE `issue_user` SET is_read = ? WHERE uid = ? AND issue_id = ?" - _, err := orm.Exec(rawSql, true, uid, iid) + _, err := x.Exec(rawSql, true, uid, iid) return err } @@ -423,16 +423,16 @@ func UpdateIssueUserPairByRead(uid, iid int64) error { func UpdateIssueUserPairsByMentions(uids []int64, iid int64) error { for _, uid := range uids { iu := &IssueUser{Uid: uid, IssueId: iid} - has, err := orm.Get(iu) + has, err := x.Get(iu) if err != nil { return err } iu.IsMentioned = true if has { - _, err = orm.Id(iu.Id).AllCols().Update(iu) + _, err = x.Id(iu.Id).AllCols().Update(iu) } else { - _, err = orm.Insert(iu) + _, err = x.Insert(iu) } if err != nil { return err @@ -467,7 +467,7 @@ func (m *Label) CalOpenIssues() { // NewLabel creates new label of repository. func NewLabel(l *Label) error { - _, err := orm.Insert(l) + _, err := x.Insert(l) return err } @@ -478,7 +478,7 @@ func GetLabelById(id int64) (*Label, error) { } l := &Label{Id: id} - has, err := orm.Get(l) + has, err := x.Get(l) if err != nil { return nil, err } else if !has { @@ -490,13 +490,13 @@ func GetLabelById(id int64) (*Label, error) { // GetLabels returns a list of labels of given repository ID. func GetLabels(repoId int64) ([]*Label, error) { labels := make([]*Label, 0, 10) - err := orm.Where("repo_id=?", repoId).Find(&labels) + err := x.Where("repo_id=?", repoId).Find(&labels) return labels, err } // UpdateLabel updates label information. func UpdateLabel(l *Label) error { - _, err := orm.Id(l.Id).Update(l) + _, err := x.Id(l.Id).Update(l) return err } @@ -516,7 +516,7 @@ func DeleteLabel(repoId int64, strId string) error { return err } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -569,7 +569,7 @@ func (m *Milestone) CalOpenIssues() { // NewMilestone creates new milestone of repository. func NewMilestone(m *Milestone) (err error) { - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -591,7 +591,7 @@ func NewMilestone(m *Milestone) (err error) { // GetMilestoneById returns the milestone by given ID. func GetMilestoneById(id int64) (*Milestone, error) { m := &Milestone{Id: id} - has, err := orm.Get(m) + has, err := x.Get(m) if err != nil { return nil, err } else if !has { @@ -603,7 +603,7 @@ func GetMilestoneById(id int64) (*Milestone, error) { // GetMilestoneByIndex returns the milestone of given repository and index. func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) { m := &Milestone{RepoId: repoId, Index: idx} - has, err := orm.Get(m) + has, err := x.Get(m) if err != nil { return nil, err } else if !has { @@ -615,13 +615,13 @@ func GetMilestoneByIndex(repoId, idx int64) (*Milestone, error) { // GetMilestones returns a list of milestones of given repository and status. func GetMilestones(repoId int64, isClosed bool) ([]*Milestone, error) { miles := make([]*Milestone, 0, 10) - err := orm.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles) + err := x.Where("repo_id=?", repoId).And("is_closed=?", isClosed).Find(&miles) return miles, err } // UpdateMilestone updates information of given milestone. func UpdateMilestone(m *Milestone) error { - _, err := orm.Id(m.Id).Update(m) + _, err := x.Id(m.Id).Update(m) return err } @@ -632,7 +632,7 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { return err } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -658,7 +658,7 @@ func ChangeMilestoneStatus(m *Milestone, isClosed bool) (err error) { // ChangeMilestoneAssign changes assignment of milestone for issue. func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -717,7 +717,7 @@ func ChangeMilestoneAssign(oldMid, mid int64, issue *Issue) (err error) { // DeleteMilestone deletes a milestone. func DeleteMilestone(m *Milestone) (err error) { - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -777,7 +777,7 @@ type Comment struct { // CreateComment creates comment of issue or commit. func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, content string) error { - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err @@ -816,6 +816,6 @@ func CreateComment(userId, repoId, issueId, commitId, line int64, cmtType int, c // GetIssueComments returns list of comment by given issue id. func GetIssueComments(issueId int64) ([]Comment, error) { comments := make([]Comment, 0, 10) - err := orm.Asc("created").Find(&comments, &Comment{IssueId: issueId}) + err := x.Asc("created").Find(&comments, &Comment{IssueId: issueId}) return comments, err } diff --git a/models/login.go b/models/login.go index 863ba44e..98c5c64e 100644 --- a/models/login.go +++ b/models/login.go @@ -109,19 +109,19 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) { } func CreateSource(source *LoginSource) error { - _, err := orm.Insert(source) + _, err := x.Insert(source) return err } func GetAuths() ([]*LoginSource, error) { var auths = make([]*LoginSource, 0, 5) - err := orm.Find(&auths) + err := x.Find(&auths) return auths, err } func GetLoginSourceById(id int64) (*LoginSource, error) { source := new(LoginSource) - has, err := orm.Id(id).Get(source) + has, err := x.Id(id).Get(source) if err != nil { return nil, err } else if !has { @@ -131,19 +131,19 @@ func GetLoginSourceById(id int64) (*LoginSource, error) { } func UpdateSource(source *LoginSource) error { - _, err := orm.Id(source.Id).AllCols().Update(source) + _, err := x.Id(source.Id).AllCols().Update(source) return err } func DelLoginSource(source *LoginSource) error { - cnt, err := orm.Count(&User{LoginSource: source.Id}) + cnt, err := x.Count(&User{LoginSource: source.Id}) if err != nil { return err } if cnt > 0 { return ErrAuthenticationUserUsed } - _, err = orm.Id(source.Id).Delete(&LoginSource{}) + _, err = x.Id(source.Id).Delete(&LoginSource{}) return err } @@ -156,7 +156,7 @@ func UserSignIn(uname, passwd string) (*User, error) { u = &User{LowerName: strings.ToLower(uname)} } - has, err := orm.Get(u) + has, err := x.Get(u) if err != nil { return nil, err } @@ -182,7 +182,7 @@ func UserSignIn(uname, passwd string) (*User, error) { } else { if !has { var sources []LoginSource - if err = orm.UseBool().Find(&sources, + if err = x.UseBool().Find(&sources, &LoginSource{IsActived: true, AllowAutoRegister: true}); err != nil { return nil, err } @@ -209,7 +209,7 @@ func UserSignIn(uname, passwd string) (*User, error) { } var source LoginSource - hasSource, err := orm.Id(u.LoginSource).Get(&source) + hasSource, err := x.Id(u.LoginSource).Get(&source) if err != nil { return nil, err } else if !hasSource { diff --git a/models/models.go b/models/models.go index a59c0517..d6273d7f 100644 --- a/models/models.go +++ b/models/models.go @@ -18,7 +18,7 @@ import ( ) var ( - orm *xorm.Engine + x *xorm.Engine tables []interface{} HasEngine bool @@ -88,7 +88,7 @@ func NewTestEngine(x *xorm.Engine) (err error) { func SetEngine() (err error) { switch DbCfg.Type { case "mysql": - orm, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8", + x, err = xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8", DbCfg.User, DbCfg.Pwd, DbCfg.Host, DbCfg.Name)) case "postgres": var host, port = "127.0.0.1", "5432" @@ -99,11 +99,11 @@ func SetEngine() (err error) { if len(fields) > 1 && len(strings.TrimSpace(fields[1])) > 0 { port = fields[1] } - orm, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", + x, err = xorm.NewEngine("postgres", fmt.Sprintf("user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", DbCfg.User, DbCfg.Pwd, host, port, DbCfg.Name, DbCfg.SslMode)) case "sqlite3": os.MkdirAll(path.Dir(DbCfg.Path), os.ModePerm) - orm, err = xorm.NewEngine("sqlite3", DbCfg.Path) + x, err = xorm.NewEngine("sqlite3", DbCfg.Path) default: return fmt.Errorf("Unknown database type: %s", DbCfg.Type) } @@ -120,11 +120,11 @@ func SetEngine() (err error) { if err != nil { return fmt.Errorf("models.init(fail to create xorm.log): %v", err) } - orm.Logger = xorm.NewSimpleLogger(f) + x.Logger = xorm.NewSimpleLogger(f) - orm.ShowSQL = true - orm.ShowDebug = true - orm.ShowErr = true + x.ShowSQL = true + x.ShowDebug = true + x.ShowErr = true return nil } @@ -132,7 +132,7 @@ func NewEngine() (err error) { if err = SetEngine(); err != nil { return err } - if err = orm.Sync(tables...); err != nil { + if err = x.Sync2(tables...); err != nil { return fmt.Errorf("sync database struct error: %v\n", err) } return nil @@ -147,24 +147,24 @@ type Statistic struct { } func GetStatistic() (stats Statistic) { - stats.Counter.User, _ = orm.Count(new(User)) - stats.Counter.PublicKey, _ = orm.Count(new(PublicKey)) - stats.Counter.Repo, _ = orm.Count(new(Repository)) - stats.Counter.Watch, _ = orm.Count(new(Watch)) - stats.Counter.Action, _ = orm.Count(new(Action)) - stats.Counter.Access, _ = orm.Count(new(Access)) - stats.Counter.Issue, _ = orm.Count(new(Issue)) - stats.Counter.Comment, _ = orm.Count(new(Comment)) - stats.Counter.Mirror, _ = orm.Count(new(Mirror)) - stats.Counter.Oauth, _ = orm.Count(new(Oauth2)) - stats.Counter.Release, _ = orm.Count(new(Release)) - stats.Counter.LoginSource, _ = orm.Count(new(LoginSource)) - stats.Counter.Webhook, _ = orm.Count(new(Webhook)) - stats.Counter.Milestone, _ = orm.Count(new(Milestone)) + stats.Counter.User, _ = x.Count(new(User)) + stats.Counter.PublicKey, _ = x.Count(new(PublicKey)) + stats.Counter.Repo, _ = x.Count(new(Repository)) + stats.Counter.Watch, _ = x.Count(new(Watch)) + stats.Counter.Action, _ = x.Count(new(Action)) + stats.Counter.Access, _ = x.Count(new(Access)) + stats.Counter.Issue, _ = x.Count(new(Issue)) + stats.Counter.Comment, _ = x.Count(new(Comment)) + stats.Counter.Mirror, _ = x.Count(new(Mirror)) + stats.Counter.Oauth, _ = x.Count(new(Oauth2)) + stats.Counter.Release, _ = x.Count(new(Release)) + stats.Counter.LoginSource, _ = x.Count(new(LoginSource)) + stats.Counter.Webhook, _ = x.Count(new(Webhook)) + stats.Counter.Milestone, _ = x.Count(new(Milestone)) return } // DumpDatabase dumps all data from database to file system. func DumpDatabase(filePath string) error { - return orm.DumpAllToFile(filePath) + return x.DumpAllToFile(filePath) } diff --git a/models/oauth2.go b/models/oauth2.go index 61044d68..4b024a26 100644 --- a/models/oauth2.go +++ b/models/oauth2.go @@ -8,16 +8,16 @@ import ( "errors" ) -// OT: Oauth2 Type +type OauthType int + const ( - OT_GITHUB = iota + 1 - OT_GOOGLE - OT_TWITTER - OT_QQ - OT_WEIBO - OT_BITBUCKET - OT_OSCHINA - OT_FACEBOOK + GITHUB OauthType = iota + 1 + GOOGLE + TWITTER + QQ + WEIBO + BITBUCKET + FACEBOOK ) var ( @@ -35,18 +35,18 @@ type Oauth2 struct { } func BindUserOauth2(userId, oauthId int64) error { - _, err := orm.Id(oauthId).Update(&Oauth2{Uid: userId}) + _, err := x.Id(oauthId).Update(&Oauth2{Uid: userId}) return err } func AddOauth2(oa *Oauth2) error { - _, err := orm.Insert(oa) + _, err := x.Insert(oa) return err } func GetOauth2(identity string) (oa *Oauth2, err error) { oa = &Oauth2{Identity: identity} - isExist, err := orm.Get(oa) + isExist, err := x.Get(oa) if err != nil { return } else if !isExist { @@ -60,7 +60,7 @@ func GetOauth2(identity string) (oa *Oauth2, err error) { func GetOauth2ById(id int64) (oa *Oauth2, err error) { oa = new(Oauth2) - has, err := orm.Id(id).Get(oa) + has, err := x.Id(id).Get(oa) if err != nil { return nil, err } else if !has { @@ -71,18 +71,18 @@ func GetOauth2ById(id int64) (oa *Oauth2, err error) { // GetOauthByUserId returns list of oauthes that are releated to given user. func GetOauthByUserId(uid int64) (oas []*Oauth2, err error) { - err = orm.Find(&oas, Oauth2{Uid: uid}) + err = x.Find(&oas, Oauth2{Uid: uid}) return oas, err } // DeleteOauth2ById deletes a oauth2 by ID. func DeleteOauth2ById(id int64) error { - _, err := orm.Delete(&Oauth2{Id: id}) + _, err := x.Delete(&Oauth2{Id: id}) return err } // CleanUnbindOauth deletes all unbind OAuthes. func CleanUnbindOauth() error { - _, err := orm.Delete(&Oauth2{Uid: -1}) + _, err := x.Delete(&Oauth2{Uid: -1}) return err } diff --git a/models/publickey.go b/models/publickey.go index b0021a68..35768b48 100644 --- a/models/publickey.go +++ b/models/publickey.go @@ -107,7 +107,7 @@ func saveAuthorizedKeyFile(key *PublicKey) error { // AddPublicKey adds new public key to database and authorized_keys file. func AddPublicKey(key *PublicKey) (err error) { - has, err := orm.Get(key) + has, err := x.Get(key) if err != nil { return err } else if has { @@ -130,11 +130,11 @@ func AddPublicKey(key *PublicKey) (err error) { key.Fingerprint = strings.Split(stdout, " ")[1] // Save SSH key. - if _, err = orm.Insert(key); err != nil { + if _, err = x.Insert(key); err != nil { return err } else if err = saveAuthorizedKeyFile(key); err != nil { // Roll back. - if _, err2 := orm.Delete(key); err2 != nil { + if _, err2 := x.Delete(key); err2 != nil { return err2 } return err @@ -146,7 +146,7 @@ func AddPublicKey(key *PublicKey) (err error) { // ListPublicKey returns a list of all public keys that user has. func ListPublicKey(uid int64) ([]PublicKey, error) { keys := make([]PublicKey, 0, 5) - err := orm.Find(&keys, &PublicKey{OwnerId: uid}) + err := x.Find(&keys, &PublicKey{OwnerId: uid}) return keys, err } @@ -205,14 +205,14 @@ func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error { // DeletePublicKey deletes SSH key information both in database and authorized_keys file. func DeletePublicKey(key *PublicKey) error { - has, err := orm.Get(key) + has, err := x.Get(key) if err != nil { return err } else if !has { return ErrKeyNotExist } - if _, err = orm.Delete(key); err != nil { + if _, err = x.Delete(key); err != nil { return err } diff --git a/models/release.go b/models/release.go index 32e8c92c..3e1a7811 100644 --- a/models/release.go +++ b/models/release.go @@ -43,7 +43,7 @@ func IsReleaseExist(repoId int64, tagName string) (bool, error) { return false, nil } - return orm.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)}) + return x.Get(&Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)}) } func createTag(gitRepo *git.Repository, rel *Release) error { @@ -86,7 +86,7 @@ func CreateRelease(gitRepo *git.Repository, rel *Release) error { return err } rel.LowerTagName = strings.ToLower(rel.TagName) - _, err = orm.InsertOne(rel) + _, err = x.InsertOne(rel) return err } @@ -100,13 +100,13 @@ func GetRelease(repoId int64, tagName string) (*Release, error) { } rel := &Release{RepoId: repoId, LowerTagName: strings.ToLower(tagName)} - _, err = orm.Get(rel) + _, err = x.Get(rel) return rel, err } // GetReleasesByRepoId returns a list of releases of repository. func GetReleasesByRepoId(repoId int64) (rels []*Release, err error) { - err = orm.Desc("created").Find(&rels, Release{RepoId: repoId}) + err = x.Desc("created").Find(&rels, Release{RepoId: repoId}) return rels, err } @@ -141,6 +141,6 @@ func UpdateRelease(gitRepo *git.Repository, rel *Release) (err error) { if err = createTag(gitRepo, rel); err != nil { return err } - _, err = orm.Id(rel.Id).AllCols().Update(rel) + _, err = x.Id(rel.Id).AllCols().Update(rel) return err } diff --git a/models/repo.go b/models/repo.go index 6b98d0e4..4ccaccbf 100644 --- a/models/repo.go +++ b/models/repo.go @@ -147,7 +147,7 @@ func (repo *Repository) GetOwner() (err error) { // IsRepositoryExist returns true if the repository with given name under user has already existed. func IsRepositoryExist(u *User, repoName string) (bool, error) { repo := Repository{OwnerId: u.Id} - has, err := orm.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo) + has, err := x.Where("lower_name = ?", strings.ToLower(repoName)).Get(&repo) if err != nil { return has, err } else if !has { @@ -197,7 +197,7 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er return errors.New("git clone --mirror: " + stderr) } - if _, err = orm.InsertOne(&Mirror{ + if _, err = x.InsertOne(&Mirror{ RepoId: repoId, RepoName: strings.ToLower(userName + "/" + repoName), Interval: 24, @@ -211,7 +211,7 @@ func MirrorRepository(repoId int64, userName, repoName, repoPath, url string) er func GetMirror(repoId int64) (*Mirror, error) { m := &Mirror{RepoId: repoId} - has, err := orm.Get(m) + has, err := x.Get(m) if err != nil { return nil, err } else if !has { @@ -221,13 +221,13 @@ func GetMirror(repoId int64) (*Mirror, error) { } func UpdateMirror(m *Mirror) error { - _, err := orm.Id(m.Id).Update(m) + _, err := x.Id(m.Id).Update(m) return err } // MirrorUpdate checks and updates mirror repositories. func MirrorUpdate() { - if err := orm.Iterate(new(Mirror), func(idx int, bean interface{}) error { + if err := x.Iterate(new(Mirror), func(idx int, bean interface{}) error { m := bean.(*Mirror) if m.NextUpdate.After(time.Now()) { return nil @@ -481,7 +481,7 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir repoPath := RepoPath(user.Name, repo.Name) - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() sess.Begin() @@ -566,13 +566,13 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir // It also auto-gets corresponding users. func GetRepositoriesWithUsers(num, offset int) ([]*Repository, error) { repos := make([]*Repository, 0, num) - if err := orm.Limit(num, offset).Asc("id").Find(&repos); err != nil { + if err := x.Limit(num, offset).Asc("id").Find(&repos); err != nil { return nil, err } for _, repo := range repos { repo.Owner = &User{Id: repo.OwnerId} - has, err := orm.Get(repo.Owner) + has, err := x.Get(repo.Owner) if err != nil { return nil, err } else if !has { @@ -597,11 +597,11 @@ func TransferOwnership(user *User, newOwner string, repo *Repository) (err error // Update accesses. accesses := make([]Access, 0, 10) - if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repo.LowerName}); err != nil { + if err = x.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repo.LowerName}); err != nil { return err } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -662,11 +662,11 @@ func TransferOwnership(user *User, newOwner string, repo *Repository) (err error func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error) { // Update accesses. accesses := make([]Access, 0, 10) - if err = orm.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil { + if err = x.Find(&accesses, &Access{RepoName: strings.ToLower(userName + "/" + oldRepoName)}); err != nil { return err } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -697,21 +697,21 @@ func UpdateRepository(repo *Repository) error { if len(repo.Website) > 255 { repo.Website = repo.Website[:255] } - _, err := orm.Id(repo.Id).AllCols().Update(repo) + _, err := x.Id(repo.Id).AllCols().Update(repo) return err } // DeleteRepository deletes a repository for a user or orgnaztion. func DeleteRepository(userId, repoId int64, userName string) (err error) { repo := &Repository{Id: repoId, OwnerId: userId} - has, err := orm.Get(repo) + has, err := x.Get(repo) if err != nil { return err } else if !has { return ErrRepoNotExist } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -750,7 +750,7 @@ func DeleteRepository(userId, repoId int64, userName string) (err error) { } // Delete comments. - if err = orm.Iterate(&Issue{RepoId: repoId}, func(idx int, bean interface{}) error { + if err = x.Iterate(&Issue{RepoId: repoId}, func(idx int, bean interface{}) error { issue := bean.(*Issue) if _, err = sess.Delete(&Comment{IssueId: issue.Id}); err != nil { sess.Rollback() @@ -785,7 +785,7 @@ func GetRepositoryByName(userId int64, repoName string) (*Repository, error) { OwnerId: userId, LowerName: strings.ToLower(repoName), } - has, err := orm.Get(repo) + has, err := x.Get(repo) if err != nil { return nil, err } else if !has { @@ -797,7 +797,7 @@ func GetRepositoryByName(userId int64, repoName string) (*Repository, error) { // GetRepositoryById returns the repository by given id if exists. func GetRepositoryById(id int64) (*Repository, error) { repo := &Repository{} - has, err := orm.Id(id).Get(repo) + has, err := x.Id(id).Get(repo) if err != nil { return nil, err } else if !has { @@ -809,7 +809,7 @@ func GetRepositoryById(id int64) (*Repository, error) { // GetRepositories returns a list of repositories of given user. func GetRepositories(uid int64, private bool) ([]*Repository, error) { repos := make([]*Repository, 0, 10) - sess := orm.Desc("updated") + sess := x.Desc("updated") if !private { sess.Where("is_private=?", false) } @@ -820,19 +820,19 @@ func GetRepositories(uid int64, private bool) ([]*Repository, error) { // GetRecentUpdatedRepositories returns the list of repositories that are recently updated. func GetRecentUpdatedRepositories() (repos []*Repository, err error) { - err = orm.Where("is_private=?", false).Limit(5).Desc("updated").Find(&repos) + err = x.Where("is_private=?", false).Limit(5).Desc("updated").Find(&repos) return repos, err } // GetRepositoryCount returns the total number of repositories of user. func GetRepositoryCount(user *User) (int64, error) { - return orm.Count(&Repository{OwnerId: user.Id}) + return x.Count(&Repository{OwnerId: user.Id}) } // GetCollaboratorNames returns a list of user name of repository's collaborators. func GetCollaboratorNames(repoName string) ([]string, error) { accesses := make([]*Access, 0, 10) - if err := orm.Find(&accesses, &Access{RepoName: strings.ToLower(repoName)}); err != nil { + if err := x.Find(&accesses, &Access{RepoName: strings.ToLower(repoName)}); err != nil { return nil, err } @@ -847,7 +847,7 @@ func GetCollaboratorNames(repoName string) ([]string, error) { func GetCollaborativeRepos(uname string) ([]*Repository, error) { uname = strings.ToLower(uname) accesses := make([]*Access, 0, 10) - if err := orm.Find(&accesses, &Access{UserName: uname}); err != nil { + if err := x.Find(&accesses, &Access{UserName: uname}); err != nil { return nil, err } @@ -876,7 +876,7 @@ func GetCollaborativeRepos(uname string) ([]*Repository, error) { // GetCollaborators returns a list of users of repository's collaborators. func GetCollaborators(repoName string) (us []*User, err error) { accesses := make([]*Access, 0, 10) - if err = orm.Find(&accesses, &Access{RepoName: strings.ToLower(repoName)}); err != nil { + if err = x.Find(&accesses, &Access{RepoName: strings.ToLower(repoName)}); err != nil { return nil, err } @@ -900,18 +900,18 @@ type Watch struct { // Watch or unwatch repository. func WatchRepo(uid, rid int64, watch bool) (err error) { if watch { - if _, err = orm.Insert(&Watch{RepoId: rid, UserId: uid}); err != nil { + if _, err = x.Insert(&Watch{RepoId: rid, UserId: uid}); err != nil { return err } rawSql := "UPDATE `repository` SET num_watches = num_watches + 1 WHERE id = ?" - _, err = orm.Exec(rawSql, rid) + _, err = x.Exec(rawSql, rid) } else { - if _, err = orm.Delete(&Watch{0, uid, rid}); err != nil { + if _, err = x.Delete(&Watch{0, uid, rid}); err != nil { return err } rawSql := "UPDATE `repository` SET num_watches = num_watches - 1 WHERE id = ?" - _, err = orm.Exec(rawSql, rid) + _, err = x.Exec(rawSql, rid) } return err } @@ -919,7 +919,7 @@ func WatchRepo(uid, rid int64, watch bool) (err error) { // GetWatchers returns all watchers of given repository. func GetWatchers(rid int64) ([]*Watch, error) { watches := make([]*Watch, 0, 10) - err := orm.Find(&watches, &Watch{RepoId: rid}) + err := x.Find(&watches, &Watch{RepoId: rid}) return watches, err } @@ -933,7 +933,7 @@ func NotifyWatchers(act *Action) error { // Add feed for actioner. act.UserId = act.ActUserId - if _, err = orm.InsertOne(act); err != nil { + if _, err = x.InsertOne(act); err != nil { return errors.New("repo.NotifyWatchers(create action): " + err.Error()) } @@ -944,7 +944,7 @@ func NotifyWatchers(act *Action) error { act.Id = 0 act.UserId = watches[i].UserId - if _, err = orm.InsertOne(act); err != nil { + if _, err = x.InsertOne(act); err != nil { return errors.New("repo.NotifyWatchers(create action): " + err.Error()) } } @@ -953,7 +953,7 @@ func NotifyWatchers(act *Action) error { // IsWatching checks if user has watched given repository. func IsWatching(uid, rid int64) bool { - has, _ := orm.Get(&Watch{0, uid, rid}) + has, _ := x.Get(&Watch{0, uid, rid}) return has } diff --git a/models/user.go b/models/user.go index 04ea1fd6..50d81c94 100644 --- a/models/user.go +++ b/models/user.go @@ -110,7 +110,7 @@ func IsUserExist(name string) (bool, error) { if len(name) == 0 { return false, nil } - return orm.Get(&User{LowerName: strings.ToLower(name)}) + return x.Get(&User{LowerName: strings.ToLower(name)}) } // IsEmailUsed returns true if the e-mail has been used. @@ -118,7 +118,7 @@ func IsEmailUsed(email string) (bool, error) { if len(email) == 0 { return false, nil } - return orm.Get(&User{Email: email}) + return x.Get(&User{Email: email}) } // GetUserSalt returns a user salt token @@ -153,10 +153,10 @@ func RegisterUser(user *User) (*User, error) { user.Rands = GetUserSalt() user.Salt = GetUserSalt() user.EncodePasswd() - if _, err = orm.Insert(user); err != nil { + if _, err = x.Insert(user); err != nil { return nil, err } else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil { - if _, err := orm.Id(user.Id).Delete(&User{}); err != nil { + if _, err := x.Id(user.Id).Delete(&User{}); err != nil { return nil, errors.New(fmt.Sprintf( "both create userpath %s and delete table record faild: %v", user.Name, err)) } @@ -166,7 +166,7 @@ func RegisterUser(user *User) (*User, error) { if user.Id == 1 { user.IsAdmin = true user.IsActive = true - _, err = orm.Id(user.Id).UseBool().Update(user) + _, err = x.Id(user.Id).UseBool().Update(user) } return user, err } @@ -174,7 +174,7 @@ func RegisterUser(user *User) (*User, error) { // GetUsers returns given number of user objects with offset. func GetUsers(num, offset int) ([]User, error) { users := make([]User, 0, num) - err := orm.Limit(num, offset).Asc("id").Find(&users) + err := x.Limit(num, offset).Asc("id").Find(&users) return users, err } @@ -218,11 +218,11 @@ func ChangeUserName(user *User, newUserName string) (err error) { // Update accesses of user. accesses := make([]Access, 0, 10) - if err = orm.Find(&accesses, &Access{UserName: user.LowerName}); err != nil { + if err = x.Find(&accesses, &Access{UserName: user.LowerName}); err != nil { return err } - sess := orm.NewSession() + sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err @@ -245,7 +245,7 @@ func ChangeUserName(user *User, newUserName string) (err error) { for i := range repos { accesses = make([]Access, 0, 10) // Update accesses of user repository. - if err = orm.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repos[i].LowerName}); err != nil { + if err = x.Find(&accesses, &Access{RepoName: user.LowerName + "/" + repos[i].LowerName}); err != nil { return err } @@ -278,7 +278,7 @@ func UpdateUser(u *User) (err error) { u.Website = u.Website[:255] } - _, err = orm.Id(u.Id).AllCols().Update(u) + _, err = x.Id(u.Id).AllCols().Update(u) return err } @@ -295,33 +295,33 @@ func DeleteUser(user *User) error { // TODO: check issues, other repos' commits // Delete all followers. - if _, err = orm.Delete(&Follow{FollowId: user.Id}); err != nil { + if _, err = x.Delete(&Follow{FollowId: user.Id}); err != nil { return err } // Delete oauth2. - if _, err = orm.Delete(&Oauth2{Uid: user.Id}); err != nil { + if _, err = x.Delete(&Oauth2{Uid: user.Id}); err != nil { return err } // Delete all feeds. - if _, err = orm.Delete(&Action{UserId: user.Id}); err != nil { + if _, err = x.Delete(&Action{UserId: user.Id}); err != nil { return err } // Delete all watches. - if _, err = orm.Delete(&Watch{UserId: user.Id}); err != nil { + if _, err = x.Delete(&Watch{UserId: user.Id}); err != nil { return err } // Delete all accesses. - if _, err = orm.Delete(&Access{UserName: user.LowerName}); err != nil { + if _, err = x.Delete(&Access{UserName: user.LowerName}); err != nil { return err } // Delete all SSH keys. keys := make([]*PublicKey, 0, 10) - if err = orm.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil { + if err = x.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil { return err } for _, key := range keys { @@ -335,7 +335,13 @@ func DeleteUser(user *User) error { return err } - _, err = orm.Delete(user) + _, err = x.Delete(user) + return err +} + +// DeleteInactivateUsers deletes all inactivate users. +func DeleteInactivateUsers() error { + _, err := x.Where("is_active=?", false).Delete(new(User)) return err } @@ -347,7 +353,7 @@ func UserPath(userName string) string { func GetUserByKeyId(keyId int64) (*User, error) { user := new(User) rawSql := "SELECT a.* FROM `user` AS a, public_key AS b WHERE a.id = b.owner_id AND b.id=?" - has, err := orm.Sql(rawSql, keyId).Get(user) + has, err := x.Sql(rawSql, keyId).Get(user) if err != nil { return nil, err } else if !has { @@ -359,7 +365,7 @@ func GetUserByKeyId(keyId int64) (*User, error) { // GetUserById returns the user object by given ID if exists. func GetUserById(id int64) (*User, error) { u := new(User) - has, err := orm.Id(id).Get(u) + has, err := x.Id(id).Get(u) if err != nil { return nil, err } else if !has { @@ -374,7 +380,7 @@ func GetUserByName(name string) (*User, error) { return nil, ErrUserNotExist } user := &User{LowerName: strings.ToLower(name)} - has, err := orm.Get(user) + has, err := x.Get(user) if err != nil { return nil, err } else if !has { @@ -415,7 +421,7 @@ func GetUserByEmail(email string) (*User, error) { return nil, ErrUserNotExist } user := &User{Email: strings.ToLower(email)} - has, err := orm.Get(user) + has, err := x.Get(user) if err != nil { return nil, err } else if !has { @@ -439,7 +445,7 @@ func SearchUserByName(key string, limit int) (us []*User, err error) { key = strings.ToLower(key) us = make([]*User, 0, limit) - err = orm.Limit(limit).Where("lower_name like '%" + key + "%'").Find(&us) + err = x.Limit(limit).Where("lower_name like '%" + key + "%'").Find(&us) return us, err } @@ -452,7 +458,7 @@ type Follow struct { // FollowUser marks someone be another's follower. func FollowUser(userId int64, followId int64) (err error) { - session := orm.NewSession() + session := x.NewSession() defer session.Close() session.Begin() @@ -477,7 +483,7 @@ func FollowUser(userId int64, followId int64) (err error) { // UnFollowUser unmarks someone be another's follower. func UnFollowUser(userId int64, unFollowId int64) (err error) { - session := orm.NewSession() + session := x.NewSession() defer session.Close() session.Begin() diff --git a/models/webhook.go b/models/webhook.go index ffd47c8f..9044befb 100644 --- a/models/webhook.go +++ b/models/webhook.go @@ -68,14 +68,14 @@ func (w *Webhook) HasPushEvent() bool { // CreateWebhook creates a new web hook. func CreateWebhook(w *Webhook) error { - _, err := orm.Insert(w) + _, err := x.Insert(w) return err } // GetWebhookById returns webhook by given ID. func GetWebhookById(hookId int64) (*Webhook, error) { w := &Webhook{Id: hookId} - has, err := orm.Get(w) + has, err := x.Get(w) if err != nil { return nil, err } else if !has { @@ -86,25 +86,25 @@ func GetWebhookById(hookId int64) (*Webhook, error) { // GetActiveWebhooksByRepoId returns all active webhooks of repository. func GetActiveWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) { - err = orm.Find(&ws, &Webhook{RepoId: repoId, IsActive: true}) + err = x.Find(&ws, &Webhook{RepoId: repoId, IsActive: true}) return ws, err } // GetWebhooksByRepoId returns all webhooks of repository. func GetWebhooksByRepoId(repoId int64) (ws []*Webhook, err error) { - err = orm.Find(&ws, &Webhook{RepoId: repoId}) + err = x.Find(&ws, &Webhook{RepoId: repoId}) return ws, err } // UpdateWebhook updates information of webhook. func UpdateWebhook(w *Webhook) error { - _, err := orm.AllCols().Update(w) + _, err := x.AllCols().Update(w) return err } // DeleteWebhook deletes webhook of repository. func DeleteWebhook(hookId int64) error { - _, err := orm.Delete(&Webhook{Id: hookId}) + _, err := x.Delete(&Webhook{Id: hookId}) return err } @@ -174,20 +174,20 @@ func CreateHookTask(t *HookTask) error { return err } t.PayloadContent = string(data) - _, err = orm.Insert(t) + _, err = x.Insert(t) return err } // UpdateHookTask updates information of hook task. func UpdateHookTask(t *HookTask) error { - _, err := orm.AllCols().Update(t) + _, err := x.AllCols().Update(t) return err } // DeliverHooks checks and delivers undelivered hooks. func DeliverHooks() { timeout := time.Duration(setting.WebhookDeliverTimeout) * time.Second - orm.Where("is_deliveried=?", false).Iterate(new(HookTask), + x.Where("is_deliveried=?", false).Iterate(new(HookTask), func(idx int, bean interface{}) error { t := bean.(*HookTask) // Only support JSON now. diff --git a/modules/auth/user.go b/modules/auth/user.go index 3763c0fc..fdbba31a 100644 --- a/modules/auth/user.go +++ b/modules/auth/user.go @@ -16,20 +16,32 @@ import ( "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware/binding" + "github.com/gogits/gogs/modules/setting" ) // SignedInId returns the id of signed in user. -func SignedInId(sess session.SessionStore) int64 { +func SignedInId(header http.Header, sess session.SessionStore) int64 { if !models.HasEngine { return 0 } - uid := sess.Get("userId") - if uid == nil { - return 0 + id, _ := base.StrTo(header.Get(setting.ReverseProxyAuthUid)).Int64() + if id <= 0 { + uid := sess.Get("userId") + if uid == nil { + return 0 + } + var ok bool + if id, ok = uid.(int64); !ok { + return 0 + } } - if id, ok := uid.(int64); ok { + + if id > 0 { if _, err := models.GetUserById(id); err != nil { + if err != models.ErrUserNotExist { + log.Error("auth.user.SignedInId(GetUserById): %v", err) + } return 0 } return id @@ -37,21 +49,9 @@ func SignedInId(sess session.SessionStore) int64 { return 0 } -// SignedInName returns the name of signed in user. -func SignedInName(sess session.SessionStore) string { - uname := sess.Get("userName") - if uname == nil { - return "" - } - if s, ok := uname.(string); ok { - return s - } - return "" -} - // SignedInUser returns the user object of signed user. -func SignedInUser(sess session.SessionStore) *models.User { - uid := SignedInId(sess) +func SignedInUser(header http.Header, sess session.SessionStore) *models.User { + uid := SignedInId(header, sess) if uid <= 0 { return nil } @@ -65,8 +65,8 @@ func SignedInUser(sess session.SessionStore) *models.User { } // IsSignedIn check if any user has signed in. -func IsSignedIn(sess session.SessionStore) bool { - return SignedInId(sess) > 0 +func IsSignedIn(header http.Header, sess session.SessionStore) bool { + return SignedInId(header, sess) > 0 } type FeedsForm struct { diff --git a/modules/bin/conf.go b/modules/bin/conf.go index 80139536..71a9fac8 100644 --- a/modules/bin/conf.go +++ b/modules/bin/conf.go @@ -29,233 +29,241 @@ func conf_app_ini() ([]byte, error) { return bindata_read([]byte{ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xb4, 0x59, 0xdd, 0x72, 0xdb, 0xc8, 0xb1, 0xbe, 0xc7, 0x53, 0x8c, 0x79, 0x76, 0xcf, - 0xda, 0xa7, 0x24, 0x92, 0x92, 0x8f, 0x65, 0xad, 0xb4, 0xae, 0x98, 0x22, - 0x41, 0x09, 0xb1, 0x48, 0x6a, 0x01, 0x48, 0x8e, 0xe3, 0x52, 0xa1, 0x20, - 0x60, 0x48, 0x4e, 0x04, 0x60, 0x20, 0xcc, 0x50, 0x14, 0x73, 0x97, 0x57, - 0x48, 0xe5, 0x69, 0xf2, 0x3c, 0xb9, 0xc8, 0x63, 0xe4, 0xeb, 0x01, 0x40, - 0x81, 0x34, 0xd7, 0xeb, 0xfc, 0x55, 0x52, 0x16, 0x31, 0xd3, 0xd3, 0xd3, - 0xfd, 0xf5, 0xff, 0xec, 0x29, 0xeb, 0xe5, 0x39, 0xcb, 0xc2, 0x94, 0x33, - 0x3d, 0x0f, 0x35, 0x53, 0x73, 0xb9, 0x54, 0x4c, 0x66, 0x8c, 0x3f, 0xf2, - 0x62, 0xc5, 0xf2, 0x70, 0x86, 0x0d, 0xa1, 0x13, 0x6e, 0xf5, 0xae, 0xae, - 0x82, 0x71, 0x6f, 0x64, 0xb3, 0x77, 0xec, 0x5c, 0xce, 0xd4, 0x09, 0xfe, - 0x65, 0xe7, 0x42, 0x33, 0x8f, 0x17, 0x8f, 0x22, 0x2a, 0xf7, 0x2f, 0x27, - 0xe7, 0x13, 0xec, 0x8b, 0x74, 0xd6, 0x99, 0x86, 0x58, 0x95, 0x59, 0x3b, - 0xcf, 0x66, 0xd6, 0x29, 0xeb, 0xcf, 0xc3, 0x0c, 0x9c, 0x40, 0x2e, 0xa6, - 0x6c, 0x25, 0x17, 0xac, 0x58, 0x64, 0x2c, 0x91, 0x51, 0x98, 0x24, 0x2b, - 0xcb, 0xbd, 0x1e, 0x07, 0xd7, 0x9e, 0xed, 0xe2, 0xe4, 0x4c, 0x68, 0x50, - 0xdb, 0x42, 0xcf, 0x79, 0xc1, 0x5a, 0x31, 0x7f, 0x6c, 0xed, 0xb1, 0x56, - 0x5e, 0xc8, 0xb8, 0xc5, 0x24, 0x16, 0x34, 0x57, 0x1a, 0x2b, 0x31, 0x9f, - 0x86, 0x8b, 0x04, 0xbc, 0x54, 0x49, 0x63, 0x38, 0x8c, 0x26, 0x03, 0x92, - 0x0d, 0xdf, 0x96, 0xf5, 0xb9, 0xe0, 0xb9, 0x54, 0x42, 0xcb, 0x62, 0x75, - 0x6b, 0xb9, 0x93, 0x89, 0x8f, 0x0d, 0xcb, 0xeb, 0xbb, 0xce, 0x95, 0x1f, - 0xf8, 0x9f, 0xae, 0x88, 0xee, 0x2e, 0x54, 0x73, 0x10, 0x2a, 0x48, 0xcf, - 0x8b, 0x5b, 0xeb, 0xca, 0x9d, 0xf8, 0x93, 0xfe, 0xe4, 0x12, 0x3b, 0x73, - 0xad, 0x73, 0x6b, 0x30, 0x19, 0xf5, 0x9c, 0x31, 0xbe, 0x8c, 0x90, 0x73, - 0xa9, 0xb4, 0xe1, 0x13, 0x5c, 0xbb, 0x44, 0xf2, 0xfd, 0xcb, 0x9a, 0xfe, - 0x95, 0x3a, 0xe9, 0x74, 0xbe, 0x7f, 0x59, 0x92, 0xe3, 0xe3, 0xfb, 0x97, - 0x17, 0xbe, 0x7f, 0x15, 0x5c, 0x4d, 0x5c, 0xff, 0x95, 0xea, 0x58, 0xe6, - 0xa3, 0x37, 0x18, 0x90, 0x6e, 0xd6, 0x7a, 0x07, 0x1f, 0xaf, 0xbb, 0xdd, - 0xae, 0xe5, 0x79, 0x17, 0xf5, 0xf7, 0xe1, 0x21, 0xf4, 0x1e, 0x08, 0x15, - 0xde, 0x25, 0x9c, 0xf5, 0x07, 0x63, 0xc2, 0x3f, 0x63, 0x22, 0xab, 0xb5, - 0x4f, 0x65, 0xcc, 0xad, 0xc9, 0x70, 0x78, 0xe9, 0x8c, 0xed, 0x5a, 0xd5, - 0x69, 0x98, 0x28, 0x6e, 0x0d, 0x1c, 0xaf, 0x77, 0x76, 0x69, 0x07, 0xee, - 0xe4, 0xda, 0xb7, 0x5d, 0x32, 0xc1, 0x7a, 0xeb, 0x94, 0x9d, 0xf3, 0x8c, - 0x17, 0xa1, 0xe6, 0x4c, 0x69, 0x9e, 0xab, 0x13, 0xac, 0x7c, 0xc7, 0xa2, - 0x18, 0x66, 0xd5, 0xf3, 0x8e, 0x96, 0x9d, 0x19, 0x0c, 0xd9, 0x89, 0x16, - 0x4a, 0xcb, 0xb4, 0x43, 0x6a, 0x2b, 0x43, 0x30, 0x93, 0xc6, 0x3c, 0xdf, - 0x9d, 0x4f, 0x48, 0xe5, 0x8e, 0x2a, 0xa2, 0x4e, 0x7e, 0x3f, 0xeb, 0x44, - 0xc5, 0x2a, 0xc7, 0x19, 0x9d, 0xa8, 0xce, 0xac, 0x62, 0x1b, 0x44, 0xbc, - 0xd0, 0x6d, 0xd0, 0xef, 0x47, 0xe1, 0x3b, 0x5d, 0x2c, 0x38, 0xdb, 0x8f, - 0x17, 0xd8, 0x10, 0x32, 0x7b, 0x77, 0xfc, 0xf6, 0xa8, 0x3b, 0xef, 0xa6, - 0x5d, 0xc5, 0xf6, 0x09, 0xbe, 0x77, 0xe9, 0x8a, 0xfe, 0xb4, 0xf9, 0x53, - 0x98, 0xe6, 0x09, 0x6f, 0x47, 0x32, 0xb5, 0xfa, 0xb6, 0xeb, 0x07, 0x43, - 0xe7, 0x92, 0x94, 0x69, 0x4a, 0xd1, 0x31, 0x6c, 0x73, 0x9e, 0x5a, 0x1f, - 0xec, 0x4f, 0x3b, 0x09, 0xee, 0xf9, 0xca, 0xec, 0x9f, 0xb2, 0xeb, 0x3c, - 0x87, 0xab, 0x24, 0x80, 0x2b, 0x61, 0x72, 0xca, 0x34, 0x07, 0x77, 0x52, - 0x38, 0xcc, 0x62, 0x28, 0x0d, 0x51, 0x22, 0x36, 0x15, 0xc0, 0x94, 0x54, - 0x06, 0x79, 0xc3, 0x75, 0xe0, 0x63, 0x66, 0x95, 0x2d, 0xe1, 0x6c, 0xdc, - 0x38, 0x35, 0x2d, 0xf3, 0x27, 0x1e, 0x2d, 0x34, 0x8f, 0x2d, 0xcf, 0xef, - 0xf9, 0x4e, 0x3f, 0x30, 0x66, 0xbf, 0xea, 0xf9, 0x17, 0x64, 0x42, 0xeb, - 0x73, 0x1c, 0xea, 0x10, 0xbe, 0xc3, 0x6f, 0x1b, 0x7e, 0x9a, 0xae, 0xd4, - 0x43, 0x62, 0x3c, 0x15, 0x1a, 0xce, 0x0a, 0xae, 0x4a, 0x6f, 0xc5, 0xa2, - 0xd0, 0xfc, 0x35, 0x36, 0x84, 0xfe, 0x41, 0x91, 0xdb, 0x17, 0x2c, 0x9a, - 0x4b, 0x0a, 0x96, 0xc1, 0x59, 0xed, 0x87, 0xe6, 0xac, 0x75, 0x31, 0xf1, - 0xc8, 0x0b, 0x0e, 0x0e, 0xdf, 0xb6, 0xbb, 0xf8, 0xdf, 0xc1, 0xc9, 0xeb, - 0xd7, 0xdd, 0x23, 0xab, 0x0a, 0x37, 0xb2, 0x92, 0x55, 0x05, 0x48, 0x21, - 0xa5, 0xb6, 0xae, 0x7a, 0x9e, 0xf7, 0x71, 0xc0, 0xde, 0x41, 0x84, 0x21, - 0x5d, 0xd4, 0xb8, 0x36, 0x4b, 0x56, 0x7b, 0x8c, 0xd7, 0xf1, 0x53, 0xfa, - 0x13, 0x49, 0x56, 0xf0, 0x87, 0x85, 0x28, 0x78, 0x29, 0x18, 0x3c, 0x5e, - 0x4c, 0x57, 0xfb, 0xd3, 0x45, 0x92, 0xb4, 0xe0, 0x84, 0x97, 0xeb, 0xd8, - 0x29, 0xe9, 0x6b, 0xb6, 0xb5, 0xfc, 0x86, 0xab, 0x55, 0x41, 0x40, 0xfa, - 0x1b, 0xbf, 0x69, 0xc7, 0x77, 0x80, 0x23, 0x8c, 0x53, 0x91, 0xdd, 0x9a, - 0x40, 0x8a, 0x16, 0x85, 0xd0, 0x88, 0x37, 0x67, 0x0c, 0xe4, 0x2e, 0x2f, - 0xe1, 0x89, 0xfd, 0x0f, 0x0d, 0x57, 0x7c, 0xf1, 0xa2, 0x7f, 0xd1, 0x1b, - 0x9f, 0xdb, 0xcc, 0xbf, 0x70, 0x3c, 0xe6, 0x4f, 0xd8, 0x07, 0xdb, 0xbe, - 0x62, 0x9f, 0x26, 0xd7, 0x2e, 0x33, 0xba, 0x0d, 0x7a, 0x7e, 0x8f, 0x79, - 0xbd, 0xa1, 0xfd, 0xe2, 0x85, 0xe5, 0xd9, 0x7d, 0xd7, 0xf6, 0x03, 0x58, - 0x1f, 0x0c, 0x5e, 0xfc, 0xcf, 0xfb, 0xe1, 0xc0, 0xfe, 0xe8, 0xe2, 0xff, - 0xff, 0xfb, 0x7f, 0x2f, 0xc1, 0xa9, 0xb7, 0xd0, 0x72, 0x3f, 0x91, 0x33, - 0x44, 0x47, 0xc1, 0x53, 0x9e, 0xde, 0x41, 0xd7, 0x38, 0x5c, 0x29, 0x0b, - 0xbe, 0xef, 0x8c, 0x03, 0xd7, 0x1e, 0xd9, 0xa3, 0x33, 0x84, 0xc2, 0xa0, - 0xf7, 0xc9, 0xc3, 0xf9, 0xb7, 0x56, 0x7f, 0x32, 0xf9, 0xe0, 0xd8, 0x26, - 0xc7, 0x34, 0x20, 0x0d, 0xc2, 0x25, 0x57, 0x32, 0xe5, 0xf5, 0xf6, 0xfa, - 0x5c, 0x93, 0x46, 0x64, 0x51, 0xc1, 0x63, 0x41, 0xa8, 0x94, 0xc9, 0x02, - 0xd6, 0xbb, 0xb5, 0x7a, 0x7d, 0xdf, 0xb9, 0xb1, 0x83, 0x3e, 0x60, 0x0b, - 0x2e, 0xe9, 0xd7, 0xc8, 0x19, 0x23, 0xfa, 0xe8, 0xb6, 0x83, 0xe3, 0xae, - 0xe5, 0xda, 0x9e, 0x4d, 0x3e, 0x43, 0x56, 0xfa, 0x45, 0x22, 0xb8, 0x2e, - 0xf8, 0xb1, 0x8c, 0xf3, 0x98, 0x69, 0xc9, 0x90, 0x2b, 0xa7, 0xa2, 0x48, - 0x19, 0xdf, 0x4f, 0x43, 0x91, 0xb0, 0x29, 0x0c, 0x50, 0xf0, 0x99, 0x50, - 0xba, 0x0c, 0x27, 0xf0, 0x3c, 0x77, 0x3c, 0x0a, 0x70, 0x1b, 0x99, 0xe6, - 0x12, 0x5c, 0xc7, 0x43, 0xc7, 0x1d, 0x35, 0xf0, 0x1d, 0x48, 0xae, 0x58, - 0x26, 0x35, 0x43, 0x4e, 0x95, 0xcb, 0xea, 0x30, 0x2e, 0xa0, 0x40, 0x30, - 0x56, 0x62, 0xd0, 0xc4, 0x44, 0x46, 0x14, 0xc9, 0x45, 0xa6, 0x4b, 0xab, - 0xae, 0xb3, 0x87, 0x61, 0xef, 0xc2, 0xe3, 0x27, 0xe3, 0x06, 0x53, 0x23, - 0x62, 0x8a, 0xc8, 0x63, 0x4a, 0xcc, 0x4c, 0x3e, 0x82, 0xa8, 0x8f, 0x82, - 0x2f, 0xc1, 0x76, 0xa5, 0xe7, 0x22, 0x9b, 0xb5, 0x21, 0xd9, 0xcf, 0xd7, - 0x8e, 0x6b, 0x07, 0x9e, 0x73, 0x3e, 0x06, 0xfc, 0x37, 0x8e, 0xfd, 0xb1, - 0xc1, 0xa1, 0x1f, 0x46, 0x88, 0xb3, 0xf0, 0x11, 0x6e, 0x03, 0x59, 0x14, - 0xcb, 0x45, 0xa4, 0x17, 0x05, 0xb7, 0xec, 0xb1, 0xb9, 0xb7, 0xdf, 0xeb, - 0x5f, 0xd8, 0x41, 0xef, 0x06, 0xc6, 0x77, 0x1b, 0xa7, 0x46, 0x84, 0x01, - 0x94, 0x11, 0x53, 0x11, 0x95, 0xfa, 0x57, 0xf4, 0xe3, 0x89, 0xef, 0x0c, - 0x3f, 0x05, 0x84, 0xc1, 0x9a, 0xdc, 0xfa, 0xbc, 0xe4, 0x77, 0x73, 0x29, - 0xef, 0x29, 0x26, 0xfb, 0x05, 0x8a, 0x97, 0x0e, 0xd5, 0x3d, 0x84, 0x85, - 0xfa, 0x8f, 0x61, 0x42, 0x52, 0x43, 0x7d, 0xc4, 0xb4, 0xb2, 0xfc, 0x9e, - 0xf7, 0x21, 0x70, 0xc6, 0xc0, 0xf1, 0xa6, 0x47, 0x0c, 0x0e, 0x08, 0x38, - 0x9e, 0x08, 0x44, 0x04, 0xca, 0x5c, 0xca, 0xe5, 0x42, 0x13, 0x39, 0x9c, - 0x59, 0x66, 0xb1, 0xb2, 0x06, 0x36, 0x19, 0xce, 0x0d, 0x7c, 0x67, 0x64, - 0x23, 0xbd, 0xe2, 0xc0, 0x1b, 0xdc, 0x46, 0x06, 0xa2, 0x9a, 0x51, 0x8a, - 0x34, 0x68, 0x88, 0x7d, 0xb6, 0x98, 0x4e, 0x4d, 0x36, 0xca, 0x66, 0xc8, - 0x2b, 0x48, 0x47, 0x11, 0xea, 0x5e, 0xc6, 0x93, 0x3d, 0x76, 0xcf, 0x79, - 0x4e, 0xe5, 0x0f, 0x08, 0x08, 0x93, 0x7d, 0xaa, 0x3a, 0x18, 0xcb, 0xec, - 0x07, 0xcd, 0xee, 0x33, 0x58, 0x6c, 0x49, 0xf5, 0xd7, 0x6c, 0xb6, 0x11, - 0x00, 0xe3, 0x41, 0x70, 0x76, 0x3d, 0x1c, 0x52, 0x46, 0xb7, 0xc9, 0x22, - 0x07, 0xe4, 0x31, 0x63, 0xaa, 0xd3, 0x88, 0x52, 0xa4, 0xb8, 0x15, 0xdc, - 0x86, 0x14, 0x23, 0xa0, 0xca, 0x02, 0xed, 0x5d, 0x9f, 0xfd, 0xd6, 0xee, - 0xfb, 0xa6, 0x3c, 0xd5, 0xc5, 0xfa, 0x95, 0xaa, 0xc1, 0x2c, 0x0b, 0x1d, - 0x95, 0x04, 0x3a, 0x72, 0xc2, 0x54, 0xaa, 0xf3, 0xf6, 0x8c, 0x7e, 0x53, - 0x2a, 0x3e, 0x79, 0x73, 0xfc, 0x16, 0x7b, 0x3f, 0xff, 0x5c, 0x6d, 0x3c, - 0x3c, 0x98, 0xd5, 0xc3, 0x37, 0x75, 0x66, 0xaa, 0xd9, 0x4c, 0x0b, 0x99, - 0xc2, 0x9d, 0x62, 0x64, 0x1b, 0x65, 0x0d, 0xdd, 0xc9, 0xe8, 0x79, 0x0f, - 0x8a, 0x2f, 0x8c, 0x47, 0x93, 0x90, 0xe4, 0x75, 0x79, 0xa8, 0xd4, 0x52, - 0x16, 0x71, 0x9d, 0xbb, 0xd6, 0x79, 0x8b, 0xf2, 0xa8, 0x0c, 0x17, 0x7a, - 0xfe, 0x25, 0x86, 0xd5, 0x46, 0x1b, 0x8d, 0xc0, 0x7c, 0x71, 0xf7, 0xe5, - 0x7e, 0xff, 0xd2, 0xb1, 0xc7, 0x7e, 0xe0, 0x18, 0x2e, 0xd5, 0x47, 0x99, - 0x2d, 0xca, 0x12, 0x3f, 0xb9, 0x32, 0x01, 0x66, 0xaa, 0x04, 0x2a, 0x73, - 0x98, 0x8b, 0x8a, 0x15, 0xe9, 0xd3, 0x21, 0xf9, 0xac, 0xde, 0xb5, 0x7f, - 0x51, 0xd5, 0xf1, 0x9a, 0xac, 0x41, 0x62, 0xf2, 0x4a, 0xc7, 0x08, 0xd1, - 0xa1, 0x7f, 0x64, 0x21, 0xfe, 0xc8, 0x2d, 0x7f, 0xf2, 0xc1, 0x1e, 0x7f, - 0xe3, 0xa1, 0x28, 0x02, 0x36, 0x81, 0x96, 0xf7, 0x3c, 0xb3, 0x4c, 0x09, - 0xd6, 0x2c, 0x4a, 0x04, 0x47, 0xc4, 0x89, 0xb8, 0x2c, 0x4b, 0x1c, 0x91, - 0xa8, 0x0d, 0x94, 0xd8, 0xaf, 0xd9, 0xc1, 0xe3, 0x94, 0x44, 0x61, 0x8c, - 0xa9, 0x94, 0x49, 0x14, 0x35, 0x85, 0xc2, 0x2a, 0x67, 0x65, 0xa9, 0xec, - 0xa0, 0x0b, 0xf8, 0x03, 0x8f, 0xf4, 0x1a, 0x1e, 0xb3, 0xf3, 0x6f, 0xc3, - 0xb3, 0x5c, 0x2e, 0x2b, 0x56, 0x00, 0x4a, 0x99, 0x8b, 0x8c, 0x0e, 0x84, - 0x93, 0xc8, 0xa6, 0xb2, 0xcd, 0x8d, 0x7f, 0x7d, 0x33, 0x39, 0xa4, 0xa4, - 0x62, 0xbb, 0x0b, 0xe2, 0x2a, 0xeb, 0x6c, 0x28, 0x25, 0x4b, 0xc8, 0x0e, - 0x0d, 0x97, 0x9d, 0x18, 0x7f, 0xf5, 0x54, 0x05, 0x71, 0x05, 0xc9, 0xc3, - 0xc3, 0xbf, 0x0c, 0x07, 0x32, 0xa6, 0x71, 0x7e, 0xf6, 0xb7, 0xbf, 0xfe, - 0xf9, 0xef, 0x7f, 0xfa, 0x0b, 0x95, 0x98, 0x1d, 0x3e, 0x52, 0x84, 0xf9, - 0xbc, 0x0a, 0x8c, 0x4a, 0x82, 0x76, 0xb7, 0xe1, 0x22, 0xa7, 0x6c, 0xa7, - 0x93, 0xec, 0x3c, 0x55, 0x4a, 0x8e, 0x13, 0x3c, 0x8b, 0xc8, 0x31, 0x96, - 0x5c, 0xdc, 0xc9, 0x5d, 0xa8, 0xc1, 0x0f, 0xb2, 0xb6, 0xae, 0xcf, 0x47, - 0x33, 0xb1, 0x7f, 0x57, 0x3b, 0xda, 0xe1, 0xaf, 0xb8, 0xe7, 0xd7, 0x8f, - 0x6e, 0x38, 0x69, 0x85, 0xa0, 0x5e, 0x0a, 0xad, 0x77, 0x25, 0xb6, 0x7f, - 0x02, 0xc6, 0x5d, 0x96, 0x47, 0x0c, 0x56, 0xac, 0x9f, 0x51, 0xf8, 0x15, - 0xe1, 0x7f, 0xe1, 0xcc, 0x2e, 0xa9, 0x0d, 0x76, 0xff, 0x0d, 0x99, 0x0d, - 0xe3, 0x86, 0xdd, 0xbe, 0x41, 0xe4, 0x2f, 0x8f, 0x6c, 0x4a, 0x1c, 0x51, - 0x31, 0xdc, 0xe8, 0x1c, 0x79, 0x8a, 0x19, 0xa5, 0x6c, 0xd0, 0x90, 0xd7, - 0xf1, 0x43, 0x96, 0xab, 0x86, 0x72, 0x6b, 0xd4, 0xa9, 0x88, 0xad, 0xde, - 0xa0, 0x77, 0xe5, 0x9b, 0x8c, 0x5a, 0xae, 0xd4, 0xfd, 0x5a, 0xb5, 0x5f, - 0x35, 0x81, 0xe7, 0xfd, 0x8d, 0x0a, 0x58, 0x95, 0xb4, 0x0d, 0x8e, 0x47, - 0x5d, 0xab, 0x51, 0x0b, 0x8f, 0xba, 0x35, 0xa3, 0x52, 0x16, 0x93, 0xab, - 0x9a, 0xb2, 0x80, 0x41, 0x86, 0x1c, 0x84, 0x6a, 0xcc, 0xa8, 0x95, 0x5f, - 0x97, 0x81, 0x53, 0x66, 0x0e, 0x9c, 0xb0, 0xd6, 0xc9, 0x51, 0xf7, 0xf5, - 0x8f, 0x2d, 0x2c, 0xd4, 0xa7, 0xb0, 0xf6, 0xdc, 0xd3, 0x1e, 0x1c, 0x1c, - 0x1e, 0x1c, 0xb4, 0xaa, 0x8a, 0x62, 0xda, 0x29, 0xa5, 0xc0, 0x6c, 0x37, - 0x1e, 0x94, 0x47, 0x9e, 0x71, 0x29, 0x61, 0xa9, 0xda, 0xec, 0x5d, 0x98, - 0x60, 0x1e, 0xbb, 0x71, 0x06, 0x06, 0x14, 0x93, 0x81, 0x4e, 0xd9, 0x55, - 0x21, 0x1f, 0x45, 0x0c, 0xa6, 0xa6, 0xb3, 0x9a, 0x31, 0x99, 0x93, 0xe4, - 0xaa, 0x14, 0x0e, 0x67, 0x4e, 0x4c, 0xb3, 0x34, 0x0f, 0x1f, 0xa9, 0x58, - 0xad, 0x6a, 0xaa, 0x15, 0xa7, 0x01, 0x94, 0x58, 0xa0, 0x12, 0x96, 0xf2, - 0x3d, 0xcf, 0x0f, 0xe8, 0xac, 0xdb, 0xb3, 0x36, 0xfa, 0x6a, 0xea, 0x81, - 0xab, 0x5d, 0xd5, 0x7a, 0xd6, 0xbf, 0xe2, 0x91, 0x88, 0x7b, 0x5e, 0x2e, - 0x55, 0x55, 0xd7, 0x20, 0xb5, 0xc7, 0x72, 0x29, 0x13, 0x0f, 0xee, 0xb3, - 0xb7, 0xae, 0x8c, 0x35, 0xc3, 0x67, 0x8c, 0x8e, 0x5e, 0xbf, 0xfd, 0x71, - 0xef, 0xa0, 0xdb, 0xdd, 0x0b, 0x31, 0xbc, 0x3c, 0x09, 0x6e, 0xc0, 0x24, - 0xbd, 0x4f, 0xd0, 0x8f, 0xee, 0xe3, 0xef, 0x7e, 0x5c, 0x50, 0xb7, 0xd2, - 0x31, 0x8b, 0x2c, 0x56, 0x59, 0x7d, 0x2b, 0x3a, 0x45, 0xb4, 0x63, 0x35, - 0x47, 0x9a, 0x13, 0x4e, 0xea, 0x6b, 0xde, 0xd7, 0xc2, 0x06, 0xda, 0xcc, - 0x03, 0x6b, 0xb4, 0xca, 0x36, 0xf2, 0xbc, 0x6e, 0xeb, 0x6b, 0x95, 0x70, - 0xa7, 0x57, 0xe9, 0x1e, 0xa1, 0xad, 0x12, 0xdc, 0xd4, 0xf4, 0xba, 0x4f, - 0xae, 0xda, 0x63, 0x11, 0x90, 0x9e, 0x01, 0xba, 0x64, 0xa1, 0xe9, 0x84, - 0x53, 0x36, 0x34, 0xa8, 0x05, 0x6b, 0xe0, 0xe0, 0x76, 0x26, 0x3a, 0x2a, - 0x8f, 0x6c, 0xd8, 0xad, 0x8a, 0xd1, 0x92, 0x21, 0xc2, 0xf2, 0xda, 0xb5, - 0x1b, 0x6d, 0x94, 0x9d, 0x99, 0x31, 0x58, 0x51, 0xe5, 0x34, 0xf7, 0x6f, - 0x9c, 0xa5, 0x39, 0xb3, 0x6e, 0x07, 0xa9, 0xcf, 0x2e, 0xb9, 0xe0, 0xb8, - 0xd9, 0x78, 0x16, 0x1d, 0x01, 0x40, 0x2d, 0xdd, 0x3a, 0x0a, 0x36, 0x98, - 0x1c, 0x1f, 0xfd, 0x3f, 0x06, 0xf0, 0xf3, 0xfe, 0xba, 0x19, 0x34, 0x3d, - 0x1e, 0x98, 0x94, 0x1b, 0xcf, 0x5c, 0x12, 0x31, 0xe5, 0x86, 0xcf, 0x8e, - 0xe3, 0x9e, 0xed, 0x79, 0xe8, 0x97, 0xd1, 0xdd, 0x0f, 0xed, 0xed, 0xf3, - 0x6b, 0x0c, 0x62, 0xf8, 0x98, 0x9a, 0xb3, 0xe9, 0x22, 0x8b, 0xf6, 0xd6, - 0x7e, 0xae, 0xe6, 0xe1, 0x01, 0x79, 0x37, 0xfe, 0x1e, 0xbe, 0x39, 0xaa, - 0xdc, 0x3b, 0x7e, 0xd3, 0x6a, 0xde, 0x41, 0x34, 0xeb, 0x2b, 0x9c, 0x41, - 0x70, 0xd1, 0xf3, 0x2e, 0x86, 0xd7, 0xe3, 0x3e, 0x2e, 0x31, 0x5b, 0xcf, - 0x32, 0x9a, 0x0b, 0x30, 0x12, 0x6f, 0x88, 0x48, 0x86, 0x28, 0x10, 0xc2, - 0xe8, 0xd7, 0x4a, 0xd7, 0xd8, 0xe6, 0x65, 0xa6, 0x2b, 0x84, 0x61, 0xd5, - 0x91, 0x53, 0x18, 0xfa, 0x34, 0x12, 0x27, 0x61, 0xc4, 0xa9, 0xcd, 0xaf, - 0xd6, 0x8d, 0x6b, 0x3c, 0xcf, 0x94, 0xa5, 0x47, 0x97, 0x12, 0x3f, 0x88, - 0x4c, 0x2c, 0xb6, 0x02, 0xb2, 0xda, 0xc7, 0x65, 0xee, 0x8d, 0xd3, 0x27, - 0x44, 0xaa, 0xce, 0xb3, 0x9e, 0x34, 0xce, 0xdd, 0xad, 0x6e, 0xdf, 0xfa, - 0x8c, 0xf6, 0xa9, 0x7c, 0xa6, 0xa9, 0xe6, 0xec, 0x46, 0x42, 0xa8, 0xba, - 0xa2, 0x66, 0x46, 0xa0, 0x34, 0x64, 0xb0, 0x43, 0xa3, 0x5a, 0xca, 0x51, - 0xcf, 0xe4, 0x5b, 0xa2, 0xd4, 0x67, 0xcb, 0x39, 0x06, 0xae, 0x94, 0xa6, - 0x21, 0x29, 0xa6, 0x78, 0x1e, 0x9a, 0x47, 0x91, 0x14, 0x94, 0x22, 0x87, - 0xa7, 0xd1, 0xeb, 0x8a, 0xaa, 0x43, 0xa7, 0x3a, 0xb6, 0x67, 0xe2, 0xbe, - 0x65, 0x55, 0xb3, 0x71, 0xb5, 0xfa, 0x9f, 0x6c, 0xf2, 0xb7, 0xfa, 0xfb, - 0xae, 0xf1, 0x9b, 0x5a, 0x71, 0xbf, 0x80, 0x19, 0x48, 0xcd, 0x01, 0xbf, - 0x5b, 0xcc, 0xe8, 0x87, 0x83, 0x0e, 0x8b, 0xfe, 0x7e, 0x0c, 0x0b, 0xa3, - 0xbf, 0x5d, 0x14, 0xb2, 0xa0, 0x1f, 0x7d, 0xcc, 0xdd, 0x18, 0x93, 0xb6, - 0x53, 0x63, 0xc9, 0xc1, 0xba, 0xb4, 0x6f, 0x6c, 0x4a, 0xef, 0xe6, 0xd3, - 0xaa, 0x53, 0x7c, 0x8d, 0x8d, 0x51, 0xbd, 0x1c, 0x05, 0xc9, 0x0c, 0xed, - 0x6a, 0xfd, 0x76, 0x7d, 0x6c, 0x7d, 0xc2, 0xa0, 0xb1, 0x4d, 0x4e, 0x8b, - 0x0d, 0x5a, 0x7a, 0xaa, 0xa9, 0xf3, 0x03, 0xb6, 0xcb, 0x77, 0x02, 0xfc, - 0x30, 0xae, 0x45, 0x6f, 0x2b, 0x26, 0xb0, 0x15, 0x43, 0x71, 0x94, 0x29, - 0x2c, 0x10, 0x13, 0x15, 0x2b, 0xa4, 0xc6, 0xef, 0x97, 0x0a, 0xf5, 0x3e, - 0x32, 0x80, 0x4e, 0x25, 0x8d, 0xb0, 0x70, 0xd9, 0x3a, 0x69, 0xbf, 0xfa, - 0x32, 0x01, 0x60, 0xd6, 0x0f, 0xdc, 0x89, 0xdf, 0xf3, 0x1b, 0x91, 0x3f, - 0x0a, 0x9f, 0x10, 0xaf, 0x19, 0xd2, 0xd5, 0xc2, 0x3c, 0x0a, 0x80, 0x95, - 0x02, 0x17, 0x18, 0x98, 0xe4, 0xdc, 0xe0, 0x61, 0xe0, 0x06, 0xe0, 0xa3, - 0xde, 0xef, 0x02, 0x7a, 0x53, 0xf3, 0x6a, 0x13, 0x18, 0x23, 0x10, 0x23, - 0x85, 0x4c, 0x8d, 0x40, 0x13, 0x53, 0xfd, 0x35, 0x3e, 0x87, 0xc7, 0x28, - 0x27, 0x61, 0x06, 0x86, 0xec, 0xa7, 0x9f, 0xf0, 0xb5, 0xc7, 0x10, 0xcf, - 0xa3, 0x33, 0xc3, 0xd7, 0x73, 0x7e, 0x8f, 0x0c, 0x75, 0xe1, 0x0c, 0xcd, - 0x03, 0xdf, 0xb1, 0x09, 0xd8, 0x59, 0x4a, 0xfd, 0x1e, 0x69, 0x1d, 0xa3, - 0xb3, 0x5e, 0x7d, 0xa9, 0xd7, 0x00, 0x93, 0xed, 0xa7, 0x2f, 0x34, 0xb3, - 0x9f, 0x72, 0x81, 0x8a, 0x62, 0x9e, 0x39, 0x48, 0x1c, 0x62, 0x40, 0xb2, - 0xbc, 0x8c, 0x79, 0xc2, 0x69, 0xa6, 0x9f, 0xd2, 0xa8, 0x9f, 0x42, 0x6c, - 0xa2, 0xd8, 0x84, 0xeb, 0xad, 0x11, 0x66, 0xfd, 0x18, 0xd2, 0xf0, 0x80, - 0x6c, 0x97, 0xf9, 0xb3, 0x86, 0x3d, 0x4f, 0x99, 0xcb, 0xab, 0xaa, 0x5f, - 0x96, 0x7c, 0x7a, 0x96, 0x28, 0x5f, 0x86, 0x2b, 0x40, 0x52, 0xa4, 0xa0, - 0x70, 0xc6, 0x77, 0x24, 0x77, 0xd7, 0x46, 0x71, 0x19, 0x63, 0x20, 0x0d, - 0x90, 0x72, 0x46, 0x5e, 0xf3, 0x55, 0xd2, 0xc7, 0x79, 0xc4, 0x61, 0xb1, - 0xe6, 0xbd, 0x9c, 0xf3, 0xac, 0xd9, 0x5e, 0x80, 0x49, 0x82, 0xeb, 0xbe, - 0xc6, 0xb5, 0x59, 0x2e, 0xaa, 0x90, 0xd1, 0x51, 0x4e, 0xe1, 0xb0, 0xc8, - 0xc4, 0x53, 0x99, 0x17, 0x16, 0x71, 0xbe, 0x15, 0x13, 0x44, 0xd2, 0x7c, - 0xeb, 0xc5, 0x37, 0x18, 0x5c, 0x34, 0xbb, 0x99, 0xfa, 0xb5, 0x76, 0xfd, - 0x0a, 0x66, 0xd2, 0xcc, 0x16, 0x4e, 0xb4, 0xb8, 0x81, 0xd3, 0xd7, 0x26, - 0xf3, 0x4d, 0x11, 0x06, 0x22, 0x9c, 0x65, 0xb8, 0x50, 0x44, 0x35, 0x78, - 0xe5, 0x50, 0x6d, 0xd2, 0x64, 0xab, 0x31, 0xc5, 0x7f, 0x95, 0x70, 0x6b, - 0xac, 0xdf, 0x9c, 0xd2, 0xbf, 0x7d, 0x12, 0x2f, 0x2d, 0xcc, 0xa9, 0xa3, - 0x40, 0xfe, 0x8b, 0xc2, 0x8c, 0xdd, 0x91, 0x9a, 0x9c, 0xe0, 0x43, 0x93, - 0xc4, 0xab, 0x9c, 0xf8, 0xb9, 0x75, 0xf0, 0xbe, 0xf1, 0x70, 0xdb, 0xda, - 0x6b, 0x1d, 0x6e, 0x7c, 0xdf, 0x92, 0x5d, 0x6c, 0x7a, 0x2a, 0xf1, 0x9a, - 0xd0, 0xad, 0xf3, 0xf2, 0x36, 0x7c, 0xcf, 0x8f, 0xa8, 0x0d, 0x08, 0x37, - 0x5f, 0x53, 0xd9, 0xc6, 0xc3, 0xa6, 0x35, 0x70, 0x89, 0x7b, 0x49, 0x78, - 0x86, 0x93, 0x31, 0xfd, 0x37, 0x8a, 0x27, 0x59, 0xa4, 0xa5, 0x84, 0x27, - 0xe6, 0x61, 0xf4, 0x84, 0xfe, 0x79, 0xbf, 0x7e, 0xb1, 0x37, 0xe9, 0xe7, - 0x37, 0xc8, 0xce, 0x05, 0x3a, 0x89, 0x77, 0x0b, 0x3d, 0x3d, 0xb6, 0xc8, - 0x79, 0x88, 0xc9, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x1e, 0x92, - 0x4d, 0xf7, 0x18, 0x00, 0x00, + 0xda, 0xa7, 0x24, 0x92, 0x92, 0x8f, 0x65, 0xaf, 0xbc, 0xae, 0x63, 0x8a, + 0x04, 0x25, 0x1c, 0xf3, 0x47, 0x0b, 0x40, 0xf2, 0x2a, 0x2e, 0x15, 0x0a, + 0x02, 0x86, 0xe4, 0x44, 0x00, 0x06, 0xc2, 0x0c, 0x45, 0x31, 0x77, 0x79, + 0x85, 0x54, 0x9e, 0x26, 0xcf, 0x93, 0x8b, 0x3c, 0x46, 0xbe, 0x1e, 0x00, + 0x14, 0x28, 0x73, 0xb5, 0xce, 0x5f, 0x25, 0x65, 0x11, 0xf3, 0xd3, 0xd3, + 0xdd, 0xf3, 0xf5, 0xd7, 0xdd, 0xb3, 0xef, 0x59, 0x2f, 0xcf, 0x59, 0x16, + 0xa6, 0x9c, 0xe9, 0x45, 0xa8, 0x99, 0x5a, 0xc8, 0x95, 0x62, 0x32, 0x63, + 0xfc, 0x9e, 0x17, 0x6b, 0x96, 0x87, 0x73, 0x4c, 0x08, 0x9d, 0x70, 0xab, + 0x77, 0x7e, 0x1e, 0x4c, 0x7a, 0x63, 0x9b, 0x7d, 0x60, 0xa7, 0x72, 0xae, + 0x8e, 0xf1, 0x2f, 0x3b, 0x15, 0x9a, 0x79, 0xbc, 0xb8, 0x17, 0x51, 0x39, + 0x3f, 0x9a, 0x9e, 0x4e, 0x31, 0x2f, 0xd2, 0x79, 0x67, 0x16, 0x62, 0x54, + 0x66, 0xed, 0x3c, 0x9b, 0x5b, 0xef, 0x59, 0x7f, 0x11, 0x66, 0x90, 0x84, + 0xe5, 0x62, 0xc6, 0xd6, 0x72, 0xc9, 0x8a, 0x65, 0xc6, 0x12, 0x19, 0x85, + 0x49, 0xb2, 0xb6, 0xdc, 0x8b, 0x49, 0x70, 0xe1, 0xd9, 0x2e, 0x76, 0xce, + 0x85, 0xc6, 0x6a, 0x5b, 0xe8, 0x05, 0x2f, 0x58, 0x2b, 0xe6, 0xf7, 0xad, + 0x3d, 0xd6, 0xca, 0x0b, 0x19, 0xb7, 0x98, 0xc4, 0x80, 0xe6, 0x4a, 0x63, + 0x24, 0xe6, 0xb3, 0x70, 0x99, 0x40, 0x96, 0x2a, 0xd7, 0x18, 0x09, 0xe3, + 0xe9, 0x80, 0x74, 0xc3, 0xb7, 0x65, 0x7d, 0x29, 0x78, 0x2e, 0x95, 0xd0, + 0xb2, 0x58, 0x5f, 0x5b, 0xee, 0x74, 0xea, 0x63, 0xc2, 0xf2, 0xfa, 0xae, + 0x73, 0xee, 0x07, 0xfe, 0xd5, 0x39, 0xad, 0xbb, 0x09, 0xd5, 0x02, 0x0b, + 0x15, 0xb4, 0xe7, 0xc5, 0xb5, 0x75, 0xee, 0x4e, 0xfd, 0x69, 0x7f, 0x3a, + 0xc2, 0xcc, 0x42, 0xeb, 0xdc, 0x1a, 0x4c, 0xc7, 0x3d, 0x67, 0x82, 0x2f, + 0xa3, 0xe4, 0x42, 0x2a, 0x6d, 0xe4, 0x04, 0x17, 0x2e, 0x2d, 0xf9, 0xfe, + 0x65, 0xbd, 0xfe, 0x95, 0x3a, 0xee, 0x74, 0xbe, 0x7f, 0x59, 0x2e, 0xc7, + 0xc7, 0xf7, 0x2f, 0xcf, 0x7c, 0xff, 0x3c, 0x38, 0x9f, 0xba, 0xfe, 0x2b, + 0xd5, 0xb1, 0xcc, 0x47, 0x6f, 0x30, 0x20, 0xdb, 0xac, 0xcd, 0x0c, 0x3e, + 0x5e, 0x77, 0xbb, 0x5d, 0xcb, 0xf3, 0xce, 0xea, 0xef, 0xc3, 0x43, 0xd8, + 0x3d, 0x10, 0x2a, 0xbc, 0x49, 0x38, 0xeb, 0x0f, 0x26, 0xe4, 0xff, 0x8c, + 0x89, 0xac, 0xb6, 0x3e, 0x95, 0x31, 0xb7, 0xa6, 0xc3, 0xe1, 0xc8, 0x99, + 0xd8, 0xb5, 0xa9, 0xb3, 0x30, 0x51, 0xdc, 0x1a, 0x38, 0x5e, 0xef, 0x64, + 0x64, 0x07, 0xee, 0xf4, 0xc2, 0xb7, 0x5d, 0xba, 0x82, 0xcd, 0xd4, 0x7b, + 0x76, 0xca, 0x33, 0x5e, 0x84, 0x9a, 0x33, 0xa5, 0x79, 0xae, 0x8e, 0x31, + 0xf2, 0x1d, 0x8b, 0x62, 0x5c, 0xab, 0x5e, 0x74, 0xb4, 0xec, 0xcc, 0x71, + 0x91, 0x9d, 0x68, 0xa9, 0xb4, 0x4c, 0x3b, 0x64, 0xb6, 0x32, 0x0b, 0xe6, + 0xd2, 0x5c, 0xcf, 0x77, 0xa7, 0x53, 0x32, 0xb9, 0xa3, 0x8a, 0xa8, 0x93, + 0xdf, 0xce, 0x3b, 0x51, 0xb1, 0xce, 0xb1, 0x47, 0x27, 0xaa, 0x33, 0xaf, + 0xc4, 0x06, 0x11, 0x2f, 0x74, 0x1b, 0xeb, 0xf7, 0xa3, 0xf0, 0x83, 0x2e, + 0x96, 0x9c, 0xed, 0xc7, 0x4b, 0x4c, 0x08, 0x99, 0x7d, 0x78, 0xf7, 0xf6, + 0xa8, 0xbb, 0xe8, 0xa6, 0x5d, 0xc5, 0xf6, 0xc9, 0x7d, 0x1f, 0xd2, 0x35, + 0xfd, 0x69, 0xf3, 0x87, 0x30, 0xcd, 0x13, 0xde, 0x8e, 0x64, 0x6a, 0xf5, + 0x6d, 0xd7, 0x0f, 0x86, 0xce, 0x88, 0x8c, 0x69, 0x6a, 0xd1, 0x31, 0x62, + 0x73, 0x9e, 0x5a, 0x9f, 0xec, 0xab, 0x9d, 0x0b, 0x6e, 0xf9, 0xda, 0xcc, + 0xbf, 0x67, 0x17, 0x79, 0x0e, 0xa8, 0x24, 0x70, 0x57, 0xc2, 0xe4, 0x8c, + 0x69, 0x0e, 0xe9, 0x64, 0x70, 0x98, 0xc5, 0x30, 0x1a, 0xaa, 0x44, 0x6c, + 0x26, 0xe0, 0x53, 0x32, 0x19, 0xcb, 0x1b, 0xd0, 0x01, 0xc6, 0xcc, 0x28, + 0x5b, 0x01, 0x6c, 0xdc, 0x80, 0x9a, 0x86, 0xf9, 0x03, 0x8f, 0x96, 0x9a, + 0xc7, 0x96, 0xe7, 0xf7, 0x7c, 0xa7, 0x1f, 0x98, 0x6b, 0x3f, 0xef, 0xf9, + 0x67, 0x74, 0x85, 0xd6, 0x97, 0x38, 0xd4, 0x21, 0xb0, 0xc3, 0xaf, 0x1b, + 0x38, 0x4d, 0xd7, 0xea, 0x2e, 0x31, 0x48, 0x85, 0x85, 0xf3, 0x82, 0xab, + 0x12, 0xad, 0x18, 0x14, 0x9a, 0xbf, 0xc6, 0x84, 0xd0, 0x3f, 0x28, 0x82, + 0x7d, 0xc1, 0xa2, 0x85, 0xa4, 0x60, 0x19, 0x9c, 0xd4, 0x38, 0x34, 0x7b, + 0xad, 0xb3, 0xa9, 0x47, 0x28, 0x38, 0x38, 0x7c, 0xdb, 0xee, 0xe2, 0x7f, + 0x07, 0xc7, 0xaf, 0x5f, 0x77, 0x8f, 0xac, 0x2a, 0xdc, 0xe8, 0x96, 0xac, + 0x2a, 0x40, 0x0a, 0x29, 0xb5, 0x75, 0xde, 0xf3, 0xbc, 0xcf, 0x03, 0xf6, + 0x01, 0x2a, 0x0c, 0xe9, 0xa0, 0xc6, 0xb1, 0x59, 0xb2, 0xde, 0x63, 0xbc, + 0x8e, 0x9f, 0x12, 0x4f, 0xa4, 0x59, 0xc1, 0xef, 0x96, 0xa2, 0xe0, 0xa5, + 0x62, 0x40, 0xbc, 0x98, 0xad, 0xf7, 0x67, 0xcb, 0x24, 0x69, 0x01, 0x84, + 0xa3, 0x4d, 0xec, 0x94, 0xeb, 0x6b, 0xb1, 0xb5, 0xfe, 0x46, 0xaa, 0x55, + 0xb9, 0x80, 0xec, 0x37, 0xb8, 0x69, 0xc7, 0x37, 0x70, 0x47, 0x18, 0xa7, + 0x22, 0xbb, 0x36, 0x81, 0x14, 0x2d, 0x0b, 0xa1, 0x11, 0x6f, 0xce, 0x04, + 0x9e, 0x1b, 0x8d, 0x80, 0xc4, 0xfe, 0xa7, 0x06, 0x14, 0x5f, 0xbc, 0xe8, + 0x9f, 0xf5, 0x26, 0xa7, 0x36, 0xf3, 0xcf, 0x1c, 0x8f, 0xf9, 0x53, 0xf6, + 0xc9, 0xb6, 0xcf, 0xd9, 0xd5, 0xf4, 0xc2, 0x65, 0xc6, 0xb6, 0x41, 0xcf, + 0xef, 0x31, 0xaf, 0x37, 0xb4, 0x5f, 0xbc, 0xb0, 0x3c, 0xbb, 0xef, 0xda, + 0x7e, 0x80, 0xdb, 0x87, 0x80, 0x17, 0xff, 0xf5, 0x71, 0x38, 0xb0, 0x3f, + 0xbb, 0xf8, 0xff, 0x7f, 0xff, 0xcf, 0x4b, 0x48, 0xea, 0x2d, 0xb5, 0xdc, + 0x4f, 0xe4, 0x1c, 0xd1, 0x51, 0xf0, 0x94, 0xa7, 0x37, 0xb0, 0x35, 0x0e, + 0xd7, 0xca, 0x02, 0xf6, 0x9d, 0x49, 0xe0, 0xda, 0x63, 0x7b, 0x7c, 0x82, + 0x50, 0x18, 0xf4, 0xae, 0x3c, 0xec, 0x7f, 0x6b, 0xf5, 0xa7, 0xd3, 0x4f, + 0x8e, 0x6d, 0x38, 0xa6, 0xe1, 0xd2, 0x20, 0x5c, 0x71, 0x25, 0x53, 0x5e, + 0x4f, 0x6f, 0xf6, 0x35, 0xd7, 0x88, 0x2c, 0x2a, 0x78, 0x2c, 0x4a, 0xaf, + 0xb8, 0x44, 0x8a, 0x0a, 0xa8, 0x29, 0xe4, 0xc3, 0x9a, 0x85, 0x4b, 0x78, + 0x39, 0x03, 0xc0, 0x0c, 0xde, 0xd9, 0x82, 0x87, 0x31, 0x14, 0x31, 0x54, + 0x0a, 0x20, 0x2e, 0xc1, 0x2c, 0xcc, 0x19, 0x58, 0xae, 0x7d, 0x69, 0xbb, + 0x9e, 0x1d, 0x80, 0x30, 0x7e, 0xb9, 0x0a, 0x7a, 0x17, 0xfe, 0x99, 0x3d, + 0x01, 0xac, 0x00, 0xad, 0x29, 0x58, 0xcf, 0xc1, 0x2d, 0xb2, 0x5f, 0xf6, + 0x3f, 0xdb, 0x27, 0x34, 0xb3, 0x8f, 0xef, 0x8a, 0x93, 0x00, 0x92, 0x6b, + 0xab, 0xd7, 0xf7, 0x9d, 0x4b, 0x3b, 0xe8, 0xe3, 0x76, 0x82, 0x11, 0xfd, + 0x1a, 0x3b, 0x13, 0x04, 0x39, 0x19, 0x75, 0xf0, 0xae, 0x0b, 0xd1, 0x9e, + 0x4d, 0xd0, 0x24, 0x30, 0xfc, 0xea, 0x22, 0x44, 0x08, 0x69, 0x92, 0x71, + 0x1e, 0x33, 0x2d, 0x19, 0x28, 0x79, 0x26, 0x8a, 0x94, 0xf1, 0xfd, 0x34, + 0x14, 0x09, 0x9b, 0xe1, 0x9e, 0x0b, 0x3e, 0x17, 0x4a, 0x97, 0x51, 0x0b, + 0x99, 0xa7, 0x8e, 0x47, 0x3c, 0x62, 0x83, 0xd0, 0x46, 0x90, 0x3a, 0x19, + 0x3a, 0xee, 0xb8, 0x71, 0x8d, 0x03, 0xc9, 0x15, 0xcb, 0xa4, 0x66, 0xa0, + 0x6e, 0xb9, 0xaa, 0x36, 0xe3, 0x00, 0x8a, 0x37, 0x03, 0x06, 0x06, 0x87, + 0x99, 0x00, 0x8c, 0x22, 0xb9, 0xcc, 0x74, 0x09, 0x9e, 0x0d, 0x49, 0x19, + 0xf1, 0xae, 0xb1, 0xbe, 0x21, 0xd4, 0xa8, 0x98, 0x22, 0xc0, 0x99, 0x12, + 0x73, 0x43, 0x7b, 0x50, 0xf5, 0x5e, 0xf0, 0x15, 0xc4, 0xae, 0xf5, 0x42, + 0x64, 0xf3, 0x36, 0x34, 0xfb, 0xf9, 0xc2, 0x71, 0xed, 0xc0, 0x73, 0x4e, + 0x27, 0xb8, 0xe5, 0x4b, 0xc7, 0xfe, 0xdc, 0x90, 0xd0, 0x0f, 0x23, 0x84, + 0x73, 0x78, 0x0f, 0x74, 0x42, 0x17, 0xc5, 0x72, 0x11, 0xe9, 0x65, 0xc1, + 0x2d, 0x7b, 0x62, 0xce, 0xed, 0xf7, 0xfa, 0x67, 0x76, 0xd0, 0xbb, 0x04, + 0xc6, 0xdc, 0xc6, 0xae, 0x31, 0xf9, 0x00, 0xc6, 0x88, 0x59, 0x75, 0x8b, + 0xf5, 0xfa, 0xc9, 0xd4, 0x77, 0x86, 0x57, 0x01, 0xf9, 0xa0, 0xb9, 0x5c, + 0x82, 0x27, 0x62, 0xae, 0xb1, 0xeb, 0xd8, 0xa4, 0x09, 0x22, 0x7f, 0xa4, + 0xac, 0xc5, 0xf2, 0x86, 0xf8, 0x8c, 0xc2, 0x42, 0x68, 0x55, 0xb2, 0xaa, + 0x50, 0x6a, 0xc9, 0x55, 0xe7, 0xe0, 0xe8, 0x4d, 0x2d, 0xf3, 0x39, 0x24, + 0x6c, 0x0e, 0xb1, 0xbe, 0xac, 0xf8, 0xcd, 0x42, 0xca, 0x5b, 0xe2, 0x97, + 0x7e, 0x01, 0x5c, 0xe9, 0x50, 0xdd, 0xc2, 0x23, 0xf0, 0xf1, 0x7d, 0x98, + 0x90, 0x6b, 0xe0, 0x63, 0xf0, 0x93, 0xb2, 0xfc, 0x9e, 0xf7, 0x29, 0x70, + 0x26, 0xb8, 0xac, 0xcb, 0x1e, 0x69, 0x79, 0x40, 0xb7, 0xc3, 0x13, 0x01, + 0x8c, 0x22, 0x65, 0xa7, 0x5c, 0x2e, 0x35, 0x2d, 0x47, 0x60, 0xca, 0x2c, + 0x56, 0xd6, 0xc0, 0x26, 0x74, 0xb8, 0x81, 0xef, 0x8c, 0x6d, 0xa4, 0x0a, + 0x6c, 0x78, 0x83, 0xd3, 0x08, 0x05, 0x94, 0xff, 0x4a, 0x1d, 0x07, 0x0d, + 0x63, 0x4f, 0x96, 0xb3, 0x99, 0x61, 0xd6, 0x6c, 0x0e, 0x8e, 0x04, 0xa2, + 0x23, 0xe4, 0xf0, 0x8c, 0x27, 0x7b, 0xec, 0x96, 0xf3, 0x9c, 0x52, 0x39, + 0xdc, 0x2c, 0x0c, 0x93, 0x56, 0x39, 0x3d, 0x96, 0xd9, 0x0f, 0x9a, 0xdd, + 0x66, 0x80, 0xc5, 0x8a, 0x6a, 0x09, 0x33, 0xd9, 0x46, 0x30, 0x4f, 0x06, + 0xc1, 0xc9, 0xc5, 0x70, 0x48, 0xd9, 0xc9, 0x26, 0x53, 0x0f, 0x08, 0x96, + 0x13, 0x0a, 0x14, 0x30, 0x0e, 0xe8, 0x7a, 0x0d, 0x6c, 0x92, 0x61, 0x74, + 0x1b, 0x65, 0xb1, 0xe1, 0x5d, 0x9c, 0xfc, 0xbf, 0xdd, 0xf7, 0x4d, 0xaa, + 0xad, 0x0b, 0x8f, 0x57, 0xaa, 0xbe, 0xb1, 0x32, 0x69, 0x53, 0x7a, 0x4b, + 0xcd, 0x55, 0xa8, 0x54, 0xe7, 0xed, 0x39, 0xfd, 0xa6, 0x6b, 0x38, 0x7e, + 0xf3, 0xee, 0x2d, 0xe6, 0x7e, 0xfe, 0xb9, 0x9a, 0xb8, 0xbb, 0x33, 0xa3, + 0x87, 0x6f, 0x6a, 0x96, 0xad, 0xc5, 0xcc, 0x0a, 0x99, 0x02, 0xb3, 0x31, + 0x98, 0x53, 0x59, 0x43, 0x77, 0x3a, 0x7e, 0x9c, 0x83, 0xe1, 0x26, 0x80, + 0x4d, 0x34, 0x13, 0xb4, 0xf3, 0x50, 0xa9, 0x95, 0x2c, 0xe2, 0x9a, 0x87, + 0x37, 0x1c, 0x4c, 0x39, 0x41, 0x12, 0x15, 0x7c, 0xed, 0xc3, 0x6a, 0xa2, + 0x5d, 0x22, 0xe4, 0xeb, 0xf9, 0xfe, 0xc8, 0x01, 0x02, 0x02, 0xc3, 0x01, + 0xf5, 0x47, 0xc9, 0x7c, 0x65, 0xb9, 0x32, 0x3d, 0x37, 0x51, 0x5c, 0x03, + 0x2d, 0xcc, 0x45, 0xbb, 0x01, 0x36, 0xd2, 0xcf, 0x22, 0x14, 0x55, 0x35, + 0xc9, 0x0e, 0x3c, 0x1a, 0x8e, 0xec, 0x18, 0x25, 0x3a, 0xf4, 0x8f, 0x2c, + 0xc4, 0x1f, 0xb8, 0xe5, 0x4f, 0x3f, 0xd9, 0x93, 0x6f, 0xdc, 0x14, 0x45, + 0xf0, 0x4d, 0xa0, 0xe5, 0x2d, 0xcf, 0x2c, 0x53, 0x4e, 0x68, 0x16, 0x25, + 0x02, 0xac, 0xc7, 0x44, 0x5c, 0xa6, 0x58, 0x8e, 0x70, 0xd7, 0xc6, 0x95, + 0x98, 0xaf, 0xc5, 0x01, 0x71, 0x4a, 0x22, 0xc9, 0xc7, 0x94, 0x96, 0x25, + 0x12, 0xb4, 0x42, 0x91, 0x20, 0xe7, 0x65, 0xda, 0xef, 0x80, 0x3e, 0x7f, + 0xcf, 0x23, 0xbd, 0x71, 0x8f, 0x99, 0xf9, 0x97, 0xdd, 0xb3, 0x5a, 0xad, + 0x2a, 0x51, 0x70, 0x94, 0x32, 0x07, 0x19, 0x1b, 0xc8, 0x4f, 0x22, 0x9b, + 0xc9, 0x36, 0x37, 0xf8, 0xfa, 0xe6, 0xe5, 0xd0, 0x92, 0x0a, 0x87, 0x5d, + 0x2e, 0xae, 0xa8, 0x6d, 0xcb, 0x28, 0x59, 0xba, 0xec, 0xd0, 0x48, 0xd9, + 0xe9, 0xe3, 0x67, 0x77, 0x55, 0x2e, 0xae, 0x5c, 0x72, 0x77, 0xf7, 0x4f, + 0xbb, 0x03, 0xb4, 0x6c, 0xc0, 0xcf, 0xfe, 0xfa, 0x97, 0x3f, 0xfd, 0xed, + 0x8f, 0x7f, 0xa6, 0x74, 0xb9, 0x03, 0x23, 0x45, 0x98, 0x2f, 0xaa, 0xc0, + 0xa8, 0x34, 0x68, 0x77, 0x1b, 0x10, 0x79, 0xcf, 0x76, 0x82, 0x64, 0xe7, + 0xae, 0x52, 0x73, 0xec, 0xe0, 0x59, 0x44, 0xc0, 0x58, 0x71, 0x71, 0x23, + 0x77, 0x79, 0x0d, 0x38, 0xc8, 0xda, 0xba, 0xde, 0x1f, 0xcd, 0xc5, 0xfe, + 0x4d, 0x0d, 0xb4, 0xc3, 0xdf, 0x80, 0xe7, 0xf3, 0x5b, 0xb7, 0x40, 0x5a, + 0x79, 0x50, 0xaf, 0x84, 0xd6, 0xbb, 0x88, 0xed, 0x1f, 0x70, 0xe3, 0xae, + 0x9b, 0x47, 0x0c, 0x56, 0xa2, 0x1f, 0xbd, 0xf0, 0x1b, 0xca, 0xff, 0xca, + 0x9e, 0x5d, 0x5a, 0x1b, 0xdf, 0xfd, 0x27, 0x74, 0x36, 0x82, 0x1b, 0xf7, + 0xf6, 0x0d, 0x2a, 0x7f, 0xbd, 0x65, 0x5b, 0xe3, 0x88, 0x32, 0xee, 0x56, + 0x15, 0xcc, 0x53, 0xf4, 0x5b, 0x65, 0xb1, 0x09, 0x5e, 0xc7, 0x0f, 0x59, + 0x8e, 0x9a, 0x95, 0x4f, 0xda, 0xb6, 0x6a, 0xb1, 0xd5, 0x1b, 0xf4, 0xce, + 0x7d, 0xc3, 0xa8, 0xe5, 0x48, 0x5d, 0x7b, 0x56, 0xf3, 0x55, 0x41, 0x7b, + 0xda, 0xdf, 0xca, 0x80, 0x55, 0x4a, 0xdb, 0x92, 0x78, 0xd4, 0xb5, 0x1a, + 0xb9, 0xf0, 0xa8, 0x5b, 0x0b, 0x2a, 0x75, 0x31, 0x5c, 0xd5, 0xd4, 0x05, + 0x02, 0x32, 0x70, 0x90, 0x29, 0xdc, 0x50, 0x3d, 0x6f, 0xd2, 0xc0, 0x7b, + 0x66, 0x36, 0x1c, 0xb3, 0xd6, 0xf1, 0x51, 0xf7, 0xf5, 0x8f, 0x2d, 0x0c, + 0xd4, 0xbb, 0x30, 0xf6, 0x58, 0x9f, 0x1f, 0x1c, 0x1c, 0x1e, 0x1c, 0xb4, + 0xaa, 0x8c, 0x62, 0x6a, 0x36, 0xa5, 0x20, 0x6c, 0xb7, 0x3f, 0x88, 0x47, + 0x1e, 0xfd, 0x52, 0xba, 0xa5, 0x6a, 0x19, 0x76, 0xf9, 0x04, 0x05, 0xc2, + 0xa5, 0x33, 0x30, 0x4e, 0x31, 0x0c, 0xf4, 0x9e, 0x9d, 0x17, 0xf2, 0x5e, + 0x50, 0x75, 0x69, 0xca, 0xb7, 0x39, 0x93, 0x39, 0x69, 0xae, 0x4a, 0xe5, + 0xb0, 0xe7, 0xd8, 0x54, 0x64, 0x8b, 0xf0, 0x9e, 0x92, 0xd5, 0xba, 0x5e, + 0xb5, 0xe6, 0xd4, 0x4c, 0x93, 0x08, 0x64, 0xc2, 0x52, 0xbf, 0xc7, 0x5e, + 0x08, 0x5d, 0x42, 0x7b, 0xde, 0x46, 0x8f, 0x40, 0xf5, 0x7c, 0x35, 0xab, + 0x5a, 0x8f, 0xf6, 0x57, 0x32, 0x12, 0x71, 0xcb, 0xcb, 0xa1, 0x2a, 0xeb, + 0x1a, 0x4f, 0xed, 0xb1, 0x5c, 0xca, 0xc4, 0x03, 0x7c, 0xf6, 0x36, 0x99, + 0xb1, 0x16, 0xf8, 0xe8, 0xa3, 0xa3, 0xd7, 0x6f, 0x7f, 0xdc, 0x3b, 0xe8, + 0x76, 0xf7, 0x42, 0x34, 0x62, 0x0f, 0x82, 0x1b, 0x67, 0x92, 0xdd, 0xc7, + 0xa8, 0xad, 0xf7, 0xf1, 0x77, 0x3f, 0x2e, 0xa8, 0x5a, 0xe9, 0x98, 0x41, + 0x16, 0xab, 0xac, 0x3e, 0x15, 0xe5, 0x28, 0x6a, 0xbe, 0x5a, 0x22, 0xf5, + 0x3c, 0xc7, 0xf5, 0x31, 0x1f, 0x6b, 0x65, 0x03, 0x6d, 0x7a, 0x9b, 0x8d, + 0xb7, 0xca, 0x5a, 0xf5, 0xb4, 0x6e, 0x51, 0x6a, 0x93, 0x70, 0xa6, 0x57, + 0xd9, 0x1e, 0xa1, 0xac, 0x12, 0xdc, 0xe4, 0xf4, 0xba, 0xe6, 0xaf, 0x4a, + 0x7d, 0x11, 0x90, 0x9d, 0x41, 0x59, 0xbf, 0x61, 0x87, 0x53, 0x16, 0x34, + 0xc8, 0x05, 0x1b, 0xc7, 0x01, 0x76, 0x26, 0x3a, 0x2a, 0x44, 0x36, 0xee, + 0xad, 0x8a, 0xd1, 0x52, 0x20, 0xc2, 0xf2, 0xc2, 0xb5, 0x1b, 0x65, 0x94, + 0x9d, 0x99, 0x96, 0x5e, 0x51, 0xe6, 0x34, 0xe7, 0x6f, 0xed, 0xa5, 0x9e, + 0xb9, 0xae, 0x0f, 0xa9, 0x98, 0x2f, 0xa5, 0x60, 0xbb, 0x99, 0x78, 0x54, + 0x1d, 0x01, 0x40, 0x25, 0xdd, 0x26, 0x0a, 0xb6, 0x84, 0xbc, 0x3b, 0xfa, + 0xdf, 0x6e, 0xd7, 0x3a, 0xed, 0x6f, 0x8a, 0x41, 0x53, 0xe3, 0x41, 0x48, + 0x39, 0xf1, 0x28, 0x25, 0x11, 0x33, 0x6e, 0xe4, 0xec, 0xd8, 0xee, 0xd9, + 0x9e, 0x47, 0x2d, 0xc9, 0xc8, 0x19, 0xda, 0x4f, 0xf7, 0x6f, 0x7c, 0x10, + 0x03, 0x63, 0x6a, 0xc1, 0x66, 0xcb, 0x2c, 0xda, 0xdb, 0xe0, 0x5c, 0x2d, + 0xc2, 0x03, 0x42, 0x37, 0xfe, 0x1e, 0xbe, 0x39, 0xaa, 0xe0, 0x1d, 0xbf, + 0x69, 0x35, 0xcf, 0xa0, 0x35, 0x9b, 0x23, 0x9c, 0x41, 0x70, 0xd6, 0xf3, + 0xce, 0x86, 0x17, 0x93, 0x3e, 0x0e, 0x31, 0x53, 0x8f, 0x3a, 0x9a, 0x03, + 0xd0, 0xde, 0x6f, 0xa9, 0x48, 0x17, 0x51, 0x20, 0x84, 0x51, 0xaf, 0x95, + 0xd0, 0x78, 0x2a, 0xcb, 0x74, 0x8a, 0x08, 0xc3, 0xaa, 0xec, 0xa7, 0x30, + 0xf4, 0xa9, 0xbd, 0x4f, 0xc2, 0x88, 0x53, 0x2f, 0x51, 0x8d, 0x1b, 0x68, + 0x3c, 0xf6, 0xc7, 0x25, 0xa2, 0x4b, 0x8d, 0xef, 0x44, 0x26, 0x96, 0x4f, + 0x02, 0xb2, 0x9a, 0xc7, 0x61, 0xee, 0xa5, 0xd3, 0x27, 0x8f, 0x54, 0x95, + 0x67, 0xdd, 0xce, 0x9c, 0xba, 0x4f, 0x5a, 0x0a, 0xeb, 0x0b, 0xca, 0xa7, + 0xf2, 0xc9, 0xa9, 0x7a, 0x33, 0x68, 0x10, 0x42, 0x55, 0x15, 0x35, 0x19, + 0x81, 0x68, 0xc8, 0xf8, 0x0e, 0x85, 0x6a, 0xa9, 0x47, 0xfd, 0xbe, 0xf0, + 0x44, 0x95, 0x7a, 0x6f, 0xd9, 0x2c, 0x01, 0x4a, 0x69, 0x1a, 0x92, 0x61, + 0x8a, 0xe7, 0xa1, 0x79, 0xe0, 0x49, 0xb1, 0x52, 0xe4, 0x40, 0x1a, 0xbd, + 0x14, 0xa9, 0x3a, 0x74, 0xaa, 0x6d, 0x7b, 0x26, 0xee, 0x5b, 0x56, 0xd5, + 0xe7, 0x57, 0xa3, 0xff, 0xce, 0x22, 0xff, 0x49, 0x7d, 0xdf, 0x35, 0xb8, + 0xa9, 0x0d, 0xf7, 0x0b, 0x5c, 0x03, 0x99, 0x39, 0xe0, 0x37, 0xcb, 0x39, + 0xfd, 0x70, 0x50, 0x61, 0xd1, 0xdf, 0xcf, 0x61, 0x61, 0xec, 0xb7, 0x8b, + 0x42, 0x16, 0xf4, 0xa3, 0x5f, 0x08, 0xea, 0xa8, 0x9f, 0x52, 0x63, 0x29, + 0xc1, 0x1a, 0xa1, 0x85, 0x22, 0x7a, 0x37, 0x9f, 0x56, 0x4d, 0xf1, 0xb5, + 0x6f, 0x8c, 0xe9, 0x65, 0xbf, 0x49, 0xd7, 0xd0, 0xae, 0xc6, 0xaf, 0x37, + 0xdb, 0x36, 0x3b, 0x8c, 0x37, 0x9e, 0x2e, 0xa7, 0xc1, 0xc6, 0x5a, 0x7a, + 0x76, 0xaa, 0xf9, 0x01, 0xd3, 0xe5, 0x9b, 0x07, 0x7e, 0x18, 0x68, 0xd1, + 0x3b, 0x91, 0x09, 0x6c, 0x45, 0xcf, 0x00, 0x32, 0xc5, 0x0d, 0xc4, 0xb4, + 0x8a, 0x15, 0x52, 0xe3, 0xf7, 0x4b, 0x85, 0x7c, 0x1f, 0x19, 0x87, 0xce, + 0x24, 0xf5, 0xc9, 0x80, 0x6c, 0x4d, 0xda, 0xaf, 0xbe, 0x26, 0x80, 0xd1, + 0xf4, 0x34, 0x70, 0xa7, 0x7e, 0xcf, 0x6f, 0x44, 0xfe, 0x38, 0x7c, 0x40, + 0xbc, 0x66, 0xa0, 0xab, 0xa5, 0x79, 0xe0, 0x80, 0x28, 0x05, 0x29, 0xb8, + 0x60, 0xd2, 0x73, 0x4b, 0x86, 0x71, 0x37, 0x1c, 0x3e, 0xee, 0xfd, 0x12, + 0xd0, 0xfb, 0xa0, 0x57, 0x5f, 0x81, 0xb9, 0x04, 0x12, 0xa4, 0xc0, 0xd4, + 0x08, 0x34, 0x31, 0xd3, 0xcf, 0xc9, 0x39, 0x7c, 0x87, 0x74, 0x12, 0x66, + 0x10, 0xc8, 0x7e, 0xfa, 0x09, 0x5f, 0x7b, 0x0c, 0xf1, 0x3c, 0x3e, 0x31, + 0x72, 0x3d, 0xe7, 0x77, 0x60, 0xa8, 0x33, 0x67, 0x68, 0x1e, 0x2b, 0xdf, + 0x99, 0x80, 0x9d, 0xa7, 0x54, 0xef, 0x91, 0xd5, 0x31, 0x2a, 0xeb, 0xf5, + 0xd7, 0x76, 0x0d, 0xd0, 0x3e, 0x5f, 0x7d, 0x65, 0x99, 0xfd, 0x90, 0x0b, + 0x64, 0x14, 0xf3, 0x64, 0x43, 0xea, 0x90, 0x00, 0xd2, 0xe5, 0x65, 0xcc, + 0x13, 0x4e, 0x0f, 0x07, 0x33, 0x7a, 0x4f, 0x48, 0xa1, 0x36, 0xad, 0xd8, + 0x76, 0xd7, 0x5b, 0xa3, 0xcc, 0xe6, 0x61, 0xa7, 0x81, 0x80, 0x6c, 0xd7, + 0xf5, 0x67, 0x8d, 0xfb, 0xa4, 0xe7, 0x9b, 0x2a, 0xeb, 0x97, 0x29, 0x9f, + 0xde, 0x3e, 0xca, 0x57, 0xee, 0xca, 0x21, 0x29, 0x28, 0x28, 0x9c, 0xf3, + 0x1d, 0xe4, 0xee, 0xda, 0x48, 0x2e, 0x13, 0x34, 0xa4, 0x01, 0x28, 0x67, + 0xec, 0x35, 0x5f, 0x58, 0x7d, 0xec, 0x47, 0x1c, 0x16, 0x1b, 0xd9, 0xab, + 0x05, 0xcf, 0x9a, 0xe5, 0x05, 0x84, 0x24, 0x38, 0xee, 0x39, 0xa9, 0xcd, + 0x74, 0x51, 0x85, 0x8c, 0x8e, 0x72, 0x0a, 0x87, 0x65, 0x26, 0x1e, 0x4a, + 0x5e, 0x58, 0xc6, 0xf9, 0x93, 0x98, 0xa0, 0x25, 0xcd, 0x77, 0x6b, 0x7c, + 0x43, 0xc0, 0x59, 0xb3, 0x9a, 0xa9, 0x5f, 0x9e, 0x37, 0x2f, 0x7a, 0x86, + 0x66, 0x9e, 0xf8, 0x89, 0x06, 0xb7, 0xfc, 0xf4, 0x5c, 0x67, 0xbe, 0xad, + 0xc2, 0x40, 0x84, 0xf3, 0x0c, 0x07, 0x8a, 0xa8, 0x76, 0x5e, 0xd9, 0x54, + 0x1b, 0x9a, 0x6c, 0x35, 0xba, 0xf8, 0x67, 0x17, 0x3e, 0x69, 0xeb, 0xb7, + 0xbb, 0xf4, 0x6f, 0xef, 0xc4, 0xcb, 0x1b, 0xe6, 0x54, 0x51, 0x80, 0xff, + 0xa2, 0x30, 0x63, 0x37, 0x64, 0x26, 0x27, 0xf7, 0xa1, 0x48, 0xe2, 0x15, + 0x27, 0x7e, 0x69, 0x1d, 0x7c, 0x6c, 0x3c, 0x42, 0xb7, 0xf6, 0x5a, 0x87, + 0x5b, 0xdf, 0xd7, 0x74, 0x2f, 0x36, 0x3d, 0x95, 0x78, 0x4d, 0xd7, 0x6d, + 0x78, 0xf9, 0xa9, 0xfb, 0x1e, 0x1f, 0x84, 0x1b, 0x2e, 0xdc, 0x7e, 0x19, + 0x66, 0x5b, 0x8f, 0xb4, 0xd6, 0xc0, 0x25, 0xe9, 0xe5, 0xc2, 0x13, 0xec, + 0x8c, 0xe9, 0xbf, 0xb7, 0x3c, 0xc8, 0x22, 0x2d, 0x35, 0x3c, 0x36, 0x8f, + 0xbc, 0xc7, 0xf4, 0xcf, 0xc7, 0xcd, 0x7f, 0x7d, 0x30, 0xf4, 0xf3, 0x7f, + 0x60, 0xe7, 0x02, 0x95, 0xc4, 0x87, 0xa5, 0x9e, 0xbd, 0xb3, 0x08, 0x3c, + 0x24, 0xe4, 0xef, 0x01, 0x00, 0x00, 0xff, 0xff, 0xca, 0xc7, 0x79, 0x5b, + 0xc3, 0x19, 0x00, 0x00, }, "conf/app.ini", ) diff --git a/modules/middleware/context.go b/modules/middleware/context.go index 8c837d08..19556118 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -358,7 +358,7 @@ func InitContext() martini.Handler { }) // Get user from session if logined. - user := auth.SignedInUser(ctx.Session) + user := auth.SignedInUser(ctx.req.Header, ctx.Session) ctx.User = user ctx.IsSigned = user != nil diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 93e02210..12989963 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -47,11 +47,12 @@ var ( StaticRootPath string // Security settings. - InstallLock bool - SecretKey string - LogInRememberDays int - CookieUserName string - CookieRememberName string + InstallLock bool + SecretKey string + LogInRememberDays int + CookieUserName string + CookieRememberName string + ReverseProxyAuthUid string // Webhook settings. WebhookTaskInterval int @@ -163,6 +164,7 @@ func NewConfigContext() { LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS") CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME") CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME") + ReverseProxyAuthUid = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_UID", "X-WEBAUTH-UID") RunUser = Cfg.MustValue("", "RUN_USER") curUser := os.Getenv("USER") @@ -191,14 +193,15 @@ func NewConfigContext() { } var Service struct { - RegisterEmailConfirm bool - DisableRegistration bool - RequireSignInView bool - EnableCacheAvatar bool - NotifyMail bool - LdapAuth bool - ActiveCodeLives int - ResetPwdCodeLives int + RegisterEmailConfirm bool + DisableRegistration bool + RequireSignInView bool + EnableCacheAvatar bool + EnableNotifyMail bool + EnableReverseProxyAuth bool + LdapAuth bool + ActiveCodeLives int + ResetPwdCodeLives int } func newService() { @@ -207,6 +210,7 @@ func newService() { Service.DisableRegistration = Cfg.MustBool("service", "DISABLE_REGISTRATION") Service.RequireSignInView = Cfg.MustBool("service", "REQUIRE_SIGNIN_VIEW") Service.EnableCacheAvatar = Cfg.MustBool("service", "ENABLE_CACHE_AVATAR") + Service.EnableReverseProxyAuth = Cfg.MustBool("service", "ENABLE_REVERSE_PROXY_AUTHENTICATION") } var logLevels = map[string]string{ @@ -395,7 +399,7 @@ func newNotifyMailService() { log.Warn("Notify Mail Service: Mail Service is not enabled") return } - Service.NotifyMail = true + Service.EnableNotifyMail = true log.Info("Notify Mail Service Enabled") } diff --git a/modules/social/social.go b/modules/social/social.go index 62f4d518..326a463f 100644 --- a/modules/social/social.go +++ b/modules/social/social.go @@ -120,7 +120,7 @@ type SocialGithub struct { } func (s *SocialGithub) Type() int { - return models.OT_GITHUB + return int(models.GITHUB) } func newGitHubOauth(config *oauth.Config) { @@ -174,7 +174,7 @@ type SocialGoogle struct { } func (s *SocialGoogle) Type() int { - return models.OT_GOOGLE + return int(models.GOOGLE) } func newGoogleOauth(config *oauth.Config) { @@ -229,7 +229,7 @@ type SocialTencent struct { } func (s *SocialTencent) Type() int { - return models.OT_QQ + return int(models.QQ) } func newTencentOauth(config *oauth.Config) { @@ -295,7 +295,7 @@ type SocialTwitter struct { } func (s *SocialTwitter) Type() int { - return models.OT_TWITTER + return int(models.TWITTER) } func newTwitterOauth(config *oauth.Config) { @@ -351,7 +351,7 @@ type SocialWeibo struct { } func (s *SocialWeibo) Type() int { - return models.OT_WEIBO + return int(models.WEIBO) } func newWeiboOauth(config *oauth.Config) { diff --git a/routers/admin/admin.go b/routers/admin/admin.go index a14ffae0..1567a300 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -102,8 +102,11 @@ func updateSystemStatus() { } // Operation types. +type AdminOperation int + const ( - OT_CLEAN_OAUTH = iota + 1 + CLEAN_UNBIND_OAUTH AdminOperation = iota + 1 + CLEAN_INACTIVATE_USER ) func Dashboard(ctx *middleware.Context) { @@ -116,10 +119,13 @@ func Dashboard(ctx *middleware.Context) { var err error var success string - switch op { - case OT_CLEAN_OAUTH: + switch AdminOperation(op) { + case CLEAN_UNBIND_OAUTH: success = "All unbind OAuthes have been deleted." err = models.CleanUnbindOauth() + case CLEAN_INACTIVATE_USER: + success = "All inactivate accounts have been deleted." + err = models.DeleteInactivateUsers() } if err != nil { @@ -190,6 +196,7 @@ func Config(ctx *middleware.Context) { ctx.Data["StaticRootPath"] = setting.StaticRootPath ctx.Data["LogRootPath"] = setting.LogRootPath ctx.Data["ScriptType"] = setting.ScriptType + ctx.Data["ReverseProxyAuthUid"] = setting.ReverseProxyAuthUid ctx.Data["Service"] = setting.Service diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 808fb52b..11c573f5 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -250,7 +250,7 @@ func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.C } // Mail watchers and mentions. - if setting.Service.NotifyMail { + if setting.Service.EnableNotifyMail { tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue) if err != nil { ctx.Handle(500, "issue.CreateIssue(SendIssueNotifyMail)", err) @@ -685,7 +685,7 @@ func Comment(ctx *middleware.Context, params martini.Params) { } // Mail watchers and mentions. - if setting.Service.NotifyMail { + if setting.Service.EnableNotifyMail { issue.Content = content tos, err := mailer.SendIssueNotifyMail(ctx.User, ctx.Repo.Owner, ctx.Repo.Repository, issue) if err != nil { diff --git a/routers/repo/setting.go b/routers/repo/setting.go index ac9ce7c7..6313971c 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -192,7 +192,7 @@ func CollaborationPost(ctx *middleware.Context) { return } - if setting.Service.NotifyMail { + if setting.Service.EnableNotifyMail { if err = mailer.SendCollaboratorMail(ctx.Render, u, ctx.User, ctx.Repo.Repository); err != nil { ctx.Handle(500, "setting.CollaborationPost(SendCollaboratorMail)", err) return diff --git a/templates/VERSION b/templates/VERSION index 0848cb02..7d143dcc 100644 --- a/templates/VERSION +++ b/templates/VERSION @@ -1 +1 @@ -0.4.4.0620 Alpha \ No newline at end of file +0.4.5.0621 Alpha \ No newline at end of file diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 583ee25e..22be5900 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -36,6 +36,8 @@
{{.LogRootPath}}
Script Type
{{.ScriptType}}
+
Reverse Authentication UID
+
{{.ReverseProxyAuthUid}}
@@ -77,7 +79,7 @@
Require Sign In View
Mail Notification
-
+
Enable Cache Avatar

diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl index f709cb3f..aa2080d8 100644 --- a/templates/admin/dashboard.tmpl +++ b/templates/admin/dashboard.tmpl @@ -32,6 +32,10 @@ Clean unbind OAuthes Run + + Delete inactivate accounts + Run + -- cgit v1.2.3 From 9924e65ca11770f247723b10fcbdb81dc9534b32 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 22 Jun 2014 13:14:03 -0400 Subject: In progress of name template name constant --- modules/base/base.go | 1 + modules/mailer/mail.go | 19 ++- modules/middleware/context.go | 8 +- routers/admin/admin.go | 27 ++-- routers/admin/auth.go | 201 +++++++++++++++++++++++++++ routers/admin/auths.go | 196 -------------------------- routers/admin/user.go | 48 ++++--- routers/dashboard.go | 7 +- routers/dev/template.go | 3 +- routers/install.go | 26 ++-- routers/repo/repo.go | 2 +- templates/admin/auth/edit.tmpl | 165 ++++++++++++++++++++++ templates/admin/auth/new.tmpl | 178 ++++++++++++++++++++++++ templates/admin/auths/edit.tmpl | 165 ---------------------- templates/admin/auths/new.tmpl | 178 ------------------------ templates/admin/user/edit.tmpl | 103 ++++++++++++++ templates/admin/user/new.tmpl | 94 +++++++++++++ templates/admin/users/edit.tmpl | 103 -------------- templates/admin/users/new.tmpl | 94 ------------- templates/issue/create.tmpl | 112 --------------- templates/issue/list.tmpl | 116 ---------------- templates/issue/milestone.tmpl | 43 ------ templates/issue/milestone_edit.tmpl | 61 --------- templates/issue/milestone_new.tmpl | 62 --------- templates/issue/view.tmpl | 228 ------------------------------- templates/mail/auth/active.tmpl | 33 +++++ templates/mail/auth/active_email.tmpl | 33 ----- templates/release/edit.tmpl | 70 ---------- templates/release/list.tmpl | 62 --------- templates/release/new.tmpl | 70 ---------- templates/repo/issue/create.tmpl | 112 +++++++++++++++ templates/repo/issue/list.tmpl | 116 ++++++++++++++++ templates/repo/issue/milestone.tmpl | 43 ++++++ templates/repo/issue/milestone_edit.tmpl | 61 +++++++++ templates/repo/issue/milestone_new.tmpl | 62 +++++++++ templates/repo/issue/view.tmpl | 228 +++++++++++++++++++++++++++++++ templates/repo/release/edit.tmpl | 70 ++++++++++ templates/repo/release/list.tmpl | 62 +++++++++ templates/repo/release/new.tmpl | 70 ++++++++++ 39 files changed, 1688 insertions(+), 1644 deletions(-) create mode 100644 routers/admin/auth.go delete mode 100644 routers/admin/auths.go create mode 100644 templates/admin/auth/edit.tmpl create mode 100644 templates/admin/auth/new.tmpl delete mode 100644 templates/admin/auths/edit.tmpl delete mode 100644 templates/admin/auths/new.tmpl create mode 100644 templates/admin/user/edit.tmpl create mode 100644 templates/admin/user/new.tmpl delete mode 100644 templates/admin/users/edit.tmpl delete mode 100644 templates/admin/users/new.tmpl delete mode 100644 templates/issue/create.tmpl delete mode 100644 templates/issue/list.tmpl delete mode 100644 templates/issue/milestone.tmpl delete mode 100644 templates/issue/milestone_edit.tmpl delete mode 100644 templates/issue/milestone_new.tmpl delete mode 100644 templates/issue/view.tmpl create mode 100644 templates/mail/auth/active.tmpl delete mode 100644 templates/mail/auth/active_email.tmpl delete mode 100644 templates/release/edit.tmpl delete mode 100644 templates/release/list.tmpl delete mode 100644 templates/release/new.tmpl create mode 100644 templates/repo/issue/create.tmpl create mode 100644 templates/repo/issue/list.tmpl create mode 100644 templates/repo/issue/milestone.tmpl create mode 100644 templates/repo/issue/milestone_edit.tmpl create mode 100644 templates/repo/issue/milestone_new.tmpl create mode 100644 templates/repo/issue/view.tmpl create mode 100644 templates/repo/release/edit.tmpl create mode 100644 templates/repo/release/list.tmpl create mode 100644 templates/repo/release/new.tmpl (limited to 'modules/middleware') diff --git a/modules/base/base.go b/modules/base/base.go index 145fae6f..570600c3 100644 --- a/modules/base/base.go +++ b/modules/base/base.go @@ -7,6 +7,7 @@ package base type ( // Type TmplData represents data in the templates. TmplData map[string]interface{} + TplName string ApiJsonErr struct { Message string `json:"message"` diff --git a/modules/mailer/mail.go b/modules/mailer/mail.go index e212d006..62e15cd7 100644 --- a/modules/mailer/mail.go +++ b/modules/mailer/mail.go @@ -17,6 +17,15 @@ import ( "github.com/gogits/gogs/modules/setting" ) +const ( + AUTH_ACTIVE base.TplName = "mail/auth/active" + AUTH_REGISTER_SUCCESS base.TplName = "mail/auth/register_success" + AUTH_RESET_PASSWORD base.TplName = "mail/auth/reset_passwd" + + NOTIFY_COLLABORATOR base.TplName = "mail/notify/collaborator" + NOTIFY_MENTION base.TplName = "mail/notify/mention" +) + // Create New mail message use MailFrom and MailUser func NewMailMessageFrom(To []string, from, subject, body string) Message { msg := NewHtmlMessage(To, from, subject, body) @@ -61,7 +70,7 @@ func SendRegisterMail(r *middleware.Render, u *models.User) { data := GetMailTmplData(u) data["Code"] = code - body, err := r.HTMLString("mail/auth/register_success", data) + body, err := r.HTMLString(string(AUTH_REGISTER_SUCCESS), data) if err != nil { log.Error("mail.SendRegisterMail(fail to render): %v", err) return @@ -81,7 +90,7 @@ func SendActiveMail(r *middleware.Render, u *models.User) { data := GetMailTmplData(u) data["Code"] = code - body, err := r.HTMLString("mail/auth/active_email", data) + body, err := r.HTMLString(string(AUTH_ACTIVE), data) if err != nil { log.Error("mail.SendActiveMail(fail to render): %v", err) return @@ -101,7 +110,7 @@ func SendResetPasswdMail(r *middleware.Render, u *models.User) { data := GetMailTmplData(u) data["Code"] = code - body, err := r.HTMLString("mail/auth/reset_passwd", data) + body, err := r.HTMLString(string(AUTH_RESET_PASSWORD), data) if err != nil { log.Error("mail.SendResetPasswdMail(fail to render): %v", err) return @@ -161,7 +170,7 @@ func SendIssueMentionMail(r *middleware.Render, u, owner *models.User, data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index) data["Subject"] = subject - body, err := r.HTMLString("mail/notify/mention", data) + body, err := r.HTMLString(string(NOTIFY_MENTION), data) if err != nil { return fmt.Errorf("mail.SendIssueMentionMail(fail to render): %v", err) } @@ -182,7 +191,7 @@ func SendCollaboratorMail(r *middleware.Render, u, owner *models.User, data["RepoLink"] = path.Join(owner.Name, repo.Name) data["Subject"] = subject - body, err := r.HTMLString("mail/notify/collaborator", data) + body, err := r.HTMLString(string(NOTIFY_COLLABORATOR), data) if err != nil { return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err) } diff --git a/modules/middleware/context.go b/modules/middleware/context.go index 19556118..45f0140a 100644 --- a/modules/middleware/context.go +++ b/modules/middleware/context.go @@ -104,12 +104,12 @@ func (ctx *Context) HasError() bool { } // HTML calls render.HTML underlying but reduce one argument. -func (ctx *Context) HTML(status int, name string, htmlOpt ...HTMLOptions) { - ctx.Render.HTML(status, name, ctx.Data, htmlOpt...) +func (ctx *Context) HTML(status int, name base.TplName, htmlOpt ...HTMLOptions) { + ctx.Render.HTML(status, string(name), ctx.Data, htmlOpt...) } // RenderWithErr used for page has form validation but need to prompt error to users. -func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) { +func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form auth.Form) { if form != nil { auth.AssignForm(form, ctx.Data) } @@ -133,7 +133,7 @@ func (ctx *Context) Handle(status int, title string, err error) { case 500: ctx.Data["Title"] = "Internal Server Error" } - ctx.HTML(status, fmt.Sprintf("status/%d", status)) + ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status))) } func (ctx *Context) Debug(msg string, args ...interface{}) { diff --git a/routers/admin/admin.go b/routers/admin/admin.go index 1567a300..140e1e9f 100644 --- a/routers/admin/admin.go +++ b/routers/admin/admin.go @@ -20,6 +20,16 @@ import ( "github.com/gogits/gogs/modules/setting" ) +const ( + DASHBOARD base.TplName = "admin/dashboard" + USERS base.TplName = "admin/users" + REPOS base.TplName = "admin/repos" + AUTHS base.TplName = "admin/auths" + CONFIG base.TplName = "admin/config" + MONITOR_PROCESS base.TplName = "admin/monitor/process" + MONITOR_CRON base.TplName = "admin/monitor/cron" +) + var startTime = time.Now() var sysStatus struct { @@ -140,7 +150,7 @@ func Dashboard(ctx *middleware.Context) { ctx.Data["Stats"] = models.GetStatistic() updateSystemStatus() ctx.Data["SysStatus"] = sysStatus - ctx.HTML(200, "admin/dashboard") + ctx.HTML(200, DASHBOARD) } func Users(ctx *middleware.Context) { @@ -150,10 +160,10 @@ func Users(ctx *middleware.Context) { var err error ctx.Data["Users"], err = models.GetUsers(200, 0) if err != nil { - ctx.Handle(500, "admin.Users", err) + ctx.Handle(500, "admin.Users(GetUsers)", err) return } - ctx.HTML(200, "admin/users") + ctx.HTML(200, USERS) } func Repositories(ctx *middleware.Context) { @@ -166,7 +176,7 @@ func Repositories(ctx *middleware.Context) { ctx.Handle(500, "admin.Repositories", err) return } - ctx.HTML(200, "admin/repos") + ctx.HTML(200, REPOS) } func Auths(ctx *middleware.Context) { @@ -179,7 +189,7 @@ func Auths(ctx *middleware.Context) { ctx.Handle(500, "admin.Auths", err) return } - ctx.HTML(200, "admin/auths") + ctx.HTML(200, AUTHS) } func Config(ctx *middleware.Context) { @@ -235,7 +245,7 @@ func Config(ctx *middleware.Context) { } ctx.Data["Loggers"] = loggers - ctx.HTML(200, "admin/config") + ctx.HTML(200, CONFIG) } func Monitor(ctx *middleware.Context) { @@ -247,11 +257,10 @@ func Monitor(ctx *middleware.Context) { case "process": ctx.Data["PageIsMonitorProcess"] = true ctx.Data["Processes"] = process.Processes - ctx.HTML(200, "admin/monitor/process") + ctx.HTML(200, MONITOR_PROCESS) default: ctx.Data["PageIsMonitorCron"] = true ctx.Data["Entries"] = cron.ListEntries() - ctx.HTML(200, "admin/monitor/cron") + ctx.HTML(200, MONITOR_CRON) } - } diff --git a/routers/admin/auth.go b/routers/admin/auth.go new file mode 100644 index 00000000..ff6c0325 --- /dev/null +++ b/routers/admin/auth.go @@ -0,0 +1,201 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package admin + +import ( + "strings" + + "github.com/go-martini/martini" + "github.com/go-xorm/core" + + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/auth/ldap" + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" + "github.com/gogits/gogs/modules/middleware" +) + +const ( + AUTH_NEW base.TplName = "admin/auth/new" + AUTH_EDIT base.TplName = "admin/auth/edit" +) + +func NewAuthSource(ctx *middleware.Context) { + ctx.Data["Title"] = "New Authentication" + ctx.Data["PageIsAuths"] = true + ctx.Data["LoginTypes"] = models.LoginTypes + ctx.Data["SMTPAuths"] = models.SMTPAuths + ctx.HTML(200, AUTH_NEW) +} + +func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { + ctx.Data["Title"] = "New Authentication" + ctx.Data["PageIsAuths"] = true + ctx.Data["LoginTypes"] = models.LoginTypes + ctx.Data["SMTPAuths"] = models.SMTPAuths + + if ctx.HasError() { + ctx.HTML(200, AUTH_NEW) + return + } + + var u core.Conversion + switch models.LoginType(form.Type) { + case models.LDAP: + u = &models.LDAPConfig{ + Ldapsource: ldap.Ldapsource{ + Host: form.Host, + Port: form.Port, + UseSSL: form.UseSSL, + BaseDN: form.BaseDN, + Attributes: form.Attributes, + Filter: form.Filter, + MsAdSAFormat: form.MsAdSA, + Enabled: true, + Name: form.AuthName, + }, + } + case models.SMTP: + u = &models.SMTPConfig{ + Auth: form.SmtpAuth, + Host: form.SmtpHost, + Port: form.SmtpPort, + TLS: form.Tls, + } + default: + ctx.Error(400) + return + } + + var source = &models.LoginSource{ + Type: models.LoginType(form.Type), + Name: form.AuthName, + IsActived: true, + AllowAutoRegister: form.AllowAutoRegister, + Cfg: u, + } + + if err := models.CreateSource(source); err != nil { + ctx.Handle(500, "admin.auths.NewAuth(CreateSource)", err) + return + } + + log.Trace("%s Authentication created by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, strings.ToLower(form.AuthName)) + + ctx.Redirect("/admin/auths") +} + +func EditAuthSource(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Edit Authentication" + ctx.Data["PageIsAuths"] = true + ctx.Data["LoginTypes"] = models.LoginTypes + ctx.Data["SMTPAuths"] = models.SMTPAuths + + id, err := base.StrTo(params["authid"]).Int64() + if err != nil { + ctx.Handle(404, "admin.auths.EditAuthSource", err) + return + } + u, err := models.GetLoginSourceById(id) + if err != nil { + ctx.Handle(500, "admin.user.EditUser(GetLoginSourceById)", err) + return + } + ctx.Data["Source"] = u + ctx.HTML(200, AUTH_EDIT) +} + +func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { + ctx.Data["Title"] = "Edit Authentication" + ctx.Data["PageIsAuths"] = true + ctx.Data["LoginTypes"] = models.LoginTypes + ctx.Data["SMTPAuths"] = models.SMTPAuths + + if ctx.HasError() { + ctx.HTML(200, AUTH_EDIT) + return + } + + var config core.Conversion + switch models.LoginType(form.Type) { + case models.LDAP: + config = &models.LDAPConfig{ + Ldapsource: ldap.Ldapsource{ + Host: form.Host, + Port: form.Port, + UseSSL: form.UseSSL, + BaseDN: form.BaseDN, + Attributes: form.Attributes, + Filter: form.Filter, + MsAdSAFormat: form.MsAdSA, + Enabled: true, + Name: form.AuthName, + }, + } + case models.SMTP: + config = &models.SMTPConfig{ + Auth: form.SmtpAuth, + Host: form.SmtpHost, + Port: form.SmtpPort, + TLS: form.Tls, + } + default: + ctx.Error(400) + return + } + + u := models.LoginSource{ + Id: form.Id, + Name: form.AuthName, + IsActived: form.IsActived, + Type: models.LoginType(form.Type), + AllowAutoRegister: form.AllowAutoRegister, + Cfg: config, + } + + if err := models.UpdateSource(&u); err != nil { + ctx.Handle(500, "admin.auths.EditAuth(UpdateSource)", err) + return + } + + log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, form.AuthName) + + ctx.Redirect("/admin/auths") +} + +func DeleteAuthSource(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Delete Authentication" + ctx.Data["PageIsAuths"] = true + + id, err := base.StrTo(params["authid"]).Int64() + if err != nil { + ctx.Handle(404, "admin.auths.DeleteAuth", err) + return + } + + a, err := models.GetLoginSourceById(id) + if err != nil { + ctx.Handle(500, "admin.auths.DeleteAuth(GetLoginSourceById)", err) + return + } + + if err = models.DelLoginSource(a); err != nil { + switch err { + case models.ErrAuthenticationUserUsed: + ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.") + ctx.Redirect("/admin/auths/" + params["authid"]) + default: + ctx.Handle(500, "admin.auths.DeleteAuth(DelLoginSource)", err) + } + return + } + log.Trace("%s Authentication deleted by admin(%s): %s", ctx.Req.RequestURI, + ctx.User.LowerName, ctx.User.LowerName) + + ctx.Redirect("/admin/auths") +} diff --git a/routers/admin/auths.go b/routers/admin/auths.go deleted file mode 100644 index e0b99714..00000000 --- a/routers/admin/auths.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2014 The Gogs Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package admin - -import ( - "strings" - - "github.com/go-martini/martini" - "github.com/go-xorm/core" - - "github.com/gogits/gogs/models" - "github.com/gogits/gogs/modules/auth" - "github.com/gogits/gogs/modules/auth/ldap" - "github.com/gogits/gogs/modules/base" - "github.com/gogits/gogs/modules/log" - "github.com/gogits/gogs/modules/middleware" -) - -func NewAuthSource(ctx *middleware.Context) { - ctx.Data["Title"] = "New Authentication" - ctx.Data["PageIsAuths"] = true - ctx.Data["LoginTypes"] = models.LoginTypes - ctx.Data["SMTPAuths"] = models.SMTPAuths - ctx.HTML(200, "admin/auths/new") -} - -func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { - ctx.Data["Title"] = "New Authentication" - ctx.Data["PageIsAuths"] = true - ctx.Data["LoginTypes"] = models.LoginTypes - ctx.Data["SMTPAuths"] = models.SMTPAuths - - if ctx.HasError() { - ctx.HTML(200, "admin/auths/new") - return - } - - var u core.Conversion - switch models.LoginType(form.Type) { - case models.LDAP: - u = &models.LDAPConfig{ - Ldapsource: ldap.Ldapsource{ - Host: form.Host, - Port: form.Port, - UseSSL: form.UseSSL, - BaseDN: form.BaseDN, - Attributes: form.Attributes, - Filter: form.Filter, - MsAdSAFormat: form.MsAdSA, - Enabled: true, - Name: form.AuthName, - }, - } - case models.SMTP: - u = &models.SMTPConfig{ - Auth: form.SmtpAuth, - Host: form.SmtpHost, - Port: form.SmtpPort, - TLS: form.Tls, - } - default: - ctx.Error(400) - return - } - - var source = &models.LoginSource{ - Type: models.LoginType(form.Type), - Name: form.AuthName, - IsActived: true, - AllowAutoRegister: form.AllowAutoRegister, - Cfg: u, - } - - if err := models.CreateSource(source); err != nil { - ctx.Handle(500, "admin.auths.NewAuth", err) - return - } - - log.Trace("%s Authentication created by admin(%s): %s", ctx.Req.RequestURI, - ctx.User.LowerName, strings.ToLower(form.AuthName)) - - ctx.Redirect("/admin/auths") -} - -func EditAuthSource(ctx *middleware.Context, params martini.Params) { - ctx.Data["Title"] = "Edit Authentication" - ctx.Data["PageIsAuths"] = true - ctx.Data["LoginTypes"] = models.LoginTypes - ctx.Data["SMTPAuths"] = models.SMTPAuths - - id, err := base.StrTo(params["authid"]).Int64() - if err != nil { - ctx.Handle(404, "admin.auths.EditAuthSource", err) - return - } - u, err := models.GetLoginSourceById(id) - if err != nil { - ctx.Handle(500, "admin.user.EditUser", err) - return - } - ctx.Data["Source"] = u - ctx.HTML(200, "admin/auths/edit") -} - -func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { - ctx.Data["Title"] = "Edit Authentication" - ctx.Data["PageIsAuths"] = true - ctx.Data["LoginTypes"] = models.LoginTypes - ctx.Data["SMTPAuths"] = models.SMTPAuths - - if ctx.HasError() { - ctx.HTML(200, "admin/auths/edit") - return - } - - var config core.Conversion - switch models.LoginType(form.Type) { - case models.LDAP: - config = &models.LDAPConfig{ - Ldapsource: ldap.Ldapsource{ - Host: form.Host, - Port: form.Port, - UseSSL: form.UseSSL, - BaseDN: form.BaseDN, - Attributes: form.Attributes, - Filter: form.Filter, - MsAdSAFormat: form.MsAdSA, - Enabled: true, - Name: form.AuthName, - }, - } - case models.SMTP: - config = &models.SMTPConfig{ - Auth: form.SmtpAuth, - Host: form.SmtpHost, - Port: form.SmtpPort, - TLS: form.Tls, - } - default: - ctx.Error(400) - return - } - - u := models.LoginSource{ - Id: form.Id, - Name: form.AuthName, - IsActived: form.IsActived, - Type: models.LoginType(form.Type), - AllowAutoRegister: form.AllowAutoRegister, - Cfg: config, - } - - if err := models.UpdateSource(&u); err != nil { - ctx.Handle(500, "admin.auths.EditAuth", err) - return - } - - log.Trace("%s Authentication changed by admin(%s): %s", ctx.Req.RequestURI, - ctx.User.LowerName, form.AuthName) - - ctx.Redirect("/admin/auths") -} - -func DeleteAuthSource(ctx *middleware.Context, params martini.Params) { - ctx.Data["Title"] = "Delete Authentication" - ctx.Data["PageIsAuths"] = true - - id, err := base.StrTo(params["authid"]).Int64() - if err != nil { - ctx.Handle(404, "admin.auths.DeleteAuth", err) - return - } - - a, err := models.GetLoginSourceById(id) - if err != nil { - ctx.Handle(500, "admin.auths.DeleteAuth", err) - return - } - - if err = models.DelLoginSource(a); err != nil { - switch err { - case models.ErrAuthenticationUserUsed: - ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.") - ctx.Redirect("/admin/auths/" + params["authid"]) - default: - ctx.Handle(500, "admin.auths.DeleteAuth", err) - } - return - } - log.Trace("%s Authentication deleted by admin(%s): %s", ctx.Req.RequestURI, - ctx.User.LowerName, ctx.User.LowerName) - - ctx.Redirect("/admin/auths") -} diff --git a/routers/admin/user.go b/routers/admin/user.go index 596fe7b1..d1bbb480 100644 --- a/routers/admin/user.go +++ b/routers/admin/user.go @@ -5,8 +5,6 @@ package admin import ( - "fmt" - "strconv" "strings" "github.com/go-martini/martini" @@ -18,16 +16,21 @@ import ( "github.com/gogits/gogs/modules/middleware" ) +const ( + USER_NEW base.TplName = "admin/user/new" + USER_EDIT base.TplName = "admin/user/edit" +) + func NewUser(ctx *middleware.Context) { ctx.Data["Title"] = "New Account" ctx.Data["PageIsUsers"] = true auths, err := models.GetAuths() if err != nil { - ctx.Handle(500, "admin.user.NewUser", err) + ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) return } ctx.Data["LoginSources"] = auths - ctx.HTML(200, "admin/users/new") + ctx.HTML(200, USER_NEW) } func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { @@ -35,7 +38,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { ctx.Data["PageIsUsers"] = true if ctx.HasError() { - ctx.HTML(200, "admin/users/new") + ctx.HTML(200, USER_NEW) return } @@ -55,25 +58,25 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { } if len(form.LoginType) > 0 { + // NOTE: need rewrite. fields := strings.Split(form.LoginType, "-") - tp, _ := strconv.Atoi(fields[0]) + tp, _ := base.StrTo(fields[0]).Int() u.LoginType = models.LoginType(tp) - u.LoginSource, _ = strconv.ParseInt(fields[1], 10, 64) + u.LoginSource, _ = base.StrTo(fields[1]).Int64() u.LoginName = form.LoginName - fmt.Println(u.LoginType, u.LoginSource, u.LoginName) } var err error if u, err = models.RegisterUser(u); err != nil { switch err { case models.ErrUserAlreadyExist: - ctx.RenderWithErr("Username has been already taken", "admin/users/new", &form) + ctx.RenderWithErr("Username has been already taken", USER_NEW, &form) case models.ErrEmailAlreadyUsed: - ctx.RenderWithErr("E-mail address has been already used", "admin/users/new", &form) + ctx.RenderWithErr("E-mail address has been already used", USER_NEW, &form) case models.ErrUserNameIllegal: - ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "admin/users/new", &form) + ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), USER_NEW, &form) default: - ctx.Handle(500, "admin.user.NewUser", err) + ctx.Handle(500, "admin.user.NewUser(RegisterUser)", err) } return } @@ -96,18 +99,18 @@ func EditUser(ctx *middleware.Context, params martini.Params) { u, err := models.GetUserById(int64(uid)) if err != nil { - ctx.Handle(500, "admin.user.EditUser", err) + ctx.Handle(500, "admin.user.EditUser(GetUserById)", err) return } ctx.Data["User"] = u auths, err := models.GetAuths() if err != nil { - ctx.Handle(500, "admin.user.NewUser", err) + ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) return } ctx.Data["LoginSources"] = auths - ctx.HTML(200, "admin/users/edit") + ctx.HTML(200, USER_EDIT) } func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.AdminEditUserForm) { @@ -116,13 +119,18 @@ func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.Admi uid, err := base.StrTo(params["userid"]).Int() if err != nil { - ctx.Handle(404, "admin.user.EditUser", err) + ctx.Handle(404, "admin.user.EditUserPost", err) return } u, err := models.GetUserById(int64(uid)) if err != nil { - ctx.Handle(500, "admin.user.EditUser", err) + ctx.Handle(500, "admin.user.EditUserPost(GetUserById)", err) + return + } + + if ctx.HasError() { + ctx.HTML(200, USER_EDIT) return } @@ -134,7 +142,7 @@ func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.Admi u.IsActive = form.Active u.IsAdmin = form.Admin if err := models.UpdateUser(u); err != nil { - ctx.Handle(500, "admin.user.EditUser", err) + ctx.Handle(500, "admin.user.EditUserPost(UpdateUser)", err) return } log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI, @@ -152,13 +160,13 @@ func DeleteUser(ctx *middleware.Context, params martini.Params) { //log.Info("delete") uid, err := base.StrTo(params["userid"]).Int() if err != nil { - ctx.Handle(404, "admin.user.EditUser", err) + ctx.Handle(404, "admin.user.DeleteUser", err) return } u, err := models.GetUserById(int64(uid)) if err != nil { - ctx.Handle(500, "admin.user.EditUser", err) + ctx.Handle(500, "admin.user.DeleteUser(GetUserById)", err) return } diff --git a/routers/dashboard.go b/routers/dashboard.go index 438d0379..d65c403c 100644 --- a/routers/dashboard.go +++ b/routers/dashboard.go @@ -6,11 +6,16 @@ package routers import ( "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/setting" "github.com/gogits/gogs/routers/user" ) +const ( + HOME base.TplName = "home" +) + func Home(ctx *middleware.Context) { if ctx.IsSigned { user.Dashboard(ctx) @@ -40,7 +45,7 @@ func Home(ctx *middleware.Context) { } } ctx.Data["Repos"] = repos - ctx.HTML(200, "home") + ctx.HTML(200, HOME) } func NotFound(ctx *middleware.Context) { diff --git a/routers/dev/template.go b/routers/dev/template.go index 5e84d76e..da477c94 100644 --- a/routers/dev/template.go +++ b/routers/dev/template.go @@ -8,6 +8,7 @@ import ( "github.com/go-martini/martini" "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/base" "github.com/gogits/gogs/modules/middleware" "github.com/gogits/gogs/modules/setting" ) @@ -22,5 +23,5 @@ func TemplatePreview(ctx *middleware.Context, params martini.Params) { ctx.Data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60 ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60 ctx.Data["CurDbValue"] = "" - ctx.HTML(200, params["_1"]) + ctx.HTML(200, base.TplName(params["_1"])) } diff --git a/routers/install.go b/routers/install.go index c2eee88a..6ce7c980 100644 --- a/routers/install.go +++ b/routers/install.go @@ -26,6 +26,10 @@ import ( "github.com/gogits/gogs/modules/social" ) +const ( + INSTALL base.TplName = "install" +) + func checkRunMode() { switch setting.Cfg.MustValue("", "RUN_MODE") { case "prod": @@ -72,6 +76,7 @@ func renderDbOption(ctx *middleware.Context) { ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"} } +// @router /install [get] func Install(ctx *middleware.Context, form auth.InstallForm) { if setting.InstallLock { ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) @@ -119,12 +124,12 @@ func Install(ctx *middleware.Context, form auth.InstallForm) { ctx.Data["CurDbOption"] = curDbOp auth.AssignForm(form, ctx.Data) - ctx.HTML(200, "install") + ctx.HTML(200, INSTALL) } func InstallPost(ctx *middleware.Context, form auth.InstallForm) { if setting.InstallLock { - ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) + ctx.Handle(404, "install.InstallPost", errors.New("Installation is prohibited")) return } @@ -135,12 +140,12 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { ctx.Data["CurDbOption"] = form.Database if ctx.HasError() { - ctx.HTML(200, "install") + ctx.HTML(200, INSTALL) return } if _, err := exec.LookPath("git"); err != nil { - ctx.RenderWithErr("Fail to test 'git' command: "+err.Error(), "install", &form) + ctx.RenderWithErr("Fail to test 'git' command: "+err.Error(), INSTALL, &form) return } @@ -158,18 +163,19 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { // Set test engine. var x *xorm.Engine if err := models.NewTestEngine(x); err != nil { + // NOTE: should use core.QueryDriver (github.com/go-xorm/core) if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { ctx.RenderWithErr("Your release version does not support SQLite3, please download the official binary version "+ - "from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version.", "install", &form) + "from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version.", INSTALL, &form) } else { - ctx.RenderWithErr("Database setting is not correct: "+err.Error(), "install", &form) + ctx.RenderWithErr("Database setting is not correct: "+err.Error(), INSTALL, &form) } return } // Test repository root path. if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil { - ctx.RenderWithErr("Repository root path is invalid: "+err.Error(), "install", &form) + ctx.RenderWithErr("Repository root path is invalid: "+err.Error(), INSTALL, &form) return } @@ -180,7 +186,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { } // Does not check run user when the install lock is off. if form.RunUser != curUser { - ctx.RenderWithErr("Run user isn't the current user: "+form.RunUser+" -> "+curUser, "install", &form) + ctx.RenderWithErr("Run user isn't the current user: "+form.RunUser+" -> "+curUser, INSTALL, &form) return } @@ -214,7 +220,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { os.MkdirAll("custom/conf", os.ModePerm) if err := goconfig.SaveConfigFile(setting.Cfg, path.Join(setting.CustomPath, "conf/app.ini")); err != nil { - ctx.RenderWithErr("Fail to save configuration: "+err.Error(), "install", &form) + ctx.RenderWithErr("Fail to save configuration: "+err.Error(), INSTALL, &form) return } @@ -225,7 +231,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { IsAdmin: true, IsActive: true}); err != nil { if err != models.ErrUserAlreadyExist { setting.InstallLock = false - ctx.RenderWithErr("Admin account setting is invalid: "+err.Error(), "install", &form) + ctx.RenderWithErr("Admin account setting is invalid: "+err.Error(), INSTALL, &form) return } log.Info("Admin account already exist") diff --git a/routers/repo/repo.go b/routers/repo/repo.go index 6db45300..6154eede 100644 --- a/routers/repo/repo.go +++ b/routers/repo/repo.go @@ -318,7 +318,7 @@ func basicDecode(encoded string) (user string, name string, err error) { func authRequired(ctx *middleware.Context) { ctx.ResponseWriter.Header().Set("WWW-Authenticate", "Basic realm=\".\"") ctx.Data["ErrorMsg"] = "no basic auth and digit auth" - ctx.HTML(401, fmt.Sprintf("status/401")) + ctx.HTML(401, base.TplName("status/401")) } func Action(ctx *middleware.Context, params martini.Params) { diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl new file mode 100644 index 00000000..a2c2ddc6 --- /dev/null +++ b/templates/admin/auth/edit.tmpl @@ -0,0 +1,165 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ Edit Authentication +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} + + {{$type := .Source.Type}} +
+ + + +
+
+ +
+ +
+
+ + {{if eq $type 2}} +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ {{else if eq $type 3}} +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ {{end}} + +
+ {{if eq $type 3}} +
+
+ +
+
+ {{end}} + +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
+ + Delete this authentication +
+
+
+
+
+ +
+
+{{template "base/footer" .}} diff --git a/templates/admin/auth/new.tmpl b/templates/admin/auth/new.tmpl new file mode 100644 index 00000000..abb88043 --- /dev/null +++ b/templates/admin/auth/new.tmpl @@ -0,0 +1,178 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ New Authentication +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + +
+
+
+ +
+
+
+ +
+ +
+
+ +
+
+
+
+
+ +
+
+ Tips +
+ +
+
GMail Setting:
+

Host: smtp.gmail.com, Post: 587, Enable TLS Encryption: true

+
+
+
+
+ +{{template "base/footer" .}} diff --git a/templates/admin/auths/edit.tmpl b/templates/admin/auths/edit.tmpl deleted file mode 100644 index a2c2ddc6..00000000 --- a/templates/admin/auths/edit.tmpl +++ /dev/null @@ -1,165 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -
- {{template "admin/nav" .}} -
-
-
- Edit Authentication -
- -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} - - {{$type := .Source.Type}} -
- - - -
-
- -
- -
-
- - {{if eq $type 2}} -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- - -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- {{else if eq $type 3}} -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- {{end}} - -
- {{if eq $type 3}} -
-
- -
-
- {{end}} - -
-
- -
-
- -
-
- -
-
-
- -
- -
-
- - Delete this authentication -
-
-
-
-
- -
-
-{{template "base/footer" .}} diff --git a/templates/admin/auths/new.tmpl b/templates/admin/auths/new.tmpl deleted file mode 100644 index abb88043..00000000 --- a/templates/admin/auths/new.tmpl +++ /dev/null @@ -1,178 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -
- {{template "admin/nav" .}} -
-
-
- New Authentication -
- -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
- -
-
-
- -
- -
-
-
-
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- - - -
-
-
- -
-
-
- -
- -
-
- -
-
-
-
-
- -
-
- Tips -
- -
-
GMail Setting:
-

Host: smtp.gmail.com, Post: 587, Enable TLS Encryption: true

-
-
-
-
- -{{template "base/footer" .}} diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl new file mode 100644 index 00000000..b1fffb69 --- /dev/null +++ b/templates/admin/user/edit.tmpl @@ -0,0 +1,103 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ Edit Account +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+ + Delete this account +
+
+
+
+
+ +
+
+{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/admin/user/new.tmpl b/templates/admin/user/new.tmpl new file mode 100644 index 00000000..4f4866c4 --- /dev/null +++ b/templates/admin/user/new.tmpl @@ -0,0 +1,94 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +
+ {{template "admin/nav" .}} +
+
+
+ New Account +
+ +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+ +
+
+ + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+ +{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/admin/users/edit.tmpl b/templates/admin/users/edit.tmpl deleted file mode 100644 index b1fffb69..00000000 --- a/templates/admin/users/edit.tmpl +++ /dev/null @@ -1,103 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -
- {{template "admin/nav" .}} -
-
-
- Edit Account -
- -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
- -
-
- -
- -
- -
-
- -
- - -
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
- -
- -
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- - Delete this account -
-
-
-
-
- -
-
-{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/admin/users/new.tmpl b/templates/admin/users/new.tmpl deleted file mode 100644 index 4f4866c4..00000000 --- a/templates/admin/users/new.tmpl +++ /dev/null @@ -1,94 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -
- {{template "admin/nav" .}} -
-
-
- New Account -
- -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
- -
-
- - - -
- -
- -
-
- -
- -
- -
-
- -
-
- -
- -
-
- -
- -
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
- -{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/issue/create.tmpl b/templates/issue/create.tmpl deleted file mode 100644 index 34cecc78..00000000 --- a/templates/issue/create.tmpl +++ /dev/null @@ -1,112 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
-
-
- -
-
- No one will be assigned -    -
- - -
- No milestone - -
- - -
-
-
-
- Content with Markdown -
- -
-
-
- -
-
-
loading...
-
-
-
-
- - -
-
-
-
-
-
-{{template "base/footer" .}} diff --git a/templates/issue/list.tmpl b/templates/issue/list.tmpl deleted file mode 100644 index 0fae3eb6..00000000 --- a/templates/issue/list.tmpl +++ /dev/null @@ -1,116 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-
- -
-

Label

- - -
-
- {{.CsrfTokenHtml}} -
New Label
-
- - - -
-
- - -
-
-
-
-
- {{template "base/alert" .}} - -
- {{range .Issues}}{{if .Poster}} -
- #{{.Index}} -
- {{.Name}} - - {{range .Labels}} - {{.Name}} - {{end}} - -
-

- - {{.Poster.Name}} - {{TimeSince .Created}} - {{.NumComments}} -

-
- {{end}}{{end}} -
-
-
-
- - - -{{template "base/footer" .}} diff --git a/templates/issue/milestone.tmpl b/templates/issue/milestone.tmpl deleted file mode 100644 index 8a5751c1..00000000 --- a/templates/issue/milestone.tmpl +++ /dev/null @@ -1,43 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
- -
-
- {{range .Milestones}} -
-

{{.Name}}

- {{.NumOpenIssues}} - {{.NumClosedIssues}} -

- Edit - {{if .IsClosed}} - Open - {{else}} - Close - {{end}} - Delete - Issues -

-
-

{{.RenderedContent | str2html}}

-
- {{end}} -
-
-
-
- -{{template "base/footer" .}} diff --git a/templates/issue/milestone_edit.tmpl b/templates/issue/milestone_edit.tmpl deleted file mode 100644 index 8f1a05e0..00000000 --- a/templates/issue/milestone_edit.tmpl +++ /dev/null @@ -1,61 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
-
-
- -
-
-
- Content with Markdown -
- -
-
-
- -
-
-
loading...
-
-
-
-
- - -
-
-
-
-

Milestone Due Date

-
- -
-
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/issue/milestone_new.tmpl b/templates/issue/milestone_new.tmpl deleted file mode 100644 index 044b7d10..00000000 --- a/templates/issue/milestone_new.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-
- {{.CsrfTokenHtml}} - {{template "base/alert" .}} -
- -
-
-
- -
-
-
- Content with Markdown -
- -
-
-
- -
-
-
loading...
-
-
-
-
- - -
-
-
-
-

Milestone Due Date

- -
- -
-
-
-
-
- - -{{template "base/footer" .}} diff --git a/templates/issue/view.tmpl b/templates/issue/view.tmpl deleted file mode 100644 index ba1fe16b..00000000 --- a/templates/issue/view.tmpl +++ /dev/null @@ -1,228 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-
-
-
-
#{{.Issue.Index}}
- -

{{.Issue.Name}}

- - -

- {{if .IsIssueOwner}}Edit - - {{end}} - {{if .Issue.IsClosed}}Closed{{else}}Open{{end}} - {{.Issue.Poster.Name}} opened this issue - {{TimeSince .Issue.Created}} · {{.Issue.NumComments}} comments -

-
-
-
-
-
- {{str2html .Issue.RenderedContent}} -
- -
-
- {{range .Comments}} - {{if eq .Type 0}} -
- -
-
- {{.Poster.Name}} commented {{TimeSince .Created}} - - Owner -
-
- {{str2html .Content}} -
-
-
- {{else if eq .Type 1}} -
- -
- {{.Poster.Name}} Reopened this issue {{TimeSince .Created}} -
-
- {{else if eq .Type 2}} -
- -
- {{.Poster.Name}} Closed this issue {{TimeSince .Created}} -
-
- {{end}} - {{end}} -
- {{if .SignedUser}}
- -
- {{.CsrfTokenHtml}} -
-
-
Content with Markdown -
- -
-
-
- - -
-
-
Loading...
-
-
-
-
- {{if .IsIssueOwner}}{{if .Issue.IsClosed}} - {{else}} - {{end}}{{end}}   - -
-
-
-
-
{{else}}
Sign up for free to join this conversation. Already have an account? Sign in to comment
{{end}} -
-
- -
-
-
- - -
-

Labels

- {{if .Issue.Labels}} - {{range .Issue.Labels}} -

{{.Name}}

- {{end}} - {{else}} -

None yet

- {{end}} -
-
-
- - -
-

Milestone

- {{if .Milestone}} -

 

-

{{.Milestone.Name}}

- {{else}} -

No milestone

- {{end}} -
- -
{{if .IsRepositoryOwner}} -
- - -
{{end}} -

Assignee

-

{{if .Issue.Assignee}}{{.Issue.Assignee.Name}}{{else}}No one assigned{{end}}

-
-
-
-
-
-{{template "base/footer" .}} diff --git a/templates/mail/auth/active.tmpl b/templates/mail/auth/active.tmpl new file mode 100644 index 00000000..72d9948b --- /dev/null +++ b/templates/mail/auth/active.tmpl @@ -0,0 +1,33 @@ + + + + +{{.User.Name}}, please activate your account + + +
+
+
+
+

{{.AppName}}

+
+
+ Hi {{.User.Name}}, +
+
+

Please click the following link to verify your e-mail address within {{.ActiveCodeLives}} hours.

+

+ {{.AppUrl}}user/activate?code={{.Code}} +

+

Not working? Try copying and pasting it to your browser.

+
+
+
+
+
+ © 2014 Gogs: Go Git Service +
+
+
+ + diff --git a/templates/mail/auth/active_email.tmpl b/templates/mail/auth/active_email.tmpl deleted file mode 100644 index 72d9948b..00000000 --- a/templates/mail/auth/active_email.tmpl +++ /dev/null @@ -1,33 +0,0 @@ - - - - -{{.User.Name}}, please activate your account - - -
-
-
-
-

{{.AppName}}

-
-
- Hi {{.User.Name}}, -
-
-

Please click the following link to verify your e-mail address within {{.ActiveCodeLives}} hours.

-

- {{.AppUrl}}user/activate?code={{.Code}} -

-

Not working? Try copying and pasting it to your browser.

-
-
-
-
-
- © 2014 Gogs: Go Git Service -
-
-
- - diff --git a/templates/release/edit.tmpl b/templates/release/edit.tmpl deleted file mode 100644 index e437092c..00000000 --- a/templates/release/edit.tmpl +++ /dev/null @@ -1,70 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-

Edit Release

- {{template "base/alert" .}} -
- {{.CsrfTokenHtml}} -
- {{.Release.TagName}} - @ -
- - - - -
-

Choose an existing tag, or create a new tag on publish

-
-
- -
-
-
- Content with Markdown -
- -
-
-
- -
-
-
loading...
-
-
-
-
- -

We’ll point out that this release is identified as non-production ready.

-
-
- - -
-
-
-
-{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/release/list.tmpl b/templates/release/list.tmpl deleted file mode 100644 index 0f02508f..00000000 --- a/templates/release/list.tmpl +++ /dev/null @@ -1,62 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-

- Releases - -

- -
-
-{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/release/new.tmpl b/templates/release/new.tmpl deleted file mode 100644 index 6c5cf40c..00000000 --- a/templates/release/new.tmpl +++ /dev/null @@ -1,70 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -{{template "repo/nav" .}} -{{template "repo/toolbar" .}} -
-
-

New Release

- {{template "base/alert" .}} -
- {{.CsrfTokenHtml}} -
- - @ -
- - - - -
-

Choose an existing tag, or create a new tag on publish

-
-
- -
-
-
- Content with Markdown -
- -
-
-
- -
-
-
loading...
-
-
-
-
- -

We’ll point out that this release is identified as non-production ready.

-
-
- - -
-
-
-
-{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/repo/issue/create.tmpl b/templates/repo/issue/create.tmpl new file mode 100644 index 00000000..34cecc78 --- /dev/null +++ b/templates/repo/issue/create.tmpl @@ -0,0 +1,112 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+
+
+ +
+
+ No one will be assigned +    +
+ + +
+ No milestone + +
+ + +
+
+
+
+ Content with Markdown +
+ +
+
+
+ +
+
+
loading...
+
+
+
+
+ + +
+
+
+
+
+
+{{template "base/footer" .}} diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl new file mode 100644 index 00000000..0fae3eb6 --- /dev/null +++ b/templates/repo/issue/list.tmpl @@ -0,0 +1,116 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+
+ +
+

Label

+ + +
+
+ {{.CsrfTokenHtml}} +
New Label
+
+ + + +
+
+ + +
+
+
+
+
+ {{template "base/alert" .}} + +
+ {{range .Issues}}{{if .Poster}} +
+ #{{.Index}} +
+ {{.Name}} + + {{range .Labels}} + {{.Name}} + {{end}} + +
+

+ + {{.Poster.Name}} + {{TimeSince .Created}} + {{.NumComments}} +

+
+ {{end}}{{end}} +
+
+
+
+ + + +{{template "base/footer" .}} diff --git a/templates/repo/issue/milestone.tmpl b/templates/repo/issue/milestone.tmpl new file mode 100644 index 00000000..8a5751c1 --- /dev/null +++ b/templates/repo/issue/milestone.tmpl @@ -0,0 +1,43 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+ +
+
+ {{range .Milestones}} +
+

{{.Name}}

+ {{.NumOpenIssues}} + {{.NumClosedIssues}} +

+ Edit + {{if .IsClosed}} + Open + {{else}} + Close + {{end}} + Delete + Issues +

+
+

{{.RenderedContent | str2html}}

+
+ {{end}} +
+
+
+
+ +{{template "base/footer" .}} diff --git a/templates/repo/issue/milestone_edit.tmpl b/templates/repo/issue/milestone_edit.tmpl new file mode 100644 index 00000000..8f1a05e0 --- /dev/null +++ b/templates/repo/issue/milestone_edit.tmpl @@ -0,0 +1,61 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+
+
+ +
+
+
+ Content with Markdown +
+ +
+
+
+ +
+
+
loading...
+
+
+
+
+ + +
+
+
+
+

Milestone Due Date

+
+ +
+
+
+
+
+ + +{{template "base/footer" .}} diff --git a/templates/repo/issue/milestone_new.tmpl b/templates/repo/issue/milestone_new.tmpl new file mode 100644 index 00000000..044b7d10 --- /dev/null +++ b/templates/repo/issue/milestone_new.tmpl @@ -0,0 +1,62 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+
+ {{.CsrfTokenHtml}} + {{template "base/alert" .}} +
+ +
+
+
+ +
+
+
+ Content with Markdown +
+ +
+
+
+ +
+
+
loading...
+
+
+
+
+ + +
+
+
+
+

Milestone Due Date

+ +
+ +
+
+
+
+
+ + +{{template "base/footer" .}} diff --git a/templates/repo/issue/view.tmpl b/templates/repo/issue/view.tmpl new file mode 100644 index 00000000..ba1fe16b --- /dev/null +++ b/templates/repo/issue/view.tmpl @@ -0,0 +1,228 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+
+
+
+
#{{.Issue.Index}}
+ +

{{.Issue.Name}}

+ + +

+ {{if .IsIssueOwner}}Edit + + {{end}} + {{if .Issue.IsClosed}}Closed{{else}}Open{{end}} + {{.Issue.Poster.Name}} opened this issue + {{TimeSince .Issue.Created}} · {{.Issue.NumComments}} comments +

+
+
+
+
+
+ {{str2html .Issue.RenderedContent}} +
+ +
+
+ {{range .Comments}} + {{if eq .Type 0}} +
+ +
+
+ {{.Poster.Name}} commented {{TimeSince .Created}} + + Owner +
+
+ {{str2html .Content}} +
+
+
+ {{else if eq .Type 1}} +
+ +
+ {{.Poster.Name}} Reopened this issue {{TimeSince .Created}} +
+
+ {{else if eq .Type 2}} +
+ +
+ {{.Poster.Name}} Closed this issue {{TimeSince .Created}} +
+
+ {{end}} + {{end}} +
+ {{if .SignedUser}}
+ +
+ {{.CsrfTokenHtml}} +
+
+
Content with Markdown +
+ +
+
+
+ + +
+
+
Loading...
+
+
+
+
+ {{if .IsIssueOwner}}{{if .Issue.IsClosed}} + {{else}} + {{end}}{{end}}   + +
+
+
+
+
{{else}}
Sign up for free to join this conversation. Already have an account? Sign in to comment
{{end}} +
+
+ +
+
+
+ + +
+

Labels

+ {{if .Issue.Labels}} + {{range .Issue.Labels}} +

{{.Name}}

+ {{end}} + {{else}} +

None yet

+ {{end}} +
+
+
+ + +
+

Milestone

+ {{if .Milestone}} +

 

+

{{.Milestone.Name}}

+ {{else}} +

No milestone

+ {{end}} +
+ +
{{if .IsRepositoryOwner}} +
+ + +
{{end}} +

Assignee

+

{{if .Issue.Assignee}}{{.Issue.Assignee.Name}}{{else}}No one assigned{{end}}

+
+
+
+
+
+{{template "base/footer" .}} diff --git a/templates/repo/release/edit.tmpl b/templates/repo/release/edit.tmpl new file mode 100644 index 00000000..e437092c --- /dev/null +++ b/templates/repo/release/edit.tmpl @@ -0,0 +1,70 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+

Edit Release

+ {{template "base/alert" .}} +
+ {{.CsrfTokenHtml}} +
+ {{.Release.TagName}} + @ +
+ + + + +
+

Choose an existing tag, or create a new tag on publish

+
+
+ +
+
+
+ Content with Markdown +
+ +
+
+
+ +
+
+
loading...
+
+
+
+
+ +

We’ll point out that this release is identified as non-production ready.

+
+
+ + +
+
+
+
+{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/repo/release/list.tmpl b/templates/repo/release/list.tmpl new file mode 100644 index 00000000..0f02508f --- /dev/null +++ b/templates/repo/release/list.tmpl @@ -0,0 +1,62 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+

+ Releases + +

+ +
+
+{{template "base/footer" .}} \ No newline at end of file diff --git a/templates/repo/release/new.tmpl b/templates/repo/release/new.tmpl new file mode 100644 index 00000000..6c5cf40c --- /dev/null +++ b/templates/repo/release/new.tmpl @@ -0,0 +1,70 @@ +{{template "base/head" .}} +{{template "base/navbar" .}} +{{template "repo/nav" .}} +{{template "repo/toolbar" .}} +
+
+

New Release

+ {{template "base/alert" .}} +
+ {{.CsrfTokenHtml}} +
+ + @ +
+ + + + +
+

Choose an existing tag, or create a new tag on publish

+
+
+ +
+
+
+ Content with Markdown +
+ +
+
+
+ +
+
+
loading...
+
+
+
+
+ +

We’ll point out that this release is identified as non-production ready.

+
+
+ + +
+
+
+
+{{template "base/footer" .}} \ No newline at end of file -- cgit v1.2.3 From e0f9c628c5ff7399167944b3d0730698487af498 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 25 Jun 2014 00:44:48 -0400 Subject: Add create organization --- cmd/serve.go | 20 ++--- cmd/web.go | 5 +- gogs.go | 2 +- models/access.go | 17 ++-- models/issue.go | 4 +- models/login.go | 4 +- models/models.go | 2 +- models/org.go | 69 ++++++++++++++++ models/repo.go | 10 ++- models/user.go | 186 +++++++++++++++++++++++++++++++++--------- modules/auth/org.go | 33 ++++++++ modules/middleware/repo.go | 4 +- routers/admin/user.go | 4 +- routers/install.go | 2 +- routers/org/org.go | 96 ++++++++++++++++++++-- routers/repo/http.go | 8 +- routers/repo/setting.go | 4 +- routers/user/home.go | 13 ++- routers/user/user.go | 7 +- templates/VERSION | 2 +- templates/org/dashboard.tmpl | 73 ----------------- templates/org/new.tmpl | 24 +----- templates/user/dashboard.tmpl | 39 ++++++--- templates/user/issues.tmpl | 3 +- 24 files changed, 436 insertions(+), 195 deletions(-) create mode 100644 models/org.go create mode 100644 modules/auth/org.go delete mode 100644 templates/org/dashboard.tmpl (limited to 'modules/middleware') diff --git a/cmd/serve.go b/cmd/serve.go index 62e290d8..2a76da79 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -56,19 +56,19 @@ func parseCmd(cmd string) (string, string) { } var ( - COMMANDS_READONLY = map[string]int{ - "git-upload-pack": models.AU_WRITABLE, - "git upload-pack": models.AU_WRITABLE, - "git-upload-archive": models.AU_WRITABLE, + COMMANDS_READONLY = map[string]models.AccessType{ + "git-upload-pack": models.WRITABLE, + "git upload-pack": models.WRITABLE, + "git-upload-archive": models.WRITABLE, } - COMMANDS_WRITE = map[string]int{ - "git-receive-pack": models.AU_READABLE, - "git receive-pack": models.AU_READABLE, + COMMANDS_WRITE = map[string]models.AccessType{ + "git-receive-pack": models.READABLE, + "git receive-pack": models.READABLE, } ) -func In(b string, sl map[string]int) bool { +func In(b string, sl map[string]models.AccessType) bool { _, e := sl[b] return e } @@ -129,7 +129,7 @@ func runServ(k *cli.Context) { // Access check. switch { case isWrite: - has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_WRITABLE) + has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.WRITABLE) if err != nil { println("Gogs: internal error:", err) log.GitLogger.Fatal("Fail to check write access:", err) @@ -152,7 +152,7 @@ func runServ(k *cli.Context) { break } - has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_READABLE) + has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.READABLE) if err != nil { println("Gogs: internal error:", err) log.GitLogger.Fatal("Fail to check read access:", err) diff --git a/cmd/web.go b/cmd/web.go index d29183a9..878fdeac 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -188,14 +188,15 @@ func runWeb(*cli.Context) { reqOwner := middleware.RequireOwner() - m.Group("/o", func(r martini.Router) { + m.Group("/org", func(r martini.Router) { r.Get("/create", org.New) + r.Post("/create", bindIgnErr(auth.CreateOrganizationForm{}), org.NewPost) r.Get("/:org", org.Organization) r.Get("/:org/dashboard", org.Dashboard) r.Get("/:org/members", org.Members) r.Get("/:org/teams", org.Teams) r.Get("/:org/setting", org.Setting) - }) + }, reqSignIn) m.Group("/:username/:reponame", func(r martini.Router) { r.Get("/settings", repo.Setting) diff --git a/gogs.go b/gogs.go index 75d3eb4b..5c2c6ed9 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.5.0624 Alpha" +const APP_VER = "0.4.5.0625 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/access.go b/models/access.go index cf31fc13..5238daba 100644 --- a/models/access.go +++ b/models/access.go @@ -11,19 +11,20 @@ import ( "github.com/go-xorm/xorm" ) -// Access types. +type AccessType int + const ( - AU_READABLE = iota + 1 - AU_WRITABLE + READABLE AccessType = iota + 1 + WRITABLE ) // Access represents the accessibility of user to repository. type Access struct { Id int64 - UserName string `xorm:"unique(s)"` - RepoName string `xorm:"unique(s)"` // / - Mode int `xorm:"unique(s)"` - Created time.Time `xorm:"created"` + UserName string `xorm:"unique(s)"` + RepoName string `xorm:"unique(s)"` // / + Mode AccessType `xorm:"unique(s)"` + Created time.Time `xorm:"created"` } // AddAccess adds new access record. @@ -59,7 +60,7 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error { // HasAccess returns true if someone can read or write to given repository. // The repoName should be in format /. -func HasAccess(uname, repoName string, mode int) (bool, error) { +func HasAccess(uname, repoName string, mode AccessType) (bool, error) { if len(repoName) == 0 { return false, nil } diff --git a/models/issue.go b/models/issue.go index 11f6dd4e..6d67a72b 100644 --- a/models/issue.go +++ b/models/issue.go @@ -213,9 +213,9 @@ func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 { // IssueUser represents an issue-user relation. type IssueUser struct { Id int64 - Uid int64 // User ID. + Uid int64 `xorm:"INDEX"` // User ID. IssueId int64 - RepoId int64 + RepoId int64 `xorm:"INDEX"` MilestoneId int64 IsRead bool IsAssigned bool diff --git a/models/login.go b/models/login.go index 98c5c64e..e99b61e7 100644 --- a/models/login.go +++ b/models/login.go @@ -255,7 +255,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L Email: mail, } - return RegisterUser(user) + return CreateUser(user) } type loginAuth struct { @@ -359,5 +359,5 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S Passwd: passwd, Email: name, } - return RegisterUser(user) + return CreateUser(user) } diff --git a/models/models.go b/models/models.go index d6273d7f..4e65c00b 100644 --- a/models/models.go +++ b/models/models.go @@ -35,7 +35,7 @@ func init() { tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser), - new(Milestone), new(Label), new(HookTask)) + new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser)) } func LoadModelsConfig() { diff --git a/models/org.go b/models/org.go new file mode 100644 index 00000000..1cfe1798 --- /dev/null +++ b/models/org.go @@ -0,0 +1,69 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package models + +type AuthorizeType int + +const ( + ORG_READABLE AuthorizeType = iota + 1 + ORG_WRITABLE + ORG_ADMIN +) + +// Team represents a organization team. +type Team struct { + Id int64 + OrgId int64 `xorm:"INDEX"` + Name string + Description string + Authorize AuthorizeType + NumMembers int + NumRepos int +} + +// NewTeam creates a record of new team. +func NewTeam(t *Team) error { + _, err := x.Insert(t) + return err +} + +// ________ ____ ___ +// \_____ \_______ ____ | | \______ ___________ +// / | \_ __ \/ ___\| | / ___// __ \_ __ \ +// / | \ | \/ /_/ > | /\___ \\ ___/| | \/ +// \_______ /__| \___ /|______//____ >\___ >__| +// \/ /_____/ \/ \/ + +// OrgUser represents an organization-user relation. +type OrgUser struct { + Id int64 + Uid int64 `xorm:"INDEX"` + OrgId int64 `xorm:"INDEX"` + IsPublic bool + IsOwner bool + NumTeam int +} + +// GetOrgUsersByUserId returns all organization-user relations by user ID. +func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) { + ous := make([]*OrgUser, 0, 10) + err := x.Where("uid=?", uid).Find(&ous) + return ous, err +} + +// ___________ ____ ___ +// \__ ___/___ _____ _____ | | \______ ___________ +// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \ +// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/ +// |____| \___ >____ /__|_| /______//____ >\___ >__| +// \/ \/ \/ \/ \/ + +// TeamUser represents an team-user relation. +type TeamUser struct { + Id int64 + Uid int64 + OrgId int64 `xorm:"INDEX"` + TeamId int64 +} diff --git a/models/repo.go b/models/repo.go index 4ccaccbf..f0e46c71 100644 --- a/models/repo.go +++ b/models/repo.go @@ -158,7 +158,7 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) { } var ( - illegalEquals = []string{"raw", "install", "api", "avatar", "user", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"} + illegalEquals = []string{"raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"} illegalSuffixs = []string{".git"} ) @@ -483,7 +483,9 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir sess := x.NewSession() defer sess.Close() - sess.Begin() + if err = sess.Begin(); err != nil { + return nil, err + } if _, err = sess.Insert(repo); err != nil { if err2 := os.RemoveAll(repoPath); err2 != nil { @@ -495,9 +497,9 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir return nil, err } - mode := AU_WRITABLE + mode := WRITABLE if mirror { - mode = AU_READABLE + mode = READABLE } access := Access{ UserName: user.LowerName, diff --git a/models/user.go b/models/user.go index 50d81c94..2388be9a 100644 --- a/models/user.go +++ b/models/user.go @@ -21,10 +21,11 @@ import ( "github.com/gogits/gogs/modules/setting" ) -// User types. +type UserType int + const ( - UT_INDIVIDUAL = iota + 1 - UT_ORGANIZATION + INDIVIDUAL UserType = iota // Historic reason to make it starts at 0. + ORGANIZATION ) var ( @@ -50,7 +51,8 @@ type User struct { LoginType LoginType LoginSource int64 `xorm:"not null default 0"` LoginName string - Type int + Type UserType + Orgs []*User `xorm:"-"` NumFollowers int NumFollowings int NumStars int @@ -65,36 +67,60 @@ type User struct { Salt string `xorm:"VARCHAR(10)"` Created time.Time `xorm:"created"` Updated time.Time `xorm:"updated"` + + // For organization. + NumTeams int + NumMembers int } // HomeLink returns the user home page link. -func (user *User) HomeLink() string { - return "/user/" + user.Name +func (u *User) HomeLink() string { + return "/user/" + u.Name } // AvatarLink returns user gravatar link. -func (user *User) AvatarLink() string { +func (u *User) AvatarLink() string { if setting.DisableGravatar { return "/img/avatar_default.jpg" } else if setting.Service.EnableCacheAvatar { - return "/avatar/" + user.Avatar + return "/avatar/" + u.Avatar } - return "//1.gravatar.com/avatar/" + user.Avatar + return "//1.gravatar.com/avatar/" + u.Avatar } // NewGitSig generates and returns the signature of given user. -func (user *User) NewGitSig() *git.Signature { +func (u *User) NewGitSig() *git.Signature { return &git.Signature{ - Name: user.Name, - Email: user.Email, + Name: u.Name, + Email: u.Email, When: time.Now(), } } // EncodePasswd encodes password to safe format. -func (user *User) EncodePasswd() { - newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New) - user.Passwd = fmt.Sprintf("%x", newPasswd) +func (u *User) EncodePasswd() { + newPasswd := base.PBKDF2([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New) + u.Passwd = fmt.Sprintf("%x", newPasswd) +} + +func (u *User) IsOrganization() bool { + return u.Type == ORGANIZATION +} + +func (u *User) GetOrganizations() error { + ous, err := GetOrgUsersByUserId(u.Id) + if err != nil { + return err + } + + u.Orgs = make([]*User, len(ous)) + for i, ou := range ous { + u.Orgs[i], err = GetUserById(ou.OrgId) + if err != nil { + return err + } + } + return nil } // Member represents user is member of organization. @@ -126,49 +152,135 @@ func GetUserSalt() string { return base.GetRandomString(10) } -// RegisterUser creates record of a new user. -func RegisterUser(user *User) (*User, error) { +// CreateUser creates record of a new user. +func CreateUser(u *User) (*User, error) { + if !IsLegalName(u.Name) { + return nil, ErrUserNameIllegal + } + + isExist, err := IsUserExist(u.Name) + if err != nil { + return nil, err + } else if isExist { + return nil, ErrUserAlreadyExist + } + + isExist, err = IsEmailUsed(u.Email) + if err != nil { + return nil, err + } else if isExist { + return nil, ErrEmailAlreadyUsed + } + + u.LowerName = strings.ToLower(u.Name) + u.Avatar = base.EncodeMd5(u.Email) + u.AvatarEmail = u.Email + u.Rands = GetUserSalt() + u.Salt = GetUserSalt() + u.EncodePasswd() + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return nil, err + } - if !IsLegalName(user.Name) { + if _, err = sess.Insert(u); err != nil { + sess.Rollback() + return nil, err + } + + if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil { + sess.Rollback() + return nil, err + } + + if err = sess.Commit(); err != nil { + return nil, err + } + + // Auto-set admin for user whose ID is 1. + if u.Id == 1 { + u.IsAdmin = true + u.IsActive = true + _, err = x.Id(u.Id).UseBool().Update(u) + } + return u, err +} + +// CreateOrganization creates record of a new organization. +func CreateOrganization(org, owner *User) (*User, error) { + if !IsLegalName(org.Name) { return nil, ErrUserNameIllegal } - isExist, err := IsUserExist(user.Name) + isExist, err := IsUserExist(org.Name) if err != nil { return nil, err } else if isExist { return nil, ErrUserAlreadyExist } - isExist, err = IsEmailUsed(user.Email) + isExist, err = IsEmailUsed(org.Email) if err != nil { return nil, err } else if isExist { return nil, ErrEmailAlreadyUsed } - user.LowerName = strings.ToLower(user.Name) - user.Avatar = base.EncodeMd5(user.Email) - user.AvatarEmail = user.Email - user.Rands = GetUserSalt() - user.Salt = GetUserSalt() - user.EncodePasswd() - if _, err = x.Insert(user); err != nil { + org.LowerName = strings.ToLower(org.Name) + org.Avatar = base.EncodeMd5(org.Email) + org.AvatarEmail = org.Email + // No password for organization. + org.NumTeams = 1 + org.NumMembers = 1 + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return nil, err + } + + if _, err = sess.Insert(org); err != nil { + sess.Rollback() return nil, err - } else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil { - if _, err := x.Id(user.Id).Delete(&User{}); err != nil { - return nil, errors.New(fmt.Sprintf( - "both create userpath %s and delete table record faild: %v", user.Name, err)) - } + } + + // Create default owner team. + t := &Team{ + OrgId: org.Id, + Name: "Owner", + Authorize: ORG_ADMIN, + NumMembers: 1, + } + if _, err = sess.Insert(t); err != nil { + sess.Rollback() return nil, err } - if user.Id == 1 { - user.IsAdmin = true - user.IsActive = true - _, err = x.Id(user.Id).UseBool().Update(user) + // Add initial creator to organization and owner team. + ou := &OrgUser{ + Uid: owner.Id, + OrgId: org.Id, + IsOwner: true, + NumTeam: 1, } - return user, err + if _, err = sess.Insert(ou); err != nil { + sess.Rollback() + return nil, err + } + + tu := &TeamUser{ + Uid: owner.Id, + OrgId: org.Id, + TeamId: t.Id, + } + if _, err = sess.Insert(tu); err != nil { + sess.Rollback() + return nil, err + } + + return org, sess.Commit() } // GetUsers returns given number of user objects with offset. diff --git a/modules/auth/org.go b/modules/auth/org.go new file mode 100644 index 00000000..a60fbb85 --- /dev/null +++ b/modules/auth/org.go @@ -0,0 +1,33 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package auth + +import ( + "net/http" + "reflect" + + "github.com/go-martini/martini" + + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/middleware/binding" +) + +type CreateOrganizationForm struct { + OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"` + Email string `form:"email" binding:"Required;Email;MaxSize(50)"` +} + +func (f *CreateOrganizationForm) Name(field string) string { + names := map[string]string{ + "OrgName": "Organization name", + "Email": "E-mail address", + } + return names[field] +} + +func (f *CreateOrganizationForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) { + data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) + validate(errs, data, f) +} diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index 6c77ed2a..43ba1e8c 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -46,7 +46,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { // Collaborators who have write access can be seen as owners. if ctx.IsSigned { - ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.AU_WRITABLE) + ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE) if err != nil { ctx.Handle(500, "RepoAssignment(HasAccess)", err) return @@ -107,7 +107,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { return } - hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.AU_READABLE) + hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE) if err != nil { ctx.Handle(500, "RepoAssignment(HasAccess)", err) return diff --git a/routers/admin/user.go b/routers/admin/user.go index d1bbb480..cf99db2b 100644 --- a/routers/admin/user.go +++ b/routers/admin/user.go @@ -67,7 +67,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { } var err error - if u, err = models.RegisterUser(u); err != nil { + if u, err = models.CreateUser(u); err != nil { switch err { case models.ErrUserAlreadyExist: ctx.RenderWithErr("Username has been already taken", USER_NEW, &form) @@ -76,7 +76,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { case models.ErrUserNameIllegal: ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), USER_NEW, &form) default: - ctx.Handle(500, "admin.user.NewUser(RegisterUser)", err) + ctx.Handle(500, "admin.user.NewUser(CreateUser)", err) } return } diff --git a/routers/install.go b/routers/install.go index 6ce7c980..bb3c16ea 100644 --- a/routers/install.go +++ b/routers/install.go @@ -227,7 +227,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { GlobalInit() // Create admin account. - if _, err := models.RegisterUser(&models.User{Name: form.AdminName, Email: form.AdminEmail, Passwd: form.AdminPasswd, + if _, err := models.CreateUser(&models.User{Name: form.AdminName, Email: form.AdminEmail, Passwd: form.AdminPasswd, IsAdmin: true, IsActive: true}); err != nil { if err != models.ErrUserAlreadyExist { setting.InstallLock = false diff --git a/routers/org/org.go b/routers/org/org.go index ff97402e..0595a81b 100644 --- a/routers/org/org.go +++ b/routers/org/org.go @@ -1,33 +1,117 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package org import ( "github.com/go-martini/martini" + + "github.com/gogits/gogs/models" + "github.com/gogits/gogs/modules/auth" + "github.com/gogits/gogs/modules/base" + "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/middleware" + "github.com/gogits/gogs/routers/user" +) + +const ( + NEW base.TplName = "org/new" ) func Organization(ctx *middleware.Context, params martini.Params) { - ctx.Data["Title"] = "Organization "+params["org"] + ctx.Data["Title"] = "Organization " + params["org"] ctx.HTML(200, "org/org") } func Members(ctx *middleware.Context, params martini.Params) { - ctx.Data["Title"] = "Organization "+params["org"]+" Members" + ctx.Data["Title"] = "Organization " + params["org"] + " Members" ctx.HTML(200, "org/members") } func Teams(ctx *middleware.Context, params martini.Params) { - ctx.Data["Title"] = "Organization "+params["org"]+" Teams" + ctx.Data["Title"] = "Organization " + params["org"] + " Teams" ctx.HTML(200, "org/teams") } func New(ctx *middleware.Context) { - ctx.Data["Title"] = "Create an Organization" - ctx.HTML(200, "org/new") + ctx.Data["Title"] = "Create An Organization" + ctx.HTML(200, NEW) +} + +func NewPost(ctx *middleware.Context, form auth.CreateOrganizationForm) { + ctx.Data["Title"] = "Create An Organization" + + if ctx.HasError() { + ctx.HTML(200, NEW) + return + } + + org := &models.User{ + Name: form.OrgName, + Email: form.Email, + IsActive: true, // NOTE: may need to set false when require e-mail confirmation. + Type: models.ORGANIZATION, + } + + var err error + if org, err = models.CreateOrganization(org, ctx.User); err != nil { + switch err { + case models.ErrUserAlreadyExist: + ctx.Data["Err_OrgName"] = true + ctx.RenderWithErr("Organization name has been already taken", NEW, &form) + case models.ErrEmailAlreadyUsed: + ctx.Data["Err_Email"] = true + ctx.RenderWithErr("E-mail address has been already used", NEW, &form) + case models.ErrUserNameIllegal: + ctx.Data["Err_OrgName"] = true + ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), NEW, &form) + default: + ctx.Handle(500, "user.NewPost(CreateUser)", err) + } + return + } + log.Trace("%s Organization created: %s", ctx.Req.RequestURI, org.Name) + + ctx.Redirect("/org/" + form.OrgName + "/dashboard") } func Dashboard(ctx *middleware.Context, params martini.Params) { ctx.Data["Title"] = "Dashboard" - ctx.HTML(200, "org/dashboard") + ctx.Data["PageIsUserDashboard"] = true + ctx.Data["PageIsOrgDashboard"] = true + + org, err := models.GetUserByName(params["org"]) + if err != nil { + if err == models.ErrUserNotExist { + ctx.Handle(404, "org.Dashboard(GetUserByName)", err) + } else { + ctx.Handle(500, "org.Dashboard(GetUserByName)", err) + } + return + } + + if err := ctx.User.GetOrganizations(); err != nil { + ctx.Handle(500, "home.Dashboard(GetOrganizations)", err) + return + } + ctx.Data["Orgs"] = ctx.User.Orgs + ctx.Data["ContextUser"] = org + + ctx.Data["MyRepos"], err = models.GetRepositories(org.Id, true) + if err != nil { + ctx.Handle(500, "org.Dashboard(GetRepositories)", err) + return + } + + actions, err := models.GetFeeds(org.Id, 0, false) + if err != nil { + ctx.Handle(500, "org.Dashboard(GetFeeds)", err) + return + } + ctx.Data["Feeds"] = actions + + ctx.HTML(200, user.DASHBOARD) } func Setting(ctx *middleware.Context, param martini.Params) { diff --git a/routers/repo/http.go b/routers/repo/http.go index d2bff299..981266d5 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -107,9 +107,9 @@ func Http(ctx *middleware.Context, params martini.Params) { } if !isPublicPull { - var tp = models.AU_WRITABLE + var tp = models.WRITABLE if isPull { - tp = models.AU_READABLE + tp = models.READABLE } has, err := models.HasAccess(authUsername, username+"/"+reponame, tp) @@ -117,8 +117,8 @@ func Http(ctx *middleware.Context, params martini.Params) { ctx.Handle(401, "no basic auth and digit auth", nil) return } else if !has { - if tp == models.AU_READABLE { - has, err = models.HasAccess(authUsername, username+"/"+reponame, models.AU_WRITABLE) + if tp == models.READABLE { + has, err = models.HasAccess(authUsername, username+"/"+reponame, models.WRITABLE) if err != nil || !has { ctx.Handle(401, "no basic auth and digit auth", nil) return diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 6479cb30..3d48e79c 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -175,7 +175,7 @@ func CollaborationPost(ctx *middleware.Context) { ctx.Redirect(ctx.Req.RequestURI) return } - has, err := models.HasAccess(name, repoLink, models.AU_WRITABLE) + has, err := models.HasAccess(name, repoLink, models.WRITABLE) if err != nil { ctx.Handle(500, "setting.CollaborationPost(HasAccess)", err) return @@ -196,7 +196,7 @@ func CollaborationPost(ctx *middleware.Context) { } if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink, - Mode: models.AU_WRITABLE}); err != nil { + Mode: models.WRITABLE}); err != nil { ctx.Handle(500, "setting.CollaborationPost(AddAccess)", err) return } diff --git a/routers/user/home.go b/routers/user/home.go index 0f2cee25..86907b5a 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -20,7 +20,7 @@ import ( const ( DASHBOARD base.TplName = "user/dashboard" PROFILE base.TplName = "user/profile" - ISSUES base.TplName = "user/issue" + ISSUES base.TplName = "user/issues" PULLS base.TplName = "user/pulls" STARS base.TplName = "user/stars" ) @@ -29,6 +29,13 @@ func Dashboard(ctx *middleware.Context) { ctx.Data["Title"] = "Dashboard" ctx.Data["PageIsUserDashboard"] = true + if err := ctx.User.GetOrganizations(); err != nil { + ctx.Handle(500, "home.Dashboard(GetOrganizations)", err) + return + } + ctx.Data["Orgs"] = ctx.User.Orgs + ctx.Data["ContextUser"] = ctx.User + var err error ctx.Data["MyRepos"], err = models.GetRepositories(ctx.User.Id, true) if err != nil { @@ -53,7 +60,7 @@ func Dashboard(ctx *middleware.Context) { for _, act := range actions { if act.IsPrivate { if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, - models.AU_READABLE); !has { + models.READABLE); !has { continue } } @@ -131,7 +138,7 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) { for _, act := range actions { if act.IsPrivate { if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, - models.AU_READABLE); !has { + models.READABLE); !has { continue } } diff --git a/routers/user/user.go b/routers/user/user.go index 8144730e..a50f126c 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -226,7 +226,7 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { } var err error - if u, err = models.RegisterUser(u); err != nil { + if u, err = models.CreateUser(u); err != nil { switch err { case models.ErrUserAlreadyExist: ctx.Data["Err_UserName"] = true @@ -235,13 +235,14 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { ctx.Data["Err_Email"] = true ctx.RenderWithErr("E-mail address has been already used", SIGNUP, &form) case models.ErrUserNameIllegal: + ctx.Data["Err_UserName"] = true ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), SIGNUP, &form) default: - ctx.Handle(500, "user.SignUpPost(RegisterUser)", err) + ctx.Handle(500, "user.SignUpPost(CreateUser)", err) } return } - log.Trace("%s User created: %s", ctx.Req.RequestURI, form.UserName) + log.Trace("%s User created: %s", ctx.Req.RequestURI, u.Name) // Bind social account. if isOauth { diff --git a/templates/VERSION b/templates/VERSION index 8c2be60b..b5cda695 100644 --- a/templates/VERSION +++ b/templates/VERSION @@ -1 +1 @@ -0.4.5.0624 Alpha \ No newline at end of file +0.4.5.0625 Alpha \ No newline at end of file diff --git a/templates/org/dashboard.tmpl b/templates/org/dashboard.tmpl deleted file mode 100644 index f86de1f4..00000000 --- a/templates/org/dashboard.tmpl +++ /dev/null @@ -1,73 +0,0 @@ -{{template "base/head" .}} -{{template "base/navbar" .}} -
-
-
- - - -
- -

News Feed

-
-
-
- {{if .HasInfo}}
{{.InfoMsg}}
{{end}} -
-
    - {{range .Feeds}} -
  • - -
    {{TimeSince .Created}}
    {{ActionDesc . | str2html}}
    - -
  • - {{else}} -
  • Oh. Looks like there isn't any activity here yet. Get Busy!
  • - {{end}} -
-
-
-
-
Repositories -
- - -
-
- -
- -
-
-
-
-{{template "base/footer" .}} diff --git a/templates/org/new.tmpl b/templates/org/new.tmpl index baa9c9df..bb46db4a 100644 --- a/templates/org/new.tmpl +++ b/templates/org/new.tmpl @@ -1,22 +1,14 @@ {{template "base/head" .}} {{template "base/navbar" .}}
-
+ {{.CsrfTokenHtml}}

Create New Organization

{{template "base/alert" .}} -
- -
-

{{.SignedUserName}}

- -
-
- -
+
- + Great organization names are short and memorable.
@@ -24,18 +16,10 @@
- + Organization's Email receives all notifications and confirmations.
- -
diff --git a/templates/user/dashboard.tmpl b/templates/user/dashboard.tmpl index 12018ad8..e1b43e15 100644 --- a/templates/user/dashboard.tmpl +++ b/templates/user/dashboard.tmpl @@ -4,29 +4,46 @@
-

News Feed

+
{{if .HasInfo}}
{{.InfoMsg}}
{{end}}
@@ -44,7 +61,7 @@
-
Your Repositories +
{{if not .PageIsOrgDashboard}}Your {{end}}Repositories
- + + {{if not .PageIsOrgDashboard}}
Collaborative Repositories
@@ -78,6 +96,7 @@
+ {{end}}
{{template "base/footer" .}} diff --git a/templates/user/issues.tmpl b/templates/user/issues.tmpl index d1c2bd99..c4ad64a4 100644 --- a/templates/user/issues.tmpl +++ b/templates/user/issues.tmpl @@ -3,7 +3,7 @@
+
{{if .HasInfo}}
{{.InfoMsg}}
{{end}}
-- cgit v1.2.3 From 6e448b07145fbb090e0da6deb97f244c2bfd7ba7 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 28 Jun 2014 00:40:07 -0400 Subject: Finish delete organization --- cmd/web.go | 3 ++- gogs.go | 2 +- models/org.go | 44 ++++++++++++++++++++++++++++++++++++++++++ models/repo.go | 3 ++- models/user.go | 21 +++++--------------- modules/middleware/repo.go | 1 + routers/org/org.go | 45 ++++++++++++++++++++++++++++++++++++++++++- routers/repo/setting.go | 18 +++++++++++++---- routers/user/user.go | 2 +- templates/VERSION | 2 +- templates/user/dashboard.tmpl | 2 +- 11 files changed, 116 insertions(+), 27 deletions(-) (limited to 'modules/middleware') diff --git a/cmd/web.go b/cmd/web.go index 1668fae2..7387d445 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -194,13 +194,14 @@ func runWeb(*cli.Context) { r.Get("/:org", org.Organization) r.Get("/:org/dashboard", org.Dashboard) r.Get("/:org/members", org.Members) - // organization teams + r.Get("/:org/teams/:team/edit", org.EditTeam) r.Get("/:org/teams/new", org.NewTeam) r.Get("/:org/teams", org.Teams) r.Get("/:org/settings", org.Settings) r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost) + r.Post("/:org/settings/delete", org.DeletePost) }, reqSignIn) m.Group("/:username/:reponame", func(r martini.Router) { diff --git a/gogs.go b/gogs.go index d56760ab..3ad059bc 100644 --- a/gogs.go +++ b/gogs.go @@ -17,7 +17,7 @@ import ( "github.com/gogits/gogs/modules/setting" ) -const APP_VER = "0.4.5.0627 Alpha" +const APP_VER = "0.4.5.0628 Alpha" func init() { runtime.GOMAXPROCS(runtime.NumCPU()) diff --git a/models/org.go b/models/org.go index 553a46aa..025759b0 100644 --- a/models/org.go +++ b/models/org.go @@ -10,6 +10,16 @@ import ( "github.com/gogits/gogs/modules/base" ) +// GetOwnerTeam returns owner team of organization. +func (org *User) GetOwnerTeam() (*Team, error) { + t := &Team{ + OrgId: org.Id, + Name: OWNER_TEAM, + } + _, err := x.Get(t) + return t, err +} + // CreateOrganization creates record of a new organization. func CreateOrganization(org, owner *User) (*User, error) { if !IsLegalName(org.Name) { @@ -86,6 +96,34 @@ func CreateOrganization(org, owner *User) (*User, error) { return org, sess.Commit() } +// TODO: need some kind of mechanism to record failure. +// DeleteOrganization completely and permanently deletes everything of organization. +func DeleteOrganization(org *User) (err error) { + if err := DeleteUser(org); err != nil { + return err + } + + sess := x.NewSession() + defer sess.Close() + if err = sess.Begin(); err != nil { + return err + } + + if _, err = sess.Delete(&Team{OrgId: org.Id}); err != nil { + sess.Rollback() + return err + } + if _, err = sess.Delete(&OrgUser{OrgId: org.Id}); err != nil { + sess.Rollback() + return err + } + if _, err = sess.Delete(&TeamUser{OrgId: org.Id}); err != nil { + sess.Rollback() + return err + } + return sess.Commit() +} + type AuthorizeType int const ( @@ -158,6 +196,12 @@ func GetOrganizationCount(u *User) (int64, error) { return x.Where("uid=?", u.Id).Count(new(OrgUser)) } +// IsOrganizationOwner returns true if given user ID is in the owner team. +func IsOrganizationOwner(orgId, uid int64) bool { + has, _ := x.Where("is_owner=?", true).Get(&OrgUser{Uid: uid, OrgId: orgId}) + return has +} + // ___________ ____ ___ // \__ ___/___ _____ _____ | | \______ ___________ // | |_/ __ \\__ \ / \| | / ___// __ \_ __ \ diff --git a/models/repo.go b/models/repo.go index 85f2a913..3d38ed66 100644 --- a/models/repo.go +++ b/models/repo.go @@ -733,7 +733,7 @@ func UpdateRepository(repo *Repository) error { } // DeleteRepository deletes a repository for a user or orgnaztion. -func DeleteRepository(userId, repoId int64, userName string) (err error) { +func DeleteRepository(userId, repoId int64, userName string) error { repo := &Repository{Id: repoId, OwnerId: userId} has, err := x.Get(repo) if err != nil { @@ -747,6 +747,7 @@ func DeleteRepository(userId, repoId int64, userName string) (err error) { if err = sess.Begin(); err != nil { return err } + if _, err = sess.Delete(&Repository{Id: repoId}); err != nil { sess.Rollback() return err diff --git a/models/user.go b/models/user.go index 8ffad266..9b0bdebe 100644 --- a/models/user.go +++ b/models/user.go @@ -105,10 +105,12 @@ func (u *User) EncodePasswd() { u.Passwd = fmt.Sprintf("%x", newPasswd) } +// IsOrganization returns true if user is actually a organization. func (u *User) IsOrganization() bool { return u.Type == ORGANIZATION } +// GetOrganizations returns all organizations that user belongs to. func (u *User) GetOrganizations() error { ous, err := GetOrgUsersByUserId(u.Id) if err != nil { @@ -125,16 +127,6 @@ func (u *User) GetOrganizations() error { return nil } -// GetOwnerTeam returns owner team of organization. -func (org *User) GetOwnerTeam() (*Team, error) { - t := &Team{ - OrgId: org.Id, - Name: OWNER_TEAM, - } - _, err := x.Get(t) - return t, err -} - // IsUserExist checks if given user name exist, // the user name should be noncased unique. func IsUserExist(name string) (bool, error) { @@ -327,7 +319,8 @@ func UpdateUser(u *User) (err error) { return err } -// DeleteUser completely deletes everything of the user. +// TODO: need some kind of mechanism to record failure. +// DeleteUser completely and permanently deletes everything of user. func DeleteUser(u *User) error { // Check ownership of repository. count, err := GetRepositoryCount(u) @@ -346,32 +339,28 @@ func DeleteUser(u *User) error { } // TODO: check issues, other repos' commits + // TODO: roll backable in some point. // Delete all followers. if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil { return err } - // Delete oauth2. if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil { return err } - // Delete all feeds. if _, err = x.Delete(&Action{UserId: u.Id}); err != nil { return err } - // Delete all watches. if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil { return err } - // Delete all accesses. if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil { return err } - // Delete all SSH keys. keys := make([]*PublicKey, 0, 10) if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil { diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index 43ba1e8c..0c640275 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -44,6 +44,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { repoName := params["reponame"] refName := params["branchname"] + // TODO: need more advanced onwership and access level check. // Collaborators who have write access can be seen as owners. if ctx.IsSigned { ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE) diff --git a/routers/org/org.go b/routers/org/org.go index c036a8e5..7b2c4d73 100644 --- a/routers/org/org.go +++ b/routers/org/org.go @@ -30,7 +30,6 @@ func Members(ctx *middleware.Context, params martini.Params) { ctx.HTML(200, "org/members") } - func New(ctx *middleware.Context) { ctx.Data["Title"] = "Create An Organization" ctx.HTML(200, NEW) @@ -160,3 +159,47 @@ func SettingsPost(ctx *middleware.Context, params martini.Params, form auth.OrgS ctx.Flash.Success("Organization profile has been successfully updated.") ctx.Redirect("/org/" + org.Name + "/settings") } + +func DeletePost(ctx *middleware.Context, params martini.Params) { + ctx.Data["Title"] = "Settings" + + org, err := models.GetUserByName(params["org"]) + if err != nil { + if err == models.ErrUserNotExist { + ctx.Handle(404, "org.DeletePost(GetUserByName)", err) + } else { + ctx.Handle(500, "org.DeletePost(GetUserByName)", err) + } + return + } + ctx.Data["Org"] = org + + if !models.IsOrganizationOwner(org.Id, ctx.User.Id) { + ctx.Error(403) + return + } + + tmpUser := models.User{ + Passwd: ctx.Query("password"), + Salt: ctx.User.Salt, + } + tmpUser.EncodePasswd() + if tmpUser.Passwd != ctx.User.Passwd { + ctx.Flash.Error("Password is not correct. Make sure you are owner of this account.") + } else { + if err := models.DeleteOrganization(org); err != nil { + switch err { + case models.ErrUserOwnRepos: + ctx.Flash.Error("This organization still have ownership of repository, you have to delete or transfer them first.") + default: + ctx.Handle(500, "org.DeletePost(DeleteOrganization)", err) + return + } + } else { + ctx.Redirect("/") + return + } + } + + ctx.Redirect("/org/" + org.Name + "/settings") +} diff --git a/routers/repo/setting.go b/routers/repo/setting.go index 3d48e79c..e97eca12 100644 --- a/routers/repo/setting.go +++ b/routers/repo/setting.go @@ -122,13 +122,23 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { return } - if err := models.DeleteRepository(ctx.User.Id, ctx.Repo.Repository.Id, ctx.User.LowerName); err != nil { - ctx.Handle(500, "setting.Delete", err) + if ctx.Repo.Owner.IsOrganization() && + !models.IsOrganizationOwner(ctx.Repo.Owner.Id, ctx.User.Id) { + ctx.Error(403) return } - log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, ctx.Repo.Repository.LowerName) - ctx.Redirect("/") + if err := models.DeleteRepository(ctx.Repo.Owner.Id, ctx.Repo.Repository.Id, ctx.Repo.Owner.Name); err != nil { + ctx.Handle(500, "setting.Delete(DeleteRepository)", err) + return + } + log.Trace("%s Repository deleted: %s/%s", ctx.Req.RequestURI, ctx.Repo.Owner.LowerName, ctx.Repo.Repository.LowerName) + + if ctx.Repo.Owner.IsOrganization() { + ctx.Redirect("/org/" + ctx.Repo.Owner.Name + "/dashboard") + } else { + ctx.Redirect("/") + } } } diff --git a/routers/user/user.go b/routers/user/user.go index a402744b..561fe1c1 100644 --- a/routers/user/user.go +++ b/routers/user/user.go @@ -296,7 +296,7 @@ func DeletePost(ctx *middleware.Context) { case models.ErrUserOwnRepos: ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.") default: - ctx.Handle(500, "user.Delete(DeleteUser)", err) + ctx.Handle(500, "user.DeletePost(DeleteUser)", err) return } } else { diff --git a/templates/VERSION b/templates/VERSION index be0ebee0..09c51980 100644 --- a/templates/VERSION +++ b/templates/VERSION @@ -1 +1 @@ -0.4.5.0627 Alpha \ No newline at end of file +0.4.5.0628 Alpha \ No newline at end of file diff --git a/templates/user/dashboard.tmpl b/templates/user/dashboard.tmpl index e1b43e15..2cb19cef 100644 --- a/templates/user/dashboard.tmpl +++ b/templates/user/dashboard.tmpl @@ -76,7 +76,7 @@