Browse Source

code fix #941 caution: undertest

pull/949/head
Unknwon 10 years ago
parent
commit
6d0f3a07d4
  1. 11
      cmd/serve.go
  2. 66
      models/access.go
  3. 42
      models/action.go
  4. 10
      models/models.go
  5. 110
      models/org.go
  6. 286
      models/repo.go
  7. 10
      models/user.go
  8. 16
      modules/middleware/repo.go
  9. 4
      routers/repo/http.go
  10. 7
      routers/user/home.go

11
cmd/serve.go

@ -83,16 +83,16 @@ func In(b string, sl map[string]models.AccessMode) bool {
return e return e
} }
func runServ(k *cli.Context) { func runServ(c *cli.Context) {
if k.IsSet("config") { if c.IsSet("config") {
setting.CustomConf = k.String("config") setting.CustomConf = c.String("config")
} }
setup("serv.log") setup("serv.log")
if len(k.Args()) < 1 { if len(c.Args()) < 1 {
log.GitLogger.Fatal(2, "Not enough arguments") log.GitLogger.Fatal(2, "Not enough arguments")
} }
keys := strings.Split(k.Args()[0], "-") keys := strings.Split(c.Args()[0], "-")
if len(keys) != 2 { if len(keys) != 2 {
println("Gogs: auth file format error") println("Gogs: auth file format error")
log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2]) log.GitLogger.Fatal(2, "Invalid auth file format: %s", os.Args[2])
@ -116,6 +116,7 @@ func runServ(k *cli.Context) {
cmd := os.Getenv("SSH_ORIGINAL_COMMAND") cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
if cmd == "" { if cmd == "" {
println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.") println("Hi", user.Name, "! You've successfully authenticated, but Gogs does not provide shell access.")
println("If this is what you do not expect, please log in with password and setup Gogs under another user.")
return return
} }

66
models/access.go

@ -14,16 +14,6 @@ const (
ACCESS_MODE_OWNER ACCESS_MODE_OWNER
) )
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 // 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 // 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. // repository, the members of the owners team are in this table.
@ -34,12 +24,6 @@ type Access struct {
Mode AccessMode Mode AccessMode
} }
// 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
}
// Return the Access a user has to a repository. Will return NoneAccess if the // Return the Access a user has to a repository. Will return NoneAccess if the
// user does not have access. User can be nil! // user does not have access. User can be nil!
func AccessLevel(u *User, r *Repository) (AccessMode, error) { func AccessLevel(u *User, r *Repository) (AccessMode, error) {
@ -63,6 +47,12 @@ func AccessLevel(u *User, r *Repository) (AccessMode, error) {
return mode, nil 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)
return testMode <= mode, err
}
// GetAccessibleRepositories finds all repositories where a user has access to, // GetAccessibleRepositories finds all repositories where a user has access to,
// besides his own. // besides his own.
func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) { func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
@ -88,12 +78,21 @@ func (u *User) GetAccessibleRepositories() (map[*Repository]AccessMode, error) {
return repos, nil return repos, nil
} }
// Recalculate all accesses for repository func maxAccessMode(modes ...AccessMode) AccessMode {
func (r *Repository) RecalcAccessSess() error { max := ACCESS_MODE_NONE
for _, mode := range modes {
if mode > max {
max = mode
}
}
return max
}
func (repo *Repository) recalculateAccesses(e Engine) error {
accessMap := make(map[int64]AccessMode, 20) accessMap := make(map[int64]AccessMode, 20)
// Give all collaborators write access // Give all collaborators write access
collaborators, err := r.GetCollaborators() collaborators, err := repo.getCollaborators(e)
if err != nil { if err != nil {
return err return err
} }
@ -101,20 +100,20 @@ func (r *Repository) RecalcAccessSess() error {
accessMap[c.Id] = ACCESS_MODE_WRITE accessMap[c.Id] = ACCESS_MODE_WRITE
} }
if err := r.GetOwner(); err != nil { if err := repo.getOwner(e); err != nil {
return err return err
} }
if r.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
if err = r.Owner.GetTeams(); err != nil { if err = repo.Owner.getTeams(e); err != nil {
return err return err
} }
for _, team := range r.Owner.Teams { for _, team := range repo.Owner.Teams {
if !(team.IsOwnerTeam() || team.HasRepository(r)) { if !(team.IsOwnerTeam() || team.HasRepository(repo)) {
continue continue
} }
if err = team.GetMembers(); err != nil { if err = team.getMembers(e); err != nil {
return err return err
} }
for _, u := range team.Members { for _, u := range team.Members {
@ -124,28 +123,35 @@ func (r *Repository) RecalcAccessSess() error {
} }
minMode := ACCESS_MODE_READ minMode := ACCESS_MODE_READ
if !r.IsPrivate { if !repo.IsPrivate {
minMode = ACCESS_MODE_WRITE minMode = ACCESS_MODE_WRITE
} }
newAccesses := make([]Access, 0, len(accessMap)) newAccesses := make([]Access, 0, len(accessMap))
for userID, mode := range accessMap { for userID, mode := range accessMap {
if userID == r.OwnerId || mode <= minMode { if userID == repo.OwnerId || mode <= minMode {
continue continue
} }
newAccesses = append(newAccesses, Access{UserID: userID, RepoID: r.Id, Mode: mode}) newAccesses = append(newAccesses, Access{
UserID: userID,
RepoID: repo.Id,
Mode: mode})
} }
// Delete old accesses for repository // Delete old accesses for repository
if _, err = x.Delete(&Access{RepoID: r.Id}); err != nil { if _, err = e.Delete(&Access{RepoID: repo.Id}); err != nil {
return err return err
} }
// And insert the new ones // And insert the new ones
if _, err = x.Insert(newAccesses); err != nil { if _, err = e.Insert(newAccesses); err != nil {
return err return err
} }
return nil return nil
}
// RecalculateAccesses recalculates all accesses for repository.
func (r *Repository) RecalculateAccesses() error {
return r.recalculateAccesses(x)
} }

42
models/action.go

@ -412,21 +412,29 @@ func CommitRepoAction(userId, repoUserId int64, userName, actEmail string,
return nil return nil
} }
// NewRepoAction adds new action for creating repository. func newRepoAction(e Engine, u *User, repo *Repository) (err error) {
func NewRepoAction(u *User, repo *Repository) (err error) { if err = notifyWatchers(e, &Action{
if err = NotifyWatchers(&Action{ActUserId: u.Id, ActUserName: u.Name, ActEmail: u.Email, ActUserId: u.Id,
OpType: CREATE_REPO, RepoId: repo.Id, RepoUserName: repo.Owner.Name, RepoName: repo.Name, ActUserName: u.Name,
IsPrivate: repo.IsPrivate}); err != nil { ActEmail: u.Email,
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name) OpType: CREATE_REPO,
return err RepoId: repo.Id,
RepoUserName: repo.Owner.Name,
RepoName: repo.Name,
IsPrivate: repo.IsPrivate}); err != nil {
return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.Id)
} }
log.Trace("action.NewRepoAction: %s/%s", u.Name, repo.Name) log.Trace("action.NewRepoAction: %s/%s", u.Name, repo.Name)
return err return err
} }
// TransferRepoAction adds new action for transferring repository. // NewRepoAction adds new action for creating repository.
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) { func NewRepoAction(u *User, repo *Repository) (err error) {
return newRepoAction(x, u, repo)
}
func transferRepoAction(e Engine, u, newUser *User, repo *Repository) (err error) {
action := &Action{ action := &Action{
ActUserId: u.Id, ActUserId: u.Id,
ActUserName: u.Name, ActUserName: u.Name,
@ -438,20 +446,24 @@ func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
IsPrivate: repo.IsPrivate, IsPrivate: repo.IsPrivate,
Content: path.Join(repo.Owner.LowerName, repo.LowerName), Content: path.Join(repo.Owner.LowerName, repo.LowerName),
} }
if err = NotifyWatchers(action); err != nil { if err = notifyWatchers(e, action); err != nil {
log.Error(4, "NotifyWatchers: %d/%s", u.Id, repo.Name) return fmt.Errorf("notify watchers '%d/%s'", u.Id, repo.Id)
return err
} }
// Remove watch for organization. // Remove watch for organization.
if repo.Owner.IsOrganization() { if repo.Owner.IsOrganization() {
if err = WatchRepo(repo.Owner.Id, repo.Id, false); err != nil { if err = watchRepo(e, repo.Owner.Id, repo.Id, false); err != nil {
log.Error(4, "WatchRepo", err) return fmt.Errorf("watch repository: %v", err)
} }
} }
log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name) log.Trace("action.TransferRepoAction: %s/%s", u.Name, repo.Name)
return err return nil
}
// TransferRepoAction adds new action for transferring repository.
func TransferRepoAction(u, newUser *User, repo *Repository) (err error) {
return transferRepoAction(x, u, newUser, repo)
} }
// GetFeeds returns action list of given user in given context. // GetFeeds returns action list of given user in given context.

