mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 00:11:04 +00:00 
			
		
		
		
	Merge pull request #959 from phsmit/access_update
Updating context and fixing permission issues
This commit is contained in:
		
				commit
				
					
						fc4dff1b17
					
				
			
		
					 10 changed files with 68 additions and 72 deletions
				
			
		| 
						 | 
					@ -319,7 +319,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			||||||
		m.Get("/template/*", dev.TemplatePreview)
 | 
							m.Get("/template/*", dev.TemplatePreview)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reqTrueOwner := middleware.RequireTrueOwner()
 | 
						reqAdmin := middleware.RequireAdmin()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Organization.
 | 
						// Organization.
 | 
				
			||||||
	m.Group("/org", func() {
 | 
						m.Group("/org", func() {
 | 
				
			||||||
| 
						 | 
					@ -394,7 +394,7 @@ func runWeb(ctx *cli.Context) {
 | 
				
			||||||
				m.Post("/:name", repo.GitHooksEditPost)
 | 
									m.Post("/:name", repo.GitHooksEditPost)
 | 
				
			||||||
			}, middleware.GitHookService())
 | 
								}, middleware.GitHookService())
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}, reqSignIn, middleware.RepoAssignment(true), reqTrueOwner)
 | 
						}, reqSignIn, middleware.RepoAssignment(true), reqAdmin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m.Group("/:username/:reponame", func() {
 | 
						m.Group("/:username/:reponame", func() {
 | 
				
			||||||
		m.Get("/action/:action", repo.Action)
 | 
							m.Get("/action/:action", repo.Action)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,15 +38,25 @@ type Context struct {
 | 
				
			||||||
	IsSigned    bool
 | 
						IsSigned    bool
 | 
				
			||||||
	IsBasicAuth bool
 | 
						IsBasicAuth bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Repo struct {
 | 
						Repo RepoContext
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Org struct {
 | 
				
			||||||
		IsOwner      bool
 | 
							IsOwner      bool
 | 
				
			||||||
		IsTrueOwner  bool
 | 
							IsMember     bool
 | 
				
			||||||
 | 
							IsAdminTeam  bool // In owner team or team that has admin permission level.
 | 
				
			||||||
 | 
							Organization *models.User
 | 
				
			||||||
 | 
							OrgLink      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Team *models.Team
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type RepoContext struct {
 | 
				
			||||||
 | 
						AccessMode   models.AccessMode
 | 
				
			||||||
	IsWatching   bool
 | 
						IsWatching   bool
 | 
				
			||||||
	IsBranch     bool
 | 
						IsBranch     bool
 | 
				
			||||||
	IsTag        bool
 | 
						IsTag        bool
 | 
				
			||||||
	IsCommit     bool
 | 
						IsCommit     bool
 | 
				
			||||||
		IsAdmin      bool // Current user is admin level.
 | 
					 | 
				
			||||||
		HasAccess    bool
 | 
					 | 
				
			||||||
	Repository   *models.Repository
 | 
						Repository   *models.Repository
 | 
				
			||||||
	Owner        *models.User
 | 
						Owner        *models.User
 | 
				
			||||||
	Commit       *git.Commit
 | 
						Commit       *git.Commit
 | 
				
			||||||
| 
						 | 
					@ -62,15 +72,14 @@ type Context struct {
 | 
				
			||||||
	Mirror       *models.Mirror
 | 
						Mirror       *models.Mirror
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Org struct {
 | 
					// Return if the current user has write access for this repository
 | 
				
			||||||
		IsOwner      bool
 | 
					func (r RepoContext) IsOwner() bool {
 | 
				
			||||||
		IsMember     bool
 | 
						return r.AccessMode >= models.ACCESS_MODE_WRITE
 | 
				
			||||||
		IsAdminTeam  bool // In owner team or team that has admin permission level.
 | 
					 | 
				
			||||||
		Organization *models.User
 | 
					 | 
				
			||||||
		OrgLink      string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Team *models.Team
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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.
 | 
					// HasError returns true if error occurs in form validation.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,24 +58,19 @@ func ApiRepoAssignment() macaron.Handler {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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.JSON(500, &base.ApiJsonErr{"AccessLevel: " + err.Error(), base.DOC_URL})
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
							ctx.Repo.AccessMode = mode
 | 
				
			||||||
			ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
					 | 
				
			||||||
			ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check access.
 | 
							// Check access.
 | 
				
			||||||
		if repo.IsPrivate && !ctx.Repo.IsOwner {
 | 
							if ctx.Repo.AccessMode == models.ACCESS_MODE_NONE {
 | 
				
			||||||
			ctx.Error(404)
 | 
								ctx.Error(404)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Repo.HasAccess = true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Repo.Repository = repo
 | 
							ctx.Repo.Repository = repo
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -239,26 +234,18 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ctx.IsSigned {
 | 
					 | 
				
			||||||
		mode, err := models.AccessLevel(ctx.User, repo)
 | 
							mode, err := models.AccessLevel(ctx.User, repo)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			ctx.Handle(500, "AccessLevel", err)
 | 
								ctx.Handle(500, "AccessLevel", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			ctx.Repo.IsOwner = mode >= models.ACCESS_MODE_WRITE
 | 
							ctx.Repo.AccessMode = mode
 | 
				
			||||||
			ctx.Repo.IsAdmin = mode >= models.ACCESS_MODE_READ
 | 
					 | 
				
			||||||
			ctx.Repo.IsTrueOwner = mode >= models.ACCESS_MODE_OWNER
 | 
					 | 
				
			||||||
			if !ctx.Repo.IsTrueOwner && ctx.Repo.Owner.IsOrganization() {
 | 
					 | 
				
			||||||
				ctx.Repo.IsTrueOwner = ctx.Repo.Owner.IsOwnedBy(ctx.User.Id)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Check access.
 | 
							// Check access.
 | 
				
			||||||
		if repo.IsPrivate && !ctx.Repo.IsOwner {
 | 
							if ctx.Repo.AccessMode == models.ACCESS_MODE_NONE {
 | 
				
			||||||
			ctx.Handle(404, "no access right", err)
 | 
								ctx.Handle(404, "no access right", err)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ctx.Repo.HasAccess = true
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Data["HasAccess"] = true
 | 
							ctx.Data["HasAccess"] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -306,8 +293,8 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			||||||
		ctx.Data["Title"] = u.Name + "/" + repo.Name
 | 
							ctx.Data["Title"] = u.Name + "/" + repo.Name
 | 
				
			||||||
		ctx.Data["Repository"] = repo
 | 
							ctx.Data["Repository"] = repo
 | 
				
			||||||
		ctx.Data["Owner"] = ctx.Repo.Repository.Owner
 | 
							ctx.Data["Owner"] = ctx.Repo.Repository.Owner
 | 
				
			||||||
		ctx.Data["IsRepositoryOwner"] = ctx.Repo.IsOwner
 | 
							ctx.Data["IsRepositoryOwner"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_WRITE
 | 
				
			||||||
		ctx.Data["IsRepositoryTrueOwner"] = ctx.Repo.IsTrueOwner
 | 
							ctx.Data["IsRepositoryAdmin"] = ctx.Repo.AccessMode >= models.ACCESS_MODE_ADMIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ctx.Data["DisableSSH"] = setting.DisableSSH
 | 
							ctx.Data["DisableSSH"] = setting.DisableSSH
 | 
				
			||||||
		ctx.Repo.CloneLink, err = repo.CloneLink()
 | 
							ctx.Repo.CloneLink, err = repo.CloneLink()
 | 
				
			||||||
| 
						 | 
					@ -362,9 +349,9 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RequireTrueOwner() macaron.Handler {
 | 
					func RequireAdmin() macaron.Handler {
 | 
				
			||||||
	return func(ctx *Context) {
 | 
						return func(ctx *Context) {
 | 
				
			||||||
		if !ctx.Repo.IsTrueOwner && !ctx.Repo.IsAdmin {
 | 
							if ctx.Repo.AccessMode < models.ACCESS_MODE_ADMIN {
 | 
				
			||||||
			if !ctx.IsSigned {
 | 
								if !ctx.IsSigned {
 | 
				
			||||||
				ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
 | 
									ctx.SetCookie("redirect_to", "/"+url.QueryEscape(setting.AppSubUrl+ctx.Req.RequestURI), 0, setting.AppSubUrl)
 | 
				
			||||||
				ctx.Redirect(setting.AppSubUrl + "/user/login")
 | 
									ctx.Redirect(setting.AppSubUrl + "/user/login")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@ import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func GetRepoRawFile(ctx *middleware.Context) {
 | 
					func GetRepoRawFile(ctx *middleware.Context) {
 | 
				
			||||||
	if ctx.Repo.Repository.IsPrivate && !ctx.Repo.HasAccess {
 | 
						if !ctx.Repo.HasAccess() {
 | 
				
			||||||
		ctx.Error(404)
 | 
							ctx.Error(404)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -230,7 +230,7 @@ func CreateIssuePost(ctx *middleware.Context, form auth.CreateIssueForm) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Only collaborators can assign.
 | 
						// Only collaborators can assign.
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		form.AssigneeId = 0
 | 
							form.AssigneeId = 0
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	issue := &models.Issue{
 | 
						issue := &models.Issue{
 | 
				
			||||||
| 
						 | 
					@ -434,7 +434,7 @@ func ViewIssue(ctx *middleware.Context) {
 | 
				
			||||||
	ctx.Data["Title"] = issue.Name
 | 
						ctx.Data["Title"] = issue.Name
 | 
				
			||||||
	ctx.Data["Issue"] = issue
 | 
						ctx.Data["Issue"] = issue
 | 
				
			||||||
	ctx.Data["Comments"] = comments
 | 
						ctx.Data["Comments"] = comments
 | 
				
			||||||
	ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner || (ctx.IsSigned && issue.PosterId == ctx.User.Id)
 | 
						ctx.Data["IsIssueOwner"] = ctx.Repo.IsOwner() || (ctx.IsSigned && issue.PosterId == ctx.User.Id)
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssues"] = true
 | 
						ctx.Data["IsRepoToolbarIssues"] = true
 | 
				
			||||||
	ctx.Data["IsRepoToolbarIssuesList"] = false
 | 
						ctx.Data["IsRepoToolbarIssuesList"] = false
 | 
				
			||||||
	ctx.HTML(200, ISSUE_VIEW)
 | 
						ctx.HTML(200, ISSUE_VIEW)
 | 
				
			||||||
| 
						 | 
					@ -457,7 +457,7 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ctx.User.Id != issue.PosterId && !ctx.Repo.IsOwner {
 | 
						if ctx.User.Id != issue.PosterId && !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Error(403)
 | 
							ctx.Error(403)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -484,7 +484,7 @@ func UpdateIssue(ctx *middleware.Context, form auth.CreateIssueForm) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UpdateIssueLabel(ctx *middleware.Context) {
 | 
					func UpdateIssueLabel(ctx *middleware.Context) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Error(403)
 | 
							ctx.Error(403)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -560,7 +560,7 @@ func UpdateIssueLabel(ctx *middleware.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UpdateIssueMilestone(ctx *middleware.Context) {
 | 
					func UpdateIssueMilestone(ctx *middleware.Context) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Error(403)
 | 
							ctx.Error(403)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -606,7 +606,7 @@ func UpdateIssueMilestone(ctx *middleware.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func UpdateAssignee(ctx *middleware.Context) {
 | 
					func UpdateAssignee(ctx *middleware.Context) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Error(403)
 | 
							ctx.Error(403)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -752,7 +752,7 @@ func Comment(ctx *middleware.Context) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check if issue owner changes the status of issue.
 | 
						// Check if issue owner changes the status of issue.
 | 
				
			||||||
	var newStatus string
 | 
						var newStatus string
 | 
				
			||||||
	if ctx.Repo.IsOwner || issue.PosterId == ctx.User.Id {
 | 
						if ctx.Repo.IsOwner() || issue.PosterId == ctx.User.Id {
 | 
				
			||||||
		newStatus = ctx.Query("change_status")
 | 
							newStatus = ctx.Query("change_status")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(newStatus) > 0 {
 | 
						if len(newStatus) > 0 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ func Releases(ctx *middleware.Context) {
 | 
				
			||||||
	tags := make([]*models.Release, len(rawTags))
 | 
						tags := make([]*models.Release, len(rawTags))
 | 
				
			||||||
	for i, rawTag := range rawTags {
 | 
						for i, rawTag := range rawTags {
 | 
				
			||||||
		for j, rel := range rels {
 | 
							for j, rel := range rels {
 | 
				
			||||||
			if rel == nil || (rel.IsDraft && !ctx.Repo.IsOwner) {
 | 
								if rel == nil || (rel.IsDraft && !ctx.Repo.IsOwner()) {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if rel.TagName == rawTag {
 | 
								if rel.TagName == rawTag {
 | 
				
			||||||
| 
						 | 
					@ -140,7 +140,7 @@ func Releases(ctx *middleware.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewRelease(ctx *middleware.Context) {
 | 
					func NewRelease(ctx *middleware.Context) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Handle(403, "release.ReleasesNew", nil)
 | 
							ctx.Handle(403, "release.ReleasesNew", nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -153,7 +153,7 @@ func NewRelease(ctx *middleware.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
 | 
					func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Handle(403, "release.ReleasesNew", nil)
 | 
							ctx.Handle(403, "release.ReleasesNew", nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,7 @@ func NewReleasePost(ctx *middleware.Context, form auth.NewReleaseForm) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EditRelease(ctx *middleware.Context) {
 | 
					func EditRelease(ctx *middleware.Context) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Handle(403, "release.ReleasesEdit", nil)
 | 
							ctx.Handle(403, "release.ReleasesEdit", nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -234,7 +234,7 @@ func EditRelease(ctx *middleware.Context) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func EditReleasePost(ctx *middleware.Context, form auth.EditReleaseForm) {
 | 
					func EditReleasePost(ctx *middleware.Context, form auth.EditReleaseForm) {
 | 
				
			||||||
	if !ctx.Repo.IsOwner {
 | 
						if !ctx.Repo.IsOwner() {
 | 
				
			||||||
		ctx.Handle(403, "release.EditReleasePost", nil)
 | 
							ctx.Handle(403, "release.EditReleasePost", nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,7 +343,7 @@ func Action(ctx *middleware.Context) {
 | 
				
			||||||
	case "unstar":
 | 
						case "unstar":
 | 
				
			||||||
		err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
 | 
							err = models.StarRepo(ctx.User.Id, ctx.Repo.Repository.Id, false)
 | 
				
			||||||
	case "desc":
 | 
						case "desc":
 | 
				
			||||||
		if !ctx.Repo.IsOwner {
 | 
							if !ctx.Repo.IsOwner() {
 | 
				
			||||||
			ctx.Error(404)
 | 
								ctx.Error(404)
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,7 +49,7 @@
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
            <li id="repo-header-fork">
 | 
					            <li id="repo-header-fork">
 | 
				
			||||||
                <a id="repo-header-fork-btn" {{if or (not $.IsRepositoryTrueOwner) $.Owner.IsOrganization}}href="{{AppSubUrl}}/repo/fork?fork_id={{.Id}}"{{end}}>
 | 
					                <a id="repo-header-fork-btn" {{if or (not $.IsRepositoryAdmin) $.Owner.IsOrganization}}href="{{AppSubUrl}}/repo/fork?fork_id={{.Id}}"{{end}}>
 | 
				
			||||||
                    <button class="btn btn-gray text-bold btn-radius">
 | 
					                    <button class="btn btn-gray text-bold btn-radius">
 | 
				
			||||||
                        <i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
 | 
					                        <i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
 | 
				
			||||||
                        <span class="num">{{.NumForks}}</span>
 | 
					                        <span class="num">{{.NumForks}}</span>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@
 | 
				
			||||||
        <!-- <li>
 | 
					        <!-- <li>
 | 
				
			||||||
            <a class="radius" href="#"><i class="octicon octicon-organization"></i>contributors <span class="num right label label-gray label-radius">43</span></a>
 | 
					            <a class="radius" href="#"><i class="octicon octicon-organization"></i>contributors <span class="num right label label-gray label-radius">43</span></a>
 | 
				
			||||||
        </li> -->
 | 
					        </li> -->
 | 
				
			||||||
        {{if .IsRepositoryTrueOwner}}
 | 
					        {{if .IsRepositoryAdmin}}
 | 
				
			||||||
        <li class="border-bottom"></li>
 | 
					        <li class="border-bottom"></li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
            <a class="radius" href="{{.RepoLink}}/settings"><i class="octicon octicon-tools"></i>{{.i18n.Tr "repo.settings"}}</a>
 | 
					            <a class="radius" href="{{.RepoLink}}/settings"><i class="octicon octicon-tools"></i>{{.i18n.Tr "repo.settings"}}</a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@
 | 
				
			||||||
                            <li><a href="#">Pulse</a></li>
 | 
					                            <li><a href="#">Pulse</a></li>
 | 
				
			||||||
                            <li><a href="#">Network</a></li>
 | 
					                            <li><a href="#">Network</a></li>
 | 
				
			||||||
                        </ul>
 | 
					                        </ul>
 | 
				
			||||||
                    </li> -->{{end}}{{if .IsRepositoryTrueOwner}}
 | 
					                    </li> -->{{end}}{{if .IsRepositoryAdmin}}
 | 
				
			||||||
                    <li class="{{if .IsRepoToolbarSetting}}active{{end}}"><a href="{{.RepoLink}}/settings">Settings</a>
 | 
					                    <li class="{{if .IsRepoToolbarSetting}}active{{end}}"><a href="{{.RepoLink}}/settings">Settings</a>
 | 
				
			||||||
                    </li>{{end}}
 | 
					                    </li>{{end}}
 | 
				
			||||||
                </ul>
 | 
					                </ul>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue