| @@ -17,7 +17,7 @@ import ( | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| const APP_VER = "0.5.14.0222 Beta" | |||
| const APP_VER = "0.5.15.0223 Beta" | |||
| func init() { | |||
| runtime.GOMAXPROCS(runtime.NumCPU()) | |||
| @@ -24,21 +24,19 @@ type Access struct { | |||
| Mode AccessMode | |||
| } | |||
| // 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) { | |||
| func accessLevel(e Engine, u *User, repo *Repository) (AccessMode, error) { | |||
| mode := ACCESS_MODE_NONE | |||
| if !r.IsPrivate { | |||
| if !repo.IsPrivate { | |||
| mode = ACCESS_MODE_READ | |||
| } | |||
| if u != nil { | |||
| if u.Id == r.OwnerId { | |||
| if u.Id == repo.OwnerId { | |||
| return ACCESS_MODE_OWNER, nil | |||
| } | |||
| a := &Access{UserID: u.Id, RepoID: r.Id} | |||
| if has, err := x.Get(a); !has || err != nil { | |||
| a := &Access{UserID: u.Id, RepoID: repo.Id} | |||
| if has, err := e.Get(a); !has || err != nil { | |||
| return mode, err | |||
| } | |||
| return a.Mode, nil | |||
| @@ -47,12 +45,22 @@ func AccessLevel(u *User, r *Repository) (AccessMode, error) { | |||
| return mode, nil | |||
| } | |||
| // 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) | |||
| // AccessLevel returns 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, repo *Repository) (AccessMode, error) { | |||
| return accessLevel(x, u, repo) | |||
| } | |||
| func hasAccess(e Engine, u *User, repo *Repository, testMode AccessMode) (bool, error) { | |||
| mode, err := accessLevel(e, u, repo) | |||
| return testMode <= mode, err | |||
| } | |||
| // HasAccess returns true if someone has the request access level. User can be nil! | |||
| func HasAccess(u *User, repo *Repository, testMode AccessMode) (bool, error) { | |||
| return hasAccess(x, u, repo, testMode) | |||
| } | |||
| // GetAccessibleRepositories finds all repositories where a user has access to, | |||
| // besides his own. | |||
| func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) { | |||
| @@ -96,7 +104,8 @@ func (repo *Repository) recalculateTeamAccesses(e Engine, mode AccessMode) error | |||
| func (repo *Repository) recalculateAccesses(e Engine) error { | |||
| accessMap := make(map[int64]AccessMode, 20) | |||
| // Give all collaborators write access | |||
| // FIXME: should be able to have read-only access. | |||
| // Give all collaborators write access. | |||
| collaborators, err := repo.getCollaborators(e) | |||
| if err != nil { | |||
| return err | |||
| @@ -114,9 +123,7 @@ func (repo *Repository) recalculateAccesses(e Engine) error { | |||
| } | |||
| for _, team := range repo.Owner.Teams { | |||
| if !(team.IsOwnerTeam() || team.HasRepository(repo)) { | |||
| continue | |||
| } else if team.IsOwnerTeam() { | |||
| if team.IsOwnerTeam() { | |||
| team.Authorize = ACCESS_MODE_OWNER | |||
| } | |||
| @@ -129,6 +136,8 @@ func (repo *Repository) recalculateAccesses(e Engine) error { | |||
| } | |||
| } | |||
| // FIXME: do corss-comparison so reduce deletions and additions to the minimum? | |||
| minMode := ACCESS_MODE_READ | |||
| if !repo.IsPrivate { | |||
| minMode = ACCESS_MODE_WRITE | |||
| @@ -434,20 +434,20 @@ func NewRepoAction(u *User, repo *Repository) (err error) { | |||
| return newRepoAction(x, u, repo) | |||
| } | |||
| func transferRepoAction(e Engine, u, newUser *User, repo *Repository) (err error) { | |||
| func transferRepoAction(e Engine, actUser, oldOwner, newOwner *User, repo *Repository) (err error) { | |||
| action := &Action{ | |||
| ActUserId: u.Id, | |||
| ActUserName: u.Name, | |||
| ActEmail: u.Email, | |||
| ActUserId: actUser.Id, | |||
| ActUserName: actUser.Name, | |||
| ActEmail: actUser.Email, | |||
| OpType: TRANSFER_REPO, | |||
| RepoId: repo.Id, | |||
| RepoUserName: newUser.Name, | |||
| RepoUserName: newOwner.Name, | |||
| RepoName: repo.Name, | |||
| IsPrivate: repo.IsPrivate, | |||
| Content: path.Join(repo.Owner.LowerName, repo.LowerName), | |||
| Content: path.Join(oldOwner.LowerName, repo.LowerName), | |||
| } | |||
| if err = notifyWatchers(e, action); err != nil { | |||
| return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.Id) | |||
| return fmt.Errorf("notify watchers '%d/%s'", actUser.Id, repo.Id) | |||
| } | |||
| // Remove watch for organization. | |||
| @@ -457,13 +457,13 @@ func transferRepoAction(e Engine, u, newUser *User, repo *Repository) (err error | |||
| } | |||
| } | |||
| log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name) | |||
| log.Trace("action.TransferRepoAction: %s/%s", actUser.Name, repo.Name) | |||
| return nil | |||
| } | |||
| // TransferRepoAction adds new action for transferring repository. | |||
| func TransferRepoAction(u, newUser *User, repo *Repository) (err error) { | |||
| return transferRepoAction(x, u, newUser, repo) | |||
| func TransferRepoAction(actUser, oldOwner, newOwner *User, repo *Repository) (err error) { | |||
| return transferRepoAction(x, actUser, oldOwner, newOwner, repo) | |||
| } | |||
| // GetFeeds returns action list of given user in given context. | |||
| @@ -53,6 +53,7 @@ var migrations = []Migration{ | |||
| NewMigration("generate collaboration from access", accessToCollaboration), // V0 -> V1 | |||
| NewMigration("make authorize 4 if team is owners", ownerTeamUpdate), // V1 -> V2 | |||
| NewMigration("refactor access table to use id's", accessRefactor), // V2 -> V3 | |||
| NewMigration("generate team-repo from team", teamToTeamRepo), // V3 -> V4 | |||
| } | |||
| // Migrate database to current version | |||
| @@ -214,8 +215,8 @@ func accessToCollaboration(x *xorm.Engine) (err error) { | |||
| } | |||
| func ownerTeamUpdate(x *xorm.Engine) (err error) { | |||
| if _, err := x.Exec("UPDATE team SET authorize=4 WHERE lower_name=?", "owners"); err != nil { | |||
| return fmt.Errorf("drop table: %v", err) | |||
| if _, err := x.Exec("UPDATE `team` SET authorize=4 WHERE lower_name=?", "owners"); err != nil { | |||
| return fmt.Errorf("update owner team table: %v", err) | |||
| } | |||
| return nil | |||
| } | |||
| @@ -239,9 +240,9 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| accessMap := make(map[UserRepo]AccessMode, 50) | |||
| results, err := x.Query("SELECT r.id as `repo_id`, r.is_private as `is_private`, r.owner_id as `owner_id`, u.type as `owner_type` FROM `repository` r LEFT JOIN user u ON r.owner_id=u.id") | |||
| results, err := x.Query("SELECT r.id AS `repo_id`, r.is_private AS `is_private`, r.owner_id AS `owner_id`, u.type AS `owner_type` FROM `repository` r LEFT JOIN `user` u ON r.owner_id=u.id") | |||
| if err != nil { | |||
| return err | |||
| return fmt.Errorf("select repositories: %v", err) | |||
| } | |||
| for _, repo := range results { | |||
| repoID := com.StrTo(repo["repo_id"]).MustInt64() | |||
| @@ -249,9 +250,9 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| ownerID := com.StrTo(repo["owner_id"]).MustInt64() | |||
| ownerIsOrganization := com.StrTo(repo["owner_type"]).MustInt() > 0 | |||
| results, err := x.Query("SELECT user_id FROM collaboration WHERE repo_id=?", repoID) | |||
| results, err := x.Query("SELECT `user_id` FROM `collaboration` WHERE repo_id=?", repoID) | |||
| if err != nil { | |||
| return fmt.Errorf("select repos: %v", err) | |||
| return fmt.Errorf("select collaborators: %v", err) | |||
| } | |||
| for _, user := range results { | |||
| userID := com.StrTo(user["user_id"]).MustInt64() | |||
| @@ -262,6 +263,8 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| continue | |||
| } | |||
| // The minimum level to add a new access record, | |||
| // because public repository has implicit open access. | |||
| minAccessLevel := AccessMode(0) | |||
| if !isPrivate { | |||
| minAccessLevel = 1 | |||
| @@ -269,7 +272,7 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| repoString := "$" + string(repo["repo_id"]) + "|" | |||
| results, err = x.Query("SELECT id, authorize, repo_ids FROM team WHERE org_id=? AND authorize > ? ORDER BY authorize ASC", ownerID, int(minAccessLevel)) | |||
| results, err = x.Query("SELECT `id`,`authorize`,`repo_ids` FROM `team` WHERE org_id=? AND authorize>? ORDER BY `authorize` ASC", ownerID, int(minAccessLevel)) | |||
| if err != nil { | |||
| return fmt.Errorf("select teams from org: %v", err) | |||
| } | |||
| @@ -281,20 +284,20 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| teamID := com.StrTo(team["id"]).MustInt64() | |||
| mode := AccessMode(com.StrTo(team["authorize"]).MustInt()) | |||
| results, err := x.Query("SELECT uid FROM team_user WHERE team_id=?", teamID) | |||
| results, err := x.Query("SELECT `uid` FROM `team_user` WHERE team_id=?", teamID) | |||
| if err != nil { | |||
| return fmt.Errorf("select users from team: %v", err) | |||
| } | |||
| for _, user := range results { | |||
| userID := com.StrTo(user["uid"]).MustInt64() | |||
| userID := com.StrTo(user["user_id"]).MustInt64() | |||
| accessMap[UserRepo{userID, repoID}] = mode | |||
| } | |||
| } | |||
| } | |||
| // Drop table can't be in a session (at least not in sqlite) | |||
| if _, err = x.Exec("DROP TABLE access"); err != nil { | |||
| return fmt.Errorf("drop table: %v", err) | |||
| if _, err = x.Exec("DROP TABLE `access`"); err != nil { | |||
| return fmt.Errorf("drop access table: %v", err) | |||
| } | |||
| // Now we start writing so we make a session | |||
| @@ -313,7 +316,56 @@ func accessRefactor(x *xorm.Engine) (err error) { | |||
| accesses = append(accesses, &Access{UserID: ur.UserID, RepoID: ur.RepoID, Mode: mode}) | |||
| } | |||
| _, err = sess.Insert(accesses) | |||
| if _, err = sess.Insert(accesses); err != nil { | |||
| return fmt.Errorf("insert accesses: %v", err) | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| func teamToTeamRepo(x *xorm.Engine) error { | |||
| type TeamRepo struct { | |||
| ID int64 `xorm:"pk autoincr"` | |||
| OrgID int64 `xorm:"INDEX"` | |||
| TeamID int64 `xorm:"UNIQUE(s)"` | |||
| RepoID int64 `xorm:"UNIQUE(s)"` | |||
| } | |||
| teamRepos := make([]*TeamRepo, 0, 50) | |||
| results, err := x.Query("SELECT `id`,`org_id`,`repo_ids` FROM `team`") | |||
| if err != nil { | |||
| return fmt.Errorf("select teams: %v", err) | |||
| } | |||
| for _, team := range results { | |||
| orgID := com.StrTo(team["org_id"]).MustInt64() | |||
| teamID := com.StrTo(team["id"]).MustInt64() | |||
| for _, idStr := range strings.Split(string(team["repo_ids"]), "|") { | |||
| repoID := com.StrTo(strings.TrimPrefix(idStr, "$")).MustInt64() | |||
| if repoID == 0 { | |||
| continue | |||
| } | |||
| teamRepos = append(teamRepos, &TeamRepo{ | |||
| OrgID: orgID, | |||
| TeamID: teamID, | |||
| RepoID: repoID, | |||
| }) | |||
| } | |||
| } | |||
| sess := x.NewSession() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| return err | |||
| } | |||
| if err = sess.Sync2(new(TeamRepo)); err != nil { | |||
| return fmt.Errorf("sync: %v", err) | |||
| } else if _, err = sess.Insert(teamRepos); err != nil { | |||
| return fmt.Errorf("insert team-repos: %v", err) | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| @@ -16,7 +16,7 @@ import ( | |||
| "github.com/go-xorm/xorm" | |||
| _ "github.com/lib/pq" | |||
| // "github.com/gogits/gogs/models/migrations" | |||
| "github.com/gogits/gogs/models/migrations" | |||
| "github.com/gogits/gogs/modules/setting" | |||
| ) | |||
| @@ -59,7 +59,8 @@ func init() { | |||
| new(Watch), new(Star), new(Follow), new(Action), | |||
| new(Issue), new(Comment), new(Attachment), new(IssueUser), new(Label), new(Milestone), | |||
| new(Mirror), new(Release), new(LoginSource), new(Webhook), | |||
| new(UpdateTask), new(HookTask), new(Team), new(OrgUser), new(TeamUser), | |||
| new(UpdateTask), new(HookTask), | |||
| new(Team), new(OrgUser), new(TeamUser), new(TeamRepo), | |||
| new(Notice), new(EmailAddress)) | |||
| } | |||
| @@ -6,11 +6,10 @@ package models | |||
| import ( | |||
| "errors" | |||
| "fmt" | |||
| "os" | |||
| "strings" | |||
| "github.com/Unknwon/com" | |||
| "github.com/gogits/gogs/modules/base" | |||
| ) | |||
| @@ -126,53 +125,48 @@ func CreateOrganization(org, owner *User) (*User, error) { | |||
| org.NumMembers = 1 | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| return nil, err | |||
| } | |||
| if _, err = sess.Insert(org); err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| if err = os.MkdirAll(UserPath(org.Name), os.ModePerm); err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| // Create default owner team. | |||
| t := &Team{ | |||
| OrgId: org.Id, | |||
| OrgID: org.Id, | |||
| LowerName: strings.ToLower(OWNER_TEAM), | |||
| Name: OWNER_TEAM, | |||
| Authorize: ACCESS_MODE_OWNER, | |||
| NumMembers: 1, | |||
| } | |||
| if _, err = sess.Insert(t); err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| // Add initial creator to organization and owner team. | |||
| ou := &OrgUser{ | |||
| Uid: owner.Id, | |||
| OrgId: org.Id, | |||
| OrgID: org.Id, | |||
| IsOwner: true, | |||
| NumTeams: 1, | |||
| } | |||
| if _, err = sess.Insert(ou); err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| tu := &TeamUser{ | |||
| Uid: owner.Id, | |||
| OrgId: org.Id, | |||
| TeamId: t.Id, | |||
| OrgID: org.Id, | |||
| TeamID: t.ID, | |||
| } | |||
| if _, err = sess.Insert(tu); err != nil { | |||
| sess.Rollback() | |||
| return nil, err | |||
| } | |||
| if err = os.MkdirAll(UserPath(org.Name), os.ModePerm); err != nil { | |||
| return nil, err | |||
| } | |||
| @@ -223,15 +217,15 @@ func DeleteOrganization(org *User) (err error) { | |||
| return err | |||
| } | |||
| if _, err = sess.Delete(&Team{OrgId: org.Id}); err != nil { | |||
| if _, err = sess.Delete(&Team{OrgID: org.Id}); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| if _, err = sess.Delete(&OrgUser{OrgId: org.Id}); err != nil { | |||
| if _, err = sess.Delete(&OrgUser{OrgID: org.Id}); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| if _, err = sess.Delete(&TeamUser{OrgId: org.Id}); err != nil { | |||
| if _, err = sess.Delete(&TeamUser{OrgID: org.Id}); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| @@ -247,9 +241,9 @@ func DeleteOrganization(org *User) (err error) { | |||
| // OrgUser represents an organization-user relation. | |||
| type OrgUser struct { | |||
| Id int64 | |||
| ID int64 `xorm:"pk autoincr"` | |||
| Uid int64 `xorm:"INDEX UNIQUE(s)"` | |||
| OrgId int64 `xorm:"INDEX UNIQUE(s)"` | |||
| OrgID int64 `xorm:"INDEX UNIQUE(s)"` | |||
| IsPublic bool | |||
| IsOwner bool | |||
| NumTeams int | |||
| @@ -298,7 +292,7 @@ func ChangeOrgUserStatus(orgId, uid int64, public bool) error { | |||
| } | |||
| ou.IsPublic = public | |||
| _, err = x.Id(ou.Id).AllCols().Update(ou) | |||
| _, err = x.Id(ou.ID).AllCols().Update(ou) | |||
| return err | |||
| } | |||
| @@ -316,7 +310,7 @@ func AddOrgUser(orgId, uid int64) error { | |||
| ou := &OrgUser{ | |||
| Uid: uid, | |||
| OrgId: orgId, | |||
| OrgID: orgId, | |||
| } | |||
| if _, err := sess.Insert(ou); err != nil { | |||
| @@ -367,7 +361,7 @@ func RemoveOrgUser(orgId, uid int64) error { | |||
| return err | |||
| } | |||
| if _, err := sess.Id(ou.Id).Delete(ou); err != nil { | |||
| if _, err := sess.Id(ou.ID).Delete(ou); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } else if _, err = sess.Exec("UPDATE `user` SET num_members = num_members - 1 WHERE id = ?", orgId); err != nil { | |||
| @@ -400,7 +394,7 @@ func RemoveOrgUser(orgId, uid int64) error { | |||
| return err | |||
| } | |||
| for _, t := range ts { | |||
| if err = removeTeamMember(sess, org.Id, t.Id, u.Id); err != nil { | |||
| if err = removeTeamMember(sess, org.Id, t.ID, u.Id); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| @@ -419,13 +413,12 @@ const OWNER_TEAM = "Owners" | |||
| // Team represents a organization team. | |||
| type Team struct { | |||
| Id int64 | |||
| OrgId int64 `xorm:"INDEX"` | |||
| ID int64 `xorm:"pk autoincr"` | |||
| OrgID int64 `xorm:"INDEX"` | |||
| LowerName string | |||
| Name string | |||
| Description string | |||
| Authorize AccessMode | |||
| RepoIds string `xorm:"TEXT"` | |||
| Repos []*Repository `xorm:"-"` | |||
| Members []*User `xorm:"-"` | |||
| NumRepos int | |||
| @@ -439,23 +432,20 @@ func (t *Team) IsOwnerTeam() bool { | |||
| // IsTeamMember returns true if given user is a member of team. | |||
| func (t *Team) IsMember(uid int64) bool { | |||
| return IsTeamMember(t.OrgId, t.Id, uid) | |||
| return IsTeamMember(t.OrgID, t.ID, uid) | |||
| } | |||
| func (t *Team) getRepositories(e Engine) error { | |||
| idStrs := strings.Split(t.RepoIds, "|") | |||
| t.Repos = make([]*Repository, 0, len(idStrs)) | |||
| for _, str := range idStrs { | |||
| if len(str) == 0 { | |||
| continue | |||
| } | |||
| id := com.StrTo(str[1:]).MustInt64() | |||
| if id == 0 { | |||
| continue | |||
| } | |||
| repo, err := getRepositoryById(e, id) | |||
| func (t *Team) getRepositories(e Engine) (err error) { | |||
| teamRepos := make([]*TeamRepo, 0, t.NumRepos) | |||
| if err = x.Where("team_id=?", t.ID).Find(&teamRepos); err != nil { | |||
| return fmt.Errorf("get team-repos: %v", err) | |||
| } | |||
| t.Repos = make([]*Repository, 0, len(teamRepos)) | |||
| for i := range teamRepos { | |||
| repo, err := getRepositoryById(e, teamRepos[i].RepoID) | |||
| if err != nil { | |||
| return err | |||
| return fmt.Errorf("getRepositoryById(%d): %v", teamRepos[i].RepoID, err) | |||
| } | |||
| t.Repos = append(t.Repos, repo) | |||
| } | |||
| @@ -468,7 +458,7 @@ func (t *Team) GetRepositories() error { | |||
| } | |||
| func (t *Team) getMembers(e Engine) (err error) { | |||
| t.Members, err = getTeamMembers(e, t.Id) | |||
| t.Members, err = getTeamMembers(e, t.ID) | |||
| return err | |||
| } | |||
| @@ -479,96 +469,121 @@ func (t *Team) GetMembers() (err error) { | |||
| // AddMember adds new member to team of organization. | |||
| func (t *Team) AddMember(uid int64) error { | |||
| return AddTeamMember(t.OrgId, t.Id, uid) | |||
| return AddTeamMember(t.OrgID, t.ID, uid) | |||
| } | |||
| // RemoveMember removes member from team of organization. | |||
| func (t *Team) RemoveMember(uid int64) error { | |||
| return RemoveTeamMember(t.OrgId, t.Id, uid) | |||
| return RemoveTeamMember(t.OrgID, t.ID, uid) | |||
| } | |||
| // 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 | |||
| } | |||
| func (t *Team) hasRepository(e Engine, repoID int64) bool { | |||
| return hasTeamRepo(e, t.OrgID, t.ID, repoID) | |||
| } | |||
| if err = repo.GetOwner(); err != nil { | |||
| return err | |||
| } else if err = t.GetMembers(); err != nil { | |||
| return err | |||
| } | |||
| // HasRepository returns true if given repository belong to team. | |||
| func (t *Team) HasRepository(repoID int64) bool { | |||
| return HasTeamRepo(t.OrgID, t.ID, repoID) | |||
| } | |||
| sess := x.NewSession() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| func (t *Team) addRepository(e Engine, repo *Repository) (err error) { | |||
| if err = addTeamRepo(e, t.OrgID, t.ID, repo.Id); err != nil { | |||
| return err | |||
| } | |||
| t.NumRepos++ | |||
| t.RepoIds += idStr | |||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||
| if _, err = e.Id(t.ID).AllCols().Update(t); err != nil { | |||
| return err | |||
| } | |||
| if err = repo.recalculateAccesses(sess); err != nil { | |||
| if err = repo.recalculateAccesses(e); err != nil { | |||
| return err | |||
| } | |||
| if err = t.getMembers(e); err != nil { | |||
| return fmt.Errorf("get team members: %v", err) | |||
| } | |||
| for _, u := range t.Members { | |||
| if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { | |||
| if err = watchRepo(e, u.Id, repo.Id, true); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| func (t *Team) HasRepository(repo *Repository) bool { | |||
| idStr := "$" + com.ToStr(repo.Id) + "|" | |||
| return strings.Contains(t.RepoIds, idStr) | |||
| return nil | |||
| } | |||
| // RemoveRepository removes repository from team of organization. | |||
| func (t *Team) RemoveRepository(repoId int64) error { | |||
| idStr := "$" + com.ToStr(repoId) + "|" | |||
| if !strings.Contains(t.RepoIds, idStr) { | |||
| // AddRepository adds new repository to team of organization. | |||
| func (t *Team) AddRepository(repo *Repository) (err error) { | |||
| if repo.OwnerId != t.OrgID { | |||
| return errors.New("Repository does not belong to organization") | |||
| } else if t.HasRepository(repo.Id) { | |||
| return nil | |||
| } | |||
| repo, err := GetRepositoryById(repoId) | |||
| if err != nil { | |||
| sess := x.NewSession() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| return err | |||
| } | |||
| if err = repo.GetOwner(); err != nil { | |||
| return err | |||
| } else if err = t.GetMembers(); err != nil { | |||
| if err = t.addRepository(sess, repo); err != nil { | |||
| return err | |||
| } | |||
| sess := x.NewSession() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| return sess.Commit() | |||
| } | |||
| func (t *Team) removeRepository(e Engine, repo *Repository) (err error) { | |||
| if err = removeTeamRepo(e, t.ID, repo.Id); 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 { | |||
| if _, err = e.Id(t.ID).AllCols().Update(t); err != nil { | |||
| return err | |||
| } | |||
| if err = repo.recalculateAccesses(sess); err != nil { | |||
| if err = repo.recalculateAccesses(e); err != nil { | |||
| return err | |||
| } | |||
| if err = t.getMembers(e); err != nil { | |||
| return fmt.Errorf("get team members: %v", err) | |||
| } | |||
| for _, u := range t.Members { | |||
| if err = watchRepo(sess, u.Id, repo.Id, false); err != nil { | |||
| has, err := hasAccess(e, u, repo, ACCESS_MODE_READ) | |||
| if err != nil { | |||
| return err | |||
| } else if has { | |||
| continue | |||
| } | |||
| if err = watchRepo(e, u.Id, repo.Id, false); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| return nil | |||
| } | |||
| // RemoveRepository removes repository from team of organization. | |||
| func (t *Team) RemoveRepository(repoID int64) error { | |||
| if !t.HasRepository(repoID) { | |||
| return nil | |||
| } | |||
| repo, err := GetRepositoryById(repoID) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| sess := x.NewSession() | |||
| defer sessionRelease(sess) | |||
| if err = sess.Begin(); err != nil { | |||
| return err | |||
| } | |||
| if err = t.removeRepository(sess, repo); err != nil { | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| @@ -581,7 +596,7 @@ func NewTeam(t *Team) error { | |||
| return ErrTeamNameIllegal | |||
| } | |||
| has, err := x.Id(t.OrgId).Get(new(User)) | |||
| has, err := x.Id(t.OrgID).Get(new(User)) | |||
| if err != nil { | |||
| return err | |||
| } else if !has { | |||
| @@ -589,7 +604,7 @@ func NewTeam(t *Team) error { | |||
| } | |||
| t.LowerName = strings.ToLower(t.Name) | |||
| has, err = x.Where("org_id=?", t.OrgId).And("lower_name=?", t.LowerName).Get(new(Team)) | |||
| has, err = x.Where("org_id=?", t.OrgID).And("lower_name=?", t.LowerName).Get(new(Team)) | |||
| if err != nil { | |||
| return err | |||
| } else if has { | |||
| @@ -608,7 +623,7 @@ func NewTeam(t *Team) error { | |||
| } | |||
| // Update organization number of teams. | |||
| if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgId); err != nil { | |||
| if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?", t.OrgID); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| @@ -617,7 +632,7 @@ func NewTeam(t *Team) error { | |||
| func getTeam(e Engine, orgId int64, name string) (*Team, error) { | |||
| t := &Team{ | |||
| OrgId: orgId, | |||
| OrgID: orgId, | |||
| LowerName: strings.ToLower(name), | |||
| } | |||
| has, err := e.Get(t) | |||
| @@ -667,7 +682,7 @@ func UpdateTeam(t *Team, authChanged bool) (err error) { | |||
| } | |||
| t.LowerName = strings.ToLower(t.Name) | |||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||
| if _, err = sess.Id(t.ID).AllCols().Update(t); err != nil { | |||
| return err | |||
| } | |||
| @@ -697,7 +712,7 @@ func DeleteTeam(t *Team) error { | |||
| } | |||
| // Get organization. | |||
| org, err := GetUserById(t.OrgId) | |||
| org, err := GetUserById(t.OrgID) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| @@ -716,16 +731,16 @@ func DeleteTeam(t *Team) error { | |||
| } | |||
| // Delete team-user. | |||
| if _, err = sess.Where("org_id=?", org.Id).Where("team_id=?", t.Id).Delete(new(TeamUser)); err != nil { | |||
| if _, err = sess.Where("org_id=?", org.Id).Where("team_id=?", t.ID).Delete(new(TeamUser)); err != nil { | |||
| return err | |||
| } | |||
| // Delete team. | |||
| if _, err = sess.Id(t.Id).Delete(new(Team)); err != nil { | |||
| if _, err = sess.Id(t.ID).Delete(new(Team)); err != nil { | |||
| return err | |||
| } | |||
| // Update organization number of teams. | |||
| if _, err = sess.Exec("UPDATE `user` SET num_teams = num_teams - 1 WHERE id = ?", t.OrgId); err != nil { | |||
| if _, err = sess.Exec("UPDATE `user` SET num_teams=num_teams-1 WHERE id=?", t.OrgID); err != nil { | |||
| return err | |||
| } | |||
| @@ -741,20 +756,20 @@ func DeleteTeam(t *Team) error { | |||
| // TeamUser represents an team-user relation. | |||
| type TeamUser struct { | |||
| Id int64 | |||
| Uid int64 | |||
| OrgId int64 `xorm:"INDEX"` | |||
| TeamId int64 | |||
| ID int64 `xorm:"pk autoincr"` | |||
| OrgID int64 `xorm:"INDEX"` | |||
| TeamID int64 `xorm:"UNIQUE(s)"` | |||
| Uid int64 `xorm:"UNIQUE(s)"` | |||
| } | |||
| func isTeamMember(e Engine, orgId, teamId, uid int64) bool { | |||
| has, _ := e.Where("uid=?", uid).And("org_id=?", orgId).And("team_id=?", teamId).Get(new(TeamUser)) | |||
| func isTeamMember(e Engine, orgID, teamID, uid int64) bool { | |||
| has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("uid=?", uid).Get(new(TeamUser)) | |||
| return has | |||
| } | |||
| // IsTeamMember returns true if given user is a member of team. | |||
| func IsTeamMember(orgId, teamId, uid int64) bool { | |||
| return isTeamMember(x, orgId, teamId, uid) | |||
| func IsTeamMember(orgID, teamID, uid int64) bool { | |||
| return isTeamMember(x, orgID, teamID, uid) | |||
| } | |||
| func getTeamMembers(e Engine, teamID int64) ([]*User, error) { | |||
| @@ -777,7 +792,7 @@ func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) { | |||
| ts := make([]*Team, len(tus)) | |||
| for i, tu := range tus { | |||
| t := new(Team) | |||
| has, err := e.Id(tu.TeamId).Get(t) | |||
| has, err := e.Id(tu.TeamID).Get(t) | |||
| if err != nil { | |||
| return nil, err | |||
| } else if !has { | |||
| @@ -822,13 +837,13 @@ func AddTeamMember(orgId, teamId, uid int64) error { | |||
| tu := &TeamUser{ | |||
| Uid: uid, | |||
| OrgId: orgId, | |||
| TeamId: teamId, | |||
| OrgID: orgId, | |||
| TeamID: teamId, | |||
| } | |||
| if _, err = sess.Insert(tu); err != nil { | |||
| return err | |||
| } else if _, err = sess.Id(t.Id).Update(t); err != nil { | |||
| } else if _, err = sess.Id(t.ID).Update(t); err != nil { | |||
| return err | |||
| } | |||
| @@ -848,7 +863,7 @@ func AddTeamMember(orgId, teamId, uid int64) error { | |||
| if t.IsOwnerTeam() { | |||
| ou.IsOwner = true | |||
| } | |||
| if _, err = sess.Id(ou.Id).AllCols().Update(ou); err != nil { | |||
| if _, err = sess.Id(ou.ID).AllCols().Update(ou); err != nil { | |||
| return err | |||
| } | |||
| @@ -885,13 +900,13 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error { | |||
| tu := &TeamUser{ | |||
| Uid: uid, | |||
| OrgId: orgId, | |||
| TeamId: teamId, | |||
| OrgID: orgId, | |||
| TeamID: teamId, | |||
| } | |||
| if _, err := e.Delete(tu); err != nil { | |||
| return err | |||
| } else if _, err = e.Id(t.Id).AllCols().Update(t); err != nil { | |||
| } else if _, err = e.Id(t.ID).AllCols().Update(t); err != nil { | |||
| return err | |||
| } | |||
| @@ -912,7 +927,7 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error { | |||
| if t.IsOwnerTeam() { | |||
| ou.IsOwner = false | |||
| } | |||
| if _, err = e.Id(ou.Id).AllCols().Update(ou); err != nil { | |||
| if _, err = e.Id(ou.ID).AllCols().Update(ou); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| @@ -921,13 +936,64 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error { | |||
| // RemoveTeamMember removes member from given team of given organization. | |||
| func RemoveTeamMember(orgId, teamId, uid int64) error { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| defer sessionRelease(sess) | |||
| if err := sess.Begin(); err != nil { | |||
| return err | |||
| } | |||
| if err := removeTeamMember(sess, orgId, teamId, uid); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| // ___________ __________ | |||
| // \__ ___/___ _____ _____\______ \ ____ ______ ____ | |||
| // | |_/ __ \\__ \ / \| _// __ \\____ \ / _ \ | |||
| // | |\ ___/ / __ \| Y Y \ | \ ___/| |_> > <_> ) | |||
| // |____| \___ >____ /__|_| /____|_ /\___ > __/ \____/ | |||
| // \/ \/ \/ \/ \/|__| | |||
| // TeamRepo represents an team-repository relation. | |||
| type TeamRepo struct { | |||
| ID int64 `xorm:"pk autoincr"` | |||
| OrgID int64 `xorm:"INDEX"` | |||
| TeamID int64 `xorm:"UNIQUE(s)"` | |||
| RepoID int64 `xorm:"UNIQUE(s)"` | |||
| } | |||
| func hasTeamRepo(e Engine, orgID, teamID, repoID int64) bool { | |||
| has, _ := e.Where("org_id=?", orgID).And("team_id=?", teamID).And("repo_id=?", repoID).Get(new(TeamRepo)) | |||
| return has | |||
| } | |||
| // HasTeamRepo returns true if given repository belongs to team. | |||
| func HasTeamRepo(orgID, teamID, repoID int64) bool { | |||
| return hasTeamRepo(x, orgID, teamID, repoID) | |||
| } | |||
| func addTeamRepo(e Engine, orgID, teamID, repoID int64) error { | |||
| _, err := e.InsertOne(&TeamRepo{ | |||
| OrgID: orgID, | |||
| TeamID: teamID, | |||
| RepoID: repoID, | |||
| }) | |||
| return err | |||
| } | |||
| // AddTeamRepo adds new repository relation to team. | |||
| func AddTeamRepo(orgID, teamID, repoID int64) error { | |||
| return addTeamRepo(x, orgID, teamID, repoID) | |||
| } | |||
| func removeTeamRepo(e Engine, teamID, repoID int64) error { | |||
| _, err := e.Delete(&TeamRepo{ | |||
| TeamID: teamID, | |||
| RepoID: repoID, | |||
| }) | |||
| return err | |||
| } | |||
| // RemoveTeamRepo deletes repository relation to team. | |||
| func RemoveTeamRepo(teamID, repoID int64) error { | |||
| return removeTeamRepo(x, teamID, repoID) | |||
| } | |||
| @@ -514,7 +514,7 @@ func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bo | |||
| } | |||
| // CreateRepository creates a repository for given user or organization. | |||
| func CreateRepository(u *User, name, desc, lang, license string, private, mirror, initReadme bool) (*Repository, error) { | |||
| func CreateRepository(u *User, name, desc, lang, license string, isPrivate, isMirror, initReadme bool) (*Repository, error) { | |||
| if !IsLegalName(name) { | |||
| return nil, ErrRepoNameIllegal | |||
| } | |||
| @@ -532,7 +532,7 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror | |||
| Name: name, | |||
| LowerName: strings.ToLower(name), | |||
| Description: desc, | |||
| IsPrivate: private, | |||
| IsPrivate: isPrivate, | |||
| } | |||
| sess := x.NewSession() | |||
| @@ -558,34 +558,22 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror | |||
| // Update owner team info and count. | |||
| t, err := u.getOwnerTeam(sess) | |||
| if err != nil { | |||
| return nil, fmt.Errorf("get owner team: %v", err) | |||
| } else if err = t.getMembers(sess); err != nil { | |||
| return nil, fmt.Errorf("get team members: %v", err) | |||
| } | |||
| for _, u := range t.Members { | |||
| if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { | |||
| return nil, fmt.Errorf("watch repository: %v", err) | |||
| } | |||
| } | |||
| t.RepoIds += "$" + com.ToStr(repo.Id) + "|" | |||
| t.NumRepos++ | |||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||
| return nil, err | |||
| return nil, fmt.Errorf("getOwnerTeam: %v", err) | |||
| } else if err = t.addRepository(sess, repo); err != nil { | |||
| return nil, fmt.Errorf("addRepository: %v", err) | |||
| } | |||
| } else { | |||
| if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { | |||
| return nil, fmt.Errorf("watch repository 2: %v", err) | |||
| return nil, fmt.Errorf("watchRepo: %v", err) | |||
| } | |||
| } | |||
| if err = newRepoAction(sess, u, repo); err != nil { | |||
| return nil, fmt.Errorf("new repository action: %v", err) | |||
| return nil, fmt.Errorf("newRepoAction: %v", err) | |||
| } | |||
| // No need for init mirror. | |||
| if !mirror { | |||
| if !isMirror { | |||
| repoPath := RepoPath(u.Name, repo.Name) | |||
| if err = initRepository(sess, repoPath, u, repo, initReadme, lang, license); err != nil { | |||
| if err2 := os.RemoveAll(repoPath); err2 != nil { | |||
| @@ -640,14 +628,14 @@ func RepoPath(userName, repoName string) string { | |||
| } | |||
| // TransferOwnership transfers all corresponding setting from old user to new one. | |||
| func TransferOwnership(u *User, newOwner string, repo *Repository) error { | |||
| newUser, err := GetUserByName(newOwner) | |||
| func TransferOwnership(u *User, newOwnerName string, repo *Repository) error { | |||
| newOwner, err := GetUserByName(newOwnerName) | |||
| if err != nil { | |||
| return fmt.Errorf("fail to get new owner(%s): %v", newOwner, err) | |||
| return fmt.Errorf("get new owner(%s): %v", newOwnerName, err) | |||
| } | |||
| // Check if new owner has repository with same name. | |||
| has, err := IsRepositoryExist(newUser, repo.Name) | |||
| has, err := IsRepositoryExist(newOwner, repo.Name) | |||
| if err != nil { | |||
| return err | |||
| } else if has { | |||
| @@ -663,8 +651,8 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error { | |||
| owner := repo.Owner | |||
| // Update repository. | |||
| repo.OwnerId = newUser.Id | |||
| repo.Owner = newUser | |||
| repo.OwnerId = newOwner.Id | |||
| repo.Owner = newOwner | |||
| if _, err := sess.Id(repo.Id).Update(repo); err != nil { | |||
| return err | |||
| } | |||
| @@ -675,28 +663,38 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error { | |||
| return err | |||
| } | |||
| for _, c := range collaborators { | |||
| if c.Id == newUser.Id || newUser.IsOrgMember(c.Id) { | |||
| if c.Id == newOwner.Id || newOwner.IsOrgMember(c.Id) { | |||
| if _, err = sess.Delete(&Collaboration{RepoID: repo.Id, UserID: c.Id}); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| } | |||
| if newOwner.IsOrganization() { | |||
| // Update owner team info and count. | |||
| t, err := newOwner.GetOwnerTeam() | |||
| if err != nil { | |||
| return err | |||
| } else if err = t.addRepository(sess, repo); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| // Update user repository number. | |||
| if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", newUser.Id); err != nil { | |||
| if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", newOwner.Id); err != nil { | |||
| return err | |||
| } else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil { | |||
| return err | |||
| } else if err = repo.recalculateAccesses(sess); err != nil { | |||
| return err | |||
| } else if err = watchRepo(sess, newUser.Id, repo.Id, true); err != nil { | |||
| } else if err = watchRepo(sess, newOwner.Id, repo.Id, true); err != nil { | |||
| return err | |||
| } else if err = transferRepoAction(sess, u, newUser, repo); err != nil { | |||
| } else if err = transferRepoAction(sess, u, owner, newOwner, repo); err != nil { | |||
| return err | |||
| } | |||
| // Change repository directory name. | |||
| if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil { | |||
| if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newOwner.Name, repo.Name)); err != nil { | |||
| return err | |||
| } | |||
| @@ -734,8 +732,8 @@ func UpdateRepository(repo *Repository) error { | |||
| } | |||
| // DeleteRepository deletes a repository for a user or organization. | |||
| func DeleteRepository(uid, repoId int64, userName string) error { | |||
| repo := &Repository{Id: repoId, OwnerId: uid} | |||
| func DeleteRepository(uid, repoID int64, userName string) error { | |||
| repo := &Repository{Id: repoID, OwnerId: uid} | |||
| has, err := x.Get(repo) | |||
| if err != nil { | |||
| return err | |||
| @@ -761,70 +759,66 @@ func DeleteRepository(uid, repoId int64, userName string) error { | |||
| } | |||
| if org.IsOrganization() { | |||
| idStr := "$" + com.ToStr(repoId) + "|" | |||
| for _, t := range org.Teams { | |||
| if !strings.Contains(t.RepoIds, idStr) { | |||
| if !t.hasRepository(sess, repoID) { | |||
| continue | |||
| } | |||
| t.NumRepos-- | |||
| t.RepoIds = strings.Replace(t.RepoIds, idStr, "", 1) | |||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||
| } else if err = t.removeRepository(sess, repo); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| } | |||
| if _, err = sess.Delete(&Repository{Id: repoId}); err != nil { | |||
| if _, err = sess.Delete(&Repository{Id: repoID}); err != nil { | |||
| return err | |||
| } else if _, err := sess.Delete(&Access{RepoID: repo.Id}); err != nil { | |||
| return err | |||
| } else if _, err := sess.Delete(&Action{RepoId: repo.Id}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&Watch{RepoId: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&Watch{RepoId: repoID}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&Mirror{RepoId: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&Mirror{RepoId: repoID}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&IssueUser{RepoId: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&IssueUser{RepoId: repoID}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&Milestone{RepoId: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&Milestone{RepoId: repoID}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&Release{RepoId: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&Release{RepoId: repoID}); err != nil { | |||
| return err | |||
| } else if _, err = sess.Delete(&Collaboration{RepoID: repoId}); err != nil { | |||
| } else if _, err = sess.Delete(&Collaboration{RepoID: repoID}); err != nil { | |||
| return err | |||
| } | |||
| // Delete comments. | |||
| if err = x.Iterate(&Issue{RepoId: repoId}, func(idx int, bean interface{}) error { | |||
| issue := bean.(*Issue) | |||
| if _, err = sess.Delete(&Comment{IssueId: issue.Id}); err != nil { | |||
| issues := make([]*Issue, 0, 25) | |||
| if err = sess.Where("repo_id=?", repoID).Find(&issues); err != nil { | |||
| return err | |||
| } | |||
| for i := range issues { | |||
| if _, err = sess.Delete(&Comment{IssueId: issues[i].Id}); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| }); err != nil { | |||
| return err | |||
| } | |||
| if _, err = sess.Delete(&Issue{RepoId: repoId}); err != nil { | |||
| if _, err = sess.Delete(&Issue{RepoId: repoID}); err != nil { | |||
| return err | |||
| } | |||
| if repo.IsFork { | |||
| if _, err = sess.Exec("UPDATE `repository` SET num_forks = num_forks - 1 WHERE id = ?", repo.ForkId); err != nil { | |||
| if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks-1 WHERE id=?", repo.ForkId); err != nil { | |||
| return err | |||
| } | |||
| } | |||
| if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", uid); err != nil { | |||
| if _, err = sess.Exec("UPDATE `user` SET num_repos=num_repos-1 WHERE id=?", uid); err != nil { | |||
| return err | |||
| } | |||
| // Remove repository files. | |||
| if err = os.RemoveAll(RepoPath(userName, repo.Name)); err != nil { | |||
| desc := fmt.Sprintf("Fail to delete repository files(%s/%s): %v", userName, repo.Name, err) | |||
| desc := fmt.Sprintf("delete repository files(%s/%s): %v", userName, repo.Name, err) | |||
| log.Warn(desc) | |||
| if err = CreateRepositoryNotice(desc); err != nil { | |||
| log.Error(4, "Fail to add notice: %v", err) | |||
| log.Error(4, "add notice: %v", err) | |||
| } | |||
| } | |||
| @@ -1328,33 +1322,21 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor | |||
| // Update owner team info and count. | |||
| t, err := u.getOwnerTeam(sess) | |||
| if err != nil { | |||
| return nil, fmt.Errorf("get owner team: %v", err) | |||
| } else if err = t.getMembers(sess); err != nil { | |||
| return nil, fmt.Errorf("get team members: %v", err) | |||
| } | |||
| for _, u := range t.Members { | |||
| if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { | |||
| return nil, fmt.Errorf("watch repository: %v", err) | |||
| } | |||
| } | |||
| t.RepoIds += "$" + com.ToStr(repo.Id) + "|" | |||
| t.NumRepos++ | |||
| if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { | |||
| return nil, err | |||
| return nil, fmt.Errorf("getOwnerTeam: %v", err) | |||
| } else if err = t.addRepository(sess, repo); err != nil { | |||
| return nil, fmt.Errorf("addRepository: %v", err) | |||
| } | |||
| } else { | |||
| if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { | |||
| return nil, fmt.Errorf("watch repository 2: %v", err) | |||
| return nil, fmt.Errorf("watchRepo: %v", err) | |||
| } | |||
| } | |||
| if err = newRepoAction(sess, u, repo); err != nil { | |||
| return nil, fmt.Errorf("new repository action: %v", err) | |||
| return nil, fmt.Errorf("newRepoAction: %v", err) | |||
| } | |||
| if _, err = sess.Exec("UPDATE `repository` SET num_forks = num_forks + 1 WHERE id = ?", oldRepo.Id); err != nil { | |||
| if _, err = sess.Exec("UPDATE `repository` SET num_forks=num_forks+1 WHERE id=?", oldRepo.Id); err != nil { | |||
| return nil, err | |||
| } | |||
| @@ -231,7 +231,7 @@ func (u *User) GetOrganizations() error { | |||
| u.Orgs = make([]*User, len(ous)) | |||
| for i, ou := range ous { | |||
| u.Orgs[i], err = GetUserById(ou.OrgId) | |||
| u.Orgs[i], err = GetUserById(ou.OrgID) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| @@ -860,7 +860,7 @@ func UpdateMentions(userNames []string, issueId int64) error { | |||
| } | |||
| for _, orgUser := range orgUsers { | |||
| tempIds = append(tempIds, orgUser.Id) | |||
| tempIds = append(tempIds, orgUser.ID) | |||
| } | |||
| ids = append(ids, tempIds...) | |||
| @@ -181,7 +181,7 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) { | |||
| org := ctx.Org.Organization | |||
| t := &models.Team{ | |||
| OrgId: org.Id, | |||
| OrgID: org.Id, | |||
| Name: form.TeamName, | |||
| Description: form.Description, | |||
| Authorize: auth, | |||
| @@ -8,7 +8,6 @@ import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "path" | |||
| "strings" | |||
| "time" | |||
| @@ -1 +1 @@ | |||
| 0.5.14.0222 Beta | |||
| 0.5.15.0223 Beta | |||