Browse Source

Add units to team (#947)

* add units to team

* fix lint

* finish team setting backend

* finished permission controll on routes

* fix import blank line

* add unit check on ssh/http pull and push and fix test failed

* fix fixtures data

* remove unused code
tags/v1.2.0-rc1
Lunny Xiao 7 years ago
parent
commit
fd6034aaf2

+ 8
- 0
cmd/serv.go View File

reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git")) reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git"))


isWiki := false isWiki := false
unitType := models.UnitTypeCode
if strings.HasSuffix(reponame, ".wiki") { if strings.HasSuffix(reponame, ".wiki") {
isWiki = true isWiki = true
unitType = models.UnitTypeWiki
reponame = reponame[:len(reponame)-5] reponame = reponame[:len(reponame)-5]
} }


user.Name, requestedMode, repoPath) user.Name, requestedMode, repoPath)
} }


if !repo.CheckUnitUser(user.ID, unitType) {
fail("You do not have allowed for this action",
"User %s does not have allowed access to repository %s 's code",
user.Name, repoPath)
}

os.Setenv(models.EnvPusherName, user.Name) os.Setenv(models.EnvPusherName, user.Name)
os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID)) os.Setenv(models.EnvPusherID, fmt.Sprintf("%d", user.ID))
} }

+ 8
- 0
models/fixtures/repo_unit.yml View File

type: 2 type: 2
index: 0 index: 0
config: "{}" config: "{}"
created_unix: 946684810

-
id: 3
repo_id: 1
type: 7
index: 0
config: "{}"
created_unix: 946684810 created_unix: 946684810

+ 4
- 0
models/fixtures/team.yml View File

authorize: 4 # owner authorize: 4 # owner
num_repos: 2 num_repos: 2
num_members: 1 num_members: 1
unit_types: '[1,2,3,4,5,6,7,8,9]'


- -
id: 2 id: 2
authorize: 2 # write authorize: 2 # write
num_repos: 1 num_repos: 1
num_members: 2 num_members: 2
unit_types: '[1,2,3,4,5,6,7,8,9]'


- -
id: 3 id: 3
authorize: 4 # owner authorize: 4 # owner
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
unit_types: '[1,2,3,4,5,6,7,8,9]'


- -
id: 4 id: 4
authorize: 4 # owner authorize: 4 # owner
num_repos: 0 num_repos: 0
num_members: 1 num_members: 1
unit_types: '[1,2,3,4,5,6,7,8,9]'

+ 2
- 0
models/migrations/migrations.go View File

NewMigration("add primary key to external login user", addExternalLoginUserPK), NewMigration("add primary key to external login user", addExternalLoginUserPK),
// 31 -> 32 // 31 -> 32
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn), NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
// v32 -> v33
NewMigration("add units for team", addUnitsToRepoTeam),
} }


// Migrate database to current version // Migrate database to current version

+ 1
- 1
models/migrations/v31.go View File

// Copyright 2017 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.



+ 23
- 0
models/migrations/v32.go View File

// Copyright 2017 The Gitea 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 migrations

import "github.com/go-xorm/xorm"

func addUnitsToRepoTeam(x *xorm.Engine) error {
type Team struct {
UnitTypes []int `xorm:"json"`
}

err := x.Sync(new(Team))
if err != nil {
return err
}

_, err = x.Update(&Team{
UnitTypes: []int{1, 2, 3, 4, 5, 6, 7, 8, 9},
})
return err
}

+ 22
- 0
models/org_team.go View File

Members []*User `xorm:"-"` Members []*User `xorm:"-"`
NumRepos int NumRepos int
NumMembers int NumMembers int
UnitTypes []UnitType `xorm:"json"`
}

// GetUnitTypes returns unit types the team owned, empty means all the unit types
func (t *Team) GetUnitTypes() []UnitType {
if len(t.UnitTypes) == 0 {
return allRepUnitTypes
}
return t.UnitTypes
} }


// IsOwnerTeam returns true if team is owner team. // IsOwnerTeam returns true if team is owner team.
return sess.Commit() return sess.Commit()
} }


