diff options
Diffstat (limited to 'internal/db/perms.go')
-rw-r--r-- | internal/db/perms.go | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/internal/db/perms.go b/internal/db/perms.go index 6dc5d423..b0db295e 100644 --- a/internal/db/perms.go +++ b/internal/db/perms.go @@ -5,6 +5,8 @@ package db import ( + "strings" + "github.com/jinzhu/gorm" log "unknwon.dev/clog/v2" ) @@ -15,25 +17,32 @@ import ( type PermsStore interface { // AccessMode returns the access mode of given user has to the repository. AccessMode(userID int64, repo *Repository) AccessMode - // Authorize returns true if the user has as good as desired access mode to - // the repository. + // Authorize returns true if the user has as good as desired access mode to the repository. Authorize(userID int64, repo *Repository, desired AccessMode) bool + // SetRepoPerms does a full update to which users have which level of access to given repository. + // Keys of the "accessMap" are user IDs. + SetRepoPerms(repoID int64, accessMap map[int64]AccessMode) error } var Perms PermsStore +var _ PermsStore = (*perms)(nil) + type perms struct { *gorm.DB } -func (db *perms) AccessMode(userID int64, repo *Repository) AccessMode { - var mode AccessMode +func (db *perms) AccessMode(userID int64, repo *Repository) (mode AccessMode) { + if repo == nil { + return AccessModeNone + } + // Everyone has read access to public repository. if !repo.IsPrivate { mode = AccessModeRead } - // Quick check to avoid a DB query. + // Anonymous user gets the default access. if userID <= 0 { return mode } @@ -45,7 +54,9 @@ func (db *perms) AccessMode(userID int64, repo *Repository) AccessMode { access := new(Access) err := db.Where("user_id = ? AND repo_id = ?", userID, repo.ID).First(access).Error if err != nil { - log.Error("Failed to get access [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) + if !gorm.IsRecordNotFoundError(err){ + log.Error("Failed to get access [user_id: %d, repo_id: %d]: %v", userID, repo.ID, err) + } return mode } return access.Mode @@ -54,3 +65,22 @@ func (db *perms) AccessMode(userID int64, repo *Repository) AccessMode { func (db *perms) Authorize(userID int64, repo *Repository, desired AccessMode) bool { return desired <= db.AccessMode(userID, repo) } + +func (db *perms) SetRepoPerms(repoID int64, accessMap map[int64]AccessMode) error { + vals := make([]string, 0, len(accessMap)) + items := make([]interface{}, 0, len(accessMap)*3) + for userID, mode := range accessMap { + vals = append(vals, "(?, ?, ?)") + items = append(items, userID, repoID, mode) + } + + return db.Transaction(func(tx *gorm.DB) error { + err := tx.Where("repo_id = ?", repoID).Delete(new(Access)).Error + if err != nil { + return err + } + + sql := "INSERT INTO access (user_id, repo_id, mode) VALUES " + strings.Join(vals, ", ") + return tx.Exec(sql, items...).Error + }) +} |