2016-03-06 02:08:42 +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 (
"fmt"
)
// Collaboration represent the relation between an individual and a repository.
type Collaboration struct {
2016-03-10 03:53:30 +03:00
ID int64 ` xorm:"pk autoincr" `
RepoID int64 ` xorm:"UNIQUE(s) INDEX NOT NULL" `
UserID int64 ` xorm:"UNIQUE(s) INDEX NOT NULL" `
Mode AccessMode ` xorm:"DEFAULT 2 NOT NULL" `
2016-03-06 02:08:42 +03:00
}
2019-11-20 14:27:49 +03:00
func ( repo * Repository ) addCollaborator ( e Engine , u * User ) error {
2016-03-06 02:08:42 +03:00
collaboration := & Collaboration {
RepoID : repo . ID ,
2016-07-23 20:08:22 +03:00
UserID : u . ID ,
2016-03-06 02:08:42 +03:00
}
2019-11-20 14:27:49 +03:00
has , err := e . Get ( collaboration )
2016-03-06 02:08:42 +03:00
if err != nil {
return err
} else if has {
return nil
}
2016-11-07 19:20:37 +03:00
collaboration . Mode = AccessModeWrite
2016-03-06 02:08:42 +03:00
2019-11-20 14:27:49 +03:00
if _ , err = e . InsertOne ( collaboration ) ; err != nil {
2016-03-06 02:08:42 +03:00
return err
}
2019-11-20 14:27:49 +03:00
return repo . recalculateUserAccess ( e , u . ID )
}
// AddCollaborator adds new collaboration to a repository with default access mode.
func ( repo * Repository ) AddCollaborator ( u * User ) error {
sess := x . NewSession ( )
defer sess . Close ( )
if err := sess . Begin ( ) ; err != nil {
2016-03-06 02:08:42 +03:00
return err
}
2019-11-20 14:27:49 +03:00
if err := repo . addCollaborator ( sess , u ) ; err != nil {
return err
2016-03-06 02:08:42 +03:00
}
return sess . Commit ( )
}
func ( repo * Repository ) getCollaborations ( e Engine ) ( [ ] * Collaboration , error ) {
2016-11-29 16:05:26 +03:00
var collaborations [ ] * Collaboration
2016-03-06 02:08:42 +03:00
return collaborations , e . Find ( & collaborations , & Collaboration { RepoID : repo . ID } )
}
// Collaborator represents a user with collaboration details.
type Collaborator struct {
* User
Collaboration * Collaboration
}
func ( repo * Repository ) getCollaborators ( e Engine ) ( [ ] * Collaborator , error ) {
collaborations , err := repo . getCollaborations ( e )
if err != nil {
return nil , fmt . Errorf ( "getCollaborations: %v" , err )
}
collaborators := make ( [ ] * Collaborator , len ( collaborations ) )
for i , c := range collaborations {
user , err := getUserByID ( e , c . UserID )
if err != nil {
return nil , err
}
collaborators [ i ] = & Collaborator {
User : user ,
Collaboration : c ,
}
}
return collaborators , nil
}
// GetCollaborators returns the collaborators for a repository
func ( repo * Repository ) GetCollaborators ( ) ( [ ] * Collaborator , error ) {
return repo . getCollaborators ( x )
}
2019-10-15 03:55:21 +03:00
func ( repo * Repository ) getCollaboration ( e Engine , uid int64 ) ( * Collaboration , error ) {
collaboration := & Collaboration {
RepoID : repo . ID ,
UserID : uid ,
}
has , err := e . Get ( collaboration )
if ! has {
collaboration = nil
}
return collaboration , err
}
2016-12-26 10:37:01 +03:00
func ( repo * Repository ) isCollaborator ( e Engine , userID int64 ) ( bool , error ) {
return e . Get ( & Collaboration { RepoID : repo . ID , UserID : userID } )
}
// IsCollaborator check if a user is a collaborator of a repository
func ( repo * Repository ) IsCollaborator ( userID int64 ) ( bool , error ) {
return repo . isCollaborator ( x , userID )
}
2019-11-20 14:27:49 +03:00
func ( repo * Repository ) changeCollaborationAccessMode ( e Engine , uid int64 , mode AccessMode ) error {
2016-03-06 02:08:42 +03:00
// Discard invalid input
2016-11-07 19:20:37 +03:00
if mode <= AccessModeNone || mode > AccessModeOwner {
2016-03-06 02:08:42 +03:00
return nil
}
collaboration := & Collaboration {
RepoID : repo . ID ,
UserID : uid ,
}
2019-11-20 14:27:49 +03:00
has , err := e . Get ( collaboration )
2016-03-06 02:08:42 +03:00
if err != nil {
return fmt . Errorf ( "get collaboration: %v" , err )
} else if ! has {
return nil
}
2016-08-11 21:35:46 +03:00
if collaboration . Mode == mode {
return nil
}
2016-03-06 02:08:42 +03:00
collaboration . Mode = mode
2019-11-20 14:27:49 +03:00
if _ , err = e .
2019-06-12 22:41:28 +03:00
ID ( collaboration . ID ) .
2017-09-25 07:59:27 +03:00
Cols ( "mode" ) .
2016-11-10 18:16:32 +03:00
Update ( collaboration ) ; err != nil {
2016-03-06 02:08:42 +03:00
return fmt . Errorf ( "update collaboration: %v" , err )
2019-11-20 14:27:49 +03:00
} else if _ , err = e . Exec ( "UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?" , mode , uid , repo . ID ) ; err != nil {
2016-03-06 02:08:42 +03:00
return fmt . Errorf ( "update access table: %v" , err )
}
2019-11-20 14:27:49 +03:00
return nil
}
// ChangeCollaborationAccessMode sets new access mode for the collaboration.
func ( repo * Repository ) ChangeCollaborationAccessMode ( uid int64 , mode AccessMode ) error {
sess := x . NewSession ( )
defer sess . Close ( )
if err := sess . Begin ( ) ; err != nil {
return err
}
if err := repo . changeCollaborationAccessMode ( sess , uid , mode ) ; err != nil {
return err
}
2016-03-06 02:08:42 +03:00
return sess . Commit ( )
}
// DeleteCollaboration removes collaboration relation between the user and repository.
func ( repo * Repository ) DeleteCollaboration ( uid int64 ) ( err error ) {
collaboration := & Collaboration {
RepoID : repo . ID ,
UserID : uid ,
}
sess := x . NewSession ( )
2017-06-21 03:57:05 +03:00
defer sess . Close ( )
2016-03-06 02:08:42 +03:00
if err = sess . Begin ( ) ; err != nil {
return err
}
if has , err := sess . Delete ( collaboration ) ; err != nil || has == 0 {
return err
} else if err = repo . recalculateAccesses ( sess ) ; err != nil {
return err
}
2018-06-19 22:44:33 +03:00
if err = watchRepo ( sess , uid , repo . ID , false ) ; err != nil {
return err
}
// Remove all IssueWatches a user has subscribed to in the repository
if err := removeIssueWatchersByRepoID ( sess , uid , repo . ID ) ; err != nil {
return err
}
2016-03-06 02:08:42 +03:00
return sess . Commit ( )
}
2019-09-23 23:08:03 +03:00
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 )
}