// EnableUnit returns if the team enables unit type t
func (t *Team) EnableUnit(tp UnitType) bool {
if len(t.UnitTypes) == 0 {
return true
}
for _, u := range t.UnitTypes {
if u == tp {
return true
}
}
return false
}

// IsUsableTeamName tests if a name could be as team name // IsUsableTeamName tests if a name could be as team name
func IsUsableTeamName(name string) error { func IsUsableTeamName(name string) error {
switch name { switch name {

+ 56
- 2
models/repo.go View File

return err return err
} }


func getUnitsByRepoID(e Engine, repoID int64) (units []*RepoUnit, err error) {
return units, e.Where("repo_id = ?", repoID).Find(&units)
// CheckUnitUser check whether user could visit the unit of this repository
func (repo *Repository) CheckUnitUser(userID int64, unitType UnitType) bool {
if err := repo.getUnitsByUserID(x, userID); err != nil {
return false
}

for _, unit := range repo.Units {
if unit.Type == unitType {
return true
}
}
return false
}

// LoadUnitsByUserID loads units according userID's permissions
func (repo *Repository) LoadUnitsByUserID(userID int64) error {
return repo.getUnitsByUserID(x, userID)
}

func (repo *Repository) getUnitsByUserID(e Engine, userID int64) (err error) {
if repo.Units != nil {
return nil
}

err = repo.getUnits(e)
if err != nil {
return err
}

if !repo.Owner.IsOrganization() || userID == 0 {
return nil
}

teams, err := getUserTeams(e, repo.OwnerID, userID)
if err != nil {
return err
}

var allTypes = make(map[UnitType]struct{}, len(allRepUnitTypes))
for _, team := range teams {
for _, unitType := range team.UnitTypes {
allTypes[unitType] = struct{}{}
}
}

// unique
var newRepoUnits = make([]*RepoUnit, 0, len(repo.Units))
for _, u := range repo.Units {
if _, ok := allTypes[u.Type]; ok {
newRepoUnits = append(newRepoUnits, u)
}
}

repo.Units = newRepoUnits
return nil
} }


// EnableUnit if this repository enabled some unit // EnableUnit if this repository enabled some unit
&Release{RepoID: repoID}, &Release{RepoID: repoID},
&Collaboration{RepoID: repoID}, &Collaboration{RepoID: repoID},
&PullRequest{BaseRepoID: repoID}, &PullRequest{BaseRepoID: repoID},
&RepoUnit{RepoID: repoID},
); err != nil { ); err != nil {
return fmt.Errorf("deleteBeans: %v", err) return fmt.Errorf("deleteBeans: %v", err)
} }

+ 8
- 0
models/repo_unit.go View File

func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig { func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
return r.Config.(*ExternalTrackerConfig) return r.Config.(*ExternalTrackerConfig)
} }

func getUnitsByRepoID(e Engine, repoID int64) (units []*RepoUnit, err error) {
return units, e.Where("repo_id = ?", repoID).Find(&units)
}

func getUnitsByRepoIDAndIDs(e Engine, repoID int64, types []UnitType) (units []*RepoUnit, err error) {
return units, e.Where("repo_id = ?", repoID).In("`type`", types).Find(&units)
}

+ 50
- 30
models/unit.go View File

UnitTypeExternalTracker // 9 ExternalTracker UnitTypeExternalTracker // 9 ExternalTracker
) )


var (
// allRepUnitTypes contains all the unit types
allRepUnitTypes = []UnitType{
UnitTypeCode,
UnitTypeIssues,
UnitTypePullRequests,
UnitTypeCommits,
UnitTypeReleases,
UnitTypeWiki,
UnitTypeSettings,
UnitTypeExternalWiki,
UnitTypeExternalTracker,
}

// defaultRepoUnits contains the default unit types
defaultRepoUnits = []UnitType{
UnitTypeCode,
UnitTypeIssues,
UnitTypePullRequests,
UnitTypeCommits,
UnitTypeReleases,
UnitTypeWiki,
UnitTypeSettings,
}

// MustRepoUnits contains the units could be disabled currently
MustRepoUnits = []UnitType{
UnitTypeCode,
UnitTypeCommits,
UnitTypeReleases,
UnitTypeSettings,
}
)

