mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-31 11:52:10 +00:00
Merge branch 'access' of github.com:gogits/gogs into dev
This commit is contained in:
commit
b0b11fd7b1
36 changed files with 1385 additions and 1320 deletions
|
@ -164,7 +164,7 @@ var TemplateFuncs template.FuncMap = map[string]interface{}{
|
|||
},
|
||||
"DiffTypeToStr": DiffTypeToStr,
|
||||
"DiffLineTypeToStr": DiffLineTypeToStr,
|
||||
"Sha1": Sha1,
|
||||
"Sha1": Sha1,
|
||||
"ShortSha": ShortSha,
|
||||
"Md5": EncodeMd5,
|
||||
"ActionContent2Commits": ActionContent2Commits,
|
||||
|
|
|
@ -38,29 +38,7 @@ type Context struct {
|
|||
IsSigned bool
|
||||
IsBasicAuth bool
|
||||
|
||||
Repo struct {
|
||||
IsOwner bool
|
||||
IsTrueOwner bool
|
||||
IsWatching bool
|
||||
IsBranch bool
|
||||
IsTag bool
|
||||
IsCommit bool
|
||||
IsAdmin bool // Current user is admin level.
|
||||
HasAccess bool
|
||||
Repository *models.Repository
|
||||
Owner *models.User
|
||||
Commit *git.Commit
|
||||
Tag *git.Tag
|
||||
GitRepo *git.Repository
|
||||
BranchName string
|
||||
TagName string
|
||||
TreeName string
|
||||
CommitId string
|
||||
RepoLink string
|
||||
CloneLink models.CloneLink
|
||||
CommitsCount int
|
||||
Mirror *models.Mirror
|
||||
}
|
||||
Repo RepoContext
|
||||
|
||||
Org struct {
|
||||
IsOwner bool
|
||||
|
@ -73,6 +51,37 @@ type Context struct {
|
|||
}
|
||||
}
|
||||
|
||||
type RepoContext struct {
|
||||
AccessMode models.AccessMode
|
||||
IsWatching bool
|
||||
IsBranch bool
|
||||
IsTag bool
|
||||
IsCommit bool
|
||||
Repository *models.Repository
|
||||
Owner *models.User
|
||||
Commit *git.Commit
|
||||
Tag *git.Tag
|
||||
GitRepo *git.Repository
|
||||
BranchName string
|
||||
TagName string
|
||||
TreeName string
|
||||
CommitId string
|
||||
RepoLink string
|
||||
CloneLink models.CloneLink
|
||||
CommitsCount int
|
||||
Mirror *models.Mirror
|
||||
}
|
||||
|
||||
// Return if the current user has write access for this repository
|
||||
func (r RepoContext) IsOwner() bool {
|
||||
return r.AccessMode >= models.ACCESS_MODE_WRITE
|
||||
}
|
||||
|
||||
// Return if the current user has read access for this repository
|
||||
func (r RepoContext) HasAccess() bool {
|
||||
return r.AccessMode >= models.ACCESS_MODE_READ
|
||||
}
|
||||
|
||||
// HasError returns true if error occurs in form validation.
|
||||
func (ctx *Context) HasApiError() bool {
|
||||
hasErr, ok := ctx.Data["HasError"]
|
||||
|
|
|
@ -87,7 +87,7 @@ func OrgAssignment(redirect bool, args ...bool) macaron.Handler {
|
|||
return
|
||||
}
|
||||
ctx.Data["Team"] = ctx.Org.Team
|
||||
ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize == models.ORG_ADMIN
|
||||
ctx.Org.IsAdminTeam = ctx.Org.Team.IsOwnerTeam() || ctx.Org.Team.Authorize >= models.ACCESS_MODE_ADMIN
|
||||
}
|
||||
ctx.Data["IsAdminTeam"] = ctx.Org.IsAdminTeam
|
||||
if requireAdminTeam && !ctx.Org.IsAdminTeam {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
@ -29,17 +28,10 @@ func ApiRepoAssignment() macaron.Handler {
|
|||
err error
|
||||
)
|
||||
|
||||
// Collaborators who have write access can be seen as owners.
|
||||
if ctx.IsSigned {
|
||||
ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
|
||||
if err != nil {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"HasAccess: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
}
|
||||
ctx.Repo.IsTrueOwner = ctx.User.LowerName == strings.ToLower(userName)
|
||||
}
|
||||
|
||||
if !ctx.Repo.IsTrueOwner {
|
||||
// Check if the user is the same as the repository owner.
|
||||
if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) {
|
||||
u = ctx.User
|
||||
} else {
|
||||
u, err = models.GetUserByName(userName)
|
||||
if err != nil {
|
||||
if err == models.ErrUserNotExist {
|
||||
|
@ -49,66 +41,36 @@ func ApiRepoAssignment() macaron.Handler {
|
|||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
u = ctx.User
|
||||
}
|
||||
ctx.Repo.Owner = u
|
||||
|
||||
// Organization owner team members are true owners as well.
|
||||
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
|
||||
ctx.Repo.IsTrueOwner = true
|
||||
}
|
||||
|
||||
// Get repository.
|
||||
repo, err := models.GetRepositoryByName(u.Id, repoName)
|
||||
if err != nil {
|
||||
if err == models.ErrRepoNotExist {
|
||||
ctx.Error(404)
|
||||
return
|
||||
} else {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL})
|
||||
}
|
||||
ctx.JSON(500, &base.ApiJsonErr{"GetRepositoryByName: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
} else if err = repo.GetOwner(); err != nil {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"GetOwner: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the mirror repository owner(mirror repository doesn't have access).
|
||||
if ctx.IsSigned && !ctx.Repo.IsOwner {
|
||||
if repo.OwnerId == ctx.User.Id {
|
||||
ctx.Repo.IsOwner = true
|
||||
}
|
||||
// Check if current user has admin permission to repository.
|
||||
if u.IsOrganization() {
|
||||
auth, err := models.GetHighestAuthorize(u.Id, ctx.User.Id, repo.Id, 0)
|
||||
if err != nil {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"GetHighestAuthorize: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
}
|
||||
if auth == models.ORG_ADMIN {
|
||||
ctx.Repo.IsOwner = true
|
||||
ctx.Repo.IsAdmin = true
|
||||
}
|
||||
}
|
||||
mode, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Repo.AccessMode = mode
|
||||
|
||||
// Check access.
|
||||
if repo.IsPrivate && !ctx.Repo.IsOwner {
|
||||
if ctx.User == nil {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
|
||||
if err != nil {
|
||||
ctx.JSON(500, &base.ApiJsonErr{"HasAccess: " + err.Error(), base.DOC_URL})
|
||||
return
|
||||
} else if !hasAccess {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
if ctx.Repo.AccessMode == models.ACCESS_MODE_NONE {
|
||||
ctx.Error(404)
|
||||
return
|
||||
}
|
||||
ctx.Repo.HasAccess = true
|
||||
|
||||
ctx.Repo.Repository = repo
|
||||
}
|
||||
|
@ -242,101 +204,49 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
|||
refName = ctx.Params(":path")
|
||||
}
|
||||
|
||||
// Collaborators who have write access can be seen as owners.
|
||||
if ctx.IsSigned {
|
||||
ctx.Repo.IsOwner, err = models.HasAccess(ctx.User.Name, userName+"/"+repoName, models.WRITABLE)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "HasAccess", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.IsTrueOwner = ctx.User.LowerName == strings.ToLower(userName)
|
||||
}
|
||||
|
||||
if !ctx.Repo.IsTrueOwner {
|
||||
// Check if the user is the same as the repository owner
|
||||
if ctx.IsSigned && ctx.User.LowerName == strings.ToLower(userName) {
|
||||
u = ctx.User
|
||||
} else {
|
||||
u, err = models.GetUserByName(userName)
|
||||
if err != nil {
|
||||
if err == models.ErrUserNotExist {
|
||||
ctx.Handle(404, "GetUserByName", err)
|
||||
} else if redirect {
|
||||
log.Error(4, "GetUserByName", err)
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
} else {
|
||||
ctx.Handle(500, "GetUserByName", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
u = ctx.User
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
if redirect {
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
}
|
||||
ctx.Handle(404, "RepoAssignment", errors.New("invliad user account for single repository"))
|
||||
return
|
||||
}
|
||||
ctx.Repo.Owner = u
|
||||
|
||||
// Organization owner team members are true owners as well.
|
||||
if ctx.IsSigned && ctx.Repo.Owner.IsOrganization() && ctx.Repo.Owner.IsOwnedBy(ctx.User.Id) {
|
||||
ctx.Repo.IsTrueOwner = true
|
||||
}
|
||||
|
||||
// Get repository.
|
||||
repo, err := models.GetRepositoryByName(u.Id, repoName)
|
||||
if err != nil {
|
||||
if err == models.ErrRepoNotExist {
|
||||
ctx.Handle(404, "GetRepositoryByName", err)
|
||||
return
|
||||
} else if redirect {
|
||||
ctx.Redirect(setting.AppSubUrl + "/")
|
||||
return
|
||||
} else {
|
||||
ctx.Handle(500, "GetRepositoryByName", err)
|
||||
}
|
||||
ctx.Handle(500, "GetRepositoryByName", err)
|
||||
return
|
||||
} else if err = repo.GetOwner(); err != nil {
|
||||
ctx.Handle(500, "GetOwner", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the mirror repository owner(mirror repository doesn't have access).
|
||||
if ctx.IsSigned && !ctx.Repo.IsOwner {
|
||||
if repo.OwnerId == ctx.User.Id {
|
||||
ctx.Repo.IsOwner = true
|
||||
}
|
||||
// Check if current user has admin permission to repository.
|
||||
if u.IsOrganization() {
|
||||
auth, err := models.GetHighestAuthorize(u.Id, ctx.User.Id, repo.Id, 0)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "GetHighestAuthorize", err)
|
||||
return
|
||||
}
|
||||
if auth == models.ORG_ADMIN {
|
||||
ctx.Repo.IsOwner = true
|
||||
ctx.Repo.IsAdmin = true
|
||||
}
|
||||
}
|
||||
mode, err := models.AccessLevel(ctx.User, repo)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "AccessLevel", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.AccessMode = mode
|
||||
|
||||
// Check access.
|
||||
if repo.IsPrivate && !ctx.Repo.IsOwner {
|
||||
if ctx.User == nil {
|
||||
ctx.Handle(404, "HasAccess", nil)
|
||||
return
|
||||
}
|
||||
|
||||
hasAccess, err := models.HasAccess(ctx.User.Name, ctx.Repo.Owner.Name+"/"+repo.Name, models.READABLE)
|
||||
if err != nil {
|
||||
ctx.Handle(500, "HasAccess", err)
|
||||
return
|
||||
} else if !hasAccess {
|
||||
ctx.Handle(404, "HasAccess", nil)
|
||||
return
|
||||
}
|
||||
if ctx.Repo.AccessMode == models.ACCESS_MODE_NONE {
|
||||
ctx.Handle(404, "no access right", err)
|
||||
return
|
||||
}
|
||||
ctx.Repo.HasAccess = true
|
||||
|
||||
ctx.Data["HasAccess"] = true
|
||||
|
||||
if repo.IsMirror {
|
||||
|
@ -383,8 +293,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
|||
ctx.Data["Title"] = u.Name + "/" + repo.Name
|
||||
ctx.Data["Repository"] = repo
|
||||
ctx.Data["Owner"] = ctx.Repo.Repository.Owner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
|
||||
ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner
|
||||
ctx.Data["IsRepositoryOwner"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_WRITE
|
||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_ADMIN
|
||||
|
||||
ctx.Data["DisableSSH"] = setting.DisableSSH
|
||||
ctx.Repo.CloneLink, err = repo.CloneLink()
|
||||
|
@ -438,9 +348,9 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
|
|||
}
|
||||
}
|
||||
|
||||
func RequireTrueOwner() macaron.Handler {
|
||||
func RequireAdmin() macaron.Handler {
|
||||
return func(ctx *Context) {
|
||||
if !ctx.Repo.IsTrueOwner && !ctx.Repo.IsAdmin {
|
||||
if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN {
|
||||
if !ctx.IsSigned {
|
||||
ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
|
||||
ctx.Redirect(setting.AppSubUrl + "/user/login")
|
||||
|
|
|
@ -67,6 +67,11 @@ var (
|
|||
CookieRememberName string
|
||||
ReverseProxyAuthUser string
|
||||
|
||||
// Database settings.
|
||||
UseSQLite3 bool
|
||||
UseMySQL bool
|
||||
UsePostgreSQL bool
|
||||
|
||||
// Webhook settings.
|
||||
Webhook struct {
|
||||
TaskInterval int
|
||||
|
@ -267,10 +272,6 @@ func NewConfigContext() {
|
|||
"StampNano": time.StampNano,
|
||||
}[Cfg.Section("time").Key("FORMAT").MustString("RFC1123")]
|
||||
|
||||
if err = os.MkdirAll(AttachmentPath, os.ModePerm); err != nil {
|
||||
log.Fatal(4, "Could not create directory %s: %s", AttachmentPath, err)
|
||||
}
|
||||
|
||||
RunUser = Cfg.Section("").Key("RUN_USER").String()
|
||||
curUser := os.Getenv("USER")
|
||||
if len(curUser) == 0 {
|
||||
|
@ -293,9 +294,6 @@ func NewConfigContext() {
|
|||
} else {
|
||||
RepoRootPath = filepath.Clean(RepoRootPath)
|
||||
}
|
||||
if err = os.MkdirAll(RepoRootPath, os.ModePerm); err != nil {
|
||||
log.Fatal(4, "Fail to create repository root path(%s): %v", RepoRootPath, err)
|
||||
}
|
||||
ScriptType = sec.Key("SCRIPT_TYPE").MustString("bash")
|
||||
|
||||
sec = Cfg.Section("picture")
|
||||
|
@ -304,7 +302,6 @@ func NewConfigContext() {
|
|||
if !filepath.IsAbs(AvatarUploadPath) {
|
||||
AvatarUploadPath = path.Join(workDir, AvatarUploadPath)
|
||||
}
|
||||
os.MkdirAll(AvatarUploadPath, os.ModePerm)
|
||||
switch sec.Key("GRAVATAR_SOURCE").MustString("gravatar") {
|
||||
case "duoshuo":
|
||||
GravatarSource = "http://gravatar.duoshuo.com/avatar/"
|
||||
|
@ -369,9 +366,11 @@ func newLogService() {
|
|||
log.Fatal(4, "Unknown log mode: %s", mode)
|
||||
}
|
||||
|
||||
validLevels := []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"}
|
||||
// Log level.
|
||||
levelName := Cfg.Section("log."+mode).Key("LEVEL").In("Trace",
|
||||
[]string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
|
||||
levelName := Cfg.Section("log."+mode).Key("LEVEL").In(
|
||||
Cfg.Section("log").Key("LEVEL").In("Trace", validLevels),
|
||||
validLevels)
|
||||
level, ok := logLevels[levelName]
|
||||
if !ok {
|
||||
log.Fatal(4, "Unknown log level: %s", levelName)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue