* 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 codetags/v1.2.0-rc1
@@ -143,8 +143,10 @@ func runServ(c *cli.Context) error { | |||
reponame := strings.ToLower(strings.TrimSuffix(rr[1], ".git")) | |||
isWiki := false | |||
unitType := models.UnitTypeCode | |||
if strings.HasSuffix(reponame, ".wiki") { | |||
isWiki = true | |||
unitType = models.UnitTypeWiki | |||
reponame = reponame[:len(reponame)-5] | |||
} | |||
@@ -248,6 +250,12 @@ func runServ(c *cli.Context) error { | |||
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.EnvPusherID, fmt.Sprintf("%d", user.ID)) | |||
} |
@@ -12,4 +12,12 @@ | |||
type: 2 | |||
index: 0 | |||
config: "{}" | |||
created_unix: 946684810 | |||
- | |||
id: 3 | |||
repo_id: 1 | |||
type: 7 | |||
index: 0 | |||
config: "{}" | |||
created_unix: 946684810 |
@@ -6,6 +6,7 @@ | |||
authorize: 4 # owner | |||
num_repos: 2 | |||
num_members: 1 | |||
unit_types: '[1,2,3,4,5,6,7,8,9]' | |||
- | |||
id: 2 | |||
@@ -15,6 +16,7 @@ | |||
authorize: 2 # write | |||
num_repos: 1 | |||
num_members: 2 | |||
unit_types: '[1,2,3,4,5,6,7,8,9]' | |||
- | |||
id: 3 | |||
@@ -24,6 +26,7 @@ | |||
authorize: 4 # owner | |||
num_repos: 0 | |||
num_members: 1 | |||
unit_types: '[1,2,3,4,5,6,7,8,9]' | |||
- | |||
id: 4 | |||
@@ -33,3 +36,4 @@ | |||
authorize: 4 # owner | |||
num_repos: 0 | |||
num_members: 1 | |||
unit_types: '[1,2,3,4,5,6,7,8,9]' |
@@ -112,6 +112,8 @@ var migrations = []Migration{ | |||
NewMigration("add primary key to external login user", addExternalLoginUserPK), | |||
// 31 -> 32 | |||
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn), | |||
// v32 -> v33 | |||
NewMigration("add units for team", addUnitsToRepoTeam), | |||
} | |||
// Migrate database to current version |
@@ -1,4 +1,4 @@ | |||
// 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 | |||
// license that can be found in the LICENSE file. | |||
@@ -0,0 +1,23 @@ | |||
// 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 | |||
} |
@@ -24,6 +24,15 @@ type Team struct { | |||
Members []*User `xorm:"-"` | |||
NumRepos 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. | |||
@@ -183,6 +192,19 @@ func (t *Team) RemoveRepository(repoID int64) error { | |||
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 | |||
func IsUsableTeamName(name string) error { | |||
switch name { |
@@ -329,8 +329,61 @@ func (repo *Repository) getUnits(e Engine) (err error) { | |||
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 | |||
@@ -1595,6 +1648,7 @@ func DeleteRepository(uid, repoID int64) error { | |||
&Release{RepoID: repoID}, | |||
&Collaboration{RepoID: repoID}, | |||
&PullRequest{BaseRepoID: repoID}, | |||
&RepoUnit{RepoID: repoID}, | |||
); err != nil { | |||
return fmt.Errorf("deleteBeans: %v", err) | |||
} |
@@ -135,3 +135,11 @@ func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig { | |||
func (r *RepoUnit) ExternalTrackerConfig() *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) | |||
} |
@@ -20,6 +20,40 @@ const ( | |||
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 | |||
type Unit struct { | |||
Type UnitType | |||
@@ -29,13 +63,18 @@ type Unit struct { | |||
Idx int | |||
} | |||
// CanDisable returns if this unit could be disabled. | |||
func (u *Unit) CanDisable() bool { | |||
return u.Type != UnitTypeSettings | |||
} | |||
// Enumerate all the units | |||
var ( | |||
UnitCode = Unit{ | |||
UnitTypeCode, | |||
"repo.code", | |||
"/", | |||
"repo.code_desc", | |||
"repo.code.desc", | |||
0, | |||
} | |||
@@ -43,15 +82,15 @@ var ( | |||
UnitTypeIssues, | |||
"repo.issues", | |||
"/issues", | |||
"repo.issues_desc", | |||
"repo.issues.desc", | |||
1, | |||
} | |||
UnitExternalTracker = Unit{ | |||
UnitTypeExternalTracker, | |||
"repo.issues", | |||
"repo.ext_issues", | |||
"/issues", | |||
"repo.issues_desc", | |||
"repo.ext_issues.desc", | |||
1, | |||
} | |||
@@ -59,7 +98,7 @@ var ( | |||
UnitTypePullRequests, | |||
"repo.pulls", | |||
"/pulls", | |||
"repo.pulls_desc", | |||
"repo.pulls.desc", | |||
2, | |||
} | |||
@@ -67,7 +106,7 @@ var ( | |||
UnitTypeCommits, | |||
"repo.commits", | |||
"/commits/master", | |||
"repo.commits_desc", | |||
"repo.commits.desc", | |||
3, | |||
} | |||
@@ -75,7 +114,7 @@ var ( | |||
UnitTypeReleases, | |||
"repo.releases", | |||
"/releases", | |||
"repo.releases_desc", | |||
"repo.releases.desc", | |||
4, | |||
} | |||
@@ -83,15 +122,15 @@ var ( | |||
UnitTypeWiki, | |||
"repo.wiki", | |||
"/wiki", | |||
"repo.wiki_desc", | |||
"repo.wiki.desc", | |||
5, | |||
} | |||
UnitExternalWiki = Unit{ | |||
UnitTypeExternalWiki, | |||
"repo.wiki", | |||
"repo.ext_wiki", | |||
"/wiki", | |||
"repo.wiki_desc", | |||
"repo.ext_wiki.desc", | |||
5, | |||
} | |||
@@ -99,29 +138,10 @@ var ( | |||
UnitTypeSettings, | |||
"repo.settings", | |||
"/settings", | |||
"repo.settings_desc", | |||
"repo.settings.desc", | |||
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 = map[UnitType]Unit{ | |||
UnitTypeCode: UnitCode, |
@@ -5,6 +5,8 @@ | |||
package auth | |||
import ( | |||
"code.gitea.io/gitea/models" | |||
"github.com/go-macaron/binding" | |||
"gopkg.in/macaron.v1" | |||
) | |||
@@ -53,6 +55,7 @@ type CreateTeamForm struct { | |||
TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"` | |||
Description string `binding:"MaxSize(255)"` | |||
Permission string | |||
Units []models.UnitType | |||
} | |||
// Validate validates the fields |
@@ -493,6 +493,37 @@ func RequireRepoWriter() macaron.Handler { | |||
} | |||
} | |||
// 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. | |||
func GitHookService() macaron.Handler { | |||
return func(ctx *Context) { |
@@ -505,6 +505,7 @@ push_exist_repo = Pushing an existing repository from the command line | |||
bare_message = This repository does not contain any content. | |||
code = Code | |||
code.desc = Code is your program source | |||
branch = Branch | |||
tree = Tree | |||
filter_branch_and_tag = Filter branch or tag | |||
@@ -565,6 +566,7 @@ editor.unable_to_upload_files = Failed to upload files to '%s' with error: %v | |||
editor.upload_files_to_dir = Upload files to '%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.search = Search commits | |||
commits.find = Search | |||
@@ -575,6 +577,10 @@ commits.date = Date | |||
commits.older = Older | |||
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.labels = Labels | |||
issues.new.no_label = No Label | |||
@@ -678,6 +684,7 @@ issues.attachment.download = `Click to download "%s"` | |||
issues.subscribe = Subscribe | |||
issues.unsubscribe = Unsubscribe | |||
pulls.desc = Pulls management your code review and merge requests | |||
pulls.new = New Pull Request | |||
pulls.compare_changes = Compare Changes | |||
pulls.compare_changes_desc = Compare two branches and make a pull request for changes. | |||
@@ -734,9 +741,13 @@ milestones.filter_sort.most_complete = Most complete | |||
milestones.filter_sort.most_issues = Most 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.welcome = Welcome to the project wiki | |||
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.page = Page | |||
wiki.filter_page = Filter page | |||
@@ -753,6 +764,7 @@ wiki.pages = Pages | |||
wiki.last_updated = Last updated %s | |||
settings = Settings | |||
settings.desc = Settings management your settings for repository | |||
settings.options = Options | |||
settings.collaboration = Collaboration | |||
settings.collaboration.admin = Admin | |||
@@ -910,6 +922,7 @@ diff.view_file = View File | |||
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 | |||
releases.desc = Releases manage your milestone versions | |||
release.releases = Releases | |||
release.new_release = New Release | |||
release.draft = Draft | |||
@@ -968,6 +981,7 @@ team_desc = Description | |||
team_name_helper = You will use this name to mention this team in conversations. | |||
team_desc_helper = What is this team for? | |||
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_pattern_not_allowed = Organization name pattern '%s' is not allowed. | |||
@@ -1406,3 +1420,7 @@ error.no_committer_account = No account linked to committer's email | |||
error.no_gpg_keys_found = "No known key found for this signature in database" | |||
error.not_signed_commit = "Not a signed commit" | |||
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 |
@@ -156,6 +156,7 @@ func NewTeam(ctx *context.Context) { | |||
ctx.Data["PageIsOrgTeams"] = true | |||
ctx.Data["PageIsOrgTeamsNew"] = true | |||
ctx.Data["Team"] = &models.Team{} | |||
ctx.Data["Units"] = models.Units | |||
ctx.HTML(200, tplTeamNew) | |||
} | |||
@@ -170,6 +171,7 @@ func NewTeamPost(ctx *context.Context, form auth.CreateTeamForm) { | |||
Name: form.TeamName, | |||
Description: form.Description, | |||
Authorize: models.ParseAccessMode(form.Permission), | |||
UnitTypes: form.Units, | |||
} | |||
ctx.Data["Team"] = t | |||
@@ -220,6 +222,7 @@ func EditTeam(ctx *context.Context) { | |||
ctx.Data["PageIsOrgTeams"] = true | |||
ctx.Data["team_name"] = ctx.Org.Team.Name | |||
ctx.Data["desc"] = ctx.Org.Team.Description | |||
ctx.Data["Units"] = models.Units | |||
ctx.HTML(200, tplTeamNew) | |||
} | |||
@@ -258,6 +261,7 @@ func EditTeamPost(ctx *context.Context, form auth.CreateTeamForm) { | |||
} | |||
} | |||
t.Description = form.Description | |||
t.UnitTypes = form.Units | |||
if err := models.UpdateTeam(t, isAuthChanged); err != nil { | |||
ctx.Data["Err_TeamName"] = true | |||
switch { |
@@ -77,8 +77,10 @@ func HTTP(ctx *context.Context) { | |||
} | |||
isWiki := false | |||
var unitType = models.UnitTypeCode | |||
if strings.HasSuffix(reponame, ".wiki") { | |||
isWiki = true | |||
unitType = models.UnitTypeWiki | |||
reponame = reponame[:len(reponame)-5] | |||
} | |||
@@ -204,6 +206,12 @@ func HTTP(ctx *context.Context) { | |||
} | |||
} | |||
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{ | |||
models.EnvRepoUsername + "=" + username, | |||
models.EnvRepoName + "=" + reponame, |
@@ -252,6 +252,25 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st | |||
// Home render repository home page | |||
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 | |||
if ctx.Repo.Repository.IsBare { |
@@ -445,10 +445,11 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
}, func(ctx *context.Context) { | |||
ctx.Data["PageIsSettings"] = true | |||
}, context.UnitTypes()) | |||
}, context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeSettings)) | |||
}, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef()) | |||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action) | |||
m.Group("/:username/:reponame", func() { | |||
// 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. | |||
@@ -486,28 +487,6 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("/:id/:action", repo.ChangeMilestonStatus) | |||
m.Post("/delete", repo.DeleteMilestone) | |||
}, 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). | |||
Get(repo.CompareAndPullRequest). | |||
@@ -539,16 +518,42 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
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("", func() { | |||
m.Get("/releases", repo.MustBeNotBare, repo.Releases) | |||
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues) | |||
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue) | |||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels) | |||
m.Get("/milestones", repo.Milestones) | |||
}, context.RepoRef()) | |||
}, context.RepoRef(), context.CheckUnit(models.UnitTypeIssues)) | |||
// m.Get("/branches", repo.Branches) | |||
m.Post("/branches/:name/delete", reqSignIn, reqRepoWriter, repo.MustBeNotBare, repo.DeleteBranchPost) | |||
@@ -564,20 +569,20 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
Post(bindIgnErr(auth.NewWikiForm{}), repo.EditWikiPost) | |||
m.Post("/:page/delete", repo.DeleteWikiPagePost) | |||
}, reqSignIn, reqRepoWriter) | |||
}, repo.MustEnableWiki, context.RepoRef()) | |||
}, repo.MustEnableWiki, context.RepoRef(), context.CheckUnit(models.UnitTypeWiki)) | |||
m.Group("/wiki", func() { | |||
m.Get("/raw/*", 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.Get("/commits", context.RepoRef(), repo.ViewPullCommits) | |||
m.Get("/files", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.ViewPullFiles) | |||
m.Post("/merge", reqRepoWriter, repo.MergePullRequest) | |||
}, repo.MustAllowPulls) | |||
}, repo.MustAllowPulls, context.CheckUnit(models.UnitTypePullRequests)) | |||
m.Group("", func() { | |||
m.Get("/src/*", repo.SetEditorconfigIfExists, repo.Home) | |||
@@ -586,21 +591,22 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("/graph", repo.Graph) | |||
m.Get("/commit/:sha([a-f0-9]{7,40})$", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.Diff) | |||
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.Get("/stars", repo.Stars) | |||
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("/:reponame", func() { | |||
m.Get("", 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("/info/lfs", func() { |
@@ -52,6 +52,21 @@ | |||
<div class="ui divider"></div> | |||
{{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"> | |||
{{if .PageIsOrgTeamsNew}} | |||
<button class="ui green button">{{.i18n.Tr "org.create_new_team"}}</button> |