Finsih add/remove repo in organization

This commit is contained in:
Unknwon 2014-08-26 18:11:15 +08:00
parent f2c263c54f
commit 74b31566cf
19 changed files with 485 additions and 107 deletions

View file

@ -21,10 +21,10 @@ const (
// Access represents the accessibility of user to repository.
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"`
UserName string `xorm:"UNIQUE(s)"`
RepoName string `xorm:"UNIQUE(s)"` // <user name>/<repo name>
Mode AccessType `xorm:"UNIQUE(s)"`
Created time.Time `xorm:"CREATED"`
}
// AddAccess adds new access record.

View file

@ -369,6 +369,13 @@ const (
ORG_ADMIN
)
func AuthorizeToAccessType(auth AuthorizeType) AccessType {
if auth == ORG_READABLE {
return READABLE
}
return WRITABLE
}
const OWNER_TEAM = "Owners"
// Team represents a organization team.
@ -433,6 +440,142 @@ func (t *Team) RemoveMember(uid int64) error {
return RemoveTeamMember(t.OrgId, t.Id, uid)
}
// addAccessWithAuthorize inserts or updates access with given mode.
func addAccessWithAuthorize(sess *xorm.Session, access *Access, mode AccessType) error {
has, err := x.Get(access)
if err != nil {
return fmt.Errorf("fail to get access: %v", err)
}
access.Mode = mode
if has {
if _, err = sess.Id(access.Id).Update(access); err != nil {
return fmt.Errorf("fail to update access: %v", err)
}
} else {
if _, err = sess.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) + "|"
if repo.OwnerId != t.OrgId {
return errors.New("Repository not belong to organization")
} else if strings.Contains(t.RepoIds, idStr) {
return nil
}
if err = repo.GetOwner(); err != nil {
return err
} else if err = t.GetMembers(); err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
t.NumRepos++
t.RepoIds += idStr
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return err
}
// Give access to team members.
mode := AuthorizeToAccessType(t.Authorize)
for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, t.Id, repo.Id)
if err != nil {
sess.Rollback()
return err
}
access := &Access{
UserName: u.LowerName,
RepoName: path.Join(repo.Owner.LowerName, repo.LowerName),
}
if auth == 0 {
access.Mode = mode
if _, err = sess.Insert(access); err != nil {
sess.Rollback()
return fmt.Errorf("fail to insert access: %v", err)
}
} else if auth < t.Authorize {
if err = addAccessWithAuthorize(sess, access, mode); err != nil {
sess.Rollback()
return err
}
}
}
return sess.Commit()
}
// RemoveRepository removes repository from team of organization.
func (t *Team) RemoveRepository(repoId int64) error {
idStr := "$" + com.ToStr(repoId) + "|"
if !strings.Contains(t.RepoIds, idStr) {
return nil
}
repo, err := GetRepositoryById(repoId)
if err != nil {
return err
}
if err = repo.GetOwner(); err != nil {
return err
} else if err = t.GetMembers(); err != nil {
return err
}
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return err
}
t.NumRepos--
t.RepoIds = strings.Replace(t.RepoIds, idStr, "", 1)
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return err
}
// Remove access to team members.
for _, u := range t.Members {
auth, err := GetHighestAuthorize(t.OrgId, u.Id, t.Id, repo.Id)
if 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 auth < t.Authorize {
if err = addAccessWithAuthorize(sess, access, AuthorizeToAccessType(auth)); err != nil {
sess.Rollback()
return err
}
}
}
return sess.Commit()
}
// NewTeam creates a record of new team.
// It's caller's responsibility to assign organization ID.
func NewTeam(t *Team) error {
@ -554,16 +697,10 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
return err
}
mode := READABLE
if t.Authorize > ORG_READABLE {
mode = WRITABLE
}
access := &Access{
Mode: mode,
}
// Update access.
mode := AuthorizeToAccessType(t.Authorize)
for _, repo := range t.Repos {
access.RepoName = path.Join(org.LowerName, repo.LowerName)
for _, u := range t.Members {
// ORG_WRITABLE is the highest authorize level for now.
// Skip checking others if current team has this level.
@ -578,8 +715,11 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
}
}
access.UserName = u.LowerName
if _, err = sess.Update(access); err != nil {
access := &Access{
UserName: u.LowerName,
RepoName: path.Join(org.LowerName, repo.LowerName),
}
if err = addAccessWithAuthorize(sess, access, mode); err != nil {
sess.Rollback()
return err
}
@ -617,36 +757,26 @@ func DeleteTeam(t *Team) error {
}
// Delete all accesses.
mode := READABLE
if t.Authorize > ORG_READABLE {
mode = WRITABLE
}
access := new(Access)
for _, repo := range t.Repos {
access.RepoName = path.Join(org.LowerName, repo.LowerName)
for _, u := range t.Members {
access.UserName = u.LowerName
access.Mode = mode
auth, err := GetHighestAuthorize(org.Id, u.Id, t.Id, repo.Id)
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 err
return fmt.Errorf("fail to delete access: %v", err)
}
} else if auth < t.Authorize {
// Downgrade authorize level.
mode := READABLE
if auth > ORG_READABLE {
mode = WRITABLE
}
access.Mode = mode
if _, err = sess.Update(access); err != nil {
if err = addAccessWithAuthorize(sess, access, AuthorizeToAccessType(auth)); err != nil {
sess.Rollback()
return err
}
@ -779,15 +909,6 @@ func AddTeamMember(orgId, teamId, uid int64) error {
TeamId: teamId,
}
mode := READABLE
if t.Authorize > ORG_READABLE {
mode = WRITABLE
}
access := &Access{
UserName: u.LowerName,
Mode: mode,
}
if _, err = sess.Insert(tu); err != nil {
sess.Rollback()
return err
@ -797,6 +918,7 @@ func AddTeamMember(orgId, teamId, uid int64) error {
}
// Give access to team repositories.
mode := AuthorizeToAccessType(t.Authorize)
for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(orgId, uid, teamId, repo.Id)
if err != nil {
@ -804,22 +926,24 @@ func AddTeamMember(orgId, teamId, uid int64) error {
return err
}
access.Id = 0
access.RepoName = path.Join(org.LowerName, repo.LowerName)
access := &Access{
UserName: u.LowerName,
RepoName: path.Join(org.LowerName, repo.LowerName),
}
// Equal 0 means given access doesn't exist.
if auth == 0 {
access.Mode = mode
if _, err = sess.Insert(access); err != nil {
sess.Rollback()
return err
return fmt.Errorf("fail to insert access: %v", err)
}
} else if auth < t.Authorize {
if _, err = sess.Update(access); err != nil {
if err = addAccessWithAuthorize(sess, access, mode); err != nil {
sess.Rollback()
return err
}
}
}
fmt.Println("kao")
// We make sure it exists before.
ou := new(OrgUser)
@ -889,10 +1013,6 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
}
// Delete access to team repositories.
access := &Access{
UserName: u.LowerName,
}
for _, repo := range t.Repos {
auth, err := GetHighestAuthorize(orgId, uid, teamId, repo.Id)
if err != nil {
@ -900,22 +1020,22 @@ func removeTeamMemberWithSess(orgId, teamId, uid int64, sess *xorm.Session) erro
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 {
access.RepoName = path.Join(org.LowerName, repo.LowerName)
_, err = sess.Delete(access)
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.
mode := READABLE
if auth > ORG_READABLE {
mode = WRITABLE
if err = addAccessWithAuthorize(sess, access, AuthorizeToAccessType(auth)); err != nil {
sess.Rollback()
return err
}
access.Mode = mode
_, err = sess.Update(access)
}
if err != nil {
sess.Rollback()
return err
}
}

View file

@ -519,12 +519,11 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
sess.Rollback()
return nil, err
}
us, err := GetTeamMembers(u.Id, t.Id)
if err != nil {
if err = t.GetMembers(); err != nil {
sess.Rollback()
return nil, err
}
for _, u := range us {
for _, u := range t.Members {
access.Id = 0
access.UserName = u.LowerName
if _, err = sess.Insert(access); err != nil {
@ -963,6 +962,37 @@ func GetCollaborators(repoName string) (us []*User, err error) {
return us, nil
}
type SearchOption struct {
Keyword string
Uid int64
Limit int
}
// SearchRepositoryByName returns given number of repositories whose name contains keyword.
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
// Prevent SQL inject.
opt.Keyword = strings.TrimSpace(opt.Keyword)
if len(opt.Keyword) == 0 {
return repos, nil
}
opt.Keyword = strings.Split(opt.Keyword, " ")[0]
if len(opt.Keyword) == 0 {
return repos, nil
}
opt.Keyword = strings.ToLower(opt.Keyword)
repos = make([]*Repository, 0, opt.Limit)
// Append conditions.
sess := x.Limit(opt.Limit)
if opt.Uid > 0 {
sess.Where("owner_id=?", opt.Uid)
}
sess.And("lower_name like '%" + opt.Keyword + "%'").Find(&repos)
return repos, err
}
// Watch is connection request for receiving repository notifycation.
type Watch struct {
Id int64

View file

@ -521,21 +521,21 @@ func GetUserByEmail(email string) (*User, error) {
}
// SearchUserByName returns given number of users whose name contains keyword.
func SearchUserByName(key string, limit int) (us []*User, err error) {
func SearchUserByName(opt SearchOption) (us []*User, err error) {
// Prevent SQL inject.
key = strings.TrimSpace(key)
if len(key) == 0 {
opt.Keyword = strings.TrimSpace(opt.Keyword)
if len(opt.Keyword) == 0 {
return us, nil
}
key = strings.Split(key, " ")[0]
if len(key) == 0 {
opt.Keyword = strings.Split(opt.Keyword, " ")[0]
if len(opt.Keyword) == 0 {
return us, nil
}
key = strings.ToLower(key)
opt.Keyword = strings.ToLower(opt.Keyword)
us = make([]*User, 0, limit)
err = x.Limit(limit).Where("type=0").And("lower_name like '%" + key + "%'").Find(&us)
us = make([]*User, 0, opt.Limit)
err = x.Limit(opt.Limit).Where("type=0").And("lower_name like '%" + opt.Keyword + "%'").Find(&us)
return us, err
}