// Unit is a tab page of one repository // Unit is a tab page of one repository
type Unit struct { type Unit struct {
Type UnitType Type UnitType
Idx int Idx int
} }


// CanDisable returns if this unit could be disabled.
func (u *Unit) CanDisable() bool {
return u.Type != UnitTypeSettings
}

// Enumerate all the units // Enumerate all the units
var ( var (
UnitCode = Unit{ UnitCode = Unit{
UnitTypeCode, UnitTypeCode,
"repo.code", "repo.code",
"/", "/",
"repo.code_desc",
"repo.code.desc",
0, 0,
} }


UnitTypeIssues, UnitTypeIssues,
"repo.issues", "repo.issues",
"/issues", "/issues",
"repo.issues_desc",
"repo.issues.desc",
1, 1,
} }


UnitExternalTracker = Unit{ UnitExternalTracker = Unit{
UnitTypeExternalTracker, UnitTypeExternalTracker,
"repo.issues",
"repo.ext_issues",
"/issues", "/issues",
"repo.issues_desc",
"repo.ext_issues.desc",
1, 1,
} }


UnitTypePullRequests, UnitTypePullRequests,
"repo.pulls", "repo.pulls",
"/pulls", "/pulls",
"repo.pulls_desc",
"repo.pulls.desc",
2, 2,
} }


UnitTypeCommits, UnitTypeCommits,
"repo.commits", "repo.commits",
"/commits/master", "/commits/master",
"repo.commits_desc",
"repo.commits.desc",
3, 3,
} }


UnitTypeReleases, UnitTypeReleases,
"repo.releases", "repo.releases",
"/releases", "/releases",
"repo.releases_desc",
"repo.releases.desc",
4, 4,
} }


UnitTypeWiki, UnitTypeWiki,
"repo.wiki", "repo.wiki",
"/wiki", "/wiki",
"repo.wiki_desc",
"repo.wiki.desc",
5, 5,
} }


UnitExternalWiki = Unit{ UnitExternalWiki = Unit{
UnitTypeExternalWiki, UnitTypeExternalWiki,
"repo.wiki",
"repo.ext_wiki",
"/wiki", "/wiki",
"repo.wiki_desc",
"repo.ext_wiki.desc",
5, 5,
} }


UnitTypeSettings, UnitTypeSettings,
"repo.settings", "repo.settings",
"/settings", "/settings",
"repo.settings_desc",
"repo.settings.desc",
6, 6,
} }


// defaultRepoUnits contains all the default unit types
defaultRepoUnits = []UnitType{
UnitTypeCode,
UnitTypeIssues,
UnitTypePullRequests,
UnitTypeCommits,
UnitTypeReleases,
UnitTypeWiki,
UnitTypeSettings,
}

// MustRepoUnits contains the units could be disabled currently
MustRepoUnits = []UnitType{
UnitTypeCode,
UnitTypeCommits,
UnitTypeReleases,
UnitTypeSettings,
}

// Units contains all the units // Units contains all the units
Units = map[UnitType]Unit{ Units = map[UnitType]Unit{
UnitTypeCode: UnitCode, UnitTypeCode: UnitCode,

+ 3
- 0
modules/auth/org.go View File

package auth package auth


import ( import (
"code.gitea.io/gitea/models"

"github.com/go-macaron/binding" "github.com/go-macaron/binding"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
) )
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"` TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `binding:"MaxSize(255)"` Description string `binding:"MaxSize(255)"`
Permission string Permission string
Units []models.UnitType
} }


// Validate validates the fields // Validate validates the fields

+ 31
- 0
modules/context/repo.go View File

} }
} }


// LoadRepoUnits loads repsitory's units, it should be called after repository and user loaded
func LoadRepoUnits() macaron.Handler {
return func(ctx *Context) {
var userID int64
if ctx.User != nil {
userID = ctx.User.ID
}
err := ctx.Repo.Repository.LoadUnitsByUserID(userID)
if err != nil {
ctx.Handle(500, "LoadUnitsByUserID", err)
return
}
}
}

// CheckUnit will check whether
func CheckUnit(unitType models.UnitType) macaron.Handler {
return func(ctx *Context) {
var find bool
for _, unit := range ctx.Repo.Repository.Units {
if unit.Type == unitType {
find = true
break
}
}
if !find {
ctx.Handle(404, "CheckUnit", fmt.Errorf("%s: %v", ctx.Tr("units.error.unit_not_allowed"), unitType))
}
}
}

