mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-08 22:45:51 +01:00
Merge branch 'wip/baseurl' of https://github.com/ritschwumm/gitbucket into ritschwumm-wip/baseurl
This commit is contained in:
@@ -133,7 +133,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
val members = getGroupMembers(account.userName)
|
val members = getGroupMembers(account.userName)
|
||||||
gitbucket.core.account.html.repositories(account,
|
gitbucket.core.account.html.repositories(account,
|
||||||
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
||||||
getVisibleRepositories(context.loginAccount, context.baseUrl, Some(userName)),
|
getVisibleRepositories(context.loginAccount, Some(userName)),
|
||||||
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
|
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,7 +366,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
*/
|
*/
|
||||||
post("/new", newRepositoryForm)(usersOnly { form =>
|
post("/new", newRepositoryForm)(usersOnly { form =>
|
||||||
LockUtil.lock(s"${form.owner}/${form.name}"){
|
LockUtil.lock(s"${form.owner}/${form.name}"){
|
||||||
if(getRepository(form.owner, form.name, context.baseUrl).isEmpty){
|
if(getRepository(form.owner, form.name).isEmpty){
|
||||||
createRepository(form.owner, form.name, form.description, form.isPrivate, form.createReadme)
|
createRepository(form.owner, form.name, form.description, form.isPrivate, form.createReadme)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,9 +385,9 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
data <- extractFromJsonBody[CreateARepository] if data.isValid
|
data <- extractFromJsonBody[CreateARepository] if data.isValid
|
||||||
} yield {
|
} yield {
|
||||||
LockUtil.lock(s"${owner}/${data.name}") {
|
LockUtil.lock(s"${owner}/${data.name}") {
|
||||||
if(getRepository(owner, data.name, context.baseUrl).isEmpty){
|
if(getRepository(owner, data.name).isEmpty){
|
||||||
createRepository(owner, data.name, data.description, data.`private`, data.auto_init)
|
createRepository(owner, data.name, data.description, data.`private`, data.auto_init)
|
||||||
val repository = getRepository(owner, data.name, context.baseUrl).get
|
val repository = getRepository(owner, data.name).get
|
||||||
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(owner).get)))
|
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(owner).get)))
|
||||||
} else {
|
} else {
|
||||||
ApiError(
|
ApiError(
|
||||||
@@ -409,9 +409,9 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
data <- extractFromJsonBody[CreateARepository] if data.isValid
|
data <- extractFromJsonBody[CreateARepository] if data.isValid
|
||||||
} yield {
|
} yield {
|
||||||
LockUtil.lock(s"${groupName}/${data.name}") {
|
LockUtil.lock(s"${groupName}/${data.name}") {
|
||||||
if(getRepository(groupName, data.name, context.baseUrl).isEmpty){
|
if(getRepository(groupName, data.name).isEmpty){
|
||||||
createRepository(groupName, data.name, data.description, data.`private`, data.auto_init)
|
createRepository(groupName, data.name, data.description, data.`private`, data.auto_init)
|
||||||
val repository = getRepository(groupName, data.name, context.baseUrl).get
|
val repository = getRepository(groupName, data.name).get
|
||||||
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(groupName).get)))
|
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(groupName).get)))
|
||||||
} else {
|
} else {
|
||||||
ApiError(
|
ApiError(
|
||||||
@@ -447,7 +447,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
val accountName = form.accountName
|
val accountName = form.accountName
|
||||||
|
|
||||||
LockUtil.lock(s"${accountName}/${repository.name}"){
|
LockUtil.lock(s"${accountName}/${repository.name}"){
|
||||||
if(getRepository(accountName, repository.name, baseUrl).isDefined ||
|
if(getRepository(accountName, repository.name).isDefined ||
|
||||||
(accountName != loginUserName && !getGroupsByUserName(loginUserName).contains(accountName))){
|
(accountName != loginUserName && !getGroupsByUserName(loginUserName).contains(accountName))){
|
||||||
// redirect to the repository if repository already exists
|
// redirect to the repository if repository already exists
|
||||||
redirect(s"/${accountName}/${repository.name}")
|
redirect(s"/${accountName}/${repository.name}")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package gitbucket.core.controller
|
|||||||
import gitbucket.core.api.ApiError
|
import gitbucket.core.api.ApiError
|
||||||
import gitbucket.core.model.Account
|
import gitbucket.core.model.Account
|
||||||
import gitbucket.core.service.{AccountService, SystemSettingsService}
|
import gitbucket.core.service.{AccountService, SystemSettingsService}
|
||||||
|
import gitbucket.core.service.RepositoryService.{RepositoryInfo, RepositoryUrls}
|
||||||
import gitbucket.core.util.ControlUtil._
|
import gitbucket.core.util.ControlUtil._
|
||||||
import gitbucket.core.util.Directory._
|
import gitbucket.core.util.Directory._
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
@@ -180,11 +181,12 @@ abstract class ControllerBase extends ScalatraFilter
|
|||||||
* Context object for the current request.
|
* Context object for the current request.
|
||||||
*/
|
*/
|
||||||
case class Context(settings: SystemSettingsService.SystemSettings, loginAccount: Option[Account], request: HttpServletRequest){
|
case class Context(settings: SystemSettingsService.SystemSettings, loginAccount: Option[Account], request: HttpServletRequest){
|
||||||
|
|
||||||
val path = settings.baseUrl.getOrElse(request.getContextPath)
|
val path = settings.baseUrl.getOrElse(request.getContextPath)
|
||||||
val currentPath = request.getRequestURI.substring(request.getContextPath.length)
|
val currentPath = request.getRequestURI.substring(request.getContextPath.length)
|
||||||
val baseUrl = settings.baseUrl(request)
|
val baseUrl = settings.baseUrl(request)
|
||||||
val host = new java.net.URL(baseUrl).getHost
|
val host = new java.net.URL(baseUrl).getHost
|
||||||
|
val urls = (repositoryInfo:RepositoryInfo) => new RepositoryUrls(baseUrl, settings.sshAddress, repositoryInfo.owner, repositoryInfo.name)
|
||||||
|
val wikiUrls = (repositoryInfo:RepositoryInfo) => new RepositoryUrls(baseUrl, settings.sshAddress, repositoryInfo.owner, repositoryInfo.name + ".wiki")
|
||||||
val platform = request.getHeader("User-Agent") match {
|
val platform = request.getHeader("User-Agent") match {
|
||||||
case null => null
|
case null => null
|
||||||
case agent if agent.contains("Mac") => "mac"
|
case agent if agent.contains("Mac") => "mac"
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ trait DashboardControllerBase extends ControllerBase {
|
|||||||
|
|
||||||
val userName = context.loginAccount.get.userName
|
val userName = context.loginAccount.get.userName
|
||||||
val condition = getOrCreateCondition(Keys.Session.DashboardIssues, filter, userName)
|
val condition = getOrCreateCondition(Keys.Session.DashboardIssues, filter, userName)
|
||||||
val userRepos = getUserRepositories(userName, context.baseUrl, true).map(repo => repo.owner -> repo.name)
|
val userRepos = getUserRepositories(userName, true).map(repo => repo.owner -> repo.name)
|
||||||
val page = IssueSearchCondition.page(request)
|
val page = IssueSearchCondition.page(request)
|
||||||
|
|
||||||
html.issues(
|
html.issues(
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
val loginAccount = context.loginAccount
|
val loginAccount = context.loginAccount
|
||||||
if(loginAccount.isEmpty) {
|
if(loginAccount.isEmpty) {
|
||||||
html.index(getRecentActivities(),
|
html.index(getRecentActivities(),
|
||||||
getVisibleRepositories(loginAccount, context.baseUrl, withoutPhysicalInfo = true),
|
getVisibleRepositories(loginAccount, withoutPhysicalInfo = true),
|
||||||
loginAccount.map{ account => getUserRepositories(account.userName, context.baseUrl, withoutPhysicalInfo = true) }.getOrElse(Nil)
|
loginAccount.map{ account => getUserRepositories(account.userName, withoutPhysicalInfo = true) }.getOrElse(Nil)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val loginUserName = loginAccount.get.userName
|
val loginUserName = loginAccount.get.userName
|
||||||
@@ -40,8 +40,8 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
visibleOwnerSet ++= loginUserGroups
|
visibleOwnerSet ++= loginUserGroups
|
||||||
|
|
||||||
html.index(getRecentActivitiesByOwners(visibleOwnerSet),
|
html.index(getRecentActivitiesByOwners(visibleOwnerSet),
|
||||||
getVisibleRepositories(loginAccount, context.baseUrl, withoutPhysicalInfo = true),
|
getVisibleRepositories(loginAccount, withoutPhysicalInfo = true),
|
||||||
loginAccount.map{ account => getUserRepositories(account.userName, context.baseUrl, withoutPhysicalInfo = true) }.getOrElse(Nil)
|
loginAccount.map{ account => getUserRepositories(account.userName, withoutPhysicalInfo = true) }.getOrElse(Nil)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
baseOwner <- users.get(repository.owner)
|
baseOwner <- users.get(repository.owner)
|
||||||
headOwner <- users.get(pullRequest.requestUserName)
|
headOwner <- users.get(pullRequest.requestUserName)
|
||||||
issueUser <- users.get(issue.openedUserName)
|
issueUser <- users.get(issue.openedUserName)
|
||||||
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName, baseUrl)
|
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
|
||||||
} yield {
|
} yield {
|
||||||
JsonFormat(ApiPullRequest(
|
JsonFormat(ApiPullRequest(
|
||||||
issue,
|
issue,
|
||||||
@@ -196,7 +196,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
issue,
|
issue,
|
||||||
pullreq,
|
pullreq,
|
||||||
repository,
|
repository,
|
||||||
getRepository(pullreq.requestUserName, pullreq.requestRepositoryName, context.baseUrl).get)
|
getRepository(pullreq.requestUserName, pullreq.requestRepositoryName).get)
|
||||||
}
|
}
|
||||||
} getOrElse NotFound
|
} getOrElse NotFound
|
||||||
})
|
})
|
||||||
@@ -229,7 +229,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
if(branchProtection.needStatusCheck(loginAccount.userName)){
|
if(branchProtection.needStatusCheck(loginAccount.userName)){
|
||||||
flash += "error" -> s"branch ${pullreq.requestBranch} is protected need status check."
|
flash += "error" -> s"branch ${pullreq.requestBranch} is protected need status check."
|
||||||
} else {
|
} else {
|
||||||
val repository = getRepository(owner, name, context.baseUrl).get
|
val repository = getRepository(owner, name).get
|
||||||
LockUtil.lock(s"${owner}/${name}"){
|
LockUtil.lock(s"${owner}/${name}"){
|
||||||
val alias = if(pullreq.repositoryName == pullreq.requestRepositoryName && pullreq.userName == pullreq.requestUserName){
|
val alias = if(pullreq.repositoryName == pullreq.requestRepositoryName && pullreq.userName == pullreq.requestUserName){
|
||||||
pullreq.branch
|
pullreq.branch
|
||||||
@@ -310,7 +310,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
|
pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
|
||||||
|
|
||||||
// close issue by content of pull request
|
// close issue by content of pull request
|
||||||
val defaultBranch = getRepository(owner, name, context.baseUrl).get.repository.defaultBranch
|
val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
|
||||||
if(pullreq.branch == defaultBranch){
|
if(pullreq.branch == defaultBranch){
|
||||||
commits.flatten.foreach { commit =>
|
commits.flatten.foreach { commit =>
|
||||||
closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
|
closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
|
||||||
@@ -343,7 +343,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
val headBranch:Option[String] = params.get("head")
|
val headBranch:Option[String] = params.get("head")
|
||||||
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
|
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
|
||||||
case (Some(originUserName), Some(originRepositoryName)) => {
|
case (Some(originUserName), Some(originRepositoryName)) => {
|
||||||
getRepository(originUserName, originRepositoryName, context.baseUrl).map { originRepository =>
|
getRepository(originUserName, originRepositoryName).map { originRepository =>
|
||||||
using(
|
using(
|
||||||
Git.open(getRepositoryDir(originUserName, originRepositoryName)),
|
Git.open(getRepositoryDir(originUserName, originRepositoryName)),
|
||||||
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
|
||||||
@@ -384,12 +384,12 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
forkedRepository.repository.originRepositoryName
|
forkedRepository.repository.originRepositoryName
|
||||||
} else {
|
} else {
|
||||||
// Sibling repository
|
// Sibling repository
|
||||||
getUserRepositories(originOwner, context.baseUrl).find { x =>
|
getUserRepositories(originOwner).find { x =>
|
||||||
x.repository.originUserName == forkedRepository.repository.originUserName &&
|
x.repository.originUserName == forkedRepository.repository.originUserName &&
|
||||||
x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName
|
x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName
|
||||||
}.map(_.repository.repositoryName)
|
}.map(_.repository.repositoryName)
|
||||||
};
|
};
|
||||||
originRepository <- getRepository(originOwner, originRepositoryName, context.baseUrl)
|
originRepository <- getRepository(originOwner, originRepositoryName)
|
||||||
) yield {
|
) yield {
|
||||||
using(
|
using(
|
||||||
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
||||||
@@ -457,7 +457,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2)
|
getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_._1 == originOwner).map(_._2)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
originRepository <- getRepository(originOwner, originRepositoryName, context.baseUrl)
|
originRepository <- getRepository(originOwner, originRepositoryName)
|
||||||
) yield {
|
) yield {
|
||||||
using(
|
using(
|
||||||
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
|
||||||
|
|||||||
@@ -560,8 +560,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
html.forked(
|
html.forked(
|
||||||
getRepository(
|
getRepository(
|
||||||
repository.repository.originUserName.getOrElse(repository.owner),
|
repository.repository.originUserName.getOrElse(repository.owner),
|
||||||
repository.repository.originRepositoryName.getOrElse(repository.name),
|
repository.repository.originRepositoryName.getOrElse(repository.name)),
|
||||||
context.baseUrl),
|
|
||||||
getForkedRepositories(
|
getForkedRepositories(
|
||||||
repository.repository.originUserName.getOrElse(repository.owner),
|
repository.repository.originUserName.getOrElse(repository.owner),
|
||||||
repository.repository.originRepositoryName.getOrElse(repository.name)),
|
repository.repository.originRepositoryName.getOrElse(repository.name)),
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ trait SystemSettingsControllerBase extends ControllerBase {
|
|||||||
"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()))),
|
||||||
"ssh" -> trim(label("SSH access", boolean())),
|
"ssh" -> trim(label("SSH access", boolean())),
|
||||||
|
"sshHost" -> trim(label("SSH host", optional(text()))),
|
||||||
"sshPort" -> trim(label("SSH port", optional(number()))),
|
"sshPort" -> trim(label("SSH port", optional(number()))),
|
||||||
"useSMTP" -> trim(label("SMTP", boolean())),
|
"useSMTP" -> trim(label("SMTP", boolean())),
|
||||||
"smtp" -> optionalIfNotChecked("useSMTP", mapping(
|
"smtp" -> optionalIfNotChecked("useSMTP", mapping(
|
||||||
@@ -50,9 +51,14 @@ trait SystemSettingsControllerBase extends ControllerBase {
|
|||||||
"keystore" -> trim(label("Keystore", optional(text())))
|
"keystore" -> trim(label("Keystore", optional(text())))
|
||||||
)(Ldap.apply))
|
)(Ldap.apply))
|
||||||
)(SystemSettings.apply).verifying { settings =>
|
)(SystemSettings.apply).verifying { settings =>
|
||||||
|
Vector(
|
||||||
if(settings.ssh && settings.baseUrl.isEmpty){
|
if(settings.ssh && settings.baseUrl.isEmpty){
|
||||||
Seq("baseUrl" -> "Base URL is required if SSH access is enabled.")
|
Some("baseUrl" -> "Base URL is required if SSH access is enabled.")
|
||||||
} else Nil
|
} else None,
|
||||||
|
if(settings.ssh && settings.sshHost.isEmpty){
|
||||||
|
Some("sshHost" -> "SSH host is required if SSH access is enabled.")
|
||||||
|
} else None
|
||||||
|
).flatten
|
||||||
}
|
}
|
||||||
|
|
||||||
private val pluginForm = mapping(
|
private val pluginForm = mapping(
|
||||||
@@ -68,16 +74,13 @@ trait SystemSettingsControllerBase extends ControllerBase {
|
|||||||
post("/admin/system", form)(adminOnly { form =>
|
post("/admin/system", form)(adminOnly { form =>
|
||||||
saveSystemSettings(form)
|
saveSystemSettings(form)
|
||||||
|
|
||||||
if(form.ssh && SshServer.isActive && context.settings.sshPort != form.sshPort){
|
if (form.sshAddress != context.settings.sshAddress) {
|
||||||
SshServer.stop()
|
SshServer.stop()
|
||||||
|
for {
|
||||||
|
sshAddress <- form.sshAddress
|
||||||
|
baseUrl <- form.baseUrl
|
||||||
}
|
}
|
||||||
|
SshServer.start(sshAddress, baseUrl)
|
||||||
if(form.ssh && !SshServer.isActive && form.baseUrl.isDefined){
|
|
||||||
SshServer.start(
|
|
||||||
form.sshPort.getOrElse(SystemSettingsService.DefaultSshPort),
|
|
||||||
form.baseUrl.get)
|
|
||||||
} else if(!form.ssh && SshServer.isActive){
|
|
||||||
SshServer.stop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flash += "info" -> "System settings has been updated."
|
flash += "info" -> "System settings has been updated."
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
|
import gitbucket.core.service.SystemSettingsService.SshAddress
|
||||||
import gitbucket.core.model.{Collaborator, Repository, Account}
|
import gitbucket.core.model.{Collaborator, Repository, Account}
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import gitbucket.core.util.JGitUtil
|
import gitbucket.core.util.JGitUtil
|
||||||
@@ -194,10 +195,9 @@ trait RepositoryService { self: AccountService =>
|
|||||||
*
|
*
|
||||||
* @param userName the user name of the repository owner
|
* @param userName the user name of the repository owner
|
||||||
* @param repositoryName the repository name
|
* @param repositoryName the repository name
|
||||||
* @param baseUrl the base url of this application
|
|
||||||
* @return the repository information
|
* @return the repository information
|
||||||
*/
|
*/
|
||||||
def getRepository(userName: String, repositoryName: String, baseUrl: String)(implicit s: Session): Option[RepositoryInfo] = {
|
def getRepository(userName: String, repositoryName: String)(implicit s: Session): Option[RepositoryInfo] = {
|
||||||
(Repositories filter { t => t.byRepository(userName, repositoryName) } firstOption) map { repository =>
|
(Repositories filter { t => t.byRepository(userName, repositoryName) } firstOption) map { repository =>
|
||||||
// for getting issue count and pull request count
|
// for getting issue count and pull request count
|
||||||
val issues = Issues.filter { t =>
|
val issues = Issues.filter { t =>
|
||||||
@@ -205,7 +205,7 @@ trait RepositoryService { self: AccountService =>
|
|||||||
}.map(_.pullRequest).list
|
}.map(_.pullRequest).list
|
||||||
|
|
||||||
new RepositoryInfo(
|
new RepositoryInfo(
|
||||||
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl),
|
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName),
|
||||||
repository,
|
repository,
|
||||||
issues.count(_ == false),
|
issues.count(_ == false),
|
||||||
issues.count(_ == true),
|
issues.count(_ == true),
|
||||||
@@ -234,7 +234,7 @@ trait RepositoryService { self: AccountService =>
|
|||||||
}.list
|
}.list
|
||||||
}
|
}
|
||||||
|
|
||||||
def getUserRepositories(userName: String, baseUrl: String, withoutPhysicalInfo: Boolean = false)
|
def getUserRepositories(userName: String, withoutPhysicalInfo: Boolean = false)
|
||||||
(implicit s: Session): List[RepositoryInfo] = {
|
(implicit s: Session): List[RepositoryInfo] = {
|
||||||
Repositories.filter { t1 =>
|
Repositories.filter { t1 =>
|
||||||
(t1.userName === userName.bind) ||
|
(t1.userName === userName.bind) ||
|
||||||
@@ -242,9 +242,9 @@ trait RepositoryService { self: AccountService =>
|
|||||||
}.sortBy(_.lastActivityDate desc).list.map{ repository =>
|
}.sortBy(_.lastActivityDate desc).list.map{ repository =>
|
||||||
new RepositoryInfo(
|
new RepositoryInfo(
|
||||||
if(withoutPhysicalInfo){
|
if(withoutPhysicalInfo){
|
||||||
new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName, baseUrl)
|
new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
|
||||||
} else {
|
} else {
|
||||||
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl)
|
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
|
||||||
},
|
},
|
||||||
repository,
|
repository,
|
||||||
getForkedCount(
|
getForkedCount(
|
||||||
@@ -260,13 +260,12 @@ trait RepositoryService { self: AccountService =>
|
|||||||
* If repositoryUserName is given then filters results by repository owner.
|
* If repositoryUserName is given then filters results by repository owner.
|
||||||
*
|
*
|
||||||
* @param loginAccount the logged in account
|
* @param loginAccount the logged in account
|
||||||
* @param baseUrl the base url of this application
|
|
||||||
* @param repositoryUserName the repository owner (if None then returns all repositories which are visible for logged in user)
|
* @param repositoryUserName the repository owner (if None then returns all repositories which are visible for logged in user)
|
||||||
* @param withoutPhysicalInfo if true then the result does not include physical repository information such as commit count,
|
* @param withoutPhysicalInfo if true then the result does not include physical repository information such as commit count,
|
||||||
* branches and tags
|
* branches and tags
|
||||||
* @return the repository information which is sorted in descending order of lastActivityDate.
|
* @return the repository information which is sorted in descending order of lastActivityDate.
|
||||||
*/
|
*/
|
||||||
def getVisibleRepositories(loginAccount: Option[Account], baseUrl: String, repositoryUserName: Option[String] = None,
|
def getVisibleRepositories(loginAccount: Option[Account], repositoryUserName: Option[String] = None,
|
||||||
withoutPhysicalInfo: Boolean = false)
|
withoutPhysicalInfo: Boolean = false)
|
||||||
(implicit s: Session): List[RepositoryInfo] = {
|
(implicit s: Session): List[RepositoryInfo] = {
|
||||||
(loginAccount match {
|
(loginAccount match {
|
||||||
@@ -284,9 +283,9 @@ trait RepositoryService { self: AccountService =>
|
|||||||
}.sortBy(_.lastActivityDate desc).list.map{ repository =>
|
}.sortBy(_.lastActivityDate desc).list.map{ repository =>
|
||||||
new RepositoryInfo(
|
new RepositoryInfo(
|
||||||
if(withoutPhysicalInfo){
|
if(withoutPhysicalInfo){
|
||||||
new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName, baseUrl)
|
new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
|
||||||
} else {
|
} else {
|
||||||
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName, baseUrl)
|
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
|
||||||
},
|
},
|
||||||
repository,
|
repository,
|
||||||
getForkedCount(
|
getForkedCount(
|
||||||
@@ -389,31 +388,45 @@ trait RepositoryService { self: AccountService =>
|
|||||||
|
|
||||||
object RepositoryService {
|
object RepositoryService {
|
||||||
|
|
||||||
case class RepositoryInfo(owner: String, name: String, httpUrl: String, repository: Repository,
|
case class RepositoryInfo(owner: String, name: String, repository: Repository,
|
||||||
issueCount: Int, pullCount: Int, commitCount: Int, forkedCount: Int,
|
issueCount: Int, pullCount: Int, commitCount: Int, forkedCount: Int,
|
||||||
branchList: Seq[String], tags: Seq[JGitUtil.TagInfo], managers: Seq[String]){
|
branchList: Seq[String], tags: Seq[JGitUtil.TagInfo], managers: Seq[String]) {
|
||||||
|
|
||||||
lazy val host = """^https?://(.+?)(:\d+)?/""".r.findFirstMatchIn(httpUrl).get.group(1)
|
|
||||||
|
|
||||||
def sshUrl(port: Int, userName: String) = s"ssh://${userName}@${host}:${port}/${owner}/${name}.git"
|
|
||||||
|
|
||||||
def sshOpenRepoUrl(platform: String, port: Int, userName: String) = openRepoUrl(platform, sshUrl(port, userName))
|
|
||||||
|
|
||||||
def httpOpenRepoUrl(platform: String) = openRepoUrl(platform, httpUrl)
|
|
||||||
|
|
||||||
def openRepoUrl(platform: String, openUrl: String) = s"github-${platform}://openRepo/${openUrl}"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instance with issue count and pull request count.
|
* Creates instance with issue count and pull request count.
|
||||||
*/
|
*/
|
||||||
def this(repo: JGitUtil.RepositoryInfo, model: Repository, issueCount: Int, pullCount: Int, forkedCount: Int, managers: Seq[String]) =
|
def this(repo: JGitUtil.RepositoryInfo, model: Repository, issueCount: Int, pullCount: Int, forkedCount: Int, managers: Seq[String]) =
|
||||||
this(repo.owner, repo.name, repo.url, model, issueCount, pullCount, repo.commitCount, forkedCount, repo.branchList, repo.tags, managers)
|
this(
|
||||||
|
repo.owner, repo.name, model,
|
||||||
|
issueCount, pullCount,
|
||||||
|
repo.commitCount, forkedCount, repo.branchList, repo.tags, managers)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates instance without issue count and pull request count.
|
* Creates instance without issue count and pull request count.
|
||||||
*/
|
*/
|
||||||
def this(repo: JGitUtil.RepositoryInfo, model: Repository, forkedCount: Int, managers: Seq[String]) =
|
def this(repo: JGitUtil.RepositoryInfo, model: Repository, forkedCount: Int, managers: Seq[String]) =
|
||||||
this(repo.owner, repo.name, repo.url, model, 0, 0, repo.commitCount, forkedCount, repo.branchList, repo.tags, managers)
|
this(
|
||||||
|
repo.owner, repo.name, model,
|
||||||
|
0, 0,
|
||||||
|
repo.commitCount, forkedCount, repo.branchList, repo.tags, managers)
|
||||||
|
}
|
||||||
|
|
||||||
|
final class RepositoryUrls(baseUrl:String, sshAddress:Option[SshAddress], owner:String, name:String) {
|
||||||
|
def httpUrl:String =
|
||||||
|
s"${baseUrl}/git/${owner}/${name}.git"
|
||||||
|
|
||||||
|
// BETTER make this return an Option and use it in the gui
|
||||||
|
def sshUrl(userName: String):String =
|
||||||
|
sshAddress.fold("")(adr => s"ssh://${userName}@${adr.host}:${adr.port}/${owner}/${name}.git")
|
||||||
|
|
||||||
|
def sshOpenRepoUrl(platform: String, userName: String) =
|
||||||
|
openRepoUrl(platform, sshUrl(userName))
|
||||||
|
|
||||||
|
def httpOpenRepoUrl(platform: String) =
|
||||||
|
openRepoUrl(platform, httpUrl)
|
||||||
|
|
||||||
|
private def openRepoUrl(platform: String, openUrl: String) =
|
||||||
|
s"github-${platform}://openRepo/${openUrl}"
|
||||||
}
|
}
|
||||||
|
|
||||||
case class RepositoryTreeNode(owner: String, name: String, children: List[RepositoryTreeNode])
|
case class RepositoryTreeNode(owner: String, name: String, children: List[RepositoryTreeNode])
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import gitbucket.core.util.{Directory, ControlUtil}
|
import gitbucket.core.util.{Directory, ControlUtil}
|
||||||
|
import gitbucket.core.util.Implicits._
|
||||||
import Directory._
|
import Directory._
|
||||||
import ControlUtil._
|
import ControlUtil._
|
||||||
import SystemSettingsService._
|
import SystemSettingsService._
|
||||||
@@ -21,6 +22,7 @@ trait SystemSettingsService {
|
|||||||
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))
|
||||||
props.setProperty(Ssh, settings.ssh.toString)
|
props.setProperty(Ssh, settings.ssh.toString)
|
||||||
|
settings.sshHost.foreach(x => props.setProperty(SshHost, x.trim))
|
||||||
settings.sshPort.foreach(x => props.setProperty(SshPort, x.toString))
|
settings.sshPort.foreach(x => props.setProperty(SshPort, x.toString))
|
||||||
props.setProperty(UseSMTP, settings.useSMTP.toString)
|
props.setProperty(UseSMTP, settings.useSMTP.toString)
|
||||||
if(settings.useSMTP) {
|
if(settings.useSMTP) {
|
||||||
@@ -75,6 +77,7 @@ trait SystemSettingsService {
|
|||||||
getValue(props, Notification, false),
|
getValue(props, Notification, false),
|
||||||
getOptionValue[Int](props, ActivityLogLimit, None),
|
getOptionValue[Int](props, ActivityLogLimit, None),
|
||||||
getValue(props, Ssh, false),
|
getValue(props, Ssh, false),
|
||||||
|
getOptionValue[String](props, SshHost, None).map(_.trim),
|
||||||
getOptionValue(props, SshPort, Some(DefaultSshPort)),
|
getOptionValue(props, SshPort, Some(DefaultSshPort)),
|
||||||
getValue(props, UseSMTP, getValue(props, Notification, false)), // handle migration scenario from only notification to useSMTP
|
getValue(props, UseSMTP, getValue(props, Notification, false)), // handle migration scenario from only notification to useSMTP
|
||||||
if(getValue(props, UseSMTP, getValue(props, Notification, false))){
|
if(getValue(props, UseSMTP, getValue(props, Notification, false))){
|
||||||
@@ -126,16 +129,20 @@ object SystemSettingsService {
|
|||||||
notification: Boolean,
|
notification: Boolean,
|
||||||
activityLogLimit: Option[Int],
|
activityLogLimit: Option[Int],
|
||||||
ssh: Boolean,
|
ssh: Boolean,
|
||||||
|
sshHost: Option[String],
|
||||||
sshPort: Option[Int],
|
sshPort: Option[Int],
|
||||||
useSMTP: Boolean,
|
useSMTP: Boolean,
|
||||||
smtp: Option[Smtp],
|
smtp: Option[Smtp],
|
||||||
ldapAuthentication: Boolean,
|
ldapAuthentication: Boolean,
|
||||||
ldap: Option[Ldap]){
|
ldap: Option[Ldap]){
|
||||||
def baseUrl(request: HttpServletRequest): String = baseUrl.getOrElse {
|
def baseUrl(request: HttpServletRequest): String = baseUrl.fold(request.baseUrl)(_.stripSuffix("/"))
|
||||||
defining(request.getRequestURL.toString){ url =>
|
|
||||||
url.substring(0, url.length - (request.getRequestURI.length - request.getContextPath.length))
|
def sshAddress:Option[SshAddress] =
|
||||||
|
for {
|
||||||
|
host <- sshHost
|
||||||
|
if ssh
|
||||||
}
|
}
|
||||||
}.stripSuffix("/")
|
yield SshAddress(host, sshPort.getOrElse(DefaultSshPort))
|
||||||
}
|
}
|
||||||
|
|
||||||
case class Ldap(
|
case class Ldap(
|
||||||
@@ -161,6 +168,10 @@ object SystemSettingsService {
|
|||||||
fromAddress: Option[String],
|
fromAddress: Option[String],
|
||||||
fromName: Option[String])
|
fromName: Option[String])
|
||||||
|
|
||||||
|
case class SshAddress(
|
||||||
|
host:String,
|
||||||
|
port:Int)
|
||||||
|
|
||||||
val DefaultSshPort = 29418
|
val DefaultSshPort = 29418
|
||||||
val DefaultSmtpPort = 25
|
val DefaultSmtpPort = 25
|
||||||
val DefaultLdapPort = 389
|
val DefaultLdapPort = 389
|
||||||
@@ -174,6 +185,7 @@ object SystemSettingsService {
|
|||||||
private val Notification = "notification"
|
private val Notification = "notification"
|
||||||
private val ActivityLogLimit = "activity_log_limit"
|
private val ActivityLogLimit = "activity_log_limit"
|
||||||
private val Ssh = "ssh"
|
private val Ssh = "ssh"
|
||||||
|
private val SshHost = "ssh.host"
|
||||||
private val SshPort = "ssh.port"
|
private val SshPort = "ssh.port"
|
||||||
private val UseSMTP = "useSMTP"
|
private val UseSMTP = "useSMTP"
|
||||||
private val SmtpHost = "smtp.host"
|
private val SmtpHost = "smtp.host"
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ trait WebHookPullRequestService extends WebHookService {
|
|||||||
baseOwner <- users.get(repository.owner)
|
baseOwner <- users.get(repository.owner)
|
||||||
headOwner <- users.get(pullRequest.requestUserName)
|
headOwner <- users.get(pullRequest.requestUserName)
|
||||||
issueUser <- users.get(issue.openedUserName)
|
issueUser <- users.get(issue.openedUserName)
|
||||||
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName, baseUrl)
|
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
|
||||||
} yield {
|
} yield {
|
||||||
WebHookPullRequestPayload(
|
WebHookPullRequestPayload(
|
||||||
action = action,
|
action = action,
|
||||||
@@ -200,7 +200,7 @@ trait WebHookPullRequestService extends WebHookService {
|
|||||||
import WebHookService._
|
import WebHookService._
|
||||||
for{
|
for{
|
||||||
((issue, issueUser, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(requestRepository.owner, requestRepository.name, requestBranch)
|
((issue, issueUser, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(requestRepository.owner, requestRepository.name, requestBranch)
|
||||||
baseRepo <- getRepository(pullRequest.userName, pullRequest.repositoryName, baseUrl)
|
baseRepo <- getRepository(pullRequest.userName, pullRequest.repositoryName)
|
||||||
} yield {
|
} yield {
|
||||||
val payload = WebHookPullRequestPayload(
|
val payload = WebHookPullRequestPayload(
|
||||||
action = action,
|
action = action,
|
||||||
@@ -229,7 +229,7 @@ trait WebHookPullRequestReviewCommentService extends WebHookService {
|
|||||||
baseOwner <- users.get(repository.owner)
|
baseOwner <- users.get(repository.owner)
|
||||||
headOwner <- users.get(pullRequest.requestUserName)
|
headOwner <- users.get(pullRequest.requestUserName)
|
||||||
issueUser <- users.get(issue.openedUserName)
|
issueUser <- users.get(issue.openedUserName)
|
||||||
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName, baseUrl)
|
headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
|
||||||
} yield {
|
} yield {
|
||||||
WebHookPullRequestReviewCommentPayload(
|
WebHookPullRequestReviewCommentPayload(
|
||||||
action = action,
|
action = action,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import gitbucket.core.service.SystemSettingsService.SshAddress
|
||||||
import gitbucket.core.model.Account
|
import gitbucket.core.model.Account
|
||||||
import gitbucket.core.util._
|
import gitbucket.core.util._
|
||||||
import gitbucket.core.util.ControlUtil._
|
import gitbucket.core.util.ControlUtil._
|
||||||
@@ -14,6 +15,7 @@ import org.eclipse.jgit.patch._
|
|||||||
import org.eclipse.jgit.api.errors.PatchFormatException
|
import org.eclipse.jgit.api.errors.PatchFormatException
|
||||||
import scala.collection.JavaConverters._
|
import scala.collection.JavaConverters._
|
||||||
import RepositoryService.RepositoryInfo
|
import RepositoryService.RepositoryInfo
|
||||||
|
import RepositoryService.RepositoryUrls
|
||||||
|
|
||||||
object WikiService {
|
object WikiService {
|
||||||
|
|
||||||
@@ -37,11 +39,6 @@ object WikiService {
|
|||||||
* @param date the commit date
|
* @param date the commit date
|
||||||
*/
|
*/
|
||||||
case class WikiPageHistoryInfo(name: String, committer: String, message: String, date: Date)
|
case class WikiPageHistoryInfo(name: String, committer: String, message: String, date: Date)
|
||||||
|
|
||||||
def httpUrl(repository: RepositoryInfo) = repository.httpUrl.replaceFirst("\\.git\\Z", ".wiki.git")
|
|
||||||
|
|
||||||
def sshUrl(repository: RepositoryInfo, settings: SystemSettingsService.SystemSettings, userName: String) =
|
|
||||||
repository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), userName).replaceFirst("\\.git\\Z", ".wiki.git")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait WikiService {
|
trait WikiService {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
|||||||
|
|
||||||
request.paths match {
|
request.paths match {
|
||||||
case Array(_, repositoryOwner, repositoryName, _*) =>
|
case Array(_, repositoryOwner, repositoryName, _*) =>
|
||||||
getRepository(repositoryOwner, repositoryName.replaceFirst("\\.wiki\\.git$|\\.git$", ""), "") match {
|
getRepository(repositoryOwner, repositoryName.replaceFirst("\\.wiki\\.git$|\\.git$", "")) match {
|
||||||
case Some(repository) => {
|
case Some(repository) => {
|
||||||
if(!isUpdating && !repository.repository.isPrivate && settings.allowAnonymousAccess){
|
if(!isUpdating && !repository.repository.isPrivate && settings.allowAnonymousAccess){
|
||||||
chain.doFilter(request, response)
|
chain.doFilter(request, response)
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
|||||||
countIssue(IssueSearchCondition(state = "open"), false, owner -> repository) +
|
countIssue(IssueSearchCondition(state = "open"), false, owner -> repository) +
|
||||||
countIssue(IssueSearchCondition(state = "closed"), false, owner -> repository)
|
countIssue(IssueSearchCondition(state = "closed"), false, owner -> repository)
|
||||||
|
|
||||||
val repositoryInfo = getRepository(owner, repository, baseUrl).get
|
val repositoryInfo = getRepository(owner, repository).get
|
||||||
|
|
||||||
// Extract new commit and apply issue comment
|
// Extract new commit and apply issue comment
|
||||||
val defaultBranch = repositoryInfo.repository.defaultBranch
|
val defaultBranch = repositoryInfo.repository.defaultBranch
|
||||||
|
|||||||
@@ -87,11 +87,11 @@ abstract class DefaultGitCommand(val owner: String, val repoName: String) extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class DefaultGitUploadPack(owner: String, repoName: String, baseUrl: String) extends DefaultGitCommand(owner, repoName)
|
class DefaultGitUploadPack(owner: String, repoName: String) extends DefaultGitCommand(owner, repoName)
|
||||||
with RepositoryService with AccountService {
|
with RepositoryService with AccountService {
|
||||||
|
|
||||||
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
||||||
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", ""), baseUrl).foreach { repositoryInfo =>
|
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).foreach { repositoryInfo =>
|
||||||
if(!repositoryInfo.repository.isPrivate || isWritableUser(user, repositoryInfo)){
|
if(!repositoryInfo.repository.isPrivate || isWritableUser(user, repositoryInfo)){
|
||||||
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
@@ -107,7 +107,7 @@ class DefaultGitReceivePack(owner: String, repoName: String, baseUrl: String) ex
|
|||||||
with RepositoryService with AccountService {
|
with RepositoryService with AccountService {
|
||||||
|
|
||||||
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
||||||
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", ""), baseUrl).foreach { repositoryInfo =>
|
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).foreach { repositoryInfo =>
|
||||||
if(isWritableUser(user, repositoryInfo)){
|
if(isWritableUser(user, repositoryInfo)){
|
||||||
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
@@ -124,7 +124,7 @@ class DefaultGitReceivePack(owner: String, repoName: String, baseUrl: String) ex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PluginGitUploadPack(repoName: String, baseUrl: String, routing: GitRepositoryRouting) extends GitCommand
|
class PluginGitUploadPack(repoName: String, routing: GitRepositoryRouting) extends GitCommand
|
||||||
with SystemSettingsService {
|
with SystemSettingsService {
|
||||||
|
|
||||||
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
||||||
@@ -139,7 +139,7 @@ class PluginGitUploadPack(repoName: String, baseUrl: String, routing: GitReposit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PluginGitReceivePack(repoName: String, baseUrl: String, routing: GitRepositoryRouting) extends GitCommand
|
class PluginGitReceivePack(repoName: String, routing: GitRepositoryRouting) extends GitCommand
|
||||||
with SystemSettingsService {
|
with SystemSettingsService {
|
||||||
|
|
||||||
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
||||||
@@ -163,9 +163,9 @@ class GitCommandFactory(baseUrl: String) extends CommandFactory {
|
|||||||
logger.debug(s"command: $command")
|
logger.debug(s"command: $command")
|
||||||
|
|
||||||
command match {
|
command match {
|
||||||
case SimpleCommandRegex ("upload" , repoName) if(pluginRepository(repoName)) => new PluginGitUploadPack (repoName, baseUrl, routing(repoName))
|
case SimpleCommandRegex ("upload" , repoName) if(pluginRepository(repoName)) => new PluginGitUploadPack (repoName, routing(repoName))
|
||||||
case SimpleCommandRegex ("receive", repoName) if(pluginRepository(repoName)) => new PluginGitReceivePack(repoName, baseUrl, routing(repoName))
|
case SimpleCommandRegex ("receive", repoName) if(pluginRepository(repoName)) => new PluginGitReceivePack(repoName, routing(repoName))
|
||||||
case DefaultCommandRegex("upload" , owner, repoName) => new DefaultGitUploadPack (owner, repoName, baseUrl)
|
case DefaultCommandRegex("upload" , owner, repoName) => new DefaultGitUploadPack (owner, repoName)
|
||||||
case DefaultCommandRegex("receive", owner, repoName) => new DefaultGitReceivePack(owner, repoName, baseUrl)
|
case DefaultCommandRegex("receive", owner, repoName) => new DefaultGitReceivePack(owner, repoName, baseUrl)
|
||||||
case _ => new UnknownCommand(command)
|
case _ => new UnknownCommand(command)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package gitbucket.core.ssh
|
package gitbucket.core.ssh
|
||||||
|
|
||||||
import gitbucket.core.service.SystemSettingsService
|
import gitbucket.core.service.SystemSettingsService
|
||||||
|
import gitbucket.core.service.SystemSettingsService.SshAddress
|
||||||
import org.apache.sshd.common.Factory
|
import org.apache.sshd.common.Factory
|
||||||
import org.apache.sshd.server.{Environment, ExitCallback, Command}
|
import org.apache.sshd.server.{Environment, ExitCallback, Command}
|
||||||
import java.io.{OutputStream, InputStream}
|
import java.io.{OutputStream, InputStream}
|
||||||
import org.eclipse.jgit.lib.Constants
|
import org.eclipse.jgit.lib.Constants
|
||||||
|
|
||||||
class NoShell extends Factory[Command] with SystemSettingsService {
|
class NoShell(sshAddress:SshAddress) extends Factory[Command] {
|
||||||
override def create(): Command = new Command() {
|
override def create(): Command = new Command() {
|
||||||
private var in: InputStream = null
|
private var in: InputStream = null
|
||||||
private var out: OutputStream = null
|
private var out: OutputStream = null
|
||||||
@@ -15,7 +16,6 @@ class NoShell extends Factory[Command] with SystemSettingsService {
|
|||||||
|
|
||||||
override def start(env: Environment): Unit = {
|
override def start(env: Environment): Unit = {
|
||||||
val user = env.getEnv.get("USER")
|
val user = env.getEnv.get("USER")
|
||||||
val port = loadSystemSettings().sshPort.getOrElse(SystemSettingsService.DefaultSshPort)
|
|
||||||
val message =
|
val message =
|
||||||
"""
|
"""
|
||||||
| Welcome to
|
| Welcome to
|
||||||
@@ -31,8 +31,8 @@ class NoShell extends Factory[Command] with SystemSettingsService {
|
|||||||
|
|
|
|
||||||
| Please use:
|
| Please use:
|
||||||
|
|
|
|
||||||
| git clone ssh://%s@GITBUCKET_HOST:%d/OWNER/REPOSITORY_NAME.git
|
| git clone ssh://%s@%s:%d/OWNER/REPOSITORY_NAME.git
|
||||||
""".stripMargin.format(user, port).replace("\n", "\r\n") + "\r\n"
|
""".stripMargin.format(user, sshAddress.host, sshAddress.port).replace("\n", "\r\n") + "\r\n"
|
||||||
err.write(Constants.encode(message))
|
err.write(Constants.encode(message))
|
||||||
err.flush()
|
err.flush()
|
||||||
in.close()
|
in.close()
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||||||
import javax.servlet.{ServletContextEvent, ServletContextListener}
|
import javax.servlet.{ServletContextEvent, ServletContextListener}
|
||||||
|
|
||||||
import gitbucket.core.service.SystemSettingsService
|
import gitbucket.core.service.SystemSettingsService
|
||||||
import gitbucket.core.util.Directory
|
import gitbucket.core.service.SystemSettingsService.SshAddress
|
||||||
|
import gitbucket.core.util.{Directory}
|
||||||
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
|
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
@@ -14,20 +15,20 @@ object SshServer {
|
|||||||
private val server = org.apache.sshd.server.SshServer.setUpDefaultServer()
|
private val server = org.apache.sshd.server.SshServer.setUpDefaultServer()
|
||||||
private val active = new AtomicBoolean(false)
|
private val active = new AtomicBoolean(false)
|
||||||
|
|
||||||
private def configure(port: Int, baseUrl: String) = {
|
private def configure(sshAddress: SshAddress, baseUrl: String) = {
|
||||||
server.setPort(port)
|
server.setPort(sshAddress.port)
|
||||||
val provider = new SimpleGeneratorHostKeyProvider(new File(s"${Directory.GitBucketHome}/gitbucket.ser"))
|
val provider = new SimpleGeneratorHostKeyProvider(new File(s"${Directory.GitBucketHome}/gitbucket.ser"))
|
||||||
provider.setAlgorithm("RSA")
|
provider.setAlgorithm("RSA")
|
||||||
provider.setOverwriteAllowed(false)
|
provider.setOverwriteAllowed(false)
|
||||||
server.setKeyPairProvider(provider)
|
server.setKeyPairProvider(provider)
|
||||||
server.setPublickeyAuthenticator(new PublicKeyAuthenticator)
|
server.setPublickeyAuthenticator(new PublicKeyAuthenticator)
|
||||||
server.setCommandFactory(new GitCommandFactory(baseUrl))
|
server.setCommandFactory(new GitCommandFactory(baseUrl))
|
||||||
server.setShellFactory(new NoShell)
|
server.setShellFactory(new NoShell(sshAddress))
|
||||||
}
|
}
|
||||||
|
|
||||||
def start(port: Int, baseUrl: String) = {
|
def start(sshAddress: SshAddress, baseUrl: String) = {
|
||||||
if(active.compareAndSet(false, true)){
|
if(active.compareAndSet(false, true)){
|
||||||
configure(port, baseUrl)
|
configure(sshAddress, baseUrl)
|
||||||
server.start()
|
server.start()
|
||||||
logger.info(s"Start SSH Server Listen on ${server.getPort}")
|
logger.info(s"Start SSH Server Listen on ${server.getPort}")
|
||||||
}
|
}
|
||||||
@@ -55,20 +56,18 @@ class SshServerListener extends ServletContextListener with SystemSettingsServic
|
|||||||
|
|
||||||
override def contextInitialized(sce: ServletContextEvent): Unit = {
|
override def contextInitialized(sce: ServletContextEvent): Unit = {
|
||||||
val settings = loadSystemSettings()
|
val settings = loadSystemSettings()
|
||||||
if(settings.ssh){
|
if (settings.sshAddress.isDefined && settings.baseUrl.isEmpty) {
|
||||||
settings.baseUrl match {
|
|
||||||
case None =>
|
|
||||||
logger.error("Could not start SshServer because the baseUrl is not configured.")
|
logger.error("Could not start SshServer because the baseUrl is not configured.")
|
||||||
case Some(baseUrl) =>
|
|
||||||
SshServer.start(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), baseUrl)
|
|
||||||
}
|
}
|
||||||
|
for {
|
||||||
|
sshAddress <- settings.sshAddress
|
||||||
|
baseUrl <- settings.baseUrl
|
||||||
}
|
}
|
||||||
|
SshServer.start(sshAddress, baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def contextDestroyed(sce: ServletContextEvent): Unit = {
|
override def contextDestroyed(sce: ServletContextEvent): Unit = {
|
||||||
if(loadSystemSettings().ssh){
|
|
||||||
SshServer.stop()
|
SshServer.stop()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ trait OwnerAuthenticator { self: ControllerBase with RepositoryService with Acco
|
|||||||
private def authenticate(action: (RepositoryInfo) => Any) = {
|
private def authenticate(action: (RepositoryInfo) => Any) = {
|
||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1), baseUrl).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.isAdmin) => action(repository)
|
||||||
case Some(x) if(repository.owner == x.userName) => action(repository)
|
case Some(x) if(repository.owner == x.userName) => action(repository)
|
||||||
@@ -95,7 +95,7 @@ trait CollaboratorsAuthenticator { self: ControllerBase with RepositoryService =
|
|||||||
private def authenticate(action: (RepositoryInfo) => Any) = {
|
private def authenticate(action: (RepositoryInfo) => Any) = {
|
||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1), baseUrl).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.isAdmin) => action(repository)
|
||||||
case Some(x) if(paths(0) == x.userName) => action(repository)
|
case Some(x) if(paths(0) == x.userName) => action(repository)
|
||||||
@@ -118,7 +118,7 @@ trait ReferrerAuthenticator { self: ControllerBase with RepositoryService =>
|
|||||||
private def authenticate(action: (RepositoryInfo) => Any) = {
|
private def authenticate(action: (RepositoryInfo) => Any) = {
|
||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1), baseUrl).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
if(!repository.repository.isPrivate){
|
if(!repository.repository.isPrivate){
|
||||||
action(repository)
|
action(repository)
|
||||||
} else {
|
} else {
|
||||||
@@ -145,7 +145,7 @@ trait ReadableUsersAuthenticator { self: ControllerBase with RepositoryService =
|
|||||||
private def authenticate(action: (RepositoryInfo) => Any) = {
|
private def authenticate(action: (RepositoryInfo) => Any) = {
|
||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1), baseUrl).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.isAdmin) => action(repository)
|
||||||
case Some(x) if(!repository.repository.isPrivate) => action(repository)
|
case Some(x) if(!repository.repository.isPrivate) => action(repository)
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ object Implicits {
|
|||||||
|
|
||||||
def gitRepositoryPath: String = request.getRequestURI.replaceFirst("^/git/", "/")
|
def gitRepositoryPath: String = request.getRequestURI.replaceFirst("^/git/", "/")
|
||||||
|
|
||||||
|
def baseUrl:String = {
|
||||||
|
val url = request.getRequestURL.toString
|
||||||
|
val len = url.length - (request.getRequestURI.length - request.getContextPath.length)
|
||||||
|
url.substring(0, len).stripSuffix("/")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implicit class RichSession(session: HttpSession){
|
implicit class RichSession(session: HttpSession){
|
||||||
|
|||||||
@@ -32,14 +32,13 @@ object JGitUtil {
|
|||||||
*
|
*
|
||||||
* @param owner the user name of the repository owner
|
* @param owner the user name of the repository owner
|
||||||
* @param name the repository name
|
* @param name the repository name
|
||||||
* @param url the repository URL
|
|
||||||
* @param commitCount the commit count. If the repository has over 1000 commits then this property is 1001.
|
* @param commitCount the commit count. If the repository has over 1000 commits then this property is 1001.
|
||||||
* @param branchList the list of branch names
|
* @param branchList the list of branch names
|
||||||
* @param tags the list of tags
|
* @param tags the list of tags
|
||||||
*/
|
*/
|
||||||
case class RepositoryInfo(owner: String, name: String, url: String, commitCount: Int, branchList: List[String], tags: List[TagInfo]){
|
case class RepositoryInfo(owner: String, name: String, commitCount: Int, branchList: List[String], tags: List[TagInfo]){
|
||||||
def this(owner: String, name: String, baseUrl: String) = {
|
def this(owner: String, name: String) = {
|
||||||
this(owner, name, s"${baseUrl}/git/${owner}/${name}.git", 0, Nil, Nil)
|
this(owner, name, 0, Nil, Nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,14 +173,14 @@ object JGitUtil {
|
|||||||
/**
|
/**
|
||||||
* Returns the repository information. It contains branch names and tag names.
|
* Returns the repository information. It contains branch names and tag names.
|
||||||
*/
|
*/
|
||||||
def getRepositoryInfo(owner: String, repository: String, baseUrl: String): RepositoryInfo = {
|
def getRepositoryInfo(owner: String, repository: String): RepositoryInfo = {
|
||||||
using(Git.open(getRepositoryDir(owner, repository))){ git =>
|
using(Git.open(getRepositoryDir(owner, repository))){ git =>
|
||||||
try {
|
try {
|
||||||
// get commit count
|
// get commit count
|
||||||
val commitCount = git.log.all.call.iterator.asScala.map(_ => 1).take(10001).sum
|
val commitCount = git.log.all.call.iterator.asScala.map(_ => 1).take(10001).sum
|
||||||
|
|
||||||
RepositoryInfo(
|
RepositoryInfo(
|
||||||
owner, repository, s"${baseUrl}/git/${owner}/${repository}.git",
|
owner, repository,
|
||||||
// commit count
|
// commit count
|
||||||
commitCount,
|
commitCount,
|
||||||
// branches
|
// branches
|
||||||
@@ -197,7 +196,7 @@ object JGitUtil {
|
|||||||
} catch {
|
} catch {
|
||||||
// not initialized
|
// not initialized
|
||||||
case e: NoHeadException => RepositoryInfo(
|
case e: NoHeadException => RepositoryInfo(
|
||||||
owner, repository, s"${baseUrl}/git/${owner}/${repository}.git", 0, Nil, Nil)
|
owner, repository, 0, Nil, Nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ object Markdown {
|
|||||||
pages: List[String])
|
pages: List[String])
|
||||||
(implicit val context: Context) extends Renderer(options) with LinkConverter with RequestCache {
|
(implicit val context: Context) extends Renderer(options) with LinkConverter with RequestCache {
|
||||||
|
|
||||||
|
private val repositoryUrls = context.urls(repository)
|
||||||
|
|
||||||
override def heading(text: String, level: Int, raw: String): String = {
|
override def heading(text: String, level: Int, raw: String): String = {
|
||||||
val id = generateAnchorName(text)
|
val id = generateAnchorName(text)
|
||||||
val out = new StringBuilder()
|
val out = new StringBuilder()
|
||||||
@@ -135,7 +137,7 @@ object Markdown {
|
|||||||
(link, link)
|
(link, link)
|
||||||
}
|
}
|
||||||
|
|
||||||
val url = repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/" + StringUtil.urlEncode(page)
|
val url = repositoryUrls.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/" + StringUtil.urlEncode(page)
|
||||||
if(pages.contains(page)){
|
if(pages.contains(page)){
|
||||||
"<a href=\"" + url + "\">" + escape(label) + "</a>"
|
"<a href=\"" + url + "\">" + escape(label) + "</a>"
|
||||||
} else {
|
} else {
|
||||||
@@ -157,14 +159,14 @@ object Markdown {
|
|||||||
} else if(context.currentPath.contains("/tree/")){
|
} else if(context.currentPath.contains("/tree/")){
|
||||||
val paths = context.currentPath.split("/")
|
val paths = context.currentPath.split("/")
|
||||||
val branch = if(paths.length > 3) paths.drop(4).mkString("/") else repository.repository.defaultBranch
|
val branch = if(paths.length > 3) paths.drop(4).mkString("/") else repository.repository.defaultBranch
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + url + (if(isImage) "?raw=true" else "")
|
repositoryUrls.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + url + (if(isImage) "?raw=true" else "")
|
||||||
} else {
|
} else {
|
||||||
val paths = context.currentPath.split("/")
|
val paths = context.currentPath.split("/")
|
||||||
val branch = if(paths.length > 3) paths.last else repository.repository.defaultBranch
|
val branch = if(paths.length > 3) paths.last else repository.repository.defaultBranch
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + url + (if(isImage) "?raw=true" else "")
|
repositoryUrls.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/blob/" + branch + "/" + url + (if(isImage) "?raw=true" else "")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/_blob/" + url
|
repositoryUrls.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/_blob/" + url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,13 +111,22 @@
|
|||||||
Enable SSH access to git repository
|
Enable SSH access to git repository
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<div class="form-group ssh">
|
<div class="ssh">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="control-label col-md-3" for="sshHost">SSH Host</label>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<input type="text" id="sshHost" name="sshHost" class="form-control" value="@settings.sshHost"/>
|
||||||
|
<span id="error-sshHost" class="error"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
<label class="control-label col-md-3" for="sshPort">SSH Port</label>
|
<label class="control-label col-md-3" for="sshPort">SSH Port</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<input type="text" id="sshPort" name="sshPort" class="form-control" value="@settings.sshPort"/>
|
<input type="text" id="sshPort" name="sshPort" class="form-control" value="@settings.sshPort"/>
|
||||||
<span id="error-sshPort" class="error"></span>
|
<span id="error-sshPort" class="error"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<p class="muted">
|
<p class="muted">
|
||||||
Base URL is required if SSH access is enabled.
|
Base URL is required if SSH access is enabled.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
<script src="@assets/vendors/jquery-hotkeys/jquery.hotkeys.js"></script>
|
<script src="@assets/vendors/jquery-hotkeys/jquery.hotkeys.js"></script>
|
||||||
@repository.map { repository =>
|
@repository.map { repository =>
|
||||||
@if(!repository.repository.isPrivate){
|
@if(!repository.repository.isPrivate){
|
||||||
<meta name="go-import" content="@context.baseUrl.replaceFirst("^https?://", "")/@repository.owner/@repository.name git @repository.httpUrl" />
|
<meta name="go-import" content="@context.baseUrl.replaceFirst("^https?://", "")/@repository.owner/@repository.name git @context.urls(repository).httpUrl" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -80,8 +80,8 @@
|
|||||||
<div class="small">
|
<div class="small">
|
||||||
<strong id="repository-url-proto">HTTP</strong> <span class="mute">clone URL</span>
|
<strong id="repository-url-proto">HTTP</strong> <span class="mute">clone URL</span>
|
||||||
</div>
|
</div>
|
||||||
@helper.html.copy("repository-url-copy", repository.httpUrl){
|
@helper.html.copy("repository-url-copy", context.urls(repository).httpUrl){
|
||||||
<input type="text" value="@repository.httpUrl" id="repository-url" class="form-control input-sm" readonly>
|
<input type="text" value="@context.urls(repository).httpUrl" id="repository-url" class="form-control input-sm" readonly>
|
||||||
}
|
}
|
||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
<div class="small">
|
<div class="small">
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
@id.map { id =>
|
@id.map { id =>
|
||||||
@if(context.platform != "linux" && context.platform != null){
|
@if(context.platform != "linux" && context.platform != null){
|
||||||
<div style="margin-top: 10px;">
|
<div style="margin-top: 10px;">
|
||||||
<a href="@repository.httpOpenRepoUrl(context.platform)" id="repository-clone-url" class="btn btn-sm btn-default btn-block"><i class="octicon octicon-desktop-download"></i> Clone in Desktop</a>
|
<a href="@context.urls(repository).httpOpenRepoUrl(context.platform)" id="repository-clone-url" class="btn btn-sm btn-default btn-block"><i class="octicon octicon-desktop-download"></i> Clone in Desktop</a>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div style="margin-top: 10px;">
|
<div style="margin-top: 10px;">
|
||||||
@@ -184,15 +184,15 @@ $(function(){
|
|||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
$('#repository-url-http').click(function(){
|
$('#repository-url-http').click(function(){
|
||||||
$('#repository-url-proto').text('HTTP');
|
$('#repository-url-proto').text('HTTP');
|
||||||
$('#repository-url').val('@repository.httpUrl');
|
$('#repository-url').val('@context.urls(repository).httpUrl');
|
||||||
$('#repository-clone-url').attr('href', '@repository.httpOpenRepoUrl(context.platform)')
|
$('#repository-clone-url').attr('href', '@context.urls(repository).httpOpenRepoUrl(context.platform)')
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#repository-url-ssh').click(function(){
|
$('#repository-url-ssh').click(function(){
|
||||||
$('#repository-url-proto').text('SSH');
|
$('#repository-url-proto').text('SSH');
|
||||||
$('#repository-url').val('@repository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)');
|
$('#repository-url').val('@context.urls(repository).sshUrl(loginAccount.get.userName)');
|
||||||
$('#repository-clone-url').attr('href', '@repository.sshOpenRepoUrl(context.platform, settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)');
|
$('#repository-clone-url').attr('href', '@context.urls(repository).sshOpenRepoUrl(context.platform, loginAccount.get.userName)');
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,21 +100,21 @@
|
|||||||
you can perform a manual merge on the command line.
|
you can perform a manual merge on the command line.
|
||||||
</p>
|
</p>
|
||||||
}
|
}
|
||||||
@helper.html.copy("repository-url-copy", forkedRepository.httpUrl, true){
|
@helper.html.copy("repository-url-copy", context.urls(forkedRepository).httpUrl, true){
|
||||||
<div class="btn-group" data-toggle="buttons-radio">
|
<div class="btn-group" data-toggle="buttons-radio">
|
||||||
<button class="btn btn-small active" type="button" id="repository-url-http">HTTP</button>
|
<button class="btn btn-small active" type="button" id="repository-url-http">HTTP</button>
|
||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
<button class="btn btn-small" type="button" id="repository-url-ssh" style="border-radius: 0px;">SSH</button>
|
<button class="btn btn-small" type="button" id="repository-url-ssh" style="border-radius: 0px;">SSH</button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<input type="text" style="width: 500px;" value="@forkedRepository.httpUrl" id="repository-url" readonly />
|
<input type="text" style="width: 500px;" value="@context.urls(forkedRepository).httpUrl" id="repository-url" readonly />
|
||||||
}
|
}
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<span class="strong">Step 1:</span> From your project repository, check out a new branch and test the changes.
|
<span class="strong">Step 1:</span> From your project repository, check out a new branch and test the changes.
|
||||||
</p>
|
</p>
|
||||||
@defining(s"git checkout -b ${pullreq.requestUserName}-${pullreq.requestBranch} ${pullreq.branch}\n" +
|
@defining(s"git checkout -b ${pullreq.requestUserName}-${pullreq.requestBranch} ${pullreq.branch}\n" +
|
||||||
s"git pull ${forkedRepository.httpUrl} ${pullreq.requestBranch}"){ command =>
|
s"git pull ${context.urls(forkedRepository).httpUrl} ${pullreq.requestBranch}"){ command =>
|
||||||
@helper.html.copy("merge-command-copy-1", command){
|
@helper.html.copy("merge-command-copy-1", command){
|
||||||
<pre style="width: 600px; float: left; font-size: 12px; border-radius: 3px 0px 3px 3px;" id="merge-command">@Html(command)</pre>
|
<pre style="width: 600px; float: left; font-size: 12px; border-radius: 3px 0px 3px 3px;" id="merge-command">@Html(command)</pre>
|
||||||
}
|
}
|
||||||
@@ -174,24 +174,24 @@ $(function(){
|
|||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
$('#repository-url-http').click(function(){
|
$('#repository-url-http').click(function(){
|
||||||
// Update URL box
|
// Update URL box
|
||||||
$('#repository-url').val('@forkedRepository.httpUrl');
|
$('#repository-url').val('@context.urls(forkedRepository).httpUrl');
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
// Update command guidance
|
// Update command guidance
|
||||||
$('#merge-command').text($('#merge-command').text().replace(
|
$('#merge-command').text($('#merge-command').text().replace(
|
||||||
'@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)',
|
'@context.urls(forkedRepository).sshUrl(loginAccount.get.userName)',
|
||||||
'@forkedRepository.httpUrl'
|
'@context.urls(forkedRepository).httpUrl'
|
||||||
));
|
));
|
||||||
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#repository-url-ssh').click(function(){
|
$('#repository-url-ssh').click(function(){
|
||||||
// Update URL box
|
// Update URL box
|
||||||
$('#repository-url').val('@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)');
|
$('#repository-url').val('@context.urls(forkedRepository).sshUrl(loginAccount.get.userName)');
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
// Update command guidance
|
// Update command guidance
|
||||||
$('#merge-command').text($('#merge-command').text().replace(
|
$('#merge-command').text($('#merge-command').text().replace(
|
||||||
'@forkedRepository.httpUrl',
|
'@context.urls(forkedRepository).httpUrl',
|
||||||
'@forkedRepository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)'
|
'@context.urls(forkedRepository).sshUrl(loginAccount.get.userName)'
|
||||||
));
|
));
|
||||||
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
$('#merge-command-copy-1').attr('data-clipboard-text', $('#merge-command').text());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
} else {
|
} else {
|
||||||
<h3><strong>Quick setup</strong> — if you've done this kind of thing before</h3>
|
<h3><strong>Quick setup</strong> — if you've done this kind of thing before</h3>
|
||||||
<div class="empty-repo-options">
|
<div class="empty-repo-options">
|
||||||
via <a href="@repository.httpUrl" class="git-protocol-selector">HTTP</a>
|
via <a href="@context.urls(repository).httpUrl" class="git-protocol-selector">HTTP</a>
|
||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
or
|
or
|
||||||
<a href="@repository.sshUrl(settings.sshPort.getOrElse(SystemSettingsService.DefaultSshPort), loginAccount.get.userName)" class="git-protocol-selector">SSH</a>
|
<a href="@context.urls(repository).sshUrl(loginAccount.get.userName)" class="git-protocol-selector">SSH</a>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<h3 style="margin-top: 30px;">Create a new repository on the command line</h3>
|
<h3 style="margin-top: 30px;">Create a new repository on the command line</h3>
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
git init
|
git init
|
||||||
git add README.md
|
git add README.md
|
||||||
git commit -m "first commit"
|
git commit -m "first commit"
|
||||||
git remote add origin <span class="live-clone-url">@repository.httpUrl</span>
|
git remote add origin <span class="live-clone-url">@context.urls(repository).httpUrl</span>
|
||||||
git push -u origin master
|
git push -u origin master
|
||||||
}
|
}
|
||||||
<h3 style="margin-top: 30px;">Push an existing repository from the command line</h3>
|
<h3 style="margin-top: 30px;">Push an existing repository from the command line</h3>
|
||||||
@pre {
|
@pre {
|
||||||
git remote add origin <span class="live-clone-url">@repository.httpUrl</span>
|
git remote add origin <span class="live-clone-url">@context.urls(repository).httpUrl</span>
|
||||||
git push -u origin master
|
git push -u origin master
|
||||||
}
|
}
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -67,8 +67,8 @@
|
|||||||
<div class="small">
|
<div class="small">
|
||||||
<strong>Clone this wiki locally</strong>
|
<strong>Clone this wiki locally</strong>
|
||||||
</div>
|
</div>
|
||||||
@helper.html.copy("repository-url-copy", httpUrl(repository)){
|
@helper.html.copy("repository-url-copy", context.wikiUrls(repository).httpUrl){
|
||||||
<input type="text" value="@httpUrl(repository)" id="repository-url" class="form-control input-sm" readonly>
|
<input type="text" value="@context.wikiUrls(repository).httpUrl" id="repository-url" class="form-control input-sm" readonly>
|
||||||
}
|
}
|
||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
<div class="small">
|
<div class="small">
|
||||||
@@ -133,11 +133,11 @@ $(function(){
|
|||||||
|
|
||||||
@if(settings.ssh && loginAccount.isDefined){
|
@if(settings.ssh && loginAccount.isDefined){
|
||||||
$('#repository-url-http').click(function(){
|
$('#repository-url-http').click(function(){
|
||||||
$('#repository-url').val('@httpUrl(repository)');
|
$('#repository-url').val('@context.wikiUrls(repository).httpUrl');
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
});
|
});
|
||||||
$('#repository-url-ssh').click(function(){
|
$('#repository-url-ssh').click(function(){
|
||||||
$('#repository-url').val('@sshUrl(repository, settings, loginAccount.get.userName)');
|
$('#repository-url').val('@context.wikiUrls(repository).sshUrl(loginAccount.get.userName)');
|
||||||
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
$('#repository-url-copy').attr('data-clipboard-text', $('#repository-url').val());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
|||||||
notification = false,
|
notification = false,
|
||||||
activityLogLimit = None,
|
activityLogLimit = None,
|
||||||
ssh = false,
|
ssh = false,
|
||||||
|
sshHost = None,
|
||||||
sshPort = None,
|
sshPort = None,
|
||||||
useSMTP = false,
|
useSMTP = false,
|
||||||
smtp = None,
|
smtp = None,
|
||||||
|
|||||||
Reference in New Issue
Block a user