mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 13:51:35 +01:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									5db5e16ab6
								
							
						
					
					
						commit
						fd6034aaf2
					
				| @ -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)) | ||||
| 		} | ||||
|  | ||||
| @ -13,3 +13,11 @@ | ||||
|   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. | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										23
									
								
								models/migrations/v32.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								models/migrations/v32.go
									
									
									
									
									
										Normal 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) | ||||
| } | ||||
|  | ||||
							
								
								
									
										168
									
								
								models/unit.go
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								models/unit.go
									
									
									
									
									
								
							| @ -20,90 +20,21 @@ const ( | ||||
| 	UnitTypeExternalTracker                     // 9 ExternalTracker | ||||
| ) | ||||
| 
 | ||||
| // Unit is a tab page of one repository | ||||
| type Unit struct { | ||||
| 	Type    UnitType | ||||
| 	NameKey string | ||||
| 	URI     string | ||||
| 	DescKey string | ||||
| 	Idx     int | ||||
| } | ||||
| 
 | ||||
| // Enumerate all the units | ||||
| var ( | ||||
| 	UnitCode = Unit{ | ||||
| 	// allRepUnitTypes contains all the unit types | ||||
| 	allRepUnitTypes = []UnitType{ | ||||
| 		UnitTypeCode, | ||||
| 		"repo.code", | ||||
| 		"/", | ||||
| 		"repo.code_desc", | ||||
| 		0, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitIssues = Unit{ | ||||
| 		UnitTypeIssues, | ||||
| 		"repo.issues", | ||||
| 		"/issues", | ||||
| 		"repo.issues_desc", | ||||
| 		1, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitExternalTracker = Unit{ | ||||
| 		UnitTypeExternalTracker, | ||||
| 		"repo.issues", | ||||
| 		"/issues", | ||||
| 		"repo.issues_desc", | ||||
| 		1, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitPullRequests = Unit{ | ||||
| 		UnitTypePullRequests, | ||||
| 		"repo.pulls", | ||||
| 		"/pulls", | ||||
| 		"repo.pulls_desc", | ||||
| 		2, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitCommits = Unit{ | ||||
| 		UnitTypeCommits, | ||||
| 		"repo.commits", | ||||
| 		"/commits/master", | ||||
| 		"repo.commits_desc", | ||||
| 		3, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitReleases = Unit{ | ||||
| 		UnitTypeReleases, | ||||
| 		"repo.releases", | ||||
| 		"/releases", | ||||
| 		"repo.releases_desc", | ||||
| 		4, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitWiki = Unit{ | ||||
| 		UnitTypeWiki, | ||||
| 		"repo.wiki", | ||||
| 		"/wiki", | ||||
| 		"repo.wiki_desc", | ||||
| 		5, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitExternalWiki = Unit{ | ||||
| 		UnitTypeExternalWiki, | ||||
| 		"repo.wiki", | ||||
| 		"/wiki", | ||||
| 		"repo.wiki_desc", | ||||
| 		5, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitSettings = Unit{ | ||||
| 		UnitTypeSettings, | ||||
| 		"repo.settings", | ||||
| 		"/settings", | ||||
| 		"repo.settings_desc", | ||||
| 		6, | ||||
| 		UnitTypeExternalWiki, | ||||
| 		UnitTypeExternalTracker, | ||||
| 	} | ||||
| 
 | ||||
| 	// defaultRepoUnits contains all the default unit types | ||||
| 	// defaultRepoUnits contains the default unit types | ||||
| 	defaultRepoUnits = []UnitType{ | ||||
| 		UnitTypeCode, | ||||
| 		UnitTypeIssues, | ||||
| @ -121,6 +52,95 @@ var ( | ||||
| 		UnitTypeReleases, | ||||
| 		UnitTypeSettings, | ||||
| 	} | ||||
| ) | ||||
| 
 | ||||
| // Unit is a tab page of one repository | ||||
| type Unit struct { | ||||
| 	Type    UnitType | ||||
| 	NameKey string | ||||
| 	URI     string | ||||
| 	DescKey string | ||||
| 	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", | ||||
| 		0, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitIssues = Unit{ | ||||
| 		UnitTypeIssues, | ||||
| 		"repo.issues", | ||||
| 		"/issues", | ||||
| 		"repo.issues.desc", | ||||
| 		1, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitExternalTracker = Unit{ | ||||
| 		UnitTypeExternalTracker, | ||||
| 		"repo.ext_issues", | ||||
| 		"/issues", | ||||
| 		"repo.ext_issues.desc", | ||||
| 		1, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitPullRequests = Unit{ | ||||
| 		UnitTypePullRequests, | ||||
| 		"repo.pulls", | ||||
| 		"/pulls", | ||||
| 		"repo.pulls.desc", | ||||
| 		2, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitCommits = Unit{ | ||||
| 		UnitTypeCommits, | ||||
| 		"repo.commits", | ||||
| 		"/commits/master", | ||||
| 		"repo.commits.desc", | ||||
| 		3, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitReleases = Unit{ | ||||
| 		UnitTypeReleases, | ||||
| 		"repo.releases", | ||||
| 		"/releases", | ||||
| 		"repo.releases.desc", | ||||
| 		4, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitWiki = Unit{ | ||||
| 		UnitTypeWiki, | ||||
| 		"repo.wiki", | ||||
| 		"/wiki", | ||||
| 		"repo.wiki.desc", | ||||
| 		5, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitExternalWiki = Unit{ | ||||
| 		UnitTypeExternalWiki, | ||||
| 		"repo.ext_wiki", | ||||
| 		"/wiki", | ||||
| 		"repo.ext_wiki.desc", | ||||
| 		5, | ||||
| 	} | ||||
| 
 | ||||
| 	UnitSettings = Unit{ | ||||
| 		UnitTypeSettings, | ||||
| 		"repo.settings", | ||||
| 		"/settings", | ||||
| 		"repo.settings.desc", | ||||
| 		6, | ||||
| 	} | ||||
| 
 | ||||
| 	// Units contains all the units | ||||
| 	Units = map[UnitType]Unit{ | ||||
|  | ||||
| @ -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> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user