// GitHookService checks if repository Git hooks service has been enabled. // GitHookService checks if repository Git hooks service has been enabled.
func GitHookService() macaron.Handler { func GitHookService() macaron.Handler {
return func(ctx *Context) { return func(ctx *Context) {

+ 18
- 0
options/locale/locale_en-US.ini View File

bare_message = This repository does not contain any content. bare_message = This repository does not contain any content.


code = Code code = Code
code.desc = Code is your program source
branch = Branch branch = Branch
tree = Tree tree = Tree
filter_branch_and_tag = Filter branch or tag filter_branch_and_tag = Filter branch or tag
editor.upload_files_to_dir = Upload files to '%s' editor.upload_files_to_dir = Upload files to '%s'
editor.cannot_commit_to_protected_branch = Can not commit to protected branch '%s'. editor.cannot_commit_to_protected_branch = Can not commit to protected branch '%s'.


commits.desc = Commits show the history submited
commits.commits = Commits commits.commits = Commits
commits.search = Search commits commits.search = Search commits
commits.find = Search commits.find = Search
commits.older = Older commits.older = Older
commits.newer = Newer commits.newer = Newer


ext_issues = Ext Issues
ext_issues.desc = Ext Issues link to an external issues management

issues.desc = Issues management your tasks for this repository
issues.new = New Issue issues.new = New Issue
issues.new.labels = Labels issues.new.labels = Labels
issues.new.no_label = No Label issues.new.no_label = No Label
issues.subscribe = Subscribe issues.subscribe = Subscribe
issues.unsubscribe = Unsubscribe issues.unsubscribe = Unsubscribe


pulls.desc = Pulls management your code review and merge requests
pulls.new = New Pull Request pulls.new = New Pull Request
pulls.compare_changes = Compare Changes pulls.compare_changes = Compare Changes
pulls.compare_changes_desc = Compare two branches and make a pull request for changes. pulls.compare_changes_desc = Compare two branches and make a pull request for changes.
milestones.filter_sort.most_issues = Most issues milestones.filter_sort.most_issues = Most issues
milestones.filter_sort.least_issues = Least issues milestones.filter_sort.least_issues = Least issues


ext_wiki = Ext Wiki
ext_wiki.desc = Ext Wiki links to an external wiki system

wiki = Wiki wiki = Wiki
wiki.welcome = Welcome to the project wiki wiki.welcome = Welcome to the project wiki
wiki.welcome_desc = A wiki allows you and your collaborators to easily document your project. wiki.welcome_desc = A wiki allows you and your collaborators to easily document your project.
wiki.desc = Wiki is a collection of your documents
wiki.create_first_page = Create the first page wiki.create_first_page = Create the first page
wiki.page = Page wiki.page = Page
wiki.filter_page = Filter page wiki.filter_page = Filter page
wiki.last_updated = Last updated %s wiki.last_updated = Last updated %s


settings = Settings settings = Settings
settings.desc = Settings management your settings for repository
settings.options = Options settings.options = Options
settings.collaboration = Collaboration settings.collaboration = Collaboration
settings.collaboration.admin = Admin settings.collaboration.admin = Admin
diff.file_suppressed = File diff suppressed because it is too large diff.file_suppressed = File diff suppressed because it is too large
diff.too_many_files = Some files were not shown because too many files changed in this diff diff.too_many_files = Some files were not shown because too many files changed in this diff


releases.desc = Releases manage your milestone versions
release.releases = Releases release.releases = Releases
release.new_release = New Release release.new_release = New Release
release.draft = Draft release.draft = Draft
team_name_helper = You will use this name to mention this team in conversations. team_name_helper = You will use this name to mention this team in conversations.
team_desc_helper = What is this team for? team_desc_helper = What is this team for?
team_permission_desc = What permissions should this team have? team_permission_desc = What permissions should this team have?
team_unit_desc = Which units should this team have?


form.name_reserved = Organization name '%s' is reserved. form.name_reserved = Organization name '%s' is reserved.
form.name_pattern_not_allowed = Organization name pattern '%s' is not allowed. form.name_pattern_not_allowed = Organization name pattern '%s' is not allowed.
error.no_gpg_keys_found = "No known key found for this signature in database" error.no_gpg_keys_found = "No known key found for this signature in database"
error.not_signed_commit = "Not a signed commit" error.not_signed_commit = "Not a signed commit"
error.failed_retrieval_gpg_keys = "Failed to retrieve any key attached to the committer account" error.failed_retrieval_gpg_keys = "Failed to retrieve any key attached to the committer account"

[units]
error.no_unit_allowed_repo = Cannot find any unit allowed on this repository
error.unit_not_allowed = You have not allowed to visit this repository unit

+ 4
- 0
routers/org/teams.go View File

ctx.Data["PageIsOrgTeams"] = true ctx.Data["PageIsOrgTeams"] = true
ctx.Data["PageIsOrgTeamsNew"] = true ctx.Data["PageIsOrgTeamsNew"] = true
ctx.Data["Team"] = &models.Team{} ctx.Data["Team"] = &models.Team{}
ctx.Data["Units"] = models.Units
ctx.HTML(200, tplTeamNew) ctx.HTML(200, tplTeamNew)
} }


Name: form.TeamName, Name: form.TeamName,
Description: form.Description, Description: form.Description,
Authorize: models.ParseAccessMode(form.Permission), Authorize: models.ParseAccessMode(form.Permission),
UnitTypes: form.Units,
} }
ctx.Data["Team"] = t ctx.Data["Team"] = t