10
models/models.go

@ -24,12 +24,22 @@ import (
type Engine interface { type Engine interface {
Delete(interface{}) (int64, error) Delete(interface{}) (int64, error)
Exec(string, ...interface{}) (sql.Result, error) Exec(string, ...interface{}) (sql.Result, error)
Find(interface{}, ...interface{}) error
Get(interface{}) (bool, error) Get(interface{}) (bool, error)
Insert(...interface{}) (int64, error) Insert(...interface{}) (int64, error)
InsertOne(interface{}) (int64, error)
Id(interface{}) *xorm.Session Id(interface{}) *xorm.Session
Sql(string, ...interface{}) *xorm.Session
Where(string, ...interface{}) *xorm.Session Where(string, ...interface{}) *xorm.Session
} }
func sessionRelease(sess *xorm.Session) {
if !sess.IsCommitedOrRollbacked {
sess.Rollback()
}
sess.Close()
}
var ( var (
x *xorm.Engine x *xorm.Engine
tables []interface{} tables []interface{}

110
models/org.go

@ -32,19 +32,31 @@ func (org *User) IsOrgMember(uid int64) bool {
return IsOrganizationMember(org.Id, uid) return IsOrganizationMember(org.Id, uid)
} }
func (org *User) getTeam(e Engine, name string) (*Team, error) {
return getTeam(e, org.Id, name)
}
// GetTeam returns named team of organization. // GetTeam returns named team of organization.
func (org *User) GetTeam(name string) (*Team, error) { func (org *User) GetTeam(name string) (*Team, error) {
return GetTeam(org.Id, name) return org.getTeam(x, name)
}
func (org *User) getOwnerTeam(e Engine) (*Team, error) {
return org.getTeam(e, OWNER_TEAM)
} }
// GetOwnerTeam returns owner team of organization. // GetOwnerTeam returns owner team of organization.
func (org *User) GetOwnerTeam() (*Team, error) { func (org *User) GetOwnerTeam() (*Team, error) {
return org.GetTeam(OWNER_TEAM) return org.getOwnerTeam(x)
}
func (org *User) getTeams(e Engine) error {
return e.Where("org_id=?", org.Id).Find(&org.Teams)
} }
// GetTeams returns all teams that belong to organization. // GetTeams returns all teams that belong to organization.
func (org *User) GetTeams() error { func (org *User) GetTeams() error {
return x.Where("org_id=?", org.Id).Find(&org.Teams) return org.getTeams(x)
} }
// GetMembers returns all members of organization. // GetMembers returns all members of organization.
@ -430,8 +442,7 @@ func (t *Team) IsMember(uid int64) bool {
return IsTeamMember(t.OrgId, t.Id, uid) return IsTeamMember(t.OrgId, t.Id, uid)
} }
// GetRepositories returns all repositories in team of organization. func (t *Team) getRepositories(e Engine) error {
func (t *Team) GetRepositories() error {
idStrs := strings.Split(t.RepoIds, "|") idStrs := strings.Split(t.RepoIds, "|")
t.Repos = make([]*Repository, 0, len(idStrs)) t.Repos = make([]*Repository, 0, len(idStrs))
for _, str := range idStrs { for _, str := range idStrs {
@ -442,7 +453,7 @@ func (t *Team) GetRepositories() error {
if id == 0 { if id == 0 {
continue continue
} }
repo, err := GetRepositoryById(id) repo, err := getRepositoryById(e, id)
if err != nil { if err != nil {
return err return err
} }
@ -451,10 +462,19 @@ func (t *Team) GetRepositories() error {
return nil return nil
} }
// GetRepositories returns all repositories in team of organization.
func (t *Team) GetRepositories() error {
return t.getRepositories(x)
}
func (t *Team) getMembers(e Engine) (err error) {
t.Members, err = getTeamMembers(e, t.Id)
return err
}
// GetMembers returns all members in team of organization. // GetMembers returns all members in team of organization.
func (t *Team) GetMembers() (err error) { func (t *Team) GetMembers() (err error) {
t.Members, err = GetTeamMembers(t.OrgId, t.Id) return t.getMembers(x)
return err
} }
// AddMember adds new member to team of organization. // AddMember adds new member to team of organization.
@ -483,7 +503,7 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
@ -491,26 +511,23 @@ func (t *Team) AddRepository(repo *Repository) (err error) {
t.NumRepos++ t.NumRepos++
t.RepoIds += idStr t.RepoIds += idStr
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return err return err
} }
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
sess.Rollback()
return err return err
} }
for _, u := range t.Members { for _, u := range t.Members {
if err = WatchRepo(u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
sess.Rollback()
return err return err
} }
} }
return sess.Commit() return sess.Commit()
} }
func (t *Team) HasRepository(r *Repository) bool { func (t *Team) HasRepository(repo *Repository) bool {
idStr := "$" + com.ToStr(r.Id) + "|" idStr := "$" + com.ToStr(repo.Id) + "|"
return strings.Contains(t.RepoIds, idStr) return strings.Contains(t.RepoIds, idStr)
} }
@ -533,7 +550,7 @@ func (t *Team) RemoveRepository(repoId int64) error {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
@ -541,18 +558,15 @@ func (t *Team) RemoveRepository(repoId int64) error {
t.NumRepos-- t.NumRepos--
t.RepoIds = strings.Replace(t.RepoIds, idStr, "", 1) t.RepoIds = strings.Replace(t.RepoIds, idStr, "", 1)
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return err return err
} }
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
sess.Rollback()
return err return err
} }
for _, u := range t.Members { for _, u := range t.Members {
if err = WatchRepo(u.Id, repo.Id, false); err != nil { if err = watchRepo(sess, u.Id, repo.Id, false); err != nil {
sess.Rollback()
return err return err
} }
} }
@ -601,13 +615,12 @@ func NewTeam(t *Team) error {
return sess.Commit() return sess.Commit()
} }
// GetTeam returns team by given team name and organization. func getTeam(e Engine, orgId int64, name string) (*Team, error) {
func GetTeam(orgId int64, name string) (*Team, error) {
t := &Team{ t := &Team{
OrgId: orgId, OrgId: orgId,
LowerName: strings.ToLower(name), LowerName: strings.ToLower(name),
} }
has, err := x.Get(t) has, err := e.Get(t)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
@ -616,6 +629,11 @@ func GetTeam(orgId int64, name string) (*Team, error) {
return t, nil return t, nil
} }
// GetTeam returns team by given team name and organization.
func GetTeam(orgId int64, name string) (*Team, error) {
return getTeam(x, orgId, name)
}
func getTeamById(e Engine, teamId int64) (*Team, error) { func getTeamById(e Engine, teamId int64) (*Team, error) {
t := new(Team) t := new(Team)
has, err := e.Id(teamId).Get(t) has, err := e.Id(teamId).Get(t)
@ -643,19 +661,19 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
// Update access for team members if needed. // Update access for team members if needed.
if authChanged { if authChanged {
if err = t.GetRepositories(); err != nil { if err = t.getRepositories(sess); err != nil {
return err return err
} }
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
return err return err
} }
} }
@ -663,7 +681,6 @@ func UpdateTeam(t *Team, authChanged bool) (err error) {
t.LowerName = strings.ToLower(t.Name) 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 {
sess.Rollback()
return err return err
} }
return sess.Commit() return sess.Commit()
@ -685,32 +702,29 @@ func DeleteTeam(t *Team) error {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
// Delete all accesses. // Delete all accesses.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
return err return err
} }
} }
// Delete team-user. // 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 {
sess.Rollback()
return err return err
} }
// Delete team. // Delete team.
if _, err = sess.Id(t.Id).Delete(new(Team)); err != nil { if _, err = sess.Id(t.Id).Delete(new(Team)); err != nil {
sess.Rollback()
return err return err
} }
// Update organization number of teams. // 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 return err
} }
@ -742,13 +756,17 @@ func IsTeamMember(orgId, teamId, uid int64) bool {
return isTeamMember(x, orgId, teamId, uid) return isTeamMember(x, orgId, teamId, uid)
} }
// GetTeamMembers returns all members in given team of organization. func getTeamMembers(e Engine, teamID int64) ([]*User, error) {
func GetTeamMembers(orgId, teamId int64) ([]*User, error) {
us := make([]*User, 0, 10) us := make([]*User, 0, 10)
err := x.Sql("SELECT * FROM `user` JOIN `team_user` ON `team_user`.`team_id` = ? AND `team_user`.`uid` = `user`.`id`", teamId).Find(&us) err := e.Sql("SELECT * FROM `user` JOIN `team_user` ON `team_user`.`team_id` = ? AND `team_user`.`uid` = `user`.`id`", teamID).Find(&us)
return us, err return us, err
} }
// GetTeamMembers returns all members in given team of organization.
func GetTeamMembers(teamID int64) ([]*User, error) {
return getTeamMembers(x, teamID)
}
func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) { func getUserTeams(e Engine, orgId, uid int64) ([]*Team, error) {
tus := make([]*TeamUser, 0, 5) tus := make([]*TeamUser, 0, 5)
if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil { if err := e.Where("uid=?", uid).And("org_id=?", orgId).Find(&tus); err != nil {
@ -796,7 +814,7 @@ func AddTeamMember(orgId, teamId, uid int64) error {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
@ -808,26 +826,21 @@ func AddTeamMember(orgId, teamId, uid int64) error {
} }
if _, err = sess.Insert(tu); err != nil { if _, err = sess.Insert(tu); err != nil {
sess.Rollback()
return err return err
} else if _, err = sess.Id(t.Id).Update(t); err != nil { } else if _, err = sess.Id(t.Id).Update(t); err != nil {
sess.Rollback()
return err return err
} }
// Give access to team repositories. // Give access to team repositories.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
sess.Rollback()
return err return err
} }
} }
// We make sure it exists before. // We make sure it exists before.
ou := new(OrgUser) ou := new(OrgUser)
_, err = sess.Where("uid=?", uid).And("org_id=?", orgId).Get(ou) if _, err = sess.Where("uid=?", uid).And("org_id=?", orgId).Get(ou); err != nil {
if err != nil {
sess.Rollback()
return err return err
} }
ou.NumTeams++ ou.NumTeams++
@ -835,7 +848,6 @@ func AddTeamMember(orgId, teamId, uid int64) error {
ou.IsOwner = true 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 {
sess.Rollback()
return err return err
} }
@ -860,12 +872,12 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
t.NumMembers-- t.NumMembers--
if err = t.GetRepositories(); err != nil { if err = t.getRepositories(e); err != nil {
return err return err
} }
// Get organization. // Get organization.
org, err := GetUserById(orgId) org, err := getUserById(e, orgId)
if err != nil { if err != nil {
return err return err
} }
@ -884,7 +896,7 @@ func removeTeamMember(e Engine, orgId, teamId, uid int64) error {
// Delete access to team repositories. // Delete access to team repositories.
for _, repo := range t.Repos { for _, repo := range t.Repos {
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(e); err != nil {
return err return err
} }
} }

286
models/repo.go

@ -167,13 +167,17 @@ type Repository struct {
Updated time.Time `xorm:"UPDATED"` Updated time.Time `xorm:"UPDATED"`
} }
func (repo *Repository) GetOwner() (err error) { func (repo *Repository) getOwner(e Engine) (err error) {
if repo.Owner == nil { if repo.Owner == nil {
repo.Owner, err = GetUserById(repo.OwnerId) repo.Owner, err = getUserById(e, repo.OwnerId)
} }
return err return err
} }
func (repo *Repository) GetOwner() (err error) {
return repo.getOwner(x)
}
func (repo *Repository) GetMirror() (err error) { func (repo *Repository) GetMirror() (err error) {
repo.Mirror, err = GetMirror(repo.Id) repo.Mirror, err = GetMirror(repo.Id)
return err return err
@ -403,7 +407,7 @@ func createUpdateHook(repoPath string) error {
} }
// InitRepository initializes README and .gitignore if needed. // InitRepository initializes README and .gitignore if needed.
func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLang, license string) error { func initRepository(e Engine, f string, u *User, repo *Repository, initReadme bool, repoLang, license string) error {
repoPath := RepoPath(u.Name, repo.Name) repoPath := RepoPath(u.Name, repo.Name)
// Create bare new repository. // Create bare new repository.
@ -493,12 +497,12 @@ func initRepository(f string, u *User, repo *Repository, initReadme bool, repoLa
if len(fileName) == 0 { if len(fileName) == 0 {
// Re-fetch the repository from database before updating it (else it would // Re-fetch the repository from database before updating it (else it would
// override changes that were done earlier with sql) // override changes that were done earlier with sql)
if repo, err = GetRepositoryById(repo.Id); err != nil { if repo, err = getRepositoryById(e, repo.Id); err != nil {
return err return err
} }
repo.IsBare = true repo.IsBare = true
repo.DefaultBranch = "master" repo.DefaultBranch = "master"
return UpdateRepository(repo) return updateRepository(e, repo)
} }
// Apply changes and commit. // Apply changes and commit.
@ -518,12 +522,6 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
return nil, ErrRepoAlreadyExist return nil, ErrRepoAlreadyExist
} }
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return nil, err
}
repo := &Repository{ repo := &Repository{
OwnerId: u.Id, OwnerId: u.Id,
Owner: u, Owner: u,
@ -533,8 +531,13 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
IsPrivate: private, IsPrivate: private,
} }
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return nil, err
}
if _, err = sess.Insert(repo); err != nil { if _, err = sess.Insert(repo); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
@ -544,15 +547,12 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
// Give access to all members in owner team. // Give access to all members in owner team.
if u.IsOrganization() { if u.IsOrganization() {
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
} }
if _, err = sess.Exec( if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
"UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
@ -561,63 +561,54 @@ func CreateRepository(u *User, name, desc, lang, license string, private, mirror
t.RepoIds += "$" + com.ToStr(repo.Id) + "|" t.RepoIds += "$" + com.ToStr(repo.Id) + "|"
t.NumRepos++ t.NumRepos++
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
} }
if err = sess.Commit(); err != nil {
return nil, err
}
if u.IsOrganization() { if u.IsOrganization() {
t, err := u.GetOwnerTeam() t, err := u.getOwnerTeam(sess)
if err != nil { if err != nil {
log.Error(4, "GetOwnerTeam: %v", err) return nil, fmt.Errorf("get owner team: %v", err)
} else { } else if err = t.getMembers(sess); err != nil {
if err = t.GetMembers(); err != nil { return nil, fmt.Errorf("get team members: %v", err)
log.Error(4, "GetMembers: %v", err) }
} else {
for _, u := range t.Members { for _, u := range t.Members {
if err = WatchRepo(u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo2: %v", err) return nil, fmt.Errorf("watch repository: %v", err)
}
}
} }
} }
} else { } else {
if err = WatchRepo(u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo3: %v", err) return nil, fmt.Errorf("watch repository 2: %v", err)
} }
} }
if err = NewRepoAction(u, repo); err != nil { if err = newRepoAction(sess, u, repo); err != nil {
log.Error(4, "NewRepoAction: %v", err) return nil, fmt.Errorf("new repository action: %v", err)
} }
// No need for init mirror. // No need for init mirror.
if mirror { if !mirror {
return repo, nil 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 {
repoPath := RepoPath(u.Name, repo.Name) log.Error(4, "initRepository: %v", err)
if err = initRepository(repoPath, u, repo, initReadme, lang, license); err != nil { return nil, fmt.Errorf(
if err2 := os.RemoveAll(repoPath); err2 != nil { "delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2)
log.Error(4, "initRepository: %v", err) }
return nil, fmt.Errorf( return nil, fmt.Errorf("initRepository: %v", err)
"delete repo directory %s/%s failed(2): %v", u.Name, repo.Name, err2)
} }
return nil, fmt.Errorf("initRepository: %v", err)
}
_, stderr, err := process.ExecDir(-1, _, stderr, err := process.ExecDir(-1,
repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath), repoPath, fmt.Sprintf("CreateRepository(git update-server-info): %s", repoPath),
"git", "update-server-info") "git", "update-server-info")
if err != nil { if err != nil {
return nil, errors.New("CreateRepository(git update-server-info): " + stderr) return nil, errors.New("CreateRepository(git update-server-info): " + stderr)
}
} }
return repo, nil return repo, sess.Commit()
} }
// CountRepositories returns number of repositories. // CountRepositories returns number of repositories.
@ -668,7 +659,7 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
} }
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sessionRelease(sess)
if err = sess.Begin(); err != nil { if err = sess.Begin(); err != nil {
return err return err
} }
@ -679,44 +670,28 @@ func TransferOwnership(u *User, newOwner string, repo *Repository) error {
repo.OwnerId = newUser.Id repo.OwnerId = newUser.Id
repo.Owner = newUser repo.Owner = newUser
if _, err := sess.Id(repo.Id).Update(repo); err != nil { if _, err := sess.Id(repo.Id).Update(repo); err != nil {
sess.Rollback()
return err return err
} }
// Update user repository number. // 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 = ?", newUser.Id); err != nil {
sess.Rollback()
return err return err
} } else if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil {
if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos - 1 WHERE id = ?", owner.Id); err != nil {
sess.Rollback()
return err return err
} } else if err = repo.recalculateAccesses(sess); err != nil {
if err = repo.RecalcAccessSess(); err != nil {
return err return err
} } else if err = watchRepo(sess, newUser.Id, repo.Id, true); err != nil {
// Change repository directory name.
if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
sess.Rollback()
return err return err
} } else if err = transferRepoAction(sess, u, newUser, repo); err != nil {
if err = sess.Commit(); err != nil {
return err return err
} }
if err = WatchRepo(newUser.Id, repo.Id, true); err != nil { // Change repository directory name.
log.Error(4, "WatchRepo", err) if err = os.Rename(RepoPath(owner.Name, repo.Name), RepoPath(newUser.Name, repo.Name)); err != nil {
}
if err = TransferRepoAction(u, newUser, repo); err != nil {
return err return err
} }
return nil return sess.Commit()
} }
// ChangeRepositoryName changes all corresponding setting from old repository name to new one. // ChangeRepositoryName changes all corresponding setting from old repository name to new one.
@ -732,7 +707,7 @@ func ChangeRepositoryName(userName, oldRepoName, newRepoName string) (err error)
return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName)) return os.Rename(RepoPath(userName, oldRepoName), RepoPath(userName, newRepoName))
} }
func UpdateRepository(repo *Repository) error { func updateRepository(e Engine, repo *Repository) error {
repo.LowerName = strings.ToLower(repo.Name) repo.LowerName = strings.ToLower(repo.Name)
if len(repo.Description) > 255 { if len(repo.Description) > 255 {
@ -741,10 +716,14 @@ func UpdateRepository(repo *Repository) error {
if len(repo.Website) > 255 { if len(repo.Website) > 255 {
repo.Website = repo.Website[:255] repo.Website = repo.Website[:255]
} }
_, err := x.Id(repo.Id).AllCols().Update(repo) _, err := e.Id(repo.Id).AllCols().Update(repo)
return err return err
} }
func UpdateRepository(repo *Repository) error {
return updateRepository(x, repo)
}
// DeleteRepository deletes a repository for a user or organization. // DeleteRepository deletes a repository for a user or organization.
func DeleteRepository(uid, repoId int64, userName string) error { func DeleteRepository(uid, repoId int64, userName string) error {
repo := &Repository{Id: repoId, OwnerId: uid} repo := &Repository{Id: repoId, OwnerId: uid}
@ -898,10 +877,9 @@ func GetRepositoryByName(uid int64, repoName string) (*Repository, error) {
return repo, err return repo, err
} }
// GetRepositoryById returns the repository by given id if exists. func getRepositoryById(e Engine, id int64) (*Repository, error) {
func GetRepositoryById(id int64) (*Repository, error) {
repo := &Repository{} repo := &Repository{}
has, err := x.Id(id).Get(repo) has, err := e.Id(id).Get(repo)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
@ -910,6 +888,11 @@ func GetRepositoryById(id int64) (*Repository, error) {
return repo, nil return repo, nil
} }
// GetRepositoryById returns the repository by given id if exists.
func GetRepositoryById(id int64) (*Repository, error) {
return getRepositoryById(x, id)
}
// GetRepositories returns a list of repositories of given user. // GetRepositories returns a list of repositories of given user.
func GetRepositories(uid int64, private bool) ([]*Repository, error) { func GetRepositories(uid int64, private bool) ([]*Repository, error) {
repos := make([]*Repository, 0, 10) repos := make([]*Repository, 0, 10)
@ -1096,38 +1079,43 @@ type Collaboration struct {
} }
// Add collaborator and accompanying access // Add collaborator and accompanying access
func (r *Repository) AddCollaborator(u *User) error { func (repo *Repository) AddCollaborator(u *User) error {
collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id} collaboration := &Collaboration{
RepoID: repo.Id,
UserID: u.Id,
}
has, err := x.Get(collaboration) has, err := x.Get(collaboration)
if err != nil { if err != nil {
return err return err
} } else if has {
if has {
return nil return nil
} }
if _, err = x.InsertOne(collaboration); err != nil { sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return err return err
} }
if err = r.GetOwner(); err != nil { if _, err = sess.InsertOne(collaboration); err != nil {
return err
} else if err = repo.recalculateAccesses(sess); err != nil {
return err return err
} }
return r.RecalcAccessSess() return sess.Commit()
} }
// GetCollaborators returns the collaborators for a repository func (repo *Repository) getCollaborators(e Engine) ([]*User, error) {
func (r *Repository) GetCollaborators() ([]*User, error) {
collaborations := make([]*Collaboration, 0) collaborations := make([]*Collaboration, 0)
if err := x.Find(&collaborations, &Collaboration{RepoID: r.Id}); err != nil { if err := e.Find(&collaborations, &Collaboration{RepoID: repo.Id}); err != nil {
return nil, err return nil, err
} }
users := make([]*User, len(collaborations)) users := make([]*User, len(collaborations))
for i, c := range collaborations { for i, c := range collaborations {
user, err := GetUserById(c.UserID) user, err := getUserById(e, c.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1136,15 +1124,31 @@ func (r *Repository) GetCollaborators() ([]*User, error) {
return users, nil 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 // Delete collaborator and accompanying access
func (r *Repository) DeleteCollaborator(u *User) error { func (repo *Repository) DeleteCollaborator(u *User) (err error) {
collaboration := &Collaboration{RepoID: r.Id, UserID: u.Id} 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 := x.Delete(collaboration); err != nil || has == 0 { if has, err := sess.Delete(collaboration); err != nil || has == 0 {
return err
} else if err = repo.recalculateAccesses(sess); err != nil {
return err return err
} }
return r.RecalcAccessSess() return sess.Commit()
} }
// __ __ __ .__ // __ __ __ .__
@ -1193,25 +1197,28 @@ func WatchRepo(uid, repoId int64, watch bool) (err error) {
return watchRepo(x, uid, repoId, watch) return watchRepo(x, uid, repoId, watch)
} }
// GetWatchers returns all watchers of given repository. func getWatchers(e Engine, rid int64) ([]*Watch, error) {
func GetWatchers(rid int64) ([]*Watch, error) {
watches := make([]*Watch, 0, 10) watches := make([]*Watch, 0, 10)
err := x.Find(&watches, &Watch{RepoId: rid}) err := e.Find(&watches, &Watch{RepoId: rid})
return watches, err return watches, err
} }
// NotifyWatchers creates batch of actions for every watcher. // GetWatchers returns all watchers of given repository.
func NotifyWatchers(act *Action) error { func GetWatchers(rid int64) ([]*Watch, error) {
return getWatchers(x, rid)
}
func notifyWatchers(e Engine, act *Action) error {
// Add feeds for user self and all watchers. // Add feeds for user self and all watchers.
watches, err := GetWatchers(act.RepoId) watches, err := getWatchers(e, act.RepoId)
if err != nil { if err != nil {
return errors.New("repo.NotifyWatchers(get watches): " + err.Error()) return fmt.Errorf("get watchers: %v", err)
} }
// Add feed for actioner. // Add feed for actioner.
act.UserId = act.ActUserId act.UserId = act.ActUserId
if _, err = x.InsertOne(act); err != nil { if _, err = e.InsertOne(act); err != nil {
return errors.New("repo.NotifyWatchers(create action): " + err.Error()) return fmt.Errorf("insert new actioner: %v", err)
} }
for i := range watches { for i := range watches {
@ -1221,13 +1228,18 @@ func NotifyWatchers(act *Action) error {
act.Id = 0 act.Id = 0
act.UserId = watches[i].UserId act.UserId = watches[i].UserId
if _, err = x.InsertOne(act); err != nil { if _, err = e.InsertOne(act); err != nil {
return errors.New("repo.NotifyWatchers(create action): " + err.Error()) return fmt.Errorf("insert new action: %v", err)
} }
} }
return nil return nil
} }
// NotifyWatchers creates batch of actions for every watcher.
func NotifyWatchers(act *Action) error {
return notifyWatchers(x, act)
}
// _________ __ // _________ __
// / _____// |______ _______ // / _____// |______ _______
// \_____ \\ __\__ \\_ __ \ // \_____ \\ __\__ \\_ __ \
@ -1296,12 +1308,6 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
} }
} }
sess := x.NewSession()
defer sess.Close()
if err = sess.Begin(); err != nil {
return nil, err
}
repo := &Repository{ repo := &Repository{
OwnerId: u.Id, OwnerId: u.Id,
Owner: u, Owner: u,
@ -1313,19 +1319,23 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
ForkId: oldRepo.Id, ForkId: oldRepo.Id,
} }
sess := x.NewSession()
defer sessionRelease(sess)
if err = sess.Begin(); err != nil {
return nil, err
}
if _, err = sess.Insert(repo); err != nil { if _, err = sess.Insert(repo); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
if err = repo.RecalcAccessSess(); err != nil { if err = repo.recalculateAccesses(sess); err != nil {
return nil, err return nil, err
} }
var t *Team // Owner team. var t *Team // Owner team.
if _, err = sess.Exec( if _, err = sess.Exec("UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
"UPDATE `user` SET num_repos = num_repos + 1 WHERE id = ?", u.Id); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
@ -1334,50 +1344,42 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
t.RepoIds += "$" + com.ToStr(repo.Id) + "|" t.RepoIds += "$" + com.ToStr(repo.Id) + "|"
t.NumRepos++ t.NumRepos++
if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil { if _, err = sess.Id(t.Id).AllCols().Update(t); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
} }
if u.IsOrganization() { if u.IsOrganization() {
t, err := u.GetOwnerTeam() t, err := u.getOwnerTeam(sess)
if err != nil { if err != nil {
log.Error(4, "GetOwnerTeam: %v", err) return nil, fmt.Errorf("get owner team: %v", err)
} else { } else {
if err = t.GetMembers(); err != nil { if err = t.getMembers(sess); err != nil {
log.Error(4, "GetMembers: %v", err) return nil, fmt.Errorf("get team members: %v", err)
} else { } else {
for _, u := range t.Members { for _, u := range t.Members {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo2: %v", err) return nil, fmt.Errorf("watch repository: %v", err)
} }
} }
} }
} }
} else { } else {
if err = watchRepo(sess, u.Id, repo.Id, true); err != nil { if err = watchRepo(sess, u.Id, repo.Id, true); err != nil {
log.Error(4, "WatchRepo3: %v", err) return nil, fmt.Errorf("watch repository 2: %v", err)
} }
} }
if err = NewRepoAction(u, repo); err != nil { if err = newRepoAction(sess, u, repo); err != nil {
log.Error(4, "NewRepoAction: %v", err) return nil, fmt.Errorf("new repository action: %v", err)
} }
if _, err = sess.Exec( if _, err = sess.Exec("UPDATE `repository` SET num_forks = num_forks + 1 WHERE id = ?", oldRepo.Id); err != nil {
"UPDATE `repository` SET num_forks = num_forks + 1 WHERE id = ?", oldRepo.Id); err != nil {
sess.Rollback()
return nil, err return nil, err
} }
oldRepoPath, err := oldRepo.RepoPath() oldRepoPath, err := oldRepo.RepoPath()
if err != nil { if err != nil {
sess.Rollback() return nil, fmt.Errorf("get old repository path: %v", err)
return nil, fmt.Errorf("fail to get repo path(%s): %v", oldRepo.Name, err)
}
if err = sess.Commit(); err != nil {
return nil, err
} }
repoPath := RepoPath(u.Name, repo.Name) repoPath := RepoPath(u.Name, repo.Name)
@ -1385,15 +1387,15 @@ func ForkRepository(u *User, oldRepo *Repository, name, desc string) (*Repositor
fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name), fmt.Sprintf("ForkRepository(git clone): %s/%s", u.Name, repo.Name),
"git", "clone", "--bare", oldRepoPath, repoPath) "git", "clone", "--bare", oldRepoPath, repoPath)
if err != nil { if err != nil {
return nil, errors.New("ForkRepository(git clone): " + stderr) return nil, fmt.Errorf("git clone: %v", stderr)
} }
_, stderr, err = process.ExecDir(-1, _, stderr, err = process.ExecDir(-1,
repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath), repoPath, fmt.Sprintf("ForkRepository(git update-server-info): %s", repoPath),
"git", "update-server-info") "git", "update-server-info")
if err != nil { if err != nil {
return nil, errors.New("ForkRepository(git update-server-info): " + stderr) return nil, fmt.Errorf("git update-server-info: %v", err)
} }
return repo, nil return repo, sess.Commit()
} }

