| @@ -5,7 +5,7 @@ Gogs - Go Git Service [ | |||
| ##### Current version: 0.7.21 Beta | |||
| ##### Current version: 0.7.22 Beta | |||
| <table> | |||
| <tr> | |||
| @@ -395,7 +395,7 @@ func runWeb(ctx *cli.Context) { | |||
| m.Get("/teams/:team/repositories", org.TeamRepositories) | |||
| m.Route("/teams/:team/action/:action", "GET,POST", org.TeamsAction) | |||
| m.Route("/teams/:team/action/repo/:action", "GET,POST", org.TeamsRepoAction) | |||
| }, middleware.OrgAssignment(true, true)) | |||
| }, middleware.OrgAssignment(true)) | |||
| m.Group("/:org", func() { | |||
| m.Get("/teams/new", org.NewTeam) | |||
| @@ -424,11 +424,8 @@ func runWeb(ctx *cli.Context) { | |||
| }) | |||
| m.Route("/invitations/new", "GET,POST", org.Invitation) | |||
| }, middleware.OrgAssignment(true, true, true)) | |||
| }, middleware.OrgAssignment(true, true)) | |||
| }, reqSignIn) | |||
| m.Group("/org", func() { | |||
| m.Get("/:org", org.Home) | |||
| }, ignSignIn, middleware.OrgAssignment(true)) | |||
| // ***** END: Organization ***** | |||
| // ***** START: Repository ***** | |||
| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.7.21.1124 Beta" | |||
| const APP_VER = "0.7.22.1124 Beta" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -145,9 +145,6 @@ func (u *User) DashboardLink() string { | |||
| // HomeLink returns the user or organization home page link. | |||
| func (u *User) HomeLink() string { | |||
| if u.IsOrganization() { | |||
| return setting.AppSubUrl + "/org/" + u.Name | |||
| } | |||
| return setting.AppSubUrl + "/" + u.Name | |||
| } | |||
| @@ -8,97 +8,94 @@ import ( | |||
| "gopkg.in/macaron.v1" | |||
| "github.com/gogits/gogs/models" | |||
| "github.com/gogits/gogs/modules/log" | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| func OrgAssignment(redirect bool, args ...bool) macaron.Handler { | |||
| return func(ctx *Context) { | |||
| var ( | |||
| requireMember bool | |||
| requireOwner bool | |||
| requireAdminTeam bool | |||
| ) | |||
| if len(args) >= 1 { | |||
| requireMember = args[0] | |||
| } | |||
| if len(args) >= 2 { | |||
| requireOwner = args[1] | |||
| } | |||
| if len(args) >= 3 { | |||
| requireAdminTeam = args[2] | |||
| } | |||
| func HandleOrgAssignment(ctx *Context, args ...bool) { | |||
| var ( | |||
| requireMember bool | |||
| requireOwner bool | |||
| requireAdminTeam bool | |||
| ) | |||
| if len(args) >= 1 { | |||
| requireMember = args[0] | |||
| } | |||
| if len(args) >= 2 { | |||
| requireOwner = args[1] | |||
| } | |||
| if len(args) >= 3 { | |||
| requireAdminTeam = args[2] | |||
| } | |||
| orgName := ctx.Params(":org") | |||
| orgName := ctx.Params(":org") | |||
| var err error | |||
| ctx.Org.Organization, err = models.GetUserByName(orgName) | |||
| if err != nil { | |||
| if models.IsErrUserNotExist(err) { | |||
| ctx.Handle(404, "GetUserByName", err) | |||
| } else if redirect { | |||
| log.Error(4, "GetUserByName", err) | |||
| ctx.Redirect(setting.AppSubUrl + "/") | |||
| } else { | |||
| ctx.Handle(500, "GetUserByName", err) | |||
| } | |||
| return | |||
| var err error | |||
| ctx.Org.Organization, err = models.GetUserByName(orgName) | |||
| if err != nil { | |||
| if models.IsErrUserNotExist(err) { | |||
| ctx.Handle(404, "GetUserByName", err) | |||
| } else { | |||
| ctx.Handle(500, "GetUserByName", err) | |||
| } | |||
| org := ctx.Org.Organization | |||
| ctx.Data["Org"] = org | |||
| return | |||
| } | |||
| org := ctx.Org.Organization | |||
| ctx.Data["Org"] = org | |||
| // Force redirection when username is actually a user. | |||
| if !org.IsOrganization() { | |||
| ctx.Redirect("/" + org.Name) | |||
| return | |||
| } | |||
| // Force redirection when username is actually a user. | |||
| if !org.IsOrganization() { | |||
| ctx.Redirect("/" + org.Name) | |||
| return | |||
| } | |||
| if ctx.IsSigned { | |||
| ctx.Org.IsOwner = org.IsOwnedBy(ctx.User.Id) | |||
| if ctx.Org.IsOwner { | |||
| if ctx.IsSigned { | |||
| ctx.Org.IsOwner = org.IsOwnedBy(ctx.User.Id) | |||
| if ctx.Org.IsOwner { | |||
| ctx.Org.IsMember = true | |||
| ctx.Org.IsAdminTeam = true | |||
| } else { | |||
| if org.IsOrgMember(ctx.User.Id) { | |||
| ctx.Org.IsMember = true | |||
| ctx.Org.IsAdminTeam = true | |||
| } else { | |||
| if org.IsOrgMember(ctx.User.Id) { | |||
| ctx.Org.IsMember = true | |||
| } | |||
| } | |||
| } else { | |||
| // Fake data. | |||
| ctx.Data["SignedUser"] = &models.User{} | |||
| } | |||
| if (requireMember && !ctx.Org.IsMember) || | |||
| (requireOwner && !ctx.Org.IsOwner) { | |||
| ctx.Handle(404, "OrgAssignment", err) | |||
| return | |||
| } | |||
| ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner | |||
| } else { | |||
| // Fake data. | |||
| ctx.Data["SignedUser"] = &models.User{} | |||
| } | |||
| if (requireMember && !ctx.Org.IsMember) || | |||
| (requireOwner && !ctx.Org.IsOwner) { | |||
| ctx.Handle(404, "OrgAssignment", err) | |||
| return | |||
| } | |||
| ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner | |||
| ctx.Org.OrgLink = setting.AppSubUrl + "/org/" + org.Name | |||
| ctx.Data["OrgLink"] = ctx.Org.OrgLink | |||
| ctx.Org.OrgLink = setting.AppSubUrl + "/org/" + org.Name | |||
| ctx.Data["OrgLink"] = ctx.Org.OrgLink | |||
| // Team. | |||
| teamName := ctx.Params(":team") | |||
| if len(teamName) > 0 { | |||
| ctx.Org.Team, err = org.GetTeam(teamName) | |||
| if err != nil { | |||
| if err == models.ErrTeamNotExist { | |||
| ctx.Handle(404, "GetTeam", err) | |||
| } else if redirect { | |||
| log.Error(4, "GetTeam", err) | |||
| ctx.Redirect(setting.AppSubUrl + "/") | |||
| } else { | |||
| ctx.Handle(500, "GetTeam", err) | |||
| } | |||
| return | |||
| // Team. | |||
| teamName := ctx.Params(":team") | |||
| if len(teamName) > 0 { | |||
| ctx.Org.Team, err = org.GetTeam(teamName) | |||
| if err != nil { | |||
| if err == models.ErrTeamNotExist { | |||
| ctx.Handle(404, "GetTeam", err) | |||
| } else { | |||
| ctx.Handle(500, "GetTeam", err) | |||
| } | |||
| ctx.Data["Team"] = ctx.Org.Team | |||
| ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.ACCESS_MODE_ADMIN | |||
| } | |||
| ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam | |||
| if requireAdminTeam && !ctx.Org.IsAdminTeam { | |||
| ctx.Handle(404, "OrgAssignment", err) | |||
| return | |||
| } | |||
| ctx.Data["Team"] = ctx.Org.Team | |||
| ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.ACCESS_MODE_ADMIN | |||
| } | |||
| ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam | |||
| if requireAdminTeam && !ctx.Org.IsAdminTeam { | |||
| ctx.Handle(404, "OrgAssignment", err) | |||
| return | |||
| } | |||
| } | |||
| func OrgAssignment(args ...bool) macaron.Handler { | |||
| return func(ctx *Context) { | |||
| HandleOrgAssignment(ctx, args...) | |||
| } | |||
| } | |||
| @@ -14,36 +14,9 @@ import ( | |||
| ) | |||
| const ( | |||
| HOME base.TplName = "org/home" | |||
| CREATE base.TplName = "org/create" | |||
| ) | |||
| func Home(ctx *middleware.Context) { | |||
| org := ctx.Org.Organization | |||
| ctx.Data["Title"] = org.FullName | |||
| repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id)) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetRepositories", err) | |||
| return | |||
| } | |||
| ctx.Data["Repos"] = repos | |||
| if err = org.GetMembers(); err != nil { | |||
| ctx.Handle(500, "GetMembers", err) | |||
| return | |||
| } | |||
| ctx.Data["Members"] = org.Members | |||
| if err = org.GetTeams(); err != nil { | |||
| ctx.Handle(500, "GetTeams", err) | |||
| return | |||
| } | |||
| ctx.Data["Teams"] = org.Teams | |||
| ctx.HTML(200, HOME) | |||
| } | |||
| func Create(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = ctx.Tr("new_org") | |||
| ctx.HTML(200, CREATE) | |||
| @@ -23,6 +23,7 @@ const ( | |||
| ISSUES base.TplName = "user/dashboard/issues" | |||
| STARS base.TplName = "user/stars" | |||
| PROFILE base.TplName = "user/profile" | |||
| ORG_HOME base.TplName = "org/home" | |||
| ) | |||
| func getDashboardContextUser(ctx *middleware.Context) *models.User { | |||
| @@ -305,6 +306,38 @@ func ShowSSHKeys(ctx *middleware.Context, uid int64) { | |||
| ctx.PlainText(200, buf.Bytes()) | |||
| } | |||
| func showOrgProfile(ctx *middleware.Context) { | |||
| ctx.SetParams(":org", ctx.Params(":username")) | |||
| middleware.HandleOrgAssignment(ctx) | |||
| if ctx.Written() { | |||
| return | |||
| } | |||
| org := ctx.Org.Organization | |||
| ctx.Data["Title"] = org.FullName | |||
| repos, err := models.GetRepositories(org.Id, ctx.IsSigned && org.IsOrgMember(ctx.User.Id)) | |||
| if err != nil { | |||
| ctx.Handle(500, "GetRepositories", err) | |||
| return | |||
| } | |||
| ctx.Data["Repos"] = repos | |||
| if err = org.GetMembers(); err != nil { | |||
| ctx.Handle(500, "GetMembers", err) | |||
| return | |||
| } | |||
| ctx.Data["Members"] = org.Members | |||
| if err = org.GetTeams(); err != nil { | |||
| ctx.Handle(500, "GetTeams", err) | |||
| return | |||
| } | |||
| ctx.Data["Teams"] = org.Teams | |||
| ctx.HTML(200, ORG_HOME) | |||
| } | |||
| func Profile(ctx *middleware.Context) { | |||
| ctx.Data["Title"] = "Profile" | |||
| ctx.Data["PageIsUserProfile"] = true | |||
| @@ -342,7 +375,7 @@ func Profile(ctx *middleware.Context) { | |||
| } | |||
| if u.IsOrganization() { | |||
| ctx.Redirect(setting.AppSubUrl + "/org/" + u.Name) | |||
| showOrgProfile(ctx) | |||
| return | |||
| } | |||
| ctx.Data["Owner"] = u | |||
| @@ -1 +1 @@ | |||
| 0.7.21.1124 Beta | |||
| 0.7.22.1124 Beta | |||
| @@ -4,7 +4,7 @@ | |||
| <div class="column"> | |||
| <div class="ui header"> | |||
| <img class="ui image" src="{{.AvatarLink}}?s=100"> | |||
| <span class="text thin grey"><a href="{{AppSubUrl}}/org/{{.Name}}">{{.DisplayName}}</a></span> | |||
| <span class="text thin grey"><a href="{{.HomeLink}}">{{.DisplayName}}</a></span> | |||
| <div class="ui right"> | |||
| <div class="ui menu"> | |||
| @@ -40,7 +40,7 @@ | |||
| <strong>{{.i18n.Tr "org.people"}}</strong> | |||
| {{if $isMember}} | |||
| <div class="ui right"> | |||
| <a class="text grey" href="{{.Org.HomeLink}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a> | |||
| <a class="text grey" href="{{.OrgLink}}/members"><strong>{{.Org.NumMembers}}</strong><span class="octicon octicon-chevron-right"></span></a> | |||
| </div> | |||
| {{end}} | |||
| </h4> | |||
| @@ -53,7 +53,7 @@ | |||
| </div> | |||
| {{if .IsOrganizationOwner}} | |||
| <div class="ui bottom attached segment"> | |||
| <a class="ui blue small button" href="{{.Org.HomeLink}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a> | |||
| <a class="ui blue small button" href="{{.OrgLink}}/invitations/new">{{.i18n.Tr "org.invite_someone"}}</a> | |||
| </div> | |||
| {{end}} | |||
| @@ -61,20 +61,20 @@ | |||
| <div class="ui top attached header"> | |||
| <strong>{{.i18n.Tr "org.teams"}}</strong> | |||
| <div class="ui right"> | |||
| <a class="text grey" href="{{.Org.HomeLink}}/teams"><strong>{{.Org.NumTeams}}</strong><span class="octicon octicon-chevron-right"></span></a> | |||
| <a class="text grey" href="{{.OrgLink}}/teams"><strong>{{.Org.NumTeams}}</strong><span class="octicon octicon-chevron-right"></span></a> | |||
| </div> | |||
| </div> | |||
| <div class="ui attached table segment teams"> | |||
| {{range .Teams}} | |||
| <div class="item"> | |||
| <a href="{{$.Org.HomeLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | |||
| <a href="{{$.OrgLink}}/teams/{{.LowerName}}"><strong class="team-name">{{.Name}}</strong></a> | |||
| <p class="text grey">{{.NumMembers}} {{$.i18n.Tr "org.lower_members"}} · {{.NumRepos}} {{$.i18n.Tr "org.lower_repositories"}}</p> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{if .IsOrganizationOwner}} | |||
| <div class="ui bottom attached segment"> | |||
| <a class="ui blue small button" href="{{.Org.HomeLink}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a> | |||
| <a class="ui blue small button" href="{{.OrgLink}}/teams/new">{{.i18n.Tr "org.create_new_team"}}</a> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| @@ -1,13 +1,13 @@ | |||
| <div class="four wide column"> | |||
| <div class="ui vertical menu"> | |||
| <div class="header item">{{.i18n.Tr "org.settings"}}</div> | |||
| <a class="{{if .PageIsSettingsOptions}}active{{end}} item" href="{{.Org.HomeLink}}/settings"> | |||
| <a class="{{if .PageIsSettingsOptions}}active{{end}} item" href="{{.OrgLink}}/settings"> | |||
| {{.i18n.Tr "org.settings.options"}} | |||
| </a> | |||
| <a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.Org.HomeLink}}/settings/hooks"> | |||
| <a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.OrgLink}}/settings/hooks"> | |||
| {{.i18n.Tr "repo.settings.hooks"}} | |||
| </a> | |||
| <a class="{{if .PageIsSettingsDelete}}active{{end}} item" href="{{.Org.HomeLink}}/settings/delete"> | |||
| <a class="{{if .PageIsSettingsDelete}}active{{end}} item" href="{{.OrgLink}}/settings/delete"> | |||
| {{.i18n.Tr "org.settings.delete"}} | |||
| </a> | |||
| </div> | |||
| @@ -41,7 +41,7 @@ | |||
| </a> | |||
| <div class="right menu"> | |||
| <div class="item"> | |||
| <a class="ui blue basic button" href="{{AppSubUrl}}/org/{{.ContextUser.Name}}"> | |||
| <a class="ui blue basic button" href="{{.ContextUser.HomeLink}}"> | |||
| {{.i18n.Tr "home.view_home" (.ContextUser.ShortName 10)}} | |||
| </a> | |||
| </div> | |||