ctx.Data["PageIsOrgTeams"] = true ctx.Data["PageIsOrgTeams"] = true
ctx.Data["team_name"] = ctx.Org.Team.Name ctx.Data["team_name"] = ctx.Org.Team.Name
ctx.Data["desc"] = ctx.Org.Team.Description ctx.Data["desc"] = ctx.Org.Team.Description
ctx.Data["Units"] = models.Units
ctx.HTML(200, tplTeamNew) ctx.HTML(200, tplTeamNew)
} }


} }
} }
t.Description = form.Description t.Description = form.Description
t.UnitTypes = form.Units
if err := models.UpdateTeam(t, isAuthChanged); err != nil { if err := models.UpdateTeam(t, isAuthChanged); err != nil {
ctx.Data["Err_TeamName"] = true ctx.Data["Err_TeamName"] = true
switch { switch {

+ 8
- 0
routers/repo/http.go View File

} }


isWiki := false isWiki := false
var unitType = models.UnitTypeCode
if strings.HasSuffix(reponame, ".wiki") { if strings.HasSuffix(reponame, ".wiki") {
isWiki = true isWiki = true
unitType = models.UnitTypeWiki
reponame = reponame[:len(reponame)-5] reponame = reponame[:len(reponame)-5]
} }


} }
} }


if !repo.CheckUnitUser(authUser.ID, unitType) {
ctx.HandleText(http.StatusForbidden, fmt.Sprintf("User %s does not have allowed access to repository %s 's code",
authUser.Name, repo.RepoPath()))
return
}

environ = []string{ environ = []string{
models.EnvRepoUsername + "=" + username, models.EnvRepoUsername + "=" + username,
models.EnvRepoName + "=" + reponame, models.EnvRepoName + "=" + reponame,

+ 19
- 0
routers/repo/view.go View File



// Home render repository home page // Home render repository home page
func Home(ctx *context.Context) { func Home(ctx *context.Context) {
if len(ctx.Repo.Repository.Units) > 0 {
tp := ctx.Repo.Repository.Units[0].Type
if tp == models.UnitTypeCode {
renderCode(ctx)
return
}

unit, ok := models.Units[tp]
if ok {
ctx.Redirect(setting.AppSubURL + fmt.Sprintf("/%s%s",
ctx.Repo.Repository.FullName(), unit.URI))
return
}
}

ctx.Handle(404, "Home", fmt.Errorf(ctx.Tr("units.error.no_unit_allowed_repo")))
}

func renderCode(ctx *context.Context) {
ctx.Data["PageIsViewCode"] = true ctx.Data["PageIsViewCode"] = true


if ctx.Repo.Repository.IsBare { if ctx.Repo.Repository.IsBare {

+ 42
- 36
routers/routes/routes.go View File



}, func(ctx *context.Context) { }, func(ctx *context.Context) {
ctx.Data["PageIsSettings"] = true ctx.Data["PageIsSettings"] = true
}, context.UnitTypes())
}, context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeSettings))
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef()) }, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef())


