mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	
							
								
								
									
										41
									
								
								cmd/serve.go
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								cmd/serve.go
									
									
									
									
									
								
							@@ -8,7 +8,6 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/exec"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
@@ -67,19 +66,19 @@ func parseCmd(cmd string) (string, string) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	COMMANDS_READONLY = map[string]models.AccessType{
 | 
			
		||||
		"git-upload-pack":    models.WRITABLE,
 | 
			
		||||
		"git upload-pack":    models.WRITABLE,
 | 
			
		||||
		"git-upload-archive": models.WRITABLE,
 | 
			
		||||
	COMMANDS_READONLY = map[string]models.AccessMode{
 | 
			
		||||
		"git-upload-pack":    models.ACCESS_MODE_WRITE,
 | 
			
		||||
		"git upload-pack":    models.ACCESS_MODE_WRITE,
 | 
			
		||||
		"git-upload-archive": models.ACCESS_MODE_WRITE,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	COMMANDS_WRITE = map[string]models.AccessType{
 | 
			
		||||
		"git-receive-pack": models.READABLE,
 | 
			
		||||
		"git receive-pack": models.READABLE,
 | 
			
		||||
	COMMANDS_WRITE = map[string]models.AccessMode{
 | 
			
		||||
		"git-receive-pack": models.ACCESS_MODE_READ,
 | 
			
		||||
		"git receive-pack": models.ACCESS_MODE_READ,
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func In(b string, sl map[string]models.AccessType) bool {
 | 
			
		||||
func In(b string, sl map[string]models.AccessMode) bool {
 | 
			
		||||
	_, e := sl[b]
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
@@ -144,17 +143,6 @@ func runServ(k *cli.Context) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Access check.
 | 
			
		||||
	switch {
 | 
			
		||||
	case isWrite:
 | 
			
		||||
		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.WRITABLE)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			println("Gogs: internal error:", err.Error())
 | 
			
		||||
			log.GitLogger.Fatal(2, "Fail to check write access:", err)
 | 
			
		||||
		} else if !has {
 | 
			
		||||
			println("You have no right to write this repository")
 | 
			
		||||
			log.GitLogger.Fatal(2, "User %s has no right to write repository %s", user.Name, repoPath)
 | 
			
		||||
		}
 | 
			
		||||
	case isRead:
 | 
			
		||||
	repo, err := models.GetRepositoryByName(repoUser.Id, repoName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if err == models.ErrRepoNotExist {
 | 
			
		||||
@@ -165,11 +153,22 @@ func runServ(k *cli.Context) {
 | 
			
		||||
		log.GitLogger.Fatal(2, "Fail to get repository: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case isWrite:
 | 
			
		||||
		has, err := models.HasAccess(user, repo, models.ACCESS_MODE_WRITE)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			println("Gogs: internal error:", err.Error())
 | 
			
		||||
			log.GitLogger.Fatal(2, "Fail to check write access:", err)
 | 
			
		||||
		} else if !has {
 | 
			
		||||
			println("You have no right to write this repository")
 | 
			
		||||
			log.GitLogger.Fatal(2, "User %s has no right to write repository %s", user.Name, repoPath)
 | 
			
		||||
		}
 | 
			
		||||
	case isRead:
 | 
			
		||||
		if !repo.IsPrivate {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		has, err := models.HasAccess(user.Name, path.Join(repoUserName, repoName), models.READABLE)
 | 
			
		||||
		has, err := models.HasAccess(user, repo, models.ACCESS_MODE_READ)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			println("Gogs: internal error:", err.Error())
 | 
			
		||||
			log.GitLogger.Fatal(2, "Fail to check read access:", err)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										173
									
								
								models/access.go
									
									
									
									
									
								
							
							
						
						
									
										173
									
								
								models/access.go
									
									
									
									
									
								
							@@ -4,95 +4,76 @@
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type AccessType int
 | 
			
		||||
type AccessMode int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	READABLE AccessType = iota + 1
 | 
			
		||||
	WRITABLE
 | 
			
		||||
	ACCESS_MODE_NONE AccessMode = iota
 | 
			
		||||
	ACCESS_MODE_READ
 | 
			
		||||
	ACCESS_MODE_WRITE
 | 
			
		||||
	ACCESS_MODE_ADMIN
 | 
			
		||||
	ACCESS_MODE_OWNER
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Access represents the accessibility of user to repository.
 | 
			
		||||
func maxAccessMode(modes ...AccessMode) AccessMode {
 | 
			
		||||
	max := ACCESS_MODE_NONE
 | 
			
		||||
	for _, mode := range modes {
 | 
			
		||||
		if mode > max {
 | 
			
		||||
			max = mode
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return max
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Access represents the highest access level of a user to the repository. The only access type
 | 
			
		||||
// that is not in this table is the real owner of a repository. In case of an organization
 | 
			
		||||
// repository, the members of the owners team are in this table.
 | 
			
		||||
type Access struct {
 | 
			
		||||
	Id       int64
 | 
			
		||||
	UserName string     `xorm:"UNIQUE(s)"`
 | 
			
		||||
	RepoName string     `xorm:"UNIQUE(s)"` // <user name>/<repo name>
 | 
			
		||||
	Mode     AccessType `xorm:"UNIQUE(s)"`
 | 
			
		||||
	Created  time.Time  `xorm:"CREATED"`
 | 
			
		||||
	ID     int64 `xorm:"pk autoincr"`
 | 
			
		||||
	UserID int64 `xorm:"UNIQUE(s)"`
 | 
			
		||||
	RepoID int64 `xorm:"UNIQUE(s)"`
 | 
			
		||||
	Mode   AccessMode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func addAccess(e Engine, access *Access) error {
 | 
			
		||||
	access.UserName = strings.ToLower(access.UserName)
 | 
			
		||||
	access.RepoName = strings.ToLower(access.RepoName)
 | 
			
		||||
	_, err := e.Insert(access)
 | 
			
		||||
	return err
 | 
			
		||||
// HasAccess returns true if someone has the request access level. User can be nil!
 | 
			
		||||
func HasAccess(u *User, r *Repository, testMode AccessMode) (bool, error) {
 | 
			
		||||
	mode, err := AccessLevel(u, r)
 | 
			
		||||
	return testMode <= mode, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddAccess adds new access record.
 | 
			
		||||
func AddAccess(access *Access) error {
 | 
			
		||||
	return addAccess(x, access)
 | 
			
		||||
// Return the Access a user has to a repository. Will return NoneAccess if the
 | 
			
		||||
// user does not have access. User can be nil!
 | 
			
		||||
func AccessLevel(u *User, r *Repository) (AccessMode, error) {
 | 
			
		||||
	mode := ACCESS_MODE_NONE
 | 
			
		||||
	if !r.IsPrivate {
 | 
			
		||||
		mode = ACCESS_MODE_READ
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
func updateAccess(e Engine, access *Access) error {
 | 
			
		||||
	if _, err := e.Id(access.Id).Update(access); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
	if u != nil {
 | 
			
		||||
		if u.Id == r.OwnerId {
 | 
			
		||||
			return ACCESS_MODE_OWNER, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
// UpdateAccess updates access information.
 | 
			
		||||
func UpdateAccess(access *Access) error {
 | 
			
		||||
	access.UserName = strings.ToLower(access.UserName)
 | 
			
		||||
	access.RepoName = strings.ToLower(access.RepoName)
 | 
			
		||||
	return updateAccess(x, access)
 | 
			
		||||
		a := &Access{UserID: u.Id, RepoID: r.Id}
 | 
			
		||||
		if has, err := x.Get(a); !has || err != nil {
 | 
			
		||||
			return mode, err
 | 
			
		||||
		}
 | 
			
		||||
		return a.Mode, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
func deleteAccess(e Engine, access *Access) error {
 | 
			
		||||
	_, err := e.Delete(access)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteAccess deletes access record.
 | 
			
		||||
func DeleteAccess(access *Access) error {
 | 
			
		||||
	return deleteAccess(x, access)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasAccess returns true if someone can read or write to given repository.
 | 
			
		||||
// The repoName should be in format <username>/<reponame>.
 | 
			
		||||
func HasAccess(uname, repoName string, mode AccessType) (bool, error) {
 | 
			
		||||
	if len(repoName) == 0 {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	access := &Access{
 | 
			
		||||
		UserName: strings.ToLower(uname),
 | 
			
		||||
		RepoName: strings.ToLower(repoName),
 | 
			
		||||
	}
 | 
			
		||||
	has, err := x.Get(access)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return false, err
 | 
			
		||||
	} else if !has {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	} else if mode > access.Mode {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
	return true, nil
 | 
			
		||||
	return mode, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetAccessibleRepositories finds all repositories where a user has access to,
 | 
			
		||||
// besides his own.
 | 
			
		||||
func (u *User) GetAccessibleRepositories() (map[*Repository]AccessType, error) {
 | 
			
		||||
func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
 | 
			
		||||
	accesses := make([]*Access, 0, 10)
 | 
			
		||||
	if err := x.Find(&accesses, &Access{UserName: u.LowerName}); err != nil {
 | 
			
		||||
	if err := x.Find(&accesses, &Access{UserID: u.Id}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repos := make(map[*Repository]AccessType, len(accesses))
 | 
			
		||||
	repos := make(map[*Repository]AccessMode, len(accesses))
 | 
			
		||||
	for _, access := range accesses {
 | 
			
		||||
		repo, err := GetRepositoryByRef(access.RepoName)
 | 
			
		||||
		repo, err := GetRepositoryById(access.RepoID)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -106,3 +87,65 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessType, error) {
 | 
			
		||||
 | 
			
		||||
	return repos, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Recalculate all accesses for repository
 | 
			
		||||
func (r *Repository) RecalcAccessSess() error {
 | 
			
		||||
	accessMap := make(map[int64]AccessMode, 20)
 | 
			
		||||
 | 
			
		||||
	// Give all collaborators write access
 | 
			
		||||
	collaborators, err := r.GetCollaborators()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for _, c := range collaborators {
 | 
			
		||||
		accessMap[c.Id] = ACCESS_MODE_WRITE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := r.GetOwner(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	if r.Owner.IsOrganization() {
 | 
			
		||||
		if err = r.Owner.GetTeams(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, team := range r.Owner.Teams {
 | 
			
		||||
			if !(team.IsOwnerTeam() || team.HasRepository(r)) {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err = team.GetMembers(); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
			for _, u := range team.Members {
 | 
			
		||||
				accessMap[u.Id] = maxAccessMode(accessMap[u.Id], team.Authorize)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	minMode := ACCESS_MODE_READ
 | 
			
		||||
	if !r.IsPrivate {
 | 
			
		||||
		minMode = ACCESS_MODE_WRITE
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newAccesses := make([]Access, 0, len(accessMap))
 | 
			
		||||
	for userID, mode := range accessMap {
 | 
			
		||||
		if userID == r.OwnerId || mode <= minMode {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		newAccesses = append(newAccesses, Access{UserID: userID, RepoID: r.Id, Mode: mode})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Delete old accesses for repository
 | 
			
		||||
	if _, err = x.Delete(&Access{RepoID: r.Id}); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// And insert the new ones
 | 
			
		||||
	if _, err = x.Insert(newAccesses); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,7 @@ type Version struct {
 | 
			
		||||
// update _MIN_VER_DB accordingly
 | 
			
		||||
var migrations = []Migration{
 | 
			
		||||
	NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1
 | 
			
		||||
	NewMigration("refactor access table to use id's", accessRefactor),         // V1 -> V2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Migrate database to current version
 | 
			
		||||
@@ -208,3 +209,8 @@ func accessToCollaboration(x *xorm.Engine) error {
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func accessRefactor(x *xorm.Engine) error {
 | 
			
		||||
	//TODO
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										235
									
								
								models/org.go
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								models/org.go
									
									
									
									
									
								
							@@ -6,9 +6,7 @@ package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/Unknwon/com"
 | 
			
		||||
@@ -136,7 +134,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
 | 
			
		||||
		OrgId:      org.Id,
 | 
			
		||||
		LowerName:  strings.ToLower(OWNER_TEAM),
 | 
			
		||||
		Name:       OWNER_TEAM,
 | 
			
		||||
		Authorize:  ORG_ADMIN,
 | 
			
		||||
		Authorize:  ACCESS_MODE_OWNER,
 | 
			
		||||
		NumMembers: 1,
 | 
			
		||||
	}
 | 
			
		||||
	if _, err = sess.Insert(t); err != nil {
 | 
			
		||||
@@ -371,10 +369,10 @@ func RemoveOrgUser(orgId, uid int64) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	access := &Access{
 | 
			
		||||
		UserName: u.LowerName,
 | 
			
		||||
		UserID: u.Id,
 | 
			
		||||
	}
 | 
			
		||||
	for _, repo := range org.Repos {
 | 
			
		||||
		access.RepoName = path.Join(org.LowerName, repo.LowerName)
 | 
			
		||||
		access.RepoID = repo.Id
 | 
			
		||||
		if _, err = sess.Delete(access); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			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"
 | 
			
		||||
 | 
			
		||||
// Team represents a organization team.
 | 
			
		||||
@@ -429,7 +412,7 @@ type Team struct {
 | 
			
		||||
	LowerName   string
 | 
			
		||||
	Name        string
 | 
			
		||||
	Description string
 | 
			
		||||
	Authorize   AuthorizeType
 | 
			
		||||
	Authorize   AccessMode
 | 
			
		||||
	RepoIds     string        `xorm:"TEXT"`
 | 
			
		||||
	Repos       []*Repository `xorm:"-"`
 | 
			
		||||
	Members     []*User       `xorm:"-"`
 | 
			
		||||
@@ -484,25 +467,6 @@ func (t *Team) RemoveMember(uid int64) error {
 | 
			
		||||
	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.
 | 
			
		||||
func (t *Team) AddRepository(repo *Repository) (err error) {
 | 
			
		||||
	idStr := "$" + com.ToStr(repo.Id) + "|"
 | 
			
		||||
@@ -531,27 +495,13 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Give access to team members.
 | 
			
		||||
	mode := AuthorizeToAccessType(t.Authorize)
 | 
			
		||||
	if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, u := range t.Members {
 | 
			
		||||
		auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
 | 
			
		||||
		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 {
 | 
			
		||||
		if err = WatchRepo(u.Id, repo.Id, true); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
@@ -559,6 +509,11 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
 | 
			
		||||
	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.
 | 
			
		||||
func (t *Team) RemoveRepository(repoId int64) error {
 | 
			
		||||
	idStr := "$" + com.ToStr(repoId) + "|"
 | 
			
		||||
@@ -590,32 +545,16 @@ func (t *Team) RemoveRepository(repoId int64) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Remove access to team members.
 | 
			
		||||
	for _, u := range t.Members {
 | 
			
		||||
		auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, t.Id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
	if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		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 {
 | 
			
		||||
	for _, u := range t.Members {
 | 
			
		||||
		if err = WatchRepo(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()
 | 
			
		||||
@@ -693,34 +632,6 @@ func GetTeamById(teamId int64) (*Team, error) {
 | 
			
		||||
	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.
 | 
			
		||||
func UpdateTeam(t *Team, authChanged bool) (err error) {
 | 
			
		||||
	if !IsLegalName(t.Name) {
 | 
			
		||||
@@ -738,46 +649,15 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update access for team members if needed.
 | 
			
		||||
	if authChanged && !t.IsOwnerTeam() {
 | 
			
		||||
	if authChanged {
 | 
			
		||||
		if err = t.GetRepositories(); err != nil {
 | 
			
		||||
			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 _, u := range t.Members {
 | 
			
		||||
				// ORG_WRITABLE is the highest authorize level for now.
 | 
			
		||||
				// 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()
 | 
			
		||||
			if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
				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,30 +692,9 @@ func DeleteTeam(t *Team) error {
 | 
			
		||||
 | 
			
		||||
	// Delete all accesses.
 | 
			
		||||
	for _, repo := range t.Repos {
 | 
			
		||||
		for _, u := range t.Members {
 | 
			
		||||
			auth, err := GetHighestAuthorize(t.OrgId, u.Id, repo.Id, t.Id)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				sess.Rollback()
 | 
			
		||||
		if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
			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
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Delete team-user.
 | 
			
		||||
@@ -936,18 +795,6 @@ func AddTeamMember(orgId, teamId, uid int64) error {
 | 
			
		||||
		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()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	if err = sess.Begin(); err != nil {
 | 
			
		||||
@@ -969,24 +816,11 @@ func AddTeamMember(orgId, teamId, uid int64) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Give access to team repositories.
 | 
			
		||||
	mode := AuthorizeToAccessType(t.Authorize)
 | 
			
		||||
	for _, repo := range t.Repos {
 | 
			
		||||
		auth, err := getHighestAuthorize(sess, t.OrgId, u.Id, repo.Id, teamId)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
		if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			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.
 | 
			
		||||
@@ -1036,12 +870,6 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Get user.
 | 
			
		||||
	u, err := GetUserById(uid)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tu := &TeamUser{
 | 
			
		||||
		Uid:    uid,
 | 
			
		||||
		OrgId:  orgId,
 | 
			
		||||
@@ -1056,28 +884,9 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
 | 
			
		||||
 | 
			
		||||
	// Delete access to team repositories.
 | 
			
		||||
	for _, repo := range t.Repos {
 | 
			
		||||
		auth, err := getHighestAuthorize(e, t.OrgId, u.Id, repo.Id, teamId)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
		if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
			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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										253
									
								
								models/repo.go
									
									
									
									
									
								
							
							
						
						
									
										253
									
								
								models/repo.go
									
									
									
									
									
								
							@@ -206,14 +206,6 @@ func (repo *Repository) IsOwnedBy(u *User) bool {
 | 
			
		||||
	return repo.OwnerId == u.Id
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (repo *Repository) HasAccess(uname string) bool {
 | 
			
		||||
	if err := repo.GetOwner(); err != nil {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	has, _ := HasAccess(uname, path.Join(repo.Owner.Name, repo.Name), READABLE)
 | 
			
		||||
	return has
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DescriptionHtml does special handles to description and return HTML string.
 | 
			
		||||
func (repo *Repository) DescriptionHtml() template.HTML {
 | 
			
		||||
	sanitize := func(s string) string {
 | 
			
		||||
@@ -548,36 +540,11 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
 | 
			
		||||
 | 
			
		||||
	var t *Team // Owner team.
 | 
			
		||||
 | 
			
		||||
	mode := WRITABLE
 | 
			
		||||
	if mirror {
 | 
			
		||||
		mode = READABLE
 | 
			
		||||
	}
 | 
			
		||||
	access := &Access{
 | 
			
		||||
		UserName: u.LowerName,
 | 
			
		||||
		RepoName: path.Join(u.LowerName, repo.LowerName),
 | 
			
		||||
		Mode:     mode,
 | 
			
		||||
	}
 | 
			
		||||
	// TODO fix code for mirrors?
 | 
			
		||||
 | 
			
		||||
	// Give access to all members in owner team.
 | 
			
		||||
	if u.IsOrganization() {
 | 
			
		||||
		t, err = u.GetOwnerTeam()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if err = t.GetMembers(); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		for _, u := range t.Members {
 | 
			
		||||
			access.Id = 0
 | 
			
		||||
			access.UserName = u.LowerName
 | 
			
		||||
			if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
				sess.Rollback()
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
		if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -707,37 +674,10 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	owner := repo.Owner
 | 
			
		||||
	oldRepoLink := path.Join(owner.LowerName, repo.LowerName)
 | 
			
		||||
	// Delete all access first if current owner is an organization.
 | 
			
		||||
	if owner.IsOrganization() {
 | 
			
		||||
		if _, err = sess.Where("repo_name=?", oldRepoLink).Delete(new(Access)); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return fmt.Errorf("fail to delete current accesses: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// Delete current owner access.
 | 
			
		||||
		if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", owner.LowerName).
 | 
			
		||||
			Delete(new(Access)); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return fmt.Errorf("fail to delete access(owner): %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		// In case new owner has access.
 | 
			
		||||
		if _, err = sess.Where("repo_name=?", oldRepoLink).And("user_name=?", newUser.LowerName).
 | 
			
		||||
			Delete(new(Access)); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return fmt.Errorf("fail to delete access(new user): %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Change accesses to new repository path.
 | 
			
		||||
	if _, err = sess.Where("repo_name=?", oldRepoLink).
 | 
			
		||||
		Update(&Access{RepoName: path.Join(newUser.LowerName, repo.LowerName)}); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return fmt.Errorf("fail to update access(change reponame): %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update repository.
 | 
			
		||||
	repo.OwnerId = newUser.Id
 | 
			
		||||
	repo.Owner = newUser
 | 
			
		||||
	if _, err := sess.Id(repo.Id).Update(repo); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
@@ -754,54 +694,9 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mode := WRITABLE
 | 
			
		||||
	if repo.IsMirror {
 | 
			
		||||
		mode = READABLE
 | 
			
		||||
	}
 | 
			
		||||
	// New owner is organization.
 | 
			
		||||
	if newUser.IsOrganization() {
 | 
			
		||||
		access := &Access{
 | 
			
		||||
			RepoName: path.Join(newUser.LowerName, repo.LowerName),
 | 
			
		||||
			Mode:     mode,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Give access to all members in owner team.
 | 
			
		||||
		t, err := newUser.GetOwnerTeam()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
	if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
		if err = t.GetMembers(); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		for _, u := range t.Members {
 | 
			
		||||
			access.Id = 0
 | 
			
		||||
			access.UserName = u.LowerName
 | 
			
		||||
			if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
				sess.Rollback()
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Update owner team info and count.
 | 
			
		||||
		t.RepoIds += "$" + com.ToStr(repo.Id) + "|"
 | 
			
		||||
		t.NumRepos++
 | 
			
		||||
		if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		access := &Access{
 | 
			
		||||
			RepoName: path.Join(newUser.LowerName, repo.LowerName),
 | 
			
		||||
			UserName: newUser.LowerName,
 | 
			
		||||
			Mode:     mode,
 | 
			
		||||
		}
 | 
			
		||||
		if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return fmt.Errorf("fail to insert access: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Change repository directory name.
 | 
			
		||||
	if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
 | 
			
		||||
@@ -833,33 +728,8 @@ func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error)
 | 
			
		||||
		return ErrRepoNameIllegal
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update accesses.
 | 
			
		||||
	accesses := make([]Access, 0, 10)
 | 
			
		||||
	if err = x.Find(&accesses, &Access{RepoName: userName + "/" + oldRepoName}); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := x.NewSession()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	if err = sess.Begin(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := range accesses {
 | 
			
		||||
		accesses[i].RepoName = userName + "/" + newRepoName
 | 
			
		||||
		if err = updateAccess(sess, &accesses[i]); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Change repository directory name.
 | 
			
		||||
	if err = os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
	return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func UpdateRepository(repo *Repository) error {
 | 
			
		||||
@@ -908,7 +778,7 @@ func DeleteRepository(uid, repoId int64, userName string) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Delete all access.
 | 
			
		||||
	if _, err := sess.Delete(&Access{RepoName: strings.ToLower(path.Join(userName, repo.Name))}); err != nil {
 | 
			
		||||
	if _, err := sess.Delete(&Access{RepoID: repo.Id}); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
@@ -1228,41 +1098,30 @@ type Collaboration struct {
 | 
			
		||||
// Add collaborator and accompanying access
 | 
			
		||||
func (r *Repository) AddCollaborator(u *User) error {
 | 
			
		||||
	collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
 | 
			
		||||
 | 
			
		||||
	has, err := x.Get(collaboration)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	} else if has {
 | 
			
		||||
	}
 | 
			
		||||
	if has {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err = x.InsertOne(collaboration); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = r.GetOwner(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := x.NewSession()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	if err = sess.Begin(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err = sess.InsertOne(collaboration); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	} else if err = addAccess(sess, &Access{
 | 
			
		||||
		UserName: u.LowerName,
 | 
			
		||||
		RepoName: path.Join(r.Owner.LowerName, r.LowerName),
 | 
			
		||||
		Mode:     WRITABLE}); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
	return r.RecalcAccessSess()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetCollaborators returns the collaborators for a repository
 | 
			
		||||
func (r *Repository) GetCollaborators() ([]*User, error) {
 | 
			
		||||
	collaborations := make([]*Collaboration, 0, 5)
 | 
			
		||||
	if err := x.Where("repo_id=?", r.Id).Find(&collaborations); err != nil {
 | 
			
		||||
	collaborations := make([]*Collaboration, 0)
 | 
			
		||||
	if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1278,50 +1137,14 @@ func (r *Repository) GetCollaborators() ([]*User, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete collaborator and accompanying access
 | 
			
		||||
func (r *Repository) DeleteCollaborator(u *User) (err error) {
 | 
			
		||||
func (r *Repository) DeleteCollaborator(u *User) error {
 | 
			
		||||
	collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id}
 | 
			
		||||
	has, err := x.Get(collaboration)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	} else if !has {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = r.GetOwner(); err != nil {
 | 
			
		||||
	if has, err := x.Delete(collaboration); err != nil || has == 0 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := x.NewSession()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	if err = sess.Begin(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	needDelete := true
 | 
			
		||||
	if r.Owner.IsOrganization() {
 | 
			
		||||
		auth, err := getHighestAuthorize(sess, r.Owner.Id, u.Id, r.Id, 0)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		if auth > 0 {
 | 
			
		||||
			needDelete = false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if needDelete {
 | 
			
		||||
		if err = deleteAccess(sess, &Access{
 | 
			
		||||
			UserName: u.LowerName,
 | 
			
		||||
			RepoName: path.Join(r.Owner.LowerName, r.LowerName),
 | 
			
		||||
			Mode:     WRITABLE}); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		} else if _, err = sess.Delete(collaboration); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
	return r.RecalcAccessSess()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//  __      __         __         .__
 | 
			
		||||
@@ -1495,41 +1318,11 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = repo.RecalcAccessSess(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	var t *Team // Owner team.
 | 
			
		||||
 | 
			
		||||
	mode := WRITABLE
 | 
			
		||||
 | 
			
		||||
	access := &Access{
 | 
			
		||||
		UserName: u.LowerName,
 | 
			
		||||
		RepoName: path.Join(u.LowerName, repo.LowerName),
 | 
			
		||||
		Mode:     mode,
 | 
			
		||||
	}
 | 
			
		||||
	// Give access to all members in owner team.
 | 
			
		||||
	if u.IsOrganization() {
 | 
			
		||||
		t, err = u.GetOwnerTeam()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		if err = t.GetMembers(); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
		for _, u := range t.Members {
 | 
			
		||||
			access.Id = 0
 | 
			
		||||
			access.UserName = u.LowerName
 | 
			
		||||
			if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
				sess.Rollback()
 | 
			
		||||
				return nil, err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if _, err = sess.Insert(access); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if _, err = sess.Exec(
 | 
			
		||||
		"UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
 
 | 
			
		||||
@@ -396,61 +396,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
 | 
			
		||||
		return ErrUserNameIllegal
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newUserName = strings.ToLower(newUserName)
 | 
			
		||||
 | 
			
		||||
	// Update accesses of user.
 | 
			
		||||
	accesses := make([]Access, 0, 10)
 | 
			
		||||
	if err = x.Find(&accesses, &Access{UserName: u.LowerName}); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sess := x.NewSession()
 | 
			
		||||
	defer sess.Close()
 | 
			
		||||
	if err = sess.Begin(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := range accesses {
 | 
			
		||||
		accesses[i].UserName = newUserName
 | 
			
		||||
		if strings.HasPrefix(accesses[i].RepoName, u.LowerName+"/") {
 | 
			
		||||
			accesses[i].RepoName = strings.Replace(accesses[i].RepoName, u.LowerName, newUserName, 1)
 | 
			
		||||
		}
 | 
			
		||||
		if err = updateAccess(sess, &accesses[i]); err != nil {
 | 
			
		||||
			sess.Rollback()
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repos, err := GetRepositories(u.Id, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	for i := range repos {
 | 
			
		||||
		accesses = make([]Access, 0, 10)
 | 
			
		||||
		// Update accesses of user repository.
 | 
			
		||||
		if err = x.Find(&accesses, &Access{RepoName: u.LowerName + "/" + repos[i].LowerName}); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for j := range accesses {
 | 
			
		||||
			// if the access is not the user's access (already updated above)
 | 
			
		||||
			if accesses[j].UserName != u.LowerName {
 | 
			
		||||
				accesses[j].RepoName = newUserName + "/" + repos[i].LowerName
 | 
			
		||||
				if err = updateAccess(sess, &accesses[j]); err != nil {
 | 
			
		||||
					sess.Rollback()
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Change user directory name.
 | 
			
		||||
	if err = os.Rename(UserPath(u.LowerName), UserPath(newUserName)); err != nil {
 | 
			
		||||
		sess.Rollback()
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sess.Commit()
 | 
			
		||||
	return os.Rename(UserPath(u.LowerName), UserPath(newUserName))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// UpdateUser updates user's information.
 | 
			
		||||
@@ -523,7 +469,7 @@ func DeleteUser(u *User) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// Delete all accesses.
 | 
			
		||||
	if _, err = x.Delete(&Access{UserName: u.LowerName}); err != nil {
 | 
			
		||||
	if _, err = x.Delete(&Access{UserID: u.Id}); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// Delete all alternative email addresses
 | 
			
		||||
 
 | 
			
		||||
@@ -87,7 +87,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Data["Team"] = ctx.Org.Team
 | 
			
		||||
			ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize == models.ORG_ADMIN
 | 
			
		||||
			ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.ACCESS_MODE_ADMIN
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
			
		||||
		if requireAdminTeam && !ctx.Org.IsAdminTeam {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
package middleware
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strings"
 | 
			
		||||
@@ -29,17 +28,10 @@ func ApiRepoAssignment() macaron.Handler {
 | 
			
		||||
			err error
 | 
			
		||||
		)
 | 
			
		||||
 | 
			
		||||
		// Collaborators who have write access can be seen as owners.
 | 
			
		||||
		if ctx.IsSigned {
 | 
			
		||||
			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"HasAccess: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Repo.IsTrueOwner = ctx.User.LowerName == strings.ToLower(userName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !ctx.Repo.IsTrueOwner {
 | 
			
		||||
		// Check if the user is the same as the repository owner
 | 
			
		||||
		if ctx.IsSigned && u.LowerName == strings.ToLower(userName) {
 | 
			
		||||
			u = ctx.User
 | 
			
		||||
		} else {
 | 
			
		||||
			u, err = models.GetUserByName(userName)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				if err == models.ErrUserNotExist {
 | 
			
		||||
@@ -49,65 +41,40 @@ func ApiRepoAssignment() macaron.Handler {
 | 
			
		||||
				}
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			u = ctx.User
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Repo.Owner = u
 | 
			
		||||
 | 
			
		||||
		// Organization owner team members are true owners as well.
 | 
			
		||||
		if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
			
		||||
			ctx.Repo.IsTrueOwner = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get repository.
 | 
			
		||||
		repo, err := models.GetRepositoryByName(u.Id, repoName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err == models.ErrRepoNotExist {
 | 
			
		||||
				ctx.Error(404)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL})
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		} else if err = repo.GetOwner(); err != nil {
 | 
			
		||||
			ctx.JSON(500, &base.ApiJsonErr{"GetOwner: " + err.Error(), base.DOC_URL})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if the mirror repository owner(mirror repository doesn't have access).
 | 
			
		||||
		if ctx.IsSigned && !ctx.Repo.IsOwner {
 | 
			
		||||
			if repo.OwnerId == ctx.User.Id {
 | 
			
		||||
				ctx.Repo.IsOwner = true
 | 
			
		||||
			}
 | 
			
		||||
			// Check if current user has admin permission to repository.
 | 
			
		||||
			if u.IsOrganization() {
 | 
			
		||||
				auth, err := models.GetHighestAuthorize(u.Id, ctx.User.Id, repo.Id, 0)
 | 
			
		||||
		if ctx.IsSigned {
 | 
			
		||||
			mode, err := models.AccessLevel(ctx.User, repo)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
					ctx.JSON(500, &base.ApiJsonErr{"GetHighestAuthorize: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
				if auth == models.ORG_ADMIN {
 | 
			
		||||
					ctx.Repo.IsOwner = true
 | 
			
		||||
					ctx.Repo.IsAdmin = true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
			
		||||
			ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
			
		||||
			ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check access.
 | 
			
		||||
		if repo.IsPrivate && !ctx.Repo.IsOwner {
 | 
			
		||||
			if ctx.User == nil {
 | 
			
		||||
			ctx.Error(404)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"HasAccess: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				return
 | 
			
		||||
			} else if !hasAccess {
 | 
			
		||||
				ctx.Error(404)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Repo.HasAccess = true
 | 
			
		||||
 | 
			
		||||
		ctx.Repo.Repository = repo
 | 
			
		||||
@@ -242,101 +209,54 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
			
		||||
			refName = ctx.Params(":path")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Collaborators who have write access can be seen as owners.
 | 
			
		||||
		if ctx.IsSigned {
 | 
			
		||||
			ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.Handle(500, "HasAccess", err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Repo.IsTrueOwner = ctx.User.LowerName == strings.ToLower(userName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !ctx.Repo.IsTrueOwner {
 | 
			
		||||
		// Check if the user is the same as the repository owner
 | 
			
		||||
		if ctx.IsSigned && u.LowerName == strings.ToLower(userName) {
 | 
			
		||||
			u = ctx.User
 | 
			
		||||
		} else {
 | 
			
		||||
			u, err = models.GetUserByName(userName)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				if err == models.ErrUserNotExist {
 | 
			
		||||
					ctx.Handle(404, "GetUserByName", err)
 | 
			
		||||
				} else if redirect {
 | 
			
		||||
					log.Error(4, "GetUserByName", err)
 | 
			
		||||
					ctx.Redirect(setting.AppSubUrl + "/")
 | 
			
		||||
					ctx.Error(404)
 | 
			
		||||
				} else {
 | 
			
		||||
					ctx.Handle(500, "GetUserByName", err)
 | 
			
		||||
					ctx.JSON(500, &base.ApiJsonErr{"GetUserByName: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				}
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			u = ctx.User
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if u == nil {
 | 
			
		||||
			if redirect {
 | 
			
		||||
				ctx.Redirect(setting.AppSubUrl + "/")
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Handle(404, "RepoAssignment", errors.New("invliad user account for single repository"))
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Repo.Owner = u
 | 
			
		||||
 | 
			
		||||
		// Organization owner team members are true owners as well.
 | 
			
		||||
		if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
			
		||||
			ctx.Repo.IsTrueOwner = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get repository.
 | 
			
		||||
		repo, err := models.GetRepositoryByName(u.Id, repoName)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			if err == models.ErrRepoNotExist {
 | 
			
		||||
				ctx.Handle(404, "GetRepositoryByName", err)
 | 
			
		||||
				return
 | 
			
		||||
			} else if redirect {
 | 
			
		||||
				ctx.Redirect(setting.AppSubUrl + "/")
 | 
			
		||||
				return
 | 
			
		||||
				ctx.Error(404)
 | 
			
		||||
			} else {
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL})
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Handle(500, "GetRepositoryByName", err)
 | 
			
		||||
			return
 | 
			
		||||
		} else if err = repo.GetOwner(); err != nil {
 | 
			
		||||
			ctx.Handle(500, "GetOwner", err)
 | 
			
		||||
			ctx.JSON(500, &base.ApiJsonErr{"GetOwner: " + err.Error(), base.DOC_URL})
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if the mirror repository owner(mirror repository doesn't have access).
 | 
			
		||||
		if ctx.IsSigned && !ctx.Repo.IsOwner {
 | 
			
		||||
			if repo.OwnerId == ctx.User.Id {
 | 
			
		||||
				ctx.Repo.IsOwner = true
 | 
			
		||||
			}
 | 
			
		||||
			// Check if current user has admin permission to repository.
 | 
			
		||||
			if u.IsOrganization() {
 | 
			
		||||
				auth, err := models.GetHighestAuthorize(u.Id, ctx.User.Id, repo.Id, 0)
 | 
			
		||||
		if ctx.IsSigned {
 | 
			
		||||
			mode, err := models.AccessLevel(ctx.User, repo)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
					ctx.Handle(500, "GetHighestAuthorize", err)
 | 
			
		||||
				ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
				if auth == models.ORG_ADMIN {
 | 
			
		||||
					ctx.Repo.IsOwner = true
 | 
			
		||||
					ctx.Repo.IsAdmin = true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
			
		||||
			ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
			
		||||
			ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check access.
 | 
			
		||||
		if repo.IsPrivate && !ctx.Repo.IsOwner {
 | 
			
		||||
			if ctx.User == nil {
 | 
			
		||||
				ctx.Handle(404, "HasAccess", nil)
 | 
			
		||||
			ctx.Error(404)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.Handle(500, "HasAccess", err)
 | 
			
		||||
				return
 | 
			
		||||
			} else if !hasAccess {
 | 
			
		||||
				ctx.Handle(404, "HasAccess", nil)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ctx.Repo.HasAccess = true
 | 
			
		||||
 | 
			
		||||
		ctx.Data["HasAccess"] = true
 | 
			
		||||
 | 
			
		||||
		if repo.IsMirror {
 | 
			
		||||
 
 | 
			
		||||
@@ -255,7 +255,7 @@ func ListMyRepos(ctx *middleware.Context) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		repos[i] = ToApiRepository(repo.Owner, repo, api.Permission{false, access >= models.WRITABLE, true})
 | 
			
		||||
		repos[i] = ToApiRepository(repo.Owner, repo, api.Permission{false, access >= models.ACCESS_MODE_WRITE, true})
 | 
			
		||||
 | 
			
		||||
		// FIXME: cache result to reduce DB query?
 | 
			
		||||
		if repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
			
		||||
 
 | 
			
		||||
@@ -165,14 +165,14 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Validate permission level.
 | 
			
		||||
	var auth models.AuthorizeType
 | 
			
		||||
	var auth models.AccessMode
 | 
			
		||||
	switch form.Permission {
 | 
			
		||||
	case "read":
 | 
			
		||||
		auth = models.ORG_READABLE
 | 
			
		||||
		auth = models.ACCESS_MODE_READ
 | 
			
		||||
	case "write":
 | 
			
		||||
		auth = models.ORG_WRITABLE
 | 
			
		||||
		auth = models.ACCESS_MODE_WRITE
 | 
			
		||||
	case "admin":
 | 
			
		||||
		auth = models.ORG_ADMIN
 | 
			
		||||
		auth = models.ACCESS_MODE_ADMIN
 | 
			
		||||
	default:
 | 
			
		||||
		ctx.Error(401)
 | 
			
		||||
		return
 | 
			
		||||
@@ -246,14 +246,14 @@ func EditTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
			
		||||
	isAuthChanged := false
 | 
			
		||||
	if !t.IsOwnerTeam() {
 | 
			
		||||
		// Validate permission level.
 | 
			
		||||
		var auth models.AuthorizeType
 | 
			
		||||
		var auth models.AccessMode
 | 
			
		||||
		switch form.Permission {
 | 
			
		||||
		case "read":
 | 
			
		||||
			auth = models.ORG_READABLE
 | 
			
		||||
			auth = models.ACCESS_MODE_READ
 | 
			
		||||
		case "write":
 | 
			
		||||
			auth = models.ORG_WRITABLE
 | 
			
		||||
			auth = models.ACCESS_MODE_WRITE
 | 
			
		||||
		case "admin":
 | 
			
		||||
			auth = models.ORG_ADMIN
 | 
			
		||||
			auth = models.ACCESS_MODE_ADMIN
 | 
			
		||||
		default:
 | 
			
		||||
			ctx.Error(401)
 | 
			
		||||
			return
 | 
			
		||||
 
 | 
			
		||||
@@ -137,18 +137,18 @@ func Http(ctx *middleware.Context) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !isPublicPull {
 | 
			
		||||
			var tp = models.WRITABLE
 | 
			
		||||
			var tp = models.ACCESS_MODE_WRITE
 | 
			
		||||
			if isPull {
 | 
			
		||||
				tp = models.READABLE
 | 
			
		||||
				tp = models.ACCESS_MODE_READ
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			has, err := models.HasAccess(authUsername, username+"/"+reponame, tp)
 | 
			
		||||
			has, err := models.HasAccess(authUser, repo, tp)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
			
		||||
				return
 | 
			
		||||
			} else if !has {
 | 
			
		||||
				if tp == models.READABLE {
 | 
			
		||||
					has, err = models.HasAccess(authUsername, username+"/"+reponame, models.WRITABLE)
 | 
			
		||||
				if tp == models.ACCESS_MODE_READ {
 | 
			
		||||
					has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE)
 | 
			
		||||
					if err != nil || !has {
 | 
			
		||||
						ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
			
		||||
						return
 | 
			
		||||
@@ -288,7 +288,7 @@ func serviceRpc(rpc string, hr handler) {
 | 
			
		||||
 | 
			
		||||
	access := hasAccess(r, hr.Config, dir, rpc, true)
 | 
			
		||||
	if access == false {
 | 
			
		||||
		renderNoAccess(w)
 | 
			
		||||
		renderACCESS_MODE_NONE(w)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -515,7 +515,7 @@ func renderNotFound(w http.ResponseWriter) {
 | 
			
		||||
	w.Write([]byte("Not Found"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func renderNoAccess(w http.ResponseWriter) {
 | 
			
		||||
func renderACCESS_MODE_NONE(w http.ResponseWriter) {
 | 
			
		||||
	w.WriteHeader(http.StatusForbidden)
 | 
			
		||||
	w.Write([]byte("Forbidden"))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -103,8 +103,7 @@ func Dashboard(ctx *middleware.Context) {
 | 
			
		||||
	feeds := make([]*models.Action, 0, len(actions))
 | 
			
		||||
	for _, act := range actions {
 | 
			
		||||
		if act.IsPrivate {
 | 
			
		||||
			if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
 | 
			
		||||
				models.READABLE); !has {
 | 
			
		||||
			if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true}, models.ACCESS_MODE_READ); !has {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -211,8 +210,8 @@ func Profile(ctx *middleware.Context) {
 | 
			
		||||
				if !ctx.IsSigned {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				if has, _ := models.HasAccess(ctx.User.Name, act.RepoUserName+"/"+act.RepoName,
 | 
			
		||||
					models.READABLE); !has {
 | 
			
		||||
				if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true},
 | 
			
		||||
					models.ACCESS_MODE_READ); !has {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user