10
models/user.go

@ -521,10 +521,9 @@ func GetUserByKeyId(keyId int64) (*User, error) {
return user, nil return user, nil
} }
// GetUserById returns the user object by given ID if exists. func getUserById(e Engine, id int64) (*User, error) {
func GetUserById(id int64) (*User, error) {
u := new(User) u := new(User)
has, err := x.Id(id).Get(u) has, err := e.Id(id).Get(u)
if err != nil { if err != nil {
return nil, err return nil, err
} else if !has { } else if !has {
@ -533,6 +532,11 @@ func GetUserById(id int64) (*User, error) {
return u, nil return u, nil
} }
// GetUserById returns the user object by given ID if exists.
func GetUserById(id int64) (*User, error) {
return getUserById(x, id)
}
// GetUserByName returns user by given name. // GetUserByName returns user by given name.
func GetUserByName(name string) (*User, error) { func GetUserByName(name string) (*User, error) {
if len(name) == 0 { if len(name) == 0 {

16
modules/middleware/repo.go

@ -28,7 +28,7 @@ func ApiRepoAssignment() macaron.Handler {
err error err error
) )
// Check if the user is the same as the repository owner // Check if the user is the same as the repository owner.
if ctx.IsSigned && u.LowerName == strings.ToLower(userName) { if ctx.IsSigned && u.LowerName == strings.ToLower(userName) {
u = ctx.User u = ctx.User
} else { } else {
@ -216,9 +216,9 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
u, err = models.GetUserByName(userName) u, err = models.GetUserByName(userName)
if err != nil { if err != nil {
if err == models.ErrUserNotExist { if err == models.ErrUserNotExist {
ctx.Error(404) ctx.Handle(404, "GetUserByName", err)
} else { } else {
ctx.JSON(500, &base.ApiJsonErr{"GetUserByName: " + err.Error(), base.DOC_URL}) ctx.Handle(500, "GetUserByName", err)
} }
return return
} }
@ -229,20 +229,20 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
repo, err := models.GetRepositoryByName(u.Id, repoName) repo, err := models.GetRepositoryByName(u.Id, repoName)
if err != nil { if err != nil {
if err == models.ErrRepoNotExist { if err == models.ErrRepoNotExist {
ctx.Error(404) ctx.Handle(404, "GetRepositoryByName", err)
} else { } else {
ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL}) ctx.Handle(500, "GetRepositoryByName", err)
} }
return return
} else if err = repo.GetOwner(); err != nil { } else if err = repo.GetOwner(); err != nil {
ctx.JSON(500, &base.ApiJsonErr{"GetOwner: " + err.Error(), base.DOC_URL}) ctx.Handle(500, "GetOwner", err)
return return
} }
if ctx.IsSigned { if ctx.IsSigned {
mode, err := models.AccessLevel(ctx.User, repo) mode, err := models.AccessLevel(ctx.User, repo)
if err != nil { if err != nil {
ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL}) ctx.Handle(500, "AccessLevel", err)
return return
} }
ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
@ -252,7 +252,7 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
// Check access. // Check access.
if repo.IsPrivate && !ctx.Repo.IsOwner { if repo.IsPrivate && !ctx.Repo.IsOwner {
ctx.Error(404) ctx.Handle(404, "no access right", err)
return return
} }
ctx.Repo.HasAccess = true ctx.Repo.HasAccess = true

4
routers/repo/http.go

@ -288,7 +288,7 @@ func serviceRpc(rpc string, hr handler) {
access := hasAccess(r, hr.Config, dir, rpc, true) access := hasAccess(r, hr.Config, dir, rpc, true)
if access == false { if access == false {
renderACCESS_MODE_NONE(w) renderNoAccess(w)
return return
} }
@ -515,7 +515,7 @@ func renderNotFound(w http.ResponseWriter) {
w.Write([]byte("Not Found")) w.Write([]byte("Not Found"))
} }
func renderACCESS_MODE_NONE(w http.ResponseWriter) { func renderNoAccess(w http.ResponseWriter) {
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
w.Write([]byte("Forbidden")) w.Write([]byte("Forbidden"))
} }

7
routers/user/home.go

@ -210,8 +210,11 @@ func Profile(ctx *middleware.Context) {
if !ctx.IsSigned { if !ctx.IsSigned {
continue continue
} }
if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true}, if has, _ := models.HasAccess(ctx.User,
models.ACCESS_MODE_READ); !has { &models.Repository{
Id: act.RepoId,
IsPrivate: true,
}, models.ACCESS_MODE_READ); !has {
continue continue
} }
} }

Loading…
Cancel
Save