Conflicts: models/update.go routers/repo/http.gotags/v1.2.0-rc1
| @@ -75,9 +75,6 @@ There are 5 ways to install Gogs: | |||||
| The [core team](http://gogs.io/team) of this project. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors. | The [core team](http://gogs.io/team) of this project. See [contributors page](https://github.com/gogits/gogs/graphs/contributors) for full list of contributors. | ||||
| [][koding] | |||||
| [koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1 | |||||
| ## License | ## License | ||||
| This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text. | This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text. | ||||
| @@ -66,9 +66,6 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依 | |||||
| 本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。 | 本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。 | ||||
| [][koding] | |||||
| [koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1 | |||||
| ## 授权许可 | ## 授权许可 | ||||
| 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。 | 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。 | ||||
| @@ -56,19 +56,19 @@ func parseCmd(cmd string) (string, string) { | |||||
| } | } | ||||
| var ( | 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] | _, e := sl[b] | ||||
| return e | return e | ||||
| } | } | ||||
| @@ -129,7 +129,7 @@ func runServ(k *cli.Context) { | |||||
| // Access check. | // Access check. | ||||
| switch { | switch { | ||||
| case isWrite: | 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 { | if err != nil { | ||||
| println("Gogs: internal error:", err) | println("Gogs: internal error:", err) | ||||
| log.GitLogger.Fatal("Fail to check write access:", err) | log.GitLogger.Fatal("Fail to check write access:", err) | ||||
| @@ -152,7 +152,7 @@ func runServ(k *cli.Context) { | |||||
| break | 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 { | if err != nil { | ||||
| println("Gogs: internal error:", err) | println("Gogs: internal error:", err) | ||||
| log.GitLogger.Fatal("Fail to check read access:", err) | log.GitLogger.Fatal("Fail to check read access:", err) | ||||
| @@ -42,5 +42,7 @@ func runUpdate(c *cli.Context) { | |||||
| repoUserName := os.Getenv("repoUserName") | repoUserName := os.Getenv("repoUserName") | ||||
| repoName := os.Getenv("repoName") | repoName := os.Getenv("repoName") | ||||
| models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId) | |||||
| if err := models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId); err != nil { | |||||
| log.GitLogger.Fatal(err.Error()) | |||||
| } | |||||
| } | } | ||||
| @@ -188,9 +188,20 @@ func runWeb(*cli.Context) { | |||||
| reqOwner := middleware.RequireOwner() | 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.CreateOrgForm{}), org.NewPost) | |||||
| r.Get("/:org", org.Organization) | 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) | |||||
| }, reqSignIn) | |||||
| m.Group("/:username/:reponame", func(r martini.Router) { | m.Group("/:username/:reponame", func(r martini.Router) { | ||||
| r.Get("/settings", repo.Setting) | r.Get("/settings", repo.Setting) | ||||
| @@ -51,8 +51,8 @@ SECRET_KEY = !#@FDEWREWR&*( | |||||
| LOGIN_REMEMBER_DAYS = 7 | LOGIN_REMEMBER_DAYS = 7 | ||||
| COOKIE_USERNAME = gogs_awesome | COOKIE_USERNAME = gogs_awesome | ||||
| COOKIE_REMEMBER_NAME = gogs_incredible | COOKIE_REMEMBER_NAME = gogs_incredible | ||||
| ; Reverse proxy authentication header name of user ID | |||||
| REVERSE_PROXY_AUTHENTICATION_UID = X-WEBAUTH-UID | |||||
| ; Reverse proxy authentication header name of user name | |||||
| REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER | |||||
| [service] | [service] | ||||
| ACTIVE_CODE_LIVE_MINUTES = 180 | ACTIVE_CODE_LIVE_MINUTES = 180 | ||||
| @@ -17,7 +17,7 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| const APP_VER = "0.4.5.0621 Alpha" | |||||
| const APP_VER = "0.4.5.0627 Alpha" | |||||
| func init() { | func init() { | ||||
| runtime.GOMAXPROCS(runtime.NumCPU()) | runtime.GOMAXPROCS(runtime.NumCPU()) | ||||
| @@ -11,19 +11,20 @@ import ( | |||||
| "github.com/go-xorm/xorm" | "github.com/go-xorm/xorm" | ||||
| ) | ) | ||||
| // Access types. | |||||
| type AccessType int | |||||
| const ( | const ( | ||||
| AU_READABLE = iota + 1 | |||||
| AU_WRITABLE | |||||
| READABLE AccessType = iota + 1 | |||||
| WRITABLE | |||||
| ) | ) | ||||
| // Access represents the accessibility of user to repository. | // Access represents the accessibility of user to repository. | ||||
| type Access struct { | type Access struct { | ||||
| Id int64 | Id int64 | ||||
| UserName string `xorm:"unique(s)"` | |||||
| RepoName string `xorm:"unique(s)"` // <user name>/<repo name> | |||||
| Mode int `xorm:"unique(s)"` | |||||
| Created time.Time `xorm:"created"` | |||||
| UserName string `xorm:"unique(s)"` | |||||
| RepoName string `xorm:"unique(s)"` // <user name>/<repo name> | |||||
| Mode AccessType `xorm:"unique(s)"` | |||||
| Created time.Time `xorm:"created"` | |||||
| } | } | ||||
| // AddAccess adds new access record. | // 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. | // HasAccess returns true if someone can read or write to given repository. | ||||
| // The repoName should be in format <username>/<reponame>. | // The repoName should be in format <username>/<reponame>. | ||||
| func HasAccess(uname, repoName string, mode int) (bool, error) { | |||||
| func HasAccess(uname, repoName string, mode AccessType) (bool, error) { | |||||
| if len(repoName) == 0 { | if len(repoName) == 0 { | ||||
| return false, nil | return false, nil | ||||
| } | } | ||||
| @@ -182,14 +182,15 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string, | |||||
| } | } | ||||
| // NewRepoAction adds new action for creating repository. | // NewRepoAction adds new action for creating repository. | ||||
| func NewRepoAction(user *User, repo *Repository) (err error) { | |||||
| if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email, | |||||
| OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name, IsPrivate: repo.IsPrivate}); err != nil { | |||||
| log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name) | |||||
| func NewRepoAction(u *User, repo *Repository) (err error) { | |||||
| if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email, | |||||
| OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name, | |||||
| IsPrivate: repo.IsPrivate}); err != nil { | |||||
| log.Error("action.NewRepoAction(notify watchers): %d/%s", u.Id, repo.Name) | |||||
| return err | return err | ||||
| } | } | ||||
| log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName) | |||||
| log.Trace("action.NewRepoAction: %s/%s", u.LowerName, repo.LowerName) | |||||
| return err | return err | ||||
| } | } | ||||
| @@ -213,9 +213,9 @@ func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 { | |||||
| // IssueUser represents an issue-user relation. | // IssueUser represents an issue-user relation. | ||||
| type IssueUser struct { | type IssueUser struct { | ||||
| Id int64 | Id int64 | ||||
| Uid int64 // User ID. | |||||
| Uid int64 `xorm:"INDEX"` // User ID. | |||||
| IssueId int64 | IssueId int64 | ||||
| RepoId int64 | |||||
| RepoId int64 `xorm:"INDEX"` | |||||
| MilestoneId int64 | MilestoneId int64 | ||||
| IsRead bool | IsRead bool | ||||
| IsAssigned bool | IsAssigned bool | ||||
| @@ -255,7 +255,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L | |||||
| Email: mail, | Email: mail, | ||||
| } | } | ||||
| return RegisterUser(user) | |||||
| return CreateUser(user) | |||||
| } | } | ||||
| type loginAuth struct { | type loginAuth struct { | ||||
| @@ -359,5 +359,5 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S | |||||
| Passwd: passwd, | Passwd: passwd, | ||||
| Email: name, | Email: name, | ||||
| } | } | ||||
| return RegisterUser(user) | |||||
| return CreateUser(user) | |||||
| } | } | ||||
| @@ -35,7 +35,7 @@ func init() { | |||||
| tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch), | ||||
| new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow), | ||||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser), | 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() { | func LoadModelsConfig() { | ||||
| @@ -0,0 +1,192 @@ | |||||
| // 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 | |||||
| import ( | |||||
| "strings" | |||||
| "github.com/gogits/gogs/modules/base" | |||||
| ) | |||||
| // CreateOrganization creates record of a new organization. | |||||
| func CreateOrganization(org, owner *User) (*User, error) { | |||||
| if !IsLegalName(org.Name) { | |||||
| return nil, ErrUserNameIllegal | |||||
| } | |||||
| isExist, err := IsUserExist(org.Name) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if isExist { | |||||
| return nil, ErrUserAlreadyExist | |||||
| } | |||||
| isExist, err = IsEmailUsed(org.Email) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } else if isExist { | |||||
| return nil, ErrEmailAlreadyUsed | |||||
| } | |||||
| org.LowerName = strings.ToLower(org.Name) | |||||
| org.FullName = 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 | |||||
| } | |||||
| // Create default owner team. | |||||
| t := &Team{ | |||||
| OrgId: org.Id, | |||||
| Name: OWNER_TEAM, | |||||
| Authorize: ORG_ADMIN, | |||||
| NumMembers: 1, | |||||
| } | |||||
| if _, err = sess.Insert(t); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | |||||
| // Add initial creator to organization and owner team. | |||||
| ou := &OrgUser{ | |||||
| Uid: owner.Id, | |||||
| OrgId: org.Id, | |||||
| IsOwner: true, | |||||
| NumTeam: 1, | |||||
| } | |||||
| 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() | |||||
| } | |||||
| type AuthorizeType int | |||||
| const ( | |||||
| ORG_READABLE AuthorizeType = iota + 1 | |||||
| ORG_WRITABLE | |||||
| ORG_ADMIN | |||||
| ) | |||||
| const OWNER_TEAM = "Owner" | |||||
| // Team represents a organization team. | |||||
| type Team struct { | |||||
| Id int64 | |||||
| OrgId int64 `xorm:"INDEX"` | |||||
| Name string | |||||
| Description string | |||||
| Authorize AuthorizeType | |||||
| RepoIds string `xorm:"TEXT"` | |||||
| NumMembers int | |||||
| NumRepos int | |||||
| } | |||||
| // NewTeam creates a record of new team. | |||||
| func NewTeam(t *Team) error { | |||||
| _, err := x.Insert(t) | |||||
| return err | |||||
| } | |||||
| func UpdateTeam(t *Team) error { | |||||
| if len(t.Description) > 255 { | |||||
| t.Description = t.Description[:255] | |||||
| } | |||||
| _, err := x.Id(t.Id).AllCols().Update(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 | |||||
| } | |||||
| // GetOrgUsersByOrgId returns all organization-user relations by organization ID. | |||||
| func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) { | |||||
| ous := make([]*OrgUser, 0, 10) | |||||
| err := x.Where("org_id=?", orgId).Find(&ous) | |||||
| return ous, err | |||||
| } | |||||
| func GetOrganizationCount(u *User) (int64, error) { | |||||
| return x.Where("uid=?", u.Id).Count(new(OrgUser)) | |||||
| } | |||||
| // ___________ ____ ___ | |||||
| // \__ ___/___ _____ _____ | | \______ ___________ | |||||
| // | |_/ __ \\__ \ / \| | / ___// __ \_ __ \ | |||||
| // | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/ | |||||
| // |____| \___ >____ /__|_| /______//____ >\___ >__| | |||||
| // \/ \/ \/ \/ \/ | |||||
| // TeamUser represents an team-user relation. | |||||
| type TeamUser struct { | |||||
| Id int64 | |||||
| Uid int64 | |||||
| OrgId int64 `xorm:"INDEX"` | |||||
| TeamId int64 | |||||
| } | |||||
| // GetTeamMembers returns all members in given team of organization. | |||||
| func GetTeamMembers(orgId, teamId int64) ([]*User, error) { | |||||
| tus := make([]*TeamUser, 0, 10) | |||||
| err := x.Where("org_id=?", orgId).And("team_id=?", teamId).Find(&tus) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| us := make([]*User, len(tus)) | |||||
| for i, tu := range tus { | |||||
| us[i], err = GetUserById(tu.Uid) | |||||
| if err != nil { | |||||
| return nil, err | |||||
| } | |||||
| } | |||||
| return us, nil | |||||
| } | |||||
| @@ -158,7 +158,7 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) { | |||||
| } | } | ||||
| var ( | 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"} | illegalSuffixs = []string{".git"} | ||||
| ) | ) | ||||
| @@ -240,7 +240,7 @@ func MirrorUpdate() { | |||||
| "git", "remote", "update"); err != nil { | "git", "remote", "update"); err != nil { | ||||
| return errors.New("git remote update: " + stderr) | return errors.New("git remote update: " + stderr) | ||||
| } else if err = git.UnpackRefs(repoPath); err != nil { | } else if err = git.UnpackRefs(repoPath); err != nil { | ||||
| return err | |||||
| return errors.New("UnpackRefs: " + err.Error()) | |||||
| } | } | ||||
| m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour) | m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour) | ||||
| @@ -251,8 +251,8 @@ func MirrorUpdate() { | |||||
| } | } | ||||
| // MigrateRepository migrates a existing repository from other project hosting. | // MigrateRepository migrates a existing repository from other project hosting. | ||||
| func MigrateRepository(user *User, name, desc string, private, mirror bool, url string) (*Repository, error) { | |||||
| repo, err := CreateRepository(user, name, desc, "", "", private, mirror, false) | |||||
| func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) { | |||||
| repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -261,11 +261,11 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url | |||||
| tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond())) | tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond())) | ||||
| os.MkdirAll(tmpDir, os.ModePerm) | os.MkdirAll(tmpDir, os.ModePerm) | ||||
| repoPath := RepoPath(user.Name, name) | |||||
| repoPath := RepoPath(u.Name, name) | |||||
| repo.IsBare = false | repo.IsBare = false | ||||
| if mirror { | if mirror { | ||||
| if err = MirrorRepository(repo.Id, user.Name, repo.Name, repoPath, url); err != nil { | |||||
| if err = MirrorRepository(repo.Id, u.Name, repo.Name, repoPath, url); err != nil { | |||||
| return repo, err | return repo, err | ||||
| } | } | ||||
| repo.IsMirror = true | repo.IsMirror = true | ||||
| @@ -454,21 +454,28 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep | |||||
| return initRepoCommit(tmpDir, user.NewGitSig()) | return initRepoCommit(tmpDir, user.NewGitSig()) | ||||
| } | } | ||||
| // CreateRepository creates a repository for given user or orgnaziation. | |||||
| func CreateRepository(user *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) { | |||||
| // CreateRepository creates a repository for given user or organization. | |||||
| func CreateRepository(u *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) { | |||||
| if !IsLegalName(name) { | if !IsLegalName(name) { | ||||
| return nil, ErrRepoNameIllegal | return nil, ErrRepoNameIllegal | ||||
| } | } | ||||
| isExist, err := IsRepositoryExist(user, name) | |||||
| isExist, err := IsRepositoryExist(u, name) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } else if isExist { | } else if isExist { | ||||
| return nil, ErrRepoAlreadyExist | return nil, ErrRepoAlreadyExist | ||||
| } | } | ||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| if err = sess.Begin(); err != nil { | |||||
| return nil, err | |||||
| } | |||||
| repo := &Repository{ | repo := &Repository{ | ||||
| OwnerId: user.Id, | |||||
| OwnerId: u.Id, | |||||
| Owner: u, | |||||
| Name: name, | Name: name, | ||||
| LowerName: strings.ToLower(name), | LowerName: strings.ToLower(name), | ||||
| Description: desc, | Description: desc, | ||||
| @@ -479,67 +486,85 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir | |||||
| repo.DefaultBranch = "master" | repo.DefaultBranch = "master" | ||||
| } | } | ||||
| repoPath := RepoPath(user.Name, repo.Name) | |||||
| sess := x.NewSession() | |||||
| defer sess.Close() | |||||
| sess.Begin() | |||||
| if _, err = sess.Insert(repo); err != nil { | if _, err = sess.Insert(repo); err != nil { | ||||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||||
| log.Error("repo.CreateRepository(repo): %v", err) | |||||
| return nil, errors.New(fmt.Sprintf( | |||||
| "delete repo directory %s/%s failed(1): %v", user.Name, repo.Name, err2)) | |||||
| } | |||||
| sess.Rollback() | sess.Rollback() | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| mode := AU_WRITABLE | |||||
| var t *Team // Owner team. | |||||
| mode := WRITABLE | |||||
| if mirror { | if mirror { | ||||
| mode = AU_READABLE | |||||
| mode = READABLE | |||||
| } | } | ||||
| access := Access{ | |||||
| UserName: user.LowerName, | |||||
| RepoName: strings.ToLower(path.Join(user.Name, repo.Name)), | |||||
| access := &Access{ | |||||
| UserName: u.LowerName, | |||||
| RepoName: strings.ToLower(path.Join(u.Name, repo.Name)), | |||||
| Mode: mode, | Mode: mode, | ||||
| } | } | ||||
| if _, err = sess.Insert(&access); err != nil { | |||||
| sess.Rollback() | |||||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||||
| log.Error("repo.CreateRepository(access): %v", err) | |||||
| return nil, errors.New(fmt.Sprintf( | |||||
| "delete repo directory %s/%s failed(2): %v", user.Name, repo.Name, err2)) | |||||
| // Give access to all members in owner team. | |||||
| if u.IsOrganization() { | |||||
| t, err = u.GetOwnerTeam() | |||||
| if err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | |||||
| us, err := GetTeamMembers(u.Id, t.Id) | |||||
| if err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | |||||
| for _, u := range us { | |||||
| access.UserName = u.LowerName | |||||
| if _, err = sess.Insert(access); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | |||||
| } | |||||
| } else { | |||||
| if _, err = sess.Insert(access); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | } | ||||
| return nil, err | |||||
| } | } | ||||
| rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?" | rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?" | ||||
| if _, err = sess.Exec(rawSql, user.Id); err != nil { | |||||
| if _, err = sess.Exec(rawSql, u.Id); err != nil { | |||||
| sess.Rollback() | sess.Rollback() | ||||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||||
| log.Error("repo.CreateRepository(repo count): %v", err) | |||||
| return nil, errors.New(fmt.Sprintf( | |||||
| "delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2)) | |||||
| } | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| if err = sess.Commit(); err != nil { | |||||
| sess.Rollback() | |||||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||||
| log.Error("repo.CreateRepository(commit): %v", err) | |||||
| return nil, errors.New(fmt.Sprintf( | |||||
| "delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2)) | |||||
| // Update owner team info and count. | |||||
| if u.IsOrganization() { | |||||
| t.RepoIds += "$" + base.ToStr(repo.Id) + "|" | |||||
| t.NumRepos++ | |||||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | |||||
| } | } | ||||
| } | |||||
| if err = sess.Commit(); err != nil { | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| if err = WatchRepo(user.Id, repo.Id, true); err != nil { | |||||
| log.Error("repo.CreateRepository(WatchRepo): %v", err) | |||||
| if u.IsOrganization() { | |||||
| ous, err := GetOrgUsersByOrgId(u.Id) | |||||
| if err != nil { | |||||
| log.Error("repo.CreateRepository(GetOrgUsersByOrgId): %v", err) | |||||
| } else { | |||||
| for _, ou := range ous { | |||||
| if err = WatchRepo(ou.Uid, repo.Id, true); err != nil { | |||||
| log.Error("repo.CreateRepository(WatchRepo): %v", err) | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| if err = WatchRepo(u.Id, repo.Id, true); err != nil { | |||||
| log.Error("repo.CreateRepository(WatchRepo2): %v", err) | |||||
| } | } | ||||
| if err = NewRepoAction(user, repo); err != nil { | |||||
| if err = NewRepoAction(u, repo); err != nil { | |||||
| log.Error("repo.CreateRepository(NewRepoAction): %v", err) | log.Error("repo.CreateRepository(NewRepoAction): %v", err) | ||||
| } | } | ||||
| @@ -548,7 +573,13 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir | |||||
| return repo, nil | return repo, nil | ||||
| } | } | ||||
| if err = initRepository(repoPath, user, repo, initReadme, lang, license); err != nil { | |||||
| repoPath := RepoPath(u.Name, repo.Name) | |||||
| if err = initRepository(repoPath, u, repo, initReadme, lang, license); err != nil { | |||||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||||
| log.Error("repo.CreateRepository(initRepository): %v", err) | |||||
| return nil, errors.New(fmt.Sprintf( | |||||
| "delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2)) | |||||
| } | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -6,6 +6,7 @@ package models | |||||
| import ( | import ( | ||||
| "container/list" | "container/list" | ||||
| "fmt" | |||||
| "os/exec" | "os/exec" | ||||
| "strings" | "strings" | ||||
| @@ -15,13 +16,13 @@ import ( | |||||
| "github.com/gogits/gogs/modules/log" | "github.com/gogits/gogs/modules/log" | ||||
| ) | ) | ||||
| func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) { | |||||
| func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error { | |||||
| //fmt.Println(refName, oldCommitId, newCommitId) | //fmt.Println(refName, oldCommitId, newCommitId) | ||||
| //fmt.Println(userName, repoUserName, repoName) | //fmt.Println(userName, repoUserName, repoName) | ||||
| isNew := strings.HasPrefix(oldCommitId, "0000000") | isNew := strings.HasPrefix(oldCommitId, "0000000") | ||||
| if isNew && | if isNew && | ||||
| strings.HasPrefix(newCommitId, "0000000") { | strings.HasPrefix(newCommitId, "0000000") { | ||||
| log.GitLogger.Fatal("old rev and new rev both 000000") | |||||
| return fmt.Errorf("old rev and new rev both 000000") | |||||
| } | } | ||||
| f := RepoPath(repoUserName, repoName) | f := RepoPath(repoUserName, repoName) | ||||
| @@ -33,18 +34,17 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||||
| isDel := strings.HasPrefix(newCommitId, "0000000") | isDel := strings.HasPrefix(newCommitId, "0000000") | ||||
| if isDel { | if isDel { | ||||
| log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId) | log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId) | ||||
| return | |||||
| return nil | |||||
| } | } | ||||
| repo, err := git.OpenRepository(f) | repo, err := git.OpenRepository(f) | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("runUpdate.Open repoId: %v", err) | |||||
| return fmt.Errorf("runUpdate.Open repoId: %v", err) | |||||
| } | } | ||||
| newCommit, err := repo.GetCommit(newCommitId) | newCommit, err := repo.GetCommit(newCommitId) | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("runUpdate GetCommit of newCommitId: %v", err) | |||||
| return | |||||
| return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err) | |||||
| } | } | ||||
| var l *list.List | var l *list.List | ||||
| @@ -52,28 +52,27 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||||
| if isNew { | if isNew { | ||||
| l, err = newCommit.CommitsBefore() | l, err = newCommit.CommitsBefore() | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("Find CommitsBefore erro: %v", err) | |||||
| return fmt.Errorf("Find CommitsBefore erro: %v", err) | |||||
| } | } | ||||
| } else { | } else { | ||||
| l, err = newCommit.CommitsBeforeUntil(oldCommitId) | l, err = newCommit.CommitsBeforeUntil(oldCommitId) | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("Find CommitsBeforeUntil erro: %v", err) | |||||
| return | |||||
| return fmt.Errorf("Find CommitsBeforeUntil erro: %v", err) | |||||
| } | } | ||||
| } | } | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("runUpdate.Commit repoId: %v", err) | |||||
| return fmt.Errorf("runUpdate.Commit repoId: %v", err) | |||||
| } | } | ||||
| ru, err := GetUserByName(repoUserName) | ru, err := GetUserByName(repoUserName) | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("runUpdate.GetUserByName: %v", err) | |||||
| return fmt.Errorf("runUpdate.GetUserByName: %v", err) | |||||
| } | } | ||||
| repos, err := GetRepositoryByName(ru.Id, repoName) | repos, err := GetRepositoryByName(ru.Id, repoName) | ||||
| if err != nil { | if err != nil { | ||||
| log.GitLogger.Fatal("runUpdate.GetRepositoryByName userId: %v", err) | |||||
| return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err) | |||||
| } | } | ||||
| // if tags push | // if tags push | ||||
| @@ -104,6 +103,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||||
| return | return | ||||
| } | } | ||||
| // if commits push | |||||
| commits := make([]*base.PushCommit, 0) | commits := make([]*base.PushCommit, 0) | ||||
| var maxCommits = 3 | var maxCommits = 3 | ||||
| var actEmail string | var actEmail string | ||||
| @@ -126,6 +126,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName | |||||
| //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) | //commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()}) | ||||
| if err = CommitRepoAction(userId, ru.Id, userName, actEmail, | if err = CommitRepoAction(userId, ru.Id, userName, actEmail, | ||||
| repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { | repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil { | ||||
| log.GitLogger.Fatal("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | |||||
| return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err) | |||||
| } | } | ||||
| return nil | |||||
| } | } | ||||
| @@ -21,14 +21,16 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| // User types. | |||||
| type UserType int | |||||
| const ( | const ( | ||||
| UT_INDIVIDUAL = iota + 1 | |||||
| UT_ORGANIZATION | |||||
| INDIVIDUAL UserType = iota // Historic reason to make it starts at 0. | |||||
| ORGANIZATION | |||||
| ) | ) | ||||
| var ( | var ( | ||||
| ErrUserOwnRepos = errors.New("User still have ownership of repositories") | ErrUserOwnRepos = errors.New("User still have ownership of repositories") | ||||
| ErrUserHasOrgs = errors.New("User still have membership of organization") | |||||
| ErrUserAlreadyExist = errors.New("User already exist") | ErrUserAlreadyExist = errors.New("User already exist") | ||||
| ErrUserNotExist = errors.New("User does not exist") | ErrUserNotExist = errors.New("User does not exist") | ||||
| ErrUserNotKeyOwner = errors.New("User does not the owner of public key") | ErrUserNotKeyOwner = errors.New("User does not the owner of public key") | ||||
| @@ -50,7 +52,8 @@ type User struct { | |||||
| LoginType LoginType | LoginType LoginType | ||||
| LoginSource int64 `xorm:"not null default 0"` | LoginSource int64 `xorm:"not null default 0"` | ||||
| LoginName string | LoginName string | ||||
| Type int | |||||
| Type UserType | |||||
| Orgs []*User `xorm:"-"` | |||||
| NumFollowers int | NumFollowers int | ||||
| NumFollowings int | NumFollowings int | ||||
| NumStars int | NumStars int | ||||
| @@ -65,43 +68,71 @@ type User struct { | |||||
| Salt string `xorm:"VARCHAR(10)"` | Salt string `xorm:"VARCHAR(10)"` | ||||
| Created time.Time `xorm:"created"` | Created time.Time `xorm:"created"` | ||||
| Updated time.Time `xorm:"updated"` | Updated time.Time `xorm:"updated"` | ||||
| // For organization. | |||||
| Description string | |||||
| NumTeams int | |||||
| NumMembers int | |||||
| } | } | ||||
| // HomeLink returns the user home page link. | // 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. | // AvatarLink returns user gravatar link. | ||||
| func (user *User) AvatarLink() string { | |||||
| func (u *User) AvatarLink() string { | |||||
| if setting.DisableGravatar { | if setting.DisableGravatar { | ||||
| return "/img/avatar_default.jpg" | return "/img/avatar_default.jpg" | ||||
| } else if setting.Service.EnableCacheAvatar { | } 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. | // NewGitSig generates and returns the signature of given user. | ||||
| func (user *User) NewGitSig() *git.Signature { | |||||
| func (u *User) NewGitSig() *git.Signature { | |||||
| return &git.Signature{ | return &git.Signature{ | ||||
| Name: user.Name, | |||||
| Email: user.Email, | |||||
| Name: u.Name, | |||||
| Email: u.Email, | |||||
| When: time.Now(), | When: time.Now(), | ||||
| } | } | ||||
| } | } | ||||
| // EncodePasswd encodes password to safe format. | // 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) | |||||
| } | } | ||||
| // Member represents user is member of organization. | |||||
| type Member struct { | |||||
| Id int64 | |||||
| OrgId int64 `xorm:"unique(member) index"` | |||||
| UserId int64 `xorm:"unique(member)"` | |||||
| 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 | |||||
| } | |||||
| // 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, | // IsUserExist checks if given user name exist, | ||||
| @@ -126,49 +157,60 @@ func GetUserSalt() string { | |||||
| return base.GetRandomString(10) | return base.GetRandomString(10) | ||||
| } | } | ||||
| // RegisterUser creates record of a new user. | |||||
| func RegisterUser(user *User) (*User, error) { | |||||
| if !IsLegalName(user.Name) { | |||||
| // CreateUser creates record of a new user. | |||||
| func CreateUser(u *User) (*User, error) { | |||||
| if !IsLegalName(u.Name) { | |||||
| return nil, ErrUserNameIllegal | return nil, ErrUserNameIllegal | ||||
| } | } | ||||
| isExist, err := IsUserExist(user.Name) | |||||
| isExist, err := IsUserExist(u.Name) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } else if isExist { | } else if isExist { | ||||
| return nil, ErrUserAlreadyExist | return nil, ErrUserAlreadyExist | ||||
| } | } | ||||
| isExist, err = IsEmailUsed(user.Email) | |||||
| isExist, err = IsEmailUsed(u.Email) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, err | return nil, err | ||||
| } else if isExist { | } else if isExist { | ||||
| return nil, ErrEmailAlreadyUsed | 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 { | |||||
| 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 _, err = sess.Insert(u); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | 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)) | |||||
| } | |||||
| } | |||||
| if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil { | |||||
| sess.Rollback() | |||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| if user.Id == 1 { | |||||
| user.IsAdmin = true | |||||
| user.IsActive = true | |||||
| _, err = x.Id(user.Id).UseBool().Update(user) | |||||
| if err = sess.Commit(); err != nil { | |||||
| return nil, err | |||||
| } | } | ||||
| return user, 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 | |||||
| } | } | ||||
| // GetUsers returns given number of user objects with offset. | // GetUsers returns given number of user objects with offset. | ||||
| @@ -277,51 +319,62 @@ func UpdateUser(u *User) (err error) { | |||||
| if len(u.Website) > 255 { | if len(u.Website) > 255 { | ||||
| u.Website = u.Website[:255] | u.Website = u.Website[:255] | ||||
| } | } | ||||
| if len(u.Description) > 255 { | |||||
| u.Description = u.Description[:255] | |||||
| } | |||||
| _, err = x.Id(u.Id).AllCols().Update(u) | _, err = x.Id(u.Id).AllCols().Update(u) | ||||
| return err | return err | ||||
| } | } | ||||
| // DeleteUser completely deletes everything of the user. | // DeleteUser completely deletes everything of the user. | ||||
| func DeleteUser(user *User) error { | |||||
| func DeleteUser(u *User) error { | |||||
| // Check ownership of repository. | // Check ownership of repository. | ||||
| count, err := GetRepositoryCount(user) | |||||
| count, err := GetRepositoryCount(u) | |||||
| if err != nil { | if err != nil { | ||||
| return errors.New("modesl.GetRepositories: " + err.Error()) | |||||
| return errors.New("modesl.GetRepositories(GetRepositoryCount): " + err.Error()) | |||||
| } else if count > 0 { | } else if count > 0 { | ||||
| return ErrUserOwnRepos | return ErrUserOwnRepos | ||||
| } | } | ||||
| // Check membership of organization. | |||||
| count, err = GetOrganizationCount(u) | |||||
| if err != nil { | |||||
| return errors.New("modesl.GetRepositories(GetOrganizationCount): " + err.Error()) | |||||
| } else if count > 0 { | |||||
| return ErrUserHasOrgs | |||||
| } | |||||
| // TODO: check issues, other repos' commits | // TODO: check issues, other repos' commits | ||||
| // Delete all followers. | // Delete all followers. | ||||
| if _, err = x.Delete(&Follow{FollowId: user.Id}); err != nil { | |||||
| if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| // Delete oauth2. | // Delete oauth2. | ||||
| if _, err = x.Delete(&Oauth2{Uid: user.Id}); err != nil { | |||||
| if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| // Delete all feeds. | // Delete all feeds. | ||||
| if _, err = x.Delete(&Action{UserId: user.Id}); err != nil { | |||||
| if _, err = x.Delete(&Action{UserId: u.Id}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| // Delete all watches. | // Delete all watches. | ||||
| if _, err = x.Delete(&Watch{UserId: user.Id}); err != nil { | |||||
| if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| // Delete all accesses. | // Delete all accesses. | ||||
| if _, err = x.Delete(&Access{UserName: user.LowerName}); err != nil { | |||||
| if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| // Delete all SSH keys. | // Delete all SSH keys. | ||||
| keys := make([]*PublicKey, 0, 10) | keys := make([]*PublicKey, 0, 10) | ||||
| if err = x.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil { | |||||
| if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| for _, key := range keys { | for _, key := range keys { | ||||
| @@ -331,11 +384,11 @@ func DeleteUser(user *User) error { | |||||
| } | } | ||||
| // Delete user directory. | // Delete user directory. | ||||
| if err = os.RemoveAll(UserPath(user.Name)); err != nil { | |||||
| if err = os.RemoveAll(UserPath(u.Name)); err != nil { | |||||
| return err | return err | ||||
| } | } | ||||
| _, err = x.Delete(user) | |||||
| _, err = x.Delete(u) | |||||
| return err | return err | ||||
| } | } | ||||
| @@ -0,0 +1,57 @@ | |||||
| // 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 CreateOrgForm struct { | |||||
| OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"` | |||||
| Email string `form:"email" binding:"Required;Email;MaxSize(50)"` | |||||
| } | |||||
| func (f *CreateOrgForm) Name(field string) string { | |||||
| names := map[string]string{ | |||||
| "OrgName": "Organization name", | |||||
| "Email": "E-mail address", | |||||
| } | |||||
| return names[field] | |||||
| } | |||||
| func (f *CreateOrgForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) { | |||||
| data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | |||||
| validate(errs, data, f) | |||||
| } | |||||
| type OrgSettingForm struct { | |||||
| DisplayName string `form:"display_name" binding:"Required;MaxSize(100)"` | |||||
| Email string `form:"email" binding:"Required;Email;MaxSize(50)"` | |||||
| Description string `form:"desc" binding:"MaxSize(255)"` | |||||
| Website string `form:"site" binding:"Url;MaxSize(100)"` | |||||
| Location string `form:"location" binding:"MaxSize(50)"` | |||||
| } | |||||
| func (f *OrgSettingForm) Name(field string) string { | |||||
| names := map[string]string{ | |||||
| "DisplayName": "Display name", | |||||
| "Email": "E-mail address", | |||||
| "Description": "Description", | |||||
| "Website": "Website address", | |||||
| "Location": "Location", | |||||
| } | |||||
| return names[field] | |||||
| } | |||||
| func (f *OrgSettingForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) { | |||||
| data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData) | |||||
| validate(errors, data, f) | |||||
| } | |||||
| @@ -22,9 +22,10 @@ import ( | |||||
| // \/ \/|__| \/ \/ | // \/ \/|__| \/ \/ | ||||
| type CreateRepoForm struct { | type CreateRepoForm struct { | ||||
| Uid int64 `form:"uid" binding:"Required"` | |||||
| RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | ||||
| Private bool `form:"private"` | Private bool `form:"private"` | ||||
| Description string `form:"desc" binding:"MaxSize(100)"` | |||||
| Description string `form:"desc" binding:"MaxSize(255)"` | |||||
| Language string `form:"language"` | Language string `form:"language"` | ||||
| License string `form:"license"` | License string `form:"license"` | ||||
| InitReadme bool `form:"initReadme"` | InitReadme bool `form:"initReadme"` | ||||
| @@ -47,10 +48,11 @@ type MigrateRepoForm struct { | |||||
| Url string `form:"url" binding:"Url"` | Url string `form:"url" binding:"Url"` | ||||
| AuthUserName string `form:"auth_username"` | AuthUserName string `form:"auth_username"` | ||||
| AuthPasswd string `form:"auth_password"` | AuthPasswd string `form:"auth_password"` | ||||
| Uid int64 `form:"uid" binding:"Required"` | |||||
| RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | RepoName string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"` | ||||
| Mirror bool `form:"mirror"` | Mirror bool `form:"mirror"` | ||||
| Private bool `form:"private"` | Private bool `form:"private"` | ||||
| Description string `form:"desc" binding:"MaxSize(100)"` | |||||
| Description string `form:"desc" binding:"MaxSize(255)"` | |||||
| } | } | ||||
| func (f *MigrateRepoForm) Name(field string) string { | func (f *MigrateRepoForm) Name(field string) string { | ||||
| @@ -69,7 +71,7 @@ func (f *MigrateRepoForm) Validate(errors *binding.Errors, req *http.Request, co | |||||
| type RepoSettingForm struct { | type RepoSettingForm struct { | ||||
| RepoName string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"` | RepoName string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"` | ||||
| Description string `form:"desc" binding:"MaxSize(100)"` | |||||
| Description string `form:"desc" binding:"MaxSize(255)"` | |||||
| Website string `form:"site" binding:"Url;MaxSize(100)"` | Website string `form:"site" binding:"Url;MaxSize(100)"` | ||||
| Branch string `form:"branch"` | Branch string `form:"branch"` | ||||
| Interval int `form:"interval"` | Interval int `form:"interval"` | ||||
| @@ -25,23 +25,25 @@ func SignedInId(header http.Header, sess session.SessionStore) int64 { | |||||
| return 0 | return 0 | ||||
| } | } | ||||
| var id int64 | |||||
| if setting.Service.EnableReverseProxyAuth { | if setting.Service.EnableReverseProxyAuth { | ||||
| 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 | |||||
| webAuthUser := header.Get(setting.ReverseProxyAuthUser) | |||||
| if len(webAuthUser) > 0 { | |||||
| u, err := models.GetUserByName(webAuthUser) | |||||
| if err != nil { | |||||
| if err != models.ErrUserNotExist { | |||||
| log.Error("auth.user.SignedInId(GetUserByName): %v", err) | |||||
| } | |||||
| return 0 | |||||
| } | |||||
| return u.Id | |||||
| } | } | ||||
| } | } | ||||
| if id > 0 { | |||||
| uid := sess.Get("userId") | |||||
| if uid == nil { | |||||
| return 0 | |||||
| } | |||||
| if id, ok := uid.(int64); ok { | |||||
| if _, err := models.GetUserById(id); err != nil { | if _, err := models.GetUserById(id); err != nil { | ||||
| if err != models.ErrUserNotExist { | if err != models.ErrUserNotExist { | ||||
| log.Error("auth.user.SignedInId(GetUserById): %v", err) | log.Error("auth.user.SignedInId(GetUserById): %v", err) | ||||
| @@ -91,7 +93,7 @@ func (f *UpdateProfileForm) Name(field string) string { | |||||
| names := map[string]string{ | names := map[string]string{ | ||||
| "UserName": "Username", | "UserName": "Username", | ||||
| "Email": "E-mail address", | "Email": "E-mail address", | ||||
| "Website": "Website", | |||||
| "Website": "Website address", | |||||
| "Location": "Location", | "Location": "Location", | ||||
| "Avatar": "Gravatar Email", | "Avatar": "Gravatar Email", | ||||
| } | } | ||||
| @@ -7,6 +7,7 @@ package base | |||||
| type ( | type ( | ||||
| // Type TmplData represents data in the templates. | // Type TmplData represents data in the templates. | ||||
| TmplData map[string]interface{} | TmplData map[string]interface{} | ||||
| TplName string | |||||
| ApiJsonErr struct { | ApiJsonErr struct { | ||||
| Message string `json:"message"` | Message string `json:"message"` | ||||
| @@ -28,242 +28,241 @@ func bindata_read(data []byte, name string) ([]byte, error) { | |||||
| func conf_app_ini() ([]byte, error) { | func conf_app_ini() ([]byte, error) { | ||||
| return bindata_read([]byte{ | return bindata_read([]byte{ | ||||
| 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xb4, 0x59, | 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, 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, | |||||
| 0xeb, 0x72, 0xdb, 0xc8, 0x95, 0xfe, 0x8f, 0xa7, 0x68, 0x73, 0x67, 0x76, | |||||
| 0xec, 0x2d, 0x89, 0xa4, 0xe4, 0xb5, 0xec, 0x91, 0xc7, 0xb5, 0xa6, 0x48, | |||||
| 0x50, 0xc2, 0x9a, 0x17, 0x0d, 0x00, 0xc9, 0xa3, 0xb8, 0x54, 0x28, 0x08, | |||||
| 0x68, 0x92, 0x1d, 0x01, 0x68, 0x08, 0xdd, 0x14, 0xc5, 0xfc, 0xcb, 0x2b, | |||||
| 0xa4, 0xf2, 0x34, 0x79, 0x9e, 0xfc, 0xc8, 0x63, 0xe4, 0x3b, 0x0d, 0x80, | |||||
| 0x02, 0x65, 0x8e, 0xc6, 0xb9, 0x55, 0x52, 0x16, 0xd1, 0xdd, 0xe7, 0xf4, | |||||
| 0xb9, 0x7c, 0xe7, 0xd6, 0xf3, 0x9e, 0xf5, 0xf2, 0x9c, 0x65, 0x61, 0xca, | |||||
| 0x99, 0x5e, 0x84, 0x9a, 0xa9, 0x85, 0x5c, 0x29, 0x26, 0x33, 0xc6, 0xef, | |||||
| 0x79, 0xb1, 0x66, 0x79, 0x38, 0xc7, 0x86, 0xd0, 0x09, 0xb7, 0x7a, 0xe7, | |||||
| 0xe7, 0xc1, 0xa4, 0x37, 0xb6, 0xd9, 0x07, 0x76, 0x2a, 0xe7, 0xea, 0x18, | |||||
| 0xff, 0xb2, 0x53, 0xa1, 0x99, 0xc7, 0x8b, 0x7b, 0x11, 0x95, 0xfb, 0xa3, | |||||
| 0xe9, 0xe9, 0x14, 0xfb, 0x22, 0x9d, 0x77, 0x66, 0x21, 0x56, 0x65, 0xd6, | |||||
| 0xce, 0xb3, 0xb9, 0xf5, 0x9e, 0xf5, 0x17, 0x61, 0x06, 0x4e, 0x38, 0x2e, | |||||
| 0x66, 0x6c, 0x2d, 0x97, 0xac, 0x58, 0x66, 0x2c, 0x91, 0x51, 0x98, 0x24, | |||||
| 0x6b, 0xcb, 0xbd, 0x98, 0x04, 0x17, 0x9e, 0xed, 0x82, 0x72, 0x2e, 0x34, | |||||
| 0x4e, 0xdb, 0x42, 0x2f, 0x78, 0xc1, 0x5a, 0x31, 0xbf, 0x6f, 0xed, 0xb1, | |||||
| 0x56, 0x5e, 0xc8, 0xb8, 0xc5, 0x24, 0x16, 0x34, 0x57, 0x1a, 0x2b, 0x31, | |||||
| 0x9f, 0x85, 0xcb, 0x04, 0xbc, 0x54, 0x79, 0xc6, 0x70, 0x18, 0x4f, 0x07, | |||||
| 0x24, 0x1b, 0xbe, 0x2d, 0xeb, 0x4b, 0xc1, 0x73, 0xa9, 0x84, 0x96, 0xc5, | |||||
| 0xfa, 0xda, 0x72, 0xa7, 0x53, 0x1f, 0x1b, 0x96, 0xd7, 0x77, 0x9d, 0x73, | |||||
| 0x3f, 0xf0, 0xaf, 0xce, 0xe9, 0xdc, 0x4d, 0xa8, 0x16, 0x38, 0xa8, 0x20, | |||||
| 0x3d, 0x2f, 0xae, 0xad, 0x73, 0x77, 0xea, 0x4f, 0xfb, 0xd3, 0x11, 0x76, | |||||
| 0x16, 0x5a, 0xe7, 0xd6, 0x60, 0x3a, 0xee, 0x39, 0x13, 0x7c, 0x19, 0x21, | |||||
| 0x17, 0x52, 0x69, 0xc3, 0x27, 0xb8, 0x70, 0xe9, 0xc8, 0xf7, 0x2f, 0xeb, | |||||
| 0xf3, 0xaf, 0xd4, 0x71, 0xa7, 0xf3, 0xfd, 0xcb, 0xf2, 0x38, 0x3e, 0xbe, | |||||
| 0x7f, 0x79, 0xe6, 0xfb, 0xe7, 0xc1, 0xf9, 0xd4, 0xf5, 0x5f, 0xa9, 0x8e, | |||||
| 0x65, 0x3e, 0x7a, 0x83, 0x01, 0xe9, 0x66, 0x6d, 0x76, 0xf0, 0xf1, 0xba, | |||||
| 0xdb, 0xed, 0x5a, 0x9e, 0x77, 0x56, 0x7f, 0x1f, 0x1e, 0x42, 0xef, 0x81, | |||||
| 0x50, 0xe1, 0x4d, 0xc2, 0x59, 0x7f, 0x30, 0x21, 0xfb, 0x67, 0x4c, 0x64, | |||||
| 0xb5, 0xf6, 0xa9, 0x8c, 0xb9, 0x35, 0x1d, 0x0e, 0x47, 0xce, 0xc4, 0xae, | |||||
| 0x55, 0x9d, 0x85, 0x89, 0xe2, 0xd6, 0xc0, 0xf1, 0x7a, 0x27, 0x23, 0x3b, | |||||
| 0x70, 0xa7, 0x17, 0xbe, 0xed, 0x92, 0x0b, 0x36, 0x5b, 0xef, 0xd9, 0x29, | |||||
| 0xcf, 0x78, 0x11, 0x6a, 0xce, 0x94, 0xe6, 0xb9, 0x3a, 0xc6, 0xca, 0x77, | |||||
| 0x2c, 0x8a, 0xe1, 0x56, 0xbd, 0xe8, 0x68, 0xd9, 0x99, 0xc3, 0x91, 0x9d, | |||||
| 0x68, 0xa9, 0xb4, 0x4c, 0x3b, 0xa4, 0xb6, 0x32, 0x07, 0xe6, 0xd2, 0xb8, | |||||
| 0xe7, 0xbb, 0xd3, 0x29, 0xa9, 0xdc, 0x51, 0x45, 0xd4, 0xc9, 0x6f, 0xe7, | |||||
| 0x9d, 0xa8, 0x58, 0xe7, 0xa0, 0xd1, 0x89, 0xea, 0xcc, 0x2b, 0xb6, 0x41, | |||||
| 0xc4, 0x0b, 0xdd, 0xc6, 0xf9, 0xfd, 0x28, 0xfc, 0xa0, 0x8b, 0x25, 0x67, | |||||
| 0xfb, 0xf1, 0x12, 0x1b, 0x42, 0x66, 0x1f, 0xde, 0xbd, 0x3d, 0xea, 0x2e, | |||||
| 0xba, 0x69, 0x57, 0xb1, 0x7d, 0x32, 0xdf, 0x87, 0x74, 0x4d, 0x7f, 0xda, | |||||
| 0xfc, 0x21, 0x4c, 0xf3, 0x84, 0xb7, 0x23, 0x99, 0x5a, 0x7d, 0xdb, 0xf5, | |||||
| 0x83, 0xa1, 0x33, 0x22, 0x65, 0x9a, 0x52, 0x74, 0x0c, 0xdb, 0x9c, 0xa7, | |||||
| 0xd6, 0x27, 0xfb, 0x6a, 0xe7, 0x81, 0x5b, 0xbe, 0x36, 0xfb, 0xef, 0xd9, | |||||
| 0x45, 0x9e, 0x03, 0x2a, 0x09, 0xcc, 0x95, 0x30, 0x39, 0x63, 0x9a, 0x83, | |||||
| 0x3b, 0x29, 0x1c, 0x66, 0x31, 0x94, 0x86, 0x28, 0x11, 0x9b, 0x09, 0xd8, | |||||
| 0x94, 0x54, 0xc6, 0xf1, 0x06, 0x74, 0x80, 0x31, 0xb3, 0xca, 0x56, 0x00, | |||||
| 0x1b, 0x37, 0xa0, 0xa6, 0x65, 0xfe, 0xc0, 0xa3, 0xa5, 0xe6, 0xb1, 0xe5, | |||||
| 0xf9, 0x3d, 0xdf, 0xe9, 0x07, 0xc6, 0xed, 0xe7, 0x3d, 0xff, 0x8c, 0x5c, | |||||
| 0x68, 0x7d, 0x89, 0x43, 0x1d, 0x02, 0x3b, 0xfc, 0xba, 0x81, 0xd3, 0x74, | |||||
| 0xad, 0xee, 0x12, 0x83, 0x54, 0x68, 0x38, 0x2f, 0xb8, 0x2a, 0xd1, 0x8a, | |||||
| 0x45, 0xa1, 0xf9, 0x6b, 0x6c, 0x08, 0xfd, 0x83, 0x22, 0xd8, 0x17, 0x2c, | |||||
| 0x5a, 0x48, 0x0a, 0x96, 0xc1, 0x49, 0x8d, 0x43, 0x43, 0x6b, 0x9d, 0x4d, | |||||
| 0x3d, 0x42, 0xc1, 0xc1, 0xe1, 0xdb, 0x76, 0x17, 0xff, 0x3b, 0x38, 0x7e, | |||||
| 0xfd, 0xba, 0x7b, 0x64, 0x55, 0xe1, 0x46, 0x5e, 0xb2, 0xaa, 0x00, 0x29, | |||||
| 0xa4, 0xd4, 0xd6, 0x79, 0xcf, 0xf3, 0x3e, 0x0f, 0xd8, 0x07, 0x88, 0x30, | |||||
| 0xa4, 0x8b, 0x1a, 0xd7, 0x66, 0xc9, 0x7a, 0x8f, 0xf1, 0x3a, 0x7e, 0x4a, | |||||
| 0x3c, 0x91, 0x64, 0x05, 0xbf, 0x5b, 0x8a, 0x82, 0x97, 0x82, 0x01, 0xf1, | |||||
| 0x62, 0xb6, 0xde, 0x9f, 0x2d, 0x93, 0xa4, 0x05, 0x10, 0x8e, 0x36, 0xb1, | |||||
| 0x53, 0x9e, 0xaf, 0xd9, 0xd6, 0xf2, 0x1b, 0xae, 0x56, 0x65, 0x02, 0xd2, | |||||
| 0xdf, 0xe0, 0xa6, 0x1d, 0xdf, 0xc0, 0x1c, 0x61, 0x9c, 0x8a, 0xec, 0xda, | |||||
| 0x04, 0x52, 0xb4, 0x2c, 0x84, 0x46, 0xbc, 0x39, 0x13, 0x58, 0x6e, 0x34, | |||||
| 0x02, 0x12, 0xfb, 0x9f, 0x1a, 0x50, 0x7c, 0xf1, 0xa2, 0x7f, 0xd6, 0x9b, | |||||
| 0x9c, 0xda, 0xcc, 0x3f, 0x73, 0x3c, 0xe6, 0x4f, 0xd9, 0x27, 0xdb, 0x3e, | |||||
| 0x67, 0x57, 0xd3, 0x0b, 0x97, 0x19, 0xdd, 0x06, 0x3d, 0xbf, 0xc7, 0xbc, | |||||
| 0xde, 0xd0, 0x7e, 0xf1, 0xc2, 0xf2, 0xec, 0xbe, 0x6b, 0xfb, 0x01, 0xbc, | |||||
| 0x0f, 0x06, 0x2f, 0xfe, 0xeb, 0xe3, 0x70, 0x60, 0x7f, 0x76, 0xf1, 0xff, | |||||
| 0xff, 0xfe, 0x9f, 0x97, 0xe0, 0xd4, 0x5b, 0x6a, 0xb9, 0x9f, 0xc8, 0x39, | |||||
| 0xa2, 0xa3, 0xe0, 0x29, 0x4f, 0x6f, 0xa0, 0x6b, 0x1c, 0xae, 0x95, 0x05, | |||||
| 0xec, 0x3b, 0x93, 0xc0, 0xb5, 0xc7, 0xf6, 0xf8, 0x04, 0xa1, 0x30, 0xe8, | |||||
| 0x5d, 0x79, 0xa0, 0x7f, 0x6b, 0xf5, 0xa7, 0xd3, 0x4f, 0x8e, 0x6d, 0x72, | |||||
| 0x4c, 0xc3, 0xa4, 0x41, 0xb8, 0xe2, 0x4a, 0xa6, 0xbc, 0xde, 0xde, 0xd0, | |||||
| 0x35, 0xcf, 0x88, 0x2c, 0x2a, 0x78, 0x2c, 0x4a, 0xab, 0xb8, 0x94, 0x14, | |||||
| 0x15, 0x50, 0x53, 0xc8, 0x87, 0x35, 0x0b, 0x97, 0xb0, 0x72, 0x06, 0x80, | |||||
| 0x19, 0xbc, 0xb3, 0x05, 0x0f, 0x63, 0x08, 0x62, 0x52, 0x29, 0x80, 0xb8, | |||||
| 0x54, 0xd5, 0x87, 0xe5, 0xda, 0x97, 0xb6, 0xeb, 0xd9, 0x01, 0x52, 0xc6, | |||||
| 0x2f, 0x57, 0x41, 0xef, 0xc2, 0x3f, 0xb3, 0x27, 0x00, 0x16, 0xc0, 0x35, | |||||
| 0xdd, 0xe4, 0xbd, 0x5f, 0xf6, 0x3f, 0xdb, 0x27, 0xb4, 0xb5, 0x4f, 0x0b, | |||||
| 0x55, 0x5e, 0x02, 0x50, 0xae, 0xad, 0x5e, 0xdf, 0x77, 0x2e, 0xed, 0xa0, | |||||
| 0x0f, 0x0f, 0x05, 0x23, 0xfa, 0x35, 0x76, 0x26, 0x08, 0x74, 0x52, 0xec, | |||||
| 0xe0, 0x5d, 0x17, 0xcc, 0x3d, 0x9b, 0xe0, 0x49, 0x80, 0xf8, 0xd5, 0x43, | |||||
| 0x88, 0x12, 0x23, 0x0d, 0xe7, 0x31, 0xd3, 0x92, 0x21, 0x2d, 0xcf, 0x44, | |||||
| 0x91, 0x32, 0xbe, 0x9f, 0x86, 0x22, 0x61, 0x33, 0xf8, 0xba, 0xe0, 0x73, | |||||
| 0xa1, 0x74, 0x19, 0xb9, 0xe0, 0x79, 0xea, 0x78, 0x94, 0x4b, 0x6c, 0x24, | |||||
| 0xb5, 0x11, 0xb8, 0x4e, 0x86, 0x8e, 0x3b, 0x6e, 0xb8, 0x72, 0x20, 0xb9, | |||||
| 0x62, 0x99, 0xd4, 0x0c, 0xe9, 0x5b, 0xae, 0x2a, 0x62, 0x5c, 0x40, 0x31, | |||||
| 0x67, 0x00, 0xc1, 0x60, 0x34, 0x13, 0x84, 0x51, 0x24, 0x97, 0x99, 0x2e, | |||||
| 0x01, 0xb4, 0x49, 0x54, 0x86, 0xbd, 0x6b, 0xf4, 0x6f, 0x30, 0x35, 0x22, | |||||
| 0xa6, 0x08, 0x72, 0xa6, 0xc4, 0xdc, 0xa4, 0x3e, 0x88, 0x7a, 0x2f, 0xf8, | |||||
| 0x0a, 0x6c, 0xd7, 0x7a, 0x21, 0xb2, 0x79, 0x1b, 0x92, 0xfd, 0x7c, 0xe1, | |||||
| 0xb8, 0x76, 0xe0, 0x39, 0xa7, 0x13, 0x78, 0xfa, 0xd2, 0xb1, 0x3f, 0x37, | |||||
| 0x38, 0xf4, 0xc3, 0x08, 0x21, 0x1d, 0xde, 0x03, 0xa1, 0x90, 0x45, 0xb1, | |||||
| 0x5c, 0x44, 0x7a, 0x59, 0x70, 0xcb, 0x9e, 0x98, 0x7b, 0xfb, 0xbd, 0xfe, | |||||
| 0x99, 0x1d, 0xf4, 0x2e, 0x81, 0x33, 0xb7, 0x41, 0x35, 0x26, 0x1b, 0x40, | |||||
| 0x19, 0x31, 0xab, 0x3c, 0x59, 0x9f, 0x9f, 0x4c, 0x7d, 0x67, 0x78, 0x15, | |||||
| 0x90, 0x0d, 0x9a, 0xc7, 0x25, 0x72, 0x45, 0xcc, 0x35, 0xa8, 0x8e, 0x4d, | |||||
| 0xa9, 0xa0, 0x02, 0x80, 0xb2, 0xb5, 0x58, 0xde, 0x50, 0x4e, 0xa3, 0xd0, | |||||
| 0x10, 0x5a, 0x95, 0x99, 0x55, 0x28, 0xb5, 0xe4, 0xaa, 0x73, 0x70, 0xf4, | |||||
| 0xa6, 0xe6, 0xf9, 0x1c, 0x16, 0x36, 0x97, 0x58, 0x5f, 0x56, 0xfc, 0x66, | |||||
| 0x21, 0xe5, 0x2d, 0xe5, 0x98, 0x7e, 0x01, 0x6c, 0xe9, 0x50, 0xdd, 0xc2, | |||||
| 0x22, 0xb0, 0xf1, 0x7d, 0x98, 0x90, 0x69, 0x60, 0x63, 0xe4, 0x28, 0x65, | |||||
| 0xf9, 0x3d, 0xef, 0x53, 0xe0, 0x4c, 0xe0, 0xac, 0xcb, 0x1e, 0x49, 0x79, | |||||
| 0x40, 0xde, 0xe1, 0x89, 0x00, 0x4e, 0x51, 0xb6, 0x53, 0x2e, 0x97, 0x9a, | |||||
| 0x8e, 0x23, 0x38, 0x65, 0x16, 0x2b, 0x6b, 0x60, 0x13, 0x3a, 0xdc, 0xc0, | |||||
| 0x77, 0xc6, 0x36, 0xca, 0x05, 0x08, 0xde, 0xe0, 0x36, 0x42, 0x01, 0xd5, | |||||
| 0xc0, 0x52, 0xc6, 0x41, 0x43, 0xd9, 0x93, 0xe5, 0x6c, 0x66, 0xb2, 0x6b, | |||||
| 0x36, 0x47, 0x9e, 0x04, 0xaa, 0x23, 0xd4, 0xf1, 0x8c, 0x27, 0x7b, 0xec, | |||||
| 0x96, 0xf3, 0x9c, 0xca, 0x39, 0xcc, 0x2c, 0x4c, 0x36, 0xad, 0xea, 0x7a, | |||||
| 0x2c, 0xb3, 0x1f, 0x34, 0xbb, 0xcd, 0x00, 0x8b, 0x15, 0xf5, 0x13, 0x66, | |||||
| 0xb3, 0x8d, 0x80, 0x9e, 0x0c, 0x82, 0x93, 0x8b, 0xe1, 0x90, 0x2a, 0x94, | |||||
| 0x4d, 0xaa, 0x1e, 0x10, 0x2c, 0x27, 0x14, 0x2c, 0xc8, 0x3a, 0x48, 0xd9, | |||||
| 0x6b, 0x60, 0x93, 0x14, 0x23, 0x6f, 0x94, 0x0d, 0x87, 0x77, 0x71, 0xf2, | |||||
| 0xff, 0x76, 0xdf, 0x37, 0xe5, 0xb6, 0x6e, 0x3e, 0x5e, 0xa9, 0xda, 0x63, | |||||
| 0x65, 0xe1, 0xa6, 0x12, 0x97, 0x1a, 0x57, 0xa8, 0x54, 0xe7, 0xed, 0x39, | |||||
| 0xfd, 0x26, 0x37, 0x1c, 0xbf, 0x79, 0xf7, 0x16, 0x7b, 0x3f, 0xff, 0x5c, | |||||
| 0x6d, 0xdc, 0xdd, 0x99, 0xd5, 0xc3, 0x37, 0x75, 0xa6, 0xad, 0xd9, 0xcc, | |||||
| 0x0a, 0x99, 0x02, 0xb3, 0x31, 0xb2, 0xa7, 0xb2, 0x86, 0xee, 0x74, 0xfc, | |||||
| 0xb8, 0x07, 0xc5, 0x37, 0x41, 0x6c, 0xa0, 0x9d, 0x87, 0x4a, 0xad, 0x64, | |||||
| 0x11, 0xd7, 0xb9, 0x78, 0x93, 0x87, 0xa9, 0x2e, 0x48, 0x4a, 0x07, 0x5f, | |||||
| 0xdb, 0xb0, 0xda, 0x68, 0x97, 0x08, 0xf9, 0x7a, 0xbf, 0x3f, 0x72, 0x80, | |||||
| 0x80, 0xc0, 0x31, 0x5c, 0xaa, 0x8f, 0x32, 0xfb, 0x95, 0x2d, 0xcb, 0xf4, | |||||
| 0xdc, 0x44, 0x71, 0x0d, 0xb4, 0x30, 0x17, 0xed, 0x06, 0xd8, 0x48, 0x3e, | |||||
| 0x8b, 0x50, 0x54, 0xf5, 0x25, 0x3b, 0xf0, 0x68, 0xf2, 0x64, 0xc7, 0x08, | |||||
| 0xd1, 0xa1, 0x7f, 0x64, 0x21, 0xfe, 0xc0, 0x2d, 0x7f, 0xfa, 0xc9, 0x9e, | |||||
| 0x7c, 0x23, 0x51, 0x14, 0xc1, 0x36, 0x81, 0x96, 0xb7, 0x3c, 0xb3, 0x4c, | |||||
| 0x4b, 0xa1, 0x59, 0x94, 0x08, 0x64, 0x3e, 0x26, 0xe2, 0xb2, 0xcc, 0x72, | |||||
| 0x84, 0xbb, 0x36, 0xa6, 0xc4, 0x7e, 0xcd, 0x0e, 0x88, 0x53, 0x12, 0x85, | |||||
| 0x3e, 0xa6, 0xd2, 0x2c, 0x51, 0xa4, 0x15, 0x1a, 0x05, 0x39, 0x2f, 0x4b, | |||||
| 0x7f, 0x07, 0x29, 0xf4, 0xf7, 0x3c, 0xd2, 0x1b, 0xf3, 0x98, 0x9d, 0x7f, | |||||
| 0xd9, 0x3c, 0xab, 0xd5, 0xaa, 0x62, 0x05, 0x43, 0x29, 0x73, 0x91, 0xd1, | |||||
| 0x81, 0xec, 0x24, 0xb2, 0x99, 0x6c, 0x73, 0x83, 0xaf, 0x6f, 0x3e, 0x0e, | |||||
| 0x29, 0xa9, 0x79, 0xd8, 0x65, 0xe2, 0x2a, 0xb5, 0x6d, 0x29, 0x25, 0x4b, | |||||
| 0x93, 0x1d, 0x1a, 0x2e, 0x3b, 0x6d, 0xfc, 0x2c, 0x55, 0x65, 0xe2, 0xca, | |||||
| 0x24, 0x77, 0x77, 0xff, 0xb4, 0x39, 0x90, 0x96, 0x0d, 0xf8, 0xd9, 0x5f, | |||||
| 0xff, 0xf2, 0xa7, 0xbf, 0xfd, 0xf1, 0xcf, 0x54, 0x32, 0x77, 0x60, 0xa4, | |||||
| 0x08, 0xf3, 0x45, 0x15, 0x18, 0x95, 0x04, 0xed, 0x6e, 0x03, 0x22, 0xef, | |||||
| 0xd9, 0x4e, 0x90, 0xec, 0xa4, 0x2a, 0x25, 0x07, 0x05, 0xcf, 0x22, 0x02, | |||||
| 0xc6, 0x8a, 0x8b, 0x1b, 0xb9, 0xcb, 0x6a, 0xc0, 0x41, 0xd6, 0xd6, 0x35, | |||||
| 0x7d, 0x34, 0x17, 0xfb, 0x37, 0x35, 0xd0, 0x0e, 0x7f, 0x03, 0x9e, 0xcf, | |||||
| 0x93, 0x6e, 0x81, 0xb4, 0xb2, 0xa0, 0x5e, 0x09, 0xad, 0x77, 0x25, 0xb6, | |||||
| 0x7f, 0xc0, 0x8c, 0xbb, 0x3c, 0x8f, 0x18, 0xac, 0x58, 0x3f, 0x5a, 0xe1, | |||||
| 0x37, 0x84, 0xff, 0x15, 0x9a, 0x5d, 0x52, 0x1b, 0xdb, 0xfd, 0x27, 0x64, | |||||
| 0x36, 0x8c, 0x1b, 0x7e, 0xfb, 0x06, 0x91, 0xbf, 0x26, 0xd9, 0x96, 0x38, | |||||
| 0xa2, 0x8a, 0xbb, 0xd5, 0x09, 0xf3, 0x14, 0x33, 0x57, 0xd9, 0x70, 0x22, | |||||
| 0xaf, 0xe3, 0x87, 0x2c, 0x57, 0xcd, 0xc9, 0x27, 0xa3, 0x5b, 0x75, 0xd8, | |||||
| 0xea, 0x0d, 0x7a, 0xe7, 0xbe, 0xc9, 0xa8, 0xe5, 0x4a, 0xdd, 0x7f, 0x56, | |||||
| 0xfb, 0x55, 0x53, 0x7b, 0xda, 0xdf, 0xaa, 0x80, 0x55, 0x49, 0xdb, 0xe2, | |||||
| 0x78, 0xd4, 0xb5, 0x1a, 0xb5, 0xf0, 0xa8, 0x5b, 0x33, 0x2a, 0x65, 0x31, | |||||
| 0xb9, 0xaa, 0x29, 0x0b, 0x18, 0x64, 0xc8, 0x41, 0xa6, 0x79, 0x43, 0x07, | |||||
| 0xbd, 0x29, 0x03, 0xef, 0x99, 0x21, 0x38, 0x66, 0xad, 0xe3, 0xa3, 0xee, | |||||
| 0xeb, 0x1f, 0x5b, 0x58, 0xa8, 0xa9, 0xb0, 0xf6, 0xd8, 0xa3, 0x1f, 0x1c, | |||||
| 0x1c, 0x1e, 0x1c, 0xb4, 0xaa, 0x8a, 0x62, 0x7a, 0x36, 0xa5, 0xc0, 0x6c, | |||||
| 0xb7, 0x3d, 0x28, 0x8f, 0x3c, 0xda, 0xa5, 0x34, 0x4b, 0x35, 0x36, 0xec, | |||||
| 0xb2, 0x09, 0x1a, 0x84, 0x4b, 0x67, 0x60, 0x8c, 0x62, 0x32, 0xd0, 0x7b, | |||||
| 0x76, 0x5e, 0xc8, 0x7b, 0x41, 0x1d, 0xa6, 0x69, 0xdf, 0xe6, 0x4c, 0xe6, | |||||
| 0x24, 0xb9, 0x2a, 0x85, 0x03, 0xcd, 0xb1, 0xe9, 0xc8, 0x16, 0xe1, 0x3d, | |||||
| 0x15, 0xab, 0x75, 0x7d, 0x6a, 0xcd, 0x69, 0xa0, 0x26, 0x16, 0xa8, 0x84, | |||||
| 0xa5, 0x7c, 0x8f, 0xf3, 0x10, 0x26, 0x85, 0xf6, 0xbc, 0x8d, 0x39, 0x81, | |||||
| 0x7a, 0xfa, 0x6a, 0x57, 0xb5, 0x1e, 0xf5, 0xaf, 0x78, 0x24, 0xe2, 0x96, | |||||
| 0x97, 0x4b, 0x55, 0xd5, 0x35, 0x96, 0xda, 0x63, 0xb9, 0x94, 0x89, 0x07, | |||||
| 0xf8, 0xec, 0x6d, 0x2a, 0x63, 0xcd, 0xf0, 0xd1, 0x46, 0x47, 0xaf, 0xdf, | |||||
| 0xfe, 0xb8, 0x77, 0xd0, 0xed, 0xee, 0x85, 0x18, 0xc6, 0x1e, 0x04, 0x37, | |||||
| 0xc6, 0x24, 0xbd, 0x8f, 0xd1, 0x5f, 0xef, 0xe3, 0xef, 0x7e, 0x5c, 0x50, | |||||
| 0xb7, 0xd2, 0x31, 0x8b, 0x2c, 0x56, 0x59, 0x7d, 0x2b, 0xda, 0x51, 0xf4, | |||||
| 0x7c, 0x35, 0x47, 0x9a, 0x7b, 0x8e, 0xeb, 0x6b, 0x3e, 0xd6, 0xc2, 0x06, | |||||
| 0xda, 0xcc, 0x37, 0x1b, 0x6b, 0x95, 0xbd, 0xea, 0x69, 0x3d, 0xa6, 0xd4, | |||||
| 0x2a, 0xe1, 0x4e, 0xaf, 0xd2, 0x3d, 0x42, 0x5b, 0x25, 0x78, 0xd9, 0x98, | |||||
| 0x57, 0x7d, 0x7f, 0xd5, 0xee, 0x8b, 0x80, 0xf4, 0x0c, 0xca, 0xfe, 0x0d, | |||||
| 0x14, 0x4e, 0xd9, 0xd0, 0xa0, 0x16, 0x6c, 0x0c, 0x07, 0xd8, 0x99, 0xe8, | |||||
| 0xa8, 0x10, 0xd9, 0xf0, 0x5b, 0x15, 0xa3, 0x25, 0x43, 0x84, 0xe5, 0x85, | |||||
| 0x6b, 0x37, 0xda, 0x28, 0x3b, 0x33, 0x63, 0xbd, 0xa2, 0xca, 0x69, 0xee, | |||||
| 0xdf, 0xa2, 0xa5, 0xb9, 0xb9, 0xee, 0x0f, 0xa9, 0x99, 0x2f, 0xb9, 0x80, | |||||
| 0xdc, 0x6c, 0x3c, 0x8a, 0x8e, 0x00, 0xa0, 0x96, 0x6e, 0x13, 0x05, 0x5b, | |||||
| 0x4c, 0xde, 0x1d, 0xfd, 0x6f, 0xb7, 0x6b, 0x9d, 0xf6, 0x37, 0xcd, 0xa0, | |||||
| 0xe9, 0xf1, 0xc0, 0xa4, 0xdc, 0x78, 0xe4, 0x92, 0x88, 0x19, 0x37, 0x7c, | |||||
| 0x76, 0x90, 0x7b, 0xb6, 0xe7, 0xd1, 0x50, 0x32, 0x72, 0x86, 0xf6, 0x53, | |||||
| 0xfa, 0x8d, 0x0d, 0x62, 0x60, 0x4c, 0x2d, 0xd8, 0x6c, 0x99, 0x45, 0x7b, | |||||
| 0x1b, 0x9c, 0xab, 0x45, 0x78, 0x40, 0xe8, 0xc6, 0xdf, 0xc3, 0x37, 0x47, | |||||
| 0x15, 0xbc, 0xe3, 0x37, 0xad, 0xe6, 0x1d, 0x74, 0x66, 0x73, 0x85, 0x33, | |||||
| 0x08, 0xce, 0x7a, 0xde, 0xd9, 0xf0, 0x62, 0xd2, 0xc7, 0x25, 0x66, 0xeb, | |||||
| 0x51, 0x46, 0x73, 0x01, 0x46, 0xfc, 0x2d, 0x11, 0xc9, 0x11, 0x05, 0x42, | |||||
| 0x18, 0xfd, 0x5a, 0x09, 0x8d, 0xa7, 0xbc, 0xcc, 0xb4, 0x88, 0x30, 0xac, | |||||
| 0xda, 0x7e, 0x0a, 0x43, 0x9f, 0x46, 0xfc, 0x24, 0x8c, 0x38, 0xcd, 0x12, | |||||
| 0xd5, 0xba, 0x81, 0xc6, 0xe3, 0x8c, 0x5c, 0x22, 0xba, 0x94, 0xf8, 0x4e, | |||||
| 0x64, 0x62, 0xf9, 0x24, 0x20, 0xab, 0x7d, 0x5c, 0xe6, 0x5e, 0x3a, 0x7d, | |||||
| 0xb2, 0x48, 0xd5, 0x79, 0xd6, 0xe3, 0xcc, 0xa9, 0xfb, 0x64, 0xa4, 0xb0, | |||||
| 0xbe, 0xa0, 0x7d, 0x2a, 0x9f, 0x9d, 0xaa, 0x77, 0x83, 0x46, 0x42, 0xa8, | |||||
| 0xba, 0xa2, 0x66, 0x46, 0xa0, 0x34, 0x64, 0x6c, 0x87, 0x46, 0xb5, 0x94, | |||||
| 0xa3, 0x7e, 0x63, 0x78, 0x22, 0x4a, 0x4d, 0x5b, 0x0e, 0x4b, 0x80, 0x52, | |||||
| 0x9a, 0x86, 0xa4, 0x98, 0xe2, 0x79, 0x68, 0x1e, 0x79, 0x52, 0x9c, 0x14, | |||||
| 0x39, 0x90, 0x46, 0xaf, 0x45, 0xaa, 0x0e, 0x9d, 0x8a, 0x6c, 0xcf, 0xc4, | |||||
| 0x7d, 0xcb, 0xaa, 0x66, 0xfd, 0x6a, 0xf5, 0xdf, 0xd9, 0xe4, 0x3f, 0xe9, | |||||
| 0xef, 0xbb, 0x06, 0x37, 0xb5, 0xe2, 0x7e, 0x01, 0x37, 0x90, 0x9a, 0x03, | |||||
| 0x7e, 0xb3, 0x9c, 0xd3, 0x0f, 0x07, 0x1d, 0x16, 0xfd, 0xfd, 0x1c, 0x16, | |||||
| 0x46, 0x7f, 0xbb, 0x28, 0x64, 0x41, 0x3f, 0xfa, 0x85, 0xa0, 0xa9, 0xfa, | |||||
| 0x69, 0x6a, 0x2c, 0x39, 0x58, 0x23, 0x8c, 0x50, 0x94, 0xde, 0xcd, 0xa7, | |||||
| 0x55, 0xa7, 0xf8, 0xda, 0x36, 0x46, 0xf5, 0x72, 0xde, 0x24, 0x37, 0xb4, | |||||
| 0xab, 0xf5, 0xeb, 0x0d, 0xd9, 0x86, 0xc2, 0x58, 0xe3, 0xe9, 0x71, 0x5a, | |||||
| 0x6c, 0x9c, 0xa5, 0xa7, 0xa7, 0x3a, 0x3f, 0x60, 0xbb, 0x7c, 0xf7, 0xc0, | |||||
| 0x0f, 0x03, 0x2d, 0x7a, 0x2b, 0x32, 0x81, 0xad, 0xe8, 0x29, 0x40, 0xa6, | |||||
| 0xf0, 0x40, 0x4c, 0xa7, 0x58, 0x21, 0x35, 0x7e, 0xbf, 0x54, 0xa8, 0xf7, | |||||
| 0x91, 0x31, 0xe8, 0x4c, 0xd2, 0x9c, 0x0c, 0xc8, 0xd6, 0x49, 0xfb, 0xd5, | |||||
| 0xd7, 0x09, 0x60, 0x34, 0x3d, 0x0d, 0xdc, 0xa9, 0xdf, 0xf3, 0x1b, 0x91, | |||||
| 0x3f, 0x0e, 0x1f, 0x10, 0xaf, 0x19, 0xd2, 0xd5, 0xd2, 0x3c, 0x72, 0x80, | |||||
| 0x95, 0x02, 0x17, 0x38, 0x98, 0xe4, 0xdc, 0xe2, 0x61, 0xcc, 0x0d, 0x83, | |||||
| 0x8f, 0x7b, 0xbf, 0x04, 0xf4, 0x46, 0xe8, 0xd5, 0x2e, 0x30, 0x4e, 0x20, | |||||
| 0x46, 0x0a, 0x99, 0x1a, 0x81, 0x26, 0x66, 0xfa, 0x39, 0x3e, 0x87, 0xef, | |||||
| 0x50, 0x4e, 0xc2, 0x0c, 0x0c, 0xd9, 0x4f, 0x3f, 0xe1, 0x6b, 0x8f, 0x21, | |||||
| 0x9e, 0xc7, 0x27, 0x86, 0xaf, 0xe7, 0xfc, 0x0e, 0x19, 0xea, 0xcc, 0x19, | |||||
| 0x9a, 0x07, 0xcb, 0x77, 0x26, 0x60, 0xe7, 0x29, 0xf5, 0x7b, 0xa4, 0x75, | |||||
| 0x8c, 0xce, 0x7a, 0xfd, 0xb5, 0x5e, 0x03, 0x8c, 0xcf, 0x57, 0x5f, 0x69, | |||||
| 0x66, 0x3f, 0xe4, 0x02, 0x15, 0xc5, 0x3c, 0xdb, 0x90, 0x38, 0xc4, 0x80, | |||||
| 0x64, 0x79, 0x19, 0xf3, 0x84, 0xd3, 0xc3, 0xc1, 0x8c, 0xde, 0x13, 0x52, | |||||
| 0x88, 0x4d, 0x27, 0xb6, 0xcd, 0xf5, 0xd6, 0x08, 0xb3, 0x79, 0xdc, 0x69, | |||||
| 0x20, 0x20, 0xdb, 0xe5, 0xfe, 0xac, 0xe1, 0x4f, 0x7a, 0xc2, 0xa9, 0xaa, | |||||
| 0x7e, 0x59, 0xf2, 0xe9, 0xed, 0xa3, 0x7c, 0xe9, 0xae, 0x0c, 0x92, 0x22, | |||||
| 0x05, 0x85, 0x73, 0xbe, 0x23, 0xb9, 0xbb, 0x36, 0x8a, 0xcb, 0x04, 0x03, | |||||
| 0x69, 0x80, 0x94, 0x33, 0xf6, 0x9a, 0xaf, 0xac, 0x3e, 0xe8, 0x11, 0x87, | |||||
| 0xc5, 0x86, 0xf7, 0x6a, 0xc1, 0xb3, 0x66, 0x7b, 0x01, 0x26, 0x09, 0xae, | |||||
| 0x7b, 0x8e, 0x6b, 0xb3, 0x5c, 0x54, 0x21, 0xa3, 0xa3, 0x9c, 0xc2, 0x61, | |||||
| 0x99, 0x89, 0x87, 0x32, 0x2f, 0x2c, 0xe3, 0xfc, 0x49, 0x4c, 0xd0, 0x91, | |||||
| 0xe6, 0xdb, 0x35, 0xbe, 0xc1, 0xe0, 0xac, 0xd9, 0xcd, 0xd4, 0xaf, 0xcf, | |||||
| 0x9b, 0x57, 0x3d, 0x93, 0x66, 0x9e, 0xd8, 0x89, 0x16, 0xb7, 0xec, 0xf4, | |||||
| 0xdc, 0x64, 0xbe, 0x2d, 0xc2, 0x40, 0x84, 0xf3, 0x0c, 0x17, 0x8a, 0xa8, | |||||
| 0x36, 0x5e, 0x39, 0x54, 0x9b, 0x34, 0xd9, 0x6a, 0x4c, 0xf1, 0xcf, 0x1e, | |||||
| 0x7c, 0x32, 0xd6, 0x6f, 0x4f, 0xe9, 0xdf, 0x3e, 0x89, 0x97, 0x1e, 0xe6, | |||||
| 0xd4, 0x51, 0x20, 0xff, 0x45, 0x61, 0xc6, 0x6e, 0x48, 0x4d, 0x4e, 0xe6, | |||||
| 0x43, 0x93, 0xc4, 0xab, 0x9c, 0xf8, 0xa5, 0x75, 0xf0, 0xb1, 0xf1, 0x10, | |||||
| 0xdd, 0xda, 0x6b, 0x1d, 0x6e, 0x7d, 0x5f, 0x93, 0x5f, 0x6c, 0x7a, 0x2a, | |||||
| 0xf1, 0x9a, 0xa6, 0xdb, 0xe4, 0xe5, 0xa7, 0xe6, 0x7b, 0x7c, 0x14, 0x6e, | |||||
| 0x98, 0x70, 0xfb, 0x75, 0x98, 0x6d, 0x3d, 0xd4, 0x5a, 0x03, 0x97, 0xb8, | |||||
| 0x97, 0x07, 0x4f, 0x40, 0x19, 0xd3, 0x7f, 0x73, 0x79, 0x90, 0x45, 0x5a, | |||||
| 0x4a, 0x78, 0x6c, 0x1e, 0x7a, 0x8f, 0xe9, 0x9f, 0x8f, 0x9b, 0xff, 0x02, | |||||
| 0x61, 0xd2, 0xcf, 0xff, 0x21, 0x3b, 0x17, 0xe8, 0x24, 0x3e, 0x2c, 0xf5, | |||||
| 0xec, 0x9d, 0x45, 0xe0, 0x21, 0x26, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, | |||||
| 0xc9, 0x2e, 0x07, 0x65, 0xc7, 0x19, 0x00, 0x00, | |||||
| }, | }, | ||||
| "conf/app.ini", | "conf/app.ini", | ||||
| ) | ) | ||||
| @@ -17,6 +17,15 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "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 | // Create New mail message use MailFrom and MailUser | ||||
| func NewMailMessageFrom(To []string, from, subject, body string) Message { | func NewMailMessageFrom(To []string, from, subject, body string) Message { | ||||
| msg := NewHtmlMessage(To, from, subject, body) | msg := NewHtmlMessage(To, from, subject, body) | ||||
| @@ -61,7 +70,7 @@ func SendRegisterMail(r *middleware.Render, u *models.User) { | |||||
| data := GetMailTmplData(u) | data := GetMailTmplData(u) | ||||
| data["Code"] = code | data["Code"] = code | ||||
| body, err := r.HTMLString("mail/auth/register_success", data) | |||||
| body, err := r.HTMLString(string(AUTH_REGISTER_SUCCESS), data) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("mail.SendRegisterMail(fail to render): %v", err) | log.Error("mail.SendRegisterMail(fail to render): %v", err) | ||||
| return | return | ||||
| @@ -81,7 +90,7 @@ func SendActiveMail(r *middleware.Render, u *models.User) { | |||||
| data := GetMailTmplData(u) | data := GetMailTmplData(u) | ||||
| data["Code"] = code | data["Code"] = code | ||||
| body, err := r.HTMLString("mail/auth/active_email", data) | |||||
| body, err := r.HTMLString(string(AUTH_ACTIVE), data) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("mail.SendActiveMail(fail to render): %v", err) | log.Error("mail.SendActiveMail(fail to render): %v", err) | ||||
| return | return | ||||
| @@ -101,7 +110,7 @@ func SendResetPasswdMail(r *middleware.Render, u *models.User) { | |||||
| data := GetMailTmplData(u) | data := GetMailTmplData(u) | ||||
| data["Code"] = code | data["Code"] = code | ||||
| body, err := r.HTMLString("mail/auth/reset_passwd", data) | |||||
| body, err := r.HTMLString(string(AUTH_RESET_PASSWORD), data) | |||||
| if err != nil { | if err != nil { | ||||
| log.Error("mail.SendResetPasswdMail(fail to render): %v", err) | log.Error("mail.SendResetPasswdMail(fail to render): %v", err) | ||||
| return | 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["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index) | ||||
| data["Subject"] = subject | data["Subject"] = subject | ||||
| body, err := r.HTMLString("mail/notify/mention", data) | |||||
| body, err := r.HTMLString(string(NOTIFY_MENTION), data) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("mail.SendIssueMentionMail(fail to render): %v", err) | 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["RepoLink"] = path.Join(owner.Name, repo.Name) | ||||
| data["Subject"] = subject | data["Subject"] = subject | ||||
| body, err := r.HTMLString("mail/notify/collaborator", data) | |||||
| body, err := r.HTMLString(string(NOTIFY_COLLABORATOR), data) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err) | return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err) | ||||
| } | } | ||||
| @@ -104,12 +104,12 @@ func (ctx *Context) HasError() bool { | |||||
| } | } | ||||
| // HTML calls render.HTML underlying but reduce one argument. | // 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. | // 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 { | if form != nil { | ||||
| auth.AssignForm(form, ctx.Data) | auth.AssignForm(form, ctx.Data) | ||||
| } | } | ||||
| @@ -133,7 +133,7 @@ func (ctx *Context) Handle(status int, title string, err error) { | |||||
| case 500: | case 500: | ||||
| ctx.Data["Title"] = "Internal Server Error" | 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{}) { | func (ctx *Context) Debug(msg string, args ...interface{}) { | ||||
| @@ -46,7 +46,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||||
| // Collaborators who have write access can be seen as owners. | // Collaborators who have write access can be seen as owners. | ||||
| if ctx.IsSigned { | 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 { | if err != nil { | ||||
| ctx.Handle(500, "RepoAssignment(HasAccess)", err) | ctx.Handle(500, "RepoAssignment(HasAccess)", err) | ||||
| return | return | ||||
| @@ -107,7 +107,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler { | |||||
| return | 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 { | if err != nil { | ||||
| ctx.Handle(500, "RepoAssignment(HasAccess)", err) | ctx.Handle(500, "RepoAssignment(HasAccess)", err) | ||||
| return | return | ||||
| @@ -47,12 +47,12 @@ var ( | |||||
| StaticRootPath string | StaticRootPath string | ||||
| // Security settings. | // Security settings. | ||||
| InstallLock bool | |||||
| SecretKey string | |||||
| LogInRememberDays int | |||||
| CookieUserName string | |||||
| CookieRememberName string | |||||
| ReverseProxyAuthUid string | |||||
| InstallLock bool | |||||
| SecretKey string | |||||
| LogInRememberDays int | |||||
| CookieUserName string | |||||
| CookieRememberName string | |||||
| ReverseProxyAuthUser string | |||||
| // Webhook settings. | // Webhook settings. | ||||
| WebhookTaskInterval int | WebhookTaskInterval int | ||||
| @@ -164,7 +164,7 @@ func NewConfigContext() { | |||||
| LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS") | LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS") | ||||
| CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME") | CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME") | ||||
| CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME") | CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME") | ||||
| ReverseProxyAuthUid = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_UID", "X-WEBAUTH-UID") | |||||
| ReverseProxyAuthUser = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_USER", "X-WEBAUTH-USER") | |||||
| RunUser = Cfg.MustValue("", "RUN_USER") | RunUser = Cfg.MustValue("", "RUN_USER") | ||||
| curUser := os.Getenv("USER") | curUser := os.Getenv("USER") | ||||
| @@ -257,6 +257,9 @@ html, body { | |||||
| .card .btn { | .card .btn { | ||||
| cursor: pointer; | cursor: pointer; | ||||
| } | |||||
| .card .btn-primary { | |||||
| margin-right: 1.2em; | margin-right: 1.2em; | ||||
| } | } | ||||
| @@ -372,7 +375,7 @@ html, body { | |||||
| /* gogits repo create */ | /* gogits repo create */ | ||||
| #repo-create { | |||||
| #repo-create, #org-create, #org-teams-create, #org-teams-edit { | |||||
| width: 800px; | width: 800px; | ||||
| } | } | ||||
| @@ -638,7 +641,7 @@ html, body { | |||||
| margin: 0 .5em; | margin: 0 .5em; | ||||
| } | } | ||||
| #dashboard-switch .btn { | |||||
| #dashboard-switch .btn, #repo-owner-switch .btn { | |||||
| height: 40px; | height: 40px; | ||||
| } | } | ||||
| @@ -647,7 +650,7 @@ html, body { | |||||
| margin-right: 18px; | margin-right: 18px; | ||||
| } | } | ||||
| #dashboard-switch .dropdown-menu { | |||||
| #dashboard-switch .dropdown-menu,#repo-owner-switch .dropdown-menu { | |||||
| padding: 0; | padding: 0; | ||||
| } | } | ||||
| @@ -662,6 +665,14 @@ html, body { | |||||
| padding: .8em 1.2em; | padding: .8em 1.2em; | ||||
| } | } | ||||
| #dashboard-switch-menu > li > a:hover { | |||||
| text-decoration: none; | |||||
| } | |||||
| #dashboard-switch-menu > li > a img, #dashboard-switch button img { | |||||
| margin-right: 6px; | |||||
| } | |||||
| #dashboard-switch-menu > li { | #dashboard-switch-menu > li { | ||||
| border-bottom: 1px solid #eaeaea; | border-bottom: 1px solid #eaeaea; | ||||
| } | } | ||||
| @@ -1864,16 +1875,44 @@ html, body { | |||||
| padding: 16px 0; | padding: 16px 0; | ||||
| } | } | ||||
| #body-nav.org-nav.org-nav-auto { | |||||
| height: auto; | |||||
| } | |||||
| .org-nav > .container { | |||||
| padding-left: 0; | |||||
| padding-left: 0; | |||||
| } | |||||
| .org-nav .org-logo { | .org-nav .org-logo { | ||||
| margin-right: 16px; | margin-right: 16px; | ||||
| width: 100px; | width: 100px; | ||||
| height: 100px; | height: 100px; | ||||
| } | } | ||||
| .org-nav .org-small-logo { | |||||
| margin-right: 16px; | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| } | |||||
| .org-nav .org-name { | .org-nav .org-name { | ||||
| margin-top: 0; | margin-top: 0; | ||||
| } | } | ||||
| .org-nav-auto .org-name { | |||||
| font-size: 1.4em; | |||||
| line-height: 48px; | |||||
| } | |||||
| #body-nav.org-nav-auto .nav { | |||||
| margin-top: 6px; | |||||
| } | |||||
| #body-nav.org-nav-auto .nav a:hover { | |||||
| text-decoration: none; | |||||
| } | |||||
| .org-description { | .org-description { | ||||
| font-size: 16px; | font-size: 16px; | ||||
| } | } | ||||
| @@ -1894,6 +1933,10 @@ html, body { | |||||
| margin-left: 0; | margin-left: 0; | ||||
| } | } | ||||
| .org-main { | |||||
| padding-left: 0; | |||||
| } | |||||
| .org-sidebar { | .org-sidebar { | ||||
| margin-top: -100px; | margin-top: -100px; | ||||
| } | } | ||||
| @@ -1947,4 +1990,72 @@ html, body { | |||||
| .org-team a:hover .org-team-name { | .org-team a:hover .org-team-name { | ||||
| color: #0079bc !important; | color: #0079bc !important; | ||||
| } | |||||
| #org-members { | |||||
| margin-right: 30px; | |||||
| } | |||||
| #org-members .member .avatar img { | |||||
| width: 50px; | |||||
| height: 50px; | |||||
| } | |||||
| #org-members .member { | |||||
| padding-bottom: 20px; | |||||
| margin-bottom: 20px; | |||||
| border-bottom: 1px solid #DDD; | |||||
| height: 70px; | |||||
| } | |||||
| #org-members .member .name { | |||||
| padding-top: 4px; | |||||
| } | |||||
| #org-members .member .nick { | |||||
| display: block; | |||||
| color: #888; | |||||
| } | |||||
| #org-members .member .name a { | |||||
| color: #444; | |||||
| } | |||||
| #org-members .member .name strong { | |||||
| font-size: 1.2em; | |||||
| } | |||||
| #org-members .status, #org-members .role { | |||||
| line-height: 48px; | |||||
| text-align: right; | |||||
| } | |||||
| #org-teams .org-team .panel-heading { | |||||
| margin-top: 0; | |||||
| } | |||||
| #org-teams .org-team .panel-heading a { | |||||
| color: #444; | |||||
| } | |||||
| #org-teams .org-team-members { | |||||
| margin-top: 18px; | |||||
| } | |||||
| #org-teams .org-team-members img { | |||||
| width: 40px; | |||||
| height: 40px; | |||||
| margin-right: 12px; | |||||
| } | |||||
| #org-teams .org-team-members a { | |||||
| display: inline-block; | |||||
| } | |||||
| #org-teams .org-team .panel-footer { | |||||
| height: 60px; | |||||
| } | |||||
| #org-teams .org-team { | |||||
| border-bottom: none; | |||||
| } | } | ||||
| @@ -758,6 +758,27 @@ function initRepoSetting() { | |||||
| }); | }); | ||||
| } | } | ||||
| function initRepoCreating() { | |||||
| // owner switch menu click | |||||
| (function () { | |||||
| $('#repo-owner-switch .dropdown-menu').on("click", "li", function () { | |||||
| var uid = $(this).data('uid'); | |||||
| // set to input | |||||
| $('#repo-owner-id').val(uid); | |||||
| // set checked class | |||||
| if (!$(this).hasClass("checked")) { | |||||
| $(this).parent().find(".checked").removeClass("checked"); | |||||
| $(this).addClass("checked"); | |||||
| } | |||||
| // set button group to show clicked owner | |||||
| $('#repo-owner-avatar').attr("src",$(this).find('img').attr("src")); | |||||
| $('#repo-owner-name').text($(this).text().trim()); | |||||
| console.log("set repo owner to uid :",uid,$(this).text().trim()); | |||||
| }); | |||||
| }()); | |||||
| console.log("init repo-creating scripts"); | |||||
| } | |||||
| (function ($) { | (function ($) { | ||||
| $(function () { | $(function () { | ||||
| initCore(); | initCore(); | ||||
| @@ -780,6 +801,9 @@ function initRepoSetting() { | |||||
| if ($('#repo-setting-container').length) { | if ($('#repo-setting-container').length) { | ||||
| initRepoSetting(); | initRepoSetting(); | ||||
| } | } | ||||
| if ($('#repo-create').length) { | |||||
| initRepoCreating(); | |||||
| } | |||||
| }); | }); | ||||
| })(jQuery); | })(jQuery); | ||||
| @@ -20,6 +20,16 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "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 startTime = time.Now() | ||||
| var sysStatus struct { | var sysStatus struct { | ||||
| @@ -140,7 +150,7 @@ func Dashboard(ctx *middleware.Context) { | |||||
| ctx.Data["Stats"] = models.GetStatistic() | ctx.Data["Stats"] = models.GetStatistic() | ||||
| updateSystemStatus() | updateSystemStatus() | ||||
| ctx.Data["SysStatus"] = sysStatus | ctx.Data["SysStatus"] = sysStatus | ||||
| ctx.HTML(200, "admin/dashboard") | |||||
| ctx.HTML(200, DASHBOARD) | |||||
| } | } | ||||
| func Users(ctx *middleware.Context) { | func Users(ctx *middleware.Context) { | ||||
| @@ -150,10 +160,10 @@ func Users(ctx *middleware.Context) { | |||||
| var err error | var err error | ||||
| ctx.Data["Users"], err = models.GetUsers(200, 0) | ctx.Data["Users"], err = models.GetUsers(200, 0) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.Users", err) | |||||
| ctx.Handle(500, "admin.Users(GetUsers)", err) | |||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(200, "admin/users") | |||||
| ctx.HTML(200, USERS) | |||||
| } | } | ||||
| func Repositories(ctx *middleware.Context) { | func Repositories(ctx *middleware.Context) { | ||||
| @@ -166,7 +176,7 @@ func Repositories(ctx *middleware.Context) { | |||||
| ctx.Handle(500, "admin.Repositories", err) | ctx.Handle(500, "admin.Repositories", err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(200, "admin/repos") | |||||
| ctx.HTML(200, REPOS) | |||||
| } | } | ||||
| func Auths(ctx *middleware.Context) { | func Auths(ctx *middleware.Context) { | ||||
| @@ -179,7 +189,7 @@ func Auths(ctx *middleware.Context) { | |||||
| ctx.Handle(500, "admin.Auths", err) | ctx.Handle(500, "admin.Auths", err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(200, "admin/auths") | |||||
| ctx.HTML(200, AUTHS) | |||||
| } | } | ||||
| func Config(ctx *middleware.Context) { | func Config(ctx *middleware.Context) { | ||||
| @@ -196,7 +206,7 @@ func Config(ctx *middleware.Context) { | |||||
| ctx.Data["StaticRootPath"] = setting.StaticRootPath | ctx.Data["StaticRootPath"] = setting.StaticRootPath | ||||
| ctx.Data["LogRootPath"] = setting.LogRootPath | ctx.Data["LogRootPath"] = setting.LogRootPath | ||||
| ctx.Data["ScriptType"] = setting.ScriptType | ctx.Data["ScriptType"] = setting.ScriptType | ||||
| ctx.Data["ReverseProxyAuthUid"] = setting.ReverseProxyAuthUid | |||||
| ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser | |||||
| ctx.Data["Service"] = setting.Service | ctx.Data["Service"] = setting.Service | ||||
| @@ -235,7 +245,7 @@ func Config(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["Loggers"] = loggers | ctx.Data["Loggers"] = loggers | ||||
| ctx.HTML(200, "admin/config") | |||||
| ctx.HTML(200, CONFIG) | |||||
| } | } | ||||
| func Monitor(ctx *middleware.Context) { | func Monitor(ctx *middleware.Context) { | ||||
| @@ -247,11 +257,10 @@ func Monitor(ctx *middleware.Context) { | |||||
| case "process": | case "process": | ||||
| ctx.Data["PageIsMonitorProcess"] = true | ctx.Data["PageIsMonitorProcess"] = true | ||||
| ctx.Data["Processes"] = process.Processes | ctx.Data["Processes"] = process.Processes | ||||
| ctx.HTML(200, "admin/monitor/process") | |||||
| ctx.HTML(200, MONITOR_PROCESS) | |||||
| default: | default: | ||||
| ctx.Data["PageIsMonitorCron"] = true | ctx.Data["PageIsMonitorCron"] = true | ||||
| ctx.Data["Entries"] = cron.ListEntries() | ctx.Data["Entries"] = cron.ListEntries() | ||||
| ctx.HTML(200, "admin/monitor/cron") | |||||
| ctx.HTML(200, MONITOR_CRON) | |||||
| } | } | ||||
| } | } | ||||
| @@ -18,12 +18,17 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "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) { | func NewAuthSource(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "New Authentication" | ctx.Data["Title"] = "New Authentication" | ||||
| ctx.Data["PageIsAuths"] = true | ctx.Data["PageIsAuths"] = true | ||||
| ctx.Data["LoginTypes"] = models.LoginTypes | ctx.Data["LoginTypes"] = models.LoginTypes | ||||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | ctx.Data["SMTPAuths"] = models.SMTPAuths | ||||
| ctx.HTML(200, "admin/auths/new") | |||||
| ctx.HTML(200, AUTH_NEW) | |||||
| } | } | ||||
| func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | ||||
| @@ -33,7 +38,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | ctx.Data["SMTPAuths"] = models.SMTPAuths | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "admin/auths/new") | |||||
| ctx.HTML(200, AUTH_NEW) | |||||
| return | return | ||||
| } | } | ||||
| @@ -74,7 +79,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||
| } | } | ||||
| if err := models.CreateSource(source); err != nil { | if err := models.CreateSource(source); err != nil { | ||||
| ctx.Handle(500, "admin.auths.NewAuth", err) | |||||
| ctx.Handle(500, "admin.auths.NewAuth(CreateSource)", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -97,11 +102,11 @@ func EditAuthSource(ctx *middleware.Context, params martini.Params) { | |||||
| } | } | ||||
| u, err := models.GetLoginSourceById(id) | u, err := models.GetLoginSourceById(id) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.user.EditUser", err) | |||||
| ctx.Handle(500, "admin.user.EditUser(GetLoginSourceById)", err) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["Source"] = u | ctx.Data["Source"] = u | ||||
| ctx.HTML(200, "admin/auths/edit") | |||||
| ctx.HTML(200, AUTH_EDIT) | |||||
| } | } | ||||
| func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | ||||
| @@ -111,7 +116,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||
| ctx.Data["SMTPAuths"] = models.SMTPAuths | ctx.Data["SMTPAuths"] = models.SMTPAuths | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "admin/auths/edit") | |||||
| ctx.HTML(200, AUTH_EDIT) | |||||
| return | return | ||||
| } | } | ||||
| @@ -153,7 +158,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) { | |||||
| } | } | ||||
| if err := models.UpdateSource(&u); err != nil { | if err := models.UpdateSource(&u); err != nil { | ||||
| ctx.Handle(500, "admin.auths.EditAuth", err) | |||||
| ctx.Handle(500, "admin.auths.EditAuth(UpdateSource)", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -175,7 +180,7 @@ func DeleteAuthSource(ctx *middleware.Context, params martini.Params) { | |||||
| a, err := models.GetLoginSourceById(id) | a, err := models.GetLoginSourceById(id) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.auths.DeleteAuth", err) | |||||
| ctx.Handle(500, "admin.auths.DeleteAuth(GetLoginSourceById)", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -185,7 +190,7 @@ func DeleteAuthSource(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.") | 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"]) | ctx.Redirect("/admin/auths/" + params["authid"]) | ||||
| default: | default: | ||||
| ctx.Handle(500, "admin.auths.DeleteAuth", err) | |||||
| ctx.Handle(500, "admin.auths.DeleteAuth(DelLoginSource)", err) | |||||
| } | } | ||||
| return | return | ||||
| } | } | ||||
| @@ -5,8 +5,6 @@ | |||||
| package admin | package admin | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "strconv" | |||||
| "strings" | "strings" | ||||
| "github.com/go-martini/martini" | "github.com/go-martini/martini" | ||||
| @@ -18,16 +16,21 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "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) { | func NewUser(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "New Account" | ctx.Data["Title"] = "New Account" | ||||
| ctx.Data["PageIsUsers"] = true | ctx.Data["PageIsUsers"] = true | ||||
| auths, err := models.GetAuths() | auths, err := models.GetAuths() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.user.NewUser", err) | |||||
| ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["LoginSources"] = auths | ctx.Data["LoginSources"] = auths | ||||
| ctx.HTML(200, "admin/users/new") | |||||
| ctx.HTML(200, USER_NEW) | |||||
| } | } | ||||
| func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | ||||
| @@ -35,7 +38,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | |||||
| ctx.Data["PageIsUsers"] = true | ctx.Data["PageIsUsers"] = true | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "admin/users/new") | |||||
| ctx.HTML(200, USER_NEW) | |||||
| return | return | ||||
| } | } | ||||
| @@ -55,25 +58,25 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) { | |||||
| } | } | ||||
| if len(form.LoginType) > 0 { | if len(form.LoginType) > 0 { | ||||
| // NOTE: need rewrite. | |||||
| fields := strings.Split(form.LoginType, "-") | fields := strings.Split(form.LoginType, "-") | ||||
| tp, _ := strconv.Atoi(fields[0]) | |||||
| tp, _ := base.StrTo(fields[0]).Int() | |||||
| u.LoginType = models.LoginType(tp) | u.LoginType = models.LoginType(tp) | ||||
| u.LoginSource, _ = strconv.ParseInt(fields[1], 10, 64) | |||||
| u.LoginSource, _ = base.StrTo(fields[1]).Int64() | |||||
| u.LoginName = form.LoginName | u.LoginName = form.LoginName | ||||
| fmt.Println(u.LoginType, u.LoginSource, u.LoginName) | |||||
| } | } | ||||
| var err error | var err error | ||||
| if u, err = models.RegisterUser(u); err != nil { | |||||
| if u, err = models.CreateUser(u); err != nil { | |||||
| switch err { | switch err { | ||||
| case models.ErrUserAlreadyExist: | 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: | 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: | case models.ErrUserNameIllegal: | ||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "admin/users/new", &form) | |||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), USER_NEW, &form) | |||||
| default: | default: | ||||
| ctx.Handle(500, "admin.user.NewUser", err) | |||||
| ctx.Handle(500, "admin.user.NewUser(CreateUser)", err) | |||||
| } | } | ||||
| return | return | ||||
| } | } | ||||
| @@ -96,18 +99,18 @@ func EditUser(ctx *middleware.Context, params martini.Params) { | |||||
| u, err := models.GetUserById(int64(uid)) | u, err := models.GetUserById(int64(uid)) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.user.EditUser", err) | |||||
| ctx.Handle(500, "admin.user.EditUser(GetUserById)", err) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["User"] = u | ctx.Data["User"] = u | ||||
| auths, err := models.GetAuths() | auths, err := models.GetAuths() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.user.NewUser", err) | |||||
| ctx.Handle(500, "admin.user.NewUser(GetAuths)", err) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["LoginSources"] = auths | 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) { | 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() | uid, err := base.StrTo(params["userid"]).Int() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(404, "admin.user.EditUser", err) | |||||
| ctx.Handle(404, "admin.user.EditUserPost", err) | |||||
| return | return | ||||
| } | } | ||||
| u, err := models.GetUserById(int64(uid)) | u, err := models.GetUserById(int64(uid)) | ||||
| if err != nil { | 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 | return | ||||
| } | } | ||||
| @@ -134,7 +142,7 @@ func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.Admi | |||||
| u.IsActive = form.Active | u.IsActive = form.Active | ||||
| u.IsAdmin = form.Admin | u.IsAdmin = form.Admin | ||||
| if err := models.UpdateUser(u); err != nil { | if err := models.UpdateUser(u); err != nil { | ||||
| ctx.Handle(500, "admin.user.EditUser", err) | |||||
| ctx.Handle(500, "admin.user.EditUserPost(UpdateUser)", err) | |||||
| return | return | ||||
| } | } | ||||
| log.Trace("%s User profile updated by admin(%s): %s", ctx.Req.RequestURI, | 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") | //log.Info("delete") | ||||
| uid, err := base.StrTo(params["userid"]).Int() | uid, err := base.StrTo(params["userid"]).Int() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(404, "admin.user.EditUser", err) | |||||
| ctx.Handle(404, "admin.user.DeleteUser", err) | |||||
| return | return | ||||
| } | } | ||||
| u, err := models.GetUserById(int64(uid)) | u, err := models.GetUserById(int64(uid)) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "admin.user.EditUser", err) | |||||
| ctx.Handle(500, "admin.user.DeleteUser(GetUserById)", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -6,11 +6,16 @@ package routers | |||||
| import ( | import ( | ||||
| "github.com/gogits/gogs/models" | "github.com/gogits/gogs/models" | ||||
| "github.com/gogits/gogs/modules/base" | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| "github.com/gogits/gogs/routers/user" | "github.com/gogits/gogs/routers/user" | ||||
| ) | ) | ||||
| const ( | |||||
| HOME base.TplName = "home" | |||||
| ) | |||||
| func Home(ctx *middleware.Context) { | func Home(ctx *middleware.Context) { | ||||
| if ctx.IsSigned { | if ctx.IsSigned { | ||||
| user.Dashboard(ctx) | user.Dashboard(ctx) | ||||
| @@ -40,7 +45,7 @@ func Home(ctx *middleware.Context) { | |||||
| } | } | ||||
| } | } | ||||
| ctx.Data["Repos"] = repos | ctx.Data["Repos"] = repos | ||||
| ctx.HTML(200, "home") | |||||
| ctx.HTML(200, HOME) | |||||
| } | } | ||||
| func NotFound(ctx *middleware.Context) { | func NotFound(ctx *middleware.Context) { | ||||
| @@ -8,6 +8,7 @@ import ( | |||||
| "github.com/go-martini/martini" | "github.com/go-martini/martini" | ||||
| "github.com/gogits/gogs/models" | "github.com/gogits/gogs/models" | ||||
| "github.com/gogits/gogs/modules/base" | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| "github.com/gogits/gogs/modules/setting" | "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["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60 | ||||
| ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60 | ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60 | ||||
| ctx.Data["CurDbValue"] = "" | ctx.Data["CurDbValue"] = "" | ||||
| ctx.HTML(200, params["_1"]) | |||||
| ctx.HTML(200, base.TplName(params["_1"])) | |||||
| } | } | ||||
| @@ -26,6 +26,10 @@ import ( | |||||
| "github.com/gogits/gogs/modules/social" | "github.com/gogits/gogs/modules/social" | ||||
| ) | ) | ||||
| const ( | |||||
| INSTALL base.TplName = "install" | |||||
| ) | |||||
| func checkRunMode() { | func checkRunMode() { | ||||
| switch setting.Cfg.MustValue("", "RUN_MODE") { | switch setting.Cfg.MustValue("", "RUN_MODE") { | ||||
| case "prod": | case "prod": | ||||
| @@ -72,6 +76,7 @@ func renderDbOption(ctx *middleware.Context) { | |||||
| ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"} | ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"} | ||||
| } | } | ||||
| // @router /install [get] | |||||
| func Install(ctx *middleware.Context, form auth.InstallForm) { | func Install(ctx *middleware.Context, form auth.InstallForm) { | ||||
| if setting.InstallLock { | if setting.InstallLock { | ||||
| ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) | 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 | ctx.Data["CurDbOption"] = curDbOp | ||||
| auth.AssignForm(form, ctx.Data) | auth.AssignForm(form, ctx.Data) | ||||
| ctx.HTML(200, "install") | |||||
| ctx.HTML(200, INSTALL) | |||||
| } | } | ||||
| func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | ||||
| if setting.InstallLock { | if setting.InstallLock { | ||||
| ctx.Handle(404, "install.Install", errors.New("Installation is prohibited")) | |||||
| ctx.Handle(404, "install.InstallPost", errors.New("Installation is prohibited")) | |||||
| return | return | ||||
| } | } | ||||
| @@ -135,12 +140,12 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | |||||
| ctx.Data["CurDbOption"] = form.Database | ctx.Data["CurDbOption"] = form.Database | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "install") | |||||
| ctx.HTML(200, INSTALL) | |||||
| return | return | ||||
| } | } | ||||
| if _, err := exec.LookPath("git"); err != nil { | 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 | return | ||||
| } | } | ||||
| @@ -158,18 +163,19 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | |||||
| // Set test engine. | // Set test engine. | ||||
| var x *xorm.Engine | var x *xorm.Engine | ||||
| if err := models.NewTestEngine(x); err != nil { | 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`) { | if strings.Contains(err.Error(), `Unknown database type: sqlite3`) { | ||||
| ctx.RenderWithErr("Your release version does not support SQLite3, please download the official binary version "+ | 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 { | } else { | ||||
| ctx.RenderWithErr("Database setting is not correct: "+err.Error(), "install", &form) | |||||
| ctx.RenderWithErr("Database setting is not correct: "+err.Error(), INSTALL, &form) | |||||
| } | } | ||||
| return | return | ||||
| } | } | ||||
| // Test repository root path. | // Test repository root path. | ||||
| if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil { | 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 | return | ||||
| } | } | ||||
| @@ -180,7 +186,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | |||||
| } | } | ||||
| // Does not check run user when the install lock is off. | // Does not check run user when the install lock is off. | ||||
| if form.RunUser != curUser { | 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 | return | ||||
| } | } | ||||
| @@ -214,18 +220,18 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) { | |||||
| os.MkdirAll("custom/conf", os.ModePerm) | os.MkdirAll("custom/conf", os.ModePerm) | ||||
| if err := goconfig.SaveConfigFile(setting.Cfg, path.Join(setting.CustomPath, "conf/app.ini")); err != nil { | 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 | return | ||||
| } | } | ||||
| GlobalInit() | GlobalInit() | ||||
| // Create admin account. | // 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 { | IsAdmin: true, IsActive: true}); err != nil { | ||||
| if err != models.ErrUserAlreadyExist { | if err != models.ErrUserAlreadyExist { | ||||
| setting.InstallLock = false | 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 | return | ||||
| } | } | ||||
| log.Info("Admin account already exist") | log.Info("Admin account already exist") | ||||
| @@ -1,11 +1,162 @@ | |||||
| // 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 | package org | ||||
| import ( | import ( | ||||
| "github.com/go-martini/martini" | "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/modules/middleware" | ||||
| "github.com/gogits/gogs/routers/user" | |||||
| ) | |||||
| const ( | |||||
| NEW base.TplName = "org/new" | |||||
| SETTINGS base.TplName = "org/settings" | |||||
| ) | ) | ||||
| func Organization(ctx *middleware.Context, params martini.Params) { | func Organization(ctx *middleware.Context, params martini.Params) { | ||||
| ctx.Data["Title"] = "Organization Name" + params["org"] | |||||
| ctx.Data["Title"] = "Organization " + params["org"] | |||||
| ctx.HTML(200, "org/org") | ctx.HTML(200, "org/org") | ||||
| } | } | ||||
| func Members(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["Title"] = "Organization " + params["org"] + " Members" | |||||
| ctx.HTML(200, "org/members") | |||||
| } | |||||
| func New(ctx *middleware.Context) { | |||||
| ctx.Data["Title"] = "Create An Organization" | |||||
| ctx.HTML(200, NEW) | |||||
| } | |||||
| func NewPost(ctx *middleware.Context, form auth.CreateOrgForm) { | |||||
| 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.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 Settings(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.Settings(GetUserByName)", err) | |||||
| } else { | |||||
| ctx.Handle(500, "org.Settings(GetUserByName)", err) | |||||
| } | |||||
| return | |||||
| } | |||||
| ctx.Data["Org"] = org | |||||
| ctx.HTML(200, SETTINGS) | |||||
| } | |||||
| func SettingsPost(ctx *middleware.Context, params martini.Params, form auth.OrgSettingForm) { | |||||
| ctx.Data["Title"] = "Settings" | |||||
| org, err := models.GetUserByName(params["org"]) | |||||
| if err != nil { | |||||
| if err == models.ErrUserNotExist { | |||||
| ctx.Handle(404, "org.SettingsPost(GetUserByName)", err) | |||||
| } else { | |||||
| ctx.Handle(500, "org.SettingsPost(GetUserByName)", err) | |||||
| } | |||||
| return | |||||
| } | |||||
| ctx.Data["Org"] = org | |||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, SETTINGS) | |||||
| return | |||||
| } | |||||
| org.FullName = form.DisplayName | |||||
| org.Email = form.Email | |||||
| org.Description = form.Description | |||||
| org.Website = form.Website | |||||
| org.Location = form.Location | |||||
| if err = models.UpdateUser(org); err != nil { | |||||
| ctx.Handle(500, "org.SettingsPost(UpdateUser)", err) | |||||
| return | |||||
| } | |||||
| log.Trace("%s Organization setting updated: %s", ctx.Req.RequestURI, org.LowerName) | |||||
| ctx.Flash.Success("Organization profile has been successfully updated.") | |||||
| ctx.Redirect("/org/" + org.Name + "/settings") | |||||
| } | |||||
| @@ -0,0 +1,21 @@ | |||||
| package org | |||||
| import ( | |||||
| "github.com/go-martini/martini" | |||||
| "github.com/gogits/gogs/modules/middleware" | |||||
| ) | |||||
| func Teams(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["Title"] = "Organization "+params["org"]+" Teams" | |||||
| ctx.HTML(200, "org/teams") | |||||
| } | |||||
| func NewTeam(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["Title"] = "Organization "+params["org"]+" New Team" | |||||
| ctx.HTML(200, "org/new_team") | |||||
| } | |||||
| func EditTeam(ctx *middleware.Context, params martini.Params){ | |||||
| ctx.Data["Title"] = "Organization "+params["org"]+" Edit Team" | |||||
| ctx.HTML(200,"org/edit_team") | |||||
| } | |||||
| @@ -7,22 +7,27 @@ package repo | |||||
| import ( | import ( | ||||
| "github.com/go-martini/martini" | "github.com/go-martini/martini" | ||||
| "github.com/gogits/gogs/modules/base" | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| BRANCH base.TplName = "repo/branch" | |||||
| ) | |||||
| func Branches(ctx *middleware.Context, params martini.Params) { | func Branches(ctx *middleware.Context, params martini.Params) { | ||||
| ctx.Data["Title"] = "Branches" | ctx.Data["Title"] = "Branches" | ||||
| ctx.Data["IsRepoToolbarBranches"] = true | ctx.Data["IsRepoToolbarBranches"] = true | ||||
| brs, err := ctx.Repo.GitRepo.GetBranches() | brs, err := ctx.Repo.GitRepo.GetBranches() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "repo.Branches", err) | |||||
| ctx.Handle(500, "repo.Branches(GetBranches)", err) | |||||
| return | return | ||||
| } else if len(brs) == 0 { | } else if len(brs) == 0 { | ||||
| ctx.Handle(404, "repo.Branches", nil) | |||||
| ctx.Handle(404, "repo.Branches(GetBranches)", nil) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["Branches"] = brs | ctx.Data["Branches"] = brs | ||||
| ctx.HTML(200, "repo/branches") | |||||
| ctx.HTML(200, BRANCH) | |||||
| } | } | ||||
| @@ -14,6 +14,11 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| COMMITS base.TplName = "repo/commits" | |||||
| DIFF base.TplName = "repo/diff" | |||||
| ) | |||||
| func Commits(ctx *middleware.Context, params martini.Params) { | func Commits(ctx *middleware.Context, params martini.Params) { | ||||
| ctx.Data["IsRepoToolbarCommits"] = true | ctx.Data["IsRepoToolbarCommits"] = true | ||||
| @@ -22,10 +27,10 @@ func Commits(ctx *middleware.Context, params martini.Params) { | |||||
| brs, err := ctx.Repo.GitRepo.GetBranches() | brs, err := ctx.Repo.GitRepo.GetBranches() | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "repo.Commits", err) | |||||
| ctx.Handle(500, "repo.Commits(GetBranches)", err) | |||||
| return | return | ||||
| } else if len(brs) == 0 { | } else if len(brs) == 0 { | ||||
| ctx.Handle(404, "repo.Commits", nil) | |||||
| ctx.Handle(404, "repo.Commits(GetBranches)", nil) | |||||
| return | return | ||||
| } | } | ||||
| @@ -61,7 +66,43 @@ func Commits(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["CommitCount"] = commitsCount | ctx.Data["CommitCount"] = commitsCount | ||||
| ctx.Data["LastPageNum"] = lastPage | ctx.Data["LastPageNum"] = lastPage | ||||
| ctx.Data["NextPageNum"] = nextPage | ctx.Data["NextPageNum"] = nextPage | ||||
| ctx.HTML(200, "repo/commits") | |||||
| ctx.HTML(200, COMMITS) | |||||
| } | |||||
| func SearchCommits(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["IsSearchPage"] = true | |||||
| ctx.Data["IsRepoToolbarCommits"] = true | |||||
| keyword := ctx.Query("q") | |||||
| if len(keyword) == 0 { | |||||
| ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchName) | |||||
| return | |||||
| } | |||||
| userName := params["username"] | |||||
| repoName := params["reponame"] | |||||
| brs, err := ctx.Repo.GitRepo.GetBranches() | |||||
| if err != nil { | |||||
| ctx.Handle(500, "repo.SearchCommits(GetBranches)", err) | |||||
| return | |||||
| } else if len(brs) == 0 { | |||||
| ctx.Handle(404, "repo.SearchCommits(GetBranches)", nil) | |||||
| return | |||||
| } | |||||
| commits, err := ctx.Repo.Commit.SearchCommits(keyword) | |||||
| if err != nil { | |||||
| ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Keyword"] = keyword | |||||
| ctx.Data["Username"] = userName | |||||
| ctx.Data["Reponame"] = repoName | |||||
| ctx.Data["CommitCount"] = commits.Len() | |||||
| ctx.Data["Commits"] = commits | |||||
| ctx.HTML(200, COMMITS) | |||||
| } | } | ||||
| func Diff(ctx *middleware.Context, params martini.Params) { | func Diff(ctx *middleware.Context, params martini.Params) { | ||||
| @@ -75,7 +116,7 @@ func Diff(ctx *middleware.Context, params martini.Params) { | |||||
| diff, err := models.GetDiff(models.RepoPath(userName, repoName), commitId) | diff, err := models.GetDiff(models.RepoPath(userName, repoName), commitId) | ||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(404, "repo.Diff", err) | |||||
| ctx.Handle(404, "repo.Diff(GetDiff)", err) | |||||
| return | return | ||||
| } | } | ||||
| @@ -119,43 +160,7 @@ func Diff(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 | ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0 | ||||
| ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId) | ctx.Data["SourcePath"] = "/" + path.Join(userName, repoName, "src", commitId) | ||||
| ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", commitId) | ctx.Data["RawPath"] = "/" + path.Join(userName, repoName, "raw", commitId) | ||||
| ctx.HTML(200, "repo/diff") | |||||
| } | |||||
| func SearchCommits(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["IsSearchPage"] = true | |||||
| ctx.Data["IsRepoToolbarCommits"] = true | |||||
| keyword := ctx.Query("q") | |||||
| if len(keyword) == 0 { | |||||
| ctx.Redirect(ctx.Repo.RepoLink + "/commits/" + ctx.Repo.BranchName) | |||||
| return | |||||
| } | |||||
| userName := params["username"] | |||||
| repoName := params["reponame"] | |||||
| brs, err := ctx.Repo.GitRepo.GetBranches() | |||||
| if err != nil { | |||||
| ctx.Handle(500, "repo.SearchCommits(GetBranches)", err) | |||||
| return | |||||
| } else if len(brs) == 0 { | |||||
| ctx.Handle(404, "repo.SearchCommits(GetBranches)", nil) | |||||
| return | |||||
| } | |||||
| commits, err := ctx.Repo.Commit.SearchCommits(keyword) | |||||
| if err != nil { | |||||
| ctx.Handle(500, "repo.SearchCommits(SearchCommits)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Keyword"] = keyword | |||||
| ctx.Data["Username"] = userName | |||||
| ctx.Data["Reponame"] = repoName | |||||
| ctx.Data["CommitCount"] = commits.Len() | |||||
| ctx.Data["Commits"] = commits | |||||
| ctx.HTML(200, "repo/commits") | |||||
| ctx.HTML(200, DIFF) | |||||
| } | } | ||||
| func FileHistory(ctx *middleware.Context, params martini.Params) { | func FileHistory(ctx *middleware.Context, params martini.Params) { | ||||
| @@ -184,8 +189,7 @@ func FileHistory(ctx *middleware.Context, params martini.Params) { | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "repo.FileHistory(GetCommitsCount)", err) | ctx.Handle(500, "repo.FileHistory(GetCommitsCount)", err) | ||||
| return | return | ||||
| } | |||||
| if commitsCount == 0 { | |||||
| } else if commitsCount == 0 { | |||||
| ctx.Handle(404, "repo.FileHistory", nil) | ctx.Handle(404, "repo.FileHistory", nil) | ||||
| return | return | ||||
| } | } | ||||
| @@ -217,5 +221,5 @@ func FileHistory(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["CommitCount"] = commitsCount | ctx.Data["CommitCount"] = commitsCount | ||||
| ctx.Data["LastPageNum"] = lastPage | ctx.Data["LastPageNum"] = lastPage | ||||
| ctx.Data["NextPageNum"] = nextPage | ctx.Data["NextPageNum"] = nextPage | ||||
| ctx.HTML(200, "repo/commits") | |||||
| ctx.HTML(200, COMMITS) | |||||
| } | } | ||||
| @@ -107,9 +107,9 @@ func Http(ctx *middleware.Context, params martini.Params) { | |||||
| } | } | ||||
| if !isPublicPull { | if !isPublicPull { | ||||
| var tp = models.AU_WRITABLE | |||||
| var tp = models.WRITABLE | |||||
| if isPull { | if isPull { | ||||
| tp = models.AU_READABLE | |||||
| tp = models.READABLE | |||||
| } | } | ||||
| has, err := models.HasAccess(authUsername, username+"/"+reponame, tp) | 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) | ctx.Handle(401, "no basic auth and digit auth", nil) | ||||
| return | return | ||||
| } else if !has { | } 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 { | if err != nil || !has { | ||||
| ctx.Handle(401, "no basic auth and digit auth", nil) | ctx.Handle(401, "no basic auth and digit auth", nil) | ||||
| return | return | ||||
| @@ -22,6 +22,16 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| const ( | |||||
| ISSUES base.TplName = "repo/issue/list" | |||||
| ISSUE_CREATE base.TplName = "repo/issue/create" | |||||
| ISSUE_VIEW base.TplName = "repo/issue/view" | |||||
| MILESTONE base.TplName = "repo/issue/milestone" | |||||
| MILESTONE_NEW base.TplName = "repo/issue/milestone_new" | |||||
| MILESTONE_EDIT base.TplName = "repo/issue/milestone_edit" | |||||
| ) | |||||
| func Issues(ctx *middleware.Context) { | func Issues(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Issues" | ctx.Data["Title"] = "Issues" | ||||
| ctx.Data["IsRepoToolbarIssues"] = true | ctx.Data["IsRepoToolbarIssues"] = true | ||||
| @@ -134,7 +144,7 @@ func Issues(ctx *middleware.Context) { | |||||
| } else { | } else { | ||||
| ctx.Data["ShowCount"] = issueStats.OpenCount | ctx.Data["ShowCount"] = issueStats.OpenCount | ||||
| } | } | ||||
| ctx.HTML(200, "issue/list") | |||||
| ctx.HTML(200, ISSUES) | |||||
| } | } | ||||
| func CreateIssue(ctx *middleware.Context, params martini.Params) { | func CreateIssue(ctx *middleware.Context, params martini.Params) { | ||||
| @@ -161,7 +171,7 @@ func CreateIssue(ctx *middleware.Context, params martini.Params) { | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["Collaborators"] = us | ctx.Data["Collaborators"] = us | ||||
| ctx.HTML(200, "issue/create") | |||||
| ctx.HTML(200, ISSUE_CREATE) | |||||
| } | } | ||||
| func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { | func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { | ||||
| @@ -190,7 +200,7 @@ func CreateIssuePost(ctx *middleware.Context, params martini.Params, form auth.C | |||||
| ctx.Data["Collaborators"] = us | ctx.Data["Collaborators"] = us | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "issue/create") | |||||
| ctx.HTML(200, ISSUE_CREATE) | |||||
| return | return | ||||
| } | } | ||||
| @@ -392,7 +402,7 @@ func ViewIssue(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner || (ctx.IsSigned && issue.PosterId == ctx.User.Id) | ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner || (ctx.IsSigned && issue.PosterId == ctx.User.Id) | ||||
| ctx.Data["IsRepoToolbarIssues"] = true | ctx.Data["IsRepoToolbarIssues"] = true | ||||
| ctx.Data["IsRepoToolbarIssuesList"] = false | ctx.Data["IsRepoToolbarIssuesList"] = false | ||||
| ctx.HTML(200, "issue/view") | |||||
| ctx.HTML(200, ISSUE_VIEW) | |||||
| } | } | ||||
| func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { | func UpdateIssue(ctx *middleware.Context, params martini.Params, form auth.CreateIssueForm) { | ||||
| @@ -794,14 +804,14 @@ func Milestones(ctx *middleware.Context) { | |||||
| } else { | } else { | ||||
| ctx.Data["State"] = "open" | ctx.Data["State"] = "open" | ||||
| } | } | ||||
| ctx.HTML(200, "issue/milestone") | |||||
| ctx.HTML(200, MILESTONE) | |||||
| } | } | ||||
| func NewMilestone(ctx *middleware.Context) { | func NewMilestone(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "New Milestone" | ctx.Data["Title"] = "New Milestone" | ||||
| ctx.Data["IsRepoToolbarIssues"] = true | ctx.Data["IsRepoToolbarIssues"] = true | ||||
| ctx.Data["IsRepoToolbarIssuesList"] = true | ctx.Data["IsRepoToolbarIssuesList"] = true | ||||
| ctx.HTML(200, "issue/milestone_new") | |||||
| ctx.HTML(200, MILESTONE_NEW) | |||||
| } | } | ||||
| func NewMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) { | func NewMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) { | ||||
| @@ -809,6 +819,11 @@ func NewMilestonePost(ctx *middleware.Context, form auth.CreateMilestoneForm) { | |||||
| ctx.Data["IsRepoToolbarIssues"] = true | ctx.Data["IsRepoToolbarIssues"] = true | ||||
| ctx.Data["IsRepoToolbarIssuesList"] = true | ctx.Data["IsRepoToolbarIssuesList"] = true | ||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, MILESTONE_NEW) | |||||
| return | |||||
| } | |||||
| var deadline time.Time | var deadline time.Time | ||||
| var err error | var err error | ||||
| if len(form.Deadline) == 0 { | if len(form.Deadline) == 0 { | ||||
| @@ -890,7 +905,7 @@ func UpdateMilestone(ctx *middleware.Context, params martini.Params) { | |||||
| } | } | ||||
| ctx.Data["Milestone"] = mile | ctx.Data["Milestone"] = mile | ||||
| ctx.HTML(200, "issue/milestone_edit") | |||||
| ctx.HTML(200, MILESTONE_EDIT) | |||||
| } | } | ||||
| func UpdateMilestonePost(ctx *middleware.Context, params martini.Params, form auth.CreateMilestoneForm) { | func UpdateMilestonePost(ctx *middleware.Context, params martini.Params, form auth.CreateMilestoneForm) { | ||||
| @@ -914,6 +929,11 @@ func UpdateMilestonePost(ctx *middleware.Context, params martini.Params, form au | |||||
| return | return | ||||
| } | } | ||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, MILESTONE_EDIT) | |||||
| return | |||||
| } | |||||
| var deadline time.Time | var deadline time.Time | ||||
| if len(form.Deadline) == 0 { | if len(form.Deadline) == 0 { | ||||
| form.Deadline = "12/31/9999" | form.Deadline = "12/31/9999" | ||||
| @@ -7,10 +7,15 @@ package repo | |||||
| import ( | import ( | ||||
| "github.com/go-martini/martini" | "github.com/go-martini/martini" | ||||
| "github.com/gogits/gogs/modules/base" | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| PULLS base.TplName = "repo/pulls" | |||||
| ) | |||||
| func Pulls(ctx *middleware.Context, params martini.Params) { | func Pulls(ctx *middleware.Context, params martini.Params) { | ||||
| ctx.Data["IsRepoToolbarPulls"] = true | ctx.Data["IsRepoToolbarPulls"] = true | ||||
| ctx.HTML(200, "repo/pulls") | |||||
| ctx.HTML(200, PULLS) | |||||
| } | } | ||||
| @@ -14,6 +14,12 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| RELEASES base.TplName = "repo/release/list" | |||||
| RELEASE_NEW base.TplName = "repo/release/new" | |||||
| RELEASE_EDIT base.TplName = "repo/release/edit" | |||||
| ) | |||||
| func Releases(ctx *middleware.Context) { | func Releases(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Releases" | ctx.Data["Title"] = "Releases" | ||||
| ctx.Data["IsRepoToolbarReleases"] = true | ctx.Data["IsRepoToolbarReleases"] = true | ||||
| @@ -100,7 +106,7 @@ func Releases(ctx *middleware.Context) { | |||||
| } | } | ||||
| models.SortReleases(tags) | models.SortReleases(tags) | ||||
| ctx.Data["Releases"] = tags | ctx.Data["Releases"] = tags | ||||
| ctx.HTML(200, "release/list") | |||||
| ctx.HTML(200, RELEASES) | |||||
| } | } | ||||
| func NewRelease(ctx *middleware.Context) { | func NewRelease(ctx *middleware.Context) { | ||||
| @@ -112,7 +118,7 @@ func NewRelease(ctx *middleware.Context) { | |||||
| ctx.Data["Title"] = "New Release" | ctx.Data["Title"] = "New Release" | ||||
| ctx.Data["IsRepoToolbarReleases"] = true | ctx.Data["IsRepoToolbarReleases"] = true | ||||
| ctx.Data["IsRepoReleaseNew"] = true | ctx.Data["IsRepoReleaseNew"] = true | ||||
| ctx.HTML(200, "release/new") | |||||
| ctx.HTML(200, RELEASE_NEW) | |||||
| } | } | ||||
| func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) { | func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) { | ||||
| @@ -126,7 +132,7 @@ func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) { | |||||
| ctx.Data["IsRepoReleaseNew"] = true | ctx.Data["IsRepoReleaseNew"] = true | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "release/new") | |||||
| ctx.HTML(200, RELEASE_NEW) | |||||
| return | return | ||||
| } | } | ||||
| @@ -187,7 +193,7 @@ func EditRelease(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["Title"] = "Edit Release" | ctx.Data["Title"] = "Edit Release" | ||||
| ctx.Data["IsRepoToolbarReleases"] = true | ctx.Data["IsRepoToolbarReleases"] = true | ||||
| ctx.HTML(200, "release/edit") | |||||
| ctx.HTML(200, RELEASE_EDIT) | |||||
| } | } | ||||
| func EditReleasePost(ctx *middleware.Context, params martini.Params, form auth.EditReleaseForm) { | func EditReleasePost(ctx *middleware.Context, params martini.Params, form auth.EditReleaseForm) { | ||||
| @@ -208,6 +214,11 @@ func EditReleasePost(ctx *middleware.Context, params martini.Params, form auth.E | |||||
| } | } | ||||
| ctx.Data["Release"] = rel | ctx.Data["Release"] = rel | ||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, RELEASE_EDIT) | |||||
| return | |||||
| } | |||||
| ctx.Data["Title"] = "Edit Release" | ctx.Data["Title"] = "Edit Release" | ||||
| ctx.Data["IsRepoToolbarReleases"] = true | ctx.Data["IsRepoToolbarReleases"] = true | ||||
| @@ -25,12 +25,25 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| CREATE base.TplName = "repo/create" | |||||
| MIGRATE base.TplName = "repo/migrate" | |||||
| SINGLE base.TplName = "repo/single" | |||||
| ) | |||||
| func Create(ctx *middleware.Context) { | func Create(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Create repository" | ctx.Data["Title"] = "Create repository" | ||||
| ctx.Data["PageIsNewRepo"] = true | ctx.Data["PageIsNewRepo"] = true | ||||
| ctx.Data["LanguageIgns"] = models.LanguageIgns | ctx.Data["LanguageIgns"] = models.LanguageIgns | ||||
| ctx.Data["Licenses"] = models.Licenses | ctx.Data["Licenses"] = models.Licenses | ||||
| ctx.HTML(200, "repo/create") | |||||
| if err := ctx.User.GetOrganizations(); err != nil { | |||||
| ctx.Handle(500, "home.Dashboard(GetOrganizations)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Orgs"] = ctx.User.Orgs | |||||
| ctx.HTML(200, CREATE) | |||||
| } | } | ||||
| func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | ||||
| @@ -39,76 +52,125 @@ func CreatePost(ctx *middleware.Context, form auth.CreateRepoForm) { | |||||
| ctx.Data["LanguageIgns"] = models.LanguageIgns | ctx.Data["LanguageIgns"] = models.LanguageIgns | ||||
| ctx.Data["Licenses"] = models.Licenses | ctx.Data["Licenses"] = models.Licenses | ||||
| if err := ctx.User.GetOrganizations(); err != nil { | |||||
| ctx.Handle(500, "home.CreatePost(GetOrganizations)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Orgs"] = ctx.User.Orgs | |||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "repo/create") | |||||
| ctx.HTML(200, CREATE) | |||||
| return | return | ||||
| } | } | ||||
| repo, err := models.CreateRepository(ctx.User, form.RepoName, form.Description, | |||||
| u := ctx.User | |||||
| // Not equal means current user is an organization. | |||||
| if u.Id != form.Uid { | |||||
| var err error | |||||
| u, err = models.GetUserById(form.Uid) | |||||
| if err != nil { | |||||
| if err == models.ErrUserNotExist { | |||||
| ctx.Handle(404, "home.CreatePost(GetUserById)", err) | |||||
| } else { | |||||
| ctx.Handle(500, "home.CreatePost(GetUserById)", err) | |||||
| } | |||||
| return | |||||
| } | |||||
| } | |||||
| repo, err := models.CreateRepository(u, form.RepoName, form.Description, | |||||
| form.Language, form.License, form.Private, false, form.InitReadme) | form.Language, form.License, form.Private, false, form.InitReadme) | ||||
| if err == nil { | if err == nil { | ||||
| log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName) | |||||
| ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName) | |||||
| log.Trace("%s Repository created: %s/%s", ctx.Req.RequestURI, u.LowerName, form.RepoName) | |||||
| ctx.Redirect("/" + u.Name + "/" + form.RepoName) | |||||
| return | return | ||||
| } else if err == models.ErrRepoAlreadyExist { | } else if err == models.ErrRepoAlreadyExist { | ||||
| ctx.RenderWithErr("Repository name has already been used", "repo/create", &form) | |||||
| ctx.RenderWithErr("Repository name has already been used", CREATE, &form) | |||||
| return | return | ||||
| } else if err == models.ErrRepoNameIllegal { | } else if err == models.ErrRepoNameIllegal { | ||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/create", &form) | |||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), CREATE, &form) | |||||
| return | return | ||||
| } | } | ||||
| if repo != nil { | if repo != nil { | ||||
| if errDelete := models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); errDelete != nil { | |||||
| log.Error("repo.MigratePost(CreatePost): %v", errDelete) | |||||
| if errDelete := models.DeleteRepository(u.Id, repo.Id, u.Name); errDelete != nil { | |||||
| log.Error("repo.CreatePost(DeleteRepository): %v", errDelete) | |||||
| } | } | ||||
| } | } | ||||
| ctx.Handle(500, "repo.Create", err) | |||||
| ctx.Handle(500, "repo.CreatePost(CreateRepository)", err) | |||||
| } | } | ||||
| func Migrate(ctx *middleware.Context) { | func Migrate(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Migrate repository" | ctx.Data["Title"] = "Migrate repository" | ||||
| ctx.Data["PageIsNewRepo"] = true | ctx.Data["PageIsNewRepo"] = true | ||||
| ctx.HTML(200, "repo/migrate") | |||||
| if err := ctx.User.GetOrganizations(); err != nil { | |||||
| ctx.Handle(500, "home.Migrate(GetOrganizations)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Orgs"] = ctx.User.Orgs | |||||
| ctx.HTML(200, MIGRATE) | |||||
| } | } | ||||
| func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) { | func MigratePost(ctx *middleware.Context, form auth.MigrateRepoForm) { | ||||
| ctx.Data["Title"] = "Migrate repository" | ctx.Data["Title"] = "Migrate repository" | ||||
| ctx.Data["PageIsNewRepo"] = true | ctx.Data["PageIsNewRepo"] = true | ||||
| if err := ctx.User.GetOrganizations(); err != nil { | |||||
| ctx.Handle(500, "home.MigratePost(GetOrganizations)", err) | |||||
| return | |||||
| } | |||||
| ctx.Data["Orgs"] = ctx.User.Orgs | |||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "repo/migrate") | |||||
| ctx.HTML(200, MIGRATE) | |||||
| return | return | ||||
| } | } | ||||
| u := ctx.User | |||||
| // Not equal means current user is an organization. | |||||
| if u.Id != form.Uid { | |||||
| var err error | |||||
| u, err = models.GetUserById(form.Uid) | |||||
| if err != nil { | |||||
| if err == models.ErrUserNotExist { | |||||
| ctx.Handle(404, "home.MigratePost(GetUserById)", err) | |||||
| } else { | |||||
| ctx.Handle(500, "home.MigratePost(GetUserById)", err) | |||||
| } | |||||
| return | |||||
| } | |||||
| } | |||||
| authStr := strings.Replace(fmt.Sprintf("://%s:%s", | authStr := strings.Replace(fmt.Sprintf("://%s:%s", | ||||
| form.AuthUserName, form.AuthPasswd), "@", "%40", -1) | form.AuthUserName, form.AuthPasswd), "@", "%40", -1) | ||||
| url := strings.Replace(form.Url, "://", authStr+"@", 1) | url := strings.Replace(form.Url, "://", authStr+"@", 1) | ||||
| repo, err := models.MigrateRepository(ctx.User, form.RepoName, form.Description, form.Private, | |||||
| repo, err := models.MigrateRepository(u, form.RepoName, form.Description, form.Private, | |||||
| form.Mirror, url) | form.Mirror, url) | ||||
| if err == nil { | if err == nil { | ||||
| log.Trace("%s Repository migrated: %s/%s", ctx.Req.RequestURI, ctx.User.LowerName, form.RepoName) | |||||
| ctx.Redirect("/" + ctx.User.Name + "/" + form.RepoName) | |||||
| log.Trace("%s Repository migrated: %s/%s", ctx.Req.RequestURI, u.LowerName, form.RepoName) | |||||
| ctx.Redirect("/" + u.Name + "/" + form.RepoName) | |||||
| return | return | ||||
| } else if err == models.ErrRepoAlreadyExist { | } else if err == models.ErrRepoAlreadyExist { | ||||
| ctx.RenderWithErr("Repository name has already been used", "repo/migrate", &form) | |||||
| ctx.RenderWithErr("Repository name has already been used", MIGRATE, &form) | |||||
| return | return | ||||
| } else if err == models.ErrRepoNameIllegal { | } else if err == models.ErrRepoNameIllegal { | ||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "repo/migrate", &form) | |||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), MIGRATE, &form) | |||||
| return | return | ||||
| } | } | ||||
| if repo != nil { | if repo != nil { | ||||
| if errDelete := models.DeleteRepository(ctx.User.Id, repo.Id, ctx.User.Name); errDelete != nil { | |||||
| if errDelete := models.DeleteRepository(u.Id, repo.Id, u.Name); errDelete != nil { | |||||
| log.Error("repo.MigratePost(DeleteRepository): %v", errDelete) | log.Error("repo.MigratePost(DeleteRepository): %v", errDelete) | ||||
| } | } | ||||
| } | } | ||||
| if strings.Contains(err.Error(), "Authentication failed") { | if strings.Contains(err.Error(), "Authentication failed") { | ||||
| ctx.RenderWithErr(err.Error(), "repo/migrate", &form) | |||||
| ctx.RenderWithErr(err.Error(), MIGRATE, &form) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Handle(500, "repo.Migrate", err) | |||||
| ctx.Handle(500, "repo.Migrate(MigrateRepository)", err) | |||||
| } | } | ||||
| func Single(ctx *middleware.Context, params martini.Params) { | func Single(ctx *middleware.Context, params martini.Params) { | ||||
| @@ -291,7 +353,7 @@ func Single(ctx *middleware.Context, params martini.Params) { | |||||
| ctx.Data["Treenames"] = treenames | ctx.Data["Treenames"] = treenames | ||||
| ctx.Data["TreePath"] = treePath | ctx.Data["TreePath"] = treePath | ||||
| ctx.Data["BranchLink"] = branchLink | ctx.Data["BranchLink"] = branchLink | ||||
| ctx.HTML(200, "repo/single") | |||||
| ctx.HTML(200, SINGLE) | |||||
| } | } | ||||
| func basicEncode(username, password string) string { | func basicEncode(username, password string) string { | ||||
| @@ -318,7 +380,7 @@ func basicDecode(encoded string) (user string, name string, err error) { | |||||
| func authRequired(ctx *middleware.Context) { | func authRequired(ctx *middleware.Context) { | ||||
| ctx.ResponseWriter.Header().Set("WWW-Authenticate", "Basic realm=\".\"") | ctx.ResponseWriter.Header().Set("WWW-Authenticate", "Basic realm=\".\"") | ||||
| ctx.Data["ErrorMsg"] = "no basic auth and digit auth" | 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) { | func Action(ctx *middleware.Context, params martini.Params) { | ||||
| @@ -20,10 +20,19 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| const ( | |||||
| SETTING base.TplName = "repo/setting" | |||||
| COLLABORATION base.TplName = "repo/collaboration" | |||||
| HOOKS base.TplName = "repo/hooks" | |||||
| HOOK_ADD base.TplName = "repo/hook_add" | |||||
| HOOK_EDIT base.TplName = "repo/hook_edit" | |||||
| ) | |||||
| func Setting(ctx *middleware.Context) { | func Setting(ctx *middleware.Context) { | ||||
| ctx.Data["IsRepoToolbarSetting"] = true | ctx.Data["IsRepoToolbarSetting"] = true | ||||
| ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - settings" | ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - settings" | ||||
| ctx.HTML(200, "repo/setting") | |||||
| ctx.HTML(200, SETTING) | |||||
| } | } | ||||
| func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | ||||
| @@ -32,7 +41,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||
| switch ctx.Query("action") { | switch ctx.Query("action") { | ||||
| case "update": | case "update": | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "repo/setting") | |||||
| ctx.HTML(200, SETTING) | |||||
| return | return | ||||
| } | } | ||||
| @@ -44,7 +53,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||
| ctx.Handle(500, "setting.SettingPost(update: check existence)", err) | ctx.Handle(500, "setting.SettingPost(update: check existence)", err) | ||||
| return | return | ||||
| } else if isExist { | } else if isExist { | ||||
| ctx.RenderWithErr("Repository name has been taken in your repositories.", "repo/setting", nil) | |||||
| ctx.RenderWithErr("Repository name has been taken in your repositories.", SETTING, nil) | |||||
| return | return | ||||
| } else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil { | } else if err = models.ChangeRepositoryName(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name, newRepoName); err != nil { | ||||
| ctx.Handle(500, "setting.SettingPost(change repository name)", err) | ctx.Handle(500, "setting.SettingPost(change repository name)", err) | ||||
| @@ -84,7 +93,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||
| ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)) | ctx.Redirect(fmt.Sprintf("/%s/%s/settings", ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)) | ||||
| case "transfer": | case "transfer": | ||||
| if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { | if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { | ||||
| ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil) | |||||
| ctx.RenderWithErr("Please make sure you entered repository name is correct.", SETTING, nil) | |||||
| return | return | ||||
| } else if ctx.Repo.Repository.IsMirror { | } else if ctx.Repo.Repository.IsMirror { | ||||
| ctx.Error(404) | ctx.Error(404) | ||||
| @@ -98,7 +107,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||
| ctx.Handle(500, "setting.SettingPost(transfer: check existence)", err) | ctx.Handle(500, "setting.SettingPost(transfer: check existence)", err) | ||||
| return | return | ||||
| } else if !isExist { | } else if !isExist { | ||||
| ctx.RenderWithErr("Please make sure you entered owner name is correct.", "repo/setting", nil) | |||||
| ctx.RenderWithErr("Please make sure you entered owner name is correct.", SETTING, nil) | |||||
| return | return | ||||
| } else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil { | } else if err = models.TransferOwnership(ctx.User, newOwner, ctx.Repo.Repository); err != nil { | ||||
| ctx.Handle(500, "setting.SettingPost(transfer repository)", err) | ctx.Handle(500, "setting.SettingPost(transfer repository)", err) | ||||
| @@ -109,7 +118,7 @@ func SettingPost(ctx *middleware.Context, form auth.RepoSettingForm) { | |||||
| ctx.Redirect("/") | ctx.Redirect("/") | ||||
| case "delete": | case "delete": | ||||
| if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { | if len(ctx.Repo.Repository.Name) == 0 || ctx.Repo.Repository.Name != ctx.Query("repository") { | ||||
| ctx.RenderWithErr("Please make sure you entered repository name is correct.", "repo/setting", nil) | |||||
| ctx.RenderWithErr("Please make sure you entered repository name is correct.", SETTING, nil) | |||||
| return | return | ||||
| } | } | ||||
| @@ -156,7 +165,7 @@ func Collaboration(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["Collaborators"] = us | ctx.Data["Collaborators"] = us | ||||
| ctx.HTML(200, "repo/collaboration") | |||||
| ctx.HTML(200, COLLABORATION) | |||||
| } | } | ||||
| func CollaborationPost(ctx *middleware.Context) { | func CollaborationPost(ctx *middleware.Context) { | ||||
| @@ -166,7 +175,7 @@ func CollaborationPost(ctx *middleware.Context) { | |||||
| ctx.Redirect(ctx.Req.RequestURI) | ctx.Redirect(ctx.Req.RequestURI) | ||||
| return | return | ||||
| } | } | ||||
| has, err := models.HasAccess(name, repoLink, models.AU_WRITABLE) | |||||
| has, err := models.HasAccess(name, repoLink, models.WRITABLE) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "setting.CollaborationPost(HasAccess)", err) | ctx.Handle(500, "setting.CollaborationPost(HasAccess)", err) | ||||
| return | return | ||||
| @@ -187,7 +196,7 @@ func CollaborationPost(ctx *middleware.Context) { | |||||
| } | } | ||||
| if err = models.AddAccess(&models.Access{UserName: name, RepoName: repoLink, | 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) | ctx.Handle(500, "setting.CollaborationPost(AddAccess)", err) | ||||
| return | return | ||||
| } | } | ||||
| @@ -226,13 +235,13 @@ func WebHooks(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["Webhooks"] = ws | ctx.Data["Webhooks"] = ws | ||||
| ctx.HTML(200, "repo/hooks") | |||||
| ctx.HTML(200, HOOKS) | |||||
| } | } | ||||
| func WebHooksAdd(ctx *middleware.Context) { | func WebHooksAdd(ctx *middleware.Context) { | ||||
| ctx.Data["IsRepoToolbarWebHooks"] = true | ctx.Data["IsRepoToolbarWebHooks"] = true | ||||
| ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Webhook" | ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Webhook" | ||||
| ctx.HTML(200, "repo/hooks_add") | |||||
| ctx.HTML(200, HOOK_ADD) | |||||
| } | } | ||||
| func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { | func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { | ||||
| @@ -240,7 +249,7 @@ func WebHooksAddPost(ctx *middleware.Context, form auth.NewWebhookForm) { | |||||
| ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Webhook" | ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Add Webhook" | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "repo/hooks_add") | |||||
| ctx.HTML(200, HOOK_ADD) | |||||
| return | return | ||||
| } | } | ||||
| @@ -293,40 +302,46 @@ func WebHooksEdit(ctx *middleware.Context, params martini.Params) { | |||||
| w.GetEvent() | w.GetEvent() | ||||
| ctx.Data["Webhook"] = w | ctx.Data["Webhook"] = w | ||||
| ctx.HTML(200, "repo/hooks_edit") | |||||
| ctx.HTML(200, HOOK_EDIT) | |||||
| } | } | ||||
| func WebHooksEditPost(ctx *middleware.Context, params martini.Params, form auth.NewWebhookForm) { | func WebHooksEditPost(ctx *middleware.Context, params martini.Params, form auth.NewWebhookForm) { | ||||
| ctx.Data["IsRepoToolbarWebHooks"] = true | ctx.Data["IsRepoToolbarWebHooks"] = true | ||||
| ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Webhook" | ctx.Data["Title"] = strings.TrimPrefix(ctx.Repo.RepoLink, "/") + " - Webhook" | ||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, "repo/hooks_add") | |||||
| return | |||||
| } | |||||
| hookId, _ := base.StrTo(params["id"]).Int64() | hookId, _ := base.StrTo(params["id"]).Int64() | ||||
| if hookId == 0 { | if hookId == 0 { | ||||
| ctx.Handle(404, "setting.WebHooksEditPost", nil) | ctx.Handle(404, "setting.WebHooksEditPost", nil) | ||||
| return | return | ||||
| } | } | ||||
| w, err := models.GetWebhookById(hookId) | |||||
| if err != nil { | |||||
| if err == models.ErrWebhookNotExist { | |||||
| ctx.Handle(404, "setting.WebHooksEditPost(GetWebhookById)", nil) | |||||
| } else { | |||||
| ctx.Handle(500, "setting.WebHooksEditPost(GetWebhookById)", err) | |||||
| } | |||||
| return | |||||
| } | |||||
| if ctx.HasError() { | |||||
| ctx.HTML(200, HOOK_EDIT) | |||||
| return | |||||
| } | |||||
| ct := models.JSON | ct := models.JSON | ||||
| if form.ContentType == "2" { | if form.ContentType == "2" { | ||||
| ct = models.FORM | ct = models.FORM | ||||
| } | } | ||||
| w := &models.Webhook{ | |||||
| Id: hookId, | |||||
| RepoId: ctx.Repo.Repository.Id, | |||||
| Url: form.Url, | |||||
| ContentType: ct, | |||||
| Secret: form.Secret, | |||||
| HookEvent: &models.HookEvent{ | |||||
| PushOnly: form.PushOnly, | |||||
| }, | |||||
| IsActive: form.Active, | |||||
| w.Url = form.Url | |||||
| w.ContentType = ct | |||||
| w.Secret = form.Secret | |||||
| w.HookEvent = &models.HookEvent{ | |||||
| PushOnly: form.PushOnly, | |||||
| } | } | ||||
| w.IsActive = form.Active | |||||
| if err := w.UpdateEvent(); err != nil { | if err := w.UpdateEvent(); err != nil { | ||||
| ctx.Handle(500, "setting.WebHooksEditPost(UpdateEvent)", err) | ctx.Handle(500, "setting.WebHooksEditPost(UpdateEvent)", err) | ||||
| return | return | ||||
| @@ -17,10 +17,25 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| DASHBOARD base.TplName = "user/dashboard" | |||||
| PROFILE base.TplName = "user/profile" | |||||
| ISSUES base.TplName = "user/issues" | |||||
| PULLS base.TplName = "user/pulls" | |||||
| STARS base.TplName = "user/stars" | |||||
| ) | |||||
| func Dashboard(ctx *middleware.Context) { | func Dashboard(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Dashboard" | ctx.Data["Title"] = "Dashboard" | ||||
| ctx.Data["PageIsUserDashboard"] = true | 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 | var err error | ||||
| ctx.Data["MyRepos"], err = models.GetRepositories(ctx.User.Id, true) | ctx.Data["MyRepos"], err = models.GetRepositories(ctx.User.Id, true) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -45,21 +60,21 @@ func Dashboard(ctx *middleware.Context) { | |||||
| for _, act := range actions { | for _, act := range actions { | ||||
| if act.IsPrivate { | if act.IsPrivate { | ||||
| if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, | if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, | ||||
| models.AU_READABLE); !has { | |||||
| models.READABLE); !has { | |||||
| continue | continue | ||||
| } | } | ||||
| } | } | ||||
| feeds = append(feeds, act) | feeds = append(feeds, act) | ||||
| } | } | ||||
| ctx.Data["Feeds"] = feeds | ctx.Data["Feeds"] = feeds | ||||
| ctx.HTML(200, "user/dashboard") | |||||
| ctx.HTML(200, DASHBOARD) | |||||
| } | } | ||||
| func Profile(ctx *middleware.Context, params martini.Params) { | func Profile(ctx *middleware.Context, params martini.Params) { | ||||
| ctx.Data["Title"] = "Profile" | ctx.Data["Title"] = "Profile" | ||||
| ctx.Data["PageIsUserProfile"] = true | ctx.Data["PageIsUserProfile"] = true | ||||
| user, err := models.GetUserByName(params["username"]) | |||||
| u, err := models.GetUserByName(params["username"]) | |||||
| if err != nil { | if err != nil { | ||||
| if err == models.ErrUserNotExist { | if err == models.ErrUserNotExist { | ||||
| ctx.Handle(404, "user.Profile(GetUserByName)", err) | ctx.Handle(404, "user.Profile(GetUserByName)", err) | ||||
| @@ -68,26 +83,30 @@ func Profile(ctx *middleware.Context, params martini.Params) { | |||||
| } | } | ||||
| return | return | ||||
| } | } | ||||
| ctx.Data["Owner"] = user | |||||
| // For security reason, hide e-mail address for anonymous visitors. | |||||
| if !ctx.IsSigned { | |||||
| u.Email = "" | |||||
| } | |||||
| ctx.Data["Owner"] = u | |||||
| tab := ctx.Query("tab") | tab := ctx.Query("tab") | ||||
| ctx.Data["TabName"] = tab | ctx.Data["TabName"] = tab | ||||
| switch tab { | switch tab { | ||||
| case "activity": | case "activity": | ||||
| ctx.Data["Feeds"], err = models.GetFeeds(user.Id, 0, true) | |||||
| ctx.Data["Feeds"], err = models.GetFeeds(u.Id, 0, true) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "user.Profile(GetFeeds)", err) | ctx.Handle(500, "user.Profile(GetFeeds)", err) | ||||
| return | return | ||||
| } | } | ||||
| default: | default: | ||||
| ctx.Data["Repos"], err = models.GetRepositories(user.Id, ctx.IsSigned && ctx.User.Id == user.Id) | |||||
| ctx.Data["Repos"], err = models.GetRepositories(u.Id, ctx.IsSigned && ctx.User.Id == u.Id) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.Handle(500, "user.Profile(GetRepositories)", err) | ctx.Handle(500, "user.Profile(GetRepositories)", err) | ||||
| return | return | ||||
| } | } | ||||
| } | } | ||||
| ctx.HTML(200, "user/profile") | |||||
| ctx.HTML(200, PROFILE) | |||||
| } | } | ||||
| func Email2User(ctx *middleware.Context) { | func Email2User(ctx *middleware.Context) { | ||||
| @@ -119,7 +138,7 @@ func Feeds(ctx *middleware.Context, form auth.FeedsForm) { | |||||
| for _, act := range actions { | for _, act := range actions { | ||||
| if act.IsPrivate { | if act.IsPrivate { | ||||
| if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, | if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName, | ||||
| models.AU_READABLE); !has { | |||||
| models.READABLE); !has { | |||||
| continue | continue | ||||
| } | } | ||||
| } | } | ||||
| @@ -254,13 +273,13 @@ func Issues(ctx *middleware.Context) { | |||||
| } else { | } else { | ||||
| ctx.Data["ShowCount"] = issueStats.OpenCount | ctx.Data["ShowCount"] = issueStats.OpenCount | ||||
| } | } | ||||
| ctx.HTML(200, "user/issue") | |||||
| ctx.HTML(200, ISSUES) | |||||
| } | } | ||||
| func Pulls(ctx *middleware.Context) { | func Pulls(ctx *middleware.Context) { | ||||
| ctx.HTML(200, "user/pulls") | |||||
| ctx.HTML(200, PULLS) | |||||
| } | } | ||||
| func Stars(ctx *middleware.Context) { | func Stars(ctx *middleware.Context) { | ||||
| ctx.HTML(200, "user/stars") | |||||
| ctx.HTML(200, STARS) | |||||
| } | } | ||||
| @@ -14,12 +14,21 @@ import ( | |||||
| "github.com/gogits/gogs/modules/middleware" | "github.com/gogits/gogs/modules/middleware" | ||||
| ) | ) | ||||
| const ( | |||||
| SETTING base.TplName = "user/setting" | |||||
| SOCIAL base.TplName = "user/social" | |||||
| PASSWORD base.TplName = "user/password" | |||||
| PUBLICKEY base.TplName = "user/publickey" | |||||
| NOTIFICATION base.TplName = "user/notification" | |||||
| SECURITY base.TplName = "user/security" | |||||
| ) | |||||
| func Setting(ctx *middleware.Context) { | func Setting(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Setting" | ctx.Data["Title"] = "Setting" | ||||
| ctx.Data["PageIsUserSetting"] = true | ctx.Data["PageIsUserSetting"] = true | ||||
| ctx.Data["IsUserPageSetting"] = true | ctx.Data["IsUserPageSetting"] = true | ||||
| ctx.Data["Owner"] = ctx.User | ctx.Data["Owner"] = ctx.User | ||||
| ctx.HTML(200, "user/setting") | |||||
| ctx.HTML(200, SETTING) | |||||
| } | } | ||||
| func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | ||||
| @@ -28,7 +37,7 @@ func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | |||||
| ctx.Data["IsUserPageSetting"] = true | ctx.Data["IsUserPageSetting"] = true | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "user/setting") | |||||
| ctx.HTML(200, SETTING) | |||||
| return | return | ||||
| } | } | ||||
| @@ -59,7 +68,7 @@ func SettingPost(ctx *middleware.Context, form auth.UpdateProfileForm) { | |||||
| ctx.User.Avatar = base.EncodeMd5(form.Avatar) | ctx.User.Avatar = base.EncodeMd5(form.Avatar) | ||||
| ctx.User.AvatarEmail = form.Avatar | ctx.User.AvatarEmail = form.Avatar | ||||
| if err := models.UpdateUser(ctx.User); err != nil { | if err := models.UpdateUser(ctx.User); err != nil { | ||||
| ctx.Handle(500, "setting.Setting", err) | |||||
| ctx.Handle(500, "setting.Setting(UpdateUser)", err) | |||||
| return | return | ||||
| } | } | ||||
| log.Trace("%s User setting updated: %s", ctx.Req.RequestURI, ctx.User.LowerName) | log.Trace("%s User setting updated: %s", ctx.Req.RequestURI, ctx.User.LowerName) | ||||
| @@ -90,14 +99,14 @@ func SettingSocial(ctx *middleware.Context) { | |||||
| ctx.Handle(500, "user.SettingSocial(GetOauthByUserId)", err) | ctx.Handle(500, "user.SettingSocial(GetOauthByUserId)", err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(200, "user/social") | |||||
| ctx.HTML(200, SOCIAL) | |||||
| } | } | ||||
| func SettingPassword(ctx *middleware.Context) { | func SettingPassword(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Password" | ctx.Data["Title"] = "Password" | ||||
| ctx.Data["PageIsUserSetting"] = true | ctx.Data["PageIsUserSetting"] = true | ||||
| ctx.Data["IsUserPageSettingPasswd"] = true | ctx.Data["IsUserPageSettingPasswd"] = true | ||||
| ctx.HTML(200, "user/password") | |||||
| ctx.HTML(200, PASSWORD) | |||||
| } | } | ||||
| func SettingPasswordPost(ctx *middleware.Context, form auth.UpdatePasswdForm) { | func SettingPasswordPost(ctx *middleware.Context, form auth.UpdatePasswdForm) { | ||||
| @@ -106,7 +115,7 @@ func SettingPasswordPost(ctx *middleware.Context, form auth.UpdatePasswdForm) { | |||||
| ctx.Data["IsUserPageSettingPasswd"] = true | ctx.Data["IsUserPageSettingPasswd"] = true | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "user/password") | |||||
| ctx.HTML(200, PASSWORD) | |||||
| return | return | ||||
| } | } | ||||
| @@ -207,7 +216,7 @@ func SettingSSHKeys(ctx *middleware.Context, form auth.AddSSHKeyForm) { | |||||
| } | } | ||||
| } | } | ||||
| ctx.HTML(200, "user/publickey") | |||||
| ctx.HTML(200, PUBLICKEY) | |||||
| } | } | ||||
| func SettingNotification(ctx *middleware.Context) { | func SettingNotification(ctx *middleware.Context) { | ||||
| @@ -215,7 +224,7 @@ func SettingNotification(ctx *middleware.Context) { | |||||
| ctx.Data["Title"] = "Notification" | ctx.Data["Title"] = "Notification" | ||||
| ctx.Data["PageIsUserSetting"] = true | ctx.Data["PageIsUserSetting"] = true | ||||
| ctx.Data["IsUserPageSettingNotify"] = true | ctx.Data["IsUserPageSettingNotify"] = true | ||||
| ctx.HTML(200, "user/notification") | |||||
| ctx.HTML(200, NOTIFICATION) | |||||
| } | } | ||||
| func SettingSecurity(ctx *middleware.Context) { | func SettingSecurity(ctx *middleware.Context) { | ||||
| @@ -223,5 +232,5 @@ func SettingSecurity(ctx *middleware.Context) { | |||||
| ctx.Data["Title"] = "Security" | ctx.Data["Title"] = "Security" | ||||
| ctx.Data["PageIsUserSetting"] = true | ctx.Data["PageIsUserSetting"] = true | ||||
| ctx.Data["IsUserPageSettingSecurity"] = true | ctx.Data["IsUserPageSettingSecurity"] = true | ||||
| ctx.HTML(200, "user/security") | |||||
| ctx.HTML(200, SECURITY) | |||||
| } | } | ||||
| @@ -17,12 +17,21 @@ import ( | |||||
| "github.com/gogits/gogs/modules/setting" | "github.com/gogits/gogs/modules/setting" | ||||
| ) | ) | ||||
| const ( | |||||
| SIGNIN base.TplName = "user/signin" | |||||
| SIGNUP base.TplName = "user/signup" | |||||
| DELETE base.TplName = "user/delete" | |||||
| ACTIVATE base.TplName = "user/activate" | |||||
| FORGOT_PASSWORD base.TplName = "user/forgot_passwd" | |||||
| RESET_PASSWORD base.TplName = "user/reset_passwd" | |||||
| ) | |||||
| func SignIn(ctx *middleware.Context) { | func SignIn(ctx *middleware.Context) { | ||||
| ctx.Data["Title"] = "Log In" | ctx.Data["Title"] = "Log In" | ||||
| if _, ok := ctx.Session.Get("socialId").(int64); ok { | if _, ok := ctx.Session.Get("socialId").(int64); ok { | ||||
| ctx.Data["IsSocialLogin"] = true | ctx.Data["IsSocialLogin"] = true | ||||
| ctx.HTML(200, "user/signin") | |||||
| ctx.HTML(200, SIGNIN) | |||||
| return | return | ||||
| } | } | ||||
| @@ -34,7 +43,7 @@ func SignIn(ctx *middleware.Context) { | |||||
| // Check auto-login. | // Check auto-login. | ||||
| uname := ctx.GetCookie(setting.CookieUserName) | uname := ctx.GetCookie(setting.CookieUserName) | ||||
| if len(uname) == 0 { | if len(uname) == 0 { | ||||
| ctx.HTML(200, "user/signin") | |||||
| ctx.HTML(200, SIGNIN) | |||||
| return | return | ||||
| } | } | ||||
| @@ -57,7 +66,7 @@ func SignIn(ctx *middleware.Context) { | |||||
| secret := base.EncodeMd5(user.Rands + user.Passwd) | secret := base.EncodeMd5(user.Rands + user.Passwd) | ||||
| value, _ := ctx.GetSecureCookie(secret, setting.CookieRememberName) | value, _ := ctx.GetSecureCookie(secret, setting.CookieRememberName) | ||||
| if value != user.Name { | if value != user.Name { | ||||
| ctx.HTML(200, "user/signin") | |||||
| ctx.HTML(200, SIGNIN) | |||||
| return | return | ||||
| } | } | ||||
| @@ -86,7 +95,7 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) { | |||||
| } | } | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "user/signin") | |||||
| ctx.HTML(200, SIGNIN) | |||||
| return | return | ||||
| } | } | ||||
| @@ -94,7 +103,7 @@ func SignInPost(ctx *middleware.Context, form auth.LogInForm) { | |||||
| if err != nil { | if err != nil { | ||||
| if err == models.ErrUserNotExist { | if err == models.ErrUserNotExist { | ||||
| log.Trace("%s Log in failed: %s", ctx.Req.RequestURI, form.UserName) | log.Trace("%s Log in failed: %s", ctx.Req.RequestURI, form.UserName) | ||||
| ctx.RenderWithErr("Username or password is not correct", "user/signin", &form) | |||||
| ctx.RenderWithErr("Username or password is not correct", SIGNIN, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -151,7 +160,7 @@ func SignUp(ctx *middleware.Context) { | |||||
| if setting.Service.DisableRegistration { | if setting.Service.DisableRegistration { | ||||
| ctx.Data["DisableRegistration"] = true | ctx.Data["DisableRegistration"] = true | ||||
| ctx.HTML(200, "user/signup") | |||||
| ctx.HTML(200, SIGNUP) | |||||
| return | return | ||||
| } | } | ||||
| @@ -160,7 +169,7 @@ func SignUp(ctx *middleware.Context) { | |||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(200, "user/signup") | |||||
| ctx.HTML(200, SIGNUP) | |||||
| } | } | ||||
| func oauthSignUp(ctx *middleware.Context, sid int64) { | func oauthSignUp(ctx *middleware.Context, sid int64) { | ||||
| @@ -180,7 +189,7 @@ func oauthSignUp(ctx *middleware.Context, sid int64) { | |||||
| ctx.Data["username"] = strings.Replace(ctx.Session.Get("socialName").(string), " ", "", -1) | ctx.Data["username"] = strings.Replace(ctx.Session.Get("socialName").(string), " ", "", -1) | ||||
| ctx.Data["email"] = ctx.Session.Get("socialEmail") | ctx.Data["email"] = ctx.Session.Get("socialEmail") | ||||
| log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId")) | log.Trace("user.oauthSignUp(social ID): %v", ctx.Session.Get("socialId")) | ||||
| ctx.HTML(200, "user/signup") | |||||
| ctx.HTML(200, SIGNUP) | |||||
| } | } | ||||
| func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { | func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { | ||||
| @@ -198,14 +207,14 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { | |||||
| } | } | ||||
| if ctx.HasError() { | if ctx.HasError() { | ||||
| ctx.HTML(200, "user/signup") | |||||
| ctx.HTML(200, SIGNUP) | |||||
| return | return | ||||
| } | } | ||||
| if form.Password != form.RetypePasswd { | if form.Password != form.RetypePasswd { | ||||
| ctx.Data["Err_Password"] = true | ctx.Data["Err_Password"] = true | ||||
| ctx.Data["Err_RetypePasswd"] = true | ctx.Data["Err_RetypePasswd"] = true | ||||
| ctx.RenderWithErr("Password and re-type password are not same.", "user/signup", &form) | |||||
| ctx.RenderWithErr("Password and re-type password are not same.", SIGNUP, &form) | |||||
| return | return | ||||
| } | } | ||||
| @@ -217,22 +226,23 @@ func SignUpPost(ctx *middleware.Context, form auth.RegisterForm) { | |||||
| } | } | ||||
| var err error | var err error | ||||
| if u, err = models.RegisterUser(u); err != nil { | |||||
| if u, err = models.CreateUser(u); err != nil { | |||||
| switch err { | switch err { | ||||
| case models.ErrUserAlreadyExist: | case models.ErrUserAlreadyExist: | ||||
| ctx.Data["Err_UserName"] = true | ctx.Data["Err_UserName"] = true | ||||
| ctx.RenderWithErr("Username has been already taken", "user/signup", &form) | |||||
| ctx.RenderWithErr("Username has been already taken", SIGNUP, &form) | |||||
| case models.ErrEmailAlreadyUsed: | case models.ErrEmailAlreadyUsed: | ||||
| ctx.Data["Err_Email"] = true | ctx.Data["Err_Email"] = true | ||||
| ctx.RenderWithErr("E-mail address has been already used", "user/signup", &form) | |||||
| ctx.RenderWithErr("E-mail address has been already used", SIGNUP, &form) | |||||
| case models.ErrUserNameIllegal: | case models.ErrUserNameIllegal: | ||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "user/signup", &form) | |||||
| ctx.Data["Err_UserName"] = true | |||||
| ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), SIGNUP, &form) | |||||
| default: | default: | ||||
| ctx.Handle(500, "user.SignUpPost(RegisterUser)", err) | |||||
| ctx.Handle(500, "user.SignUpPost(CreateUser)", err) | |||||
| } | } | ||||
| return | 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. | // Bind social account. | ||||
| if isOauth { | if isOauth { | ||||
| @@ -265,7 +275,7 @@ func Delete(ctx *middleware.Context) { | |||||
| ctx.Data["Title"] = "Delete Account" | ctx.Data["Title"] = "Delete Account" | ||||
| ctx.Data["PageIsUserSetting"] = true | ctx.Data["PageIsUserSetting"] = true | ||||
| ctx.Data["IsUserPageSettingDelete"] = true | ctx.Data["IsUserPageSettingDelete"] = true | ||||
| ctx.HTML(200, "user/delete") | |||||
| ctx.HTML(200, DELETE) | |||||
| } | } | ||||
| func DeletePost(ctx *middleware.Context) { | func DeletePost(ctx *middleware.Context) { | ||||
| @@ -286,7 +296,7 @@ func DeletePost(ctx *middleware.Context) { | |||||
| case models.ErrUserOwnRepos: | case models.ErrUserOwnRepos: | ||||
| ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.") | ctx.Flash.Error("Your account still have ownership of repository, you have to delete or transfer them first.") | ||||
| default: | default: | ||||
| ctx.Handle(500, "user.Delete", err) | |||||
| ctx.Handle(500, "user.Delete(DeleteUser)", err) | |||||
| return | return | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -321,7 +331,7 @@ func Activate(ctx *middleware.Context) { | |||||
| } else { | } else { | ||||
| ctx.Data["ServiceNotEnabled"] = true | ctx.Data["ServiceNotEnabled"] = true | ||||
| } | } | ||||
| ctx.HTML(200, "user/activate") | |||||
| ctx.HTML(200, ACTIVATE) | |||||
| return | return | ||||
| } | } | ||||
| @@ -343,7 +353,7 @@ func Activate(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["IsActivateFailed"] = true | ctx.Data["IsActivateFailed"] = true | ||||
| ctx.HTML(200, "user/activate") | |||||
| ctx.HTML(200, ACTIVATE) | |||||
| } | } | ||||
| func ForgotPasswd(ctx *middleware.Context) { | func ForgotPasswd(ctx *middleware.Context) { | ||||
| @@ -351,12 +361,12 @@ func ForgotPasswd(ctx *middleware.Context) { | |||||
| if setting.MailService == nil { | if setting.MailService == nil { | ||||
| ctx.Data["IsResetDisable"] = true | ctx.Data["IsResetDisable"] = true | ||||
| ctx.HTML(200, "user/forgot_passwd") | |||||
| ctx.HTML(200, FORGOT_PASSWORD) | |||||
| return | return | ||||
| } | } | ||||
| ctx.Data["IsResetRequest"] = true | ctx.Data["IsResetRequest"] = true | ||||
| ctx.HTML(200, "user/forgot_passwd") | |||||
| ctx.HTML(200, FORGOT_PASSWORD) | |||||
| } | } | ||||
| func ForgotPasswdPost(ctx *middleware.Context) { | func ForgotPasswdPost(ctx *middleware.Context) { | ||||
| @@ -381,7 +391,7 @@ func ForgotPasswdPost(ctx *middleware.Context) { | |||||
| if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) { | if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) { | ||||
| ctx.Data["ResendLimited"] = true | ctx.Data["ResendLimited"] = true | ||||
| ctx.HTML(200, "user/forgot_passwd") | |||||
| ctx.HTML(200, FORGOT_PASSWORD) | |||||
| return | return | ||||
| } | } | ||||
| @@ -393,7 +403,7 @@ func ForgotPasswdPost(ctx *middleware.Context) { | |||||
| ctx.Data["Email"] = email | ctx.Data["Email"] = email | ||||
| ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60 | ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60 | ||||
| ctx.Data["IsResetSent"] = true | ctx.Data["IsResetSent"] = true | ||||
| ctx.HTML(200, "user/forgot_passwd") | |||||
| ctx.HTML(200, FORGOT_PASSWORD) | |||||
| } | } | ||||
| func ResetPasswd(ctx *middleware.Context) { | func ResetPasswd(ctx *middleware.Context) { | ||||
| @@ -406,7 +416,7 @@ func ResetPasswd(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["Code"] = code | ctx.Data["Code"] = code | ||||
| ctx.Data["IsResetForm"] = true | ctx.Data["IsResetForm"] = true | ||||
| ctx.HTML(200, "user/reset_passwd") | |||||
| ctx.HTML(200, RESET_PASSWORD) | |||||
| } | } | ||||
| func ResetPasswdPost(ctx *middleware.Context) { | func ResetPasswdPost(ctx *middleware.Context) { | ||||
| @@ -443,5 +453,5 @@ func ResetPasswdPost(ctx *middleware.Context) { | |||||
| } | } | ||||
| ctx.Data["IsResetFailed"] = true | ctx.Data["IsResetFailed"] = true | ||||
| ctx.HTML(200, "user/reset_passwd") | |||||
| ctx.HTML(200, RESET_PASSWORD) | |||||
| } | } | ||||
| @@ -1 +1 @@ | |||||
| 0.4.5.0621 Alpha | |||||
| 0.4.5.0627 Alpha | |||||
| @@ -36,8 +36,8 @@ | |||||
| <dd>{{.LogRootPath}}</dd> | <dd>{{.LogRootPath}}</dd> | ||||
| <dt>Script Type</dt> | <dt>Script Type</dt> | ||||
| <dd>{{.ScriptType}}</dd> | <dd>{{.ScriptType}}</dd> | ||||
| <dt>Reverse Authentication UID</dt> | |||||
| <dd>{{.ReverseProxyAuthUid}}</dd> | |||||
| <dt>Reverse Authentication User</dt> | |||||
| <dd>{{.ReverseProxyAuthUser}}</dd> | |||||
| </dl> | </dl> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -0,0 +1,75 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div id="body-nav" class="org-nav org-nav-auto"> | |||||
| <div class="container clearfix"> | |||||
| <div id="org-nav-wrapper"> | |||||
| <ul class="nav nav-pills pull-right"> | |||||
| <li><a href="#"><i class="fa fa-users"></i>Members | |||||
| <span class="label label-default">5</span></a> | |||||
| </li> | |||||
| <li class="active"><a href="#"><i class="fa fa-tags"></i>Teams | |||||
| <span class="label label-default">2</span></a> | |||||
| </li> | |||||
| </ul> | |||||
| <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> | |||||
| <div id="org-nav-info"> | |||||
| <h2 class="org-name">Organization Name</h2> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div id="body" class="container"> | |||||
| <div id="org"> | |||||
| <form id="org-teams-edit" class="form-horizontal card"> | |||||
| <h3>Edit team</h3> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Team Name<strong class="text-danger">*</strong></label> | |||||
| <div class="col-md-8"> | |||||
| <input name="team" type="text" class="form-control" placeholder="Type your team name" value="" required="required"> | |||||
| <span class="help-block">You'll use this name to mention this team in conversations.</span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Description</label> | |||||
| <div class="col-md-8"> | |||||
| <input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value=""> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Permission</label> | |||||
| <div class="col-md-8"> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="pull" checked=""> | |||||
| <strong>Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to view and clone its repositories.</p> | |||||
| </div> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="push"> | |||||
| <strong>Push, Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to read its repositories, as well as push to them.</p> | |||||
| </div> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="admin"> | |||||
| <strong>Collaboration, Push, Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to push/pull to its repositories, as well as add other collaborators to them.</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <hr/> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2"> </label> | |||||
| <div class="col-md-8"> | |||||
| <button class="btn btn-primary">Edit this team</button> | |||||
| <button class="btn btn-danger pull-right" value="delete" name="delete">Delete this team</button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,56 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div id="body-nav" class="org-nav org-nav-auto"> | |||||
| <div class="container clearfix"> | |||||
| <div id="org-nav-wrapper"> | |||||
| <ul class="nav nav-pills pull-right"> | |||||
| <li class="active"><a href="#"><i class="fa fa-users"></i>Members | |||||
| <span class="label label-default">5</span></a> | |||||
| </li> | |||||
| <li><a href="#"><i class="fa fa-tags"></i>Teams | |||||
| <span class="label label-default">2</span></a> | |||||
| </li> | |||||
| </ul> | |||||
| <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> | |||||
| <div id="org-nav-info"> | |||||
| <h2 class="org-name">Organization Name</h2> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div id="body" class="container"> | |||||
| <div id="org"> | |||||
| <div id="org-members"> | |||||
| <div class="member"> | |||||
| <div class="avatar col-md-1"> | |||||
| <img src="https://avatars3.githubusercontent.com/u/2142787?s=140" alt=""/> | |||||
| </div> | |||||
| <div class="name col-md-4"> | |||||
| <a href="#"><strong>fuxiaohei</strong><span class="nick">傅小黑</span></a> | |||||
| </div> | |||||
| <div class="role col-md-2 pull-right"> | |||||
| <strong>Member</strong> | |||||
| </div> | |||||
| <div class="status col-md-1 pull-right"> | |||||
| <strong>Public</strong> | |||||
| </div> | |||||
| </div> | |||||
| <div class="member"> | |||||
| <div class="avatar col-md-1"> | |||||
| <img src="https://avatars3.githubusercontent.com/u/2142787?s=140" alt=""/> | |||||
| </div> | |||||
| <div class="name col-md-4"> | |||||
| <a href="#"><strong>fuxiaohei</strong><span class="nick">傅小黑</span></a> | |||||
| </div> | |||||
| <div class="role col-md-2 pull-right"> | |||||
| <strong><i class="fa fa-user"></i>Owner</strong> | |||||
| </div> | |||||
| <div class="status col-md-1 pull-right"> | |||||
| <i class="fa fa-lock"></i>Private | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,32 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div class="container" id="body"> | |||||
| <form action="/org/create" method="post" class="form-horizontal card" id="org-create"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <h3>Create New Organization</h3> | |||||
| {{template "base/alert" .}} | |||||
| <div class="form-group {{if .Err_OrgName}}has-error has-feedback{{end}}"> | |||||
| <label class="col-md-2 control-label">Organization<strong class="text-danger">*</strong></label> | |||||
| <div class="col-md-8"> | |||||
| <input name="orgname" type="text" class="form-control" placeholder="Type your organization name" value="{{.orgname}}" required="required"> | |||||
| <span class="help-block">Great organization names are short and memorable. </span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}"> | |||||
| <label class="col-md-2 control-label">Email<strong class="text-danger">*</strong></label> | |||||
| <div class="col-md-8"> | |||||
| <input name="email" type="text" class="form-control" placeholder="Type organization's email" value="{{.email}}" required="required"> | |||||
| <span class="help-block">Organization's Email receives all notifications and confirmations.</span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <div class="col-md-offset-2 col-md-8"> | |||||
| <button type="submit" class="btn btn-lg btn-primary">Create An Organization</button> | |||||
| <a href="/" class="text-danger">Cancel</a> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,74 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div id="body-nav" class="org-nav org-nav-auto"> | |||||
| <div class="container clearfix"> | |||||
| <div id="org-nav-wrapper"> | |||||
| <ul class="nav nav-pills pull-right"> | |||||
| <li><a href="#"><i class="fa fa-users"></i>Members | |||||
| <span class="label label-default">5</span></a> | |||||
| </li> | |||||
| <li class="active"><a href="#"><i class="fa fa-tags"></i>Teams | |||||
| <span class="label label-default">2</span></a> | |||||
| </li> | |||||
| </ul> | |||||
| <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> | |||||
| <div id="org-nav-info"> | |||||
| <h2 class="org-name">Organization Name</h2> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div id="body" class="container"> | |||||
| <div id="org"> | |||||
| <form id="org-teams-create" class="form-horizontal card"> | |||||
| <h3>Create new team</h3> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Team Name<strong class="text-danger">*</strong></label> | |||||
| <div class="col-md-8"> | |||||
| <input name="team" type="text" class="form-control" placeholder="Type your team name" value="" required="required"> | |||||
| <span class="help-block">You'll use this name to mention this team in conversations.</span> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Description</label> | |||||
| <div class="col-md-8"> | |||||
| <input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value=""> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2 control-label">Permission</label> | |||||
| <div class="col-md-8"> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="pull" checked=""> | |||||
| <strong>Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to view and clone its repositories.</p> | |||||
| </div> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="push"> | |||||
| <strong>Push, Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to read its repositories, as well as push to them.</p> | |||||
| </div> | |||||
| <div class="radio"> | |||||
| <label> | |||||
| <input type="radio" name="permission" value="admin"> | |||||
| <strong>Collaboration, Push, Read & Clone</strong> | |||||
| </label> | |||||
| <p>This team will be able to push/pull to its repositories, as well as add other collaborators to them.</p> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <hr/> | |||||
| <div class="form-group"> | |||||
| <label class="col-md-2"> </label> | |||||
| <div class="col-md-8"> | |||||
| <button class="btn btn-primary">Create team</button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,130 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div id="body-nav"> | |||||
| <div class="container"> | |||||
| <div class="btn-group pull-left" id="dashboard-switch"> | |||||
| <button type="button" class="btn btn-default"> | |||||
| <img src="{{.Org.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.Org.Name}} | |||||
| </button> | |||||
| </div> | |||||
| <ul class="nav nav-pills pull-right"> | |||||
| <li><a href="/org/{{.Org.Name}}/dashboard/">News Feed</a></li> | |||||
| <li><a href="/org/{{.Org.Name}}/dashboard/issues">Issues</a></li> | |||||
| <li class="active"><a href="/org/{{.Org.Name}}/settings">Settings</a></li> | |||||
| <!-- <li><a href="/pulls">Pull Requests</a></li> | |||||
| <li><a href="/stars">Stars</a></li> --> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| <div id="body" class="container" data-page="org"> | |||||
| <div id="user-setting-nav" class="col-md-2 repo-setting-nav"> | |||||
| <ul class="list-group"> | |||||
| <li class="list-group-item active"><a href="#">Options</a></li> | |||||
| </ul> | |||||
| </div> | |||||
| <div id="repo-setting-container" class="col-md-10"> | |||||
| {{template "base/alert" .}} | |||||
| <div class="panel panel-default"> | |||||
| <div class="panel-heading"> | |||||
| Organization Options | |||||
| </div> | |||||
| <div class="panel-body"> | |||||
| <form action="/org/{{.Org.Name}}/settings" method="post" class="form-horizontal"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <input type="hidden" name="action" value="update"> | |||||
| <div class="form-group{{if .Err_DisplayName}} has-error has-feedback{{end}}"> | |||||
| <label class="col-md-3 text-right" for="org-setting-name">Display Name</label> | |||||
| <div class="col-md-9"> | |||||
| <input class="form-control" name="display_name" value="{{.Org.FullName}}" title="" id="org-setting-name"/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group{{if .Err_Email}} has-error has-feedback{{end}}"> | |||||
| <label class="col-md-3 text-right" for="org-email">Email</label> | |||||
| <div class="col-md-9"> | |||||
| <input class="form-control" name="email" value="{{.Org.Email}}" title="" id="org-email" type="email"/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group{{if .Err_Description}} has-error has-feedback{{end}}"> | |||||
| <label class="col-md-3 text-right" for="org-desc">Description</label> | |||||
| <div class="col-md-9"> | |||||
| <textarea class="form-control" name="desc" id="org-desc" rows="3">{{.Org.Description}}</textarea> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group{{if .Err_Website}} has-error has-feedback{{end}}"> | |||||
| <label class="col-md-3 text-right" for="org-site">Official Site</label> | |||||
| <div class="col-md-9"> | |||||
| <input type="url" class="form-control" name="site" value="{{.Org.Website}}" id="org-site"/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group{{if .Err_Location}} has-error has-feedback{{end}}"> | |||||
| <label class="col-md-3 text-right" for="org-location">Location</label> | |||||
| <div class="col-md-9"> | |||||
| <input class="form-control" name="location" value="{{.Org.Location}}" title="" id="org-location"/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="form-group"> | |||||
| <div class="col-md-9 col-md-offset-3"> | |||||
| <button class="btn btn-primary" type="submit">Save Options</button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| <div class="panel panel-warning"> | |||||
| <div class="panel-heading"> | |||||
| Danger Zone | |||||
| </div> | |||||
| <div class="panel-body"> | |||||
| <button type="button" class="btn btn-default pull-right" href="#delete-org-modal" data-toggle="modal"> | |||||
| Delete this organization | |||||
| </button> | |||||
| <dd> | |||||
| <dt>Delete this organization</dt> | |||||
| <dl>Once you delete this organization and all repositories in, there is no going back. Please be | |||||
| certain. | |||||
| </dl> | |||||
| </dd> | |||||
| <div class="modal fade" id="delete-org-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" | |||||
| aria-hidden="true"> | |||||
| <div class="modal-dialog"> | |||||
| <form action="/org/{{.Org.Name}}/settings/delete" method="post" | |||||
| class="modal-content"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <div class="modal-header"> | |||||
| <button type="button" class="close" data-dismiss="modal" | |||||
| aria-hidden="true">×</button> | |||||
| <h4 class="modal-title" id="myModalLabel">Delete organization</h4> | |||||
| </div> | |||||
| <div class="modal-body"> | |||||
| <div class="form-group"> | |||||
| <label>Make sure your are owner of this organization. Please enter your password.<strong class="text-danger">*</strong></label> | |||||
| <input name="password" class="form-control" type="password" placeholder="Type your account password" required="required"> | |||||
| </div> | |||||
| </div> | |||||
| <div class="modal-footer"> | |||||
| <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> | |||||
| <button class="btn btn-danger btn-lg">I understand the consequences, delete this | |||||
| organization | |||||
| </button> | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -0,0 +1,71 @@ | |||||
| {{template "base/head" .}} | |||||
| {{template "base/navbar" .}} | |||||
| <div id="body-nav" class="org-nav org-nav-auto"> | |||||
| <div class="container clearfix"> | |||||
| <div id="org-nav-wrapper"> | |||||
| <ul class="nav nav-pills pull-right"> | |||||
| <li><a href="#"><i class="fa fa-users"></i>Members | |||||
| <span class="label label-default">5</span></a> | |||||
| </li> | |||||
| <li class="active"><a href="#"><i class="fa fa-tags"></i>Teams | |||||
| <span class="label label-default">2</span></a> | |||||
| </li> | |||||
| </ul> | |||||
| <img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/> | |||||
| <div id="org-nav-info"> | |||||
| <h2 class="org-name">Organization Name</h2> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div id="body" class="container"> | |||||
| <div id="org"> | |||||
| <div id="org-teams"> | |||||
| <div id="org-teams-action"> | |||||
| <div class="col-md-12"> | |||||
| <a href="#"><button class="btn btn-success"><i class="fa fa-plus-square"></i>New Team</button></a> | |||||
| <hr/> | |||||
| </div> | |||||
| </div> | |||||
| <div class="org-team col-md-6"> | |||||
| <div class="panel panel-default"> | |||||
| <h2 class="panel-heading org-team-name"><a href="#"><strong>Team Name</strong></a></h2> | |||||
| <div class="panel-body"> | |||||
| <p class="org-team-meta">4 members · 10 repositories</p> | |||||
| <p class="org-team-members"> | |||||
| <a href="#"> | |||||
| <img class="img-thumbnail" src="https://avatars2.githubusercontent.com/u/2946214?s=60" alt=""/> | |||||
| </a> | |||||
| <a href="#"> | |||||
| <img class="img-thumbnail" src="https://avatars2.githubusercontent.com/u/2946214?s=60" alt=""/> | |||||
| </a> | |||||
| </p> | |||||
| </div> | |||||
| <div class="panel-footer"> | |||||
| <button class="pull-right btn btn-default">Join</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="org-team col-md-6"> | |||||
| <div class="panel panel-default"> | |||||
| <h2 class="panel-heading org-team-name"><a href="#"><strong>Team Name</strong></a></h2> | |||||
| <div class="panel-body"> | |||||
| <p class="org-team-meta">4 members · 10 repositories</p> | |||||
| <p class="org-team-members"> | |||||
| <a href="#"> | |||||
| <img class="img-thumbnail" src="https://avatars2.githubusercontent.com/u/2946214?s=60" alt=""/> | |||||
| </a> | |||||
| <a href="#"> | |||||
| <img class="img-thumbnail" src="https://avatars2.githubusercontent.com/u/2946214?s=60" alt=""/> | |||||
| </a> | |||||
| </p> | |||||
| </div> | |||||
| <div class="panel-footer"> | |||||
| <button class="pull-right btn btn-danger">Leave</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -8,9 +8,37 @@ | |||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label> | <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label> | ||||
| <div class="col-md-8"> | <div class="col-md-8"> | ||||
| <p class="form-control-static">{{.SignedUserName}}</p> | |||||
| <input type="hidden" value="{{.SignedUserId}}" name="userId"/> | |||||
| <div class="btn-group" id="repo-owner-switch"> | |||||
| <button type="button" class="btn btn-default" id="repo-owner-current"> | |||||
| <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username" id="repo-owner-avatar"> | |||||
| <span id="repo-owner-name">{{.SignedUser.Name}}</span> | |||||
| </button> | |||||
| <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | |||||
| <span class="caret"></span> | |||||
| </button> | |||||
| <div class="dropdown-menu clone-group-btn no-propagation"> | |||||
| <ul id="dashboard-switch-menu" class="list-unstyled"> | |||||
| <li data-uid="{{.SignedUser.Id}}" class="checked"> | |||||
| <a> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.SignedUser.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{range .Orgs}} | |||||
| <li data-uid="{{.Id}}"> | |||||
| <a> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{end}} | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <input type="hidden" value="{{.SignedUserId}}" name="uid" id="repo-owner-id"/> | |||||
| </div> | </div> | ||||
| <div class="form-group {{if .Err_RepoName}}has-error has-feedback{{end}}"> | <div class="form-group {{if .Err_RepoName}}has-error has-feedback{{end}}"> | ||||
| @@ -44,9 +44,37 @@ | |||||
| <div class="form-group"> | <div class="form-group"> | ||||
| <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label> | <label class="col-md-2 control-label">Owner<strong class="text-danger">*</strong></label> | ||||
| <div class="col-md-8"> | <div class="col-md-8"> | ||||
| <p class="form-control-static">{{.SignedUserName}}</p> | |||||
| <input type="hidden" value="{{.SignedUserId}}" name="userId"/> | |||||
| <div class="btn-group" id="repo-owner-switch"> | |||||
| <button type="button" class="btn btn-default" id="repo-owner-current"> | |||||
| <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username" id="repo-owner-avatar"> | |||||
| <span id="repo-owner-name">{{.SignedUser.Name}}</span> | |||||
| </button> | |||||
| <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | |||||
| <span class="caret"></span> | |||||
| </button> | |||||
| <div class="dropdown-menu clone-group-btn no-propagation"> | |||||
| <ul id="dashboard-switch-menu" class="list-unstyled"> | |||||
| <li data-uid="{{.SignedUser.Id}}" class="checked"> | |||||
| <a> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.SignedUser.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{range .Orgs}} | |||||
| <li data-uid="{{.Id}}"> | |||||
| <a> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{end}} | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <input type="hidden" value="{{.SignedUserId}}" name="uid" id="repo-owner-id"/> | |||||
| </div> | </div> | ||||
| <div class="form-group {{if .Err_RepoName}}has-error has-feedback{{end}}"> | <div class="form-group {{if .Err_RepoName}}has-error has-feedback{{end}}"> | ||||
| @@ -4,27 +4,46 @@ | |||||
| <div class="container"> | <div class="container"> | ||||
| <div class="btn-group pull-left" id="dashboard-switch"> | <div class="btn-group pull-left" id="dashboard-switch"> | ||||
| <button type="button" class="btn btn-default"> | <button type="button" class="btn btn-default"> | ||||
| <img src="//1.gravatar.com/avatar/f72f7454ce9d710baa506394f68f4132?s=28" alt="user-avatar" title="username"> | |||||
| fuxiaohei | |||||
| <img src="{{.ContextUser.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.ContextUser.Name}} | |||||
| </button> | </button> | ||||
| <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> | ||||
| <span class="caret"></span> | <span class="caret"></span> | ||||
| </button> | </button> | ||||
| <div class="dropdown-menu clone-group-btn no-propagation"> | <div class="dropdown-menu clone-group-btn no-propagation"> | ||||
| <ul id="dashboard-switch-menu" class="list-unstyled"> | <ul id="dashboard-switch-menu" class="list-unstyled"> | ||||
| <li class="checked"><a href="#"><i class="fa fa-check"></i> gogits/gogs</a></li> | |||||
| <li{{if not .PageIsOrgDashboard}} class="checked"{{end}}> | |||||
| <a href="/"> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.SignedUser.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.SignedUser.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{range .Orgs}} | |||||
| <li{{if eq $.ContextUser.Id .Id}} class="checked"{{end}}> | |||||
| <a href="/org/{{.Name}}/dashboard"> | |||||
| <i class="fa fa-check"></i> | |||||
| <img src="{{.AvatarLink}}?s=28" alt="user-avatar" title="username"> | |||||
| {{.Name}} | |||||
| </a> | |||||
| </li> | |||||
| {{end}} | |||||
| <li> | |||||
| <a href="/org/create">Create organization</a> | |||||
| </li> | |||||
| </ul> | </ul> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <ul class="nav nav-pills pull-right"> | <ul class="nav nav-pills pull-right"> | ||||
| <li class="active"><a href="/">Feed</a></li> | |||||
| <li><a href="/issues">Issues</a></li> | |||||
| <li class="active"><a href="/{{if .PageIsOrgDashboard}}org/{{.ContextUser.Name}}/dashboard{{end}}">News Feed</a></li> | |||||
| <li><a href="/{{if .PageIsOrgDashboard}}org/{{.ContextUser.Name}}/dashboard/{{end}}issues">Issues</a></li> | |||||
| {{if .PageIsOrgDashboard}}<li><a href="/org/{{.ContextUser.Name}}/settings">Settings</a></li>{{end}} | |||||
| <!-- <li><a href="/pulls">Pull Requests</a></li> | <!-- <li><a href="/pulls">Pull Requests</a></li> | ||||
| <li><a href="/stars">Stars</a></li> --> | <li><a href="/stars">Stars</a></li> --> | ||||
| </ul> | </ul> | ||||
| <h3>News Feed</h3> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div id="body" class="container" data-page="user"> | <div id="body" class="container" data-page="user"> | ||||
| {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}} | {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}} | ||||
| <div id="feed-left" class="col-md-8"> | <div id="feed-left" class="col-md-8"> | ||||
| @@ -42,7 +61,7 @@ | |||||
| </div> | </div> | ||||
| <div id="feed-right" class="col-md-4"> | <div id="feed-right" class="col-md-4"> | ||||
| <div class="panel panel-default repo-panel"> | <div class="panel panel-default repo-panel"> | ||||
| <div class="panel-heading">Your Repositories | |||||
| <div class="panel-heading">{{if not .PageIsOrgDashboard}}Your {{end}}Repositories | |||||
| <div class="btn-group pull-right" id="user-dashboard-repo-new"> | <div class="btn-group pull-right" id="user-dashboard-repo-new"> | ||||
| <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus-square"></i>New</button> | <button type="button" class="btn btn-success btn-sm dropdown-toggle" data-toggle="dropdown"><i class="fa fa-plus-square"></i>New</button> | ||||
| <div class="dropdown-menu dropdown-menu-right"> | <div class="dropdown-menu dropdown-menu-right"> | ||||
| @@ -64,7 +83,8 @@ | |||||
| </ul> | </ul> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{if not .PageIsOrgDashboard}} | |||||
| <div class="panel panel-default repo-panel"> | <div class="panel panel-default repo-panel"> | ||||
| <div class="panel-heading">Collaborative Repositories</div> | <div class="panel-heading">Collaborative Repositories</div> | ||||
| <div class="panel-body"> | <div class="panel-body"> | ||||
| @@ -76,6 +96,7 @@ | |||||
| </ul> | </ul> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{template "base/footer" .}} | {{template "base/footer" .}} | ||||
| @@ -3,7 +3,7 @@ | |||||
| <div id="body-nav"> | <div id="body-nav"> | ||||
| <div class="container"> | <div class="container"> | ||||
| <ul class="nav nav-pills pull-right"> | <ul class="nav nav-pills pull-right"> | ||||
| <li><a href="/">Feed</a></li> | |||||
| <li><a href="/">News Feed</a></li> | |||||
| <li class="active"><a href="/issues">Issues</a></li> | <li class="active"><a href="/issues">Issues</a></li> | ||||
| <!-- <li><a href="/pulls">Pull Requests</a></li> | <!-- <li><a href="/pulls">Pull Requests</a></li> | ||||
| <li><a href="/stars">Stars</a></li> --> | <li><a href="/stars">Stars</a></li> --> | ||||
| @@ -11,6 +11,7 @@ | |||||
| <h3>Your Issues</h3> | <h3>Your Issues</h3> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div id="body" class="container" data-page="user"> | <div id="body" class="container" data-page="user"> | ||||
| {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}} | {{if .HasInfo}}<div class="alert alert-info">{{.InfoMsg}}</div>{{end}} | ||||
| <div id="issue"> | <div id="issue"> | ||||