Add teams to repo on collaboration page. (#8045)
* Add teams to repo on collaboration page. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add option for repository admins to change teams access to repo. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add comment for functions Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Make RepoAdminChangeTeamAccess default false in xorm and make it default checked in template instead. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Make proper language strings and fix error redirection. * Add unit tests for adding and deleting team from repository. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Add database migration Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix redirect Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Fix locale string mismatch. Signed-off-by: David Svantesson <davidsvantesson@gmail.com> * Move team access mode text logic to template. * Move collaborator access mode text logic to template.
This commit is contained in:
parent
63ff61615e
commit
a0e88dfc2e
30 changed files with 575 additions and 79 deletions
|
@ -1370,6 +1370,23 @@ func (err ErrTeamAlreadyExist) Error() string {
|
|||
return fmt.Sprintf("team already exists [org_id: %d, name: %s]", err.OrgID, err.Name)
|
||||
}
|
||||
|
||||
// ErrTeamNotExist represents a "TeamNotExist" error
|
||||
type ErrTeamNotExist struct {
|
||||
OrgID int64
|
||||
TeamID int64
|
||||
Name string
|
||||
}
|
||||
|
||||
// IsErrTeamNotExist checks if an error is a ErrTeamNotExist.
|
||||
func IsErrTeamNotExist(err error) bool {
|
||||
_, ok := err.(ErrTeamNotExist)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrTeamNotExist) Error() string {
|
||||
return fmt.Sprintf("team does not exist [org_id %d, team_id %d, name: %s]", err.OrgID, err.TeamID, err.Name)
|
||||
}
|
||||
|
||||
//
|
||||
// Two-factor authentication
|
||||
//
|
||||
|
|
|
@ -508,4 +508,15 @@
|
|||
num_stars: 0
|
||||
num_forks: 0
|
||||
num_issues: 0
|
||||
is_mirror: false
|
||||
|
||||
-
|
||||
id: 43
|
||||
owner_id: 26
|
||||
lower_name: repo26
|
||||
name: repo26
|
||||
is_private: true
|
||||
num_stars: 0
|
||||
num_forks: 0
|
||||
num_issues: 0
|
||||
is_mirror: false
|
|
@ -87,3 +87,12 @@
|
|||
authorize: 1 # owner
|
||||
num_repos: 0
|
||||
num_members: 1
|
||||
|
||||
-
|
||||
id: 11
|
||||
org_id: 26
|
||||
lower_name: team11
|
||||
name: team11
|
||||
authorize: 1 # read
|
||||
num_repos: 0
|
||||
num_members: 0
|
||||
|
|
|
@ -410,3 +410,21 @@
|
|||
num_repos: 0
|
||||
num_members: 1
|
||||
num_teams: 1
|
||||
|
||||
-
|
||||
id: 26
|
||||
lower_name: org26
|
||||
name: org26
|
||||
full_name: "Org26"
|
||||
email: org26@example.com
|
||||
email_notifications_preference: onmention
|
||||
passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f4701772a025a # password
|
||||
type: 1 # organization
|
||||
salt: ZogKvWdyEx
|
||||
is_admin: false
|
||||
avatar: avatar26
|
||||
avatar_email: org26@example.com
|
||||
num_repos: 1
|
||||
num_members: 0
|
||||
num_teams: 1
|
||||
repo_admin_change_team_access: true
|
|
@ -248,6 +248,8 @@ var migrations = []Migration{
|
|||
NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns),
|
||||
// v96 -> v97
|
||||
NewMigration("delete orphaned attachments", deleteOrphanedAttachments),
|
||||
// v97 -> v98
|
||||
NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser),
|
||||
}
|
||||
|
||||
// Migrate database to current version
|
||||
|
|
15
models/migrations/v97.go
Normal file
15
models/migrations/v97.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2019 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 addRepoAdminChangeTeamAccessColumnForUser(x *xorm.Engine) error {
|
||||
type User struct {
|
||||
RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"`
|
||||
}
|
||||
|
||||
return x.Sync2(new(User))
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -20,11 +19,6 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrTeamNotExist team does not exist
|
||||
ErrTeamNotExist = errors.New("Team does not exist")
|
||||
)
|
||||
|
||||
// IsOwnedBy returns true if given user is in the owner team.
|
||||
func (org *User) IsOwnedBy(uid int64) (bool, error) {
|
||||
return IsOrganizationOwner(org.ID, uid)
|
||||
|
@ -304,7 +298,7 @@ type OrgUser struct {
|
|||
func isOrganizationOwner(e Engine, orgID, uid int64) (bool, error) {
|
||||
ownerTeam, err := getOwnerTeam(e, orgID)
|
||||
if err != nil {
|
||||
if err == ErrTeamNotExist {
|
||||
if IsErrTeamNotExist(err) {
|
||||
log.Error("Organization does not have owner team: %d", orgID)
|
||||
return false, nil
|
||||
}
|
||||
|
|
|
@ -352,7 +352,7 @@ func getTeam(e Engine, orgID int64, name string) (*Team, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
return nil, ErrTeamNotExist{orgID, 0, name}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ func getTeamByID(e Engine, teamID int64) (*Team, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrTeamNotExist
|
||||
return nil, ErrTeamNotExist{0, teamID, ""}
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
|
|
@ -64,11 +64,11 @@ func TestUser_GetTeam(t *testing.T) {
|
|||
assert.Equal(t, "team1", team.LowerName)
|
||||
|
||||
_, err = org.GetTeam("does not exist")
|
||||
assert.Equal(t, ErrTeamNotExist, err)
|
||||
assert.True(t, IsErrTeamNotExist(err))
|
||||
|
||||
nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||
_, err = nonOrg.GetTeam("team")
|
||||
assert.Equal(t, ErrTeamNotExist, err)
|
||||
assert.True(t, IsErrTeamNotExist(err))
|
||||
}
|
||||
|
||||
func TestUser_GetOwnerTeam(t *testing.T) {
|
||||
|
@ -80,7 +80,7 @@ func TestUser_GetOwnerTeam(t *testing.T) {
|
|||
|
||||
nonOrg := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||
_, err = nonOrg.GetOwnerTeam()
|
||||
assert.Equal(t, ErrTeamNotExist, err)
|
||||
assert.True(t, IsErrTeamNotExist(err))
|
||||
}
|
||||
|
||||
func TestUser_GetTeams(t *testing.T) {
|
||||
|
|
|
@ -16,20 +16,6 @@ type Collaboration struct {
|
|||
Mode AccessMode `xorm:"DEFAULT 2 NOT NULL"`
|
||||
}
|
||||
|
||||
// ModeI18nKey returns the collaboration mode I18n Key
|
||||
func (c *Collaboration) ModeI18nKey() string {
|
||||
switch c.Mode {
|
||||
case AccessModeRead:
|
||||
return "repo.settings.collaboration.read"
|
||||
case AccessModeWrite:
|
||||
return "repo.settings.collaboration.write"
|
||||
case AccessModeAdmin:
|
||||
return "repo.settings.collaboration.admin"
|
||||
default:
|
||||
return "repo.settings.collaboration.undefined"
|
||||
}
|
||||
}
|
||||
|
||||
// AddCollaborator adds new collaboration to a repository with default access mode.
|
||||
func (repo *Repository) AddCollaborator(u *User) error {
|
||||
collaboration := &Collaboration{
|
||||
|
@ -183,3 +169,17 @@ func (repo *Repository) DeleteCollaboration(uid int64) (err error) {
|
|||
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
func (repo *Repository) getRepoTeams(e Engine) (teams []*Team, err error) {
|
||||
return teams, e.
|
||||
Join("INNER", "team_repo", "team_repo.team_id = team.id").
|
||||
Where("team.org_id = ?", repo.OwnerID).
|
||||
And("team_repo.repo_id=?", repo.ID).
|
||||
OrderBy("CASE WHEN name LIKE '" + ownerTeamName + "' THEN '' ELSE name END").
|
||||
Find(&teams)
|
||||
}
|
||||
|
||||
// GetRepoTeams gets the list of teams that has access to the repository
|
||||
func (repo *Repository) GetRepoTeams() ([]*Team, error) {
|
||||
return repo.getRepoTeams(x)
|
||||
}
|
||||
|
|
|
@ -10,17 +10,6 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCollaboration_ModeI18nKey(t *testing.T) {
|
||||
assert.Equal(t, "repo.settings.collaboration.read",
|
||||
(&Collaboration{Mode: AccessModeRead}).ModeI18nKey())
|
||||
assert.Equal(t, "repo.settings.collaboration.write",
|
||||
(&Collaboration{Mode: AccessModeWrite}).ModeI18nKey())
|
||||
assert.Equal(t, "repo.settings.collaboration.admin",
|
||||
(&Collaboration{Mode: AccessModeAdmin}).ModeI18nKey())
|
||||
assert.Equal(t, "repo.settings.collaboration.undefined",
|
||||
(&Collaboration{Mode: AccessModeNone}).ModeI18nKey())
|
||||
}
|
||||
|
||||
func TestRepository_AddCollaborator(t *testing.T) {
|
||||
assert.NoError(t, PrepareTestDatabase())
|
||||
|
||||
|
|
|
@ -147,12 +147,13 @@ type User struct {
|
|||
NumRepos int
|
||||
|
||||
// For organization
|
||||
NumTeams int
|
||||
NumMembers int
|
||||
Teams []*Team `xorm:"-"`
|
||||
Members UserList `xorm:"-"`
|
||||
MembersIsPublic map[int64]bool `xorm:"-"`
|
||||
Visibility structs.VisibleType `xorm:"NOT NULL DEFAULT 0"`
|
||||
NumTeams int
|
||||
NumMembers int
|
||||
Teams []*Team `xorm:"-"`
|
||||
Members UserList `xorm:"-"`
|
||||
MembersIsPublic map[int64]bool `xorm:"-"`
|
||||
Visibility structs.VisibleType `xorm:"NOT NULL DEFAULT 0"`
|
||||
RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"`
|
||||
|
||||
// Preferences
|
||||
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
|
||||
|
|
|
@ -140,7 +140,10 @@ func TestSearchUsers(t *testing.T) {
|
|||
testOrgSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 3, PageSize: 2},
|
||||
[]int64{19, 25})
|
||||
|
||||
testOrgSuccess(&SearchUserOptions{Page: 4, PageSize: 2},
|
||||
testOrgSuccess(&SearchUserOptions{OrderBy: "id ASC", Page: 4, PageSize: 2},
|
||||
[]int64{26})
|
||||
|
||||
testOrgSuccess(&SearchUserOptions{Page: 5, PageSize: 2},
|
||||
[]int64{})
|
||||
|
||||
// test users
|
||||
|
|
|
@ -43,7 +43,7 @@ func (users UserList) loadOrganizationOwners(e Engine, orgID int64) (map[int64]*
|
|||
}
|
||||
ownerTeam, err := getOwnerTeam(e, orgID)
|
||||
if err != nil {
|
||||
if err == ErrTeamNotExist {
|
||||
if IsErrTeamNotExist(err) {
|
||||
log.Error("Organization does not have owner team: %d", orgID)
|
||||
return nil, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue