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