m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action) m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)

m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest. // FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
// So they can apply their own enable/disable logic on routers. // So they can apply their own enable/disable logic on routers.
m.Get("/:id/:action", repo.ChangeMilestonStatus) m.Get("/:id/:action", repo.ChangeMilestonStatus)
m.Post("/delete", repo.DeleteMilestone) m.Post("/delete", repo.DeleteMilestone)
}, reqRepoWriter, context.RepoRef()) }, reqRepoWriter, context.RepoRef())
m.Group("/releases", func() {
m.Get("/new", repo.NewRelease)
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Post("/delete", repo.DeleteRelease)
}, repo.MustBeNotBare, reqRepoWriter, context.RepoRef())
m.Group("/releases", func() {
m.Get("/edit/*", repo.EditRelease)
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, repo.MustBeNotBare, reqRepoWriter, func(ctx *context.Context) {
var err error
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
if err != nil {
ctx.Handle(500, "GetBranchCommit", err)
return
}
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
if err != nil {
ctx.Handle(500, "CommitsCount", err)
return
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
})


m.Combo("/compare/*", repo.MustAllowPulls, repo.SetEditorconfigIfExists). m.Combo("/compare/*", repo.MustAllowPulls, repo.SetEditorconfigIfExists).
Get(repo.CompareAndPullRequest). Get(repo.CompareAndPullRequest).
return return
} }
}) })
}, reqSignIn, context.RepoAssignment(), context.UnitTypes())
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeIssues))

// Releases
m.Group("/:username/:reponame", func() {
m.Group("/releases", func() {
m.Get("/", repo.MustBeNotBare, repo.Releases)
m.Get("/new", repo.NewRelease)
m.Post("/new", bindIgnErr(auth.NewReleaseForm{}), repo.NewReleasePost)
m.Post("/delete", repo.DeleteRelease)
}, repo.MustBeNotBare, reqRepoWriter, context.RepoRef())
m.Group("/releases", func() {
m.Get("/edit/*", repo.EditRelease)
m.Post("/edit/*", bindIgnErr(auth.EditReleaseForm{}), repo.EditReleasePost)
}, repo.MustBeNotBare, reqRepoWriter, func(ctx *context.Context) {
var err error
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch)
if err != nil {
ctx.Handle(500, "GetBranchCommit", err)
return
}
ctx.Repo.CommitsCount, err = ctx.Repo.Commit.CommitsCount()
if err != nil {
ctx.Handle(500, "CommitsCount", err)
return
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
})
}, reqSignIn, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeReleases))


m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Group("", func() { m.Group("", func() {
m.Get("/releases", repo.MustBeNotBare, repo.Releases)
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues) m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue) m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
m.Get("/labels/", repo.RetrieveLabels, repo.Labels) m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
m.Get("/milestones", repo.Milestones) m.Get("/milestones", repo.Milestones)
}, context.RepoRef())
}, context.RepoRef(), context.CheckUnit(models.UnitTypeIssues))


// m.Get("/branches", repo.Branches) // m.Get("/branches", repo.Branches)
m.Post("/branches/:name/delete", reqSignIn, reqRepoWriter, repo.MustBeNotBare, repo.DeleteBranchPost) m.Post("/branches/:name/delete", reqSignIn, reqRepoWriter, repo.MustBeNotBare, repo.DeleteBranchPost)
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost) Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost)
m.Post("/:page/delete", repo.DeleteWikiPagePost) m.Post("/:page/delete", repo.DeleteWikiPagePost)
}, reqSignIn, reqRepoWriter) }, reqSignIn, reqRepoWriter)
}, repo.MustEnableWiki, context.RepoRef())
}, repo.MustEnableWiki, context.RepoRef(), context.CheckUnit(models.UnitTypeWiki))


