* 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
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)) | ||||
} | } |
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 |
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]' |
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 |
// 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. | ||||
// 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 | |||||
} |
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 { |
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) | ||||
} | } |
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) | |||||
} |
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, |
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 |
} | } | ||||
} | } | ||||
// 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) { |
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 |
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 { |
} | } | ||||
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, |
// 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 { |
}, 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() { |
<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> |