@ -6,9 +6,7 @@ package models
import (
import (
"errors"
"errors"
"fmt"
"os"
"os"
"path"
"strings"
"strings"
"github.com/Unknwon/com"
"github.com/Unknwon/com"
@ -136,7 +134,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
OrgId : org . Id ,
OrgId : org . Id ,
LowerName : strings . ToLower ( OWNER_TEAM ) ,
LowerName : strings . ToLower ( OWNER_TEAM ) ,
Name : OWNER_TEAM ,
Name : OWNER_TEAM ,
Authorize : ORG_ADMIN ,
Authorize : OwnerAccess ,
NumMembers : 1 ,
NumMembers : 1 ,
}
}
if _ , err = sess . Insert ( t ) ; err != nil {
if _ , err = sess . Insert ( t ) ; err != nil {
@ -371,10 +369,10 @@ func RemoveOrgUser(orgId, uid int64) error {
return err
return err
}
}
access := & Access {
access := & Access {
UserName : u . LowerName ,
UserID : u . Id ,
}
}
for _ , repo := range org . Repos {
for _ , repo := range org . Repos {
access . RepoName = path . Join ( org . LowerName , repo . LowerName )
access . RepoID = repo . Id
if _ , err = sess . Delete ( access ) ; err != nil {
if _ , err = sess . Delete ( access ) ; err != nil {
sess . Rollback ( )
sess . Rollback ( )
return err
return err
@ -405,21 +403,6 @@ func RemoveOrgUser(orgId, uid int64) error {
// |____| \___ >____ /__|_| /
// |____| \___ >____ /__|_| /
// \/ \/ \/
// \/ \/ \/
type AuthorizeType int
const (
ORG_READABLE AuthorizeType = iota + 1
ORG_WRITABLE
ORG_ADMIN
)
func AuthorizeToAccessType ( auth AuthorizeType ) AccessType {
if auth == ORG_READABLE {
return READABLE
}
return WRITABLE
}
const OWNER_TEAM = "Owners"
const OWNER_TEAM = "Owners"
// Team represents a organization team.
// Team represents a organization team.
@ -429,7 +412,7 @@ type Team struct {
LowerName string
LowerName string
Name string
Name string
Description string
Description string
Authorize AuthorizeTyp e
Authorize AccessMod e
RepoIds string ` xorm:"TEXT" `
RepoIds string ` xorm:"TEXT" `
Repos [ ] * Repository ` xorm:"-" `
Repos [ ] * Repository ` xorm:"-" `
Members [ ] * User ` xorm:"-" `
Members [ ] * User ` xorm:"-" `
@ -484,25 +467,6 @@ func (t *Team) RemoveMember(uid int64) error {
return RemoveTeamMember ( t . OrgId , t . Id , uid )
return RemoveTeamMember ( t . OrgId , t . Id , uid )
}
}
// addAccessWithAuthorize inserts or updates access with given mode.
func addAccessWithAuthorize ( e Engine , access * Access , mode AccessType ) error {
has , err := e . Get ( access )
if err != nil {
return fmt . Errorf ( "fail to get access: %v" , err )
}
access . Mode = mode
if has {
if _ , err = e . Id ( access . Id ) . Update ( access ) ; err != nil {
return fmt . Errorf ( "fail to update access: %v" , err )
}
} else {
if _ , err = e . Insert ( access ) ; err != nil {
return fmt . Errorf ( "fail to insert access: %v" , err )
}
}
return nil
}
// AddRepository adds new repository to team of organization.
// AddRepository adds new repository to team of organization.
func ( t * Team ) AddRepository ( repo * Repository ) ( err error ) {
func ( t * Team ) AddRepository ( repo * Repository ) ( err error ) {
idStr := "$" + com . ToStr ( repo . Id ) + "|"
idStr := "$" + com . ToStr ( repo . Id ) + "|"
@ -531,27 +495,13 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
return err
return err
}
}
// Give access to team members.
if err = repo . RecalcAccessSess ( ) ; err != nil {
mode := AuthorizeToAccessType ( t . Authorize )
sess . Rollback ( )
return err
}
for _ , u := range t . Members {
for _ , u := range t . Members {
auth , err := getHighestAuthorize ( sess , t . OrgId , u . Id , repo . Id , t . Id )
if err = WatchRepo ( u . Id , repo . Id , true ) ; err != nil {
if err != nil {
sess . Rollback ( )
return err
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( repo . Owner . LowerName , repo . LowerName ) ,
}
if auth < t . Authorize {
if err = addAccessWithAuthorize ( sess , access , mode ) ; err != nil {
sess . Rollback ( )
return err
}
}
if err = watchRepo ( sess , u . Id , repo . Id , true ) ; err != nil {
sess . Rollback ( )
sess . Rollback ( )
return err
return err
}
}
@ -559,6 +509,11 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
return sess . Commit ( )
return sess . Commit ( )
}
}
func ( t * Team ) HasRepository ( r * Repository ) bool {
idStr := "$" + com . ToStr ( r . Id ) + "|"
return strings . Contains ( t . RepoIds , idStr )
}
// RemoveRepository removes repository from team of organization.
// RemoveRepository removes repository from team of organization.
func ( t * Team ) RemoveRepository ( repoId int64 ) error {
func ( t * Team ) RemoveRepository ( repoId int64 ) error {
idStr := "$" + com . ToStr ( repoId ) + "|"
idStr := "$" + com . ToStr ( repoId ) + "|"
@ -590,32 +545,16 @@ func (t *Team) RemoveRepository(repoId int64) error {
return err
return err
}
}
// Remove access to team members.
if err = repo . RecalcAccessSess ( ) ; err != nil {
sess . Rollback ( )
return err
}
for _ , u := range t . Members {
for _ , u := range t . Members {
auth , err := getHighestAuthorize ( sess , t . OrgId , u . Id , repo . Id , t . Id )
if err = WatchRepo ( u . Id , repo . Id , false ) ; err != nil {
if err != nil {
sess . Rollback ( )
sess . Rollback ( )
return err
return err
}
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( repo . Owner . LowerName , repo . LowerName ) ,
}
if auth == 0 {
if _ , err = sess . Delete ( access ) ; err != nil {
sess . Rollback ( )
return fmt . Errorf ( "fail to delete access: %v" , err )
} else if err = watchRepo ( sess , u . Id , repo . Id , false ) ; err != nil {
sess . Rollback ( )
return err
}
} else if auth < t . Authorize {
if err = addAccessWithAuthorize ( sess , access , AuthorizeToAccessType ( auth ) ) ; err != nil {
sess . Rollback ( )
return err
}
}
}
}
return sess . Commit ( )
return sess . Commit ( )
@ -693,34 +632,6 @@ func GetTeamById(teamId int64) (*Team, error) {
return getTeamById ( x , teamId )
return getTeamById ( x , teamId )
}
}
func getHighestAuthorize ( e Engine , orgId , uid , repoId , teamId int64 ) ( AuthorizeType , error ) {
ts , err := getUserTeams ( e , orgId , uid )
if err != nil {
return 0 , err
}
var auth AuthorizeType = 0
for _ , t := range ts {
// Not current team and has given repository.
if t . Id != teamId && strings . Contains ( t . RepoIds , "$" + com . ToStr ( repoId ) + "|" ) {
// Fast return.
if t . Authorize == ORG_WRITABLE {
return ORG_WRITABLE , nil
}
if t . Authorize > auth {
auth = t . Authorize
}
}
}
return auth , nil
}
// GetHighestAuthorize returns highest repository authorize level for given user and team.
func GetHighestAuthorize ( orgId , uid , repoId , teamId int64 ) ( AuthorizeType , error ) {
return getHighestAuthorize ( x , orgId , uid , repoId , teamId )
}
// UpdateTeam updates information of team.
// UpdateTeam updates information of team.
func UpdateTeam ( t * Team , authChanged bool ) ( err error ) {
func UpdateTeam ( t * Team , authChanged bool ) ( err error ) {
if ! IsLegalName ( t . Name ) {
if ! IsLegalName ( t . Name ) {
@ -738,45 +649,14 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
}
}
// Update access for team members if needed.
// Update access for team members if needed.
if authChanged && ! t . IsOwnerTeam ( ) {
if authChanged {
if err = t . GetRepositories ( ) ; err != nil {
if err = t . GetRepositories ( ) ; err != nil {
return err
return err
} else if err = t . GetMembers ( ) ; err != nil {
return err
}
}
// Get organization.
org , err := GetUserById ( t . OrgId )
if err != nil {
return err
}
// Update access.
mode := AuthorizeToAccessType ( t . Authorize )
for _ , repo := range t . Repos {
for _ , repo := range t . Repos {
for _ , u := range t . Members {
if err = repo . RecalcAccessSess ( ) ; err != nil {
// ORG_WRITABLE is the highest authorize level for now.
return err
// Skip checking others if current team has this level.
if t . Authorize < ORG_WRITABLE {
auth , err := GetHighestAuthorize ( t . OrgId , u . Id , repo . Id , t . Id )
if err != nil {
sess . Rollback ( )
return err
}
if auth >= t . Authorize {
continue // Other team has higher or same authorize level.
}
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( org . LowerName , repo . LowerName ) ,
}
if err = addAccessWithAuthorize ( sess , access , mode ) ; err != nil {
sess . Rollback ( )
return err
}
}
}
}
}
}
}
@ -812,29 +692,8 @@ func DeleteTeam(t *Team) error {
// Delete all accesses.
// Delete all accesses.
for _ , repo := range t . Repos {
for _ , repo := range t . Repos {
for _ , u := range t . Members {
if err = repo . RecalcAccessSess ( ) ; err != nil {
auth , err := GetHighestAuthorize ( t . OrgId , u . Id , repo . Id , t . Id )
return err
if err != nil {
sess . Rollback ( )
return err
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( org . LowerName , repo . LowerName ) ,
}
if auth == 0 {
if _ , err = sess . Delete ( access ) ; err != nil {
sess . Rollback ( )
return fmt . Errorf ( "fail to delete access: %v" , err )
}
} else if auth < t . Authorize {
// Downgrade authorize level.
if err = addAccessWithAuthorize ( sess , access , AuthorizeToAccessType ( auth ) ) ; err != nil {
sess . Rollback ( )
return err
}
}
}
}
}
}
@ -936,18 +795,6 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return err
return err
}
}
// Get organization.
org , err := GetUserById ( orgId )
if err != nil {
return err
}
// Get user.
u , err := GetUserById ( uid )
if err != nil {
return err
}
sess := x . NewSession ( )
sess := x . NewSession ( )
defer sess . Close ( )
defer sess . Close ( )
if err = sess . Begin ( ) ; err != nil {
if err = sess . Begin ( ) ; err != nil {
@ -969,24 +816,11 @@ func AddTeamMember(orgId, teamId, uid int64) error {
}
}
// Give access to team repositories.
// Give access to team repositories.
mode := AuthorizeToAccessType ( t . Authorize )
for _ , repo := range t . Repos {
for _ , repo := range t . Repos {
auth , err := getHighestAuthorize ( sess , t . OrgId , u . Id , repo . Id , teamId )
if err = repo . RecalcAccessSess ( ) ; err != nil {
if err != nil {
sess . Rollback ( )
sess . Rollback ( )
return err
return err
}
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( org . LowerName , repo . LowerName ) ,
}
if auth < t . Authorize {
if err = addAccessWithAuthorize ( sess , access , mode ) ; err != nil {
sess . Rollback ( )
return err
}
}
}
}
// We make sure it exists before.
// We make sure it exists before.
@ -1036,12 +870,6 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
return err
return err
}
}
// Get user.
u , err := GetUserById ( uid )
if err != nil {
return err
}
tu := & TeamUser {
tu := & TeamUser {
Uid : uid ,
Uid : uid ,
OrgId : orgId ,
OrgId : orgId ,
@ -1056,28 +884,9 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
// Delete access to team repositories.
// Delete access to team repositories.
for _ , repo := range t . Repos {
for _ , repo := range t . Repos {
auth , err := getHighestAuthorize ( e , t . OrgId , u . Id , repo . Id , teamId )
if err = repo . RecalcAccessSess ( ) ; err != nil {
if err != nil {
return err
return err
}
}
access := & Access {
UserName : u . LowerName ,
RepoName : path . Join ( org . LowerName , repo . LowerName ) ,
}
// Delete access if this is the last team user belongs to.
if auth == 0 {
if _ , err = e . Delete ( access ) ; err != nil {
return fmt . Errorf ( "fail to delete access: %v" , err )
} else if err = watchRepo ( e , u . Id , repo . Id , false ) ; err != nil {
return err
}
} else if auth < t . Authorize {
// Downgrade authorize level.
if err = addAccessWithAuthorize ( e , access , AuthorizeToAccessType ( auth ) ) ; err != nil {
return err
}
}
}
}
// This must exist.
// This must exist.