diff options
Diffstat (limited to 'models')
-rw-r--r-- | models/access.go | 21 | ||||
-rw-r--r-- | models/issue_comment.go | 3 | ||||
-rw-r--r-- | models/repo.go | 100 | ||||
-rw-r--r-- | models/repo_collaboration.go | 161 |
4 files changed, 173 insertions, 112 deletions
diff --git a/models/access.go b/models/access.go index 5eef32819e..fe2350606a 100644 --- a/models/access.go +++ b/models/access.go @@ -13,11 +13,11 @@ import ( type AccessMode int const ( - ACCESS_MODE_NONE AccessMode = iota - ACCESS_MODE_READ - ACCESS_MODE_WRITE - ACCESS_MODE_ADMIN - ACCESS_MODE_OWNER + ACCESS_MODE_NONE AccessMode = iota // 0 + ACCESS_MODE_READ // 1 + ACCESS_MODE_WRITE // 2 + ACCESS_MODE_ADMIN // 3 + ACCESS_MODE_OWNER // 4 ) // Access represents the highest access level of a user to the repository. The only access type @@ -151,15 +151,14 @@ func (repo *Repository) refreshAccesses(e Engine, accessMap map[int64]AccessMode return nil } -// FIXME: should be able to have read-only access. -// Give all collaborators write access. +// refreshCollaboratorAccesses retrieves repository collaborations with their access modes. func (repo *Repository) refreshCollaboratorAccesses(e Engine, accessMap map[int64]AccessMode) error { - collaborators, err := repo.getCollaborators(e) + collaborations, err := repo.getCollaborations(e) if err != nil { - return fmt.Errorf("getCollaborators: %v", err) + return fmt.Errorf("getCollaborations: %v", err) } - for _, c := range collaborators { - accessMap[c.Id] = ACCESS_MODE_WRITE + for _, c := range collaborations { + accessMap[c.UserID] = c.Mode } return nil } diff --git a/models/issue_comment.go b/models/issue_comment.go index 9ffad62fe6..e1230d8136 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -121,7 +121,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err return nil, err } - // Compose comment action, could be plain comment, close or reopen issue. + // Compose comment action, could be plain comment, close or reopen issue/pull request. // This object will be used to notify watchers in the end of function. act := &Action{ ActUserID: opts.Doer.Id, @@ -179,6 +179,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err if err != nil { return nil, err } + case COMMENT_TYPE_CLOSE: act.OpType = ACTION_CLOSE_ISSUE if opts.Issue.IsPull { diff --git a/models/repo.go b/models/repo.go index eff66254f0..98b3e0532e 100644 --- a/models/repo.go +++ b/models/repo.go @@ -330,7 +330,6 @@ func (repo *Repository) RepoRelLink() string { return "/" + repo.MustOwner().Name + "/" + repo.Name } - func (repo *Repository) ComposeCompareURL(oldCommitID, newCommitID string) string { return fmt.Sprintf("%s/%s/compare/%s...%s", repo.MustOwner().Name, repo.Name, oldCommitID, newCommitID) } @@ -1797,105 +1796,6 @@ func CheckRepoStats() { // ***** END: Repository.NumForks ***** } -// _________ .__ .__ ___. __ .__ -// \_ ___ \ ____ | | | | _____ \_ |__ ________________ _/ |_|__| ____ ____ -// / \ \/ / _ \| | | | \__ \ | __ \ / _ \_ __ \__ \\ __\ |/ _ \ / \ -// \ \___( <_> ) |_| |__/ __ \| \_\ ( <_> ) | \// __ \| | | ( <_> ) | \ -// \______ /\____/|____/____(____ /___ /\____/|__| (____ /__| |__|\____/|___| / -// \/ \/ \/ \/ \/ - -// A Collaboration is a relation between an individual and a repository -type Collaboration struct { - ID int64 `xorm:"pk autoincr"` - RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - UserID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` - Created time.Time `xorm:"CREATED"` -} - -// Add collaborator and accompanying access -func (repo *Repository) AddCollaborator(u *User) error { - collaboration := &Collaboration{ - RepoID: repo.ID, - UserID: u.Id, - } - - has, err := x.Get(collaboration) - if err != nil { - return err - } else if has { - return nil - } - - if err = repo.GetOwner(); err != nil { - return fmt.Errorf("GetOwner: %v", err) - } - - sess := x.NewSession() - defer sessionRelease(sess) - if err = sess.Begin(); err != nil { - return err - } - - if _, err = sess.InsertOne(collaboration); err != nil { - return err - } - - if repo.Owner.IsOrganization() { - err = repo.recalculateTeamAccesses(sess, 0) - } else { - err = repo.recalculateAccesses(sess) - } - if err != nil { - return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err) - } - - return sess.Commit() -} - -func (repo *Repository) getCollaborators(e Engine) ([]*User, error) { - collaborations := make([]*Collaboration, 0) - if err := e.Find(&collaborations, &Collaboration{RepoID: repo.ID}); err != nil { - return nil, err - } - - users := make([]*User, len(collaborations)) - for i, c := range collaborations { - user, err := getUserByID(e, c.UserID) - if err != nil { - return nil, err - } - users[i] = user - } - return users, nil -} - -// GetCollaborators returns the collaborators for a repository -func (repo *Repository) GetCollaborators() ([]*User, error) { - return repo.getCollaborators(x) -} - -// Delete collaborator and accompanying access -func (repo *Repository) DeleteCollaborator(u *User) (err error) { - collaboration := &Collaboration{ - RepoID: repo.ID, - UserID: u.Id, - } - - sess := x.NewSession() - defer sessionRelease(sess) - 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 - } - - return sess.Commit() -} - // __ __ __ .__ // / \ / \_____ _/ |_ ____ | |__ // \ \/\/ /\__ \\ __\/ ___\| | \ diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go new file mode 100644 index 0000000000..419169f09c --- /dev/null +++ b/models/repo_collaboration.go @@ -0,0 +1,161 @@ +// 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" + "time" +) + +// Collaboration represent the relation between an individual and a repository. +type Collaboration struct { + 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"` + Created time.Time `xorm:"CREATED"` +} + +func (c *Collaboration) ModeName() string { + switch c.Mode { + case ACCESS_MODE_READ: + return "Read" + case ACCESS_MODE_WRITE: + return "Write" + case ACCESS_MODE_ADMIN: + return "Admin" + } + return "Undefined" +} + +// AddCollaborator adds new collaboration relation between an individual and a repository. +func (repo *Repository) AddCollaborator(u *User) error { + collaboration := &Collaboration{ + RepoID: repo.ID, + UserID: u.Id, + } + + has, err := x.Get(collaboration) + if err != nil { + return err + } else if has { + return nil + } + collaboration.Mode = ACCESS_MODE_WRITE + + sess := x.NewSession() + defer sessionRelease(sess) + if err = sess.Begin(); err != nil { + return err + } + + if _, err = sess.InsertOne(collaboration); err != nil { + return err + } + + if repo.Owner.IsOrganization() { + err = repo.recalculateTeamAccesses(sess, 0) + } else { + err = repo.recalculateAccesses(sess) + } + if err != nil { + return fmt.Errorf("recalculateAccesses 'team=%v': %v", repo.Owner.IsOrganization(), err) + } + + return sess.Commit() +} + +func (repo *Repository) getCollaborations(e Engine) ([]*Collaboration, error) { + collaborations := make([]*Collaboration, 0) + 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) +} + +// ChangeCollaborationAccessMode sets new access mode for the collaboration. +func (repo *Repository) ChangeCollaborationAccessMode(uid int64, mode AccessMode) error { + // Discard invalid input + if mode <= ACCESS_MODE_NONE || mode > ACCESS_MODE_OWNER { + return nil + } + + collaboration := &Collaboration{ + RepoID: repo.ID, + UserID: uid, + } + has, err := x.Get(collaboration) + if err != nil { + return fmt.Errorf("get collaboration: %v", err) + } else if !has { + return nil + } + + collaboration.Mode = mode + + sess := x.NewSession() + defer sessionRelease(sess) + if err = sess.Begin(); err != nil { + return err + } + + if _, err = sess.Id(collaboration.ID).AllCols().Update(collaboration); err != nil { + return fmt.Errorf("update collaboration: %v", err) + } else if _, err = sess.Exec("UPDATE access SET mode = ? WHERE user_id = ? AND repo_id = ?", mode, uid, repo.ID); err != nil { + return fmt.Errorf("update access table: %v", err) + } + + 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() + defer sessionRelease(sess) + 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 + } + + return sess.Commit() +} |