2016-03-26 01:04:02 +03:00
// Copyright 2016 The Gogs 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 models
import (
"errors"
"fmt"
"strings"
)
2016-11-28 04:30:08 +03:00
const ownerTeamName = "Owners"
2016-03-26 01:04:02 +03:00
// Team represents a organization team.
type Team struct {
ID int64 ` xorm:"pk autoincr" `
OrgID int64 ` xorm:"INDEX" `
LowerName string
Name string
Description string
Authorize AccessMode
Repos [ ] * Repository ` xorm:"-" `
Members [ ] * User ` xorm:"-" `
NumRepos int
NumMembers int
2017-05-18 17:54:24 +03:00
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
2016-03-26 01:04:02 +03:00
}
// IsOwnerTeam returns true if team is owner team.
func ( t * Team ) IsOwnerTeam ( ) bool {
2016-11-28 04:30:08 +03:00
return t . Name == ownerTeamName
2016-03-26 01:04:02 +03:00
}
2016-11-28 04:30:08 +03:00
// IsMember returns true if given user is a member of team.
2016-11-28 11:33:08 +03:00
func ( t * Team ) IsMember ( userID int64 ) bool {
return IsTeamMember ( t . OrgID , t . ID , userID )
2016-03-26 01:04:02 +03:00
}
2017-02-23 04:36:15 +03:00
func ( t * Team ) getRepositories ( e Engine ) error {
2017-02-16 07:07:58 +03:00
return e . Join ( "INNER" , "team_repo" , "repository.id = team_repo.repo_id" ) .
Where ( "team_repo.team_id=?" , t . ID ) . Find ( & t . Repos )
2016-03-26 01:04:02 +03:00
}
// GetRepositories returns all repositories in team of organization.
func ( t * Team ) GetRepositories ( ) error {
return t . getRepositories ( x )
}
func ( t * Team ) getMembers ( e Engine ) ( err error ) {
t . Members , err = getTeamMembers ( e , t . ID )
return err
}
// GetMembers returns all members in team of organization.
func ( t * Team ) GetMembers ( ) ( err error ) {
return t . getMembers ( x )
}
// AddMember adds new membership of the team to the organization,
// the user will have membership to the organization automatically when needed.
2016-11-28 11:33:08 +03:00
func ( t * Team ) AddMember ( userID int64 ) error {
2017-02-24 09:25:09 +03:00
return AddTeamMember ( t , userID )
2016-03-26 01:04:02 +03:00
}
// RemoveMember removes member from team of organization.
2016-11-28 11:33:08 +03:00
func ( t * Team ) RemoveMember ( userID int64 ) error {
2017-02-24 09:25:09 +03:00
return RemoveTeamMember ( t , userID )
2016-03-26 01:04:02 +03:00
}
func ( t * Team ) hasRepository ( e Engine , repoID int64 ) bool {
return hasTeamRepo ( e , t . OrgID , t . ID , repoID )
}
// HasRepository returns true if given repository belong to team.
func ( t * Team ) HasRepository ( repoID int64 ) bool {
return t . hasRepository ( x , repoID )
}
func ( t * Team ) addRepository ( e Engine , repo * Repository ) ( err error ) {
if err = addTeamRepo ( e , t . OrgID , t . ID , repo . ID ) ; err != nil {
return err
}
t . NumRepos ++
if _ , err = e . Id ( t . ID ) . AllCols ( ) . Update ( t ) ; err != nil {
return fmt . Errorf ( "update team: %v" , err )
}
if err = repo . recalculateTeamAccesses ( e , 0 ) ; err != nil {
return fmt . Errorf ( "recalculateAccesses: %v" , err )
}
if err = t . getMembers ( e ) ; err != nil {
return fmt . Errorf ( "getMembers: %v" , err )
}
for _ , u := range t . Members {
2016-07-23 20:08:22 +03:00
if err = watchRepo ( e , u . ID , repo . ID , true ) ; err != nil {
2016-03-26 01:04:02 +03:00
return fmt . Errorf ( "watchRepo: %v" , err )
}
}
return nil
}
// AddRepository adds new repository to team of organization.
func ( t * Team ) AddRepository ( repo * Repository ) ( err error ) {
if repo . OwnerID != t . OrgID {
return errors . New ( "Repository does not belong to organization" )
} else if t . HasRepository ( repo . ID ) {
return nil
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-03-26 01:04:02 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
if err = t . addRepository ( sess , repo ) ; err != nil {
return err
}
return sess . Commit ( )
}
func ( t * Team ) removeRepository ( e Engine , repo * Repository , recalculate bool ) ( err error ) {
if err = removeTeamRepo ( e , t . ID , repo . ID ) ; err != nil {
return err
}
t . NumRepos --
if _ , err = e . Id ( t . ID ) . AllCols ( ) . Update ( t ) ; err != nil {
return err
}
// Don't need to recalculate when delete a repository from organization.
if recalculate {
if err = repo . recalculateTeamAccesses ( e , t . ID ) ; err != nil {
return err
}
}
2017-03-15 03:51:46 +03:00
teamUsers , err := getTeamUsersByTeamID ( e , t . ID )
if err != nil {
return fmt . Errorf ( "getTeamUsersByTeamID: %v" , err )
2016-03-26 01:04:02 +03:00
}
2017-03-21 03:55:00 +03:00
for _ , teamUser := range teamUsers {
2017-03-15 03:51:46 +03:00
has , err := hasAccess ( e , teamUser . UID , repo , AccessModeRead )
2016-03-26 01:04:02 +03:00
if err != nil {
return err
} else if has {
continue
}
2017-03-15 03:51:46 +03:00
if err = watchRepo ( e , teamUser . UID , repo . ID , false ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
}
return nil
}
// RemoveRepository removes repository from team of organization.
func ( t * Team ) RemoveRepository ( repoID int64 ) error {
if ! t . HasRepository ( repoID ) {
return nil
}
repo , err := GetRepositoryByID ( repoID )
if err != nil {
return err
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-03-26 01:04:02 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
if err = t . removeRepository ( sess , repo , true ) ; err != nil {
return err
}
return sess . Commit ( )
}
2017-08-02 11:46:54 +03:00
// UnitEnabled returns if the team has the given unit type enabled
func ( t * Team ) UnitEnabled ( tp UnitType ) bool {
2017-05-18 17:54:24 +03:00
if len ( t . UnitTypes ) == 0 {
return true
}
for _ , u := range t . UnitTypes {
if u == tp {
return true
}
}
return false
}
2016-11-28 04:30:08 +03:00
// IsUsableTeamName tests if a name could be as team name
2017-02-23 04:36:15 +03:00
func IsUsableTeamName ( name string ) error {
switch name {
case "new" :
return ErrNameReserved { name }
default :
return nil
2016-11-06 12:07:03 +03:00
}
}
2016-03-26 01:04:02 +03:00
// NewTeam creates a record of new team.
// It's caller's responsibility to assign organization ID.
2016-11-06 12:07:03 +03:00
func NewTeam ( t * Team ) ( err error ) {
2016-03-26 01:04:02 +03:00
if len ( t . Name ) == 0 {
return errors . New ( "empty team name" )
}
2016-11-06 12:07:03 +03:00
if err = IsUsableTeamName ( t . Name ) ; err != nil {
return err
}
2016-03-26 01:04:02 +03:00
has , err := x . Id ( t . OrgID ) . Get ( new ( User ) )
if err != nil {
return err
} else if ! has {
2017-07-06 16:30:19 +03:00
return ErrOrgNotExist { t . OrgID , "" }
2016-03-26 01:04:02 +03:00
}
t . LowerName = strings . ToLower ( t . Name )
2016-11-10 18:16:32 +03:00
has , err = x .
Where ( "org_id=?" , t . OrgID ) .
And ( "lower_name=?" , t . LowerName ) .
Get ( new ( Team ) )
2016-03-26 01:04:02 +03:00
if err != nil {
return err
} else if has {
return ErrTeamAlreadyExist { t . OrgID , t . LowerName }
}
sess := x . NewSession ( )
defer sess . Close ( )
if err = sess . Begin ( ) ; err != nil {
return err
}
if _ , err = sess . Insert ( t ) ; err != nil {
sess . Rollback ( )
return err
}
// Update organization number of teams.
if _ , err = sess . Exec ( "UPDATE `user` SET num_teams=num_teams+1 WHERE id = ?" , t . OrgID ) ; err != nil {
sess . Rollback ( )
return err
}
return sess . Commit ( )
}
2016-11-28 04:30:08 +03:00
func getTeam ( e Engine , orgID int64 , name string ) ( * Team , error ) {
2016-03-26 01:04:02 +03:00
t := & Team {
2016-11-28 04:30:08 +03:00
OrgID : orgID ,
2016-03-26 01:04:02 +03:00
LowerName : strings . ToLower ( name ) ,
}
has , err := e . Get ( t )
if err != nil {
return nil , err
} else if ! has {
return nil , ErrTeamNotExist
}
return t , nil
}
// GetTeam returns team by given team name and organization.
2016-11-28 04:30:08 +03:00
func GetTeam ( orgID int64 , name string ) ( * Team , error ) {
return getTeam ( x , orgID , name )
2016-03-26 01:04:02 +03:00
}
2016-11-28 04:30:08 +03:00
func getTeamByID ( e Engine , teamID int64 ) ( * Team , error ) {
2016-03-26 01:04:02 +03:00
t := new ( Team )
2016-11-28 04:30:08 +03:00
has , err := e . Id ( teamID ) . Get ( t )
2016-03-26 01:04:02 +03:00
if err != nil {
return nil , err
} else if ! has {
return nil , ErrTeamNotExist
}
return t , nil
}
// GetTeamByID returns team by given ID.
2016-11-28 04:30:08 +03:00
func GetTeamByID ( teamID int64 ) ( * Team , error ) {
return getTeamByID ( x , teamID )
2016-03-26 01:04:02 +03:00
}
// UpdateTeam updates information of team.
func UpdateTeam ( t * Team , authChanged bool ) ( err error ) {
if len ( t . Name ) == 0 {
return errors . New ( "empty team name" )
}
if len ( t . Description ) > 255 {
t . Description = t . Description [ : 255 ]
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-03-26 01:04:02 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
t . LowerName = strings . ToLower ( t . Name )
2017-01-27 19:11:41 +03:00
has , err := sess .
2016-11-10 18:16:32 +03:00
Where ( "org_id=?" , t . OrgID ) .
And ( "lower_name=?" , t . LowerName ) .
And ( "id!=?" , t . ID ) .
Get ( new ( Team ) )
2016-03-26 01:04:02 +03:00
if err != nil {
return err
} else if has {
return ErrTeamAlreadyExist { t . OrgID , t . LowerName }
}
if _ , err = sess . Id ( t . ID ) . AllCols ( ) . Update ( t ) ; err != nil {
return fmt . Errorf ( "update: %v" , err )
}
// Update access for team members if needed.
if authChanged {
if err = t . getRepositories ( sess ) ; err != nil {
2017-02-23 04:36:15 +03:00
return fmt . Errorf ( "getRepositories: %v" , err )
2016-03-26 01:04:02 +03:00
}
for _ , repo := range t . Repos {
if err = repo . recalculateTeamAccesses ( sess , 0 ) ; err != nil {
return fmt . Errorf ( "recalculateTeamAccesses: %v" , err )
}
}
}
return sess . Commit ( )
}
// DeleteTeam deletes given team.
// It's caller's responsibility to assign organization ID.
func DeleteTeam ( t * Team ) error {
if err := t . GetRepositories ( ) ; err != nil {
return err
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2017-03-01 04:09:49 +03:00
if err := sess . Begin ( ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Delete all accesses.
for _ , repo := range t . Repos {
2017-03-01 04:09:49 +03:00
if err := repo . recalculateTeamAccesses ( sess , t . ID ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
}
2017-02-23 04:36:15 +03:00
// Delete team-repo
2017-03-01 04:09:49 +03:00
if _ , err := sess .
2017-02-23 04:36:15 +03:00
Where ( "team_id=?" , t . ID ) .
Delete ( new ( TeamRepo ) ) ; err != nil {
return err
}
2016-03-26 01:04:02 +03:00
// Delete team-user.
2017-03-01 04:09:49 +03:00
if _ , err := sess .
Where ( "org_id=?" , t . OrgID ) .
2016-11-10 18:16:32 +03:00
Where ( "team_id=?" , t . ID ) .
Delete ( new ( TeamUser ) ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Delete team.
2017-03-01 04:09:49 +03:00
if _ , err := sess . Id ( t . ID ) . Delete ( new ( Team ) ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Update organization number of teams.
2017-03-01 04:09:49 +03:00
if _ , err := sess . Exec ( "UPDATE `user` SET num_teams=num_teams-1 WHERE id=?" , t . OrgID ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
return sess . Commit ( )
}
// ___________ ____ ___
// \__ ___/___ _____ _____ | | \______ ___________
// | |_/ __ \\__ \ / \| | / ___// __ \_ __ \
// | |\ ___/ / __ \| Y Y \ | /\___ \\ ___/| | \/
// |____| \___ >____ /__|_| /______//____ >\___ >__|
// \/ \/ \/ \/ \/
// TeamUser represents an team-user relation.
type TeamUser struct {
ID int64 ` xorm:"pk autoincr" `
OrgID int64 ` xorm:"INDEX" `
TeamID int64 ` xorm:"UNIQUE(s)" `
2016-11-28 04:30:08 +03:00
UID int64 ` xorm:"UNIQUE(s)" `
2016-03-26 01:04:02 +03:00
}
2016-11-28 11:33:08 +03:00
func isTeamMember ( e Engine , orgID , teamID , userID int64 ) bool {
2016-11-10 18:16:32 +03:00
has , _ := e .
Where ( "org_id=?" , orgID ) .
And ( "team_id=?" , teamID ) .
2016-11-28 11:33:08 +03:00
And ( "uid=?" , userID ) .
2016-11-10 18:16:32 +03:00
Get ( new ( TeamUser ) )
2016-03-26 01:04:02 +03:00
return has
}
// IsTeamMember returns true if given user is a member of team.
2016-11-28 11:33:08 +03:00
func IsTeamMember ( orgID , teamID , userID int64 ) bool {
return isTeamMember ( x , orgID , teamID , userID )
2016-03-26 01:04:02 +03:00
}
2017-03-15 03:51:46 +03:00
func getTeamUsersByTeamID ( e Engine , teamID int64 ) ( [ ] * TeamUser , error ) {
2016-03-26 01:04:02 +03:00
teamUsers := make ( [ ] * TeamUser , 0 , 10 )
2017-03-15 03:51:46 +03:00
return teamUsers , e .
2016-11-10 18:16:32 +03:00
Where ( "team_id=?" , teamID ) .
2017-03-15 03:51:46 +03:00
Find ( & teamUsers )
}
func getTeamMembers ( e Engine , teamID int64 ) ( _ [ ] * User , err error ) {
teamUsers , err := getTeamUsersByTeamID ( e , teamID )
if err != nil {
2016-03-26 01:04:02 +03:00
return nil , fmt . Errorf ( "get team-users: %v" , err )
}
2017-03-15 03:51:46 +03:00
members := make ( [ ] * User , len ( teamUsers ) )
for i , teamUser := range teamUsers {
member , err := getUserByID ( e , teamUser . UID )
if err != nil {
return nil , fmt . Errorf ( "get user '%d': %v" , teamUser . UID , err )
2016-03-26 01:04:02 +03:00
}
2017-03-15 03:51:46 +03:00
members [ i ] = member
2016-03-26 01:04:02 +03:00
}
return members , nil
}
// GetTeamMembers returns all members in given team of organization.
func GetTeamMembers ( teamID int64 ) ( [ ] * User , error ) {
return getTeamMembers ( x , teamID )
}
2017-02-16 07:06:23 +03:00
func getUserTeams ( e Engine , orgID , userID int64 ) ( teams [ ] * Team , err error ) {
return teams , e .
Join ( "INNER" , "team_user" , "team_user.team_id = team.id" ) .
Where ( "team.org_id = ?" , orgID ) .
And ( "team_user.uid=?" , userID ) .
Find ( & teams )
2016-03-26 01:04:02 +03:00
}
// GetUserTeams returns all teams that user belongs to in given organization.
2016-11-28 11:33:08 +03:00
func GetUserTeams ( orgID , userID int64 ) ( [ ] * Team , error ) {
return getUserTeams ( x , orgID , userID )
2016-03-26 01:04:02 +03:00
}
// AddTeamMember adds new membership of given team to given organization,
// the user will have membership to given organization automatically when needed.
2017-02-24 09:25:09 +03:00
func AddTeamMember ( team * Team , userID int64 ) error {
if IsTeamMember ( team . OrgID , team . ID , userID ) {
2016-03-26 01:04:02 +03:00
return nil
}
2017-02-24 09:25:09 +03:00
if err := AddOrgUser ( team . OrgID , userID ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Get team and its repositories.
2017-02-24 09:25:09 +03:00
team . NumMembers ++
2016-03-26 01:04:02 +03:00
2017-02-24 09:25:09 +03:00
if err := team . GetRepositories ( ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2017-02-24 09:25:09 +03:00
if err := sess . Begin ( ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
2017-02-24 09:25:09 +03:00
if _ , err := sess . Insert ( & TeamUser {
2016-11-28 11:33:08 +03:00
UID : userID ,
2017-02-24 09:25:09 +03:00
OrgID : team . OrgID ,
TeamID : team . ID ,
} ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
2017-02-24 09:25:09 +03:00
} else if _ , err := sess . Id ( team . ID ) . Update ( team ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Give access to team repositories.
2017-02-24 09:25:09 +03:00
for _ , repo := range team . Repos {
if err := repo . recalculateTeamAccesses ( sess , 0 ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
}
// We make sure it exists before.
ou := new ( OrgUser )
2017-02-24 09:25:09 +03:00
if _ , err := sess .
2016-11-28 11:33:08 +03:00
Where ( "uid = ?" , userID ) .
2017-02-24 09:25:09 +03:00
And ( "org_id = ?" , team . OrgID ) .
2016-11-10 18:16:32 +03:00
Get ( ou ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
ou . NumTeams ++
2017-02-24 09:25:09 +03:00
if team . IsOwnerTeam ( ) {
2016-03-26 01:04:02 +03:00
ou . IsOwner = true
}
2017-02-24 09:25:09 +03:00
if _ , err := sess . Id ( ou . ID ) . AllCols ( ) . Update ( ou ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
return sess . Commit ( )
}
2017-02-24 09:25:09 +03:00
func removeTeamMember ( e Engine , team * Team , userID int64 ) error {
if ! isTeamMember ( e , team . OrgID , team . ID , userID ) {
2016-03-26 01:04:02 +03:00
return nil
}
// Check if the user to delete is the last member in owner team.
2017-02-24 09:25:09 +03:00
if team . IsOwnerTeam ( ) && team . NumMembers == 1 {
2016-11-28 11:33:08 +03:00
return ErrLastOrgOwner { UID : userID }
2016-03-26 01:04:02 +03:00
}
2017-02-24 09:25:09 +03:00
team . NumMembers --
2016-03-26 01:04:02 +03:00
2017-02-24 09:25:09 +03:00
if err := team . getRepositories ( e ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
2017-02-24 09:25:09 +03:00
if _ , err := e . Delete ( & TeamUser {
2016-11-28 11:33:08 +03:00
UID : userID ,
2017-02-24 09:25:09 +03:00
OrgID : team . OrgID ,
TeamID : team . ID ,
} ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
2016-11-10 18:16:32 +03:00
} else if _ , err = e .
2017-02-24 09:25:09 +03:00
Id ( team . ID ) .
2016-11-10 18:16:32 +03:00
AllCols ( ) .
2017-02-24 09:25:09 +03:00
Update ( team ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
// Delete access to team repositories.
2017-02-24 09:25:09 +03:00
for _ , repo := range team . Repos {
2017-03-01 04:09:49 +03:00
if err := repo . recalculateTeamAccesses ( e , 0 ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
}
// This must exist.
ou := new ( OrgUser )
2017-03-01 04:09:49 +03:00
_ , err := e .
2016-11-28 11:33:08 +03:00
Where ( "uid = ?" , userID ) .
2017-03-01 04:09:49 +03:00
And ( "org_id = ?" , team . OrgID ) .
2016-11-10 18:16:32 +03:00
Get ( ou )
2016-03-26 01:04:02 +03:00
if err != nil {
return err
}
ou . NumTeams --
2017-02-24 09:25:09 +03:00
if team . IsOwnerTeam ( ) {
2016-03-26 01:04:02 +03:00
ou . IsOwner = false
}
2016-11-10 18:16:32 +03:00
if _ , err = e .
Id ( ou . ID ) .
AllCols ( ) .
Update ( ou ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
return nil
}
// RemoveTeamMember removes member from given team of given organization.
2017-02-24 09:25:09 +03:00
func RemoveTeamMember ( team * Team , userID int64 ) error {
2016-03-26 01:04:02 +03:00
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-03-26 01:04:02 +03:00
if err := sess . Begin ( ) ; err != nil {
return err
}
2017-02-24 09:25:09 +03:00
if err := removeTeamMember ( sess , team , userID ) ; err != nil {
2016-03-26 01:04:02 +03:00
return err
}
return sess . Commit ( )
}
// ___________ __________
// \__ ___/___ _____ _____\______ \ ____ ______ ____
// | |_/ __ \\__ \ / \| _// __ \\____ \ / _ \
// | |\ ___/ / __ \| Y Y \ | \ ___/| |_> > <_> )
// |____| \___ >____ /__|_| /____|_ /\___ > __/ \____/
// \/ \/ \/ \/ \/|__|
// TeamRepo represents an team-repository relation.
type TeamRepo struct {
ID int64 ` xorm:"pk autoincr" `
OrgID int64 ` xorm:"INDEX" `
TeamID int64 ` xorm:"UNIQUE(s)" `
RepoID int64 ` xorm:"UNIQUE(s)" `
}
func hasTeamRepo ( e Engine , orgID , teamID , repoID int64 ) bool {
2016-11-10 18:16:32 +03:00
has , _ := e .
Where ( "org_id=?" , orgID ) .
And ( "team_id=?" , teamID ) .
And ( "repo_id=?" , repoID ) .
Get ( new ( TeamRepo ) )
2016-03-26 01:04:02 +03:00
return has
}
// HasTeamRepo returns true if given repository belongs to team.
func HasTeamRepo ( orgID , teamID , repoID int64 ) bool {
return hasTeamRepo ( x , orgID , teamID , repoID )
}
func addTeamRepo ( e Engine , orgID , teamID , repoID int64 ) error {
_ , err := e . InsertOne ( & TeamRepo {
OrgID : orgID ,
TeamID : teamID ,
RepoID : repoID ,
} )
return err
}
func removeTeamRepo ( e Engine , teamID , repoID int64 ) error {
_ , err := e . Delete ( & TeamRepo {
TeamID : teamID ,
RepoID : repoID ,
} )
return err
}