2014-03-15 20:03:23 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2017-09-12 09:48:13 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2014-03-15 20:03:23 +04:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2016-03-11 19:56:52 +03:00
package context
2014-03-15 20:03:23 +04:00
import (
2014-03-20 08:12:33 +04:00
"fmt"
2016-08-12 03:07:09 +03:00
"io/ioutil"
2015-10-31 19:04:04 +03:00
"path"
2014-03-17 12:47:42 +04:00
"strings"
2014-03-16 10:28:24 +04:00
2016-11-11 15:11:45 +03:00
"code.gitea.io/git"
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
2016-11-11 15:11:45 +03:00
"github.com/Unknwon/com"
2017-09-12 09:48:13 +03:00
"gopkg.in/editorconfig/editorconfig-core-go.v1"
"gopkg.in/macaron.v1"
2014-03-15 20:03:23 +04:00
)
2016-11-25 09:51:01 +03:00
// PullRequest contains informations to make a pull request
2016-03-14 00:37:44 +03:00
type PullRequest struct {
BaseRepo * models . Repository
Allowed bool
SameRepo bool
HeadInfo string // [<user>:]<branch>
}
2017-03-15 03:52:01 +03:00
// Repository contains information to operate a repository
2016-03-14 00:37:44 +03:00
type Repository struct {
AccessMode models . AccessMode
IsWatching bool
IsViewBranch bool
IsViewTag bool
IsViewCommit bool
Repository * models . Repository
Owner * models . User
Commit * git . Commit
Tag * git . Tag
GitRepo * git . Repository
BranchName string
TagName string
2016-08-25 07:35:03 +03:00
TreePath string
2016-03-14 00:37:44 +03:00
CommitID string
RepoLink string
CloneLink models . CloneLink
CommitsCount int64
Mirror * models . Mirror
2016-08-30 12:08:38 +03:00
PullRequest * PullRequest
2016-03-14 00:37:44 +03:00
}
// IsOwner returns true if current user is the owner of repository.
func ( r * Repository ) IsOwner ( ) bool {
2016-11-07 19:20:37 +03:00
return r . AccessMode >= models . AccessModeOwner
2016-03-14 00:37:44 +03:00
}
// IsAdmin returns true if current user has admin or higher access of repository.
func ( r * Repository ) IsAdmin ( ) bool {
2016-11-07 19:20:37 +03:00
return r . AccessMode >= models . AccessModeAdmin
2016-03-14 00:37:44 +03:00
}
// IsWriter returns true if current user has write or higher access of repository.
func ( r * Repository ) IsWriter ( ) bool {
2016-11-07 19:20:37 +03:00
return r . AccessMode >= models . AccessModeWrite
2016-03-14 00:37:44 +03:00
}
// HasAccess returns true if the current user has at least read access for this repository
func ( r * Repository ) HasAccess ( ) bool {
2016-11-07 19:20:37 +03:00
return r . AccessMode >= models . AccessModeRead
2016-03-14 00:37:44 +03:00
}
2016-08-30 12:08:38 +03:00
// CanEnableEditor returns true if repository is editable and user has proper access level.
func ( r * Repository ) CanEnableEditor ( ) bool {
return r . Repository . CanEnableEditor ( ) && r . IsViewBranch && r . IsWriter ( )
}
2017-05-02 03:49:55 +03:00
// CanCommitToBranch returns true if repository is editable and user has proper access level
// and branch is not protected
2017-09-14 11:16:22 +03:00
func ( r * Repository ) CanCommitToBranch ( doer * models . User ) ( bool , error ) {
protectedBranch , err := r . Repository . IsProtectedBranch ( r . BranchName , doer )
2017-05-02 03:49:55 +03:00
if err != nil {
return false , err
}
return r . CanEnableEditor ( ) && ! protectedBranch , nil
}
2017-09-12 09:48:13 +03:00
// CanUseTimetracker returns whether or not a user can use the timetracker.
func ( r * Repository ) CanUseTimetracker ( issue * models . Issue , user * models . User ) bool {
// Checking for following:
// 1. Is timetracker enabled
// 2. Is the user a contributor, admin, poster or assignee and do the repository policies require this?
return r . Repository . IsTimetrackerEnabled ( ) && ( ! r . Repository . AllowOnlyContributorsToTrackTime ( ) ||
r . IsWriter ( ) || issue . IsPoster ( user . ID ) || issue . AssigneeID == user . ID )
}
2016-08-12 03:07:09 +03:00
// GetEditorconfig returns the .editorconfig definition if found in the
// HEAD of the default repo branch.
func ( r * Repository ) GetEditorconfig ( ) ( * editorconfig . Editorconfig , error ) {
commit , err := r . GitRepo . GetBranchCommit ( r . Repository . DefaultBranch )
if err != nil {
return nil , err
}
treeEntry , err := commit . GetTreeEntryByPath ( ".editorconfig" )
if err != nil {
return nil , err
}
reader , err := treeEntry . Blob ( ) . Data ( )
if err != nil {
return nil , err
}
data , err := ioutil . ReadAll ( reader )
if err != nil {
return nil , err
}
return editorconfig . ParseBytes ( data )
}
2016-11-25 09:51:01 +03:00
// RetrieveBaseRepo retrieves base repository
2015-09-01 18:43:53 +03:00
func RetrieveBaseRepo ( ctx * Context , repo * models . Repository ) {
// Non-fork repository will not return error in this method.
if err := repo . GetBaseRepo ( ) ; err != nil {
if models . IsErrRepoNotExist ( err ) {
repo . IsFork = false
repo . ForkID = 0
return
}
ctx . Handle ( 500 , "GetBaseRepo" , err )
return
} else if err = repo . BaseRepo . GetOwner ( ) ; err != nil {
ctx . Handle ( 500 , "BaseRepo.GetOwner" , err )
return
}
}
2017-09-23 16:24:24 +03:00
// ComposeGoGetImport returns go-get-import meta content.
func ComposeGoGetImport ( owner , repo string ) string {
2016-11-27 13:14:25 +03:00
return path . Join ( setting . Domain , setting . AppSubURL , owner , repo )
2016-08-08 00:29:16 +03:00
}
2017-09-23 16:24:24 +03:00
// EarlyResponseForGoGetMeta responses appropriate go-get meta with status 200
2016-08-08 00:29:16 +03:00
// if user does not have actual access to the requested repository,
// or the owner or repository does not exist at all.
// This is particular a workaround for "go get" command which does not respect
// .netrc file.
2017-09-23 16:24:24 +03:00
func EarlyResponseForGoGetMeta ( ctx * Context ) {
username := ctx . Params ( ":username" )
reponame := ctx . Params ( ":reponame" )
2016-08-08 00:29:16 +03:00
ctx . PlainText ( 200 , [ ] byte ( com . Expand ( ` <meta name="go-import" content=" { GoGetImport} git { CloneLink}"> ` ,
map [ string ] string {
2017-09-23 16:24:24 +03:00
"GoGetImport" : ComposeGoGetImport ( username , strings . TrimSuffix ( reponame , ".git" ) ) ,
"CloneLink" : models . ComposeHTTPSCloneURL ( username , reponame ) ,
2016-08-08 00:29:16 +03:00
} ) ) )
}
2017-02-05 17:35:03 +03:00
// RedirectToRepo redirect to a differently-named repository
func RedirectToRepo ( ctx * Context , redirectRepoID int64 ) {
ownerName := ctx . Params ( ":username" )
previousRepoName := ctx . Params ( ":reponame" )
repo , err := models . GetRepositoryByID ( redirectRepoID )
if err != nil {
ctx . Handle ( 500 , "GetRepositoryByID" , err )
return
}
redirectPath := strings . Replace (
ctx . Req . URL . Path ,
fmt . Sprintf ( "%s/%s" , ownerName , previousRepoName ) ,
fmt . Sprintf ( "%s/%s" , ownerName , repo . Name ) ,
1 ,
)
ctx . Redirect ( redirectPath )
}
2017-09-19 14:44:49 +03:00
2017-09-18 17:52:20 +03:00
// RepoIDAssignment returns an macaron handler which assigns the repo to the context.
func RepoIDAssignment ( ) macaron . Handler {
return func ( ctx * Context ) {
var (
2017-09-19 14:44:49 +03:00
err error
2017-09-18 17:52:20 +03:00
)
repoID := ctx . ParamsInt64 ( ":repoid" )
// Get repository.
repo , err := models . GetRepositoryByID ( repoID )
if err != nil {
if models . IsErrRepoNotExist ( err ) {
ctx . Handle ( 404 , "GetRepositoryByID" , nil )
} else {
ctx . Handle ( 500 , "GetRepositoryByID" , err )
}
return
}
if err = repo . GetOwner ( ) ; err != nil {
ctx . Handle ( 500 , "GetOwner" , err )
return
}
// Admin has super access.
if ctx . IsSigned && ctx . User . IsAdmin {
ctx . Repo . AccessMode = models . AccessModeOwner
} else {
var userID int64
if ctx . User != nil {
userID = ctx . User . ID
}
mode , err := models . AccessLevel ( userID , repo )
if err != nil {
ctx . Handle ( 500 , "AccessLevel" , err )
return
}
ctx . Repo . AccessMode = mode
}
// Check access.
if ctx . Repo . AccessMode == models . AccessModeNone {
if ctx . Query ( "go-get" ) == "1" {
2017-09-23 16:24:24 +03:00
EarlyResponseForGoGetMeta ( ctx )
2017-09-18 17:52:20 +03:00
return
}
ctx . Handle ( 404 , "no access right" , err )
return
}
ctx . Data [ "HasAccess" ] = true
if repo . IsMirror {
ctx . Repo . Mirror , err = models . GetMirrorByRepoID ( repo . ID )
if err != nil {
ctx . Handle ( 500 , "GetMirror" , err )
return
}
ctx . Data [ "MirrorEnablePrune" ] = ctx . Repo . Mirror . EnablePrune
ctx . Data [ "MirrorInterval" ] = ctx . Repo . Mirror . Interval
ctx . Data [ "Mirror" ] = ctx . Repo . Mirror
}
ctx . Repo . Repository = repo
ctx . Data [ "RepoName" ] = ctx . Repo . Repository . Name
ctx . Data [ "IsBareRepo" ] = ctx . Repo . Repository . IsBare
}
}
2017-02-05 17:35:03 +03:00
2016-11-25 09:51:01 +03:00
// RepoAssignment returns a macaron to handle repository assignment
2017-03-18 13:59:07 +03:00
func RepoAssignment ( ) macaron . Handler {
2014-07-26 08:24:27 +04:00
return func ( ctx * Context ) {
2014-03-15 20:03:23 +04:00
var (
2015-10-31 19:04:04 +03:00
owner * models . User
err error
2014-03-15 20:03:23 +04:00
)
2014-07-26 08:24:27 +04:00
userName := ctx . Params ( ":username" )
repoName := ctx . Params ( ":reponame" )
2014-03-30 06:09:59 +04:00
2015-02-05 16:29:08 +03:00
// Check if the user is the same as the repository owner
2015-02-13 10:14:57 +03:00
if ctx . IsSigned && ctx . User . LowerName == strings . ToLower ( userName ) {
2015-10-31 19:04:04 +03:00
owner = ctx . User
2015-02-05 16:29:08 +03:00
} else {
2015-10-31 19:04:04 +03:00
owner , err = models . GetUserByName ( userName )
2014-03-15 20:03:23 +04:00
if err != nil {
2015-08-05 06:14:17 +03:00
if models . IsErrUserNotExist ( err ) {
2016-08-08 00:29:16 +03:00
if ctx . Query ( "go-get" ) == "1" {
2017-09-23 16:24:24 +03:00
EarlyResponseForGoGetMeta ( ctx )
2016-08-08 00:29:16 +03:00
return
}
2017-08-19 15:32:18 +03:00
ctx . Handle ( 404 , "GetUserByName" , nil )
2014-08-14 10:12:21 +04:00
} else {
2015-02-13 08:58:46 +03:00
ctx . Handle ( 500 , "GetUserByName" , err )
2014-03-15 20:03:23 +04:00
}
return
}
}
2015-10-31 19:04:04 +03:00
ctx . Repo . Owner = owner
2016-08-30 12:08:38 +03:00
ctx . Data [ "Username" ] = ctx . Repo . Owner . Name
2014-03-15 20:03:23 +04:00
2014-08-24 17:09:05 +04:00
// Get repository.
2016-07-23 20:08:22 +03:00
repo , err := models . GetRepositoryByName ( owner . ID , repoName )
2014-03-15 20:03:23 +04:00
if err != nil {
2015-03-16 11:04:27 +03:00
if models . IsErrRepoNotExist ( err ) {
2017-02-05 17:35:03 +03:00
redirectRepoID , err := models . LookupRepoRedirect ( owner . ID , repoName )
if err == nil {
RedirectToRepo ( ctx , redirectRepoID )
} else if models . IsErrRepoRedirectNotExist ( err ) {
if ctx . Query ( "go-get" ) == "1" {
2017-09-23 16:24:24 +03:00
EarlyResponseForGoGetMeta ( ctx )
2017-02-05 17:35:03 +03:00
return
}
2017-08-19 15:32:18 +03:00
ctx . Handle ( 404 , "GetRepositoryByName" , nil )
2017-02-05 17:35:03 +03:00
} else {
ctx . Handle ( 500 , "LookupRepoRedirect" , err )
2016-08-08 00:29:16 +03:00
}
2015-02-05 16:29:08 +03:00
} else {
2015-02-13 08:58:46 +03:00
ctx . Handle ( 500 , "GetRepositoryByName" , err )
2014-03-15 20:03:23 +04:00
}
2014-07-26 08:24:27 +04:00
return
2014-03-30 06:09:59 +04:00
}
2017-02-02 15:33:56 +03:00
repo . Owner = owner
2014-04-12 05:47:39 +04:00
2015-11-19 03:49:11 +03:00
// Admin has super access.
2015-11-19 19:40:00 +03:00
if ctx . IsSigned && ctx . User . IsAdmin {
2016-11-07 19:20:37 +03:00
ctx . Repo . AccessMode = models . AccessModeOwner
2015-11-19 03:49:11 +03:00
} else {
2017-03-15 05:13:54 +03:00
var userID int64
if ctx . User != nil {
userID = ctx . User . ID
}
mode , err := models . AccessLevel ( userID , repo )
2015-11-19 03:49:11 +03:00
if err != nil {
ctx . Handle ( 500 , "AccessLevel" , err )
return
}
ctx . Repo . AccessMode = mode
2014-05-14 03:26:13 +04:00
}
2014-04-12 05:47:39 +04:00
// Check access.
2016-11-07 19:20:37 +03:00
if ctx . Repo . AccessMode == models . AccessModeNone {
2016-08-08 00:29:16 +03:00
if ctx . Query ( "go-get" ) == "1" {
2017-09-23 16:24:24 +03:00
EarlyResponseForGoGetMeta ( ctx )
2016-08-08 00:29:16 +03:00
return
}
2015-02-13 08:58:46 +03:00
ctx . Handle ( 404 , "no access right" , err )
2015-02-05 16:29:08 +03:00
return
2014-04-12 05:47:39 +04:00
}
ctx . Data [ "HasAccess" ] = true
2014-04-13 06:30:00 +04:00
if repo . IsMirror {
2016-08-31 02:18:33 +03:00
ctx . Repo . Mirror , err = models . GetMirrorByRepoID ( repo . ID )
2014-04-13 06:30:00 +04:00
if err != nil {
2014-07-26 08:24:27 +04:00
ctx . Handle ( 500 , "GetMirror" , err )
2014-04-13 06:30:00 +04:00
return
}
2016-07-09 08:22:28 +03:00
ctx . Data [ "MirrorEnablePrune" ] = ctx . Repo . Mirror . EnablePrune
2014-04-13 06:30:00 +04:00
ctx . Data [ "MirrorInterval" ] = ctx . Repo . Mirror . Interval
2015-12-09 04:06:12 +03:00
ctx . Data [ "Mirror" ] = ctx . Repo . Mirror
2014-04-13 06:30:00 +04:00
}
2014-03-30 06:09:59 +04:00
ctx . Repo . Repository = repo
2016-08-30 12:08:38 +03:00
ctx . Data [ "RepoName" ] = ctx . Repo . Repository . Name
2014-03-30 09:30:17 +04:00
ctx . Data [ "IsBareRepo" ] = ctx . Repo . Repository . IsBare
2014-03-30 06:09:59 +04:00
gitRepo , err := git . OpenRepository ( models . RepoPath ( userName , repoName ) )
if err != nil {
2014-04-11 06:03:31 +04:00
ctx . Handle ( 500 , "RepoAssignment Invalid repo " + models . RepoPath ( userName , repoName ) , err )
2014-03-15 20:03:23 +04:00
return
}
2014-03-30 06:09:59 +04:00
ctx . Repo . GitRepo = gitRepo
2016-07-15 16:53:43 +03:00
ctx . Repo . RepoLink = repo . Link ( )
2014-08-15 14:29:41 +04:00
ctx . Data [ "RepoLink" ] = ctx . Repo . RepoLink
2015-09-02 12:09:12 +03:00
ctx . Data [ "RepoRelPath" ] = ctx . Repo . Owner . Name + "/" + ctx . Repo . Repository . Name
2014-03-30 07:38:41 +04:00
2014-04-14 05:00:12 +04:00
tags , err := ctx . Repo . GitRepo . GetTags ( )
if err != nil {
2014-07-26 08:24:27 +04:00
ctx . Handle ( 500 , "GetTags" , err )
2014-04-14 05:00:12 +04:00
return
}
2014-09-23 21:47:54 +04:00
ctx . Data [ "Tags" ] = tags
2017-08-28 17:06:10 +03:00
count , err := models . GetReleaseCountByRepoID ( ctx . Repo . Repository . ID , models . FindReleasesOptions {
IncludeDrafts : false ,
2017-09-20 08:26:49 +03:00
IncludeTags : true ,
2017-08-28 17:06:10 +03:00
} )
if err != nil {
ctx . Handle ( 500 , "GetReleaseCountByRepoID" , err )
return
}
ctx . Repo . Repository . NumReleases = int ( count )
2014-04-14 05:00:12 +04:00
2016-03-04 23:43:01 +03:00
ctx . Data [ "Title" ] = owner . Name + "/" + repo . Name
ctx . Data [ "Repository" ] = repo
ctx . Data [ "Owner" ] = ctx . Repo . Repository . Owner
ctx . Data [ "IsRepositoryOwner" ] = ctx . Repo . IsOwner ( )
ctx . Data [ "IsRepositoryAdmin" ] = ctx . Repo . IsAdmin ( )
2016-03-06 04:45:23 +03:00
ctx . Data [ "IsRepositoryWriter" ] = ctx . Repo . IsWriter ( )
2016-03-04 23:43:01 +03:00
2016-02-28 04:48:39 +03:00
ctx . Data [ "DisableSSH" ] = setting . SSH . Disabled
2017-07-15 17:21:51 +03:00
ctx . Data [ "ExposeAnonSSH" ] = setting . SSH . ExposeAnonymous
2016-10-04 19:58:14 +03:00
ctx . Data [ "DisableHTTP" ] = setting . Repository . DisableHTTPGit
2015-12-01 04:45:55 +03:00
ctx . Data [ "CloneLink" ] = repo . CloneLink ( )
ctx . Data [ "WikiCloneLink" ] = repo . WikiCloneLink ( )
2014-03-30 07:38:41 +04:00
2015-10-03 02:58:36 +03:00
if ctx . IsSigned {
2016-07-23 20:08:22 +03:00
ctx . Data [ "IsWatchingRepo" ] = models . IsWatching ( ctx . User . ID , repo . ID )
ctx . Data [ "IsStaringRepo" ] = models . IsStaring ( ctx . User . ID , repo . ID )
2015-10-03 02:58:36 +03:00
}
2014-03-30 09:30:17 +04:00
// repo is bare and display enable
2014-08-11 07:11:18 +04:00
if ctx . Repo . Repository . IsBare {
2017-03-18 13:59:07 +03:00
ctx . Data [ "BranchName" ] = ctx . Repo . Repository . DefaultBranch
2014-03-30 09:30:17 +04:00
return
2014-03-30 06:09:59 +04:00
}
2014-03-15 20:03:23 +04:00
2014-06-28 19:56:41 +04:00
ctx . Data [ "TagName" ] = ctx . Repo . TagName
2014-04-13 05:35:36 +04:00
brs , err := ctx . Repo . GitRepo . GetBranches ( )
2014-04-11 08:01:38 +04:00
if err != nil {
2014-09-23 21:47:54 +04:00
ctx . Handle ( 500 , "GetBranches" , err )
return
2014-04-11 08:01:38 +04:00
}
ctx . Data [ "Branches" ] = brs
2014-07-26 08:24:27 +04:00
ctx . Data [ "BrancheCount" ] = len ( brs )
2014-07-22 16:46:04 +04:00
// If not branch selected, try default one.
// If default branch doesn't exists, fall back to some other branch.
2015-08-08 17:43:14 +03:00
if len ( ctx . Repo . BranchName ) == 0 {
if len ( ctx . Repo . Repository . DefaultBranch ) > 0 && gitRepo . IsBranchExist ( ctx . Repo . Repository . DefaultBranch ) {
2014-07-22 16:46:04 +04:00
ctx . Repo . BranchName = ctx . Repo . Repository . DefaultBranch
} else if len ( brs ) > 0 {
ctx . Repo . BranchName = brs [ 0 ]
}
}
ctx . Data [ "BranchName" ] = ctx . Repo . BranchName
2015-08-31 10:24:28 +03:00
ctx . Data [ "CommitID" ] = ctx . Repo . CommitID
2015-08-03 22:27:07 +03:00
2016-03-07 07:57:46 +03:00
if repo . IsFork {
RetrieveBaseRepo ( ctx , repo )
if ctx . Written ( ) {
return
}
}
2017-03-15 03:52:01 +03:00
// People who have push access or have forked repository can propose a new pull request.
2016-08-08 23:02:55 +03:00
if ctx . Repo . IsWriter ( ) || ( ctx . IsSigned && ctx . User . HasForkedRepo ( ctx . Repo . Repository . ID ) ) {
2016-03-07 07:57:46 +03:00
// Pull request is allowed if this is a fork repository
// and base repository accepts pull requests.
2017-05-30 15:04:12 +03:00
if repo . BaseRepo != nil && repo . BaseRepo . AllowsPulls ( ) {
ctx . Data [ "BaseRepo" ] = repo . BaseRepo
ctx . Repo . PullRequest . BaseRepo = repo . BaseRepo
ctx . Repo . PullRequest . Allowed = true
ctx . Repo . PullRequest . HeadInfo = ctx . Repo . Owner . Name + ":" + ctx . Repo . BranchName
2016-03-07 07:57:46 +03:00
} else {
// Or, this is repository accepts pull requests between branches.
if repo . AllowsPulls ( ) {
ctx . Data [ "BaseRepo" ] = repo
ctx . Repo . PullRequest . BaseRepo = repo
ctx . Repo . PullRequest . Allowed = true
ctx . Repo . PullRequest . SameRepo = true
ctx . Repo . PullRequest . HeadInfo = ctx . Repo . BranchName
}
}
2017-07-17 05:04:43 +03:00
// Reset repo units as otherwise user specific units wont be loaded later
ctx . Repo . Repository . Units = nil
2016-03-07 07:57:46 +03:00
}
ctx . Data [ "PullRequestCtx" ] = ctx . Repo . PullRequest
2015-10-31 19:04:04 +03:00
if ctx . Query ( "go-get" ) == "1" {
2017-09-23 16:24:24 +03:00
ctx . Data [ "GoGetImport" ] = ComposeGoGetImport ( owner . Name , repo . Name )
2016-11-27 13:14:25 +03:00
prefix := setting . AppURL + path . Join ( owner . Name , repo . Name , "src" , ctx . Repo . BranchName )
2015-10-31 19:04:04 +03:00
ctx . Data [ "GoDocDirectory" ] = prefix + "{/dir}"
ctx . Data [ "GoDocFile" ] = prefix + "{/dir}/{file}#L{line}"
}
2014-03-15 20:03:23 +04:00
}
}
2014-05-06 03:58:13 +04:00
2015-12-05 01:20:23 +03:00
// RepoRef handles repository reference name including those contain `/`.
func RepoRef ( ) macaron . Handler {
return func ( ctx * Context ) {
// Empty repository does not have reference information.
if ctx . Repo . Repository . IsBare {
return
}
var (
refName string
err error
)
// For API calls.
if ctx . Repo . GitRepo == nil {
repoPath := models . RepoPath ( ctx . Repo . Owner . Name , ctx . Repo . Repository . Name )
2016-08-30 12:08:38 +03:00
ctx . Repo . GitRepo , err = git . OpenRepository ( repoPath )
2015-12-05 01:20:23 +03:00
if err != nil {
ctx . Handle ( 500 , "RepoRef Invalid repo " + repoPath , err )
return
}
}
// Get default branch.
if len ( ctx . Params ( "*" ) ) == 0 {
refName = ctx . Repo . Repository . DefaultBranch
if ! ctx . Repo . GitRepo . IsBranchExist ( refName ) {
brs , err := ctx . Repo . GitRepo . GetBranches ( )
if err != nil {
ctx . Handle ( 500 , "GetBranches" , err )
return
2017-05-29 05:25:23 +03:00
} else if len ( brs ) == 0 {
err = fmt . Errorf ( "No branches in non-bare repository %s" ,
ctx . Repo . GitRepo . Path )
ctx . Handle ( 500 , "GetBranches" , err )
2017-07-04 04:29:57 +03:00
return
2015-12-05 01:20:23 +03:00
}
refName = brs [ 0 ]
}
2015-12-10 04:46:05 +03:00
ctx . Repo . Commit , err = ctx . Repo . GitRepo . GetBranchCommit ( refName )
2015-12-05 01:20:23 +03:00
if err != nil {
2015-12-10 04:46:05 +03:00
ctx . Handle ( 500 , "GetBranchCommit" , err )
2015-12-05 01:20:23 +03:00
return
}
ctx . Repo . CommitID = ctx . Repo . Commit . ID . String ( )
2015-12-09 08:32:53 +03:00
ctx . Repo . IsViewBranch = true
2015-12-05 01:20:23 +03:00
} else {
hasMatched := false
parts := strings . Split ( ctx . Params ( "*" ) , "/" )
for i , part := range parts {
refName = strings . TrimPrefix ( refName + "/" + part , "/" )
if ctx . Repo . GitRepo . IsBranchExist ( refName ) ||
ctx . Repo . GitRepo . IsTagExist ( refName ) {
if i < len ( parts ) - 1 {
2016-08-25 07:35:03 +03:00
ctx . Repo . TreePath = strings . Join ( parts [ i + 1 : ] , "/" )
2015-12-05 01:20:23 +03:00
}
hasMatched = true
break
}
}
if ! hasMatched && len ( parts [ 0 ] ) == 40 {
refName = parts [ 0 ]
2016-08-25 07:35:03 +03:00
ctx . Repo . TreePath = strings . Join ( parts [ 1 : ] , "/" )
2015-12-05 01:20:23 +03:00
}
if ctx . Repo . GitRepo . IsBranchExist ( refName ) {
2015-12-09 08:32:53 +03:00
ctx . Repo . IsViewBranch = true
2015-12-05 01:20:23 +03:00
2015-12-10 04:46:05 +03:00
ctx . Repo . Commit , err = ctx . Repo . GitRepo . GetBranchCommit ( refName )
2015-12-05 01:20:23 +03:00
if err != nil {
2015-12-10 04:46:05 +03:00
ctx . Handle ( 500 , "GetBranchCommit" , err )
2015-12-05 01:20:23 +03:00
return
}
ctx . Repo . CommitID = ctx . Repo . Commit . ID . String ( )
} else if ctx . Repo . GitRepo . IsTagExist ( refName ) {
2015-12-09 08:32:53 +03:00
ctx . Repo . IsViewTag = true
2015-12-10 04:46:05 +03:00
ctx . Repo . Commit , err = ctx . Repo . GitRepo . GetTagCommit ( refName )
2015-12-05 01:20:23 +03:00
if err != nil {
2015-12-10 04:46:05 +03:00
ctx . Handle ( 500 , "GetTagCommit" , err )
2015-12-05 01:20:23 +03:00
return
}
ctx . Repo . CommitID = ctx . Repo . Commit . ID . String ( )
} else if len ( refName ) == 40 {
2015-12-09 08:32:53 +03:00
ctx . Repo . IsViewCommit = true
2015-12-05 01:20:23 +03:00
ctx . Repo . CommitID = refName
ctx . Repo . Commit , err = ctx . Repo . GitRepo . GetCommit ( refName )
if err != nil {
ctx . Handle ( 404 , "GetCommit" , nil )
return
}
} else {
ctx . Handle ( 404 , "RepoRef invalid repo" , fmt . Errorf ( "branch or tag not exist: %s" , refName ) )
return
}
}
ctx . Repo . BranchName = refName
ctx . Data [ "BranchName" ] = ctx . Repo . BranchName
ctx . Data [ "CommitID" ] = ctx . Repo . CommitID
2016-08-30 12:08:38 +03:00
ctx . Data [ "TreePath" ] = ctx . Repo . TreePath
2015-12-09 08:32:53 +03:00
ctx . Data [ "IsViewBranch" ] = ctx . Repo . IsViewBranch
ctx . Data [ "IsViewTag" ] = ctx . Repo . IsViewTag
ctx . Data [ "IsViewCommit" ] = ctx . Repo . IsViewCommit
2015-12-05 01:20:23 +03:00
ctx . Repo . CommitsCount , err = ctx . Repo . Commit . CommitsCount ( )
if err != nil {
ctx . Handle ( 500 , "CommitsCount" , err )
return
}
ctx . Data [ "CommitsCount" ] = ctx . Repo . CommitsCount
}
}
2016-11-25 09:51:01 +03:00
// RequireRepoAdmin returns a macaron middleware for requiring repository admin permission
2015-08-03 12:42:09 +03:00
func RequireRepoAdmin ( ) macaron . Handler {
2014-05-06 03:58:13 +04:00
return func ( ctx * Context ) {
2016-03-06 04:45:23 +03:00
if ! ctx . IsSigned || ( ! ctx . Repo . IsAdmin ( ) && ! ctx . User . IsAdmin ) {
2015-11-27 09:50:38 +03:00
ctx . Handle ( 404 , ctx . Req . RequestURI , nil )
return
}
}
}
2016-11-25 09:51:01 +03:00
// RequireRepoWriter returns a macaron middleware for requiring repository write permission
2016-03-06 04:45:23 +03:00
func RequireRepoWriter ( ) macaron . Handler {
2015-11-27 09:50:38 +03:00
return func ( ctx * Context ) {
2016-03-06 04:45:23 +03:00
if ! ctx . IsSigned || ( ! ctx . Repo . IsWriter ( ) && ! ctx . User . IsAdmin ) {
2014-05-06 03:58:13 +04:00
ctx . Handle ( 404 , ctx . Req . RequestURI , nil )
return
}
}
}
2014-10-07 01:50:00 +04:00
2017-05-18 17:54:24 +03:00
// LoadRepoUnits loads repsitory's units, it should be called after repository and user loaded
func LoadRepoUnits ( ) macaron . Handler {
return func ( ctx * Context ) {
2017-05-19 03:59:26 +03:00
var isAdmin bool
if ctx . User != nil && ctx . User . IsAdmin {
isAdmin = true
}
2017-05-18 17:54:24 +03:00
var userID int64
if ctx . User != nil {
userID = ctx . User . ID
}
2017-05-19 03:59:26 +03:00
err := ctx . Repo . Repository . LoadUnitsByUserID ( userID , isAdmin )
2017-05-18 17:54:24 +03:00
if err != nil {
ctx . Handle ( 500 , "LoadUnitsByUserID" , err )
return
}
}
}
// CheckUnit will check whether
func CheckUnit ( unitType models . UnitType ) macaron . Handler {
return func ( ctx * Context ) {
2017-08-02 11:46:54 +03:00
if ! ctx . Repo . Repository . UnitEnabled ( unitType ) {
2017-05-18 17:54:24 +03:00
ctx . Handle ( 404 , "CheckUnit" , fmt . Errorf ( "%s: %v" , ctx . Tr ( "units.error.unit_not_allowed" ) , unitType ) )
}
}
}
2014-12-07 04:22:48 +03:00
// GitHookService checks if repository Git hooks service has been enabled.
2014-10-07 01:50:00 +04:00
func GitHookService ( ) macaron . Handler {
return func ( ctx * Context ) {
2015-11-04 02:40:52 +03:00
if ! ctx . User . CanEditGitHook ( ) {
2014-10-07 01:50:00 +04:00
ctx . Handle ( 404 , "GitHookService" , nil )
return
}
}
}
2017-02-04 18:53:46 +03:00
// UnitTypes returns a macaron middleware to set unit types to context variables.
func UnitTypes ( ) macaron . Handler {
return func ( ctx * Context ) {
ctx . Data [ "UnitTypeCode" ] = models . UnitTypeCode
ctx . Data [ "UnitTypeIssues" ] = models . UnitTypeIssues
ctx . Data [ "UnitTypePullRequests" ] = models . UnitTypePullRequests
ctx . Data [ "UnitTypeReleases" ] = models . UnitTypeReleases
ctx . Data [ "UnitTypeWiki" ] = models . UnitTypeWiki
ctx . Data [ "UnitTypeExternalWiki" ] = models . UnitTypeExternalWiki
ctx . Data [ "UnitTypeExternalTracker" ] = models . UnitTypeExternalTracker
}
}