2017-02-23 04:36:15 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2017-02-23 04:36:15 +03:00
2024-11-28 00:12:26 +03:00
package org
2017-02-23 04:36:15 +03:00
import (
2024-11-28 00:12:26 +03:00
"fmt"
2017-02-23 04:36:15 +03:00
"strings"
"testing"
2021-11-24 12:49:20 +03:00
"code.gitea.io/gitea/models/db"
2022-03-29 09:29:02 +03:00
"code.gitea.io/gitea/models/organization"
2021-11-28 14:58:28 +03:00
"code.gitea.io/gitea/models/perm"
2022-05-11 13:09:36 +03:00
access_model "code.gitea.io/gitea/models/perm/access"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-12 17:36:47 +03:00
"code.gitea.io/gitea/models/unittest"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2024-11-28 00:12:26 +03:00
"code.gitea.io/gitea/modules/structs"
repo_service "code.gitea.io/gitea/services/repository"
2021-11-17 15:34:35 +03:00
2017-02-23 04:36:15 +03:00
"github.com/stretchr/testify/assert"
)
func TestTeam_AddMember ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2024-03-04 11:16:03 +03:00
test := func ( team * organization . Team , user * user_model . User ) {
assert . NoError ( t , AddTeamMember ( db . DefaultContext , team , user ) )
unittest . AssertExistsAndLoadBean ( t , & organization . TeamUser { UID : user . ID , TeamID : team . ID } )
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } , & user_model . User { ID : team . OrgID } )
2017-02-23 04:36:15 +03:00
}
2024-03-04 11:16:03 +03:00
team1 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 1 } )
team3 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 3 } )
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
user4 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } )
test ( team1 , user2 )
test ( team1 , user4 )
test ( team3 , user2 )
2017-02-23 04:36:15 +03:00
}
func TestTeam_RemoveMember ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2024-03-04 11:16:03 +03:00
testSuccess := func ( team * organization . Team , user * user_model . User ) {
assert . NoError ( t , RemoveTeamMember ( db . DefaultContext , team , user ) )
unittest . AssertNotExistsBean ( t , & organization . TeamUser { UID : user . ID , TeamID : team . ID } )
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } )
2017-02-23 04:36:15 +03:00
}
2024-03-04 11:16:03 +03:00
team1 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 1 } )
team2 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 2 } )
team3 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 3 } )
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
user4 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } )
testSuccess ( team1 , user4 )
testSuccess ( team2 , user2 )
testSuccess ( team3 , user2 )
err := RemoveTeamMember ( db . DefaultContext , team1 , user2 )
2022-03-29 09:29:02 +03:00
assert . True ( t , organization . IsErrLastOrgOwner ( err ) )
2017-02-23 04:36:15 +03:00
}
func TestNewTeam ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
const teamName = "newTeamName"
2022-03-29 09:29:02 +03:00
team := & organization . Team { Name : teamName , OrgID : 3 }
2023-09-14 20:09:32 +03:00
assert . NoError ( t , NewTeam ( db . DefaultContext , team ) )
2022-03-29 09:29:02 +03:00
unittest . AssertExistsAndLoadBean ( t , & organization . Team { Name : teamName } )
unittest . CheckConsistencyFor ( t , & organization . Team { } , & user_model . User { ID : team . OrgID } )
2017-02-23 04:36:15 +03:00
}
func TestUpdateTeam ( t * testing . T ) {
// successful update
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2022-08-16 05:22:25 +03:00
team := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 2 } )
2017-02-23 04:36:15 +03:00
team . LowerName = "newname"
team . Name = "newName"
team . Description = strings . Repeat ( "A long description!" , 100 )
2022-01-05 06:37:00 +03:00
team . AccessMode = perm . AccessModeAdmin
2023-09-14 20:09:32 +03:00
assert . NoError ( t , UpdateTeam ( db . DefaultContext , team , true , false ) )
2017-02-23 04:36:15 +03:00
2022-08-16 05:22:25 +03:00
team = unittest . AssertExistsAndLoadBean ( t , & organization . Team { Name : "newName" } )
2017-02-23 04:36:15 +03:00
assert . True ( t , strings . HasPrefix ( team . Description , "A long description!" ) )
2022-08-16 05:22:25 +03:00
access := unittest . AssertExistsAndLoadBean ( t , & access_model . Access { UserID : 4 , RepoID : 3 } )
2021-11-28 14:58:28 +03:00
assert . EqualValues ( t , perm . AccessModeAdmin , access . Mode )
2017-02-23 04:36:15 +03:00
2022-03-29 09:29:02 +03:00
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } )
2017-02-23 04:36:15 +03:00
}
func TestUpdateTeam2 ( t * testing . T ) {
// update to already-existing team
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2022-08-16 05:22:25 +03:00
team := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 2 } )
2017-02-23 04:36:15 +03:00
team . LowerName = "owners"
team . Name = "Owners"
team . Description = strings . Repeat ( "A long description!" , 100 )
2023-09-14 20:09:32 +03:00
err := UpdateTeam ( db . DefaultContext , team , true , false )
2022-03-29 09:29:02 +03:00
assert . True ( t , organization . IsErrTeamAlreadyExist ( err ) )
2017-02-23 04:36:15 +03:00
2022-03-29 09:29:02 +03:00
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } )
2017-02-23 04:36:15 +03:00
}
func TestDeleteTeam ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2022-08-16 05:22:25 +03:00
team := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 2 } )
2023-09-14 20:09:32 +03:00
assert . NoError ( t , DeleteTeam ( db . DefaultContext , team ) )
2022-03-29 09:29:02 +03:00
unittest . AssertNotExistsBean ( t , & organization . Team { ID : team . ID } )
unittest . AssertNotExistsBean ( t , & organization . TeamRepo { TeamID : team . ID } )
unittest . AssertNotExistsBean ( t , & organization . TeamUser { TeamID : team . ID } )
2017-02-23 04:36:15 +03:00
// check that team members don't have "leftover" access to repos
2022-08-16 05:22:25 +03:00
user := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } )
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 3 } )
2022-11-19 11:12:33 +03:00
accessMode , err := access_model . AccessLevel ( db . DefaultContext , user , repo )
2017-02-23 04:36:15 +03:00
assert . NoError ( t , err )
2021-11-28 14:58:28 +03:00
assert . True ( t , accessMode < perm . AccessModeWrite )
2017-02-23 04:36:15 +03:00
}
func TestAddTeamMember ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2024-03-04 11:16:03 +03:00
test := func ( team * organization . Team , user * user_model . User ) {
assert . NoError ( t , AddTeamMember ( db . DefaultContext , team , user ) )
unittest . AssertExistsAndLoadBean ( t , & organization . TeamUser { UID : user . ID , TeamID : team . ID } )
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } , & user_model . User { ID : team . OrgID } )
2017-02-23 04:36:15 +03:00
}
2024-03-04 11:16:03 +03:00
team1 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 1 } )
team3 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 3 } )
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
user4 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } )
test ( team1 , user2 )
test ( team1 , user4 )
test ( team3 , user2 )
2017-02-23 04:36:15 +03:00
}
func TestRemoveTeamMember ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-23 04:36:15 +03:00
2024-03-04 11:16:03 +03:00
testSuccess := func ( team * organization . Team , user * user_model . User ) {
assert . NoError ( t , RemoveTeamMember ( db . DefaultContext , team , user ) )
unittest . AssertNotExistsBean ( t , & organization . TeamUser { UID : user . ID , TeamID : team . ID } )
unittest . CheckConsistencyFor ( t , & organization . Team { ID : team . ID } )
2017-02-23 04:36:15 +03:00
}
2024-03-04 11:16:03 +03:00
team1 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 1 } )
team2 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 2 } )
team3 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 3 } )
user2 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } )
user4 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 4 } )
testSuccess ( team1 , user4 )
testSuccess ( team2 , user2 )
testSuccess ( team3 , user2 )
err := RemoveTeamMember ( db . DefaultContext , team1 , user2 )
2022-03-29 09:29:02 +03:00
assert . True ( t , organization . IsErrLastOrgOwner ( err ) )
2018-12-11 14:28:37 +03:00
}
2022-05-11 13:09:36 +03:00
func TestRepository_RecalculateAccesses3 ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2022-08-16 05:22:25 +03:00
team5 := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : 5 } )
user29 := unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 29 } )
2022-05-11 13:09:36 +03:00
2024-03-04 11:16:03 +03:00
has , err := db . GetEngine ( db . DefaultContext ) . Get ( & access_model . Access { UserID : user29 . ID , RepoID : 23 } )
2022-05-11 13:09:36 +03:00
assert . NoError ( t , err )
assert . False ( t , has )
// adding user29 to team5 should add an explicit access row for repo 23
// even though repo 23 is public
2024-03-04 11:16:03 +03:00
assert . NoError ( t , AddTeamMember ( db . DefaultContext , team5 , user29 ) )
2022-05-11 13:09:36 +03:00
2024-03-04 11:16:03 +03:00
has , err = db . GetEngine ( db . DefaultContext ) . Get ( & access_model . Access { UserID : user29 . ID , RepoID : 23 } )
2022-05-11 13:09:36 +03:00
assert . NoError ( t , err )
assert . True ( t , has )
}
2024-11-28 00:12:26 +03:00
func TestIncludesAllRepositoriesTeams ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
testTeamRepositories := func ( teamID int64 , repoIDs [ ] int64 ) {
team := unittest . AssertExistsAndLoadBean ( t , & organization . Team { ID : teamID } )
assert . NoError ( t , team . LoadRepositories ( db . DefaultContext ) , "%s: GetRepositories" , team . Name )
assert . Len ( t , team . Repos , team . NumRepos , "%s: len repo" , team . Name )
assert . Len ( t , team . Repos , len ( repoIDs ) , "%s: repo count" , team . Name )
for i , rid := range repoIDs {
if rid > 0 {
assert . True ( t , repo_service . HasRepository ( db . DefaultContext , team , rid ) , "%s: HasRepository(%d) %d" , rid , i )
}
}
}
// Get an admin user.
user , err := user_model . GetUserByID ( db . DefaultContext , 1 )
assert . NoError ( t , err , "GetUserByID" )
// Create org.
org := & organization . Organization {
Name : "All_repo" ,
IsActive : true ,
Type : user_model . UserTypeOrganization ,
Visibility : structs . VisibleTypePublic ,
}
assert . NoError ( t , organization . CreateOrganization ( db . DefaultContext , org , user ) , "CreateOrganization" )
// Check Owner team.
ownerTeam , err := org . GetOwnerTeam ( db . DefaultContext )
assert . NoError ( t , err , "GetOwnerTeam" )
assert . True ( t , ownerTeam . IncludesAllRepositories , "Owner team includes all repositories" )
// Create repos.
repoIDs := make ( [ ] int64 , 0 )
for i := 0 ; i < 3 ; i ++ {
r , err := repo_service . CreateRepositoryDirectly ( db . DefaultContext , user , org . AsUser ( ) , repo_service . CreateRepoOptions { Name : fmt . Sprintf ( "repo-%d" , i ) } )
assert . NoError ( t , err , "CreateRepository %d" , i )
if r != nil {
repoIDs = append ( repoIDs , r . ID )
}
}
// Get fresh copy of Owner team after creating repos.
ownerTeam , err = org . GetOwnerTeam ( db . DefaultContext )
assert . NoError ( t , err , "GetOwnerTeam" )
// Create teams and check repositories.
teams := [ ] * organization . Team {
ownerTeam ,
{
OrgID : org . ID ,
Name : "team one" ,
AccessMode : perm . AccessModeRead ,
IncludesAllRepositories : true ,
} ,
{
OrgID : org . ID ,
Name : "team 2" ,
AccessMode : perm . AccessModeRead ,
IncludesAllRepositories : false ,
} ,
{
OrgID : org . ID ,
Name : "team three" ,
AccessMode : perm . AccessModeWrite ,
IncludesAllRepositories : true ,
} ,
{
OrgID : org . ID ,
Name : "team 4" ,
AccessMode : perm . AccessModeWrite ,
IncludesAllRepositories : false ,
} ,
}
teamRepos := [ ] [ ] int64 {
repoIDs ,
repoIDs ,
{ } ,
repoIDs ,
{ } ,
}
for i , team := range teams {
if i > 0 { // first team is Owner.
assert . NoError ( t , NewTeam ( db . DefaultContext , team ) , "%s: NewTeam" , team . Name )
}
testTeamRepositories ( team . ID , teamRepos [ i ] )
}
// Update teams and check repositories.
teams [ 3 ] . IncludesAllRepositories = false
teams [ 4 ] . IncludesAllRepositories = true
teamRepos [ 4 ] = repoIDs
for i , team := range teams {
assert . NoError ( t , UpdateTeam ( db . DefaultContext , team , false , true ) , "%s: UpdateTeam" , team . Name )
testTeamRepositories ( team . ID , teamRepos [ i ] )
}
// Create repo and check teams repositories.
r , err := repo_service . CreateRepositoryDirectly ( db . DefaultContext , user , org . AsUser ( ) , repo_service . CreateRepoOptions { Name : "repo-last" } )
assert . NoError ( t , err , "CreateRepository last" )
if r != nil {
repoIDs = append ( repoIDs , r . ID )
}
teamRepos [ 0 ] = repoIDs
teamRepos [ 1 ] = repoIDs
teamRepos [ 4 ] = repoIDs
for i , team := range teams {
testTeamRepositories ( team . ID , teamRepos [ i ] )
}
// Remove repo and check teams repositories.
assert . NoError ( t , repo_service . DeleteRepositoryDirectly ( db . DefaultContext , user , repoIDs [ 0 ] ) , "DeleteRepository" )
teamRepos [ 0 ] = repoIDs [ 1 : ]
teamRepos [ 1 ] = repoIDs [ 1 : ]
teamRepos [ 3 ] = repoIDs [ 1 : 3 ]
teamRepos [ 4 ] = repoIDs [ 1 : ]
for i , team := range teams {
testTeamRepositories ( team . ID , teamRepos [ i ] )
}
// Wipe created items.
for i , rid := range repoIDs {
if i > 0 { // first repo already deleted.
assert . NoError ( t , repo_service . DeleteRepositoryDirectly ( db . DefaultContext , user , rid ) , "DeleteRepository %d" , i )
}
}
assert . NoError ( t , organization . DeleteOrganization ( db . DefaultContext , org ) , "DeleteOrganization" )
}