mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Merge remote-tracking branch 'mine/access_refactor' into access_refactor
Conflicts: cmd/serve.go models/access.go models/migrations/migrations.go models/org.go models/repo.go models/user.go modules/middleware/org.go modules/middleware/repo.go routers/api/v1/repo.go routers/org/teams.go routers/repo/http.go routers/user/home.go
This commit is contained in:
		
							
								
								
									
										14
									
								
								cmd/serve.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								cmd/serve.go
									
									
									
									
									
								
							@@ -67,14 +67,14 @@ func parseCmd(cmd string) (string, string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	COMMANDS_READONLY = map[string]models.AccessMode{
 | 
						COMMANDS_READONLY = map[string]models.AccessMode{
 | 
				
			||||||
		"git-upload-pack":    models.WriteAccess,
 | 
							"git-upload-pack":    models.ACCESS_MODE_WRITE,
 | 
				
			||||||
		"git upload-pack":    models.WriteAccess,
 | 
							"git upload-pack":    models.ACCESS_MODE_WRITE,
 | 
				
			||||||
		"git-upload-archive": models.WriteAccess,
 | 
							"git-upload-archive": models.ACCESS_MODE_WRITE,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	COMMANDS_WRITE = map[string]models.AccessMode{
 | 
						COMMANDS_WRITE = map[string]models.AccessMode{
 | 
				
			||||||
		"git-receive-pack": models.ReadAccess,
 | 
							"git-receive-pack": models.ACCESS_MODE_READ,
 | 
				
			||||||
		"git receive-pack": models.ReadAccess,
 | 
							"git receive-pack": models.ACCESS_MODE_READ,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -155,7 +155,7 @@ func runServ(k *cli.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case isWrite:
 | 
						case isWrite:
 | 
				
			||||||
		has, err := models.HasAccess(user, repo, models.WriteAccess)
 | 
							has, err := models.HasAccess(user, repo, models.ACCESS_MODE_WRITE)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			println("Gogs: internal error:", err.Error())
 | 
								println("Gogs: internal error:", err.Error())
 | 
				
			||||||
			log.GitLogger.Fatal(2, "Fail to check write access:", err)
 | 
								log.GitLogger.Fatal(2, "Fail to check write access:", err)
 | 
				
			||||||
@@ -168,7 +168,7 @@ func runServ(k *cli.Context) {
 | 
				
			|||||||
			break
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		has, err := models.HasAccess(user, repo, models.ReadAccess)
 | 
							has, err := models.HasAccess(user, repo, models.ACCESS_MODE_READ)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			println("Gogs: internal error:", err.Error())
 | 
								println("Gogs: internal error:", err.Error())
 | 
				
			||||||
			log.GitLogger.Fatal(2, "Fail to check read access:", err)
 | 
								log.GitLogger.Fatal(2, "Fail to check read access:", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,15 +7,15 @@ package models
 | 
				
			|||||||
type AccessMode int
 | 
					type AccessMode int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	NoAccess AccessMode = iota
 | 
						ACCESS_MODE_NONE AccessMode = iota
 | 
				
			||||||
	ReadAccess
 | 
						ACCESS_MODE_READ
 | 
				
			||||||
	WriteAccess
 | 
						ACCESS_MODE_WRITE
 | 
				
			||||||
	AdminAccess
 | 
						ACCESS_MODE_ADMIN
 | 
				
			||||||
	OwnerAccess
 | 
						ACCESS_MODE_OWNER
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func maxAccessMode(modes ...AccessMode) AccessMode {
 | 
					func maxAccessMode(modes ...AccessMode) AccessMode {
 | 
				
			||||||
	max := NoAccess
 | 
						max := ACCESS_MODE_NONE
 | 
				
			||||||
	for _, mode := range modes {
 | 
						for _, mode := range modes {
 | 
				
			||||||
		if mode > max {
 | 
							if mode > max {
 | 
				
			||||||
			max = mode
 | 
								max = mode
 | 
				
			||||||
@@ -43,14 +43,14 @@ func HasAccess(u *User, r *Repository, testMode AccessMode) (bool, error) {
 | 
				
			|||||||
// 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) {
 | 
				
			||||||
	mode := NoAccess
 | 
						mode := ACCESS_MODE_NONE
 | 
				
			||||||
	if !r.IsPrivate {
 | 
						if !r.IsPrivate {
 | 
				
			||||||
		mode = ReadAccess
 | 
							mode = ACCESS_MODE_READ
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if u != nil {
 | 
						if u != nil {
 | 
				
			||||||
		if u.Id == r.OwnerId {
 | 
							if u.Id == r.OwnerId {
 | 
				
			||||||
			return OwnerAccess, nil
 | 
								return ACCESS_MODE_OWNER, nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		a := &Access{UserID: u.Id, RepoID: r.Id}
 | 
							a := &Access{UserID: u.Id, RepoID: r.Id}
 | 
				
			||||||
@@ -98,7 +98,7 @@ func (r *Repository) RecalcAccessSess() error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, c := range collaborators {
 | 
						for _, c := range collaborators {
 | 
				
			||||||
		accessMap[c.Id] = WriteAccess
 | 
							accessMap[c.Id] = ACCESS_MODE_WRITE
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := r.GetOwner(); err != nil {
 | 
						if err := r.GetOwner(); err != nil {
 | 
				
			||||||
@@ -123,9 +123,9 @@ func (r *Repository) RecalcAccessSess() error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	minMode := ReadAccess
 | 
						minMode := ACCESS_MODE_READ
 | 
				
			||||||
	if !r.IsPrivate {
 | 
						if !r.IsPrivate {
 | 
				
			||||||
		minMode = WriteAccess
 | 
							minMode = ACCESS_MODE_WRITE
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newAccesses := make([]Access, 0, len(accessMap))
 | 
						newAccesses := make([]Access, 0, len(accessMap))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -134,7 +134,7 @@ func CreateOrganization(org, owner *User) (*User, error) {
 | 
				
			|||||||
		OrgId:      org.Id,
 | 
							OrgId:      org.Id,
 | 
				
			||||||
		LowerName:  strings.ToLower(OWNER_TEAM),
 | 
							LowerName:  strings.ToLower(OWNER_TEAM),
 | 
				
			||||||
		Name:       OWNER_TEAM,
 | 
							Name:       OWNER_TEAM,
 | 
				
			||||||
		Authorize:  OwnerAccess,
 | 
							Authorize:  ACCESS_MODE_OWNER,
 | 
				
			||||||
		NumMembers: 1,
 | 
							NumMembers: 1,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, err = sess.Insert(t); err != nil {
 | 
						if _, err = sess.Insert(t); err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -395,6 +395,7 @@ func ChangeUserName(u *User, newUserName string) (err error) {
 | 
				
			|||||||
	if !IsLegalName(newUserName) {
 | 
						if !IsLegalName(newUserName) {
 | 
				
			||||||
		return ErrUserNameIllegal
 | 
							return ErrUserNameIllegal
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return os.Rename(UserPath(u.LowerName), UserPath(newUserName))
 | 
						return os.Rename(UserPath(u.LowerName), UserPath(newUserName))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,7 +87,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx.Data["Team"] = ctx.Org.Team
 | 
								ctx.Data["Team"] = ctx.Org.Team
 | 
				
			||||||
			ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.AdminAccess
 | 
								ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.ACCESS_MODE_ADMIN
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
							ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
 | 
				
			||||||
		if requireAdminTeam && !ctx.Org.IsAdminTeam {
 | 
							if requireAdminTeam && !ctx.Org.IsAdminTeam {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -64,9 +64,10 @@ func ApiRepoAssignment() macaron.Handler {
 | 
				
			|||||||
				ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
									ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx.Repo.IsOwner = mode >= models.WriteAccess
 | 
					
 | 
				
			||||||
			ctx.Repo.IsAdmin = mode >= models.ReadAccess
 | 
								ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
				
			||||||
			ctx.Repo.IsTrueOwner = mode >= models.OwnerAccess
 | 
								ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
				
			||||||
 | 
								ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check access.
 | 
							// Check access.
 | 
				
			||||||
@@ -244,9 +245,9 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			|||||||
				ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
									ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ctx.Repo.IsOwner = mode >= models.WriteAccess
 | 
								ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
				
			||||||
			ctx.Repo.IsAdmin = mode >= models.ReadAccess
 | 
								ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
				
			||||||
			ctx.Repo.IsTrueOwner = mode >= models.OwnerAccess
 | 
								ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check access.
 | 
							// Check access.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -255,7 +255,7 @@ func ListMyRepos(ctx *middleware.Context) {
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		repos[i] = ToApiRepository(repo.Owner, repo, api.Permission{false, access >= models.WriteAccess, true})
 | 
							repos[i] = ToApiRepository(repo.Owner, repo, api.Permission{false, access >= models.ACCESS_MODE_WRITE, true})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// FIXME: cache result to reduce DB query?
 | 
							// FIXME: cache result to reduce DB query?
 | 
				
			||||||
		if repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
							if repo.Owner.IsOrganization() && repo.Owner.IsOwnedBy(ctx.User.Id) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -168,11 +168,11 @@ func NewTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			|||||||
	var auth models.AccessMode
 | 
						var auth models.AccessMode
 | 
				
			||||||
	switch form.Permission {
 | 
						switch form.Permission {
 | 
				
			||||||
	case "read":
 | 
						case "read":
 | 
				
			||||||
		auth = models.ReadAccess
 | 
							auth = models.ACCESS_MODE_READ
 | 
				
			||||||
	case "write":
 | 
						case "write":
 | 
				
			||||||
		auth = models.WriteAccess
 | 
							auth = models.ACCESS_MODE_WRITE
 | 
				
			||||||
	case "admin":
 | 
						case "admin":
 | 
				
			||||||
		auth = models.AdminAccess
 | 
							auth = models.ACCESS_MODE_ADMIN
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		ctx.Error(401)
 | 
							ctx.Error(401)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -249,11 +249,11 @@ func EditTeamPost(ctx *middleware.Context, form auth.CreateTeamForm) {
 | 
				
			|||||||
		var auth models.AccessMode
 | 
							var auth models.AccessMode
 | 
				
			||||||
		switch form.Permission {
 | 
							switch form.Permission {
 | 
				
			||||||
		case "read":
 | 
							case "read":
 | 
				
			||||||
			auth = models.ReadAccess
 | 
								auth = models.ACCESS_MODE_READ
 | 
				
			||||||
		case "write":
 | 
							case "write":
 | 
				
			||||||
			auth = models.WriteAccess
 | 
								auth = models.ACCESS_MODE_WRITE
 | 
				
			||||||
		case "admin":
 | 
							case "admin":
 | 
				
			||||||
			auth = models.AdminAccess
 | 
								auth = models.ACCESS_MODE_ADMIN
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			ctx.Error(401)
 | 
								ctx.Error(401)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -137,9 +137,9 @@ func Http(ctx *middleware.Context) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if !isPublicPull {
 | 
							if !isPublicPull {
 | 
				
			||||||
			var tp = models.WriteAccess
 | 
								var tp = models.ACCESS_MODE_WRITE
 | 
				
			||||||
			if isPull {
 | 
								if isPull {
 | 
				
			||||||
				tp = models.ReadAccess
 | 
									tp = models.ACCESS_MODE_READ
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			has, err := models.HasAccess(authUser, repo, tp)
 | 
								has, err := models.HasAccess(authUser, repo, tp)
 | 
				
			||||||
@@ -147,8 +147,8 @@ func Http(ctx *middleware.Context) {
 | 
				
			|||||||
				ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
									ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			} else if !has {
 | 
								} else if !has {
 | 
				
			||||||
				if tp == models.ReadAccess {
 | 
									if tp == models.ACCESS_MODE_READ {
 | 
				
			||||||
					has, err = models.HasAccess(authUser, repo, models.WriteAccess)
 | 
										has, err = models.HasAccess(authUser, repo, models.ACCESS_MODE_WRITE)
 | 
				
			||||||
					if err != nil || !has {
 | 
										if err != nil || !has {
 | 
				
			||||||
						ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
											ctx.Handle(401, "no basic auth and digit auth", nil)
 | 
				
			||||||
						return
 | 
											return
 | 
				
			||||||
@@ -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 {
 | 
				
			||||||
		renderNoAccess(w)
 | 
							renderACCESS_MODE_NONE(w)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -515,7 +515,7 @@ func renderNotFound(w http.ResponseWriter) {
 | 
				
			|||||||
	w.Write([]byte("Not Found"))
 | 
						w.Write([]byte("Not Found"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func renderNoAccess(w http.ResponseWriter) {
 | 
					func renderACCESS_MODE_NONE(w http.ResponseWriter) {
 | 
				
			||||||
	w.WriteHeader(http.StatusForbidden)
 | 
						w.WriteHeader(http.StatusForbidden)
 | 
				
			||||||
	w.Write([]byte("Forbidden"))
 | 
						w.Write([]byte("Forbidden"))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,7 @@ func Dashboard(ctx *middleware.Context) {
 | 
				
			|||||||
	feeds := make([]*models.Action, 0, len(actions))
 | 
						feeds := make([]*models.Action, 0, len(actions))
 | 
				
			||||||
	for _, act := range actions {
 | 
						for _, act := range actions {
 | 
				
			||||||
		if act.IsPrivate {
 | 
							if act.IsPrivate {
 | 
				
			||||||
			if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true}, models.ReadAccess); !has {
 | 
								if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true}, models.ACCESS_MODE_READ); !has {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -211,7 +211,7 @@ func Profile(ctx *middleware.Context) {
 | 
				
			|||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true},
 | 
									if has, _ := models.HasAccess(ctx.User, &models.Repository{Id: act.RepoId, IsPrivate: true},
 | 
				
			||||||
					models.ReadAccess); !has {
 | 
										models.ACCESS_MODE_READ); !has {
 | 
				
			||||||
					continue
 | 
										continue
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user