mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-08 06:25:51 +01:00
Repository operation restrictions (#2469)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
version = "2.6.1"
|
version = "1.5.1"
|
||||||
project.git = true
|
project.git = true
|
||||||
|
|
||||||
maxColumn = 120
|
maxColumn = 120
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import gitbucket.core.util._
|
|||||||
import org.scalatra.i18n.Messages
|
import org.scalatra.i18n.Messages
|
||||||
import org.scalatra.BadRequest
|
import org.scalatra.BadRequest
|
||||||
import org.scalatra.forms._
|
import org.scalatra.forms._
|
||||||
|
import org.scalatra.Forbidden
|
||||||
|
|
||||||
class AccountController
|
class AccountController
|
||||||
extends AccountControllerBase
|
extends AccountControllerBase
|
||||||
@@ -691,27 +692,28 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
* Create new repository.
|
* Create new repository.
|
||||||
*/
|
*/
|
||||||
post("/new", newRepositoryForm)(usersOnly { form =>
|
post("/new", newRepositoryForm)(usersOnly { form =>
|
||||||
LockUtil.lock(s"${form.owner}/${form.name}") {
|
if (context.settings.repositoryOperation.create || context.loginAccount.get.isAdmin) {
|
||||||
if (getRepository(form.owner, form.name).isEmpty) {
|
LockUtil.lock(s"${form.owner}/${form.name}") {
|
||||||
createRepository(
|
if (getRepository(form.owner, form.name).isEmpty) {
|
||||||
context.loginAccount.get,
|
createRepository(
|
||||||
form.owner,
|
context.loginAccount.get,
|
||||||
form.name,
|
form.owner,
|
||||||
form.description,
|
form.name,
|
||||||
form.isPrivate,
|
form.description,
|
||||||
form.initOption,
|
form.isPrivate,
|
||||||
form.sourceUrl
|
form.initOption,
|
||||||
)
|
form.sourceUrl
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
// redirect to the repository
|
||||||
|
redirect(s"/${form.owner}/${form.name}")
|
||||||
// redirect to the repository
|
} else Forbidden()
|
||||||
redirect(s"/${form.owner}/${form.name}")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
get("/:owner/:repository/fork")(readableUsersOnly { repository =>
|
get("/:owner/:repository/fork")(readableUsersOnly { repository =>
|
||||||
if (repository.repository.options.allowFork) {
|
val loginAccount = context.loginAccount.get
|
||||||
val loginAccount = context.loginAccount.get
|
if (repository.repository.options.allowFork && (context.settings.repositoryOperation.fork || loginAccount.isAdmin)) {
|
||||||
val loginUserName = loginAccount.userName
|
val loginUserName = loginAccount.userName
|
||||||
val groups = getGroupsByUserName(loginUserName)
|
val groups = getGroupsByUserName(loginUserName)
|
||||||
groups match {
|
groups match {
|
||||||
@@ -735,8 +737,8 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
})
|
})
|
||||||
|
|
||||||
post("/:owner/:repository/fork", accountForm)(readableUsersOnly { (form, repository) =>
|
post("/:owner/:repository/fork", accountForm)(readableUsersOnly { (form, repository) =>
|
||||||
if (repository.repository.options.allowFork) {
|
val loginAccount = context.loginAccount.get
|
||||||
val loginAccount = context.loginAccount.get
|
if (repository.repository.options.allowFork && (context.settings.repositoryOperation.fork || loginAccount.isAdmin)) {
|
||||||
val loginUserName = loginAccount.userName
|
val loginUserName = loginAccount.userName
|
||||||
val accountName = form.accountName
|
val accountName = form.accountName
|
||||||
|
|
||||||
@@ -750,7 +752,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
// redirect to the repository
|
// redirect to the repository
|
||||||
redirect(s"/${accountName}/${repository.name}")
|
redirect(s"/${accountName}/${repository.name}")
|
||||||
}
|
}
|
||||||
} else BadRequest()
|
} else Forbidden()
|
||||||
})
|
})
|
||||||
|
|
||||||
private def existsAccount: Constraint = new Constraint() {
|
private def existsAccount: Constraint = new Constraint() {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.eclipse.jgit.lib.Constants
|
|||||||
import org.eclipse.jgit.lib.ObjectId
|
import org.eclipse.jgit.lib.ObjectId
|
||||||
|
|
||||||
import scala.util.Using
|
import scala.util.Using
|
||||||
|
import org.scalatra.Forbidden
|
||||||
|
|
||||||
class RepositorySettingsController
|
class RepositorySettingsController
|
||||||
extends RepositorySettingsControllerBase
|
extends RepositorySettingsControllerBase
|
||||||
@@ -44,7 +45,6 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
// for repository options
|
// for repository options
|
||||||
case class OptionsForm(
|
case class OptionsForm(
|
||||||
repositoryName: String,
|
|
||||||
description: Option[String],
|
description: Option[String],
|
||||||
isPrivate: Boolean,
|
isPrivate: Boolean,
|
||||||
issuesOption: String,
|
issuesOption: String,
|
||||||
@@ -57,9 +57,6 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val optionsForm = mapping(
|
val optionsForm = mapping(
|
||||||
"repositoryName" -> trim(
|
|
||||||
label("Repository Name", text(required, maxlength(100), repository, renameRepositoryName))
|
|
||||||
),
|
|
||||||
"description" -> trim(label("Description", optional(text()))),
|
"description" -> trim(label("Description", optional(text()))),
|
||||||
"isPrivate" -> trim(label("Repository Type", boolean())),
|
"isPrivate" -> trim(label("Repository Type", boolean())),
|
||||||
"issuesOption" -> trim(label("Issues Option", text(required, featureOption))),
|
"issuesOption" -> trim(label("Issues Option", text(required, featureOption))),
|
||||||
@@ -104,6 +101,15 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
(url, events, ctype, token) => WebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
|
(url, events, ctype, token) => WebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// for rename repository
|
||||||
|
case class RenameRepositoryForm(repositoryName: String)
|
||||||
|
|
||||||
|
val renameForm = mapping(
|
||||||
|
"repositoryName" -> trim(
|
||||||
|
label("New repository name", text(required, maxlength(100), repository, renameRepositoryName))
|
||||||
|
)
|
||||||
|
)(RenameRepositoryForm.apply)
|
||||||
|
|
||||||
// for transfer ownership
|
// for transfer ownership
|
||||||
case class TransferOwnerShipForm(newOwner: String)
|
case class TransferOwnerShipForm(newOwner: String)
|
||||||
|
|
||||||
@@ -144,13 +150,8 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
form.mergeOptions,
|
form.mergeOptions,
|
||||||
form.defaultMergeOption
|
form.defaultMergeOption
|
||||||
)
|
)
|
||||||
// Change repository name
|
|
||||||
if (repository.name != form.repositoryName) {
|
|
||||||
// Update database
|
|
||||||
renameRepository(repository.owner, repository.name, repository.owner, form.repositoryName)
|
|
||||||
}
|
|
||||||
flash.update("info", "Repository settings has been updated.")
|
flash.update("info", "Repository settings has been updated.")
|
||||||
redirect(s"/${repository.owner}/${form.repositoryName}/settings/options")
|
redirect(s"/${repository.owner}/${repository.name}/settings/options")
|
||||||
})
|
})
|
||||||
|
|
||||||
/** branch settings */
|
/** branch settings */
|
||||||
@@ -364,24 +365,40 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
html.danger(_, flash.get("info"))
|
html.danger(_, flash.get("info"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rename repository.
|
||||||
|
*/
|
||||||
|
post("/:owner/:repository/settings/rename", renameForm)(ownerOnly { (form, repository) =>
|
||||||
|
if (context.settings.repositoryOperation.rename || context.loginAccount.get.isAdmin) {
|
||||||
|
if (repository.name != form.repositoryName) {
|
||||||
|
renameRepository(repository.owner, repository.name, repository.owner, form.repositoryName)
|
||||||
|
}
|
||||||
|
redirect(s"/${repository.owner}/${form.repositoryName}")
|
||||||
|
} else Forbidden()
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfer repository ownership.
|
* Transfer repository ownership.
|
||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/transfer", transferForm)(ownerOnly { (form, repository) =>
|
post("/:owner/:repository/settings/transfer", transferForm)(ownerOnly { (form, repository) =>
|
||||||
// Change repository owner
|
if (context.settings.repositoryOperation.transfer || context.loginAccount.get.isAdmin) {
|
||||||
if (repository.owner != form.newOwner) {
|
// Change repository owner
|
||||||
renameRepository(repository.owner, repository.name, form.newOwner, repository.name)
|
if (repository.owner != form.newOwner) {
|
||||||
}
|
renameRepository(repository.owner, repository.name, form.newOwner, repository.name)
|
||||||
redirect(s"/${form.newOwner}/${repository.name}")
|
}
|
||||||
|
redirect(s"/${form.newOwner}/${repository.name}")
|
||||||
|
} else Forbidden()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the repository.
|
* Delete the repository.
|
||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/delete")(ownerOnly { repository =>
|
post("/:owner/:repository/settings/delete")(ownerOnly { repository =>
|
||||||
// Delete the repository and related files
|
if (context.settings.repositoryOperation.delete || context.loginAccount.get.isAdmin) {
|
||||||
deleteRepository(repository.repository)
|
// Delete the repository and related files
|
||||||
redirect(s"/${repository.owner}")
|
deleteRepository(repository.repository)
|
||||||
|
redirect(s"/${repository.owner}")
|
||||||
|
} else Forbidden()
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,7 +38,14 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
"information" -> trim(label("Information", optional(text()))),
|
"information" -> trim(label("Information", optional(text()))),
|
||||||
"allowAccountRegistration" -> trim(label("Account registration", boolean())),
|
"allowAccountRegistration" -> trim(label("Account registration", boolean())),
|
||||||
"allowAnonymousAccess" -> trim(label("Anonymous access", boolean())),
|
"allowAnonymousAccess" -> trim(label("Anonymous access", boolean())),
|
||||||
"isCreateRepoOptionPublic" -> trim(label("Default option to create a new repository", boolean())),
|
"isCreateRepoOptionPublic" -> trim(label("Default visibility of new repository", boolean())),
|
||||||
|
"repositoryOperation" -> mapping(
|
||||||
|
"create" -> trim(label("Allow all users to create repository", boolean())),
|
||||||
|
"delete" -> trim(label("Allow all users to delete repository", boolean())),
|
||||||
|
"rename" -> trim(label("Allow all users to rename repository", boolean())),
|
||||||
|
"transfer" -> trim(label("Allow all users to transfer repository", boolean())),
|
||||||
|
"fork" -> trim(label("Allow all users to fork repository", boolean()))
|
||||||
|
)(RepositoryOperation.apply),
|
||||||
"gravatar" -> trim(label("Gravatar", boolean())),
|
"gravatar" -> trim(label("Gravatar", boolean())),
|
||||||
"notification" -> trim(label("Notification", boolean())),
|
"notification" -> trim(label("Notification", boolean())),
|
||||||
"activityLogLimit" -> trim(label("Limit of activity logs", optional(number()))),
|
"activityLogLimit" -> trim(label("Limit of activity logs", optional(number()))),
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ trait SystemSettingsService {
|
|||||||
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
|
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
|
||||||
props.setProperty(AllowAnonymousAccess, settings.allowAnonymousAccess.toString)
|
props.setProperty(AllowAnonymousAccess, settings.allowAnonymousAccess.toString)
|
||||||
props.setProperty(IsCreateRepoOptionPublic, settings.isCreateRepoOptionPublic.toString)
|
props.setProperty(IsCreateRepoOptionPublic, settings.isCreateRepoOptionPublic.toString)
|
||||||
|
props.setProperty(RepositoryOperationCreate, settings.repositoryOperation.create.toString)
|
||||||
|
props.setProperty(RepositoryOperationDelete, settings.repositoryOperation.delete.toString)
|
||||||
|
props.setProperty(RepositoryOperationRename, settings.repositoryOperation.rename.toString)
|
||||||
|
props.setProperty(RepositoryOperationTransfer, settings.repositoryOperation.transfer.toString)
|
||||||
|
props.setProperty(RepositoryOperationFork, settings.repositoryOperation.fork.toString)
|
||||||
props.setProperty(Gravatar, settings.gravatar.toString)
|
props.setProperty(Gravatar, settings.gravatar.toString)
|
||||||
props.setProperty(Notification, settings.notification.toString)
|
props.setProperty(Notification, settings.notification.toString)
|
||||||
settings.activityLogLimit.foreach(x => props.setProperty(ActivityLogLimit, x.toString))
|
settings.activityLogLimit.foreach(x => props.setProperty(ActivityLogLimit, x.toString))
|
||||||
@@ -98,6 +103,13 @@ trait SystemSettingsService {
|
|||||||
getValue(props, AllowAccountRegistration, false),
|
getValue(props, AllowAccountRegistration, false),
|
||||||
getValue(props, AllowAnonymousAccess, true),
|
getValue(props, AllowAnonymousAccess, true),
|
||||||
getValue(props, IsCreateRepoOptionPublic, true),
|
getValue(props, IsCreateRepoOptionPublic, true),
|
||||||
|
RepositoryOperation(
|
||||||
|
create = getValue(props, RepositoryOperationCreate, true),
|
||||||
|
delete = getValue(props, RepositoryOperationDelete, true),
|
||||||
|
rename = getValue(props, RepositoryOperationRename, true),
|
||||||
|
transfer = getValue(props, RepositoryOperationTransfer, true),
|
||||||
|
fork = getValue(props, RepositoryOperationFork, true)
|
||||||
|
),
|
||||||
getValue(props, Gravatar, false),
|
getValue(props, Gravatar, false),
|
||||||
getValue(props, Notification, false),
|
getValue(props, Notification, false),
|
||||||
getOptionValue[Int](props, ActivityLogLimit, None),
|
getOptionValue[Int](props, ActivityLogLimit, None),
|
||||||
@@ -185,6 +197,7 @@ object SystemSettingsService {
|
|||||||
allowAccountRegistration: Boolean,
|
allowAccountRegistration: Boolean,
|
||||||
allowAnonymousAccess: Boolean,
|
allowAnonymousAccess: Boolean,
|
||||||
isCreateRepoOptionPublic: Boolean,
|
isCreateRepoOptionPublic: Boolean,
|
||||||
|
repositoryOperation: RepositoryOperation,
|
||||||
gravatar: Boolean,
|
gravatar: Boolean,
|
||||||
notification: Boolean,
|
notification: Boolean,
|
||||||
activityLogLimit: Option[Int],
|
activityLogLimit: Option[Int],
|
||||||
@@ -226,6 +239,14 @@ object SystemSettingsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case class RepositoryOperation(
|
||||||
|
create: Boolean,
|
||||||
|
delete: Boolean,
|
||||||
|
rename: Boolean,
|
||||||
|
transfer: Boolean,
|
||||||
|
fork: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
case class Ssh(
|
case class Ssh(
|
||||||
enabled: Boolean,
|
enabled: Boolean,
|
||||||
sshHost: Option[String],
|
sshHost: Option[String],
|
||||||
@@ -291,6 +312,11 @@ object SystemSettingsService {
|
|||||||
private val AllowAccountRegistration = "allow_account_registration"
|
private val AllowAccountRegistration = "allow_account_registration"
|
||||||
private val AllowAnonymousAccess = "allow_anonymous_access"
|
private val AllowAnonymousAccess = "allow_anonymous_access"
|
||||||
private val IsCreateRepoOptionPublic = "is_create_repository_option_public"
|
private val IsCreateRepoOptionPublic = "is_create_repository_option_public"
|
||||||
|
private val RepositoryOperationCreate = "repository_operation_create"
|
||||||
|
private val RepositoryOperationDelete = "repository_operation_delete"
|
||||||
|
private val RepositoryOperationRename = "repository_operation_rename"
|
||||||
|
private val RepositoryOperationTransfer = "repository_operation_transfer"
|
||||||
|
private val RepositoryOperationFork = "repository_operation_fork"
|
||||||
private val Gravatar = "gravatar"
|
private val Gravatar = "gravatar"
|
||||||
private val Notification = "notification"
|
private val Notification = "notification"
|
||||||
private val ActivityLogLimit = "activity_log_limit"
|
private val ActivityLogLimit = "activity_log_limit"
|
||||||
|
|||||||
@@ -116,8 +116,80 @@
|
|||||||
<span class="strong">Deny</span> <span class="normal">- Only administrators can create accounts.</span>
|
<span class="strong">Deny</span> <span class="normal">- Only administrators can create accounts.</span>
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<!--====================================================================-->
|
||||||
|
<!-- Repository operations -->
|
||||||
|
<!--====================================================================-->
|
||||||
<hr>
|
<hr>
|
||||||
<label class="strong">Default permissions when creating a new repository</label>
|
<label class="strong">Repository operation</label>
|
||||||
|
<fieldset>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Create</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.create" value="true"@if(context.settings.repositoryOperation.create){ checked}>
|
||||||
|
<span class="strong">All users</span> <span class="normal">- All users can create repository.</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.create" value="false"@if(!context.settings.repositoryOperation.create){ checked}>
|
||||||
|
<span class="strong">Admin only</span> <span class="normal">- Only administrators can create repository.</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Delete</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.delete" value="true"@if(context.settings.repositoryOperation.delete){ checked}>
|
||||||
|
<span class="strong">All users</span> <span class="normal">- All users can delete repository.</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.delete" value="false"@if(!context.settings.repositoryOperation.delete){ checked}>
|
||||||
|
<span class="strong">Admin only</span> <span class="normal">- Only administrators can delete repository.</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Rename</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.rename" value="true"@if(context.settings.repositoryOperation.rename){ checked}>
|
||||||
|
<span class="strong">All users</span> <span class="normal">- All users can rename repository.</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.rename" value="false"@if(!context.settings.repositoryOperation.rename){ checked}>
|
||||||
|
<span class="strong">Admin only</span> <span class="normal">- Only administrators can rename repository.</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Transfer</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.transfer" value="true"@if(context.settings.repositoryOperation.transfer){ checked}>
|
||||||
|
<span class="strong">All users</span> <span class="normal">- All users can transfer repository.</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.transfer" value="false"@if(!context.settings.repositoryOperation.transfer){ checked}>
|
||||||
|
<span class="strong">Admin only</span> <span class="normal">- Only administrators can transfer repository.</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-2">Fork</label>
|
||||||
|
<div class="col-md-10">
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.fork" value="true"@if(context.settings.repositoryOperation.fork){ checked}>
|
||||||
|
<span class="strong">All users</span> <span class="normal">- All users can fork repository.</span>
|
||||||
|
</label>
|
||||||
|
<label class="radio">
|
||||||
|
<input type="radio" name="repositoryOperation.fork" value="false"@if(!context.settings.repositoryOperation.fork){ checked}>
|
||||||
|
<span class="strong">Admin only</span> <span class="normal">- Only administrators can fork repository.</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<hr>
|
||||||
|
<label class="strong">Default visibility when creating a new repository</label>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="isCreateRepoOptionPublic" value="true"@if(context.settings.isCreateRepoOptionPublic){ checked}>
|
<input type="radio" name="isCreateRepoOptionPublic" value="true"@if(context.settings.isCreateRepoOptionPublic){ checked}>
|
||||||
|
|||||||
@@ -102,7 +102,9 @@
|
|||||||
<ul class="dropdown-menu pull-right" style="width: auto;">
|
<ul class="dropdown-menu pull-right" style="width: auto;">
|
||||||
<li>
|
<li>
|
||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li><a href="@context.path/new">New repository</a></li>
|
@if(context.settings.repositoryOperation.create || context.loginAccount.get.isAdmin){
|
||||||
|
<li><a href="@context.path/new">New repository</a></li>
|
||||||
|
}
|
||||||
<li><a href="@context.path/groups/new">New group</a></li>
|
<li><a href="@context.path/groups/new">New group</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
@gitbucket.core.plugin.PluginRegistry().getRepositoryHeaders.map { repositoryHeaderComponent =>
|
@gitbucket.core.plugin.PluginRegistry().getRepositoryHeaders.map { repositoryHeaderComponent =>
|
||||||
@repositoryHeaderComponent(repository, context)
|
@repositoryHeaderComponent(repository, context)
|
||||||
}
|
}
|
||||||
@if(repository.repository.options.allowFork) {
|
@if(repository.repository.options.allowFork && (context.settings.repositoryOperation.fork || context.loginAccount.map(_.isAdmin).getOrElse(false))) {
|
||||||
@if(context.loginAccount.isEmpty){
|
@if(context.loginAccount.isEmpty){
|
||||||
<a class="btn btn-default btn-sm" href="@context.path/signin?redirect=@helpers.urlEncode(s"${context.path}/${repository.owner}/${repository.name}")">
|
<a class="btn btn-default btn-sm" href="@context.path/signin?redirect=@helpers.urlEncode(s"${context.path}/${repository.owner}/${repository.name}")">
|
||||||
<span class="strong"><i class="octicon octicon-repo-forked"></i>Fork</span><span class="muted">: @repository.forkedCount</span>
|
<span class="strong"><i class="octicon octicon-repo-forked"></i>Fork</span><span class="muted">: @repository.forkedCount</span>
|
||||||
|
|||||||
@@ -7,32 +7,8 @@
|
|||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading strong">Danger Zone</div>
|
<div class="panel-heading strong">Danger Zone</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form id="transfer-form" method="post" action="@helpers.url(repository)/settings/transfer" validate="true" autocomplete="off">
|
|
||||||
<fieldset class="form-group">
|
|
||||||
<label class="strong">Transfer Ownership</label>
|
|
||||||
<div>
|
|
||||||
Transfer this repo to another user or to group.
|
|
||||||
<div class="pull-right">
|
|
||||||
@gitbucket.core.helper.html.account("newOwner", 200, true, true)
|
|
||||||
<input type="submit" class="btn btn-danger" value="Transfer"/>
|
|
||||||
<div>
|
|
||||||
<span id="error-newOwner" class="error"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
<form id="delete-form" method="post" action="@helpers.url(repository)/settings/delete">
|
|
||||||
<fieldset class="border-top form-group">
|
|
||||||
<label class="strong">Delete repository</label>
|
|
||||||
<div>
|
|
||||||
Once you delete a repository, there is no going back.
|
|
||||||
<input type="submit" class="btn btn-danger pull-right" value="Delete this repository"/>
|
|
||||||
</div>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
<form id="gc-form" method="post" action="@helpers.url(repository)/settings/gc">
|
<form id="gc-form" method="post" action="@helpers.url(repository)/settings/gc">
|
||||||
<fieldset class="border-top form-group">
|
<fieldset class="form-group">
|
||||||
<label class="strong">Garbage collection</label>
|
<label class="strong">Garbage collection</label>
|
||||||
<div>
|
<div>
|
||||||
Run garbage collection for this git repository immediately.
|
Run garbage collection for this git repository immediately.
|
||||||
@@ -40,6 +16,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
|
@if(context.settings.repositoryOperation.rename || context.loginAccount.get.isAdmin){
|
||||||
|
<form id="rename-form" method="post" action="@helpers.url(repository)/settings/rename" validate="true" autocomplete="off">
|
||||||
|
<fieldset class="border-top form-group">
|
||||||
|
<label class="strong">Rename repository</label>
|
||||||
|
<div>
|
||||||
|
Rename this repository. The current URL will be unavailable.
|
||||||
|
<div class="pull-right">
|
||||||
|
<input type="text" name="repositoryName" id="repositoryName" class="form-control" style="width: 200px; display: inline; vertical-align: middle;" value="@repository.name"/>
|
||||||
|
<input type="submit" class="btn btn-danger" value="Rename"/>
|
||||||
|
<div>
|
||||||
|
<span id="error-repositoryName" class="error"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
@if(context.settings.repositoryOperation.transfer || context.loginAccount.get.isAdmin){
|
||||||
|
<form id="transfer-form" method="post" action="@helpers.url(repository)/settings/transfer" validate="true" autocomplete="off">
|
||||||
|
<fieldset class="border-top form-group">
|
||||||
|
<label class="strong">Transfer Ownership</label>
|
||||||
|
<div>
|
||||||
|
Transfer this repo to another user or to group.
|
||||||
|
<div class="pull-right">
|
||||||
|
@gitbucket.core.helper.html.account("newOwner", 200, true, true)
|
||||||
|
<input type="submit" class="btn btn-danger" value="Transfer"/>
|
||||||
|
<div>
|
||||||
|
<span id="error-newOwner" class="error"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
@if(context.settings.repositoryOperation.delete || context.loginAccount.get.isAdmin){
|
||||||
|
<form id="delete-form" method="post" action="@helpers.url(repository)/settings/delete">
|
||||||
|
<fieldset class="border-top form-group">
|
||||||
|
<label class="strong">Delete repository</label>
|
||||||
|
<div>
|
||||||
|
Once you delete a repository, there is no going back.
|
||||||
|
<input type="submit" class="btn btn-danger pull-right" value="Delete this repository"/>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -50,6 +71,13 @@ $(function(){
|
|||||||
$('#delete-form').submit(function(){
|
$('#delete-form').submit(function(){
|
||||||
return confirm('Once you delete a repository, there is no going back.\nAre you sure?');
|
return confirm('Once you delete a repository, there is no going back.\nAre you sure?');
|
||||||
});
|
});
|
||||||
|
$('#rename-form').submit(function(){
|
||||||
|
if($('#rename-form').data('validated') === true){
|
||||||
|
return confirm('Rename this repository as you entered. The current URL will be unavailable.\nAre you sure?');
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
$('#transfer-form').submit(function(){
|
$('#transfer-form').submit(function(){
|
||||||
if($('#transfer-form').data('validated') === true){
|
if($('#transfer-form').data('validated') === true){
|
||||||
return confirm('Transfer to the repository owner you entered.\nAre you sure?');
|
return confirm('Transfer to the repository owner you entered.\nAre you sure?');
|
||||||
|
|||||||
@@ -9,11 +9,6 @@
|
|||||||
<div class="panel-heading strong">Settings</div>
|
<div class="panel-heading strong">Settings</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<label for="repositoryName" class="strong">Repository Name:</label>
|
|
||||||
<input type="text" name="repositoryName" id="repositoryName" class="form-control" value="@repository.name"/>
|
|
||||||
<span id="error-repositoryName" class="error"></span>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="border-top form-group">
|
|
||||||
<label for="description" class="strong">Description:</label>
|
<label for="description" class="strong">Description:</label>
|
||||||
<input type="text" name="description" id="description" class="form-control" value="@repository.repository.description"/>
|
<input type="text" name="description" id="description" class="form-control" value="@repository.repository.description"/>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import java.sql.DriverManager
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings}
|
import gitbucket.core.service.SystemSettingsService.{RepositoryOperation, Ssh, SystemSettings}
|
||||||
import javax.servlet.http.{HttpServletRequest, HttpSession}
|
import javax.servlet.http.{HttpServletRequest, HttpSession}
|
||||||
import org.scalatestplus.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
import org.mockito.Mockito._
|
import org.mockito.Mockito._
|
||||||
@@ -36,6 +36,13 @@ trait ServiceSpecBase extends MockitoSugar {
|
|||||||
allowAccountRegistration = false,
|
allowAccountRegistration = false,
|
||||||
allowAnonymousAccess = true,
|
allowAnonymousAccess = true,
|
||||||
isCreateRepoOptionPublic = true,
|
isCreateRepoOptionPublic = true,
|
||||||
|
repositoryOperation = RepositoryOperation(
|
||||||
|
create = true,
|
||||||
|
delete = true,
|
||||||
|
rename = true,
|
||||||
|
transfer = true,
|
||||||
|
fork = true
|
||||||
|
),
|
||||||
gravatar = false,
|
gravatar = false,
|
||||||
notification = false,
|
notification = false,
|
||||||
activityLogLimit = None,
|
activityLogLimit = None,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import javax.servlet.http.{HttpServletRequest, HttpSession}
|
|||||||
import gitbucket.core.controller.Context
|
import gitbucket.core.controller.Context
|
||||||
import gitbucket.core.model.Account
|
import gitbucket.core.model.Account
|
||||||
import gitbucket.core.service.RequestCache
|
import gitbucket.core.service.RequestCache
|
||||||
import gitbucket.core.service.SystemSettingsService.{Ssh, SystemSettings, WebHook, Upload}
|
import gitbucket.core.service.SystemSettingsService.{RepositoryOperation, Ssh, SystemSettings, Upload, WebHook}
|
||||||
import org.mockito.Mockito._
|
import org.mockito.Mockito._
|
||||||
import org.scalatest.FunSpec
|
import org.scalatest.FunSpec
|
||||||
import org.scalatestplus.mockito.MockitoSugar
|
import org.scalatestplus.mockito.MockitoSugar
|
||||||
@@ -122,6 +122,13 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
|||||||
allowAccountRegistration = false,
|
allowAccountRegistration = false,
|
||||||
allowAnonymousAccess = true,
|
allowAnonymousAccess = true,
|
||||||
isCreateRepoOptionPublic = true,
|
isCreateRepoOptionPublic = true,
|
||||||
|
repositoryOperation = RepositoryOperation(
|
||||||
|
create = true,
|
||||||
|
delete = true,
|
||||||
|
rename = true,
|
||||||
|
transfer = true,
|
||||||
|
fork = true
|
||||||
|
),
|
||||||
gravatar = useGravatar,
|
gravatar = useGravatar,
|
||||||
notification = false,
|
notification = false,
|
||||||
activityLogLimit = None,
|
activityLogLimit = None,
|
||||||
|
|||||||
Reference in New Issue
Block a user