m.Group("/wiki", func() { m.Group("/wiki", func() {
m.Get("/raw/*", repo.WikiRaw) m.Get("/raw/*", repo.WikiRaw)
m.Get("/*", repo.WikiRaw) m.Get("/*", repo.WikiRaw)
}, repo.MustEnableWiki)
}, repo.MustEnableWiki, context.CheckUnit(models.UnitTypeWiki), context.CheckUnit(models.UnitTypeWiki))


m.Get("/archive/*", repo.MustBeNotBare, repo.Download)
m.Get("/archive/*", repo.MustBeNotBare, repo.Download, context.CheckUnit(models.UnitTypeCode))


m.Group("/pulls/:index", func() { m.Group("/pulls/:index", func() {
m.Get("/commits", context.RepoRef(), repo.ViewPullCommits) m.Get("/commits", context.RepoRef(), repo.ViewPullCommits)
m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles) m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles)
m.Post("/merge", reqRepoWriter, repo.MergePullRequest) m.Post("/merge", reqRepoWriter, repo.MergePullRequest)
}, repo.MustAllowPulls)
}, repo.MustAllowPulls, context.CheckUnit(models.UnitTypePullRequests))


m.Group("", func() { m.Group("", func() {
m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home) m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home)
m.Get("/graph", repo.Graph) m.Get("/graph", repo.Graph)
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff)
m.Get("/forks", repo.Forks) m.Get("/forks", repo.Forks)
}, context.RepoRef())
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.MustBeNotBare, repo.RawDiff)
}, context.RepoRef(), context.CheckUnit(models.UnitTypeCode))
m.Get("/commit/:sha([a-f0-9]{7,40})\\.:ext(patch|diff)", repo.MustBeNotBare, repo.RawDiff, context.CheckUnit(models.UnitTypeCode))


m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.MustBeNotBare, repo.CompareDiff)
}, ignSignIn, context.RepoAssignment(), context.UnitTypes())
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.SetEditorconfigIfExists,
repo.SetDiffViewStyle, repo.MustBeNotBare, repo.CompareDiff, context.CheckUnit(models.UnitTypeCode))
}, ignSignIn, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits())
m.Group("/:username/:reponame", func() { m.Group("/:username/:reponame", func() {
m.Get("/stars", repo.Stars) m.Get("/stars", repo.Stars)
m.Get("/watchers", repo.Watchers) m.Get("/watchers", repo.Watchers)
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes())
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes(), context.LoadRepoUnits())


m.Group("/:username", func() { m.Group("/:username", func() {
m.Group("/:reponame", func() { m.Group("/:reponame", func() {
m.Get("", repo.SetEditorconfigIfExists, repo.Home) m.Get("", repo.SetEditorconfigIfExists, repo.Home)
m.Get("\\.git$", repo.SetEditorconfigIfExists, repo.Home) m.Get("\\.git$", repo.SetEditorconfigIfExists, repo.Home)
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes())
}, ignSignIn, context.RepoAssignment(), context.RepoRef(), context.UnitTypes(), context.LoadRepoUnits())


m.Group("/:reponame", func() { m.Group("/:reponame", func() {
m.Group("/info/lfs", func() { m.Group("/info/lfs", func() {

+ 15
- 0
templates/org/team/new.tmpl View File

<div class="ui divider"></div> <div class="ui divider"></div>
{{end}} {{end}}


<div class="required grouped field">
<label>{{.i18n.Tr "org.team_unit_desc"}}</label>
<br>
{{range $t, $unit := $.Units}}
<div class="field">
<div class="ui toggle checkbox">
<input type="checkbox" class="hidden" name="units" value="{{$unit.Type}}"{{if $.Team.EnableUnit $unit.Type}} checked{{end}}>
<label>{{$.i18n.Tr $unit.NameKey}}</label>
<span class="help">{{$.i18n.Tr $unit.DescKey}}</span>
</div>
</div>
{{end}}
</div>
<div class="ui divider"></div>

<div class="field"> <div class="field">
{{if .PageIsOrgTeamsNew}} {{if .PageIsOrgTeamsNew}}
<button class="ui green button">{{.i18n.Tr "org.create_new_team"}}</button> <button class="ui green button">{{.i18n.Tr "org.create_new_team"}}</button>

Loading…
Cancel
Save