Browse Source

Merge branch 'master' of github.com:gogits/gogs

Conflicts:
	models/update.go
	routers/repo/http.go
Lunny Xiao 5 years ago
parent
commit
86e2627175
75 changed files with 2032 additions and 659 deletions
  1. 0 3
      README.md
  2. 0 3
      README_ZH.md
  3. 10 10
      cmd/serve.go
  4. 3 1
      cmd/update.go
  5. 13 2
      cmd/web.go
  6. 2 2
      conf/app.ini
  7. 1 1
      gogs.go
  8. 9 8
      models/access.go
  9. 6 5
      models/action.go
  10. 2 2
      models/issue.go
  11. 2 2
      models/login.go
  12. 1 1
      models/models.go
  13. 192 0
      models/org.go
  14. 80 49
      models/repo.go
  15. 14 13
      models/update.go
  16. 107 54
      models/user.go
  17. 57 0
      modules/auth/org.go
  18. 5 3
      modules/auth/repo.go
  19. 16 14
      modules/auth/user.go
  20. 1 0
      modules/base/base.go
  21. 235 236
      modules/bin/conf.go
  22. 14 5
      modules/mailer/mail.go
  23. 4 4
      modules/middleware/context.go
  24. 2 2
      modules/middleware/repo.go
  25. 7 7
      modules/setting/setting.go
  26. 114 3
      public/css/gogs.css
  27. 24 0
      public/js/app.js
  28. 19 10
      routers/admin/admin.go
  29. 14 9
      routers/admin/auths.go
  30. 29 21
      routers/admin/user.go
  31. 6 1
      routers/dashboard.go
  32. 2 1
      routers/dev/template.go
  33. 17 11
      routers/install.go
  34. 152 1
      routers/org/org.go
  35. 21 0
      routers/org/teams.go
  36. 8 3
      routers/repo/branch.go
  37. 48 44
      routers/repo/commit.go
  38. 4 4
      routers/repo/http.go
  39. 27 7
      routers/repo/issue.go
  40. 6 1
      routers/repo/pull.go
  41. 15 4
      routers/repo/release.go
  42. 84 22
      routers/repo/repo.go
  43. 43 28
      routers/repo/setting.go
  44. 30 11
      routers/user/home.go
  45. 18 9
      routers/user/setting.go
  46. 36 26
      routers/user/user.go
  47. 1 1
      templates/VERSION
  48. 0 0
      templates/admin/auth/edit.tmpl
  49. 0 0
      templates/admin/auth/new.tmpl
  50. 2 2
      templates/admin/config.tmpl
  51. 0 0
      templates/admin/user/edit.tmpl
  52. 0 0
      templates/admin/user/new.tmpl
  53. 0 0
      templates/mail/auth/active.tmpl
  54. 75 0
      templates/org/edit_team.tmpl
  55. 56 0
      templates/org/members.tmpl
  56. 32 0
      templates/org/new.tmpl
  57. 74 0
      templates/org/new_team.tmpl
  58. 130 0
      templates/org/settings.tmpl
  59. 71 0
      templates/org/teams.tmpl
  60. 0 0
      templates/repo/branch.tmpl
  61. 30 2
      templates/repo/create.tmpl
  62. 0 0
      templates/repo/hook_add.tmpl
  63. 0 0
      templates/repo/hook_edit.tmpl
  64. 0 0
      templates/repo/issue/create.tmpl
  65. 0 0
      templates/repo/issue/list.tmpl
  66. 0 0
      templates/repo/issue/milestone.tmpl
  67. 0 0
      templates/repo/issue/milestone_edit.tmpl
  68. 0 0
      templates/repo/issue/milestone_new.tmpl
  69. 0 0
      templates/repo/issue/view.tmpl
  70. 30 2
      templates/repo/migrate.tmpl
  71. 0 0
      templates/repo/release/edit.tmpl
  72. 0 0
      templates/repo/release/list.tmpl
  73. 0 0
      templates/repo/release/new.tmpl
  74. 29 8
      templates/user/dashboard.tmpl
  75. 2 1
      templates/user/issue.tmpl

+ 0 - 3
README.md

@@ -75,9 +75,6 @@ There are 5 ways to install Gogs:
75 75
 
76 76
 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.
77 77
 
78
-[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
79
-[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
80
-
81 78
 ## License
82 79
 
83 80
 This project is under the MIT License. See the [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) file for the full license text.

+ 0 - 3
README_ZH.md

@@ -66,9 +66,6 @@ Gogs 完全使用 Go 语言来实现对 Git 数据的操作,实现 **零** 依
66 66
 
67 67
 本项目的 [开发团队](http://gogs.io/team)。您可以通过查看 [贡献者页面](https://github.com/gogits/gogs/graphs/contributors) 获取完整的贡献者列表。
68 68
 
69
-[![Clone in Koding](http://learn.koding.com/btn/clone_d.png)][koding]
70
-[koding]: https://koding.com/Teamwork?import=https://github.com/gogits/gogs/archive/master.zip&c=git1
71
-
72 69
 ## 授权许可
73 70
 
74 71
 本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/gogits/gogs/blob/master/LICENSE) 文件中。

+ 10 - 10
cmd/serve.go

@@ -56,19 +56,19 @@ func parseCmd(cmd string) (string, string) {
56 56
 }
57 57
 
58 58
 var (
59
-	COMMANDS_READONLY = map[string]int{
60
-		"git-upload-pack":    models.AU_WRITABLE,
61
-		"git upload-pack":    models.AU_WRITABLE,
62
-		"git-upload-archive": models.AU_WRITABLE,
59
+	COMMANDS_READONLY = map[string]models.AccessType{
60
+		"git-upload-pack":    models.WRITABLE,
61
+		"git upload-pack":    models.WRITABLE,
62
+		"git-upload-archive": models.WRITABLE,
63 63
 	}
64 64
 
65
-	COMMANDS_WRITE = map[string]int{
66
-		"git-receive-pack": models.AU_READABLE,
67
-		"git receive-pack": models.AU_READABLE,
65
+	COMMANDS_WRITE = map[string]models.AccessType{
66
+		"git-receive-pack": models.READABLE,
67
+		"git receive-pack": models.READABLE,
68 68
 	}
69 69
 )
70 70
 
71
-func In(b string, sl map[string]int) bool {
71
+func In(b string, sl map[string]models.AccessType) bool {
72 72
 	_, e := sl[b]
73 73
 	return e
74 74
 }
@@ -129,7 +129,7 @@ func runServ(k *cli.Context) {
129 129
 	// Access check.
130 130
 	switch {
131 131
 	case isWrite:
132
-		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_WRITABLE)
132
+		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.WRITABLE)
133 133
 		if err != nil {
134 134
 			println("Gogs: internal error:", err)
135 135
 			log.GitLogger.Fatal("Fail to check write access:", err)
@@ -152,7 +152,7 @@ func runServ(k *cli.Context) {
152 152
 			break
153 153
 		}
154 154
 
155
-		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.AU_READABLE)
155
+		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.READABLE)
156 156
 		if err != nil {
157 157
 			println("Gogs: internal error:", err)
158 158
 			log.GitLogger.Fatal("Fail to check read access:", err)

+ 3 - 1
cmd/update.go

@@ -42,5 +42,7 @@ func runUpdate(c *cli.Context) {
42 42
 	repoUserName := os.Getenv("repoUserName")
43 43
 	repoName := os.Getenv("repoName")
44 44
 
45
-	models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId)
45
+	if err := models.Update(args[0], args[1], args[2], userName, repoUserName, repoName, userId); err != nil {
46
+		log.GitLogger.Fatal(err.Error())
47
+	}
46 48
 }

+ 13 - 2
cmd/web.go

@@ -188,9 +188,20 @@ func runWeb(*cli.Context) {
188 188
 
189 189
 	reqOwner := middleware.RequireOwner()
190 190
 
191
-	m.Group("/o", func(r martini.Router) {
191
+	m.Group("/org", func(r martini.Router) {
192
+		r.Get("/create", org.New)
193
+		r.Post("/create", bindIgnErr(auth.CreateOrgForm{}), org.NewPost)
192 194
 		r.Get("/:org", org.Organization)
193
-	})
195
+		r.Get("/:org/dashboard", org.Dashboard)
196
+		r.Get("/:org/members", org.Members)
197
+		// organization teams
198
+		r.Get("/:org/teams/:team/edit", org.EditTeam)
199
+		r.Get("/:org/teams/new", org.NewTeam)
200
+		r.Get("/:org/teams", org.Teams)
201
+
202
+		r.Get("/:org/settings", org.Settings)
203
+		r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost)
204
+	}, reqSignIn)
194 205
 
195 206
 	m.Group("/:username/:reponame", func(r martini.Router) {
196 207
 		r.Get("/settings", repo.Setting)

+ 2 - 2
conf/app.ini

@@ -51,8 +51,8 @@ SECRET_KEY = !#@FDEWREWR&*(
51 51
 LOGIN_REMEMBER_DAYS = 7
52 52
 COOKIE_USERNAME = gogs_awesome
53 53
 COOKIE_REMEMBER_NAME = gogs_incredible
54
-; Reverse proxy authentication header name of user ID
55
-REVERSE_PROXY_AUTHENTICATION_UID = X-WEBAUTH-UID
54
+; Reverse proxy authentication header name of user name
55
+REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
56 56
 
57 57
 [service]
58 58
 ACTIVE_CODE_LIVE_MINUTES = 180

+ 1 - 1
gogs.go

@@ -17,7 +17,7 @@ import (
17 17
 	"github.com/gogits/gogs/modules/setting"
18 18
 )
19 19
 
20
-const APP_VER = "0.4.5.0621 Alpha"
20
+const APP_VER = "0.4.5.0627 Alpha"
21 21
 
22 22
 func init() {
23 23
 	runtime.GOMAXPROCS(runtime.NumCPU())

+ 9 - 8
models/access.go

@@ -11,19 +11,20 @@ import (
11 11
 	"github.com/go-xorm/xorm"
12 12
 )
13 13
 
14
-// Access types.
14
+type AccessType int
15
+
15 16
 const (
16
-	AU_READABLE = iota + 1
17
-	AU_WRITABLE
17
+	READABLE AccessType = iota + 1
18
+	WRITABLE
18 19
 )
19 20
 
20 21
 // Access represents the accessibility of user to repository.
21 22
 type Access struct {
22 23
 	Id       int64
23
-	UserName string    `xorm:"unique(s)"`
24
-	RepoName string    `xorm:"unique(s)"` // <user name>/<repo name>
25
-	Mode     int       `xorm:"unique(s)"`
26
-	Created  time.Time `xorm:"created"`
24
+	UserName string     `xorm:"unique(s)"`
25
+	RepoName string     `xorm:"unique(s)"` // <user name>/<repo name>
26
+	Mode     AccessType `xorm:"unique(s)"`
27
+	Created  time.Time  `xorm:"created"`
27 28
 }
28 29
 
29 30
 // AddAccess adds new access record.
@@ -59,7 +60,7 @@ func UpdateAccessWithSession(sess *xorm.Session, access *Access) error {
59 60
 
60 61
 // HasAccess returns true if someone can read or write to given repository.
61 62
 // The repoName should be in format <username>/<reponame>.
62
-func HasAccess(uname, repoName string, mode int) (bool, error) {
63
+func HasAccess(uname, repoName string, mode AccessType) (bool, error) {
63 64
 	if len(repoName) == 0 {
64 65
 		return false, nil
65 66
 	}

+ 6 - 5
models/action.go

@@ -182,14 +182,15 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
182 182
 }
183 183
 
184 184
 // NewRepoAction adds new action for creating repository.
185
-func NewRepoAction(user *User, repo *Repository) (err error) {
186
-	if err = NotifyWatchers(&Action{ActUserId: user.Id, ActUserName: user.Name, ActEmail: user.Email,
187
-		OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoName: repo.Name, IsPrivate: repo.IsPrivate}); err != nil {
188
-		log.Error("action.NewRepoAction(notify watchers): %d/%s", user.Id, repo.Name)
185
+func NewRepoAction(u *User, repo *Repository) (err error) {
186
+	if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email,
187
+		OpType: OP_CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name,
188
+		IsPrivate: repo.IsPrivate}); err != nil {
189
+		log.Error("action.NewRepoAction(notify watchers): %d/%s", u.Id, repo.Name)
189 190
 		return err
190 191
 	}
191 192
 
192
-	log.Trace("action.NewRepoAction: %s/%s", user.LowerName, repo.LowerName)
193
+	log.Trace("action.NewRepoAction: %s/%s", u.LowerName, repo.LowerName)
193 194
 	return err
194 195
 }
195 196
 

+ 2 - 2
models/issue.go

@@ -213,9 +213,9 @@ func GetIssueCountByPoster(uid, rid int64, isClosed bool) int64 {
213 213
 // IssueUser represents an issue-user relation.
214 214
 type IssueUser struct {
215 215
 	Id          int64
216
-	Uid         int64 // User ID.
216
+	Uid         int64 `xorm:"INDEX"` // User ID.
217 217
 	IssueId     int64
218
-	RepoId      int64
218
+	RepoId      int64 `xorm:"INDEX"`
219 219
 	MilestoneId int64
220 220
 	IsRead      bool
221 221
 	IsAssigned  bool

+ 2 - 2
models/login.go

@@ -255,7 +255,7 @@ func LoginUserLdapSource(user *User, name, passwd string, sourceId int64, cfg *L
255 255
 		Email:       mail,
256 256
 	}
257 257
 
258
-	return RegisterUser(user)
258
+	return CreateUser(user)
259 259
 }
260 260
 
261 261
 type loginAuth struct {
@@ -359,5 +359,5 @@ func LoginUserSMTPSource(user *User, name, passwd string, sourceId int64, cfg *S
359 359
 		Passwd:      passwd,
360 360
 		Email:       name,
361 361
 	}
362
-	return RegisterUser(user)
362
+	return CreateUser(user)
363 363
 }

+ 1 - 1
models/models.go

@@ -35,7 +35,7 @@ func init() {
35 35
 	tables = append(tables, new(User), new(PublicKey), new(Repository), new(Watch),
36 36
 		new(Action), new(Access), new(Issue), new(Comment), new(Oauth2), new(Follow),
37 37
 		new(Mirror), new(Release), new(LoginSource), new(Webhook), new(IssueUser),
38
-		new(Milestone), new(Label), new(HookTask))
38
+		new(Milestone), new(Label), new(HookTask), new(Team), new(OrgUser), new(TeamUser))
39 39
 }
40 40
 
41 41
 func LoadModelsConfig() {

+ 192 - 0
models/org.go

@@ -0,0 +1,192 @@
1
+// Copyright 2014 The Gogs Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package models
6
+
7
+import (
8
+	"strings"
9
+
10
+	"github.com/gogits/gogs/modules/base"
11
+)
12
+
13
+// CreateOrganization creates record of a new organization.
14
+func CreateOrganization(org, owner *User) (*User, error) {
15
+	if !IsLegalName(org.Name) {
16
+		return nil, ErrUserNameIllegal
17
+	}
18
+
19
+	isExist, err := IsUserExist(org.Name)
20
+	if err != nil {
21
+		return nil, err
22
+	} else if isExist {
23
+		return nil, ErrUserAlreadyExist
24
+	}
25
+
26
+	isExist, err = IsEmailUsed(org.Email)
27
+	if err != nil {
28
+		return nil, err
29
+	} else if isExist {
30
+		return nil, ErrEmailAlreadyUsed
31
+	}
32
+
33
+	org.LowerName = strings.ToLower(org.Name)
34
+	org.FullName = org.Name
35
+	org.Avatar = base.EncodeMd5(org.Email)
36
+	org.AvatarEmail = org.Email
37
+	// No password for organization.
38
+	org.NumTeams = 1
39
+	org.NumMembers = 1
40
+
41
+	sess := x.NewSession()
42
+	defer sess.Close()
43
+	if err = sess.Begin(); err != nil {
44
+		return nil, err
45
+	}
46
+
47
+	if _, err = sess.Insert(org); err != nil {
48
+		sess.Rollback()
49
+		return nil, err
50
+	}
51
+
52
+	// Create default owner team.
53
+	t := &Team{
54
+		OrgId:      org.Id,
55
+		Name:       OWNER_TEAM,
56
+		Authorize:  ORG_ADMIN,
57
+		NumMembers: 1,
58
+	}
59
+	if _, err = sess.Insert(t); err != nil {
60
+		sess.Rollback()
61
+		return nil, err
62
+	}
63
+
64
+	// Add initial creator to organization and owner team.
65
+	ou := &OrgUser{
66
+		Uid:     owner.Id,
67
+		OrgId:   org.Id,
68
+		IsOwner: true,
69
+		NumTeam: 1,
70
+	}
71
+	if _, err = sess.Insert(ou); err != nil {
72
+		sess.Rollback()
73
+		return nil, err
74
+	}
75
+
76
+	tu := &TeamUser{
77
+		Uid:    owner.Id,
78
+		OrgId:  org.Id,
79
+		TeamId: t.Id,
80
+	}
81
+	if _, err = sess.Insert(tu); err != nil {
82
+		sess.Rollback()
83
+		return nil, err
84
+	}
85
+
86
+	return org, sess.Commit()
87
+}
88
+
89
+type AuthorizeType int
90
+
91
+const (
92
+	ORG_READABLE AuthorizeType = iota + 1
93
+	ORG_WRITABLE
94
+	ORG_ADMIN
95
+)
96
+
97
+const OWNER_TEAM = "Owner"
98
+
99
+// Team represents a organization team.
100
+type Team struct {
101
+	Id          int64
102
+	OrgId       int64 `xorm:"INDEX"`
103
+	Name        string
104
+	Description string
105
+	Authorize   AuthorizeType
106
+	RepoIds     string `xorm:"TEXT"`
107
+	NumMembers  int
108
+	NumRepos    int
109
+}
110
+
111
+// NewTeam creates a record of new team.
112
+func NewTeam(t *Team) error {
113
+	_, err := x.Insert(t)
114
+	return err
115
+}
116
+
117
+func UpdateTeam(t *Team) error {
118
+	if len(t.Description) > 255 {
119
+		t.Description = t.Description[:255]
120
+	}
121
+
122
+	_, err := x.Id(t.Id).AllCols().Update(t)
123
+	return err
124
+}
125
+
126
+// ________                ____ ___
127
+// \_____  \_______  ____ |    |   \______ ___________
128
+//  /   |   \_  __ \/ ___\|    |   /  ___// __ \_  __ \
129
+// /    |    \  | \/ /_/  >    |  /\___ \\  ___/|  | \/
130
+// \_______  /__|  \___  /|______//____  >\___  >__|
131
+//         \/     /_____/              \/     \/
132
+
133
+// OrgUser represents an organization-user relation.
134
+type OrgUser struct {
135
+	Id       int64
136
+	Uid      int64 `xorm:"INDEX"`
137
+	OrgId    int64 `xorm:"INDEX"`
138
+	IsPublic bool
139
+	IsOwner  bool
140
+	NumTeam  int
141
+}
142
+
143
+// GetOrgUsersByUserId returns all organization-user relations by user ID.
144
+func GetOrgUsersByUserId(uid int64) ([]*OrgUser, error) {
145
+	ous := make([]*OrgUser, 0, 10)
146
+	err := x.Where("uid=?", uid).Find(&ous)
147
+	return ous, err
148
+}
149
+
150
+// GetOrgUsersByOrgId returns all organization-user relations by organization ID.
151
+func GetOrgUsersByOrgId(orgId int64) ([]*OrgUser, error) {
152
+	ous := make([]*OrgUser, 0, 10)
153
+	err := x.Where("org_id=?", orgId).Find(&ous)
154
+	return ous, err
155
+}
156
+
157
+func GetOrganizationCount(u *User) (int64, error) {
158
+	return x.Where("uid=?", u.Id).Count(new(OrgUser))
159
+}
160
+
161
+// ___________                    ____ ___
162
+// \__    ___/___ _____    _____ |    |   \______ ___________
163
+//   |    |_/ __ \\__  \  /     \|    |   /  ___// __ \_  __ \
164
+//   |    |\  ___/ / __ \|  Y Y  \    |  /\___ \\  ___/|  | \/
165
+//   |____| \___  >____  /__|_|  /______//____  >\___  >__|
166
+//              \/     \/      \/             \/     \/
167
+
168
+// TeamUser represents an team-user relation.
169
+type TeamUser struct {
170
+	Id     int64
171
+	Uid    int64
172
+	OrgId  int64 `xorm:"INDEX"`
173
+	TeamId int64
174
+}
175
+
176
+// GetTeamMembers returns all members in given team of organization.
177
+func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
178
+	tus := make([]*TeamUser, 0, 10)
179
+	err := x.Where("org_id=?", orgId).And("team_id=?", teamId).Find(&tus)
180
+	if err != nil {
181
+		return nil, err
182
+	}
183
+
184
+	us := make([]*User, len(tus))
185
+	for i, tu := range tus {
186
+		us[i], err = GetUserById(tu.Uid)
187
+		if err != nil {
188
+			return nil, err
189
+		}
190
+	}
191
+	return us, nil
192
+}

+ 80 - 49
models/repo.go

@@ -158,7 +158,7 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) {
158 158
 }
159 159
 
160 160
 var (
161
-	illegalEquals  = []string{"raw", "install", "api", "avatar", "user", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
161
+	illegalEquals  = []string{"raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
162 162
 	illegalSuffixs = []string{".git"}
163 163
 )
164 164
 
@@ -240,7 +240,7 @@ func MirrorUpdate() {
240 240
 			"git", "remote", "update"); err != nil {
241 241
 			return errors.New("git remote update: " + stderr)
242 242
 		} else if err = git.UnpackRefs(repoPath); err != nil {
243
-			return err
243
+			return errors.New("UnpackRefs: " + err.Error())
244 244
 		}
245 245
 
246 246
 		m.NextUpdate = time.Now().Add(time.Duration(m.Interval) * time.Hour)
@@ -251,8 +251,8 @@ func MirrorUpdate() {
251 251
 }
252 252
 
253 253
 // MigrateRepository migrates a existing repository from other project hosting.
254
-func MigrateRepository(user *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
255
-	repo, err := CreateRepository(user, name, desc, "", "", private, mirror, false)
254
+func MigrateRepository(u *User, name, desc string, private, mirror bool, url string) (*Repository, error) {
255
+	repo, err := CreateRepository(u, name, desc, "", "", private, mirror, false)
256 256
 	if err != nil {
257 257
 		return nil, err
258 258
 	}
@@ -261,11 +261,11 @@ func MigrateRepository(user *User, name, desc string, private, mirror bool, url
261 261
 	tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("%d", time.Now().Nanosecond()))
262 262
 	os.MkdirAll(tmpDir, os.ModePerm)
263 263
 
264
-	repoPath := RepoPath(user.Name, name)
264
+	repoPath := RepoPath(u.Name, name)
265 265
 
266 266
 	repo.IsBare = false
267 267
 	if mirror {
268
-		if err = MirrorRepository(repo.Id, user.Name, repo.Name, repoPath, url); err != nil {
268
+		if err = MirrorRepository(repo.Id, u.Name, repo.Name, repoPath, url); err != nil {
269 269
 			return repo, err
270 270
 		}
271 271
 		repo.IsMirror = true
@@ -454,21 +454,28 @@ func initRepository(f string, user *User, repo *Repository, initReadme bool, rep
454 454
 	return initRepoCommit(tmpDir, user.NewGitSig())
455 455
 }
456 456
 
457
-// CreateRepository creates a repository for given user or orgnaziation.
458
-func CreateRepository(user *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) {
457
+// CreateRepository creates a repository for given user or organization.
458
+func CreateRepository(u *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) {
459 459
 	if !IsLegalName(name) {
460 460
 		return nil, ErrRepoNameIllegal
461 461
 	}
462 462
 
463
-	isExist, err := IsRepositoryExist(user, name)
463
+	isExist, err := IsRepositoryExist(u, name)
464 464
 	if err != nil {
465 465
 		return nil, err
466 466
 	} else if isExist {
467 467
 		return nil, ErrRepoAlreadyExist
468 468
 	}
469 469
 
470
+	sess := x.NewSession()
471
+	defer sess.Close()
472
+	if err = sess.Begin(); err != nil {
473
+		return nil, err
474
+	}
475
+
470 476
 	repo := &Repository{
471
-		OwnerId:     user.Id,
477
+		OwnerId:     u.Id,
478
+		Owner:       u,
472 479
 		Name:        name,
473 480
 		LowerName:   strings.ToLower(name),
474 481
 		Description: desc,
@@ -479,67 +486,85 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir
479 486
 		repo.DefaultBranch = "master"
480 487
 	}
481 488
 
482
-	repoPath := RepoPath(user.Name, repo.Name)
483
-
484
-	sess := x.NewSession()
485
-	defer sess.Close()
486
-	sess.Begin()
487
-
488 489
 	if _, err = sess.Insert(repo); err != nil {
489
-		if err2 := os.RemoveAll(repoPath); err2 != nil {
490
-			log.Error("repo.CreateRepository(repo): %v", err)
491
-			return nil, errors.New(fmt.Sprintf(
492
-				"delete repo directory %s/%s failed(1): %v", user.Name, repo.Name, err2))
493
-		}
494 490
 		sess.Rollback()
495 491
 		return nil, err
496 492
 	}
497 493
 
498
-	mode := AU_WRITABLE
494
+	var t *Team // Owner team.
495
+
496
+	mode := WRITABLE
499 497
 	if mirror {
500
-		mode = AU_READABLE
498
+		mode = READABLE
501 499
 	}
502
-	access := Access{
503
-		UserName: user.LowerName,
504
-		RepoName: strings.ToLower(path.Join(user.Name, repo.Name)),
500
+	access := &Access{
501
+		UserName: u.LowerName,
502
+		RepoName: strings.ToLower(path.Join(u.Name, repo.Name)),
505 503
 		Mode:     mode,
506 504
 	}
507
-	if _, err = sess.Insert(&access); err != nil {
508
-		sess.Rollback()
509
-		if err2 := os.RemoveAll(repoPath); err2 != nil {
510
-			log.Error("repo.CreateRepository(access): %v", err)
511
-			return nil, errors.New(fmt.Sprintf(
512
-				"delete repo directory %s/%s failed(2): %v", user.Name, repo.Name, err2))
505
+	// Give access to all members in owner team.
506
+	if u.IsOrganization() {
507
+		t, err = u.GetOwnerTeam()
508
+		if err != nil {
509
+			sess.Rollback()
510
+			return nil, err
511
+		}
512
+		us, err := GetTeamMembers(u.Id, t.Id)
513
+		if err != nil {
514
+			sess.Rollback()
515
+			return nil, err
516
+		}
517
+		for _, u := range us {
518
+			access.UserName = u.LowerName
519
+			if _, err = sess.Insert(access); err != nil {
520
+				sess.Rollback()
521
+				return nil, err
522
+			}
523
+		}
524
+	} else {
525
+		if _, err = sess.Insert(access); err != nil {
526
+			sess.Rollback()
527
+			return nil, err
513 528
 		}
514
-		return nil, err
515 529
 	}
516 530
 
517 531
 	rawSql := "UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?"
518
-	if _, err = sess.Exec(rawSql, user.Id); err != nil {
532
+	if _, err = sess.Exec(rawSql, u.Id); err != nil {
519 533
 		sess.Rollback()
520
-		if err2 := os.RemoveAll(repoPath); err2 != nil {
521
-			log.Error("repo.CreateRepository(repo count): %v", err)
522
-			return nil, errors.New(fmt.Sprintf(
523
-				"delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2))
524
-		}
525 534
 		return nil, err
526 535
 	}
527 536
 
528
-	if err = sess.Commit(); err != nil {
529
-		sess.Rollback()
530
-		if err2 := os.RemoveAll(repoPath); err2 != nil {
531
-			log.Error("repo.CreateRepository(commit): %v", err)
532
-			return nil, errors.New(fmt.Sprintf(
533
-				"delete repo directory %s/%s failed(3): %v", user.Name, repo.Name, err2))
537
+	// Update owner team info and count.
538
+	if u.IsOrganization() {
539
+		t.RepoIds += "$" + base.ToStr(repo.Id) + "|"
540
+		t.NumRepos++
541
+		if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
542
+			sess.Rollback()
543
+			return nil, err
534 544
 		}
545
+	}
546
+
547
+	if err = sess.Commit(); err != nil {
535 548
 		return nil, err
536 549
 	}
537 550
 
538
-	if err = WatchRepo(user.Id, repo.Id, true); err != nil {
539
-		log.Error("repo.CreateRepository(WatchRepo): %v", err)
551
+	if u.IsOrganization() {
552
+		ous, err := GetOrgUsersByOrgId(u.Id)
553
+		if err != nil {
554
+			log.Error("repo.CreateRepository(GetOrgUsersByOrgId): %v", err)
555
+		} else {
556
+			for _, ou := range ous {
557
+				if err = WatchRepo(ou.Uid, repo.Id, true); err != nil {
558
+					log.Error("repo.CreateRepository(WatchRepo): %v", err)
559
+				}
560
+			}
561
+		}
562
+	}
563
+	if err = WatchRepo(u.Id, repo.Id, true); err != nil {
564
+		log.Error("repo.CreateRepository(WatchRepo2): %v", err)
540 565
 	}
541 566
 
542
-	if err = NewRepoAction(user, repo); err != nil {
567
+	if err = NewRepoAction(u, repo); err != nil {
543 568
 		log.Error("repo.CreateRepository(NewRepoAction): %v", err)
544 569
 	}
545 570
 
@@ -548,7 +573,13 @@ func CreateRepository(user *User, name, desc, lang, license string, private, mir
548 573
 		return repo, nil
549 574
 	}
550 575
 
551
-	if err = initRepository(repoPath, user, repo, initReadme, lang, license); err != nil {
576
+	repoPath := RepoPath(u.Name, repo.Name)
577
+	if err = initRepository(repoPath, u, repo, initReadme, lang, license); err != nil {
578
+		if err2 := os.RemoveAll(repoPath); err2 != nil {
579
+			log.Error("repo.CreateRepository(initRepository): %v", err)
580
+			return nil, errors.New(fmt.Sprintf(
581
+				"delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2))
582
+		}
552 583
 		return nil, err
553 584
 	}
554 585
 

+ 14 - 13
models/update.go

@@ -6,6 +6,7 @@ package models
6 6
 
7 7
 import (
8 8
 	"container/list"
9
+	"fmt"
9 10
 	"os/exec"
10 11
 	"strings"
11 12
 
@@ -15,13 +16,13 @@ import (
15 16
 	"github.com/gogits/gogs/modules/log"
16 17
 )
17 18
 
18
-func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) {
19
+func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName string, userId int64) error {
19 20
 	//fmt.Println(refName, oldCommitId, newCommitId)
20 21
 	//fmt.Println(userName, repoUserName, repoName)
21 22
 	isNew := strings.HasPrefix(oldCommitId, "0000000")
22 23
 	if isNew &&
23 24
 		strings.HasPrefix(newCommitId, "0000000") {
24
-		log.GitLogger.Fatal("old rev and new rev both 000000")
25
+		return fmt.Errorf("old rev and new rev both 000000")
25 26
 	}
26 27
 
27 28
 	f := RepoPath(repoUserName, repoName)
@@ -33,18 +34,17 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
33 34
 	isDel := strings.HasPrefix(newCommitId, "0000000")
34 35
 	if isDel {
35 36
 		log.GitLogger.Info("del rev", refName, "from", userName+"/"+repoName+".git", "by", userId)
36
-		return
37
+		return nil
37 38
 	}
38 39
 
39 40
 	repo, err := git.OpenRepository(f)
40 41
 	if err != nil {
41
-		log.GitLogger.Fatal("runUpdate.Open repoId: %v", err)
42
+		return fmt.Errorf("runUpdate.Open repoId: %v", err)
42 43
 	}
43 44
 
44 45
 	newCommit, err := repo.GetCommit(newCommitId)
45 46
 	if err != nil {
46
-		log.GitLogger.Fatal("runUpdate GetCommit of newCommitId: %v", err)
47
-		return
47
+		return fmt.Errorf("runUpdate GetCommit of newCommitId: %v", err)
48 48
 	}
49 49
 
50 50
 	var l *list.List
@@ -52,28 +52,27 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
52 52
 	if isNew {
53 53
 		l, err = newCommit.CommitsBefore()
54 54
 		if err != nil {
55
-			log.GitLogger.Fatal("Find CommitsBefore erro: %v", err)
55
+			return fmt.Errorf("Find CommitsBefore erro: %v", err)
56 56
 		}
57 57
 	} else {
58 58
 		l, err = newCommit.CommitsBeforeUntil(oldCommitId)
59 59
 		if err != nil {
60
-			log.GitLogger.Fatal("Find CommitsBeforeUntil erro: %v", err)
61
-			return
60
+			return fmt.Errorf("Find CommitsBeforeUntil erro: %v", err)
62 61
 		}
63 62
 	}
64 63
 
65 64
 	if err != nil {
66
-		log.GitLogger.Fatal("runUpdate.Commit repoId: %v", err)
65
+		return fmt.Errorf("runUpdate.Commit repoId: %v", err)
67 66
 	}
68 67
 
69 68
 	ru, err := GetUserByName(repoUserName)
70 69
 	if err != nil {
71
-		log.GitLogger.Fatal("runUpdate.GetUserByName: %v", err)
70
+		return fmt.Errorf("runUpdate.GetUserByName: %v", err)
72 71
 	}
73 72
 
74 73
 	repos, err := GetRepositoryByName(ru.Id, repoName)
75 74
 	if err != nil {
76
-		log.GitLogger.Fatal("runUpdate.GetRepositoryByName userId: %v", err)
75
+		return fmt.Errorf("runUpdate.GetRepositoryByName userId: %v", err)
77 76
 	}
78 77
 
79 78
 	// if tags push
@@ -104,6 +103,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
104 103
 		return
105 104
 	}
106 105
 
106
+	// if commits push
107 107
 	commits := make([]*base.PushCommit, 0)
108 108
 	var maxCommits = 3
109 109
 	var actEmail string
@@ -126,6 +126,7 @@ func Update(refName, oldCommitId, newCommitId, userName, repoUserName, repoName
126 126
 	//commits = append(commits, []string{lastCommit.Id().String(), lastCommit.Message()})
127 127
 	if err = CommitRepoAction(userId, ru.Id, userName, actEmail,
128 128
 		repos.Id, repoUserName, repoName, refName, &base.PushCommits{l.Len(), commits}); err != nil {
129
-		log.GitLogger.Fatal("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
129
+		return fmt.Errorf("runUpdate.models.CommitRepoAction: %s/%s:%v", repoUserName, repoName, err)
130 130
 	}
131
+	return nil
131 132
 }

+ 107 - 54
models/user.go

@@ -21,14 +21,16 @@ import (
21 21
 	"github.com/gogits/gogs/modules/setting"
22 22
 )
23 23
 
24
-// User types.
24
+type UserType int
25
+
25 26
 const (
26
-	UT_INDIVIDUAL = iota + 1
27
-	UT_ORGANIZATION
27
+	INDIVIDUAL UserType = iota // Historic reason to make it starts at 0.
28
+	ORGANIZATION
28 29
 )
29 30
 
30 31
 var (
31 32
 	ErrUserOwnRepos          = errors.New("User still have ownership of repositories")
33
+	ErrUserHasOrgs           = errors.New("User still have membership of organization")
32 34
 	ErrUserAlreadyExist      = errors.New("User already exist")
33 35
 	ErrUserNotExist          = errors.New("User does not exist")
34 36
 	ErrUserNotKeyOwner       = errors.New("User does not the owner of public key")
@@ -50,7 +52,8 @@ type User struct {
50 52
 	LoginType     LoginType
51 53
 	LoginSource   int64 `xorm:"not null default 0"`
52 54
 	LoginName     string
53
-	Type          int
55
+	Type          UserType
56
+	Orgs          []*User `xorm:"-"`
54 57
 	NumFollowers  int
55 58
 	NumFollowings int
56 59
 	NumStars      int
@@ -65,43 +68,71 @@ type User struct {
65 68
 	Salt          string    `xorm:"VARCHAR(10)"`
66 69
 	Created       time.Time `xorm:"created"`
67 70
 	Updated       time.Time `xorm:"updated"`
71
+
72
+	// For organization.
73
+	Description string
74
+	NumTeams    int
75
+	NumMembers  int
68 76
 }
69 77
 
70 78
 // HomeLink returns the user home page link.
71
-func (user *User) HomeLink() string {
72
-	return "/user/" + user.Name
79
+func (u *User) HomeLink() string {
80
+	return "/user/" + u.Name
73 81
 }
74 82
 
75 83
 // AvatarLink returns user gravatar link.
76
-func (user *User) AvatarLink() string {
84
+func (u *User) AvatarLink() string {
77 85
 	if setting.DisableGravatar {
78 86
 		return "/img/avatar_default.jpg"
79 87
 	} else if setting.Service.EnableCacheAvatar {
80
-		return "/avatar/" + user.Avatar
88
+		return "/avatar/" + u.Avatar
81 89
 	}
82
-	return "//1.gravatar.com/avatar/" + user.Avatar
90
+	return "//1.gravatar.com/avatar/" + u.Avatar
83 91
 }
84 92
 
85 93
 // NewGitSig generates and returns the signature of given user.
86
-func (user *User) NewGitSig() *git.Signature {
94
+func (u *User) NewGitSig() *git.Signature {
87 95
 	return &git.Signature{
88
-		Name:  user.Name,
89
-		Email: user.Email,
96
+		Name:  u.Name,
97
+		Email: u.Email,
90 98
 		When:  time.Now(),
91 99
 	}
92 100
 }
93 101
 
94 102
 // EncodePasswd encodes password to safe format.
95
-func (user *User) EncodePasswd() {
96
-	newPasswd := base.PBKDF2([]byte(user.Passwd), []byte(user.Salt), 10000, 50, sha256.New)
97
-	user.Passwd = fmt.Sprintf("%x", newPasswd)
103
+func (u *User) EncodePasswd() {
104
+	newPasswd := base.PBKDF2([]byte(u.Passwd), []byte(u.Salt), 10000, 50, sha256.New)
105
+	u.Passwd = fmt.Sprintf("%x", newPasswd)
98 106
 }
99 107
 
100
-// Member represents user is member of organization.
101
-type Member struct {
102
-	Id     int64
103
-	OrgId  int64 `xorm:"unique(member) index"`
104
-	UserId int64 `xorm:"unique(member)"`
108
+func (u *User) IsOrganization() bool {
109
+	return u.Type == ORGANIZATION
110
+}
111
+
112
+func (u *User) GetOrganizations() error {
113
+	ous, err := GetOrgUsersByUserId(u.Id)
114
+	if err != nil {
115
+		return err
116
+	}
117
+
118
+	u.Orgs = make([]*User, len(ous))
119
+	for i, ou := range ous {
120
+		u.Orgs[i], err = GetUserById(ou.OrgId)
121
+		if err != nil {
122
+			return err
123
+		}
124
+	}
125
+	return nil
126
+}
127
+
128
+// GetOwnerTeam returns owner team of organization.
129
+func (org *User) GetOwnerTeam() (*Team, error) {
130
+	t := &Team{
131
+		OrgId: org.Id,
132
+		Name:  OWNER_TEAM,
133
+	}
134
+	_, err := x.Get(t)
135
+	return t, err
105 136
 }
106 137
 
107 138
 // IsUserExist checks if given user name exist,
@@ -126,49 +157,60 @@ func GetUserSalt() string {
126 157
 	return base.GetRandomString(10)
127 158
 }
128 159
 
129
-// RegisterUser creates record of a new user.
130
-func RegisterUser(user *User) (*User, error) {
131
-
132
-	if !IsLegalName(user.Name) {
160
+// CreateUser creates record of a new user.
161
+func CreateUser(u *User) (*User, error) {
162
+	if !IsLegalName(u.Name) {
133 163
 		return nil, ErrUserNameIllegal
134 164
 	}
135 165
 
136
-	isExist, err := IsUserExist(user.Name)
166
+	isExist, err := IsUserExist(u.Name)
137 167
 	if err != nil {
138 168
 		return nil, err
139 169
 	} else if isExist {
140 170
 		return nil, ErrUserAlreadyExist
141 171
 	}
142 172
 
143
-	isExist, err = IsEmailUsed(user.Email)
173
+	isExist, err = IsEmailUsed(u.Email)
144 174
 	if err != nil {
145 175
 		return nil, err
146 176
 	} else if isExist {
147 177
 		return nil, ErrEmailAlreadyUsed
148 178
 	}
149 179
 
150
-	user.LowerName = strings.ToLower(user.Name)
151
-	user.Avatar = base.EncodeMd5(user.Email)
152
-	user.AvatarEmail = user.Email
153
-	user.Rands = GetUserSalt()
154
-	user.Salt = GetUserSalt()
155
-	user.EncodePasswd()
156
-	if _, err = x.Insert(user); err != nil {
180
+	u.LowerName = strings.ToLower(u.Name)
181
+	u.Avatar = base.EncodeMd5(u.Email)
182
+	u.AvatarEmail = u.Email
183
+	u.Rands = GetUserSalt()
184
+	u.Salt = GetUserSalt()
185
+	u.EncodePasswd()
186
+
187
+	sess := x.NewSession()
188
+	defer sess.Close()
189
+	if err = sess.Begin(); err != nil {
190
+		return nil, err
191
+	}
192
+
193
+	if _, err = sess.Insert(u); err != nil {
194
+		sess.Rollback()
157 195
 		return nil, err
158
-	} else if err = os.MkdirAll(UserPath(user.Name), os.ModePerm); err != nil {
159
-		if _, err := x.Id(user.Id).Delete(&User{}); err != nil {
160
-			return nil, errors.New(fmt.Sprintf(
161
-				"both create userpath %s and delete table record faild: %v", user.Name, err))
162
-		}
196
+	}
197
+
198
+	if err = os.MkdirAll(UserPath(u.Name), os.ModePerm); err != nil {
199
+		sess.Rollback()
163 200
 		return nil, err
164 201
 	}
165 202
 
166
-	if user.Id == 1 {
167
-		user.IsAdmin = true
168
-		user.IsActive = true
169
-		_, err = x.Id(user.Id).UseBool().Update(user)
203
+	if err = sess.Commit(); err != nil {
204
+		return nil, err
170 205
 	}
171
-	return user, err
206
+
207
+	// Auto-set admin for user whose ID is 1.
208
+	if u.Id == 1 {
209
+		u.IsAdmin = true
210
+		u.IsActive = true
211
+		_, err = x.Id(u.Id).UseBool().Update(u)
212
+	}
213
+	return u, err
172 214
 }
173 215
 
174 216
 // GetUsers returns given number of user objects with offset.
@@ -277,51 +319,62 @@ func UpdateUser(u *User) (err error) {
277 319
 	if len(u.Website) > 255 {
278 320
 		u.Website = u.Website[:255]
279 321
 	}
322
+	if len(u.Description) > 255 {
323
+		u.Description = u.Description[:255]
324
+	}
280 325
 
281 326
 	_, err = x.Id(u.Id).AllCols().Update(u)
282 327
 	return err
283 328
 }
284 329
 
285 330
 // DeleteUser completely deletes everything of the user.
286
-func DeleteUser(user *User) error {
331
+func DeleteUser(u *User) error {
287 332
 	// Check ownership of repository.
288
-	count, err := GetRepositoryCount(user)
333
+	count, err := GetRepositoryCount(u)
289 334
 	if err != nil {
290
-		return errors.New("modesl.GetRepositories: " + err.Error())
335
+		return errors.New("modesl.GetRepositories(GetRepositoryCount): " + err.Error())
291 336
 	} else if count > 0 {
292 337
 		return ErrUserOwnRepos
293 338
 	}
294 339
 
340
+	// Check membership of organization.
341
+	count, err = GetOrganizationCount(u)
342
+	if err != nil {
343
+		return errors.New("modesl.GetRepositories(GetOrganizationCount): " + err.Error())
344
+	} else if count > 0 {
345
+		return ErrUserHasOrgs
346
+	}
347
+
295 348
 	// TODO: check issues, other repos' commits
296 349
 
297 350
 	// Delete all followers.
298
-	if _, err = x.Delete(&Follow{FollowId: user.Id}); err != nil {
351
+	if _, err = x.Delete(&Follow{FollowId: u.Id}); err != nil {
299 352
 		return err
300 353
 	}
301 354
 
302 355
 	// Delete oauth2.
303
-	if _, err = x.Delete(&Oauth2{Uid: user.Id}); err != nil {
356
+	if _, err = x.Delete(&Oauth2{Uid: u.Id}); err != nil {
304 357
 		return err
305 358
 	}
306 359
 
307 360
 	// Delete all feeds.
308
-	if _, err = x.Delete(&Action{UserId: user.Id}); err != nil {
361
+	if _, err = x.Delete(&Action{UserId: u.Id}); err != nil {
309 362
 		return err
310 363
 	}
311 364
 
312 365
 	// Delete all watches.
313
-	if _, err = x.Delete(&Watch{UserId: user.Id}); err != nil {
366
+	if _, err = x.Delete(&Watch{UserId: u.Id}); err != nil {
314 367
 		return err
315 368
 	}
316 369
 
317 370
 	// Delete all accesses.
318
-	if _, err = x.Delete(&Access{UserName: user.LowerName}); err != nil {
371
+	if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
319 372
 		return err
320 373
 	}
321 374
 
322 375
 	// Delete all SSH keys.
323 376
 	keys := make([]*PublicKey, 0, 10)
324
-	if err = x.Find(&keys, &PublicKey{OwnerId: user.Id}); err != nil {
377
+	if err = x.Find(&keys, &PublicKey{OwnerId: u.Id}); err != nil {
325 378
 		return err
326 379
 	}
327 380
 	for _, key := range keys {
@@ -331,11 +384,11 @@ func DeleteUser(user *User) error {
331 384
 	}
332 385
 
333 386
 	// Delete user directory.
334
-	if err = os.RemoveAll(UserPath(user.Name)); err != nil {
387
+	if err = os.RemoveAll(UserPath(u.Name)); err != nil {
335 388
 		return err
336 389
 	}
337 390
 
338
-	_, err = x.Delete(user)
391
+	_, err = x.Delete(u)
339 392
 	return err
340 393
 }
341 394
 

+ 57 - 0
modules/auth/org.go

@@ -0,0 +1,57 @@
1
+// Copyright 2014 The Gogs Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
5
+package auth
6
+
7
+import (
8
+	"net/http"
9
+	"reflect"
10
+
11
+	"github.com/go-martini/martini"
12
+
13
+	"github.com/gogits/gogs/modules/base"
14
+	"github.com/gogits/gogs/modules/middleware/binding"
15
+)
16
+
17
+type CreateOrgForm struct {
18
+	OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"`
19
+	Email   string `form:"email" binding:"Required;Email;MaxSize(50)"`
20
+}
21
+
22
+func (f *CreateOrgForm) Name(field string) string {
23
+	names := map[string]string{
24
+		"OrgName": "Organization name",
25
+		"Email":   "E-mail address",
26
+	}
27
+	return names[field]
28
+}
29
+
30
+func (f *CreateOrgForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
31
+	data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
32
+	validate(errs, data, f)
33
+}
34
+
35
+type OrgSettingForm struct {
36
+	DisplayName string `form:"display_name" binding:"Required;MaxSize(100)"`
37
+	Email       string `form:"email" binding:"Required;Email;MaxSize(50)"`
38
+	Description string `form:"desc" binding:"MaxSize(255)"`
39
+	Website     string `form:"site" binding:"Url;MaxSize(100)"`
40
+	Location    string `form:"location" binding:"MaxSize(50)"`
41
+}
42
+
43
+func (f *OrgSettingForm) Name(field string) string {
44
+	names := map[string]string{
45
+		"DisplayName": "Display name",
46
+		"Email":       "E-mail address",
47
+		"Description": "Description",
48
+		"Website":     "Website address",
49
+		"Location":    "Location",
50
+	}
51
+	return names[field]
52
+}
53
+
54
+func (f *OrgSettingForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
55
+	data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
56
+	validate(errors, data, f)
57
+}

+ 5 - 3
modules/auth/repo.go

@@ -22,9 +22,10 @@ import (
22 22
 //         \/     \/|__|              \/                       \/
23 23
 
24 24
 type CreateRepoForm struct {
25
+	Uid         int64  `form:"uid" binding:"Required"`
25 26
 	RepoName    string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
26 27
 	Private     bool   `form:"private"`
27
-	Description string `form:"desc" binding:"MaxSize(100)"`
28
+	Description string `form:"desc" binding:"MaxSize(255)"`
28 29
 	Language    string `form:"language"`
29 30
 	License     string `form:"license"`
30 31
 	InitReadme  bool   `form:"initReadme"`
@@ -47,10 +48,11 @@ type MigrateRepoForm struct {
47 48
 	Url          string `form:"url" binding:"Url"`
48 49
 	AuthUserName string `form:"auth_username"`
49 50
 	AuthPasswd   string `form:"auth_password"`
51
+	Uid          int64  `form:"uid" binding:"Required"`
50 52
 	RepoName     string `form:"repo" binding:"Required;AlphaDash;MaxSize(100)"`
51 53
 	Mirror       bool   `form:"mirror"`
52 54
 	Private      bool   `form:"private"`
53
-	Description  string `form:"desc" binding:"MaxSize(100)"`
55
+	Description  string `form:"desc" binding:"MaxSize(255)"`
54 56
 }
55 57
 
56 58
 func (f *MigrateRepoForm) Name(field string) string {
@@ -69,7 +71,7 @@ func (f *MigrateRepoForm) Validate(errors *binding.Errors, req *http.Request, co
69 71
 
70 72
 type RepoSettingForm struct {
71 73
 	RepoName    string `form:"name" binding:"Required;AlphaDash;MaxSize(100)"`
72
-	Description string `form:"desc" binding:"MaxSize(100)"`
74
+	Description string `form:"desc" binding:"MaxSize(255)"`
73 75
 	Website     string `form:"site" binding:"Url;MaxSize(100)"`
74 76
 	Branch      string `form:"branch"`
75 77
 	Interval    int    `form:"interval"`

+ 16 - 14
modules/auth/user.go

@@ -25,23 +25,25 @@ func SignedInId(header http.Header, sess session.SessionStore) int64 {
25 25
 		return 0
26 26
 	}
27 27
 
28
-	var id int64
29 28
 	if setting.Service.EnableReverseProxyAuth {
30
-		id, _ = base.StrTo(header.Get(setting.ReverseProxyAuthUid)).Int64()
31
-	}
32
-
33
-	if id <= 0 {
34
-		uid := sess.Get("userId")
35
-		if uid == nil {
36
-			return 0
37
-		}
38
-		var ok bool
39
-		if id, ok = uid.(int64); !ok {
40
-			return 0
29
+		webAuthUser := header.Get(setting.ReverseProxyAuthUser)
30
+		if len(webAuthUser) > 0 {
31
+			u, err := models.GetUserByName(webAuthUser)
32
+			if err != nil {
33
+				if err != models.ErrUserNotExist {
34
+					log.Error("auth.user.SignedInId(GetUserByName): %v", err)
35
+				}
36
+				return 0
37
+			}
38
+			return u.Id
41 39
 		}
42 40
 	}
43 41
 
44
-	if id > 0 {
42
+	uid := sess.Get("userId")
43
+	if uid == nil {
44
+		return 0
45
+	}
46
+	if id, ok := uid.(int64); ok {
45 47
 		if _, err := models.GetUserById(id); err != nil {
46 48
 			if err != models.ErrUserNotExist {
47 49
 				log.Error("auth.user.SignedInId(GetUserById): %v", err)
@@ -91,7 +93,7 @@ func (f *UpdateProfileForm) Name(field string) string {
91 93
 	names := map[string]string{
92 94
 		"UserName": "Username",
93 95
 		"Email":    "E-mail address",
94
-		"Website":  "Website",
96
+		"Website":  "Website address",
95 97
 		"Location": "Location",
96 98
 		"Avatar":   "Gravatar Email",
97 99
 	}

+ 1 - 0
modules/base/base.go

@@ -7,6 +7,7 @@ package base
7 7
 type (
8 8
 	// Type TmplData represents data in the templates.
9 9
 	TmplData map[string]interface{}
10
+	TplName  string
10 11
 
11 12
 	ApiJsonErr struct {
12 13
 		Message string `json:"message"`

+ 235 - 236
modules/bin/conf.go

@@ -28,242 +28,241 @@ func bindata_read(data []byte, name string) ([]byte, error) {
28 28
 func conf_app_ini() ([]byte, error) {
29 29
 	return bindata_read([]byte{
30 30
 		0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0xb4, 0x59,
31
-		0xdd, 0x72, 0xdb, 0xc8, 0xb1, 0xbe, 0xc7, 0x53, 0x8c, 0x79, 0x76, 0xcf,
32
-		0xda, 0xa7, 0x24, 0x92, 0x92, 0x8f, 0x65, 0xaf, 0xbc, 0xae, 0x63, 0x8a,
33
-		0x04, 0x25, 0x1c, 0xf3, 0x47, 0x0b, 0x40, 0xf2, 0x2a, 0x2e, 0x15, 0x0a,
34
-		0x02, 0x86, 0xe4, 0x44, 0x00, 0x06, 0xc2, 0x0c, 0x45, 0x31, 0x77, 0x79,
35
-		0x85, 0x54, 0x9e, 0x26, 0xcf, 0x93, 0x8b, 0x3c, 0x46, 0xbe, 0x1e, 0x00,
36
-		0x14, 0x28, 0x73, 0xb5, 0xce, 0x5f, 0x25, 0x65, 0x11, 0xf3, 0xd3, 0xd3,
37
-		0xdd, 0xf3, 0xf5, 0xd7, 0xdd, 0xb3, 0xef, 0x59, 0x2f, 0xcf, 0x59, 0x16,
38
-		0xa6, 0x9c, 0xe9, 0x45, 0xa8, 0x99, 0x5a, 0xc8, 0x95, 0x62, 0x32, 0x63,
39
-		0xfc, 0x9e, 0x17, 0x6b, 0x96, 0x87, 0x73, 0x4c, 0x08, 0x9d, 0x70, 0xab,
40
-		0x77, 0x7e, 0x1e, 0x4c, 0x7a, 0x63, 0x9b, 0x7d, 0x60, 0xa7, 0x72, 0xae,
41
-		0x8e, 0xf1, 0x2f, 0x3b, 0x15, 0x9a, 0x79, 0xbc, 0xb8, 0x17, 0x51, 0x39,
42
-		0x3f, 0x9a, 0x9e, 0x4e, 0x31, 0x2f, 0xd2, 0x79, 0x67, 0x16, 0x62, 0x54,
43
-		0x66, 0xed, 0x3c, 0x9b, 0x5b, 0xef, 0x59, 0x7f, 0x11, 0x66, 0x90, 0x84,
44
-		0xe5, 0x62, 0xc6, 0xd6, 0x72, 0xc9, 0x8a, 0x65, 0xc6, 0x12, 0x19, 0x85,
45
-		0x49, 0xb2, 0xb6, 0xdc, 0x8b, 0x49, 0x70, 0xe1, 0xd9, 0x2e, 0x76, 0xce,
46
-		0x85, 0xc6, 0x6a, 0x5b, 0xe8, 0x05, 0x2f, 0x58, 0x2b, 0xe6, 0xf7, 0xad,
47
-		0x3d, 0xd6, 0xca, 0x0b, 0x19, 0xb7, 0x98, 0xc4, 0x80, 0xe6, 0x4a, 0x63,
48
-		0x24, 0xe6, 0xb3, 0x70, 0x99, 0x40, 0x96, 0x2a, 0xd7, 0x18, 0x09, 0xe3,
49
-		0xe9, 0x80, 0x74, 0xc3, 0xb7, 0x65, 0x7d, 0x29, 0x78, 0x2e, 0x95, 0xd0,
50
-		0xb2, 0x58, 0x5f, 0x5b, 0xee, 0x74, 0xea, 0x63, 0xc2, 0xf2, 0xfa, 0xae,
51
-		0x73, 0xee, 0x07, 0xfe, 0xd5, 0x39, 0xad, 0xbb, 0x09, 0xd5, 0x02, 0x0b,
52
-		0x15, 0xb4, 0xe7, 0xc5, 0xb5, 0x75, 0xee, 0x4e, 0xfd, 0x69, 0x7f, 0x3a,
53
-		0xc2, 0xcc, 0x42, 0xeb, 0xdc, 0x1a, 0x4c, 0xc7, 0x3d, 0x67, 0x82, 0x2f,
54
-		0xa3, 0xe4, 0x42, 0x2a, 0x6d, 0xe4, 0x04, 0x17, 0x2e, 0x2d, 0xf9, 0xfe,
55
-		0x65, 0xbd, 0xfe, 0x95, 0x3a, 0xee, 0x74, 0xbe, 0x7f, 0x59, 0x2e, 0xc7,
56
-		0xc7, 0xf7, 0x2f, 0xcf, 0x7c, 0xff, 0x3c, 0x38, 0x9f, 0xba, 0xfe, 0x2b,
57
-		0xd5, 0xb1, 0xcc, 0x47, 0x6f, 0x30, 0x20, 0xdb, 0xac, 0xcd, 0x0c, 0x3e,
58
-		0x5e, 0x77, 0xbb, 0x5d, 0xcb, 0xf3, 0xce, 0xea, 0xef, 0xc3, 0x43, 0xd8,
59
-		0x3d, 0x10, 0x2a, 0xbc, 0x49, 0x38, 0xeb, 0x0f, 0x26, 0xe4, 0xff, 0x8c,
60
-		0x89, 0xac, 0xb6, 0x3e, 0x95, 0x31, 0xb7, 0xa6, 0xc3, 0xe1, 0xc8, 0x99,
61
-		0xd8, 0xb5, 0xa9, 0xb3, 0x30, 0x51, 0xdc, 0x1a, 0x38, 0x5e, 0xef, 0x64,
62
-		0x64, 0x07, 0xee, 0xf4, 0xc2, 0xb7, 0x5d, 0xba, 0x82, 0xcd, 0xd4, 0x7b,
63
-		0x76, 0xca, 0x33, 0x5e, 0x84, 0x9a, 0x33, 0xa5, 0x79, 0xae, 0x8e, 0x31,
64
-		0xf2, 0x1d, 0x8b, 0x62, 0x5c, 0xab, 0x5e, 0x74, 0xb4, 0xec, 0xcc, 0x71,
65
-		0x91, 0x9d, 0x68, 0xa9, 0xb4, 0x4c, 0x3b, 0x64, 0xb6, 0x32, 0x0b, 0xe6,
66
-		0xd2, 0x5c, 0xcf, 0x77, 0xa7, 0x53, 0x32, 0xb9, 0xa3, 0x8a, 0xa8, 0x93,
67
-		0xdf, 0xce, 0x3b, 0x51, 0xb1, 0xce, 0xb1, 0x47, 0x27, 0xaa, 0x33, 0xaf,
68
-		0xc4, 0x06, 0x11, 0x2f, 0x74, 0x1b, 0xeb, 0xf7, 0xa3, 0xf0, 0x83, 0x2e,
69
-		0x96, 0x9c, 0xed, 0xc7, 0x4b, 0x4c, 0x08, 0x99, 0x7d, 0x78, 0xf7, 0xf6,
70
-		0xa8, 0xbb, 0xe8, 0xa6, 0x5d, 0xc5, 0xf6, 0xc9, 0x7d, 0x1f, 0xd2, 0x35,
71
-		0xfd, 0x69, 0xf3, 0x87, 0x30, 0xcd, 0x13, 0xde, 0x8e, 0x64, 0x6a, 0xf5,
72
-		0x6d, 0xd7, 0x0f, 0x86, 0xce, 0x88, 0x8c, 0x69, 0x6a, 0xd1, 0x31, 0x62,
73
-		0x73, 0x9e, 0x5a, 0x9f, 0xec, 0xab, 0x9d, 0x0b, 0x6e, 0xf9, 0xda, 0xcc,
74
-		0xbf, 0x67, 0x17, 0x79, 0x0e, 0xa8, 0x24, 0x70, 0x57, 0xc2, 0xe4, 0x8c,
75
-		0x69, 0x0e, 0xe9, 0x64, 0x70, 0x98, 0xc5, 0x30, 0x1a, 0xaa, 0x44, 0x6c,
76
-		0x26, 0xe0, 0x53, 0x32, 0x19, 0xcb, 0x1b, 0xd0, 0x01, 0xc6, 0xcc, 0x28,
77
-		0x5b, 0x01, 0x6c, 0xdc, 0x80, 0x9a, 0x86, 0xf9, 0x03, 0x8f, 0x96, 0x9a,
78
-		0xc7, 0x96, 0xe7, 0xf7, 0x7c, 0xa7, 0x1f, 0x98, 0x6b, 0x3f, 0xef, 0xf9,
79
-		0x67, 0x74, 0x85, 0xd6, 0x97, 0x38, 0xd4, 0x21, 0xb0, 0xc3, 0xaf, 0x1b,
80
-		0x38, 0x4d, 0xd7, 0xea, 0x2e, 0x31, 0x48, 0x85, 0x85, 0xf3, 0x82, 0xab,
81
-		0x12, 0xad, 0x18, 0x14, 0x9a, 0xbf, 0xc6, 0x84, 0xd0, 0x3f, 0x28, 0x82,
82
-		0x7d, 0xc1, 0xa2, 0x85, 0xa4, 0x60, 0x19, 0x9c, 0xd4, 0x38, 0x34, 0x7b,
83
-		0xad, 0xb3, 0xa9, 0x47, 0x28, 0x38, 0x38, 0x7c, 0xdb, 0xee, 0xe2, 0x7f,
84
-		0x07, 0xc7, 0xaf, 0x5f, 0x77, 0x8f, 0xac, 0x2a, 0xdc, 0xe8, 0x96, 0xac,
85
-		0x2a, 0x40, 0x0a, 0x29, 0xb5, 0x75, 0xde, 0xf3, 0xbc, 0xcf, 0x03, 0xf6,
86
-		0x01, 0x2a, 0x0c, 0xe9, 0xa0, 0xc6, 0xb1, 0x59, 0xb2, 0xde, 0x63, 0xbc,
87
-		0x8e, 0x9f, 0x12, 0x4f, 0xa4, 0x59, 0xc1, 0xef, 0x96, 0xa2, 0xe0, 0xa5,
88
-		0x62, 0x40, 0xbc, 0x98, 0xad, 0xf7, 0x67, 0xcb, 0x24, 0x69, 0x01, 0x84,
89
-		0xa3, 0x4d, 0xec, 0x94, 0xeb, 0x6b, 0xb1, 0xb5, 0xfe, 0x46, 0xaa, 0x55,
90
-		0xb9, 0x80, 0xec, 0x37, 0xb8, 0x69, 0xc7, 0x37, 0x70, 0x47, 0x18, 0xa7,
91
-		0x22, 0xbb, 0x36, 0x81, 0x14, 0x2d, 0x0b, 0xa1, 0x11, 0x6f, 0xce, 0x04,
92
-		0x9e, 0x1b, 0x8d, 0x80, 0xc4, 0xfe, 0xa7, 0x06, 0x14, 0x5f, 0xbc, 0xe8,
93
-		0x9f, 0xf5, 0x26, 0xa7, 0x36, 0xf3, 0xcf, 0x1c, 0x8f, 0xf9, 0x53, 0xf6,
94
-		0xc9, 0xb6, 0xcf, 0xd9, 0xd5, 0xf4, 0xc2, 0x65, 0xc6, 0xb6, 0x41, 0xcf,
95
-		0xef, 0x31, 0xaf, 0x37, 0xb4, 0x5f, 0xbc, 0xb0, 0x3c, 0xbb, 0xef, 0xda,
96
-		0x7e, 0x80, 0xdb, 0x87, 0x80, 0x17, 0xff, 0xf5, 0x71, 0x38, 0xb0, 0x3f,
97
-		0xbb, 0xf8, 0xff, 0x7f, 0xff, 0xcf, 0x4b, 0x48, 0xea, 0x2d, 0xb5, 0xdc,
98
-		0x4f, 0xe4, 0x1c, 0xd1, 0x51, 0xf0, 0x94, 0xa7, 0x37, 0xb0, 0x35, 0x0e,
99
-		0xd7, 0xca, 0x02, 0xf6, 0x9d, 0x49, 0xe0, 0xda, 0x63, 0x7b, 0x7c, 0x82,
100
-		0x50, 0x18, 0xf4, 0xae, 0x3c, 0xec, 0x7f, 0x6b, 0xf5, 0xa7, 0xd3, 0x4f,
101
-		0x8e, 0x6d, 0x38, 0xa6, 0xe1, 0xd2, 0x20, 0x5c, 0x71, 0x25, 0x53, 0x5e,
102
-		0x4f, 0x6f, 0xf6, 0x35, 0xd7, 0x88, 0x2c, 0x2a, 0x78, 0x2c, 0x4a, 0xaf,
103
-		0xb8, 0x44, 0x8a, 0x0a, 0xa8, 0x29, 0xe4, 0xc3, 0x9a, 0x85, 0x4b, 0x78,
104
-		0x39, 0x03, 0xc0, 0x0c, 0xde, 0xd9, 0x82, 0x87, 0x31, 0x14, 0x31, 0x54,
105
-		0x0a, 0x20, 0x2e, 0xc1, 0x2c, 0xcc, 0x19, 0x58, 0xae, 0x7d, 0x69, 0xbb,
106
-		0x9e, 0x1d, 0x80, 0x30, 0x7e, 0xb9, 0x0a, 0x7a, 0x17, 0xfe, 0x99, 0x3d,
107
-		0x01, 0xac, 0x00, 0xad, 0x29, 0x58, 0xcf, 0xc1, 0x2d, 0xb2, 0x5f, 0xf6,
108
-		0x3f, 0xdb, 0x27, 0x34, 0xb3, 0x8f, 0xef, 0x8a, 0x93, 0x00, 0x92, 0x6b,
109
-		0xab, 0xd7, 0xf7, 0x9d, 0x4b, 0x3b, 0xe8, 0xe3, 0x76, 0x82, 0x11, 0xfd,
110
-		0x1a, 0x3b, 0x13, 0x04, 0x39, 0x19, 0x75, 0xf0, 0xae, 0x0b, 0xd1, 0x9e,
111
-		0x4d, 0xd0, 0x24, 0x30, 0xfc, 0xea, 0x22, 0x44, 0x08, 0x69, 0x92, 0x71,
112
-		0x1e, 0x33, 0x2d, 0x19, 0x28, 0x79, 0x26, 0x8a, 0x94, 0xf1, 0xfd, 0x34,
113
-		0x14, 0x09, 0x9b, 0xe1, 0x9e, 0x0b, 0x3e, 0x17, 0x4a, 0x97, 0x51, 0x0b,
114
-		0x99, 0xa7, 0x8e, 0x47, 0x3c, 0x62, 0x83, 0xd0, 0x46, 0x90, 0x3a, 0x19,
115
-		0x3a, 0xee, 0xb8, 0x71, 0x8d, 0x03, 0xc9, 0x15, 0xcb, 0xa4, 0x66, 0xa0,
116
-		0x6e, 0xb9, 0xaa, 0x36, 0xe3, 0x00, 0x8a, 0x37, 0x03, 0x06, 0x06, 0x87,
117
-		0x99, 0x00, 0x8c, 0x22, 0xb9, 0xcc, 0x74, 0x09, 0x9e, 0x0d, 0x49, 0x19,
118
-		0xf1, 0xae, 0xb1, 0xbe, 0x21, 0xd4, 0xa8, 0x98, 0x22, 0xc0, 0x99, 0x12,
119
-		0x73, 0x43, 0x7b, 0x50, 0xf5, 0x5e, 0xf0, 0x15, 0xc4, 0xae, 0xf5, 0x42,
120
-		0x64, 0xf3, 0x36, 0x34, 0xfb, 0xf9, 0xc2, 0x71, 0xed, 0xc0, 0x73, 0x4e,
121
-		0x27, 0xb8, 0xe5, 0x4b, 0xc7, 0xfe, 0xdc, 0x90, 0xd0, 0x0f, 0x23, 0x84,
122
-		0x73, 0x78, 0x0f, 0x74, 0x42, 0x17, 0xc5, 0x72, 0x11, 0xe9, 0x65, 0xc1,
123
-		0x2d, 0x7b, 0x62, 0xce, 0xed, 0xf7, 0xfa, 0x67, 0x76, 0xd0, 0xbb, 0x04,
124
-		0xc6, 0xdc, 0xc6, 0xae, 0x31, 0xf9, 0x00, 0xc6, 0x88, 0x59, 0x75, 0x8b,
125
-		0xf5, 0xfa, 0xc9, 0xd4, 0x77, 0x86, 0x57, 0x01, 0xf9, 0xa0, 0xb9, 0x5c,
126
-		0x82, 0x27, 0x62, 0xae, 0xb1, 0xeb, 0xd8, 0xa4, 0x09, 0x22, 0x7f, 0xa4,
127
-		0xac, 0xc5, 0xf2, 0x86, 0xf8, 0x8c, 0xc2, 0x42, 0x68, 0x55, 0xb2, 0xaa,
128
-		0x50, 0x6a, 0xc9, 0x55, 0xe7, 0xe0, 0xe8, 0x4d, 0x2d, 0xf3, 0x39, 0x24,
129
-		0x6c, 0x0e, 0xb1, 0xbe, 0xac, 0xf8, 0xcd, 0x42, 0xca, 0x5b, 0xe2, 0x97,
130
-		0x7e, 0x01, 0x5c, 0xe9, 0x50, 0xdd, 0xc2, 0x23, 0xf0, 0xf1, 0x7d, 0x98,
131
-		0x90, 0x6b, 0xe0, 0x63, 0xf0, 0x93, 0xb2, 0xfc, 0x9e, 0xf7, 0x29, 0x70,
132
-		0x26, 0xb8, 0xac, 0xcb, 0x1e, 0x69, 0x79, 0x40, 0xb7, 0xc3, 0x13, 0x01,
133
-		0x8c, 0x22, 0x65, 0xa7, 0x5c, 0x2e, 0x35, 0x2d, 0x47, 0x60, 0xca, 0x2c,
134
-		0x56, 0xd6, 0xc0, 0x26, 0x74, 0xb8, 0x81, 0xef, 0x8c, 0x6d, 0xa4, 0x0a,
135
-		0x6c, 0x78, 0x83, 0xd3, 0x08, 0x05, 0x94, 0xff, 0x4a, 0x1d, 0x07, 0x0d,
136
-		0x63, 0x4f, 0x96, 0xb3, 0x99, 0x61, 0xd6, 0x6c, 0x0e, 0x8e, 0x04, 0xa2,
137
-		0x23, 0xe4, 0xf0, 0x8c, 0x27, 0x7b, 0xec, 0x96, 0xf3, 0x9c, 0x52, 0x39,
138
-		0xdc, 0x2c, 0x0c, 0x93, 0x56, 0x39, 0x3d, 0x96, 0xd9, 0x0f, 0x9a, 0xdd,
139
-		0x66, 0x80, 0xc5, 0x8a, 0x6a, 0x09, 0x33, 0xd9, 0x46, 0x30, 0x4f, 0x06,
140
-		0xc1, 0xc9, 0xc5, 0x70, 0x48, 0xd9, 0xc9, 0x26, 0x53, 0x0f, 0x08, 0x96,
141
-		0x13, 0x0a, 0x14, 0x30, 0x0e, 0xe8, 0x7a, 0x0d, 0x6c, 0x92, 0x61, 0x74,
142
-		0x1b, 0x65, 0xb1, 0xe1, 0x5d, 0x9c, 0xfc, 0xbf, 0xdd, 0xf7, 0x4d, 0xaa,
143
-		0xad, 0x0b, 0x8f, 0x57, 0xaa, 0xbe, 0xb1, 0x32, 0x69, 0x53, 0x7a, 0x4b,
144
-		0xcd, 0x55, 0xa8, 0x54, 0xe7, 0xed, 0x39, 0xfd, 0xa6, 0x6b, 0x38, 0x7e,
145
-		0xf3, 0xee, 0x2d, 0xe6, 0x7e, 0xfe, 0xb9, 0x9a, 0xb8, 0xbb, 0x33, 0xa3,
146
-		0x87, 0x6f, 0x6a, 0x96, 0xad, 0xc5, 0xcc, 0x0a, 0x99, 0x02, 0xb3, 0x31,
147
-		0x98, 0x53, 0x59, 0x43, 0x77, 0x3a, 0x7e, 0x9c, 0x83, 0xe1, 0x26, 0x80,
148
-		0x4d, 0x34, 0x13, 0xb4, 0xf3, 0x50, 0xa9, 0x95, 0x2c, 0xe2, 0x9a, 0x87,
149
-		0x37, 0x1c, 0x4c, 0x39, 0x41, 0x12, 0x15, 0x7c, 0xed, 0xc3, 0x6a, 0xa2,
150
-		0x5d, 0x22, 0xe4, 0xeb, 0xf9, 0xfe, 0xc8, 0x01, 0x02, 0x02, 0xc3, 0x01,
151
-		0xf5, 0x47, 0xc9, 0x7c, 0x65, 0xb9, 0x32, 0x3d, 0x37, 0x51, 0x5c, 0x03,
152
-		0x2d, 0xcc, 0x45, 0xbb, 0x01, 0x36, 0xd2, 0xcf, 0x22, 0x14, 0x55, 0x35,
153
-		0xc9, 0x0e, 0x3c, 0x1a, 0x8e, 0xec, 0x18, 0x25, 0x3a, 0xf4, 0x8f, 0x2c,
154
-		0xc4, 0x1f, 0xb8, 0xe5, 0x4f, 0x3f, 0xd9, 0x93, 0x6f, 0xdc, 0x14, 0x45,
155
-		0xf0, 0x4d, 0xa0, 0xe5, 0x2d, 0xcf, 0x2c, 0x53, 0x4e, 0x68, 0x16, 0x25,
156
-		0x02, 0xac, 0xc7, 0x44, 0x5c, 0xa6, 0x58, 0x8e, 0x70, 0xd7, 0xc6, 0x95,
157
-		0x98, 0xaf, 0xc5, 0x01, 0x71, 0x4a, 0x22, 0xc9, 0xc7, 0x94, 0x96, 0x25,
158
-		0x12, 0xb4, 0x42, 0x91, 0x20, 0xe7, 0x65, 0xda, 0xef, 0x80, 0x3e, 0x7f,
159
-		0xcf, 0x23, 0xbd, 0x71, 0x8f, 0x99, 0xf9, 0x97, 0xdd, 0xb3, 0x5a, 0xad,
160
-		0x2a, 0x51, 0x70, 0x94, 0x32, 0x07, 0x19, 0x1b, 0xc8, 0x4f, 0x22, 0x9b,
161
-		0xc9, 0x36, 0x37, 0xf8, 0xfa, 0xe6, 0xe5, 0xd0, 0x92, 0x0a, 0x87, 0x5d,
162
-		0x2e, 0xae, 0xa8, 0x6d, 0xcb, 0x28, 0x59, 0xba, 0xec, 0xd0, 0x48, 0xd9,
163
-		0xe9, 0xe3, 0x67, 0x77, 0x55, 0x2e, 0xae, 0x5c, 0x72, 0x77, 0xf7, 0x4f,
164
-		0xbb, 0x03, 0xb4, 0x6c, 0xc0, 0xcf, 0xfe, 0xfa, 0x97, 0x3f, 0xfd, 0xed,
165
-		0x8f, 0x7f, 0xa6, 0x74, 0xb9, 0x03, 0x23, 0x45, 0x98, 0x2f, 0xaa, 0xc0,
166
-		0xa8, 0x34, 0x68, 0x77, 0x1b, 0x10, 0x79, 0xcf, 0x76, 0x82, 0x64, 0xe7,
167
-		0xae, 0x52, 0x73, 0xec, 0xe0, 0x59, 0x44, 0xc0, 0x58, 0x71, 0x71, 0x23,
168
-		0x77, 0x79, 0x0d, 0x38, 0xc8, 0xda, 0xba, 0xde, 0x1f, 0xcd, 0xc5, 0xfe,
169
-		0x4d, 0x0d, 0xb4, 0xc3, 0xdf, 0x80, 0xe7, 0xf3, 0x5b, 0xb7, 0x40, 0x5a,
170
-		0x79, 0x50, 0xaf, 0x84, 0xd6, 0xbb, 0x88, 0xed, 0x1f, 0x70, 0xe3, 0xae,
171
-		0x9b, 0x47, 0x0c, 0x56, 0xa2, 0x1f, 0xbd, 0xf0, 0x1b, 0xca, 0xff, 0xca,
172
-		0x9e, 0x5d, 0x5a, 0x1b, 0xdf, 0xfd, 0x27, 0x74, 0x36, 0x82, 0x1b, 0xf7,
173
-		0xf6, 0x0d, 0x2a, 0x7f, 0xbd, 0x65, 0x5b, 0xe3, 0x88, 0x32, 0xee, 0x56,
174
-		0x15, 0xcc, 0x53, 0xf4, 0x5b, 0x65, 0xb1, 0x09, 0x5e, 0xc7, 0x0f, 0x59,
175
-		0x8e, 0x9a, 0x95, 0x4f, 0xda, 0xb6, 0x6a, 0xb1, 0xd5, 0x1b, 0xf4, 0xce,
176
-		0x7d, 0xc3, 0xa8, 0xe5, 0x48, 0x5d, 0x7b, 0x56, 0xf3, 0x55, 0x41, 0x7b,
177
-		0xda, 0xdf, 0xca, 0x80, 0x55, 0x4a, 0xdb, 0x92, 0x78, 0xd4, 0xb5, 0x1a,
178
-		0xb9, 0xf0, 0xa8, 0x5b, 0x0b, 0x2a, 0x75, 0x31, 0x5c, 0xd5, 0xd4, 0x05,
179
-		0x02, 0x32, 0x70, 0x90, 0x29, 0xdc, 0x50, 0x3d, 0x6f, 0xd2, 0xc0, 0x7b,
180
-		0x66, 0x36, 0x1c, 0xb3, 0xd6, 0xf1, 0x51, 0xf7, 0xf5, 0x8f, 0x2d, 0x0c,
181
-		0xd4, 0xbb, 0x30, 0xf6, 0x58, 0x9f, 0x1f, 0x1c, 0x1c, 0x1e, 0x1c, 0xb4,
182
-		0xaa, 0x8c, 0x62, 0x6a, 0x36, 0xa5, 0x20, 0x6c, 0xb7, 0x3f, 0x88, 0x47,
183
-		0x1e, 0xfd, 0x52, 0xba, 0xa5, 0x6a, 0x19, 0x76, 0xf9, 0x04, 0x05, 0xc2,
184
-		0xa5, 0x33, 0x30, 0x4e, 0x31, 0x0c, 0xf4, 0x9e, 0x9d, 0x17, 0xf2, 0x5e,
185
-		0x50, 0x75, 0x69, 0xca, 0xb7, 0x39, 0x93, 0x39, 0x69, 0xae, 0x4a, 0xe5,
186
-		0xb0, 0xe7, 0xd8, 0x54, 0x64, 0x8b, 0xf0, 0x9e, 0x92, 0xd5, 0xba, 0x5e,
187
-		0xb5, 0xe6, 0xd4, 0x4c, 0x93, 0x08, 0x64, 0xc2, 0x52, 0xbf, 0xc7, 0x5e,
188
-		0x08, 0x5d, 0x42, 0x7b, 0xde, 0x46, 0x8f, 0x40, 0xf5, 0x7c, 0x35, 0xab,
189
-		0x5a, 0x8f, 0xf6, 0x57, 0x32, 0x12, 0x71, 0xcb, 0xcb, 0xa1, 0x2a, 0xeb,
190
-		0x1a, 0x4f, 0xed, 0xb1, 0x5c, 0xca, 0xc4, 0x03, 0x7c, 0xf6, 0x36, 0x99,
191
-		0xb1, 0x16, 0xf8, 0xe8, 0xa3, 0xa3, 0xd7, 0x6f, 0x7f, 0xdc, 0x3b, 0xe8,
192
-		0x76, 0xf7, 0x42, 0x34, 0x62, 0x0f, 0x82, 0x1b, 0x67, 0x92, 0xdd, 0xc7,
193
-		0xa8, 0xad, 0xf7, 0xf1, 0x77, 0x3f, 0x2e, 0xa8, 0x5a, 0xe9, 0x98, 0x41,
194
-		0x16, 0xab, 0xac, 0x3e, 0x15, 0xe5, 0x28, 0x6a, 0xbe, 0x5a, 0x22, 0xf5,
195
-		0x3c, 0xc7, 0xf5, 0x31, 0x1f, 0x6b, 0x65, 0x03, 0x6d, 0x7a, 0x9b, 0x8d,
196
-		0xb7, 0xca, 0x5a, 0xf5, 0xb4, 0x6e, 0x51, 0x6a, 0x93, 0x70, 0xa6, 0x57,
197
-		0xd9, 0x1e, 0xa1, 0xac, 0x12, 0xdc, 0xe4, 0xf4, 0xba, 0xe6, 0xaf, 0x4a,
198
-		0x7d, 0x11, 0x90, 0x9d, 0x41, 0x59, 0xbf, 0x61, 0x87, 0x53, 0x16, 0x34,
199
-		0xc8, 0x05, 0x1b, 0xc7, 0x01, 0x76, 0x26, 0x3a, 0x2a, 0x44, 0x36, 0xee,
200
-		0xad, 0x8a, 0xd1, 0x52, 0x20, 0xc2, 0xf2, 0xc2, 0xb5, 0x1b, 0x65, 0x94,
201
-		0x9d, 0x99, 0x96, 0x5e, 0x51, 0xe6, 0x34, 0xe7, 0x6f, 0xed, 0xa5, 0x9e,
202
-		0xb9, 0xae, 0x0f, 0xa9, 0x98, 0x2f, 0xa5, 0x60, 0xbb, 0x99, 0x78, 0x54,
203
-		0x1d, 0x01, 0x40, 0x25, 0xdd, 0x26, 0x0a, 0xb6, 0x84, 0xbc, 0x3b, 0xfa,
204
-		0xdf, 0x6e, 0xd7, 0x3a, 0xed, 0x6f, 0x8a, 0x41, 0x53, 0xe3, 0x41, 0x48,
205
-		0x39, 0xf1, 0x28, 0x25, 0x11, 0x33, 0x6e, 0xe4, 0xec, 0xd8, 0xee, 0xd9,
206
-		0x9e, 0x47, 0x2d, 0xc9, 0xc8, 0x19, 0xda, 0x4f, 0xf7, 0x6f, 0x7c, 0x10,
207
-		0x03, 0x63, 0x6a, 0xc1, 0x66, 0xcb, 0x2c, 0xda, 0xdb, 0xe0, 0x5c, 0x2d,
208
-		0xc2, 0x03, 0x42, 0x37, 0xfe, 0x1e, 0xbe, 0x39, 0xaa, 0xe0, 0x1d, 0xbf,
209
-		0x69, 0x35, 0xcf, 0xa0, 0x35, 0x9b, 0x23, 0x9c, 0x41, 0x70, 0xd6, 0xf3,
210
-		0xce, 0x86, 0x17, 0x93, 0x3e, 0x0e, 0x31, 0x53, 0x8f, 0x3a, 0x9a, 0x03,
211
-		0xd0, 0xde, 0x6f, 0xa9, 0x48, 0x17, 0x51, 0x20, 0x84, 0x51, 0xaf, 0x95,
212
-		0xd0, 0x78, 0x2a, 0xcb, 0x74, 0x8a, 0x08, 0xc3, 0xaa, 0xec, 0xa7, 0x30,
213
-		0xf4, 0xa9, 0xbd, 0x4f, 0xc2, 0x88, 0x53, 0x2f, 0x51, 0x8d, 0x1b, 0x68,
214
-		0x3c, 0xf6, 0xc7, 0x25, 0xa2, 0x4b, 0x8d, 0xef, 0x44, 0x26, 0x96, 0x4f,
215
-		0x02, 0xb2, 0x9a, 0xc7, 0x61, 0xee, 0xa5, 0xd3, 0x27, 0x8f, 0x54, 0x95,
216
-		0x67, 0xdd, 0xce, 0x9c, 0xba, 0x4f, 0x5a, 0x0a, 0xeb, 0x0b, 0xca, 0xa7,
217
-		0xf2, 0xc9, 0xa9, 0x7a, 0x33, 0x68, 0x10, 0x42, 0x55, 0x15, 0x35, 0x19,
218
-		0x81, 0x68, 0xc8, 0xf8, 0x0e, 0x85, 0x6a, 0xa9, 0x47, 0xfd, 0xbe, 0xf0,
219
-		0x44, 0x95, 0x7a, 0x6f, 0xd9, 0x2c, 0x01, 0x4a, 0x69, 0x1a, 0x92, 0x61,
220
-		0x8a, 0xe7, 0xa1, 0x79, 0xe0, 0x49, 0xb1, 0x52, 0xe4, 0x40, 0x1a, 0xbd,
221
-		0x14, 0xa9, 0x3a, 0x74, 0xaa, 0x6d, 0x7b, 0x26, 0xee, 0x5b, 0x56, 0xd5,
222
-		0xe7, 0x57, 0xa3, 0xff, 0xce, 0x22, 0xff, 0x49, 0x7d, 0xdf, 0x35, 0xb8,
223
-		0xa9, 0x0d, 0xf7, 0x0b, 0x5c, 0x03, 0x99, 0x39, 0xe0, 0x37, 0xcb, 0x39,
224
-		0xfd, 0x70, 0x50, 0x61, 0xd1, 0xdf, 0xcf, 0x61, 0x61, 0xec, 0xb7, 0x8b,
225
-		0x42, 0x16, 0xf4, 0xa3, 0x5f, 0x08, 0xea, 0xa8, 0x9f, 0x52, 0x63, 0x29,
226
-		0xc1, 0x1a, 0xa1, 0x85, 0x22, 0x7a, 0x37, 0x9f, 0x56, 0x4d, 0xf1, 0xb5,
227
-		0x6f, 0x8c, 0xe9, 0x65, 0xbf, 0x49, 0xd7, 0xd0, 0xae, 0xc6, 0xaf, 0x37,
228
-		0xdb, 0x36, 0x3b, 0x8c, 0x37, 0x9e, 0x2e, 0xa7, 0xc1, 0xc6, 0x5a, 0x7a,
229
-		0x76, 0xaa, 0xf9, 0x01, 0xd3, 0xe5, 0x9b, 0x07, 0x7e, 0x18, 0x68, 0xd1,
230
-		0x3b, 0x91, 0x09, 0x6c, 0x45, 0xcf, 0x00, 0x32, 0xc5, 0x0d, 0xc4, 0xb4,
231
-		0x8a, 0x15, 0x52, 0xe3, 0xf7, 0x4b, 0x85, 0x7c, 0x1f, 0x19, 0x87, 0xce,
232
-		0x24, 0xf5, 0xc9, 0x80, 0x6c, 0x4d, 0xda, 0xaf, 0xbe, 0x26, 0x80, 0xd1,
233
-		0xf4, 0x34, 0x70, 0xa7, 0x7e, 0xcf, 0x6f, 0x44, 0xfe, 0x38, 0x7c, 0x40,
234
-		0xbc, 0x66, 0xa0, 0xab, 0xa5, 0x79, 0xe0, 0x80, 0x28, 0x05, 0x29, 0xb8,
235
-		0x60, 0xd2, 0x73, 0x4b, 0x86, 0x71, 0x37, 0x1c, 0x3e, 0xee, 0xfd, 0x12,
236
-		0xd0, 0xfb, 0xa0, 0x57, 0x5f, 0x81, 0xb9, 0x04, 0x12, 0xa4, 0xc0, 0xd4,
237
-		0x08, 0x34, 0x31, 0xd3, 0xcf, 0xc9, 0x39, 0x7c, 0x87, 0x74, 0x12, 0x66,
238
-		0x10, 0xc8, 0x7e, 0xfa, 0x09, 0x5f, 0x7b, 0x0c, 0xf1, 0x3c, 0x3e, 0x31,
239
-		0x72, 0x3d, 0xe7, 0x77, 0x60, 0xa8, 0x33, 0x67, 0x68, 0x1e, 0x2b, 0xdf,
240
-		0x99, 0x80, 0x9d, 0xa7, 0x54, 0xef, 0x91, 0xd5, 0x31, 0x2a, 0xeb, 0xf5,
241
-		0xd7, 0x76, 0x0d, 0xd0, 0x3e, 0x5f, 0x7d, 0x65, 0x99, 0xfd, 0x90, 0x0b,
242
-		0x64, 0x14, 0xf3, 0x64, 0x43, 0xea, 0x90, 0x00, 0xd2, 0xe5, 0x65, 0xcc,
243
-		0x13, 0x4e, 0x0f, 0x07, 0x33, 0x7a, 0x4f, 0x48, 0xa1, 0x36, 0xad, 0xd8,
244
-		0x76, 0xd7, 0x5b, 0xa3, 0xcc, 0xe6, 0x61, 0xa7, 0x81, 0x80, 0x6c, 0xd7,
245
-		0xf5, 0x67, 0x8d, 0xfb, 0xa4, 0xe7, 0x9b, 0x2a, 0xeb, 0x97, 0x29, 0x9f,
246
-		0xde, 0x3e, 0xca, 0x57, 0xee, 0xca, 0x21, 0x29, 0x28, 0x28, 0x9c, 0xf3,
247
-		0x1d, 0xe4, 0xee, 0xda, 0x48, 0x2e, 0x13, 0x34, 0xa4, 0x01, 0x28, 0x67,
248
-		0xec, 0x35, 0x5f, 0x58, 0x7d, 0xec, 0x47, 0x1c, 0x16, 0x1b, 0xd9, 0xab,
249
-		0x05, 0xcf, 0x9a, 0xe5, 0x05, 0x84, 0x24, 0x38, 0xee, 0x39, 0xa9, 0xcd,
250
-		0x74, 0x51, 0x85, 0x8c, 0x8e, 0x72, 0x0a, 0x87, 0x65, 0x26, 0x1e, 0x4a,
251
-		0x5e, 0x58, 0xc6, 0xf9, 0x93, 0x98, 0xa0, 0x25, 0xcd, 0x77, 0x6b, 0x7c,
252
-		0x43, 0xc0, 0x59, 0xb3, 0x9a, 0xa9, 0x5f, 0x9e, 0x37, 0x2f, 0x7a, 0x86,
253
-		0x66, 0x9e, 0xf8, 0x89, 0x06, 0xb7, 0xfc, 0xf4, 0x5c, 0x67, 0xbe, 0xad,
254
-		0xc2, 0x40, 0x84, 0xf3, 0x0c, 0x07, 0x8a, 0xa8, 0x76, 0x5e, 0xd9, 0x54,
255
-		0x1b, 0x9a, 0x6c, 0x35, 0xba, 0xf8, 0x67, 0x17, 0x3e, 0x69, 0xeb, 0xb7,
256
-		0xbb, 0xf4, 0x6f, 0xef, 0xc4, 0xcb, 0x1b, 0xe6, 0x54, 0x51, 0x80, 0xff,
257
-		0xa2, 0x30, 0x63, 0x37, 0x64, 0x26, 0x27, 0xf7, 0xa1, 0x48, 0xe2, 0x15,
258
-		0x27, 0x7e, 0x69, 0x1d, 0x7c, 0x6c, 0x3c, 0x42, 0xb7, 0xf6, 0x5a, 0x87,
259
-		0x5b, 0xdf, 0xd7, 0x74, 0x2f, 0x36, 0x3d, 0x95, 0x78, 0x4d, 0xd7, 0x6d,
260
-		0x78, 0xf9, 0xa9, 0xfb, 0x1e, 0x1f, 0x84, 0x1b, 0x2e, 0xdc, 0x7e, 0x19,
261
-		0x66, 0x5b, 0x8f, 0xb4, 0xd6, 0xc0, 0x25, 0xe9, 0xe5, 0xc2, 0x13, 0xec,
262
-		0x8c, 0xe9, 0xbf, 0xb7, 0x3c, 0xc8, 0x22, 0x2d, 0x35, 0x3c, 0x36, 0x8f,
263
-		0xbc, 0xc7, 0xf4, 0xcf, 0xc7, 0xcd, 0x7f, 0x7d, 0x30, 0xf4, 0xf3, 0x7f,
264
-		0x60, 0xe7, 0x02, 0x95, 0xc4, 0x87, 0xa5, 0x9e, 0xbd, 0xb3, 0x08, 0x3c,
265
-		0x24, 0xe4, 0xef, 0x01, 0x00, 0x00, 0xff, 0xff, 0xca, 0xc7, 0x79, 0x5b,
266
-		0xc3, 0x19, 0x00, 0x00,
31
+		0xeb, 0x72, 0xdb, 0xc8, 0x95, 0xfe, 0x8f, 0xa7, 0x68, 0x73, 0x67, 0x76,
32
+		0xec, 0x2d, 0x89, 0xa4, 0xe4, 0xb5, 0xec, 0x91, 0xc7, 0xb5, 0xa6, 0x48,
33
+		0x50, 0xc2, 0x9a, 0x17, 0x0d, 0x00, 0xc9, 0xa3, 0xb8, 0x54, 0x28, 0x08,
34
+		0x68, 0x92, 0x1d, 0x01, 0x68, 0x08, 0xdd, 0x14, 0xc5, 0xfc, 0xcb, 0x2b,
35
+		0xa4, 0xf2, 0x34, 0x79, 0x9e, 0xfc, 0xc8, 0x63, 0xe4, 0x3b, 0x0d, 0x80,
36
+		0x02, 0x65, 0x8e, 0xc6, 0xb9, 0x55, 0x52, 0x16, 0xd1, 0xdd, 0xe7, 0xf4,
37
+		0xb9, 0x7c, 0xe7, 0xd6, 0xf3, 0x9e, 0xf5, 0xf2, 0x9c, 0x65, 0x61, 0xca,
38
+		0x99, 0x5e, 0x84, 0x9a, 0xa9, 0x85, 0x5c, 0x29, 0x26, 0x33, 0xc6, 0xef,
39
+		0x79, 0xb1, 0x66, 0x79, 0x38, 0xc7, 0x86, 0xd0, 0x09, 0xb7, 0x7a, 0xe7,
40
+		0xe7, 0xc1, 0xa4, 0x37, 0xb6, 0xd9, 0x07, 0x76, 0x2a, 0xe7, 0xea, 0x18,
41
+		0xff, 0xb2, 0x53, 0xa1, 0x99, 0xc7, 0x8b, 0x7b, 0x11, 0x95, 0xfb, 0xa3,
42
+		0xe9, 0xe9, 0x14, 0xfb, 0x22, 0x9d, 0x77, 0x66, 0x21, 0x56, 0x65, 0xd6,
43
+		0xce, 0xb3, 0xb9, 0xf5, 0x9e, 0xf5, 0x17, 0x61, 0x06, 0x4e, 0x38, 0x2e,
44
+		0x66, 0x6c, 0x2d, 0x97, 0xac, 0x58, 0x66, 0x2c, 0x91, 0x51, 0x98, 0x24,
45
+		0x6b, 0xcb, 0xbd, 0x98, 0x04, 0x17, 0x9e, 0xed, 0x82, 0x72, 0x2e, 0x34,
46
+		0x4e, 0xdb, 0x42, 0x2f, 0x78, 0xc1, 0x5a, 0x31, 0xbf, 0x6f, 0xed, 0xb1,
47
+		0x56, 0x5e, 0xc8, 0xb8, 0xc5, 0x24, 0x16, 0x34, 0x57, 0x1a, 0x2b, 0x31,
48
+		0x9f, 0x85, 0xcb, 0x04, 0xbc, 0x54, 0x79, 0xc6, 0x70, 0x18, 0x4f, 0x07,
49
+		0x24, 0x1b, 0xbe, 0x2d, 0xeb, 0x4b, 0xc1, 0x73, 0xa9, 0x84, 0x96, 0xc5,
50
+		0xfa, 0xda, 0x72, 0xa7, 0x53, 0x1f, 0x1b, 0x96, 0xd7, 0x77, 0x9d, 0x73,
51
+		0x3f, 0xf0, 0xaf, 0xce, 0xe9, 0xdc, 0x4d, 0xa8, 0x16, 0x38, 0xa8, 0x20,
52
+		0x3d, 0x2f, 0xae, 0xad, 0x73, 0x77, 0xea, 0x4f, 0xfb, 0xd3, 0x11, 0x76,
53
+		0x16, 0x5a, 0xe7, 0xd6, 0x60, 0x3a, 0xee, 0x39, 0x13, 0x7c, 0x19, 0x21,
54
+		0x17, 0x52, 0x69, 0xc3, 0x27, 0xb8, 0x70, 0xe9, 0xc8, 0xf7, 0x2f, 0xeb,
55
+		0xf3, 0xaf, 0xd4, 0x71, 0xa7, 0xf3, 0xfd, 0xcb, 0xf2, 0x38, 0x3e, 0xbe,
56
+		0x7f, 0x79, 0xe6, 0xfb, 0xe7, 0xc1, 0xf9, 0xd4, 0xf5, 0x5f, 0xa9, 0x8e,
57
+		0x65, 0x3e, 0x7a, 0x83, 0x01, 0xe9, 0x66, 0x6d, 0x76, 0xf0, 0xf1, 0xba,
58
+		0xdb, 0xed, 0x5a, 0x9e, 0x77, 0x56, 0x7f, 0x1f, 0x1e, 0x42, 0xef, 0x81,
59
+		0x50, 0xe1, 0x4d, 0xc2, 0x59, 0x7f, 0x30, 0x21, 0xfb, 0x67, 0x4c, 0x64,
60
+		0xb5, 0xf6, 0xa9, 0x8c, 0xb9, 0x35, 0x1d, 0x0e, 0x47, 0xce, 0xc4, 0xae,
61
+		0x55, 0x9d, 0x85, 0x89, 0xe2, 0xd6, 0xc0, 0xf1, 0x7a, 0x27, 0x23, 0x3b,
62
+		0x70, 0xa7, 0x17, 0xbe, 0xed, 0x92, 0x0b, 0x36, 0x5b, 0xef, 0xd9, 0x29,
63
+		0xcf, 0x78, 0x11, 0x6a, 0xce, 0x94, 0xe6, 0xb9, 0x3a, 0xc6, 0xca, 0x77,
64
+		0x2c, 0x8a, 0xe1, 0x56, 0xbd, 0xe8, 0x68, 0xd9, 0x99, 0xc3, 0x91, 0x9d,
65
+		0x68, 0xa9, 0xb4, 0x4c, 0x3b, 0xa4, 0xb6, 0x32, 0x07, 0xe6, 0xd2, 0xb8,
66
+		0xe7, 0xbb, 0xd3, 0x29, 0xa9, 0xdc, 0x51, 0x45, 0xd4, 0xc9, 0x6f, 0xe7,
67
+		0x9d, 0xa8, 0x58, 0xe7, 0xa0, 0xd1, 0x89, 0xea, 0xcc, 0x2b, 0xb6, 0x41,
68
+		0xc4, 0x0b, 0xdd, 0xc6, 0xf9, 0xfd, 0x28, 0xfc, 0xa0, 0x8b, 0x25, 0x67,
69
+		0xfb, 0xf1, 0x12, 0x1b, 0x42, 0x66, 0x1f, 0xde, 0xbd, 0x3d, 0xea, 0x2e,
70
+		0xba, 0x69, 0x57, 0xb1, 0x7d, 0x32, 0xdf, 0x87, 0x74, 0x4d, 0x7f, 0xda,
71
+		0xfc, 0x21, 0x4c, 0xf3, 0x84, 0xb7, 0x23, 0x99, 0x5a, 0x7d, 0xdb, 0xf5,
72
+		0x83, 0xa1, 0x33, 0x22, 0x65, 0x9a, 0x52, 0x74, 0x0c, 0xdb, 0x9c, 0xa7,
73
+		0xd6, 0x27, 0xfb, 0x6a, 0xe7, 0x81, 0x5b, 0xbe, 0x36, 0xfb, 0xef, 0xd9,
74
+		0x45, 0x9e, 0x03, 0x2a, 0x09, 0xcc, 0x95, 0x30, 0x39, 0x63, 0x9a, 0x83,
75
+		0x3b, 0x29, 0x1c, 0x66, 0x31, 0x94, 0x86, 0x28, 0x11, 0x9b, 0x09, 0xd8,
76
+		0x94, 0x54, 0xc6, 0xf1, 0x06, 0x74, 0x80, 0x31, 0xb3, 0xca, 0x56, 0x00,
77
+		0x1b, 0x37, 0xa0, 0xa6, 0x65, 0xfe, 0xc0, 0xa3, 0xa5, 0xe6, 0xb1, 0xe5,
78
+		0xf9, 0x3d, 0xdf, 0xe9, 0x07, 0xc6, 0xed, 0xe7, 0x3d, 0xff, 0x8c, 0x5c,
79
+		0x68, 0x7d, 0x89, 0x43, 0x1d, 0x02, 0x3b, 0xfc, 0xba, 0x81, 0xd3, 0x74,
80
+		0xad, 0xee, 0x12, 0x83, 0x54, 0x68, 0x38, 0x2f, 0xb8, 0x2a, 0xd1, 0x8a,
81
+		0x45, 0xa1, 0xf9, 0x6b, 0x6c, 0x08, 0xfd, 0x83, 0x22, 0xd8, 0x17, 0x2c,
82
+		0x5a, 0x48, 0x0a, 0x96, 0xc1, 0x49, 0x8d, 0x43, 0x43, 0x6b, 0x9d, 0x4d,
83
+		0x3d, 0x42, 0xc1, 0xc1, 0xe1, 0xdb, 0x76, 0x17, 0xff, 0x3b, 0x38, 0x7e,
84
+		0xfd, 0xba, 0x7b, 0x64, 0x55, 0xe1, 0x46, 0x5e, 0xb2, 0xaa, 0x00, 0x29,
85
+		0xa4, 0xd4, 0xd6, 0x79, 0xcf, 0xf3, 0x3e, 0x0f, 0xd8, 0x07, 0x88, 0x30,
86
+		0xa4, 0x8b, 0x1a, 0xd7, 0x66, 0xc9, 0x7a, 0x8f, 0xf1, 0x3a, 0x7e, 0x4a,
87
+		0x3c, 0x91, 0x64, 0x05, 0xbf, 0x5b, 0x8a, 0x82, 0x97, 0x82, 0x01, 0xf1,
88
+		0x62, 0xb6, 0xde, 0x9f, 0x2d, 0x93, 0xa4, 0x05, 0x10, 0x8e, 0x36, 0xb1,
89
+		0x53, 0x9e, 0xaf, 0xd9, 0xd6, 0xf2, 0x1b, 0xae, 0x56, 0x65, 0x02, 0xd2,
90
+		0xdf, 0xe0, 0xa6, 0x1d, 0xdf, 0xc0, 0x1c, 0x61, 0x9c, 0x8a, 0xec, 0xda,
91
+		0x04, 0x52, 0xb4, 0x2c, 0x84, 0x46, 0xbc, 0x39, 0x13, 0x58, 0x6e, 0x34,
92
+		0x02, 0x12, 0xfb, 0x9f, 0x1a, 0x50, 0x7c, 0xf1, 0xa2, 0x7f, 0xd6, 0x9b,
93
+		0x9c, 0xda, 0xcc, 0x3f, 0x73, 0x3c, 0xe6, 0x4f, 0xd9, 0x27, 0xdb, 0x3e,
94
+		0x67, 0x57, 0xd3, 0x0b, 0x97, 0x19, 0xdd, 0x06, 0x3d, 0xbf, 0xc7, 0xbc,
95
+		0xde, 0xd0, 0x7e, 0xf1, 0xc2, 0xf2, 0xec, 0xbe, 0x6b, 0xfb, 0x01, 0xbc,
96
+		0x0f, 0x06, 0x2f, 0xfe, 0xeb, 0xe3, 0x70, 0x60, 0x7f, 0x76, 0xf1, 0xff,
97
+		0xff, 0xfe, 0x9f, 0x97, 0xe0, 0xd4, 0x5b, 0x6a, 0xb9, 0x9f, 0xc8, 0x39,
98
+		0xa2, 0xa3, 0xe0, 0x29, 0x4f, 0x6f, 0xa0, 0x6b, 0x1c, 0xae, 0x95, 0x05,
99
+		0xec, 0x3b, 0x93, 0xc0, 0xb5, 0xc7, 0xf6, 0xf8, 0x04, 0xa1, 0x30, 0xe8,
100
+		0x5d, 0x79, 0xa0, 0x7f, 0x6b, 0xf5, 0xa7, 0xd3, 0x4f, 0x8e, 0x6d, 0x72,
101
+		0x4c, 0xc3, 0xa4, 0x41, 0xb8, 0xe2, 0x4a, 0xa6, 0xbc, 0xde, 0xde, 0xd0,
102
+		0x35, 0xcf, 0x88, 0x2c, 0x2a, 0x78, 0x2c, 0x4a, 0xab, 0xb8, 0x94, 0x14,
103
+		0x15, 0x50, 0x53, 0xc8, 0x87, 0x35, 0x0b, 0x97, 0xb0, 0x72, 0x06, 0x80,
104
+		0x19, 0xbc, 0xb3, 0x05, 0x0f, 0x63, 0x08, 0x62, 0x52, 0x29, 0x80, 0xb8,
105
+		0x54, 0xd5, 0x87, 0xe5, 0xda, 0x97, 0xb6, 0xeb, 0xd9, 0x01, 0x52, 0xc6,
106
+		0x2f, 0x57, 0x41, 0xef, 0xc2, 0x3f, 0xb3, 0x27, 0x00, 0x16, 0xc0, 0x35,
107
+		0xdd, 0xe4, 0xbd, 0x5f, 0xf6, 0x3f, 0xdb, 0x27, 0xb4, 0xb5, 0x4f, 0x0b,
108
+		0x55, 0x5e, 0x02, 0x50, 0xae, 0xad, 0x5e, 0xdf, 0x77, 0x2e, 0xed, 0xa0,
109
+		0x0f, 0x0f, 0x05, 0x23, 0xfa, 0x35, 0x76, 0x26, 0x08, 0x74, 0x52, 0xec,
110
+		0xe0, 0x5d, 0x17, 0xcc, 0x3d, 0x9b, 0xe0, 0x49, 0x80, 0xf8, 0xd5, 0x43,
111
+		0x88, 0x12, 0x23, 0x0d, 0xe7, 0x31, 0xd3, 0x92, 0x21, 0x2d, 0xcf, 0x44,
112
+		0x91, 0x32, 0xbe, 0x9f, 0x86, 0x22, 0x61, 0x33, 0xf8, 0xba, 0xe0, 0x73,
113
+		0xa1, 0x74, 0x19, 0xb9, 0xe0, 0x79, 0xea, 0x78, 0x94, 0x4b, 0x6c, 0x24,
114
+		0xb5, 0x11, 0xb8, 0x4e, 0x86, 0x8e, 0x3b, 0x6e, 0xb8, 0x72, 0x20, 0xb9,
115
+		0x62, 0x99, 0xd4, 0x0c, 0xe9, 0x5b, 0xae, 0x2a, 0x62, 0x5c, 0x40, 0x31,
116
+		0x67, 0x00, 0xc1, 0x60, 0x34, 0x13, 0x84, 0x51, 0x24, 0x97, 0x99, 0x2e,
117
+		0x01, 0xb4, 0x49, 0x54, 0x86, 0xbd, 0x6b, 0xf4, 0x6f, 0x30, 0x35, 0x22,
118
+		0xa6, 0x08, 0x72, 0xa6, 0xc4, 0xdc, 0xa4, 0x3e, 0x88, 0x7a, 0x2f, 0xf8,
119
+		0x0a, 0x6c, 0xd7, 0x7a, 0x21, 0xb2, 0x79, 0x1b, 0x92, 0xfd, 0x7c, 0xe1,
120
+		0xb8, 0x76, 0xe0, 0x39, 0xa7, 0x13, 0x78, 0xfa, 0xd2, 0xb1, 0x3f, 0x37,
121
+		0x38, 0xf4, 0xc3, 0x08, 0x21, 0x1d, 0xde, 0x03, 0xa1, 0x90, 0x45, 0xb1,
122
+		0x5c, 0x44, 0x7a, 0x59, 0x70, 0xcb, 0x9e, 0x98, 0x7b, 0xfb, 0xbd, 0xfe,
123
+		0x99, 0x1d, 0xf4, 0x2e, 0x81, 0x33, 0xb7, 0x41, 0x35, 0x26, 0x1b, 0x40,
124
+		0x19, 0x31, 0xab, 0x3c, 0x59, 0x9f, 0x9f, 0x4c, 0x7d, 0x67, 0x78, 0x15,
125
+		0x90, 0x0d, 0x9a, 0xc7, 0x25, 0x72, 0x45, 0xcc, 0x35, 0xa8, 0x8e, 0x4d,
126
+		0xa9, 0xa0, 0x02, 0x80, 0xb2, 0xb5, 0x58, 0xde, 0x50, 0x4e, 0xa3, 0xd0,
127
+		0x10, 0x5a, 0x95, 0x99, 0x55, 0x28, 0xb5, 0xe4, 0xaa, 0x73, 0x70, 0xf4,
128
+		0xa6, 0xe6, 0xf9, 0x1c, 0x16, 0x36, 0x97, 0x58, 0x5f, 0x56, 0xfc, 0x66,
129
+		0x21, 0xe5, 0x2d, 0xe5, 0x98, 0x7e, 0x01, 0x6c, 0xe9, 0x50, 0xdd, 0xc2,
130
+		0x22, 0xb0, 0xf1, 0x7d, 0x98, 0x90, 0x69, 0x60, 0x63, 0xe4, 0x28, 0x65,
131
+		0xf9, 0x3d, 0xef, 0x53, 0xe0, 0x4c, 0xe0, 0xac, 0xcb, 0x1e, 0x49, 0x79,
132
+		0x40, 0xde, 0xe1, 0x89, 0x00, 0x4e, 0x51, 0xb6, 0x53, 0x2e, 0x97, 0x9a,
133
+		0x8e, 0x23, 0x38, 0x65, 0x16, 0x2b, 0x6b, 0x60, 0x13, 0x3a, 0xdc, 0xc0,
134
+		0x77, 0xc6, 0x36, 0xca, 0x05, 0x08, 0xde, 0xe0, 0x36, 0x42, 0x01, 0xd5,
135
+		0xc0, 0x52, 0xc6, 0x41, 0x43, 0xd9, 0x93, 0xe5, 0x6c, 0x66, 0xb2, 0x6b,
136
+		0x36, 0x47, 0x9e, 0x04, 0xaa, 0x23, 0xd4, 0xf1, 0x8c, 0x27, 0x7b, 0xec,
137
+		0x96, 0xf3, 0x9c, 0xca, 0x39, 0xcc, 0x2c, 0x4c, 0x36, 0xad, 0xea, 0x7a,
138
+		0x2c, 0xb3, 0x1f, 0x34, 0xbb, 0xcd, 0x00, 0x8b, 0x15, 0xf5, 0x13, 0x66,
139
+		0xb3, 0x8d, 0x80, 0x9e, 0x0c, 0x82, 0x93, 0x8b, 0xe1, 0x90, 0x2a, 0x94,
140
+		0x4d, 0xaa, 0x1e, 0x10, 0x2c, 0x27, 0x14, 0x2c, 0xc8, 0x3a, 0x48, 0xd9,
141
+		0x6b, 0x60, 0x93, 0x14, 0x23, 0x6f, 0x94, 0x0d, 0x87, 0x77, 0x71, 0xf2,
142
+		0xff, 0x76, 0xdf, 0x37, 0xe5, 0xb6, 0x6e, 0x3e, 0x5e, 0xa9, 0xda, 0x63,
143
+		0x65, 0xe1, 0xa6, 0x12, 0x97, 0x1a, 0x57, 0xa8, 0x54, 0xe7, 0xed, 0x39,
144
+		0xfd, 0x26, 0x37, 0x1c, 0xbf, 0x79, 0xf7, 0x16, 0x7b, 0x3f, 0xff, 0x5c,
145
+		0x6d, 0xdc, 0xdd, 0x99, 0xd5, 0xc3, 0x37, 0x75, 0xa6, 0xad, 0xd9, 0xcc,
146
+		0x0a, 0x99, 0x02, 0xb3, 0x31, 0xb2, 0xa7, 0xb2, 0x86, 0xee, 0x74, 0xfc,
147
+		0xb8, 0x07, 0xc5, 0x37, 0x41, 0x6c, 0xa0, 0x9d, 0x87, 0x4a, 0xad, 0x64,
148
+		0x11, 0xd7, 0xb9, 0x78, 0x93, 0x87, 0xa9, 0x2e, 0x48, 0x4a, 0x07, 0x5f,
149
+		0xdb, 0xb0, 0xda, 0x68, 0x97, 0x08, 0xf9, 0x7a, 0xbf, 0x3f, 0x72, 0x80,
150
+		0x80, 0xc0, 0x31, 0x5c, 0xaa, 0x8f, 0x32, 0xfb, 0x95, 0x2d, 0xcb, 0xf4,
151
+		0xdc, 0x44, 0x71, 0x0d, 0xb4, 0x30, 0x17, 0xed, 0x06, 0xd8, 0x48, 0x3e,
152
+		0x8b, 0x50, 0x54, 0xf5, 0x25, 0x3b, 0xf0, 0x68, 0xf2, 0x64, 0xc7, 0x08,
153
+		0xd1, 0xa1, 0x7f, 0x64, 0x21, 0xfe, 0xc0, 0x2d, 0x7f, 0xfa, 0xc9, 0x9e,
154
+		0x7c, 0x23, 0x51, 0x14, 0xc1, 0x36, 0x81, 0x96, 0xb7, 0x3c, 0xb3, 0x4c,
155
+		0x4b, 0xa1, 0x59, 0x94, 0x08, 0x64, 0x3e, 0x26, 0xe2, 0xb2, 0xcc, 0x72,
156
+		0x84, 0xbb, 0x36, 0xa6, 0xc4, 0x7e, 0xcd, 0x0e, 0x88, 0x53, 0x12, 0x85,
157
+		0x3e, 0xa6, 0xd2, 0x2c, 0x51, 0xa4, 0x15, 0x1a, 0x05, 0x39, 0x2f, 0x4b,
158
+		0x7f, 0x07, 0x29, 0xf4, 0xf7, 0x3c, 0xd2, 0x1b, 0xf3, 0x98, 0x9d, 0x7f,
159
+		0xd9, 0x3c, 0xab, 0xd5, 0xaa, 0x62, 0x05, 0x43, 0x29, 0x73, 0x91, 0xd1,
160
+		0x81, 0xec, 0x24, 0xb2, 0x99, 0x6c, 0x73, 0x83, 0xaf, 0x6f, 0x3e, 0x0e,
161
+		0x29, 0xa9, 0x79, 0xd8, 0x65, 0xe2, 0x2a, 0xb5, 0x6d, 0x29, 0x25, 0x4b,
162
+		0x93, 0x1d, 0x1a, 0x2e, 0x3b, 0x6d, 0xfc, 0x2c, 0x55, 0x65, 0xe2, 0xca,
163
+		0x24, 0x77, 0x77, 0xff, 0xb4, 0x39, 0x90, 0x96, 0x0d, 0xf8, 0xd9, 0x5f,
164
+		0xff, 0xf2, 0xa7, 0xbf, 0xfd, 0xf1, 0xcf, 0x54, 0x32, 0x77, 0x60, 0xa4,
165
+		0x08, 0xf3, 0x45, 0x15, 0x18, 0x95, 0x04, 0xed, 0x6e, 0x03, 0x22, 0xef,
166
+		0xd9, 0x4e, 0x90, 0xec, 0xa4, 0x2a, 0x25, 0x07, 0x05, 0xcf, 0x22, 0x02,
167
+		0xc6, 0x8a, 0x8b, 0x1b, 0xb9, 0xcb, 0x6a, 0xc0, 0x41, 0xd6, 0xd6, 0x35,
168
+		0x7d, 0x34, 0x17, 0xfb, 0x37, 0x35, 0xd0, 0x0e, 0x7f, 0x03, 0x9e, 0xcf,
169
+		0x93, 0x6e, 0x81, 0xb4, 0xb2, 0xa0, 0x5e, 0x09, 0xad, 0x77, 0x25, 0xb6,
170
+		0x7f, 0xc0, 0x8c, 0xbb, 0x3c, 0x8f, 0x18, 0xac, 0x58, 0x3f, 0x5a, 0xe1,
171
+		0x37, 0x84, 0xff, 0x15, 0x9a, 0x5d, 0x52, 0x1b, 0xdb, 0xfd, 0x27, 0x64,
172
+		0x36, 0x8c, 0x1b, 0x7e, 0xfb, 0x06, 0x91, 0xbf, 0x26, 0xd9, 0x96, 0x38,
173
+		0xa2, 0x8a, 0xbb, 0xd5, 0x09, 0xf3, 0x14, 0x33, 0x57, 0xd9, 0x70, 0x22,
174
+		0xaf, 0xe3, 0x87, 0x2c, 0x57, 0xcd, 0xc9, 0x27, 0xa3, 0x5b, 0x75, 0xd8,
175
+		0xea, 0x0d, 0x7a, 0xe7, 0xbe, 0xc9, 0xa8, 0xe5, 0x4a, 0xdd, 0x7f, 0x56,
176
+		0xfb, 0x55, 0x53, 0x7b, 0xda, 0xdf, 0xaa, 0x80, 0x55, 0x49, 0xdb, 0xe2,
177
+		0x78, 0xd4, 0xb5, 0x1a, 0xb5, 0xf0, 0xa8, 0x5b, 0x33, 0x2a, 0x65, 0x31,
178
+		0xb9, 0xaa, 0x29, 0x0b, 0x18, 0x64, 0xc8, 0x41, 0xa6, 0x79, 0x43, 0x07,
179
+		0xbd, 0x29, 0x03, 0xef, 0x99, 0x21, 0x38, 0x66, 0xad, 0xe3, 0xa3, 0xee,
180
+		0xeb, 0x1f, 0x5b, 0x58, 0xa8, 0xa9, 0xb0, 0xf6, 0xd8, 0xa3, 0x1f, 0x1c,
181
+		0x1c, 0x1e, 0x1c, 0xb4, 0xaa, 0x8a, 0x62, 0x7a, 0x36, 0xa5, 0xc0, 0x6c,
182
+		0xb7, 0x3d, 0x28, 0x8f, 0x3c, 0xda, 0xa5, 0x34, 0x4b, 0x35, 0x36, 0xec,
183
+		0xb2, 0x09, 0x1a, 0x84, 0x4b, 0x67, 0x60, 0x8c, 0x62, 0x32, 0xd0, 0x7b,
184
+		0x76, 0x5e, 0xc8, 0x7b, 0x41, 0x1d, 0xa6, 0x69, 0xdf, 0xe6, 0x4c, 0xe6,
185
+		0x24, 0xb9, 0x2a, 0x85, 0x03, 0xcd, 0xb1, 0xe9, 0xc8, 0x16, 0xe1, 0x3d,
186
+		0x15, 0xab, 0x75, 0x7d, 0x6a, 0xcd, 0x69, 0xa0, 0x26, 0x16, 0xa8, 0x84,
187
+		0xa5, 0x7c, 0x8f, 0xf3, 0x10, 0x26, 0x85, 0xf6, 0xbc, 0x8d, 0x39, 0x81,
188
+		0x7a, 0xfa, 0x6a, 0x57, 0xb5, 0x1e, 0xf5, 0xaf, 0x78, 0x24, 0xe2, 0x96,
189
+		0x97, 0x4b, 0x55, 0xd5, 0x35, 0x96, 0xda, 0x63, 0xb9, 0x94, 0x89, 0x07,
190
+		0xf8, 0xec, 0x6d, 0x2a, 0x63, 0xcd, 0xf0, 0xd1, 0x46, 0x47, 0xaf, 0xdf,
191
+		0xfe, 0xb8, 0x77, 0xd0, 0xed, 0xee, 0x85, 0x18, 0xc6, 0x1e, 0x04, 0x37,
192
+		0xc6, 0x24, 0xbd, 0x8f, 0xd1, 0x5f, 0xef, 0xe3, 0xef, 0x7e, 0x5c, 0x50,
193
+		0xb7, 0xd2, 0x31, 0x8b, 0x2c, 0x56, 0x59, 0x7d, 0x2b, 0xda, 0x51, 0xf4,
194
+		0x7c, 0x35, 0x47, 0x9a, 0x7b, 0x8e, 0xeb, 0x6b, 0x3e, 0xd6, 0xc2, 0x06,
195
+		0xda, 0xcc, 0x37, 0x1b, 0x6b, 0x95, 0xbd, 0xea, 0x69, 0x3d, 0xa6, 0xd4,
196
+		0x2a, 0xe1, 0x4e, 0xaf, 0xd2, 0x3d, 0x42, 0x5b, 0x25, 0x78, 0xd9, 0x98,
197
+		0x57, 0x7d, 0x7f, 0xd5, 0xee, 0x8b, 0x80, 0xf4, 0x0c, 0xca, 0xfe, 0x0d,
198
+		0x14, 0x4e, 0xd9, 0xd0, 0xa0, 0x16, 0x6c, 0x0c, 0x07, 0xd8, 0x99, 0xe8,
199
+		0xa8, 0x10, 0xd9, 0xf0, 0x5b, 0x15, 0xa3, 0x25, 0x43, 0x84, 0xe5, 0x85,
200
+		0x6b, 0x37, 0xda, 0x28, 0x3b, 0x33, 0x63, 0xbd, 0xa2, 0xca, 0x69, 0xee,
201
+		0xdf, 0xa2, 0xa5, 0xb9, 0xb9, 0xee, 0x0f, 0xa9, 0x99, 0x2f, 0xb9, 0x80,
202
+		0xdc, 0x6c, 0x3c, 0x8a, 0x8e, 0x00, 0xa0, 0x96, 0x6e, 0x13, 0x05, 0x5b,
203
+		0x4c, 0xde, 0x1d, 0xfd, 0x6f, 0xb7, 0x6b, 0x9d, 0xf6, 0x37, 0xcd, 0xa0,
204
+		0xe9, 0xf1, 0xc0, 0xa4, 0xdc, 0x78, 0xe4, 0x92, 0x88, 0x19, 0x37, 0x7c,
205
+		0x76, 0x90, 0x7b, 0xb6, 0xe7, 0xd1, 0x50, 0x32, 0x72, 0x86, 0xf6, 0x53,
206
+		0xfa, 0x8d, 0x0d, 0x62, 0x60, 0x4c, 0x2d, 0xd8, 0x6c, 0x99, 0x45, 0x7b,
207
+		0x1b, 0x9c, 0xab, 0x45, 0x78, 0x40, 0xe8, 0xc6, 0xdf, 0xc3, 0x37, 0x47,
208
+		0x15, 0xbc, 0xe3, 0x37, 0xad, 0xe6, 0x1d, 0x74, 0x66, 0x73, 0x85, 0x33,
209
+		0x08, 0xce, 0x7a, 0xde, 0xd9, 0xf0, 0x62, 0xd2, 0xc7, 0x25, 0x66, 0xeb,
210
+		0x51, 0x46, 0x73, 0x01, 0x46, 0xfc, 0x2d, 0x11, 0xc9, 0x11, 0x05, 0x42,
211
+		0x18, 0xfd, 0x5a, 0x09, 0x8d, 0xa7, 0xbc, 0xcc, 0xb4, 0x88, 0x30, 0xac,
212
+		0xda, 0x7e, 0x0a, 0x43, 0x9f, 0x46, 0xfc, 0x24, 0x8c, 0x38, 0xcd, 0x12,
213
+		0xd5, 0xba, 0x81, 0xc6, 0xe3, 0x8c, 0x5c, 0x22, 0xba, 0x94, 0xf8, 0x4e,
214
+		0x64, 0x62, 0xf9, 0x24, 0x20, 0xab, 0x7d, 0x5c, 0xe6, 0x5e, 0x3a, 0x7d,
215
+		0xb2, 0x48, 0xd5, 0x79, 0xd6, 0xe3, 0xcc, 0xa9, 0xfb, 0x64, 0xa4, 0xb0,
216
+		0xbe, 0xa0, 0x7d, 0x2a, 0x9f, 0x9d, 0xaa, 0x77, 0x83, 0x46, 0x42, 0xa8,
217
+		0xba, 0xa2, 0x66, 0x46, 0xa0, 0x34, 0x64, 0x6c, 0x87, 0x46, 0xb5, 0x94,
218
+		0xa3, 0x7e, 0x63, 0x78, 0x22, 0x4a, 0x4d, 0x5b, 0x0e, 0x4b, 0x80, 0x52,
219
+		0x9a, 0x86, 0xa4, 0x98, 0xe2, 0x79, 0x68, 0x1e, 0x79, 0x52, 0x9c, 0x14,
220
+		0x39, 0x90, 0x46, 0xaf, 0x45, 0xaa, 0x0e, 0x9d, 0x8a, 0x6c, 0xcf, 0xc4,
221
+		0x7d, 0xcb, 0xaa, 0x66, 0xfd, 0x6a, 0xf5, 0xdf, 0xd9, 0xe4, 0x3f, 0xe9,
222
+		0xef, 0xbb, 0x06, 0x37, 0xb5, 0xe2, 0x7e, 0x01, 0x37, 0x90, 0x9a, 0x03,
223
+		0x7e, 0xb3, 0x9c, 0xd3, 0x0f, 0x07, 0x1d, 0x16, 0xfd, 0xfd, 0x1c, 0x16,
224
+		0x46, 0x7f, 0xbb, 0x28, 0x64, 0x41, 0x3f, 0xfa, 0x85, 0xa0, 0xa9, 0xfa,
225
+		0x69, 0x6a, 0x2c, 0x39, 0x58, 0x23, 0x8c, 0x50, 0x94, 0xde, 0xcd, 0xa7,
226
+		0x55, 0xa7, 0xf8, 0xda, 0x36, 0x46, 0xf5, 0x72, 0xde, 0x24, 0x37, 0xb4,
227
+		0xab, 0xf5, 0xeb, 0x0d, 0xd9, 0x86, 0xc2, 0x58, 0xe3, 0xe9, 0x71, 0x5a,
228
+		0x6c, 0x9c, 0xa5, 0xa7, 0xa7, 0x3a, 0x3f, 0x60, 0xbb, 0x7c, 0xf7, 0xc0,
229
+		0x0f, 0x03, 0x2d, 0x7a, 0x2b, 0x32, 0x81, 0xad, 0xe8, 0x29, 0x40, 0xa6,
230
+		0xf0, 0x40, 0x4c, 0xa7, 0x58, 0x21, 0x35, 0x7e, 0xbf, 0x54, 0xa8, 0xf7,
231
+		0x91, 0x31, 0xe8, 0x4c, 0xd2, 0x9c, 0x0c, 0xc8, 0xd6, 0x49, 0xfb, 0xd5,
232
+		0xd7, 0x09, 0x60, 0x34, 0x3d, 0x0d, 0xdc, 0xa9, 0xdf, 0xf3, 0x1b, 0x91,
233
+		0x3f, 0x0e, 0x1f, 0x10, 0xaf, 0x19, 0xd2, 0xd5, 0xd2, 0x3c, 0x72, 0x80,
234
+		0x95, 0x02, 0x17, 0x38, 0x98, 0xe4, 0xdc, 0xe2, 0x61, 0xcc, 0x0d, 0x83,
235
+		0x8f, 0x7b, 0xbf, 0x04, 0xf4, 0x46, 0xe8, 0xd5, 0x2e, 0x30, 0x4e, 0x20,
236
+		0x46, 0x0a, 0x99, 0x1a, 0x81, 0x26, 0x66, 0xfa, 0x39, 0x3e, 0x87, 0xef,
237
+		0x50, 0x4e, 0xc2, 0x0c, 0x0c, 0xd9, 0x4f, 0x3f, 0xe1, 0x6b, 0x8f, 0x21,
238
+		0x9e, 0xc7, 0x27, 0x86, 0xaf, 0xe7, 0xfc, 0x0e, 0x19, 0xea, 0xcc, 0x19,
239
+		0x9a, 0x07, 0xcb, 0x77, 0x26, 0x60, 0xe7, 0x29, 0xf5, 0x7b, 0xa4, 0x75,
240
+		0x8c, 0xce, 0x7a, 0xfd, 0xb5, 0x5e, 0x03, 0x8c, 0xcf, 0x57, 0x5f, 0x69,
241
+		0x66, 0x3f, 0xe4, 0x02, 0x15, 0xc5, 0x3c, 0xdb, 0x90, 0x38, 0xc4, 0x80,
242
+		0x64, 0x79, 0x19, 0xf3, 0x84, 0xd3, 0xc3, 0xc1, 0x8c, 0xde, 0x13, 0x52,
243
+		0x88, 0x4d, 0x27, 0xb6, 0xcd, 0xf5, 0xd6, 0x08, 0xb3, 0x79, 0xdc, 0x69,
244
+		0x20, 0x20, 0xdb, 0xe5, 0xfe, 0xac, 0xe1, 0x4f, 0x7a, 0xc2, 0xa9, 0xaa,
245
+		0x7e, 0x59, 0xf2, 0xe9, 0xed, 0xa3, 0x7c, 0xe9, 0xae, 0x0c, 0x92, 0x22,
246
+		0x05, 0x85, 0x73, 0xbe, 0x23, 0xb9, 0xbb, 0x36, 0x8a, 0xcb, 0x04, 0x03,
247
+		0x69, 0x80, 0x94, 0x33, 0xf6, 0x9a, 0xaf, 0xac, 0x3e, 0xe8, 0x11, 0x87,
248
+		0xc5, 0x86, 0xf7, 0x6a, 0xc1, 0xb3, 0x66, 0x7b, 0x01, 0x26, 0x09, 0xae,
249
+		0x7b, 0x8e, 0x6b, 0xb3, 0x5c, 0x54, 0x21, 0xa3, 0xa3, 0x9c, 0xc2, 0x61,
250
+		0x99, 0x89, 0x87, 0x32, 0x2f, 0x2c, 0xe3, 0xfc, 0x49, 0x4c, 0xd0, 0x91,
251
+		0xe6, 0xdb, 0x35, 0xbe, 0xc1, 0xe0, 0xac, 0xd9, 0xcd, 0xd4, 0xaf, 0xcf,
252
+		0x9b, 0x57, 0x3d, 0x93, 0x66, 0x9e, 0xd8, 0x89, 0x16, 0xb7, 0xec, 0xf4,
253
+		0xdc, 0x64, 0xbe, 0x2d, 0xc2, 0x40, 0x84, 0xf3, 0x0c, 0x17, 0x8a, 0xa8,
254
+		0x36, 0x5e, 0x39, 0x54, 0x9b, 0x34, 0xd9, 0x6a, 0x4c, 0xf1, 0xcf, 0x1e,
255
+		0x7c, 0x32, 0xd6, 0x6f, 0x4f, 0xe9, 0xdf, 0x3e, 0x89, 0x97, 0x1e, 0xe6,
256
+		0xd4, 0x51, 0x20, 0xff, 0x45, 0x61, 0xc6, 0x6e, 0x48, 0x4d, 0x4e, 0xe6,
257
+		0x43, 0x93, 0xc4, 0xab, 0x9c, 0xf8, 0xa5, 0x75, 0xf0, 0xb1, 0xf1, 0x10,
258
+		0xdd, 0xda, 0x6b, 0x1d, 0x6e, 0x7d, 0x5f, 0x93, 0x5f, 0x6c, 0x7a, 0x2a,
259
+		0xf1, 0x9a, 0xa6, 0xdb, 0xe4, 0xe5, 0xa7, 0xe6, 0x7b, 0x7c, 0x14, 0x6e,
260
+		0x98, 0x70, 0xfb, 0x75, 0x98, 0x6d, 0x3d, 0xd4, 0x5a, 0x03, 0x97, 0xb8,
261
+		0x97, 0x07, 0x4f, 0x40, 0x19, 0xd3, 0x7f, 0x73, 0x79, 0x90, 0x45, 0x5a,
262
+		0x4a, 0x78, 0x6c, 0x1e, 0x7a, 0x8f, 0xe9, 0x9f, 0x8f, 0x9b, 0xff, 0x02,
263
+		0x61, 0xd2, 0xcf, 0xff, 0x21, 0x3b, 0x17, 0xe8, 0x24, 0x3e, 0x2c, 0xf5,
264
+		0xec, 0x9d, 0x45, 0xe0, 0x21, 0x26, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff,
265
+		0xc9, 0x2e, 0x07, 0x65, 0xc7, 0x19, 0x00, 0x00,
267 266
 	},
268 267
 		"conf/app.ini",
269 268
 	)

+ 14 - 5
modules/mailer/mail.go

@@ -17,6 +17,15 @@ import (
17 17
 	"github.com/gogits/gogs/modules/setting"
18 18
 )
19 19
 
20
+const (
21
+	AUTH_ACTIVE           base.TplName = "mail/auth/active"
22
+	AUTH_REGISTER_SUCCESS base.TplName = "mail/auth/register_success"
23
+	AUTH_RESET_PASSWORD   base.TplName = "mail/auth/reset_passwd"
24
+
25
+	NOTIFY_COLLABORATOR base.TplName = "mail/notify/collaborator"
26
+	NOTIFY_MENTION      base.TplName = "mail/notify/mention"
27
+)
28
+
20 29
 // Create New mail message use MailFrom and MailUser
21 30
 func NewMailMessageFrom(To []string, from, subject, body string) Message {
22 31
 	msg := NewHtmlMessage(To, from, subject, body)
@@ -61,7 +70,7 @@ func SendRegisterMail(r *middleware.Render, u *models.User) {
61 70
 
62 71
 	data := GetMailTmplData(u)
63 72
 	data["Code"] = code
64
-	body, err := r.HTMLString("mail/auth/register_success", data)
73
+	body, err := r.HTMLString(string(AUTH_REGISTER_SUCCESS), data)
65 74
 	if err != nil {
66 75
 		log.Error("mail.SendRegisterMail(fail to render): %v", err)
67 76
 		return
@@ -81,7 +90,7 @@ func SendActiveMail(r *middleware.Render, u *models.User) {
81 90
 
82 91
 	data := GetMailTmplData(u)
83 92
 	data["Code"] = code
84
-	body, err := r.HTMLString("mail/auth/active_email", data)
93
+	body, err := r.HTMLString(string(AUTH_ACTIVE), data)
85 94
 	if err != nil {
86 95
 		log.Error("mail.SendActiveMail(fail to render): %v", err)
87 96
 		return
@@ -101,7 +110,7 @@ func SendResetPasswdMail(r *middleware.Render, u *models.User) {
101 110
 
102 111
 	data := GetMailTmplData(u)
103 112
 	data["Code"] = code
104
-	body, err := r.HTMLString("mail/auth/reset_passwd", data)
113
+	body, err := r.HTMLString(string(AUTH_RESET_PASSWORD), data)
105 114
 	if err != nil {
106 115
 		log.Error("mail.SendResetPasswdMail(fail to render): %v", err)
107 116
 		return
@@ -161,7 +170,7 @@ func SendIssueMentionMail(r *middleware.Render, u, owner *models.User,
161 170
 	data["IssueLink"] = fmt.Sprintf("%s/%s/issues/%d", owner.Name, repo.Name, issue.Index)
162 171
 	data["Subject"] = subject
163 172
 
164
-	body, err := r.HTMLString("mail/notify/mention", data)
173
+	body, err := r.HTMLString(string(NOTIFY_MENTION), data)
165 174
 	if err != nil {
166 175
 		return fmt.Errorf("mail.SendIssueMentionMail(fail to render): %v", err)
167 176
 	}
@@ -182,7 +191,7 @@ func SendCollaboratorMail(r *middleware.Render, u, owner *models.User,
182 191
 	data["RepoLink"] = path.Join(owner.Name, repo.Name)
183 192
 	data["Subject"] = subject
184 193
 
185
-	body, err := r.HTMLString("mail/notify/collaborator", data)
194
+	body, err := r.HTMLString(string(NOTIFY_COLLABORATOR), data)
186 195
 	if err != nil {
187 196
 		return fmt.Errorf("mail.SendCollaboratorMail(fail to render): %v", err)
188 197
 	}

+ 4 - 4
modules/middleware/context.go

@@ -104,12 +104,12 @@ func (ctx *Context) HasError() bool {
104 104
 }
105 105
 
106 106
 // HTML calls render.HTML underlying but reduce one argument.
107
-func (ctx *Context) HTML(status int, name string, htmlOpt ...HTMLOptions) {
108
-	ctx.Render.HTML(status, name, ctx.Data, htmlOpt...)
107
+func (ctx *Context) HTML(status int, name base.TplName, htmlOpt ...HTMLOptions) {
108
+	ctx.Render.HTML(status, string(name), ctx.Data, htmlOpt...)
109 109
 }
110 110
 
111 111
 // RenderWithErr used for page has form validation but need to prompt error to users.
112
-func (ctx *Context) RenderWithErr(msg, tpl string, form auth.Form) {
112
+func (ctx *Context) RenderWithErr(msg string, tpl base.TplName, form auth.Form) {
113 113
 	if form != nil {
114 114
 		auth.AssignForm(form, ctx.Data)
115 115
 	}
@@ -133,7 +133,7 @@ func (ctx *Context) Handle(status int, title string, err error) {
133 133
 	case 500:
134 134
 		ctx.Data["Title"] = "Internal Server Error"
135 135
 	}
136
-	ctx.HTML(status, fmt.Sprintf("status/%d", status))
136
+	ctx.HTML(status, base.TplName(fmt.Sprintf("status/%d", status)))
137 137
 }
138 138
 
139 139
 func (ctx *Context) Debug(msg string, args ...interface{}) {

+ 2 - 2
modules/middleware/repo.go

@@ -46,7 +46,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
46 46
 
47 47
 		// Collaborators who have write access can be seen as owners.
48 48
 		if ctx.IsSigned {
49
-			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.AU_WRITABLE)
49
+			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
50 50
 			if err != nil {
51 51
 				ctx.Handle(500, "RepoAssignment(HasAccess)", err)
52 52
 				return
@@ -107,7 +107,7 @@ func RepoAssignment(redirect bool, args ...bool) martini.Handler {
107 107
 				return
108 108
 			}
109 109
 
110
-			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.AU_READABLE)
110
+			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
111 111
 			if err != nil {
112 112
 				ctx.Handle(500, "RepoAssignment(HasAccess)", err)
113 113
 				return

+ 7 - 7
modules/setting/setting.go

@@ -47,12 +47,12 @@ var (
47 47
 	StaticRootPath     string
48 48
 
49 49
 	// Security settings.
50
-	InstallLock         bool
51
-	SecretKey           string
52
-	LogInRememberDays   int
53
-	CookieUserName      string
54
-	CookieRememberName  string
55
-	ReverseProxyAuthUid string
50
+	InstallLock          bool
51
+	SecretKey            string
52
+	LogInRememberDays    int
53
+	CookieUserName       string
54
+	CookieRememberName   string
55
+	ReverseProxyAuthUser string
56 56
 
57 57
 	// Webhook settings.
58 58
 	WebhookTaskInterval   int
@@ -164,7 +164,7 @@ func NewConfigContext() {
164 164
 	LogInRememberDays = Cfg.MustInt("security", "LOGIN_REMEMBER_DAYS")
165 165
 	CookieUserName = Cfg.MustValue("security", "COOKIE_USERNAME")
166 166
 	CookieRememberName = Cfg.MustValue("security", "COOKIE_REMEMBER_NAME")
167
-	ReverseProxyAuthUid = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_UID", "X-WEBAUTH-UID")
167
+	ReverseProxyAuthUser = Cfg.MustValue("security", "REVERSE_PROXY_AUTHENTICATION_USER", "X-WEBAUTH-USER")
168 168
 
169 169
 	RunUser = Cfg.MustValue("", "RUN_USER")
170 170
 	curUser := os.Getenv("USER")

+ 114 - 3
public/css/gogs.css

@@ -257,6 +257,9 @@ html, body {
257 257
 
258 258
 .card .btn {
259 259
     cursor: pointer;
260
+}
261
+
262
+.card .btn-primary {
260 263
     margin-right: 1.2em;
261 264
 }
262 265
 
@@ -372,7 +375,7 @@ html, body {
372 375
 
373 376
 /* gogits repo create */
374 377
 
375
-#repo-create {
378
+#repo-create, #org-create, #org-teams-create, #org-teams-edit {
376 379
     width: 800px;
377 380
 }
378 381
 
@@ -638,7 +641,7 @@ html, body {
638 641
     margin: 0 .5em;
639 642
 }
640 643
 
641
-#dashboard-switch .btn {
644
+#dashboard-switch .btn, #repo-owner-switch .btn {
642 645
     height: 40px;
643 646
 }
644 647
 
@@ -647,7 +650,7 @@ html, body {
647 650
     margin-right: 18px;
648 651
 }
649 652
 
650
-#dashboard-switch .dropdown-menu {
653
+#dashboard-switch .dropdown-menu,#repo-owner-switch .dropdown-menu {
651 654
     padding: 0;
652 655
 }
653 656
 
@@ -662,6 +665,14 @@ html, body {
662 665
     padding: .8em 1.2em;
663 666
 }
664 667
 
668
+#dashboard-switch-menu > li > a:hover {
669
+    text-decoration: none;
670
+}
671
+
672
+#dashboard-switch-menu > li > a img, #dashboard-switch button img {
673
+    margin-right: 6px;
674
+}
675
+
665 676
 #dashboard-switch-menu > li {
666 677
     border-bottom: 1px solid #eaeaea;
667 678
 }
@@ -1864,16 +1875,44 @@ html, body {
1864 1875
     padding: 16px 0;
1865 1876
 }
1866 1877
 
1878
+#body-nav.org-nav.org-nav-auto {
1879
+    height: auto;
1880
+}
1881
+
1882
+.org-nav > .container {
1883
+    padding-left: 0;
1884
+    padding-left: 0;
1885
+}
1886
+
1867 1887
 .org-nav .org-logo {
1868 1888
     margin-right: 16px;
1869 1889
     width: 100px;
1870 1890
     height: 100px;
1871 1891
 }
1872 1892
 
1893
+.org-nav .org-small-logo {
1894
+    margin-right: 16px;
1895
+    width: 50px;
1896
+    height: 50px;
1897
+}
1898
+
1873 1899
 .org-nav .org-name {
1874 1900
     margin-top: 0;
1875 1901
 }
1876 1902
 
1903
+.org-nav-auto .org-name {
1904
+    font-size: 1.4em;
1905
+    line-height: 48px;
1906
+}
1907
+
1908
+#body-nav.org-nav-auto .nav {
1909
+    margin-top: 6px;
1910
+}
1911
+
1912
+#body-nav.org-nav-auto .nav a:hover {
1913
+    text-decoration: none;
1914
+}
1915
+
1877 1916
 .org-description {
1878 1917
     font-size: 16px;
1879 1918
 }
@@ -1894,6 +1933,10 @@ html, body {
1894 1933
     margin-left: 0;
1895 1934
 }
1896 1935
 
1936
+.org-main {
1937
+    padding-left: 0;
1938
+}
1939
+
1897 1940
 .org-sidebar {
1898 1941
     margin-top: -100px;
1899 1942
 }
@@ -1947,4 +1990,72 @@ html, body {
1947 1990
 
1948 1991
 .org-team a:hover .org-team-name {
1949 1992
     color: #0079bc !important;
1993
+}
1994
+
1995
+#org-members {
1996
+    margin-right: 30px;
1997
+}
1998
+
1999
+#org-members .member .avatar img {
2000
+    width: 50px;
2001
+    height: 50px;
2002
+}
2003
+
2004
+#org-members .member {
2005
+    padding-bottom: 20px;
2006
+    margin-bottom: 20px;
2007
+    border-bottom: 1px solid #DDD;
2008
+    height: 70px;
2009
+}
2010
+
2011
+#org-members .member .name {
2012
+    padding-top: 4px;
2013
+}
2014
+
2015
+#org-members .member .nick {
2016
+    display: block;
2017
+    color: #888;
2018
+}
2019
+
2020
+#org-members .member .name a {
2021
+    color: #444;
2022
+}
2023
+
2024
+#org-members .member .name strong {
2025
+    font-size: 1.2em;
2026
+}
2027
+
2028
+#org-members .status, #org-members .role {
2029
+    line-height: 48px;
2030
+    text-align: right;
2031
+}
2032
+
2033
+#org-teams .org-team .panel-heading {
2034
+    margin-top: 0;
2035
+}
2036
+
2037
+#org-teams .org-team .panel-heading a {
2038
+    color: #444;
2039
+}
2040
+
2041
+#org-teams .org-team-members {
2042
+    margin-top: 18px;
2043
+}
2044
+
2045
+#org-teams .org-team-members img {
2046
+    width: 40px;
2047
+    height: 40px;
2048
+    margin-right: 12px;
2049
+}
2050
+
2051
+#org-teams .org-team-members a {
2052
+    display: inline-block;
2053
+}
2054
+
2055
+#org-teams .org-team .panel-footer {
2056
+    height: 60px;
2057
+}
2058
+
2059
+#org-teams .org-team {
2060
+    border-bottom: none;
1950 2061
 }

+ 24 - 0
public/js/app.js

@@ -758,6 +758,27 @@ function initRepoSetting() {
758 758
     });
759 759
 }
760 760
 
761
+function initRepoCreating() {
762
+    // owner switch menu click
763
+    (function () {
764
+        $('#repo-owner-switch .dropdown-menu').on("click", "li", function () {
765
+            var uid = $(this).data('uid');
766
+            // set to input
767
+            $('#repo-owner-id').val(uid);
768
+            // set checked class
769
+            if (!$(this).hasClass("checked")) {
770
+                $(this).parent().find(".checked").removeClass("checked");
771
+                $(this).addClass("checked");
772
+            }
773
+            // set button group to show clicked owner
774
+            $('#repo-owner-avatar').attr("src",$(this).find('img').attr("src"));
775
+            $('#repo-owner-name').text($(this).text().trim());
776
+            console.log("set repo owner to uid :",uid,$(this).text().trim());
777
+        });
778
+    }());
779
+    console.log("init repo-creating scripts");
780
+}
781
+
761 782
 (function ($) {
762 783
     $(function () {
763 784
         initCore();
@@ -780,6 +801,9 @@ function initRepoSetting() {
780 801
         if ($('#repo-setting-container').length) {
781 802
             initRepoSetting();
782 803
         }
804
+        if ($('#repo-create').length) {
805
+            initRepoCreating();
806
+        }
783 807
     });
784 808
 })(jQuery);
785 809
 

+ 19 - 10
routers/admin/admin.go

@@ -20,6 +20,16 @@ import (
20 20
 	"github.com/gogits/gogs/modules/setting"
21 21
 )
22 22
 
23
+const (
24
+	DASHBOARD       base.TplName = "admin/dashboard"
25
+	USERS           base.TplName = "admin/users"
26
+	REPOS           base.TplName = "admin/repos"
27
+	AUTHS           base.TplName = "admin/auths"
28
+	CONFIG          base.TplName = "admin/config"
29
+	MONITOR_PROCESS base.TplName = "admin/monitor/process"
30
+	MONITOR_CRON    base.TplName = "admin/monitor/cron"
31
+)
32
+
23 33
 var startTime = time.Now()
24 34
 
25 35
 var sysStatus struct {
@@ -140,7 +150,7 @@ func Dashboard(ctx *middleware.Context) {
140 150
 	ctx.Data["Stats"] = models.GetStatistic()
141 151
 	updateSystemStatus()
142 152
 	ctx.Data["SysStatus"] = sysStatus
143
-	ctx.HTML(200, "admin/dashboard")
153
+	ctx.HTML(200, DASHBOARD)
144 154
 }
145 155
 
146 156
 func Users(ctx *middleware.Context) {
@@ -150,10 +160,10 @@ func Users(ctx *middleware.Context) {
150 160
 	var err error
151 161
 	ctx.Data["Users"], err = models.GetUsers(200, 0)
152 162
 	if err != nil {
153
-		ctx.Handle(500, "admin.Users", err)
163
+		ctx.Handle(500, "admin.Users(GetUsers)", err)
154 164
 		return
155 165
 	}
156
-	ctx.HTML(200, "admin/users")
166
+	ctx.HTML(200, USERS)
157 167
 }
158 168
 
159 169
 func Repositories(ctx *middleware.Context) {
@@ -166,7 +176,7 @@ func Repositories(ctx *middleware.Context) {
166 176
 		ctx.Handle(500, "admin.Repositories", err)
167 177
 		return
168 178
 	}
169
-	ctx.HTML(200, "admin/repos")
179
+	ctx.HTML(200, REPOS)
170 180
 }
171 181
 
172 182
 func Auths(ctx *middleware.Context) {
@@ -179,7 +189,7 @@ func Auths(ctx *middleware.Context) {
179 189
 		ctx.Handle(500, "admin.Auths", err)
180 190
 		return
181 191
 	}
182
-	ctx.HTML(200, "admin/auths")
192
+	ctx.HTML(200, AUTHS)
183 193
 }
184 194
 
185 195
 func Config(ctx *middleware.Context) {
@@ -196,7 +206,7 @@ func Config(ctx *middleware.Context) {
196 206
 	ctx.Data["StaticRootPath"] = setting.StaticRootPath
197 207
 	ctx.Data["LogRootPath"] = setting.LogRootPath
198 208
 	ctx.Data["ScriptType"] = setting.ScriptType
199
-	ctx.Data["ReverseProxyAuthUid"] = setting.ReverseProxyAuthUid
209
+	ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
200 210
 
201 211
 	ctx.Data["Service"] = setting.Service
202 212
 
@@ -235,7 +245,7 @@ func Config(ctx *middleware.Context) {
235 245
 	}
236 246
 	ctx.Data["Loggers"] = loggers
237 247
 
238
-	ctx.HTML(200, "admin/config")
248
+	ctx.HTML(200, CONFIG)
239 249
 }
240 250
 
241 251
 func Monitor(ctx *middleware.Context) {
@@ -247,11 +257,10 @@ func Monitor(ctx *middleware.Context) {
247 257
 	case "process":
248 258
 		ctx.Data["PageIsMonitorProcess"] = true
249 259
 		ctx.Data["Processes"] = process.Processes
250
-		ctx.HTML(200, "admin/monitor/process")
260
+		ctx.HTML(200, MONITOR_PROCESS)
251 261
 	default:
252 262
 		ctx.Data["PageIsMonitorCron"] = true
253 263
 		ctx.Data["Entries"] = cron.ListEntries()
254
-		ctx.HTML(200, "admin/monitor/cron")
264
+		ctx.HTML(200, MONITOR_CRON)
255 265
 	}
256
-
257 266
 }

+ 14 - 9
routers/admin/auths.go

@@ -18,12 +18,17 @@ import (
18 18
 	"github.com/gogits/gogs/modules/middleware"
19 19
 )
20 20
 
21
+const (
22
+	AUTH_NEW  base.TplName = "admin/auth/new"
23
+	AUTH_EDIT base.TplName = "admin/auth/edit"
24
+)
25
+
21 26
 func NewAuthSource(ctx *middleware.Context) {
22 27
 	ctx.Data["Title"] = "New Authentication"
23 28
 	ctx.Data["PageIsAuths"] = true
24 29
 	ctx.Data["LoginTypes"] = models.LoginTypes
25 30
 	ctx.Data["SMTPAuths"] = models.SMTPAuths
26
-	ctx.HTML(200, "admin/auths/new")
31
+	ctx.HTML(200, AUTH_NEW)
27 32
 }
28 33
 
29 34
 func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
@@ -33,7 +38,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
33 38
 	ctx.Data["SMTPAuths"] = models.SMTPAuths
34 39
 
35 40
 	if ctx.HasError() {
36
-		ctx.HTML(200, "admin/auths/new")
41
+		ctx.HTML(200, AUTH_NEW)
37 42
 		return
38 43
 	}
39 44
 
@@ -74,7 +79,7 @@ func NewAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
74 79
 	}
75 80
 
76 81
 	if err := models.CreateSource(source); err != nil {
77
-		ctx.Handle(500, "admin.auths.NewAuth", err)
82
+		ctx.Handle(500, "admin.auths.NewAuth(CreateSource)", err)
78 83
 		return
79 84
 	}
80 85
 
@@ -97,11 +102,11 @@ func EditAuthSource(ctx *middleware.Context, params martini.Params) {
97 102
 	}
98 103
 	u, err := models.GetLoginSourceById(id)
99 104
 	if err != nil {
100
-		ctx.Handle(500, "admin.user.EditUser", err)
105
+		ctx.Handle(500, "admin.user.EditUser(GetLoginSourceById)", err)
101 106
 		return
102 107
 	}
103 108
 	ctx.Data["Source"] = u
104
-	ctx.HTML(200, "admin/auths/edit")
109
+	ctx.HTML(200, AUTH_EDIT)
105 110
 }
106 111
 
107 112
 func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
@@ -111,7 +116,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
111 116
 	ctx.Data["SMTPAuths"] = models.SMTPAuths
112 117
 
113 118
 	if ctx.HasError() {
114
-		ctx.HTML(200, "admin/auths/edit")
119
+		ctx.HTML(200, AUTH_EDIT)
115 120
 		return
116 121
 	}
117 122
 
@@ -153,7 +158,7 @@ func EditAuthSourcePost(ctx *middleware.Context, form auth.AuthenticationForm) {
153 158
 	}
154 159
 
155 160
 	if err := models.UpdateSource(&u); err != nil {
156
-		ctx.Handle(500, "admin.auths.EditAuth", err)
161
+		ctx.Handle(500, "admin.auths.EditAuth(UpdateSource)", err)
157 162
 		return
158 163
 	}
159 164
 
@@ -175,7 +180,7 @@ func DeleteAuthSource(ctx *middleware.Context, params martini.Params) {
175 180
 
176 181
 	a, err := models.GetLoginSourceById(id)
177 182
 	if err != nil {
178
-		ctx.Handle(500, "admin.auths.DeleteAuth", err)
183
+		ctx.Handle(500, "admin.auths.DeleteAuth(GetLoginSourceById)", err)
179 184
 		return
180 185
 	}
181 186
 
@@ -185,7 +190,7 @@ func DeleteAuthSource(ctx *middleware.Context, params martini.Params) {
185 190
 			ctx.Flash.Error("This authentication still has used by some users, you should move them and then delete again.")
186 191
 			ctx.Redirect("/admin/auths/" + params["authid"])
187 192
 		default:
188
-			ctx.Handle(500, "admin.auths.DeleteAuth", err)
193
+			ctx.Handle(500, "admin.auths.DeleteAuth(DelLoginSource)", err)
189 194
 		}
190 195
 		return
191 196
 	}

+ 29 - 21
routers/admin/user.go

@@ -5,8 +5,6 @@
5 5
 package admin
6 6
 
7 7
 import (
8
-	"fmt"
9
-	"strconv"
10 8
 	"strings"
11 9
 
12 10
 	"github.com/go-martini/martini"
@@ -18,16 +16,21 @@ import (
18 16
 	"github.com/gogits/gogs/modules/middleware"
19 17
 )
20 18
 
19
+const (
20
+	USER_NEW  base.TplName = "admin/user/new"
21
+	USER_EDIT base.TplName = "admin/user/edit"
22
+)
23
+
21 24
 func NewUser(ctx *middleware.Context) {
22 25
 	ctx.Data["Title"] = "New Account"
23 26
 	ctx.Data["PageIsUsers"] = true
24 27
 	auths, err := models.GetAuths()
25 28
 	if err != nil {
26
-		ctx.Handle(500, "admin.user.NewUser", err)
29
+		ctx.Handle(500, "admin.user.NewUser(GetAuths)", err)
27 30
 		return
28 31
 	}
29 32
 	ctx.Data["LoginSources"] = auths
30
-	ctx.HTML(200, "admin/users/new")
33
+	ctx.HTML(200, USER_NEW)
31 34
 }
32 35
 
33 36
 func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
@@ -35,7 +38,7 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
35 38
 	ctx.Data["PageIsUsers"] = true
36 39
 
37 40
 	if ctx.HasError() {
38
-		ctx.HTML(200, "admin/users/new")
41
+		ctx.HTML(200, USER_NEW)
39 42
 		return
40 43
 	}
41 44
 
@@ -55,25 +58,25 @@ func NewUserPost(ctx *middleware.Context, form auth.RegisterForm) {
55 58
 	}
56 59
 
57 60
 	if len(form.LoginType) > 0 {
61
+		// NOTE: need rewrite.
58 62
 		fields := strings.Split(form.LoginType, "-")
59
-		tp, _ := strconv.Atoi(fields[0])
63
+		tp, _ := base.StrTo(fields[0]).Int()
60 64
 		u.LoginType = models.LoginType(tp)
61
-		u.LoginSource, _ = strconv.ParseInt(fields[1], 10, 64)
65
+		u.LoginSource, _ = base.StrTo(fields[1]).Int64()
62 66
 		u.LoginName = form.LoginName
63
-		fmt.Println(u.LoginType, u.LoginSource, u.LoginName)
64 67
 	}
65 68
 
66 69
 	var err error
67
-	if u, err = models.RegisterUser(u); err != nil {
70
+	if u, err = models.CreateUser(u); err != nil {
68 71
 		switch err {
69 72
 		case models.ErrUserAlreadyExist:
70
-			ctx.RenderWithErr("Username has been already taken", "admin/users/new", &form)
73
+			ctx.RenderWithErr("Username has been already taken", USER_NEW, &form)
71 74
 		case models.ErrEmailAlreadyUsed:
72
-			ctx.RenderWithErr("E-mail address has been already used", "admin/users/new", &form)
75
+			ctx.RenderWithErr("E-mail address has been already used", USER_NEW, &form)
73 76
 		case models.ErrUserNameIllegal:
74
-			ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), "admin/users/new", &form)
77
+			ctx.RenderWithErr(models.ErrRepoNameIllegal.Error(), USER_NEW, &form)
75 78
 		default:
76
-			ctx.Handle(500, "admin.user.NewUser", err)
79
+			ctx.Handle(500, "admin.user.NewUser(CreateUser)", err)
77 80
 		}
78 81
 		return
79 82
 	}
@@ -96,18 +99,18 @@ func EditUser(ctx *middleware.Context, params martini.Params) {
96 99
 
97 100
 	u, err := models.GetUserById(int64(uid))
98 101
 	if err != nil {
99
-		ctx.Handle(500, "admin.user.EditUser", err)
102
+		ctx.Handle(500, "admin.user.EditUser(GetUserById)", err)
100 103
 		return
101 104
 	}
102 105
 
103 106
 	ctx.Data["User"] = u
104 107
 	auths, err := models.GetAuths()
105 108
 	if err != nil {
106
-		ctx.Handle(500, "admin.user.NewUser", err)
109
+		ctx.Handle(500, "admin.user.NewUser(GetAuths)", err)
107 110
 		return
108 111
 	}
109 112
 	ctx.Data["LoginSources"] = auths
110
-	ctx.HTML(200, "admin/users/edit")
113
+	ctx.HTML(200, USER_EDIT)
111 114
 }
112 115
 
113 116
 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
116 119
 
117 120
 	uid, err := base.StrTo(params["userid"]).Int()
118 121
 	if err != nil {
119
-		ctx.Handle(404, "admin.user.EditUser", err)
122
+		ctx.Handle(404, "admin.user.EditUserPost", err)
120 123
 		return
121 124
 	}
122 125
 
123 126
 	u, err := models.GetUserById(int64(uid))
124 127
 	if err != nil {
125
-		ctx.Handle(500, "admin.user.EditUser", err)
128
+		ctx.Handle(500, "admin.user.EditUserPost(GetUserById)", err)
129
+		return
130
+	}
131
+
132
+	if ctx.HasError() {
133
+		ctx.HTML(200, USER_EDIT)
126 134
 		return
127 135
 	}
128 136
 
@@ -134,7 +142,7 @@ func EditUserPost(ctx *middleware.Context, params martini.Params, form auth.Admi
134 142
 	u.IsActive = form.Active
135 143
 	u.IsAdmin = form.Admin
136 144
 	if err := models.UpdateUser(u); err != nil {
137
-		ctx.Handle(500, "admin.user.EditUser", err)
145
+		ctx.Handle(500, "admin.user.EditUserPost(UpdateUser)", err)
138 146
 		return
139 147
 	}
140 148
 	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) {
152 160
 	//log.Info("delete")
153 161
 	uid, err := base.StrTo(params["userid"]).Int()
154 162
 	if err != nil {
155
-		ctx.Handle(404, "admin.user.EditUser", err)
163
+		ctx.Handle(404, "admin.user.DeleteUser", err)
156 164
 		return
157 165
 	}
158 166
 
159 167
 	u, err := models.GetUserById(int64(uid))
160 168
 	if err != nil {
161
-		ctx.Handle(500, "admin.user.EditUser", err)
169
+		ctx.Handle(500, "admin.user.DeleteUser(GetUserById)", err)
162 170
 		return
163 171
 	}
164 172
 

+ 6 - 1
routers/dashboard.go

@@ -6,11 +6,16 @@ package routers
6 6
 
7 7
 import (
8 8
 	"github.com/gogits/gogs/models"
9
+	"github.com/gogits/gogs/modules/base"
9 10
 	"github.com/gogits/gogs/modules/middleware"
10 11
 	"github.com/gogits/gogs/modules/setting"
11 12
 	"github.com/gogits/gogs/routers/user"
12 13
 )
13 14
 
15
+const (
16
+	HOME base.TplName = "home"
17
+)
18
+
14 19
 func Home(ctx *middleware.Context) {
15 20
 	if ctx.IsSigned {
16 21
 		user.Dashboard(ctx)
@@ -40,7 +45,7 @@ func Home(ctx *middleware.Context) {
40 45
 		}
41 46
 	}
42 47
 	ctx.Data["Repos"] = repos
43
-	ctx.HTML(200, "home")
48
+	ctx.HTML(200, HOME)
44 49
 }
45 50
 
46 51
 func NotFound(ctx *middleware.Context) {

+ 2 - 1
routers/dev/template.go

@@ -8,6 +8,7 @@ import (
8 8
 	"github.com/go-martini/martini"
9 9
 
10 10
 	"github.com/gogits/gogs/models"
11
+	"github.com/gogits/gogs/modules/base"
11 12
 	"github.com/gogits/gogs/modules/middleware"
12 13
 	"github.com/gogits/gogs/modules/setting"
13 14
 )
@@ -22,5 +23,5 @@ func TemplatePreview(ctx *middleware.Context, params martini.Params) {
22 23
 	ctx.Data["ActiveCodeLives"] = setting.Service.ActiveCodeLives / 60
23 24
 	ctx.Data["ResetPwdCodeLives"] = setting.Service.ResetPwdCodeLives / 60
24 25
 	ctx.Data["CurDbValue"] = ""
25
-	ctx.HTML(200, params["_1"])
26
+	ctx.HTML(200, base.TplName(params["_1"]))
26 27
 }

+ 17 - 11
routers/install.go

@@ -26,6 +26,10 @@ import (
26 26
 	"github.com/gogits/gogs/modules/social"
27 27
 )
28 28
 
29
+const (
30
+	INSTALL base.TplName = "install"
31
+)
32
+
29 33
 func checkRunMode() {
30 34
 	switch setting.Cfg.MustValue("", "RUN_MODE") {
31 35
 	case "prod":
@@ -72,6 +76,7 @@ func renderDbOption(ctx *middleware.Context) {
72 76
 	ctx.Data["DbOptions"] = []string{"MySQL", "PostgreSQL", "SQLite3"}
73 77
 }
74 78
 
79
+// @router /install [get]
75 80
 func Install(ctx *middleware.Context, form auth.InstallForm) {
76 81
 	if setting.InstallLock {
77 82
 		ctx.Handle(404, "install.Install", errors.New("Installation is prohibited"))
@@ -119,12 +124,12 @@ func Install(ctx *middleware.Context, form auth.InstallForm) {
119 124
 	ctx.Data["CurDbOption"] = curDbOp
120 125
 
121 126
 	auth.AssignForm(form, ctx.Data)
122
-	ctx.HTML(200, "install")
127
+	ctx.HTML(200, INSTALL)
123 128
 }
124 129
 
125 130
 func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
126 131
 	if setting.InstallLock {
127
-		ctx.Handle(404, "install.Install", errors.New("Installation is prohibited"))
132
+		ctx.Handle(404, "install.InstallPost", errors.New("Installation is prohibited"))
128 133
 		return
129 134
 	}
130 135
 
@@ -135,12 +140,12 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
135 140
 	ctx.Data["CurDbOption"] = form.Database
136 141
 
137 142
 	if ctx.HasError() {
138
-		ctx.HTML(200, "install")
143
+		ctx.HTML(200, INSTALL)
139 144
 		return
140 145
 	}
141 146
 
142 147
 	if _, err := exec.LookPath("git"); err != nil {
143
-		ctx.RenderWithErr("Fail to test 'git' command: "+err.Error(), "install", &form)
148
+		ctx.RenderWithErr("Fail to test 'git' command: "+err.Error(), INSTALL, &form)
144 149
 		return
145 150
 	}
146 151
 
@@ -158,18 +163,19 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
158 163
 	// Set test engine.
159 164
 	var x *xorm.Engine
160 165
 	if err := models.NewTestEngine(x); err != nil {
166
+		// NOTE: should use core.QueryDriver (github.com/go-xorm/core)
161 167
 		if strings.Contains(err.Error(), `Unknown database type: sqlite3`) {
162 168
 			ctx.RenderWithErr("Your release version does not support SQLite3, please download the official binary version "+
163
-				"from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version.", "install", &form)
169
+				"from http://gogs.io/docs/installation/install_from_binary.md, NOT the gobuild version.", INSTALL, &form)
164 170
 		} else {
165
-			ctx.RenderWithErr("Database setting is not correct: "+err.Error(), "install", &form)
171
+			ctx.RenderWithErr("Database setting is not correct: "+err.Error(), INSTALL, &form)
166 172
 		}
167 173
 		return
168 174
 	}
169 175
 
170 176
 	// Test repository root path.
171 177
 	if err := os.MkdirAll(form.RepoRootPath, os.ModePerm); err != nil {
172
-		ctx.RenderWithErr("Repository root path is invalid: "+err.Error(), "install", &form)
178
+		ctx.RenderWithErr("Repository root path is invalid: "+err.Error(), INSTALL, &form)
173 179
 		return
174 180
 	}
175 181
 
@@ -180,7 +186,7 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
180 186
 	}
181 187
 	// Does not check run user when the install lock is off.
182 188
 	if form.RunUser != curUser {
183
-		ctx.RenderWithErr("Run user isn't the current user: "+form.RunUser+" -> "+curUser, "install", &form)
189
+		ctx.RenderWithErr("Run user isn't the current user: "+form.RunUser+" -> "+curUser, INSTALL, &form)
184 190
 		return
185 191
 	}
186 192
 
@@ -214,18 +220,18 @@ func InstallPost(ctx *middleware.Context, form auth.InstallForm) {
214 220
 
215 221
 	os.MkdirAll("custom/conf", os.ModePerm)
216 222
 	if err := goconfig.SaveConfigFile(setting.Cfg, path.Join(setting.CustomPath, "conf/app.ini")); err != nil {
217
-		ctx.RenderWithErr("Fail to save configuration: "+err.Error(), "install", &form)
223
+		ctx.RenderWithErr("Fail to save configuration: "+err.Error(), INSTALL, &form)
218 224
 		return
219 225
 	}
220 226
 
221 227
 	GlobalInit()
222 228
 
223 229
 	// Create admin account.
224
-	if _, err := models.RegisterUser(&models.User{Name: form.AdminName, Email: form.AdminEmail, Passwd: form.AdminPasswd,
230
+	if _, err := models.CreateUser(&models.User{Name: form.AdminName, Email: form.AdminEmail, Passwd: form.AdminPasswd,
225 231
 		IsAdmin: true, IsActive: true}); err != nil {
226 232
 		if err != models.ErrUserAlreadyExist {
227 233
 			setting.InstallLock = false
228
-			ctx.RenderWithErr("Admin account setting is invalid: "+err.Error(), "install", &form)
234
+			ctx.RenderWithErr("Admin account setting is invalid: "+err.Error(), INSTALL, &form)
229 235
 			return
230 236
 		}
231 237
 		log.Info("Admin account already exist")

+ 152 - 1
routers/org/org.go

@@ -1,11 +1,162 @@
1
+// Copyright 2014 The Gogs Authors. All rights reserved.
2
+// Use of this source code is governed by a MIT-style
3
+// license that can be found in the LICENSE file.
4
+
1 5
 package org
2 6
 
3 7
 import (
4 8
 	"github.com/go-martini/martini"
9
+
10
+	"github.com/gogits/gogs/models"
11
+	"github.com/gogits/gogs/modules/auth"
12
+	"github.com/gogits/gogs/modules/base"
13
+	"github.com/gogits/gogs/modules/log"
5