2014-05-01 13:44:22 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
2014-07-26 10:28:04 +04:00
import (
"strings"
"time"
2016-11-10 19:24:48 +03:00
"code.gitea.io/git"
2015-12-10 04:46:05 +03:00
2016-11-10 19:24:48 +03:00
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
2014-07-26 10:28:04 +04:00
)
const (
2016-11-07 23:58:22 +03:00
tplSettingsOptions base . TplName = "repo/settings/options"
tplCollaboration base . TplName = "repo/settings/collaboration"
2017-02-21 18:02:10 +03:00
tplBranches base . TplName = "repo/settings/branches"
2016-11-07 23:58:22 +03:00
tplGithooks base . TplName = "repo/settings/githooks"
tplGithookEdit base . TplName = "repo/settings/githook_edit"
tplDeployKeys base . TplName = "repo/settings/deploy_keys"
2014-07-26 10:28:04 +04:00
)
2016-11-24 10:04:31 +03:00
// Settings show a repository's settings page
2016-03-11 19:56:52 +03:00
func Settings ( ctx * context . Context ) {
2014-08-02 21:47:33 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings" )
ctx . Data [ "PageIsSettingsOptions" ] = true
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplSettingsOptions )
2014-07-26 10:28:04 +04:00
}
2016-11-24 10:04:31 +03:00
// SettingsPost response for changes of a repository
2016-03-11 19:56:52 +03:00
func SettingsPost ( ctx * context . Context , form auth . RepoSettingForm ) {
2014-08-02 21:47:33 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings" )
ctx . Data [ "PageIsSettingsOptions" ] = true
2014-07-26 10:28:04 +04:00
2015-08-31 08:36:31 +03:00
repo := ctx . Repo . Repository
2014-07-26 10:28:04 +04:00
switch ctx . Query ( "action" ) {
case "update" :
if ctx . HasError ( ) {
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplSettingsOptions )
2014-07-26 10:28:04 +04:00
return
}
2015-09-01 18:43:53 +03:00
isNameChanged := false
2015-09-01 16:29:52 +03:00
oldRepoName := repo . Name
2014-07-26 10:28:04 +04:00
newRepoName := form . RepoName
// Check if repository name has been changed.
2015-08-31 08:36:31 +03:00
if repo . LowerName != strings . ToLower ( newRepoName ) {
2015-09-01 18:43:53 +03:00
isNameChanged = true
2015-08-31 08:36:31 +03:00
if err := models . ChangeRepositoryName ( ctx . Repo . Owner , repo . Name , newRepoName ) ; err != nil {
ctx . Data [ "Err_RepoName" ] = true
2015-03-27 00:11:47 +03:00
switch {
2015-08-08 12:10:34 +03:00
case models . IsErrRepoAlreadyExist ( err ) :
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.repo_name_been_taken" ) , tplSettingsOptions , & form )
2015-03-27 00:11:47 +03:00
case models . IsErrNameReserved ( err ) :
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_reserved" , err . ( models . ErrNameReserved ) . Name ) , tplSettingsOptions , & form )
2015-03-27 00:11:47 +03:00
case models . IsErrNamePatternNotAllowed ( err ) :
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.form.name_pattern_not_allowed" , err . ( models . ErrNamePatternNotAllowed ) . Pattern ) , tplSettingsOptions , & form )
2015-03-27 00:11:47 +03:00
default :
2014-08-24 17:09:05 +04:00
ctx . Handle ( 500 , "ChangeRepositoryName" , err )
}
2014-07-26 10:28:04 +04:00
return
}
2015-09-01 18:43:53 +03:00
2017-02-05 17:35:03 +03:00
err := models . NewRepoRedirect ( ctx . Repo . Owner . ID , repo . ID , repo . Name , newRepoName )
if err != nil {
ctx . Handle ( 500 , "NewRepoRedirect" , err )
2017-03-13 04:41:40 +03:00
return
2017-02-05 17:35:03 +03:00
}
2015-08-31 08:36:31 +03:00
log . Trace ( "Repository name changed: %s/%s -> %s" , ctx . Repo . Owner . Name , repo . Name , newRepoName )
2014-07-26 10:28:04 +04:00
}
2015-08-31 08:36:31 +03:00
// In case it's just a case change.
repo . Name = newRepoName
repo . LowerName = strings . ToLower ( newRepoName )
repo . Description = form . Description
repo . Website = form . Website
2015-11-18 23:01:11 +03:00
// Visibility of forked repository is forced sync with base repository.
if repo . IsFork {
form . Private = repo . BaseRepo . IsPrivate
}
2015-08-31 08:36:31 +03:00
visibilityChanged := repo . IsPrivate != form . Private
repo . IsPrivate = form . Private
if err := models . UpdateRepository ( repo , visibilityChanged ) ; err != nil {
2015-09-01 16:29:52 +03:00
ctx . Handle ( 500 , "UpdateRepository" , err )
return
2014-07-26 10:28:04 +04:00
}
2015-12-05 05:30:33 +03:00
log . Trace ( "Repository basic settings updated: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
2014-07-26 10:28:04 +04:00
2015-09-01 18:43:53 +03:00
if isNameChanged {
if err := models . RenameRepoAction ( ctx . User , oldRepoName , repo ) ; err != nil {
log . Error ( 4 , "RenameRepoAction: %v" , err )
}
}
2016-08-31 02:18:33 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.update_settings_success" ) )
ctx . Redirect ( repo . Link ( ) + "/settings" )
2016-07-17 04:30:43 +03:00
2016-08-31 02:18:33 +03:00
case "mirror" :
if ! repo . IsMirror {
ctx . Handle ( 404 , "" , nil )
return
}
2017-04-08 18:27:26 +03:00
interval , err := time . ParseDuration ( form . Interval )
if err != nil || interval < setting . Mirror . MinInterval {
ctx . RenderWithErr ( ctx . Tr ( "repo.mirror_interval_invalid" ) , tplSettingsOptions , & form )
} else {
2016-08-31 02:18:33 +03:00
ctx . Repo . Mirror . EnablePrune = form . EnablePrune
2017-04-08 18:27:26 +03:00
ctx . Repo . Mirror . Interval = interval
ctx . Repo . Mirror . NextUpdate = time . Now ( ) . Add ( interval )
2016-08-31 02:18:33 +03:00
if err := models . UpdateMirror ( ctx . Repo . Mirror ) ; err != nil {
2017-04-08 18:27:26 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.mirror_interval_invalid" ) , tplSettingsOptions , & form )
2015-12-09 04:06:12 +03:00
return
}
2014-07-26 10:28:04 +04:00
}
2016-08-31 02:18:33 +03:00
if err := ctx . Repo . Mirror . SaveAddress ( form . MirrorAddress ) ; err != nil {
ctx . Handle ( 500 , "SaveAddress" , err )
return
}
2014-07-26 10:28:04 +04:00
2014-08-02 21:47:33 +04:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.update_settings_success" ) )
2016-07-15 16:53:43 +03:00
ctx . Redirect ( repo . Link ( ) + "/settings" )
2015-12-05 05:30:33 +03:00
2016-08-31 02:18:33 +03:00
case "mirror-sync" :
if ! repo . IsMirror {
ctx . Handle ( 404 , "" , nil )
return
}
go models . MirrorQueue . Add ( repo . ID )
ctx . Flash . Info ( ctx . Tr ( "repo.settings.mirror_sync_in_progress" ) )
ctx . Redirect ( repo . Link ( ) + "/settings" )
2015-12-05 05:30:33 +03:00
case "advanced" :
2017-02-04 18:53:46 +03:00
var units [ ] models . RepoUnit
for _ , tp := range models . MustRepoUnits {
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
Type : tp ,
Index : int ( tp ) ,
Config : new ( models . UnitConfig ) ,
} )
}
if form . EnableWiki {
if form . EnableExternalWiki {
2017-03-13 04:41:40 +03:00
if ! strings . HasPrefix ( form . ExternalWikiURL , "http://" ) && ! strings . HasPrefix ( form . ExternalWikiURL , "https://" ) {
ctx . Flash . Error ( ctx . Tr ( "repo.settings.external_wiki_url_error" ) )
ctx . Redirect ( repo . Link ( ) + "/settings" )
return
}
2017-02-04 18:53:46 +03:00
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
Type : models . UnitTypeExternalWiki ,
Index : int ( models . UnitTypeExternalWiki ) ,
Config : & models . ExternalWikiConfig {
ExternalWikiURL : form . ExternalWikiURL ,
} ,
} )
} else {
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
Type : models . UnitTypeWiki ,
Index : int ( models . UnitTypeWiki ) ,
Config : new ( models . UnitConfig ) ,
} )
}
}
if form . EnableIssues {
if form . EnableExternalTracker {
2017-03-13 04:41:40 +03:00
if ! strings . HasPrefix ( form . ExternalTrackerURL , "http://" ) && ! strings . HasPrefix ( form . ExternalTrackerURL , "https://" ) {
ctx . Flash . Error ( ctx . Tr ( "repo.settings.external_tracker_url_error" ) )
ctx . Redirect ( repo . Link ( ) + "/settings" )
return
}
2017-02-04 18:53:46 +03:00
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
2017-03-13 04:41:40 +03:00
Type : models . UnitTypeExternalTracker ,
Index : int ( models . UnitTypeExternalTracker ) ,
2017-02-04 18:53:46 +03:00
Config : & models . ExternalTrackerConfig {
ExternalTrackerURL : form . ExternalTrackerURL ,
ExternalTrackerFormat : form . TrackerURLFormat ,
ExternalTrackerStyle : form . TrackerIssueStyle ,
} ,
} )
} else {
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
Type : models . UnitTypeIssues ,
Index : int ( models . UnitTypeIssues ) ,
Config : new ( models . UnitConfig ) ,
} )
}
}
if form . EnablePulls {
units = append ( units , models . RepoUnit {
RepoID : repo . ID ,
Type : models . UnitTypePullRequests ,
Index : int ( models . UnitTypePullRequests ) ,
Config : new ( models . UnitConfig ) ,
} )
}
if err := models . UpdateRepositoryUnits ( repo , units ) ; err != nil {
ctx . Handle ( 500 , "UpdateRepositoryUnits" , err )
2015-12-05 05:30:33 +03:00
return
}
log . Trace ( "Repository advanced settings updated: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
ctx . Flash . Success ( ctx . Tr ( "repo.settings.update_settings_success" ) )
ctx . Redirect ( ctx . Repo . RepoLink + "/settings" )
2016-02-14 23:12:00 +03:00
case "convert" :
2016-03-06 04:45:23 +03:00
if ! ctx . Repo . IsOwner ( ) {
ctx . Error ( 404 )
return
}
2016-02-14 23:12:00 +03:00
if repo . Name != form . RepoName {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.enterred_invalid_repo_name" ) , tplSettingsOptions , nil )
2016-02-14 23:12:00 +03:00
return
}
if ctx . Repo . Owner . IsOrganization ( ) {
2016-07-23 20:08:22 +03:00
if ! ctx . Repo . Owner . IsOwnedBy ( ctx . User . ID ) {
2016-02-14 23:12:00 +03:00
ctx . Error ( 404 )
return
}
}
2016-02-14 23:22:36 +03:00
if ! repo . IsMirror {
ctx . Error ( 404 )
return
}
2016-02-14 23:12:00 +03:00
repo . IsMirror = false
2016-08-11 20:18:51 +03:00
if _ , err := models . CleanUpMigrateInfo ( repo ) ; err != nil {
2016-02-15 22:57:15 +03:00
ctx . Handle ( 500 , "CleanUpMigrateInfo" , err )
2016-02-14 23:12:00 +03:00
return
2016-02-15 22:57:15 +03:00
} else if err = models . DeleteMirrorByRepoID ( ctx . Repo . Repository . ID ) ; err != nil {
ctx . Handle ( 500 , "DeleteMirrorByRepoID" , err )
2016-02-14 23:12:00 +03:00
return
}
2016-02-15 00:40:39 +03:00
log . Trace ( "Repository converted from mirror to regular: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
2016-02-14 23:12:00 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.convert_succeed" ) )
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + "/" + ctx . Repo . Owner . Name + "/" + repo . Name )
2016-02-14 23:12:00 +03:00
2014-07-26 10:28:04 +04:00
case "transfer" :
2016-03-06 04:45:23 +03:00
if ! ctx . Repo . IsOwner ( ) {
ctx . Error ( 404 )
return
}
2015-08-31 08:36:31 +03:00
if repo . Name != form . RepoName {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.enterred_invalid_repo_name" ) , tplSettingsOptions , nil )
2014-07-26 10:28:04 +04:00
return
}
2015-08-31 08:36:31 +03:00
if ctx . Repo . Owner . IsOrganization ( ) {
2016-07-23 20:08:22 +03:00
if ! ctx . Repo . Owner . IsOwnedBy ( ctx . User . ID ) {
2015-08-31 08:36:31 +03:00
ctx . Error ( 404 )
return
}
}
2014-08-02 21:47:33 +04:00
newOwner := ctx . Query ( "new_owner_name" )
2015-02-23 02:24:49 +03:00
isExist , err := models . IsUserExist ( 0 , newOwner )
2014-07-26 10:28:04 +04:00
if err != nil {
2014-08-02 21:47:33 +04:00
ctx . Handle ( 500 , "IsUserExist" , err )
2014-07-26 10:28:04 +04:00
return
} else if ! isExist {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.enterred_invalid_owner_name" ) , tplSettingsOptions , nil )
2014-07-26 10:28:04 +04:00
return
2015-03-06 03:20:27 +03:00
}
2015-08-31 08:36:31 +03:00
if err = models . TransferOwnership ( ctx . User , newOwner , repo ) ; err != nil {
2015-08-08 12:10:34 +03:00
if models . IsErrRepoAlreadyExist ( err ) {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.settings.new_owner_has_same_repo" ) , tplSettingsOptions , nil )
2014-09-13 02:29:58 +04:00
} else {
ctx . Handle ( 500 , "TransferOwnership" , err )
}
2014-07-26 10:28:04 +04:00
return
}
2016-11-27 14:59:12 +03:00
log . Trace ( "Repository transferred: %s/%s -> %s" , ctx . Repo . Owner . Name , repo . Name , newOwner )
2014-09-17 22:52:46 +04:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.transfer_succeed" ) )
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + "/" + newOwner + "/" + repo . Name )
2016-03-06 04:45:23 +03:00
2014-07-26 10:28:04 +04:00
case "delete" :
2016-03-06 04:45:23 +03:00
if ! ctx . Repo . IsOwner ( ) {
ctx . Error ( 404 )
return
}
2015-08-31 08:36:31 +03:00
if repo . Name != form . RepoName {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.enterred_invalid_repo_name" ) , tplSettingsOptions , nil )
2014-07-26 10:28:04 +04:00
return
2014-08-27 12:39:36 +04:00
}
if ctx . Repo . Owner . IsOrganization ( ) {
2016-07-23 20:08:22 +03:00
if ! ctx . Repo . Owner . IsOwnedBy ( ctx . User . ID ) {
2014-08-27 12:39:36 +04:00
ctx . Error ( 404 )
return
}
2015-03-06 03:20:27 +03:00
}
2016-07-23 20:08:22 +03:00
if err := models . DeleteRepository ( ctx . Repo . Owner . ID , repo . ID ) ; err != nil {
2014-08-02 21:47:33 +04:00
ctx . Handle ( 500 , "DeleteRepository" , err )
2014-07-26 10:28:04 +04:00
return
}
2015-08-31 08:36:31 +03:00
log . Trace ( "Repository deleted: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
2015-12-06 01:39:29 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.deletion_success" ) )
2015-08-31 08:36:31 +03:00
ctx . Redirect ( ctx . Repo . Owner . DashboardLink ( ) )
2016-03-06 04:45:23 +03:00
2016-03-03 23:38:25 +03:00
case "delete-wiki" :
2016-03-06 04:45:23 +03:00
if ! ctx . Repo . IsOwner ( ) {
ctx . Error ( 404 )
return
}
2016-03-03 23:38:25 +03:00
if repo . Name != form . RepoName {
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "form.enterred_invalid_repo_name" ) , tplSettingsOptions , nil )
2016-03-03 23:38:25 +03:00
return
}
if ctx . Repo . Owner . IsOrganization ( ) {
2016-07-23 20:08:22 +03:00
if ! ctx . Repo . Owner . IsOwnedBy ( ctx . User . ID ) {
2016-03-03 23:38:25 +03:00
ctx . Error ( 404 )
return
}
}
2016-03-04 07:24:22 +03:00
repo . DeleteWiki ( )
2016-03-03 23:38:25 +03:00
log . Trace ( "Repository wiki deleted: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
2016-03-04 07:24:22 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.wiki_deletion_success" ) )
2016-03-03 23:38:25 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/settings" )
2016-08-31 02:18:33 +03:00
default :
ctx . Handle ( 404 , "" , nil )
2014-07-26 10:28:04 +04:00
}
}
2016-11-24 10:04:31 +03:00
// Collaboration render a repository's collaboration page
2016-03-11 19:56:52 +03:00
func Collaboration ( ctx * context . Context ) {
2014-08-07 14:40:05 +04:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings" )
ctx . Data [ "PageIsSettingsCollaboration" ] = true
2015-01-23 10:54:16 +03:00
users , err := ctx . Repo . Repository . GetCollaborators ( )
2014-07-26 10:28:04 +04:00
if err != nil {
2014-08-07 14:40:05 +04:00
ctx . Handle ( 500 , "GetCollaborators" , err )
2014-07-26 10:28:04 +04:00
return
}
2015-01-23 10:54:16 +03:00
ctx . Data [ "Collaborators" ] = users
2016-03-06 02:08:42 +03:00
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplCollaboration )
2014-07-26 10:28:04 +04:00
}
2016-11-24 10:04:31 +03:00
// CollaborationPost response for actions for a collaboration of a repository
2016-03-11 19:56:52 +03:00
func CollaborationPost ( ctx * context . Context ) {
2016-02-20 23:10:34 +03:00
name := strings . ToLower ( ctx . Query ( "collaborator" ) )
if len ( name ) == 0 || ctx . Repo . Owner . LowerName == name {
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + ctx . Req . URL . Path )
2016-02-20 23:10:34 +03:00
return
}
u , err := models . GetUserByName ( name )
if err != nil {
if models . IsErrUserNotExist ( err ) {
ctx . Flash . Error ( ctx . Tr ( "form.user_not_exist" ) )
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + ctx . Req . URL . Path )
2016-02-20 23:10:34 +03:00
} else {
ctx . Handle ( 500 , "GetUserByName" , err )
}
return
}
// Organization is not allowed to be added as a collaborator.
if u . IsOrganization ( ) {
ctx . Flash . Error ( ctx . Tr ( "repo.settings.org_not_allowed_to_be_collaborator" ) )
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + ctx . Req . URL . Path )
2016-02-20 23:10:34 +03:00
return
}
// Check if user is organization member.
2016-07-23 20:08:22 +03:00
if ctx . Repo . Owner . IsOrganization ( ) && ctx . Repo . Owner . IsOrgMember ( u . ID ) {
2016-02-20 23:10:34 +03:00
ctx . Flash . Info ( ctx . Tr ( "repo.settings.user_is_org_member" ) )
ctx . Redirect ( ctx . Repo . RepoLink + "/settings/collaboration" )
return
}
if err = ctx . Repo . Repository . AddCollaborator ( u ) ; err != nil {
ctx . Handle ( 500 , "AddCollaborator" , err )
return
}
if setting . Service . EnableNotifyMail {
2016-07-15 19:36:39 +03:00
models . SendCollaboratorMail ( u , ctx . User , ctx . Repo . Repository )
2016-02-20 23:10:34 +03:00
}
ctx . Flash . Success ( ctx . Tr ( "repo.settings.add_collaborator_success" ) )
2016-11-27 13:14:25 +03:00
ctx . Redirect ( setting . AppSubURL + ctx . Req . URL . Path )
2016-02-20 23:10:34 +03:00
}
2016-11-24 10:04:31 +03:00
// ChangeCollaborationAccessMode response for changing access of a collaboration
2016-03-11 19:56:52 +03:00
func ChangeCollaborationAccessMode ( ctx * context . Context ) {
2016-03-06 02:08:42 +03:00
if err := ctx . Repo . Repository . ChangeCollaborationAccessMode (
ctx . QueryInt64 ( "uid" ) ,
models . AccessMode ( ctx . QueryInt ( "mode" ) ) ) ; err != nil {
log . Error ( 4 , "ChangeCollaborationAccessMode: %v" , err )
}
}
2016-11-24 10:04:31 +03:00
// DeleteCollaboration delete a collaboration for a repository
2016-03-11 19:56:52 +03:00
func DeleteCollaboration ( ctx * context . Context ) {
2016-03-06 02:08:42 +03:00
if err := ctx . Repo . Repository . DeleteCollaboration ( ctx . QueryInt64 ( "id" ) ) ; err != nil {
ctx . Flash . Error ( "DeleteCollaboration: " + err . Error ( ) )
} else {
ctx . Flash . Success ( ctx . Tr ( "repo.settings.remove_collaborator_success" ) )
}
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Repo . RepoLink + "/settings/collaboration" ,
} )
}
2017-02-21 18:02:10 +03:00
// ProtectedBranch render the page to protect the repository
func ProtectedBranch ( ctx * context . Context ) {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings" )
ctx . Data [ "PageIsSettingsBranches" ] = true
protectedBranches , err := ctx . Repo . Repository . GetProtectedBranches ( )
if err != nil {
ctx . Handle ( 500 , "GetProtectedBranches" , err )
return
}
ctx . Data [ "ProtectedBranches" ] = protectedBranches
branches := ctx . Data [ "Branches" ] . ( [ ] string )
leftBranches := make ( [ ] string , 0 , len ( branches ) - len ( protectedBranches ) )
for _ , b := range branches {
var protected bool
for _ , pb := range protectedBranches {
if b == pb . BranchName {
protected = true
break
}
}
if ! protected {
leftBranches = append ( leftBranches , b )
}
}
ctx . Data [ "LeftBranches" ] = leftBranches
ctx . HTML ( 200 , tplBranches )
}
// ProtectedBranchPost response for protect for a branch of a repository
func ProtectedBranchPost ( ctx * context . Context ) {
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings" )
ctx . Data [ "PageIsSettingsBranches" ] = true
repo := ctx . Repo . Repository
switch ctx . Query ( "action" ) {
case "default_branch" :
if ctx . HasError ( ) {
ctx . HTML ( 200 , tplBranches )
return
}
branch := strings . ToLower ( ctx . Query ( "branch" ) )
if ctx . Repo . GitRepo . IsBranchExist ( branch ) &&
repo . DefaultBranch != branch {
repo . DefaultBranch = branch
if err := ctx . Repo . GitRepo . SetDefaultBranch ( branch ) ; err != nil {
if ! git . IsErrUnsupportedVersion ( err ) {
ctx . Handle ( 500 , "SetDefaultBranch" , err )
return
}
}
if err := repo . UpdateDefaultBranch ( ) ; err != nil {
ctx . Handle ( 500 , "SetDefaultBranch" , err )
return
}
}
log . Trace ( "Repository basic settings updated: %s/%s" , ctx . Repo . Owner . Name , repo . Name )
ctx . Flash . Success ( ctx . Tr ( "repo.settings.update_settings_success" ) )
ctx . Redirect ( setting . AppSubURL + ctx . Req . URL . Path )
case "protected_branch" :
if ctx . HasError ( ) {
ctx . JSON ( 200 , map [ string ] string {
"redirect" : setting . AppSubURL + ctx . Req . URL . Path ,
} )
return
}
branchName := strings . ToLower ( ctx . Query ( "branchName" ) )
if len ( branchName ) == 0 || ! ctx . Repo . GitRepo . IsBranchExist ( branchName ) {
ctx . JSON ( 200 , map [ string ] string {
"redirect" : setting . AppSubURL + ctx . Req . URL . Path ,
} )
return
}
canPush := ctx . QueryBool ( "canPush" )
if canPush {
if err := ctx . Repo . Repository . AddProtectedBranch ( branchName , canPush ) ; err != nil {
ctx . Flash . Error ( ctx . Tr ( "repo.settings.add_protected_branch_failed" , branchName ) )
ctx . JSON ( 200 , map [ string ] string {
"status" : "ok" ,
} )
return
}
ctx . Flash . Success ( ctx . Tr ( "repo.settings.add_protected_branch_success" , branchName ) )
ctx . JSON ( 200 , map [ string ] string {
"redirect" : setting . AppSubURL + ctx . Req . URL . Path ,
} )
} else {
if err := ctx . Repo . Repository . DeleteProtectedBranch ( ctx . QueryInt64 ( "id" ) ) ; err != nil {
ctx . Flash . Error ( "DeleteProtectedBranch: " + err . Error ( ) )
} else {
ctx . Flash . Success ( ctx . Tr ( "repo.settings.remove_protected_branch_success" , branchName ) )
}
ctx . JSON ( 200 , map [ string ] interface { } {
"status" : "ok" ,
} )
}
default :
ctx . Handle ( 404 , "" , nil )
}
}
// ChangeProtectedBranch response for changing access of a protect branch
func ChangeProtectedBranch ( ctx * context . Context ) {
if err := ctx . Repo . Repository . ChangeProtectedBranch (
ctx . QueryInt64 ( "id" ) ,
ctx . QueryBool ( "canPush" ) ) ; err != nil {
log . Error ( 4 , "ChangeProtectedBranch: %v" , err )
}
}
// DeleteProtectedBranch delete a protection for a branch of a repository
func DeleteProtectedBranch ( ctx * context . Context ) {
if err := ctx . Repo . Repository . DeleteProtectedBranch ( ctx . QueryInt64 ( "id" ) ) ; err != nil {
ctx . Flash . Error ( "DeleteProtectedBranch: " + err . Error ( ) )
} else {
ctx . Flash . Success ( ctx . Tr ( "repo.settings.remove_protected_branch_success" ) )
}
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Repo . RepoLink + "/settings/branches" ,
} )
}
// parseOwnerAndRepo get repos by owner
2016-03-11 19:56:52 +03:00
func parseOwnerAndRepo ( ctx * context . Context ) ( * models . User , * models . Repository ) {
2015-10-24 10:36:47 +03:00
owner , err := models . GetUserByName ( ctx . Params ( ":username" ) )
2015-08-07 20:04:12 +03:00
if err != nil {
if models . IsErrUserNotExist ( err ) {
ctx . Handle ( 404 , "GetUserByName" , err )
} else {
ctx . Handle ( 500 , "GetUserByName" , err )
}
2015-10-24 10:36:47 +03:00
return nil , nil
2015-08-07 20:04:12 +03:00
}
2016-07-23 20:08:22 +03:00
repo , err := models . GetRepositoryByName ( owner . ID , ctx . Params ( ":reponame" ) )
2015-08-07 20:04:12 +03:00
if err != nil {
if models . IsErrRepoNotExist ( err ) {
ctx . Handle ( 404 , "GetRepositoryByName" , err )
} else {
ctx . Handle ( 500 , "GetRepositoryByName" , err )
}
2015-10-24 10:36:47 +03:00
return nil , nil
2015-08-07 20:04:12 +03:00
}
2015-10-24 10:36:47 +03:00
return owner , repo
2015-08-06 17:48:11 +03:00
}
2016-11-24 10:04:31 +03:00
// GitHooks hooks of a repository
2016-03-11 19:56:52 +03:00
func GitHooks ( ctx * context . Context ) {
2015-08-26 19:30:06 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.githooks" )
2014-10-07 01:50:00 +04:00
ctx . Data [ "PageIsSettingsGitHooks" ] = true
hooks , err := ctx . Repo . GitRepo . Hooks ( )
if err != nil {
ctx . Handle ( 500 , "Hooks" , err )
return
}
ctx . Data [ "Hooks" ] = hooks
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplGithooks )
2014-10-07 01:50:00 +04:00
}
2016-11-24 10:04:31 +03:00
// GitHooksEdit render for editing a hook of repository page
2016-03-11 19:56:52 +03:00
func GitHooksEdit ( ctx * context . Context ) {
2015-08-26 19:30:06 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.githooks" )
2014-10-07 01:50:00 +04:00
ctx . Data [ "PageIsSettingsGitHooks" ] = true
name := ctx . Params ( ":name" )
hook , err := ctx . Repo . GitRepo . GetHook ( name )
if err != nil {
if err == git . ErrNotValidHook {
ctx . Handle ( 404 , "GetHook" , err )
} else {
ctx . Handle ( 500 , "GetHook" , err )
}
return
}
ctx . Data [ "Hook" ] = hook
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplGithookEdit )
2014-10-07 01:50:00 +04:00
}
2016-11-24 10:04:31 +03:00
// GitHooksEditPost response for editing a git hook of a repository
2016-03-11 19:56:52 +03:00
func GitHooksEditPost ( ctx * context . Context ) {
2014-10-07 01:50:00 +04:00
name := ctx . Params ( ":name" )
hook , err := ctx . Repo . GitRepo . GetHook ( name )
if err != nil {
if err == git . ErrNotValidHook {
ctx . Handle ( 404 , "GetHook" , err )
} else {
ctx . Handle ( 500 , "GetHook" , err )
}
return
}
hook . Content = ctx . Query ( "content" )
if err = hook . Update ( ) ; err != nil {
ctx . Handle ( 500 , "hook.Update" , err )
return
}
ctx . Redirect ( ctx . Repo . RepoLink + "/settings/hooks/git" )
}
2015-07-25 16:32:04 +03:00
2016-11-24 10:04:31 +03:00
// DeployKeys render the deploy keys list of a repository page
2016-03-11 19:56:52 +03:00
func DeployKeys ( ctx * context . Context ) {
2015-08-26 19:30:06 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.deploy_keys" )
2015-08-06 17:48:11 +03:00
ctx . Data [ "PageIsSettingsKeys" ] = true
2015-08-08 17:43:14 +03:00
keys , err := models . ListDeployKeys ( ctx . Repo . Repository . ID )
2015-08-06 17:48:11 +03:00
if err != nil {
ctx . Handle ( 500 , "ListDeployKeys" , err )
return
}
ctx . Data [ "Deploykeys" ] = keys
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplDeployKeys )
2015-08-06 17:48:11 +03:00
}
2016-11-24 10:04:31 +03:00
// DeployKeysPost response for adding a deploy key of a repository
2017-04-26 16:10:43 +03:00
func DeployKeysPost ( ctx * context . Context , form auth . AddKeyForm ) {
2015-08-26 19:30:06 +03:00
ctx . Data [ "Title" ] = ctx . Tr ( "repo.settings.deploy_keys" )
2015-08-06 17:48:11 +03:00
ctx . Data [ "PageIsSettingsKeys" ] = true
2015-08-20 12:11:29 +03:00
keys , err := models . ListDeployKeys ( ctx . Repo . Repository . ID )
if err != nil {
ctx . Handle ( 500 , "ListDeployKeys" , err )
return
}
ctx . Data [ "Deploykeys" ] = keys
2015-08-06 17:48:11 +03:00
if ctx . HasError ( ) {
2016-11-07 23:58:22 +03:00
ctx . HTML ( 200 , tplDeployKeys )
2015-08-06 17:48:11 +03:00
return
}
content , err := models . CheckPublicKeyString ( form . Content )
if err != nil {
2015-11-19 05:21:47 +03:00
if models . IsErrKeyUnableVerify ( err ) {
2015-08-06 17:48:11 +03:00
ctx . Flash . Info ( ctx . Tr ( "form.unable_verify_ssh_key" ) )
} else {
ctx . Data [ "HasError" ] = true
ctx . Data [ "Err_Content" ] = true
ctx . Flash . Error ( ctx . Tr ( "form.invalid_ssh_key" , err . Error ( ) ) )
ctx . Redirect ( ctx . Repo . RepoLink + "/settings/keys" )
return
}
}
2015-11-19 05:21:47 +03:00
key , err := models . AddDeployKey ( ctx . Repo . Repository . ID , form . Title , content )
if err != nil {
2015-08-06 17:48:11 +03:00
ctx . Data [ "HasError" ] = true
switch {
case models . IsErrKeyAlreadyExist ( err ) :
ctx . Data [ "Err_Content" ] = true
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.settings.key_been_used" ) , tplDeployKeys , & form )
2015-08-06 17:48:11 +03:00
case models . IsErrKeyNameAlreadyUsed ( err ) :
ctx . Data [ "Err_Title" ] = true
2016-11-07 23:58:22 +03:00
ctx . RenderWithErr ( ctx . Tr ( "repo.settings.key_name_used" ) , tplDeployKeys , & form )
2015-08-06 17:48:11 +03:00
default :
ctx . Handle ( 500 , "AddDeployKey" , err )
}
return
}
2015-08-08 17:43:14 +03:00
log . Trace ( "Deploy key added: %d" , ctx . Repo . Repository . ID )
2015-11-19 05:21:47 +03:00
ctx . Flash . Success ( ctx . Tr ( "repo.settings.add_key_success" , key . Name ) )
2015-08-06 17:48:11 +03:00
ctx . Redirect ( ctx . Repo . RepoLink + "/settings/keys" )
}
2016-11-24 10:04:31 +03:00
// DeleteDeployKey response for deleting a deploy key
2016-03-11 19:56:52 +03:00
func DeleteDeployKey ( ctx * context . Context ) {
2015-12-03 08:24:37 +03:00
if err := models . DeleteDeployKey ( ctx . User , ctx . QueryInt64 ( "id" ) ) ; err != nil {
2015-08-06 17:48:11 +03:00
ctx . Flash . Error ( "DeleteDeployKey: " + err . Error ( ) )
} else {
ctx . Flash . Success ( ctx . Tr ( "repo.settings.deploy_key_deletion_success" ) )
}
ctx . JSON ( 200 , map [ string ] interface { } {
"redirect" : ctx . Repo . RepoLink + "/settings/keys" ,
} )
2015-07-25 16:32:04 +03:00
}