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:
Lunny Xiao 2017-05-18 22:54:24 +08:00 committed by GitHub
parent 5db5e16ab6
commit fd6034aaf2
18 changed files with 366 additions and 113 deletions

View file

@ -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

View file

@ -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]'

View file

@ -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

View file

@ -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
View 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
}

View file

@ -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 {

View file

@ -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)
}

View file

@ -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)
}

View file

@ -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{