diff --git a/src/main/scala/ScalatraBootstrap.scala b/src/main/scala/ScalatraBootstrap.scala
index 08458b5..5888f4e 100644
--- a/src/main/scala/ScalatraBootstrap.scala
+++ b/src/main/scala/ScalatraBootstrap.scala
@@ -1,4 +1,3 @@
-
import java.util.EnumSet
import javax.servlet._
@@ -9,28 +8,35 @@
import gitbucket.core.util.Directory
import org.scalatra._
-
class ScalatraBootstrap extends LifeCycle with SystemSettingsService {
override def init(context: ServletContext) {
val settings = loadSystemSettings()
- if(settings.baseUrl.exists(_.startsWith("https://"))) {
+ if (settings.baseUrl.exists(_.startsWith("https://"))) {
context.getSessionCookieConfig.setSecure(true)
}
// Register TransactionFilter and BasicAuthenticationFilter at first
context.addFilter("transactionFilter", new TransactionFilter)
- context.getFilterRegistration("transactionFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
+ context
+ .getFilterRegistration("transactionFilter")
+ .addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
context.addFilter("gitAuthenticationFilter", new GitAuthenticationFilter)
- context.getFilterRegistration("gitAuthenticationFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/git/*")
+ context
+ .getFilterRegistration("gitAuthenticationFilter")
+ .addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/git/*")
context.addFilter("apiAuthenticationFilter", new ApiAuthenticationFilter)
- context.getFilterRegistration("apiAuthenticationFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/api/v3/*")
+ context
+ .getFilterRegistration("apiAuthenticationFilter")
+ .addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/api/v3/*")
// Register controllers
context.mount(new PreProcessController, "/*")
context.addFilter("pluginControllerFilter", new PluginControllerFilter)
- context.getFilterRegistration("pluginControllerFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
+ context
+ .getFilterRegistration("pluginControllerFilter")
+ .addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
context.mount(new FileUploadController, "/upload")
@@ -51,11 +57,13 @@
filter.mount(new RepositorySettingsController, "/*")
context.addFilter("compositeScalatraFilter", filter)
- context.getFilterRegistration("compositeScalatraFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
+ context
+ .getFilterRegistration("compositeScalatraFilter")
+ .addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*")
// Create GITBUCKET_HOME directory if it does not exist
val dir = new java.io.File(Directory.GitBucketHome)
- if(!dir.exists){
+ if (!dir.exists) {
dir.mkdirs()
}
}
diff --git a/src/main/scala/gitbucket/core/GitBucketCoreModule.scala b/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
index b81132a..4c2a3c4 100644
--- a/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
+++ b/src/main/scala/gitbucket/core/GitBucketCoreModule.scala
@@ -3,61 +3,52 @@
import io.github.gitbucket.solidbase.migration.{SqlMigration, LiquibaseMigration}
import io.github.gitbucket.solidbase.model.{Version, Module}
-object GitBucketCoreModule extends Module("gitbucket-core",
- new Version("4.0.0",
- new LiquibaseMigration("update/gitbucket-core_4.0.xml"),
- new SqlMigration("update/gitbucket-core_4.0.sql")
- ),
- new Version("4.1.0"),
- new Version("4.2.0",
- new LiquibaseMigration("update/gitbucket-core_4.2.xml")
- ),
- new Version("4.2.1"),
- new Version("4.3.0"),
- new Version("4.4.0"),
- new Version("4.5.0"),
- new Version("4.6.0",
- new LiquibaseMigration("update/gitbucket-core_4.6.xml")
- ),
- new Version("4.7.0",
- new LiquibaseMigration("update/gitbucket-core_4.7.xml"),
- new SqlMigration("update/gitbucket-core_4.7.sql")
- ),
- new Version("4.7.1"),
- new Version("4.8"),
- new Version("4.9.0",
- new LiquibaseMigration("update/gitbucket-core_4.9.xml")
- ),
- new Version("4.10.0"),
- new Version("4.11.0",
- new LiquibaseMigration("update/gitbucket-core_4.11.xml")
- ),
- new Version("4.12.0"),
- new Version("4.12.1"),
- new Version("4.13.0"),
- new Version("4.14.0",
- new LiquibaseMigration("update/gitbucket-core_4.14.xml"),
- new SqlMigration("update/gitbucket-core_4.14.sql")
- ),
- new Version("4.14.1"),
- new Version("4.15.0"),
- new Version("4.16.0"),
- new Version("4.17.0"),
- new Version("4.18.0"),
- new Version("4.19.0"),
- new Version("4.19.1"),
- new Version("4.19.2"),
- new Version("4.19.3"),
- new Version("4.20.0"),
- new Version("4.21.0",
- new LiquibaseMigration("update/gitbucket-core_4.21.xml")
- ),
- new Version("4.21.1"),
- new Version("4.21.2"),
- new Version("4.22.0",
- new LiquibaseMigration("update/gitbucket-core_4.22.xml")
- ),
- new Version("4.23.0",
- new LiquibaseMigration("update/gitbucket-core_4.23.xml")
- )
-)
+object GitBucketCoreModule
+ extends Module(
+ "gitbucket-core",
+ new Version(
+ "4.0.0",
+ new LiquibaseMigration("update/gitbucket-core_4.0.xml"),
+ new SqlMigration("update/gitbucket-core_4.0.sql")
+ ),
+ new Version("4.1.0"),
+ new Version("4.2.0", new LiquibaseMigration("update/gitbucket-core_4.2.xml")),
+ new Version("4.2.1"),
+ new Version("4.3.0"),
+ new Version("4.4.0"),
+ new Version("4.5.0"),
+ new Version("4.6.0", new LiquibaseMigration("update/gitbucket-core_4.6.xml")),
+ new Version(
+ "4.7.0",
+ new LiquibaseMigration("update/gitbucket-core_4.7.xml"),
+ new SqlMigration("update/gitbucket-core_4.7.sql")
+ ),
+ new Version("4.7.1"),
+ new Version("4.8"),
+ new Version("4.9.0", new LiquibaseMigration("update/gitbucket-core_4.9.xml")),
+ new Version("4.10.0"),
+ new Version("4.11.0", new LiquibaseMigration("update/gitbucket-core_4.11.xml")),
+ new Version("4.12.0"),
+ new Version("4.12.1"),
+ new Version("4.13.0"),
+ new Version(
+ "4.14.0",
+ new LiquibaseMigration("update/gitbucket-core_4.14.xml"),
+ new SqlMigration("update/gitbucket-core_4.14.sql")
+ ),
+ new Version("4.14.1"),
+ new Version("4.15.0"),
+ new Version("4.16.0"),
+ new Version("4.17.0"),
+ new Version("4.18.0"),
+ new Version("4.19.0"),
+ new Version("4.19.1"),
+ new Version("4.19.2"),
+ new Version("4.19.3"),
+ new Version("4.20.0"),
+ new Version("4.21.0", new LiquibaseMigration("update/gitbucket-core_4.21.xml")),
+ new Version("4.21.1"),
+ new Version("4.21.2"),
+ new Version("4.22.0", new LiquibaseMigration("update/gitbucket-core_4.22.xml")),
+ new Version("4.23.0", new LiquibaseMigration("update/gitbucket-core_4.23.xml"))
+ )
diff --git a/src/main/scala/gitbucket/core/api/ApiBranch.scala b/src/main/scala/gitbucket/core/api/ApiBranch.scala
index faee455..a33f7a9 100644
--- a/src/main/scala/gitbucket/core/api/ApiBranch.scala
+++ b/src/main/scala/gitbucket/core/api/ApiBranch.scala
@@ -6,13 +6,14 @@
* https://developer.github.com/v3/repos/#get-branch
* https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection
*/
-case class ApiBranch(
- name: String,
- commit: ApiBranchCommit,
- protection: ApiBranchProtection)(repositoryName:RepositoryName) extends FieldSerializable {
- def _links = Map(
- "self" -> ApiPath(s"/api/v3/repos/${repositoryName.fullName}/branches/${name}"),
- "html" -> ApiPath(s"/${repositoryName.fullName}/tree/${name}"))
+case class ApiBranch(name: String, commit: ApiBranchCommit, protection: ApiBranchProtection)(
+ repositoryName: RepositoryName
+) extends FieldSerializable {
+ def _links =
+ Map(
+ "self" -> ApiPath(s"/api/v3/repos/${repositoryName.fullName}/branches/${name}"),
+ "html" -> ApiPath(s"/${repositoryName.fullName}/tree/${name}")
+ )
}
case class ApiBranchCommit(sha: String)
diff --git a/src/main/scala/gitbucket/core/api/ApiBranchProtection.scala b/src/main/scala/gitbucket/core/api/ApiBranchProtection.scala
index dc452eb..0b7fae4 100644
--- a/src/main/scala/gitbucket/core/api/ApiBranchProtection.scala
+++ b/src/main/scala/gitbucket/core/api/ApiBranchProtection.scala
@@ -4,17 +4,22 @@
import org.json4s._
/** https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection */
-case class ApiBranchProtection(enabled: Boolean, required_status_checks: Option[ApiBranchProtection.Status]){
+case class ApiBranchProtection(enabled: Boolean, required_status_checks: Option[ApiBranchProtection.Status]) {
def status: ApiBranchProtection.Status = required_status_checks.getOrElse(ApiBranchProtection.statusNone)
}
-object ApiBranchProtection{
+object ApiBranchProtection {
+
/** form for enabling-and-disabling-branch-protection */
case class EnablingAndDisabling(protection: ApiBranchProtection)
- def apply(info: ProtectedBranchService.ProtectedBranchInfo): ApiBranchProtection = ApiBranchProtection(
- enabled = info.enabled,
- required_status_checks = Some(Status(EnforcementLevel(info.enabled && info.contexts.nonEmpty, info.includeAdministrators), info.contexts)))
+ def apply(info: ProtectedBranchService.ProtectedBranchInfo): ApiBranchProtection =
+ ApiBranchProtection(
+ enabled = info.enabled,
+ required_status_checks = Some(
+ Status(EnforcementLevel(info.enabled && info.contexts.nonEmpty, info.includeAdministrators), info.contexts)
+ )
+ )
val statusNone = Status(Off, Seq.empty)
case class Status(enforcement_level: EnforcementLevel, contexts: Seq[String])
sealed class EnforcementLevel(val name: String)
@@ -22,25 +27,28 @@
case object NonAdmins extends EnforcementLevel("non_admins")
case object Everyone extends EnforcementLevel("everyone")
object EnforcementLevel {
- def apply(enabled: Boolean, includeAdministrators: Boolean): EnforcementLevel = if(enabled){
- if(includeAdministrators){
- Everyone
- }else{
- NonAdmins
+ def apply(enabled: Boolean, includeAdministrators: Boolean): EnforcementLevel =
+ if (enabled) {
+ if (includeAdministrators) {
+ Everyone
+ } else {
+ NonAdmins
+ }
+ } else {
+ Off
}
- }else{
- Off
- }
}
- implicit val enforcementLevelSerializer = new CustomSerializer[EnforcementLevel](format => (
- {
- case JString("off") => Off
- case JString("non_admins") => NonAdmins
- case JString("everyone") => Everyone
- },
- {
- case x: EnforcementLevel => JString(x.name)
- }
- ))
+ implicit val enforcementLevelSerializer = new CustomSerializer[EnforcementLevel](
+ format =>
+ (
+ {
+ case JString("off") => Off
+ case JString("non_admins") => NonAdmins
+ case JString("everyone") => Everyone
+ }, {
+ case x: EnforcementLevel => JString(x.name)
+ }
+ )
+ )
}
diff --git a/src/main/scala/gitbucket/core/api/ApiCombinedCommitStatus.scala b/src/main/scala/gitbucket/core/api/ApiCombinedCommitStatus.scala
index 6a2ccf8..d10d55b 100644
--- a/src/main/scala/gitbucket/core/api/ApiCombinedCommitStatus.scala
+++ b/src/main/scala/gitbucket/core/api/ApiCombinedCommitStatus.scala
@@ -2,7 +2,6 @@
import gitbucket.core.model.{Account, CommitState, CommitStatus}
-
/**
* https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref
*/
@@ -11,15 +10,22 @@
sha: String,
total_count: Int,
statuses: Iterable[ApiCommitStatus],
- repository: ApiRepository){
+ repository: ApiRepository
+) {
// val commit_url = ApiPath(s"/api/v3/repos/${repository.full_name}/${sha}")
val url = ApiPath(s"/api/v3/repos/${repository.full_name}/commits/${sha}/status")
}
object ApiCombinedCommitStatus {
- def apply(sha:String, statuses: Iterable[(CommitStatus, Account)], repository:ApiRepository): ApiCombinedCommitStatus = ApiCombinedCommitStatus(
- state = CommitState.combine(statuses.map(_._1.state).toSet).name,
- sha = sha,
- total_count= statuses.size,
- statuses = statuses.map{ case (s, a)=> ApiCommitStatus(s, ApiUser(a)) },
- repository = repository)
+ def apply(
+ sha: String,
+ statuses: Iterable[(CommitStatus, Account)],
+ repository: ApiRepository
+ ): ApiCombinedCommitStatus =
+ ApiCombinedCommitStatus(
+ state = CommitState.combine(statuses.map(_._1.state).toSet).name,
+ sha = sha,
+ total_count = statuses.size,
+ statuses = statuses.map { case (s, a) => ApiCommitStatus(s, ApiUser(a)) },
+ repository = repository
+ )
}
diff --git a/src/main/scala/gitbucket/core/api/ApiComment.scala b/src/main/scala/gitbucket/core/api/ApiComment.scala
index 62bcd3c..89027af 100644
--- a/src/main/scala/gitbucket/core/api/ApiComment.scala
+++ b/src/main/scala/gitbucket/core/api/ApiComment.scala
@@ -5,25 +5,32 @@
import java.util.Date
-
/**
* https://developer.github.com/v3/issues/comments/
*/
-case class ApiComment(
- id: Int,
- user: ApiUser,
- body: String,
- created_at: Date,
- updated_at: Date)(repositoryName: RepositoryName, issueId: Int, isPullRequest: Boolean){
- val html_url = ApiPath(s"/${repositoryName.fullName}/${if(isPullRequest){ "pull" }else{ "issues" }}/${issueId}#comment-${id}")
+case class ApiComment(id: Int, user: ApiUser, body: String, created_at: Date, updated_at: Date)(
+ repositoryName: RepositoryName,
+ issueId: Int,
+ isPullRequest: Boolean
+) {
+ val html_url = ApiPath(
+ s"/${repositoryName.fullName}/${if (isPullRequest) { "pull" } else { "issues" }}/${issueId}#comment-${id}"
+ )
}
-object ApiComment{
- def apply(comment: IssueComment, repositoryName: RepositoryName, issueId: Int, user: ApiUser, isPullRequest: Boolean): ApiComment =
+object ApiComment {
+ def apply(
+ comment: IssueComment,
+ repositoryName: RepositoryName,
+ issueId: Int,
+ user: ApiUser,
+ isPullRequest: Boolean
+ ): ApiComment =
ApiComment(
id = comment.commentId,
user = user,
body = comment.content,
created_at = comment.registeredDate,
- updated_at = comment.updatedDate)(repositoryName, issueId, isPullRequest)
+ updated_at = comment.updatedDate
+ )(repositoryName, issueId, isPullRequest)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiCommit.scala b/src/main/scala/gitbucket/core/api/ApiCommit.scala
index 04c05a5..f564f13 100644
--- a/src/main/scala/gitbucket/core/api/ApiCommit.scala
+++ b/src/main/scala/gitbucket/core/api/ApiCommit.scala
@@ -20,38 +20,41 @@
removed: List[String],
modified: List[String],
author: ApiPersonIdent,
- committer: ApiPersonIdent)(repositoryName:RepositoryName, urlIsHtmlUrl: Boolean) extends FieldSerializable{
- val url = if(urlIsHtmlUrl){
+ committer: ApiPersonIdent
+)(repositoryName: RepositoryName, urlIsHtmlUrl: Boolean)
+ extends FieldSerializable {
+ val url = if (urlIsHtmlUrl) {
ApiPath(s"/${repositoryName.fullName}/commit/${id}")
- }else{
+ } else {
ApiPath(s"/api/v3/${repositoryName.fullName}/commits/${id}")
}
- val html_url = if(urlIsHtmlUrl){
+ val html_url = if (urlIsHtmlUrl) {
None
- }else{
+ } else {
Some(ApiPath(s"/${repositoryName.fullName}/commit/${id}"))
}
}
-object ApiCommit{
+object ApiCommit {
def apply(git: Git, repositoryName: RepositoryName, commit: CommitInfo, urlIsHtmlUrl: Boolean = false): ApiCommit = {
val diffs = JGitUtil.getDiffs(git, None, commit.id, false, false)
ApiCommit(
- id = commit.id,
- message = commit.fullMessage,
+ id = commit.id,
+ message = commit.fullMessage,
timestamp = commit.commitTime,
- added = diffs.collect {
- case x if x.changeType == DiffEntry.ChangeType.ADD => x.newPath
+ added = diffs.collect {
+ case x if x.changeType == DiffEntry.ChangeType.ADD => x.newPath
},
- removed = diffs.collect {
+ removed = diffs.collect {
case x if x.changeType == DiffEntry.ChangeType.DELETE => x.oldPath
},
- modified = diffs.collect {
+ modified = diffs.collect {
case x if x.changeType != DiffEntry.ChangeType.ADD && x.changeType != DiffEntry.ChangeType.DELETE => x.newPath
},
- author = ApiPersonIdent.author(commit),
+ author = ApiPersonIdent.author(commit),
committer = ApiPersonIdent.committer(commit)
)(repositoryName, urlIsHtmlUrl)
}
- def forWebhookPayload(git: Git, repositoryName: RepositoryName, commit: CommitInfo): ApiCommit = apply(git, repositoryName, commit, true)
+ def forWebhookPayload(git: Git, repositoryName: RepositoryName, commit: CommitInfo): ApiCommit =
+ apply(git, repositoryName, commit, true)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiCommitListItem.scala b/src/main/scala/gitbucket/core/api/ApiCommitListItem.scala
index a57431f..7a79474 100644
--- a/src/main/scala/gitbucket/core/api/ApiCommitListItem.scala
+++ b/src/main/scala/gitbucket/core/api/ApiCommitListItem.scala
@@ -4,7 +4,6 @@
import gitbucket.core.util.JGitUtil.CommitInfo
import gitbucket.core.util.RepositoryName
-
/**
* https://developer.github.com/v3/repos/commits/
*/
@@ -13,30 +12,33 @@
commit: Commit,
author: Option[ApiUser],
committer: Option[ApiUser],
- parents: Seq[Parent])(repositoryName: RepositoryName) {
+ parents: Seq[Parent]
+)(repositoryName: RepositoryName) {
val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/commits/${sha}")
}
object ApiCommitListItem {
- def apply(commit: CommitInfo, repositoryName: RepositoryName): ApiCommitListItem = ApiCommitListItem(
- sha = commit.id,
- commit = Commit(
- message = commit.fullMessage,
- author = ApiPersonIdent.author(commit),
- committer = ApiPersonIdent.committer(commit)
+ def apply(commit: CommitInfo, repositoryName: RepositoryName): ApiCommitListItem =
+ ApiCommitListItem(
+ sha = commit.id,
+ commit = Commit(
+ message = commit.fullMessage,
+ author = ApiPersonIdent.author(commit),
+ committer = ApiPersonIdent.committer(commit)
)(commit.id, repositoryName),
- author = None,
- committer = None,
- parents = commit.parents.map(Parent(_)(repositoryName)))(repositoryName)
+ author = None,
+ committer = None,
+ parents = commit.parents.map(Parent(_)(repositoryName))
+ )(repositoryName)
- case class Parent(sha: String)(repositoryName: RepositoryName){
+ case class Parent(sha: String)(repositoryName: RepositoryName) {
val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/commits/${sha}")
}
- case class Commit(
- message: String,
- author: ApiPersonIdent,
- committer: ApiPersonIdent)(sha:String, repositoryName: RepositoryName) {
+ case class Commit(message: String, author: ApiPersonIdent, committer: ApiPersonIdent)(
+ sha: String,
+ repositoryName: RepositoryName
+ ) {
val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/git/commits/${sha}")
}
}
diff --git a/src/main/scala/gitbucket/core/api/ApiCommitStatus.scala b/src/main/scala/gitbucket/core/api/ApiCommitStatus.scala
index 03d8ef6..6142ea1 100644
--- a/src/main/scala/gitbucket/core/api/ApiCommitStatus.scala
+++ b/src/main/scala/gitbucket/core/api/ApiCommitStatus.scala
@@ -5,7 +5,6 @@
import java.util.Date
-
/**
* https://developer.github.com/v3/repos/statuses/#create-a-status
* https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
@@ -23,16 +22,16 @@
val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/commits/${sha}/statuses")
}
-
object ApiCommitStatus {
- def apply(status: CommitStatus, creator:ApiUser): ApiCommitStatus = ApiCommitStatus(
- created_at = status.registeredDate,
- updated_at = status.updatedDate,
- state = status.state.name,
- target_url = status.targetUrl,
- description= status.description,
- id = status.commitStatusId,
- context = status.context,
- creator = creator
- )(status.commitId, RepositoryName(status))
+ def apply(status: CommitStatus, creator: ApiUser): ApiCommitStatus =
+ ApiCommitStatus(
+ created_at = status.registeredDate,
+ updated_at = status.updatedDate,
+ state = status.state.name,
+ target_url = status.targetUrl,
+ description = status.description,
+ id = status.commitStatusId,
+ context = status.context,
+ creator = creator
+ )(status.commitId, RepositoryName(status))
}
diff --git a/src/main/scala/gitbucket/core/api/ApiCommits.scala b/src/main/scala/gitbucket/core/api/ApiCommits.scala
index dc3e2ad..3b1f014 100644
--- a/src/main/scala/gitbucket/core/api/ApiCommits.scala
+++ b/src/main/scala/gitbucket/core/api/ApiCommits.scala
@@ -51,20 +51,25 @@
patch: String
)
-
- def apply(repositoryName: RepositoryName, commitInfo: CommitInfo, diffs: Seq[DiffInfo], author: Account, committer: Account,
- commentCount: Int): ApiCommits = {
+ def apply(
+ repositoryName: RepositoryName,
+ commitInfo: CommitInfo,
+ diffs: Seq[DiffInfo],
+ author: Account,
+ committer: Account,
+ commentCount: Int
+ ): ApiCommits = {
val files = diffs.map { diff =>
var additions = 0
var deletions = 0
diff.patch.getOrElse("").split("\n").foreach { line =>
- if(line.startsWith("+")) additions = additions + 1
- if(line.startsWith("-")) deletions = deletions + 1
+ if (line.startsWith("+")) additions = additions + 1
+ if (line.startsWith("-")) deletions = deletions + 1
}
File(
- filename = if(diff.changeType == ChangeType.DELETE){ diff.oldPath } else { diff.newPath },
+ filename = if (diff.changeType == ChangeType.DELETE) { diff.oldPath } else { diff.newPath },
additions = additions,
deletions = deletions,
changes = additions + deletions,
@@ -75,12 +80,12 @@
case ChangeType.RENAME => "renamed"
case ChangeType.COPY => "copied"
},
- raw_url = if(diff.changeType == ChangeType.DELETE){
+ raw_url = if (diff.changeType == ChangeType.DELETE) {
ApiPath(s"/${repositoryName.fullName}/raw/${commitInfo.parents.head}/${diff.oldPath}")
} else {
ApiPath(s"/${repositoryName.fullName}/raw/${commitInfo.id}/${diff.newPath}")
},
- blob_url = if(diff.changeType == ChangeType.DELETE){
+ blob_url = if (diff.changeType == ChangeType.DELETE) {
ApiPath(s"/${repositoryName.fullName}/blob/${commitInfo.parents.head}/${diff.oldPath}")
} else {
ApiPath(s"/${repositoryName.fullName}/blob/${commitInfo.id}/${diff.newPath}")
diff --git a/src/main/scala/gitbucket/core/api/ApiContents.scala b/src/main/scala/gitbucket/core/api/ApiContents.scala
index 8b3735a..f340595 100644
--- a/src/main/scala/gitbucket/core/api/ApiContents.scala
+++ b/src/main/scala/gitbucket/core/api/ApiContents.scala
@@ -11,18 +11,29 @@
path: String,
sha: String,
content: Option[String],
- encoding: Option[String])(repositoryName: RepositoryName){
+ encoding: Option[String]
+)(repositoryName: RepositoryName) {
val download_url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/raw/${sha}/${path}")
}
-object ApiContents{
+object ApiContents {
def apply(fileInfo: FileInfo, repositoryName: RepositoryName, content: Option[Array[Byte]]): ApiContents = {
- if(fileInfo.isDirectory) {
+ if (fileInfo.isDirectory) {
ApiContents("dir", fileInfo.name, fileInfo.path, fileInfo.commitId, None, None)(repositoryName)
} else {
- content.map(arr =>
- ApiContents("file", fileInfo.name, fileInfo.path, fileInfo.commitId, Some(Base64.getEncoder.encodeToString(arr)), Some("base64"))(repositoryName)
- ).getOrElse(ApiContents("file", fileInfo.name, fileInfo.path, fileInfo.commitId, None, None)(repositoryName))
+ content
+ .map(
+ arr =>
+ ApiContents(
+ "file",
+ fileInfo.name,
+ fileInfo.path,
+ fileInfo.commitId,
+ Some(Base64.getEncoder.encodeToString(arr)),
+ Some("base64")
+ )(repositoryName)
+ )
+ .getOrElse(ApiContents("file", fileInfo.name, fileInfo.path, fileInfo.commitId, None, None)(repositoryName))
}
}
}
diff --git a/src/main/scala/gitbucket/core/api/ApiEndPoint.scala b/src/main/scala/gitbucket/core/api/ApiEndPoint.scala
index 4c66d84..015c456 100644
--- a/src/main/scala/gitbucket/core/api/ApiEndPoint.scala
+++ b/src/main/scala/gitbucket/core/api/ApiEndPoint.scala
@@ -1,3 +1,3 @@
package gitbucket.core.api
-case class ApiEndPoint(rate_limit_url: ApiPath = ApiPath("/api/v3/rate_limit"))
\ No newline at end of file
+case class ApiEndPoint(rate_limit_url: ApiPath = ApiPath("/api/v3/rate_limit"))
diff --git a/src/main/scala/gitbucket/core/api/ApiError.scala b/src/main/scala/gitbucket/core/api/ApiError.scala
index 95114d1..f3e755b 100644
--- a/src/main/scala/gitbucket/core/api/ApiError.scala
+++ b/src/main/scala/gitbucket/core/api/ApiError.scala
@@ -1,5 +1,3 @@
package gitbucket.core.api
-case class ApiError(
- message: String,
- documentation_url: Option[String] = None)
+case class ApiError(message: String, documentation_url: Option[String] = None)
diff --git a/src/main/scala/gitbucket/core/api/ApiIssue.scala b/src/main/scala/gitbucket/core/api/ApiIssue.scala
index 9f27f55..b03cf48 100644
--- a/src/main/scala/gitbucket/core/api/ApiIssue.scala
+++ b/src/main/scala/gitbucket/core/api/ApiIssue.scala
@@ -5,7 +5,6 @@
import java.util.Date
-
/**
* https://developer.github.com/v3/issues/
*/
@@ -17,30 +16,34 @@
state: String,
created_at: Date,
updated_at: Date,
- body: String)(repositoryName: RepositoryName, isPullRequest: Boolean){
+ body: String
+)(repositoryName: RepositoryName, isPullRequest: Boolean) {
val comments_url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/issues/${number}/comments")
- val html_url = ApiPath(s"/${repositoryName.fullName}/${if(isPullRequest){ "pull" }else{ "issues" }}/${number}")
+ val html_url = ApiPath(s"/${repositoryName.fullName}/${if (isPullRequest) { "pull" } else { "issues" }}/${number}")
val pull_request = if (isPullRequest) {
- Some(Map(
- "url" -> ApiPath(s"/api/v3/repos/${repositoryName.fullName}/pulls/${number}"),
- "html_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}")
- // "diff_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}.diff"),
- // "patch_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}.patch")
- ))
+ Some(
+ Map(
+ "url" -> ApiPath(s"/api/v3/repos/${repositoryName.fullName}/pulls/${number}"),
+ "html_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}")
+ // "diff_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}.diff"),
+ // "patch_url" -> ApiPath(s"/${repositoryName.fullName}/pull/${number}.patch")
+ )
+ )
} else {
None
}
}
-object ApiIssue{
+object ApiIssue {
def apply(issue: Issue, repositoryName: RepositoryName, user: ApiUser, labels: List[ApiLabel]): ApiIssue =
ApiIssue(
number = issue.issueId,
- title = issue.title,
- user = user,
+ title = issue.title,
+ user = user,
labels = labels,
- state = if(issue.closed){ "closed" }else{ "open" },
- body = issue.content.getOrElse(""),
+ state = if (issue.closed) { "closed" } else { "open" },
+ body = issue.content.getOrElse(""),
created_at = issue.registeredDate,
- updated_at = issue.updatedDate)(repositoryName, issue.isPullRequest)
+ updated_at = issue.updatedDate
+ )(repositoryName, issue.isPullRequest)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiLabel.scala b/src/main/scala/gitbucket/core/api/ApiLabel.scala
index 2d1842b..4a080a1 100644
--- a/src/main/scala/gitbucket/core/api/ApiLabel.scala
+++ b/src/main/scala/gitbucket/core/api/ApiLabel.scala
@@ -4,18 +4,16 @@
import gitbucket.core.util.RepositoryName
/**
- * https://developer.github.com/v3/issues/labels/
- */
-case class ApiLabel(
- name: String,
- color: String)(repositoryName: RepositoryName){
+ * https://developer.github.com/v3/issues/labels/
+ */
+case class ApiLabel(name: String, color: String)(repositoryName: RepositoryName) {
var url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/labels/${name}")
}
-object ApiLabel{
- def apply(label:Label, repositoryName: RepositoryName): ApiLabel =
+object ApiLabel {
+ def apply(label: Label, repositoryName: RepositoryName): ApiLabel =
ApiLabel(
name = label.labelName,
color = label.color
)(repositoryName)
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/gitbucket/core/api/ApiPersonIdent.scala b/src/main/scala/gitbucket/core/api/ApiPersonIdent.scala
index 3c31e15..f242e3b 100644
--- a/src/main/scala/gitbucket/core/api/ApiPersonIdent.scala
+++ b/src/main/scala/gitbucket/core/api/ApiPersonIdent.scala
@@ -4,22 +4,11 @@
import java.util.Date
-
-case class ApiPersonIdent(
- name: String,
- email: String,
- date: Date)
-
+case class ApiPersonIdent(name: String, email: String, date: Date)
object ApiPersonIdent {
def author(commit: CommitInfo): ApiPersonIdent =
- ApiPersonIdent(
- name = commit.authorName,
- email = commit.authorEmailAddress,
- date = commit.authorTime)
+ ApiPersonIdent(name = commit.authorName, email = commit.authorEmailAddress, date = commit.authorTime)
def committer(commit: CommitInfo): ApiPersonIdent =
- ApiPersonIdent(
- name = commit.committerName,
- email = commit.committerEmailAddress,
- date = commit.commitTime)
+ ApiPersonIdent(name = commit.committerName, email = commit.committerEmailAddress, date = commit.commitTime)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiPlugin.scala b/src/main/scala/gitbucket/core/api/ApiPlugin.scala
index e7dbcef..d386556 100644
--- a/src/main/scala/gitbucket/core/api/ApiPlugin.scala
+++ b/src/main/scala/gitbucket/core/api/ApiPlugin.scala
@@ -10,7 +10,7 @@
jarFileName: String
)
-object ApiPlugin{
+object ApiPlugin {
def apply(plugin: PluginInfo): ApiPlugin = {
ApiPlugin(plugin.pluginId, plugin.pluginName, plugin.pluginVersion, plugin.description, plugin.pluginJar.getName)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiPullRequest.scala b/src/main/scala/gitbucket/core/api/ApiPullRequest.scala
index bf7f886..50d20b3 100644
--- a/src/main/scala/gitbucket/core/api/ApiPullRequest.scala
+++ b/src/main/scala/gitbucket/core/api/ApiPullRequest.scala
@@ -21,20 +21,21 @@
body: String,
user: ApiUser,
labels: List[ApiLabel],
- assignee: Option[ApiUser]){
- val html_url = ApiPath(s"${base.repo.html_url.path}/pull/${number}")
+ assignee: Option[ApiUser]
+) {
+ val html_url = ApiPath(s"${base.repo.html_url.path}/pull/${number}")
//val diff_url = ApiPath(s"${base.repo.html_url.path}/pull/${number}.diff")
//val patch_url = ApiPath(s"${base.repo.html_url.path}/pull/${number}.patch")
- val url = ApiPath(s"${base.repo.url.path}/pulls/${number}")
+ val url = ApiPath(s"${base.repo.url.path}/pulls/${number}")
//val issue_url = ApiPath(s"${base.repo.url.path}/issues/${number}")
- val commits_url = ApiPath(s"${base.repo.url.path}/pulls/${number}/commits")
+ val commits_url = ApiPath(s"${base.repo.url.path}/pulls/${number}/commits")
val review_comments_url = ApiPath(s"${base.repo.url.path}/pulls/${number}/comments")
- val review_comment_url = ApiPath(s"${base.repo.url.path}/pulls/comments/{number}")
- val comments_url = ApiPath(s"${base.repo.url.path}/issues/${number}/comments")
- val statuses_url = ApiPath(s"${base.repo.url.path}/statuses/${head.sha}")
+ val review_comment_url = ApiPath(s"${base.repo.url.path}/pulls/comments/{number}")
+ val comments_url = ApiPath(s"${base.repo.url.path}/issues/${number}/comments")
+ val statuses_url = ApiPath(s"${base.repo.url.path}/statuses/${head.sha}")
}
-object ApiPullRequest{
+object ApiPullRequest {
def apply(
issue: Issue,
pullRequest: PullRequest,
@@ -46,34 +47,25 @@
mergedComment: Option[(IssueComment, Account)]
): ApiPullRequest =
ApiPullRequest(
- number = issue.issueId,
- state = if (issue.closed) "closed" else "open",
+ number = issue.issueId,
+ state = if (issue.closed) "closed" else "open",
updated_at = issue.updatedDate,
created_at = issue.registeredDate,
- head = Commit(
- sha = pullRequest.commitIdTo,
- ref = pullRequest.requestBranch,
- repo = headRepo)(issue.userName),
- base = Commit(
- sha = pullRequest.commitIdFrom,
- ref = pullRequest.branch,
- repo = baseRepo)(issue.userName),
- mergeable = None, // TODO: need check mergeable.
- merged = mergedComment.isDefined,
- merged_at = mergedComment.map { case (comment, _) => comment.registeredDate },
- merged_by = mergedComment.map { case (_, account) => ApiUser(account) },
- title = issue.title,
- body = issue.content.getOrElse(""),
- user = user,
- labels = labels,
- assignee = assignee
+ head = Commit(sha = pullRequest.commitIdTo, ref = pullRequest.requestBranch, repo = headRepo)(issue.userName),
+ base = Commit(sha = pullRequest.commitIdFrom, ref = pullRequest.branch, repo = baseRepo)(issue.userName),
+ mergeable = None, // TODO: need check mergeable.
+ merged = mergedComment.isDefined,
+ merged_at = mergedComment.map { case (comment, _) => comment.registeredDate },
+ merged_by = mergedComment.map { case (_, account) => ApiUser(account) },
+ title = issue.title,
+ body = issue.content.getOrElse(""),
+ user = user,
+ labels = labels,
+ assignee = assignee
)
- case class Commit(
- sha: String,
- ref: String,
- repo: ApiRepository)(baseOwner:String){
- val label = if( baseOwner == repo.owner.login ){ ref } else { s"${repo.owner.login}:${ref}" }
+ case class Commit(sha: String, ref: String, repo: ApiRepository)(baseOwner: String) {
+ val label = if (baseOwner == repo.owner.login) { ref } else { s"${repo.owner.login}:${ref}" }
val user = repo.owner
}
diff --git a/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala b/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala
index 55d1fe9..7516b2e 100644
--- a/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala
+++ b/src/main/scala/gitbucket/core/api/ApiPullRequestReviewComment.scala
@@ -18,9 +18,10 @@
// "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
user: ApiUser,
body: String, // "Maybe you should use more emojji on this line.",
- created_at: Date, // "2015-05-05T23:40:27Z",
+ created_at: Date, // "2015-05-05T23:40:27Z",
updated_at: Date // "2015-05-05T23:40:27Z",
-)(repositoryName:RepositoryName, issueId: Int) extends FieldSerializable {
+)(repositoryName: RepositoryName, issueId: Int)
+ extends FieldSerializable {
// "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692",
val url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/pulls/comments/${id}")
// "html_url": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692",
@@ -40,22 +41,28 @@
"href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1"
}
}
- */
+ */
val _links = Map(
"self" -> Map("href" -> url),
"html" -> Map("href" -> html_url),
- "pull_request" -> Map("href" -> pull_request_url))
+ "pull_request" -> Map("href" -> pull_request_url)
+ )
}
-object ApiPullRequestReviewComment{
- def apply(comment: CommitComment, commentedUser: ApiUser, repositoryName: RepositoryName, issueId: Int): ApiPullRequestReviewComment =
+object ApiPullRequestReviewComment {
+ def apply(
+ comment: CommitComment,
+ commentedUser: ApiUser,
+ repositoryName: RepositoryName,
+ issueId: Int
+ ): ApiPullRequestReviewComment =
new ApiPullRequestReviewComment(
- id = comment.commentId,
- path = comment.fileName.getOrElse(""),
- commit_id = comment.commitId,
- user = commentedUser,
- body = comment.content,
- created_at = comment.registeredDate,
- updated_at = comment.updatedDate
- )(repositoryName, issueId)
+ id = comment.commentId,
+ path = comment.fileName.getOrElse(""),
+ commit_id = comment.commitId,
+ user = commentedUser,
+ body = comment.content,
+ created_at = comment.registeredDate,
+ updated_at = comment.updatedDate
+ )(repositoryName, issueId)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiPusher.scala b/src/main/scala/gitbucket/core/api/ApiPusher.scala
index a0b714e..038e699 100644
--- a/src/main/scala/gitbucket/core/api/ApiPusher.scala
+++ b/src/main/scala/gitbucket/core/api/ApiPusher.scala
@@ -5,7 +5,5 @@
case class ApiPusher(name: String, email: String)
object ApiPusher {
- def apply(user: Account): ApiPusher = ApiPusher(
- name = user.userName,
- email = user.mailAddress)
-}
\ No newline at end of file
+ def apply(user: Account): ApiPusher = ApiPusher(name = user.userName, email = user.mailAddress)
+}
diff --git a/src/main/scala/gitbucket/core/api/ApiRepository.scala b/src/main/scala/gitbucket/core/api/ApiRepository.scala
index facaf3f..549e8e7 100644
--- a/src/main/scala/gitbucket/core/api/ApiRepository.scala
+++ b/src/main/scala/gitbucket/core/api/ApiRepository.scala
@@ -3,7 +3,6 @@
import gitbucket.core.model.{Account, Repository}
import gitbucket.core.service.RepositoryService.RepositoryInfo
-
// https://developer.github.com/v3/repos/
case class ApiRepository(
name: String,
@@ -13,56 +12,58 @@
forks: Int,
`private`: Boolean,
default_branch: String,
- owner: ApiUser)(urlIsHtmlUrl: Boolean) {
+ owner: ApiUser
+)(urlIsHtmlUrl: Boolean) {
val forks_count = forks
val watchers_count = watchers
- val url = if(urlIsHtmlUrl){
+ val url = if (urlIsHtmlUrl) {
ApiPath(s"/${full_name}")
} else {
ApiPath(s"/api/v3/repos/${full_name}")
}
- val http_url = ApiPath(s"/git/${full_name}.git")
+ val http_url = ApiPath(s"/git/${full_name}.git")
val clone_url = ApiPath(s"/git/${full_name}.git")
- val html_url = ApiPath(s"/${full_name}")
- val ssh_url = Some(SshPath(s":${full_name}.git"))
+ val html_url = ApiPath(s"/${full_name}")
+ val ssh_url = Some(SshPath(s":${full_name}.git"))
}
-object ApiRepository{
+object ApiRepository {
def apply(
- repository: Repository,
- owner: ApiUser,
- forkedCount: Int =0,
- watchers: Int = 0,
- urlIsHtmlUrl: Boolean = false): ApiRepository =
+ repository: Repository,
+ owner: ApiUser,
+ forkedCount: Int = 0,
+ watchers: Int = 0,
+ urlIsHtmlUrl: Boolean = false
+ ): ApiRepository =
ApiRepository(
- name = repository.repositoryName,
- full_name = s"${repository.userName}/${repository.repositoryName}",
- description = repository.description.getOrElse(""),
- watchers = watchers,
- forks = forkedCount,
- `private` = repository.isPrivate,
+ name = repository.repositoryName,
+ full_name = s"${repository.userName}/${repository.repositoryName}",
+ description = repository.description.getOrElse(""),
+ watchers = watchers,
+ forks = forkedCount,
+ `private` = repository.isPrivate,
default_branch = repository.defaultBranch,
- owner = owner
+ owner = owner
)(urlIsHtmlUrl)
def apply(repositoryInfo: RepositoryInfo, owner: ApiUser): ApiRepository =
- ApiRepository(repositoryInfo.repository, owner, forkedCount=repositoryInfo.forkedCount)
+ ApiRepository(repositoryInfo.repository, owner, forkedCount = repositoryInfo.forkedCount)
def apply(repositoryInfo: RepositoryInfo, owner: Account): ApiRepository =
this(repositoryInfo.repository, ApiUser(owner))
def forWebhookPayload(repositoryInfo: RepositoryInfo, owner: ApiUser): ApiRepository =
- ApiRepository(repositoryInfo.repository, owner, forkedCount=repositoryInfo.forkedCount, urlIsHtmlUrl=true)
+ ApiRepository(repositoryInfo.repository, owner, forkedCount = repositoryInfo.forkedCount, urlIsHtmlUrl = true)
def forDummyPayload(owner: ApiUser): ApiRepository =
ApiRepository(
- name = "dummy",
- full_name = s"${owner.login}/dummy",
- description = "",
- watchers = 0,
- forks = 0,
- `private` = false,
+ name = "dummy",
+ full_name = s"${owner.login}/dummy",
+ description = "",
+ watchers = 0,
+ forks = 0,
+ `private` = false,
default_branch = "master",
- owner = owner
+ owner = owner
)(true)
}
diff --git a/src/main/scala/gitbucket/core/api/ApiUser.scala b/src/main/scala/gitbucket/core/api/ApiUser.scala
index 9b3dc9d..5d74e40 100644
--- a/src/main/scala/gitbucket/core/api/ApiUser.scala
+++ b/src/main/scala/gitbucket/core/api/ApiUser.scala
@@ -4,16 +4,10 @@
import java.util.Date
-
-case class ApiUser(
- login: String,
- email: String,
- `type`: String,
- site_admin: Boolean,
- created_at: Date) {
- val url = ApiPath(s"/api/v3/users/${login}")
- val html_url = ApiPath(s"/${login}")
- val avatar_url = ApiPath(s"/${login}/_avatar")
+case class ApiUser(login: String, email: String, `type`: String, site_admin: Boolean, created_at: Date) {
+ val url = ApiPath(s"/api/v3/users/${login}")
+ val html_url = ApiPath(s"/${login}")
+ val avatar_url = ApiPath(s"/${login}/_avatar")
// val followers_url = ApiPath(s"/api/v3/users/${login}/followers")
// val following_url = ApiPath(s"/api/v3/users/${login}/following{/other_user}")
// val gists_url = ApiPath(s"/api/v3/users/${login}/gists{/gist_id}")
@@ -25,12 +19,11 @@
// val received_events_url = ApiPath(s"/api/v3/users/${login}/received_events")
}
-
-object ApiUser{
+object ApiUser {
def apply(user: Account): ApiUser = ApiUser(
- login = user.userName,
- email = user.mailAddress,
- `type` = if(user.isGroupAccount){ "Organization" } else { "User" },
+ login = user.userName,
+ email = user.mailAddress,
+ `type` = if (user.isGroupAccount) { "Organization" } else { "User" },
site_admin = user.isAdmin,
created_at = user.registeredDate
)
diff --git a/src/main/scala/gitbucket/core/api/CreateALabel.scala b/src/main/scala/gitbucket/core/api/CreateALabel.scala
index cfd71d1..fce7c2c 100644
--- a/src/main/scala/gitbucket/core/api/CreateALabel.scala
+++ b/src/main/scala/gitbucket/core/api/CreateALabel.scala
@@ -1,18 +1,18 @@
package gitbucket.core.api
/**
- * https://developer.github.com/v3/issues/labels/#create-a-label
- * api form
- */
+ * https://developer.github.com/v3/issues/labels/#create-a-label
+ * api form
+ */
case class CreateALabel(
- name: String,
- color: String
+ name: String,
+ color: String
) {
def isValid: Boolean = {
- name.length<=100 &&
- !name.startsWith("_") &&
- !name.startsWith("-") &&
- color.length==6 &&
- color.matches("[a-fA-F0-9+_.]+")
+ name.length <= 100 &&
+ !name.startsWith("_") &&
+ !name.startsWith("-") &&
+ color.length == 6 &&
+ color.matches("[a-fA-F0-9+_.]+")
}
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/gitbucket/core/api/CreateARepository.scala b/src/main/scala/gitbucket/core/api/CreateARepository.scala
index 7247c9f..93dd00a 100644
--- a/src/main/scala/gitbucket/core/api/CreateARepository.scala
+++ b/src/main/scala/gitbucket/core/api/CreateARepository.scala
@@ -5,15 +5,15 @@
* api form
*/
case class CreateARepository(
- name: String,
- description: Option[String],
- `private`: Boolean = false,
- auto_init: Boolean = false
+ name: String,
+ description: Option[String],
+ `private`: Boolean = false,
+ auto_init: Boolean = false
) {
def isValid: Boolean = {
name.length <= 100 &&
- name.matches("[a-zA-Z0-9\\-\\+_.]+") &&
- !name.startsWith("_") &&
- !name.startsWith("-")
+ name.matches("[a-zA-Z0-9\\-\\+_.]+") &&
+ !name.startsWith("_") &&
+ !name.startsWith("-")
}
}
diff --git a/src/main/scala/gitbucket/core/api/CreateAStatus.scala b/src/main/scala/gitbucket/core/api/CreateAStatus.scala
index f8c087f..862533b 100644
--- a/src/main/scala/gitbucket/core/api/CreateAStatus.scala
+++ b/src/main/scala/gitbucket/core/api/CreateAStatus.scala
@@ -18,9 +18,9 @@
) {
def isValid: Boolean = {
CommitState.valueOf(state).isDefined &&
- // only http
- target_url.forall(f => "\\Ahttps?://".r.findPrefixOf(f).isDefined && f.length < 255) &&
- context.forall(f => f.length < 255) &&
- description.forall(f => f.length < 1000)
+ // only http
+ target_url.forall(f => "\\Ahttps?://".r.findPrefixOf(f).isDefined && f.length < 255) &&
+ context.forall(f => f.length < 255) &&
+ description.forall(f => f.length < 1000)
}
}
diff --git a/src/main/scala/gitbucket/core/api/CreateAnIssue.scala b/src/main/scala/gitbucket/core/api/CreateAnIssue.scala
index cb54652..16585b7 100644
--- a/src/main/scala/gitbucket/core/api/CreateAnIssue.scala
+++ b/src/main/scala/gitbucket/core/api/CreateAnIssue.scala
@@ -1,11 +1,12 @@
package gitbucket.core.api
/**
- * https://developer.github.com/v3/issues/#create-an-issue
- */
+ * https://developer.github.com/v3/issues/#create-an-issue
+ */
case class CreateAnIssue(
- title: String,
- body: Option[String],
- assignees: List[String],
- milestone: Option[Int],
- labels: List[String])
+ title: String,
+ body: Option[String],
+ assignees: List[String],
+ milestone: Option[Int],
+ labels: List[String]
+)
diff --git a/src/main/scala/gitbucket/core/api/JsonFormat.scala b/src/main/scala/gitbucket/core/api/JsonFormat.scala
index a9fddcd..8579926 100644
--- a/src/main/scala/gitbucket/core/api/JsonFormat.scala
+++ b/src/main/scala/gitbucket/core/api/JsonFormat.scala
@@ -15,10 +15,13 @@
val parserISO = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
- val jsonFormats = Serialization.formats(NoTypeHints) + new CustomSerializer[Date](format =>
- (
- { case JString(s) => Try(Date.from(Instant.parse(s))).getOrElse(throw new MappingException("Can't convert " + s + " to Date")) },
- { case x: Date => JString(OffsetDateTime.ofInstant(x.toInstant, ZoneId.of("UTC")).format(parserISO)) }
+ val jsonFormats = Serialization.formats(NoTypeHints) + new CustomSerializer[Date](
+ format =>
+ (
+ {
+ case JString(s) =>
+ Try(Date.from(Instant.parse(s))).getOrElse(throw new MappingException("Can't convert " + s + " to Date"))
+ }, { case x: Date => JString(OffsetDateTime.ofInstant(x.toInstant, ZoneId.of("UTC")).format(parserISO)) }
)
) + FieldSerializer[ApiUser]() +
FieldSerializer[ApiPullRequest]() +
@@ -41,19 +44,31 @@
FieldSerializer[ApiCommits.File]() +
ApiBranchProtection.enforcementLevelSerializer
- def apiPathSerializer(c: Context) = new CustomSerializer[ApiPath](_ => ({
- case JString(s) if s.startsWith(c.baseUrl) => ApiPath(s.substring(c.baseUrl.length))
- case JString(s) => throw new MappingException("Can't convert " + s + " to ApiPath")
- }, {
- case ApiPath(path) => JString(c.baseUrl + path)
- }))
+ def apiPathSerializer(c: Context) =
+ new CustomSerializer[ApiPath](
+ _ =>
+ ({
+ case JString(s) if s.startsWith(c.baseUrl) => ApiPath(s.substring(c.baseUrl.length))
+ case JString(s) => throw new MappingException("Can't convert " + s + " to ApiPath")
+ }, {
+ case ApiPath(path) => JString(c.baseUrl + path)
+ })
+ )
- def sshPathSerializer(c: Context) = new CustomSerializer[SshPath](_ => ({
- case JString(s) if c.sshUrl.exists(sshUrl => s.startsWith(sshUrl)) => SshPath(s.substring(c.sshUrl.get.length))
- case JString(s) => throw new MappingException("Can't convert " + s + " to ApiPath")
- }, {
- case SshPath(path) => c.sshUrl.map { sshUrl => JString(sshUrl + path) } getOrElse JNothing
- }))
+ def sshPathSerializer(c: Context) =
+ new CustomSerializer[SshPath](
+ _ =>
+ ({
+ case JString(s) if c.sshUrl.exists(sshUrl => s.startsWith(sshUrl)) =>
+ SshPath(s.substring(c.sshUrl.get.length))
+ case JString(s) => throw new MappingException("Can't convert " + s + " to ApiPath")
+ }, {
+ case SshPath(path) =>
+ c.sshUrl.map { sshUrl =>
+ JString(sshUrl + path)
+ } getOrElse JNothing
+ })
+ )
/**
* convert object to json string
diff --git a/src/main/scala/gitbucket/core/controller/AccountController.scala b/src/main/scala/gitbucket/core/controller/AccountController.scala
index 1b4508c..93d3a99 100644
--- a/src/main/scala/gitbucket/core/controller/AccountController.scala
+++ b/src/main/scala/gitbucket/core/controller/AccountController.scala
@@ -16,77 +16,133 @@
import org.scalatra.BadRequest
import org.scalatra.forms._
-class AccountController extends AccountControllerBase
- with AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
- with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
- with AccessTokenService with WebHookService with PrioritiesService with RepositoryCreationService
-
+class AccountController
+ extends AccountControllerBase
+ with AccountService
+ with RepositoryService
+ with ActivityService
+ with WikiService
+ with LabelsService
+ with SshKeyService
+ with OneselfAuthenticator
+ with UsersAuthenticator
+ with GroupManagerAuthenticator
+ with ReadableUsersAuthenticator
+ with AccessTokenService
+ with WebHookService
+ with PrioritiesService
+ with RepositoryCreationService
trait AccountControllerBase extends AccountManagementControllerBase {
- self: AccountService with RepositoryService with ActivityService with WikiService with LabelsService with SshKeyService
- with OneselfAuthenticator with UsersAuthenticator with GroupManagerAuthenticator with ReadableUsersAuthenticator
- with AccessTokenService with WebHookService with PrioritiesService with RepositoryCreationService =>
+ self: AccountService
+ with RepositoryService
+ with ActivityService
+ with WikiService
+ with LabelsService
+ with SshKeyService
+ with OneselfAuthenticator
+ with UsersAuthenticator
+ with GroupManagerAuthenticator
+ with ReadableUsersAuthenticator
+ with AccessTokenService
+ with WebHookService
+ with PrioritiesService
+ with RepositoryCreationService =>
- case class AccountNewForm(userName: String, password: String, fullName: String, mailAddress: String,
- description: Option[String], url: Option[String], fileId: Option[String])
+ case class AccountNewForm(
+ userName: String,
+ password: String,
+ fullName: String,
+ mailAddress: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String]
+ )
- case class AccountEditForm(password: Option[String], fullName: String, mailAddress: String,
- description: Option[String], url: Option[String], fileId: Option[String], clearImage: Boolean)
+ case class AccountEditForm(
+ password: Option[String],
+ fullName: String,
+ mailAddress: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ clearImage: Boolean
+ )
case class SshKeyForm(title: String, publicKey: String)
case class PersonalTokenForm(note: String)
val newForm = mapping(
- "userName" -> trim(label("User name" , text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
- "password" -> trim(label("Password" , text(required, maxlength(20), password))),
- "fullName" -> trim(label("Full Name" , text(required, maxlength(100)))),
- "mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress()))),
- "description" -> trim(label("bio" , optional(text()))),
- "url" -> trim(label("URL" , optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" , optional(text())))
+ "userName" -> trim(label("User name", text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
+ "password" -> trim(label("Password", text(required, maxlength(20), password))),
+ "fullName" -> trim(label("Full Name", text(required, maxlength(100)))),
+ "mailAddress" -> trim(label("Mail Address", text(required, maxlength(100), uniqueMailAddress()))),
+ "description" -> trim(label("bio", optional(text()))),
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text())))
)(AccountNewForm.apply)
val editForm = mapping(
- "password" -> trim(label("Password" , optional(text(maxlength(20), password)))),
- "fullName" -> trim(label("Full Name" , text(required, maxlength(100)))),
- "mailAddress" -> trim(label("Mail Address" , text(required, maxlength(100), uniqueMailAddress("userName")))),
- "description" -> trim(label("bio" , optional(text()))),
- "url" -> trim(label("URL" , optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" , optional(text()))),
- "clearImage" -> trim(label("Clear image" , boolean()))
+ "password" -> trim(label("Password", optional(text(maxlength(20), password)))),
+ "fullName" -> trim(label("Full Name", text(required, maxlength(100)))),
+ "mailAddress" -> trim(label("Mail Address", text(required, maxlength(100), uniqueMailAddress("userName")))),
+ "description" -> trim(label("bio", optional(text()))),
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "clearImage" -> trim(label("Clear image", boolean()))
)(AccountEditForm.apply)
val sshKeyForm = mapping(
- "title" -> trim(label("Title", text(required, maxlength(100)))),
- "publicKey" -> trim2(label("Key" , text(required, validPublicKey)))
+ "title" -> trim(label("Title", text(required, maxlength(100)))),
+ "publicKey" -> trim2(label("Key", text(required, validPublicKey)))
)(SshKeyForm.apply)
val personalTokenForm = mapping(
"note" -> trim(label("Token", text(required, maxlength(100))))
)(PersonalTokenForm.apply)
- case class NewGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String], members: String)
- case class EditGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String], members: String, clearImage: Boolean)
+ case class NewGroupForm(
+ groupName: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ members: String
+ )
+ case class EditGroupForm(
+ groupName: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ members: String,
+ clearImage: Boolean
+ )
val newGroupForm = mapping(
- "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
+ "groupName" -> trim(label("Group name", text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
"description" -> trim(label("Group description", optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text()))),
- "members" -> trim(label("Members" ,text(required, members)))
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "members" -> trim(label("Members", text(required, members)))
)(NewGroupForm.apply)
val editGroupForm = mapping(
- "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier))),
+ "groupName" -> trim(label("Group name", text(required, maxlength(100), identifier))),
"description" -> trim(label("Group description", optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text()))),
- "members" -> trim(label("Members" ,text(required, members))),
- "clearImage" -> trim(label("Clear image" ,boolean()))
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "members" -> trim(label("Members", text(required, members))),
+ "clearImage" -> trim(label("Clear image", boolean()))
)(EditGroupForm.apply)
- case class RepositoryCreationForm(owner: String, name: String, description: Option[String], isPrivate: Boolean, initOption: String, sourceUrl: Option[String])
+ case class RepositoryCreationForm(
+ owner: String,
+ name: String,
+ description: Option[String],
+ isPrivate: Boolean,
+ initOption: String,
+ sourceUrl: Option[String]
+ )
case class ForkRepositoryForm(owner: String, name: String)
val newRepositoryForm = mapping(
@@ -100,7 +156,7 @@
val forkRepositoryForm = mapping(
"owner" -> trim(label("Repository owner", text(required))),
- "name" -> trim(label("Repository name", text(required)))
+ "name" -> trim(label("Repository name", text(required)))
)(ForkRepositoryForm.apply)
case class AccountForm(accountName: String)
@@ -110,23 +166,30 @@
)(AccountForm.apply)
// for account web hook url addition.
- case class AccountWebHookForm(url: String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])
-
- def accountWebHookForm(update:Boolean) = mapping(
- "url" -> trim(label("url", text(required, accountWebHook(update)))),
- "events" -> accountWebhookEvents,
- "ctype" -> label("ctype", text()),
- "token" -> optional(trim(label("token", text(maxlength(100)))))
- )(
- (url, events, ctype, token) => AccountWebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
+ case class AccountWebHookForm(
+ url: String,
+ events: Set[WebHook.Event],
+ ctype: WebHookContentType,
+ token: Option[String]
)
+
+ def accountWebHookForm(update: Boolean) =
+ mapping(
+ "url" -> trim(label("url", text(required, accountWebHook(update)))),
+ "events" -> accountWebhookEvents,
+ "ctype" -> label("ctype", text()),
+ "token" -> optional(trim(label("token", text(maxlength(100)))))
+ )(
+ (url, events, ctype, token) => AccountWebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
+ )
+
/**
- * Provides duplication check for web hook url. duplicated from RepositorySettingsController.scala
- */
- private def accountWebHook(needExists: Boolean): Constraint = new Constraint(){
+ * Provides duplication check for web hook url. duplicated from RepositorySettingsController.scala
+ */
+ private def accountWebHook(needExists: Boolean): Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(getAccountWebHook(params("userName"), value).isDefined != needExists){
- Some(if(needExists){
+ if (getAccountWebHook(params("userName"), value).isDefined != needExists) {
+ Some(if (needExists) {
"URL had not been registered yet."
} else {
"URL had been registered already."
@@ -136,21 +199,20 @@
}
}
- private def accountWebhookEvents = new ValueType[Set[WebHook.Event]]{
+ private def accountWebhookEvents = new ValueType[Set[WebHook.Event]] {
def convert(name: String, params: Map[String, Seq[String]], messages: Messages): Set[WebHook.Event] = {
WebHook.Event.values.flatMap { t =>
params.optionValue(name + "." + t.name).map(_ => t)
}.toSet
}
def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] =
- if(convert(name, params, messages).isEmpty){
+ if (convert(name, params, messages).isEmpty) {
Seq(name -> messages("error.required").format(name))
} else {
Nil
}
}
-
/**
* Displays user information.
*/
@@ -160,24 +222,41 @@
params.getOrElse("tab", "repositories") match {
// Public Activity
case "activity" =>
- gitbucket.core.account.html.activity(account,
- if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
- getActivitiesByUser(userName, true))
+ gitbucket.core.account.html.activity(
+ account,
+ if (account.isGroupAccount) Nil else getGroupsByUserName(userName),
+ getActivitiesByUser(userName, true)
+ )
// Members
- case "members" if(account.isGroupAccount) => {
+ case "members" if (account.isGroupAccount) => {
val members = getGroupMembers(account.userName)
- gitbucket.core.account.html.members(account, members,
- context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
+ gitbucket.core.account.html.members(
+ account,
+ members,
+ context.loginAccount.exists(
+ x =>
+ members.exists { member =>
+ member.userName == x.userName && member.isManager
+ }
+ )
+ )
}
// Repositories
case _ => {
val members = getGroupMembers(account.userName)
- gitbucket.core.account.html.repositories(account,
- if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
+ gitbucket.core.account.html.repositories(
+ account,
+ if (account.isGroupAccount) Nil else getGroupsByUserName(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
+ }
+ )
+ )
}
}
} getOrElse NotFound()
@@ -189,24 +268,28 @@
helper.xml.feed(getActivitiesByUser(userName, true))
}
- get("/:userName/_avatar"){
+ get("/:userName/_avatar") {
val userName = params("userName")
contentType = "image/png"
- getAccountByUserName(userName).flatMap{ account =>
- response.setDateHeader("Last-Modified", account.updatedDate.getTime)
- account.image.map{ image =>
- Some(RawData(FileUtil.getMimeType(image), new java.io.File(getUserUploadDir(userName), image)))
- }.getOrElse{
- if (account.isGroupAccount) {
- TextAvatarUtil.textGroupAvatar(account.fullName)
- } else {
- TextAvatarUtil.textAvatar(account.fullName)
- }
+ getAccountByUserName(userName)
+ .flatMap { account =>
+ response.setDateHeader("Last-Modified", account.updatedDate.getTime)
+ account.image
+ .map { image =>
+ Some(RawData(FileUtil.getMimeType(image), new java.io.File(getUserUploadDir(userName), image)))
+ }
+ .getOrElse {
+ if (account.isGroupAccount) {
+ TextAvatarUtil.textGroupAvatar(account.fullName)
+ } else {
+ TextAvatarUtil.textAvatar(account.fullName)
+ }
+ }
}
- }.getOrElse{
- response.setHeader("Cache-Control", "max-age=3600")
- Thread.currentThread.getContextClassLoader.getResourceAsStream("noimage.png")
- }
+ .getOrElse {
+ response.setHeader("Cache-Control", "max-age=3600")
+ Thread.currentThread.getContextClassLoader.getResourceAsStream("noimage.png")
+ }
}
get("/:userName/_edit")(oneselfOnly {
@@ -219,12 +302,15 @@
post("/:userName/_edit", editForm)(oneselfOnly { form =>
val userName = params("userName")
getAccountByUserName(userName).map { account =>
- updateAccount(account.copy(
- password = form.password.map(sha1).getOrElse(account.password),
- fullName = form.fullName,
- mailAddress = form.mailAddress,
- description = form.description,
- url = form.url))
+ updateAccount(
+ account.copy(
+ password = form.password.map(sha1).getOrElse(account.password),
+ fullName = form.fullName,
+ mailAddress = form.mailAddress,
+ description = form.description,
+ url = form.url
+ )
+ )
updateImage(userName, form.fileId, form.clearImage)
flash += "info" -> "Account information has been updated."
@@ -236,11 +322,12 @@
get("/:userName/_delete")(oneselfOnly {
val userName = params("userName")
- getAccountByUserName(userName, true).map { account =>
- if(isLastAdministrator(account)){
- flash += "error" -> "Account can't be removed because this is last one administrator."
- redirect(s"/${userName}/_edit")
- } else {
+ getAccountByUserName(userName, true).map {
+ account =>
+ if (isLastAdministrator(account)) {
+ flash += "error" -> "Account can't be removed because this is last one administrator."
+ redirect(s"/${userName}/_edit")
+ } else {
// // Remove repositories
// getRepositoryNamesOfUser(userName).foreach { repositoryName =>
// deleteRepository(userName, repositoryName)
@@ -248,16 +335,16 @@
// FileUtils.deleteDirectory(getWikiRepositoryDir(userName, repositoryName))
// FileUtils.deleteDirectory(getTemporaryDir(userName, repositoryName))
// }
- // Remove from GROUP_MEMBER and COLLABORATOR
- removeUserRelatedData(userName)
- updateAccount(account.copy(isRemoved = true))
+ // Remove from GROUP_MEMBER and COLLABORATOR
+ removeUserRelatedData(userName)
+ updateAccount(account.copy(isRemoved = true))
- // call hooks
- PluginRegistry().getAccountHooks.foreach(_.deleted(userName))
+ // call hooks
+ PluginRegistry().getAccountHooks.foreach(_.deleted(userName))
- session.invalidate
- redirect("/")
- }
+ session.invalidate
+ redirect("/")
+ }
} getOrElse NotFound()
})
@@ -286,9 +373,9 @@
getAccountByUserName(userName).map { x =>
var tokens = getAccessTokens(x.userName)
val generatedToken = flash.get("generatedToken") match {
- case Some((tokenId:Int, token:String)) => {
+ case Some((tokenId: Int, token: String)) => {
val gt = tokens.find(_.accessTokenId == tokenId)
- gt.map{ t =>
+ gt.map { t =>
tokens = tokens.filterNot(_ == t)
(t, token)
}
@@ -359,8 +446,9 @@
get("/:userName/_hooks/edit")(oneselfOnly {
val userName = params("userName")
getAccountByUserName(userName).flatMap { account =>
- getAccountWebHook(userName, params("url")).map { case (webhook, events) =>
- html.edithook(webhook, events, account, false)
+ getAccountWebHook(userName, params("url")).map {
+ case (webhook, events) =>
+ html.edithook(webhook, events, account, false)
}
} getOrElse NotFound()
})
@@ -386,7 +474,9 @@
import org.apache.http.util.EntityUtils
import scala.concurrent.ExecutionContext.Implicits.global
- def _headers(h: Array[org.apache.http.Header]): Array[Array[String]] = h.map { h => Array(h.getName, h.getValue) }
+ def _headers(h: Array[org.apache.http.Header]): Array[Array[String]] = h.map { h =>
+ Array(h.getName, h.getValue)
+ }
val userName = params("userName")
val url = params("url")
@@ -400,31 +490,49 @@
val (webHook, json, reqFuture, resFuture) = callWebHook(WebHook.Push, List(dummyWebHookInfo), dummyPayload).head
- val toErrorMap: PartialFunction[Throwable, Map[String,String]] = {
- case e: java.net.UnknownHostException => Map("error"-> ("Unknown host " + e.getMessage))
- case e: java.lang.IllegalArgumentException => Map("error"-> ("invalid url"))
- case e: org.apache.http.client.ClientProtocolException => Map("error"-> ("invalid url"))
- case NonFatal(e) => Map("error"-> (e.getClass + " "+ e.getMessage))
+ val toErrorMap: PartialFunction[Throwable, Map[String, String]] = {
+ case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
+ case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
+ case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
+ case NonFatal(e) => Map("error" -> (e.getClass + " " + e.getMessage))
}
contentType = formats("json")
- org.json4s.jackson.Serialization.write(Map(
- "url" -> url,
- "request" -> Await.result(reqFuture.map(req => Map(
- "headers" -> _headers(req.getAllHeaders),
- "payload" -> json
- )).recover(toErrorMap), 20 seconds),
- "response" -> Await.result(resFuture.map(res => Map(
- "status" -> res.getStatusLine(),
- "body" -> EntityUtils.toString(res.getEntity()),
- "headers" -> _headers(res.getAllHeaders())
- )).recover(toErrorMap), 20 seconds)
- ))
+ org.json4s.jackson.Serialization.write(
+ Map(
+ "url" -> url,
+ "request" -> Await.result(
+ reqFuture
+ .map(
+ req =>
+ Map(
+ "headers" -> _headers(req.getAllHeaders),
+ "payload" -> json
+ )
+ )
+ .recover(toErrorMap),
+ 20 seconds
+ ),
+ "response" -> Await.result(
+ resFuture
+ .map(
+ res =>
+ Map(
+ "status" -> res.getStatusLine(),
+ "body" -> EntityUtils.toString(res.getEntity()),
+ "headers" -> _headers(res.getAllHeaders())
+ )
+ )
+ .recover(toErrorMap),
+ 20 seconds
+ )
+ )
+ )
})
- get("/register"){
- if(context.settings.allowAccountRegistration){
- if(context.loginAccount.isDefined){
+ get("/register") {
+ if (context.settings.allowAccountRegistration) {
+ if (context.loginAccount.isDefined) {
redirect("/")
} else {
html.register()
@@ -432,9 +540,17 @@
} else NotFound()
}
- post("/register", newForm){ form =>
- if(context.settings.allowAccountRegistration){
- createAccount(form.userName, sha1(form.password), form.fullName, form.mailAddress, false, form.description, form.url)
+ post("/register", newForm) { form =>
+ if (context.settings.allowAccountRegistration) {
+ createAccount(
+ form.userName,
+ sha1(form.password),
+ form.fullName,
+ form.mailAddress,
+ false,
+ form.description,
+ form.url
+ )
updateImage(form.userName, form.fileId, false)
redirect("/signin")
} else NotFound()
@@ -446,17 +562,23 @@
post("/groups/new", newGroupForm)(usersOnly { form =>
createGroup(form.groupName, form.description, form.url)
- updateGroupMembers(form.groupName, form.members.split(",").map {
- _.split(":") match {
- case Array(userName, isManager) => (userName, isManager.toBoolean)
- }
- }.toList)
+ updateGroupMembers(
+ form.groupName,
+ form.members
+ .split(",")
+ .map {
+ _.split(":") match {
+ case Array(userName, isManager) => (userName, isManager.toBoolean)
+ }
+ }
+ .toList
+ )
updateImage(form.groupName, form.fileId, false)
redirect(s"/${form.groupName}")
})
get("/:groupName/_editgroup")(managersOnly {
- defining(params("groupName")){ groupName =>
+ defining(params("groupName")) { groupName =>
getAccountByUserName(groupName, true).map { account =>
html.editgroup(account, getGroupMembers(groupName), flash.get("info"))
} getOrElse NotFound()
@@ -464,13 +586,14 @@
})
get("/:groupName/_deletegroup")(managersOnly {
- defining(params("groupName")){ groupName =>
- // Remove from GROUP_MEMBER
- updateGroupMembers(groupName, Nil)
- // Disable group
- getAccountByUserName(groupName, false).foreach { account =>
- updateGroup(groupName, account.description, account.url, true)
- }
+ defining(params("groupName")) {
+ groupName =>
+ // Remove from GROUP_MEMBER
+ updateGroupMembers(groupName, Nil)
+ // Disable group
+ getAccountByUserName(groupName, false).foreach { account =>
+ updateGroup(groupName, account.description, account.url, true)
+ }
// // Remove repositories
// getRepositoryNamesOfUser(groupName).foreach { repositoryName =>
// deleteRepository(groupName, repositoryName)
@@ -483,16 +606,23 @@
})
post("/:groupName/_editgroup", editGroupForm)(managersOnly { form =>
- defining(params("groupName"), form.members.split(",").map {
- _.split(":") match {
- case Array(userName, isManager) => (userName, isManager.toBoolean)
- }
- }.toList){ case (groupName, members) =>
- getAccountByUserName(groupName, true).map { account =>
- updateGroup(groupName, form.description, form.url, false)
+ defining(
+ params("groupName"),
+ form.members
+ .split(",")
+ .map {
+ _.split(":") match {
+ case Array(userName, isManager) => (userName, isManager.toBoolean)
+ }
+ }
+ .toList
+ ) {
+ case (groupName, members) =>
+ getAccountByUserName(groupName, true).map { account =>
+ updateGroup(groupName, form.description, form.url, false)
- // Update GROUP_MEMBER
- updateGroupMembers(form.groupName, members)
+ // Update GROUP_MEMBER
+ updateGroupMembers(form.groupName, members)
// // Update COLLABORATOR for group repositories
// getRepositoryNamesOfUser(form.groupName).foreach { repositoryName =>
// removeCollaborators(form.groupName, repositoryName)
@@ -501,12 +631,12 @@
// }
// }
- updateImage(form.groupName, form.fileId, form.clearImage)
+ updateImage(form.groupName, form.fileId, form.clearImage)
- flash += "info" -> "Account information has been updated."
- redirect(s"/${groupName}/_editgroup")
+ flash += "info" -> "Account information has been updated."
+ redirect(s"/${groupName}/_editgroup")
- } getOrElse NotFound()
+ } getOrElse NotFound()
}
})
@@ -521,9 +651,17 @@
* Create new repository.
*/
post("/new", newRepositoryForm)(usersOnly { form =>
- LockUtil.lock(s"${form.owner}/${form.name}"){
- if(getRepository(form.owner, form.name).isEmpty){
- createRepository(context.loginAccount.get, form.owner, form.name, form.description, form.isPrivate, form.initOption, form.sourceUrl)
+ LockUtil.lock(s"${form.owner}/${form.name}") {
+ if (getRepository(form.owner, form.name).isEmpty) {
+ createRepository(
+ context.loginAccount.get,
+ form.owner,
+ form.name,
+ form.description,
+ form.isPrivate,
+ form.initOption,
+ form.sourceUrl
+ )
}
}
@@ -532,15 +670,20 @@
})
get("/:owner/:repository/fork")(readableUsersOnly { repository =>
- if(repository.repository.options.allowFork){
- val loginAccount = context.loginAccount.get
- val loginUserName = loginAccount.userName
- val groups = getGroupsByUserName(loginUserName)
+ if (repository.repository.options.allowFork) {
+ val loginAccount = context.loginAccount.get
+ val loginUserName = loginAccount.userName
+ val groups = getGroupsByUserName(loginUserName)
groups match {
case _: List[String] =>
val managerPermissions = groups.map { group =>
val members = getGroupMembers(group)
- 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
+ }
+ )
}
helper.html.forkrepository(
repository,
@@ -552,13 +695,13 @@
})
post("/:owner/:repository/fork", accountForm)(readableUsersOnly { (form, repository) =>
- if(repository.repository.options.allowFork){
- val loginAccount = context.loginAccount.get
+ if (repository.repository.options.allowFork) {
+ val loginAccount = context.loginAccount.get
val loginUserName = loginAccount.userName
- val accountName = form.accountName
+ val accountName = form.accountName
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(s"/${accountName}/${repository.name}")
} else {
@@ -570,42 +713,49 @@
} else BadRequest()
})
- private def existsAccount: Constraint = new Constraint(){
+ private def existsAccount: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(getAccountByUserName(value).isEmpty) Some("User or group does not exist.") else None
+ if (getAccountByUserName(value).isEmpty) Some("User or group does not exist.") else None
}
- private def uniqueRepository: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] = {
+ private def uniqueRepository: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] = {
for {
userName <- params.optionValue("owner")
- _ <- getRepositoryNamesOfUser(userName).find(_ == value)
+ _ <- getRepositoryNamesOfUser(userName).find(_ == value)
} yield {
"Repository already exists."
}
}
}
- private def members: Constraint = new Constraint(){
+ private def members: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
- if(value.split(",").exists {
- _.split(":") match { case Array(userName, isManager) => isManager.toBoolean }
- }) None else Some("Must select one manager at least.")
+ if (value.split(",").exists {
+ _.split(":") match { case Array(userName, isManager) => isManager.toBoolean }
+ }) None
+ else Some("Must select one manager at least.")
}
}
- private def validPublicKey: Constraint = new Constraint(){
- override def validate(name: String, value: String, messages: Messages): Option[String] = SshUtil.str2PublicKey(value) match {
- case Some(_) if !getAllKeys().exists(_.publicKey == value) => None
- case _ => Some("Key is invalid.")
- }
+ private def validPublicKey: Constraint = new Constraint() {
+ override def validate(name: String, value: String, messages: Messages): Option[String] =
+ SshUtil.str2PublicKey(value) match {
+ case Some(_) if !getAllKeys().exists(_.publicKey == value) => None
+ case _ => Some("Key is invalid.")
+ }
}
- private def validAccountName: Constraint = new Constraint(){
+ private def validAccountName: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
getAccountByUserName(value) match {
case Some(_) => None
- case None => Some("Invalid Group/User Account.")
+ case None => Some("Invalid Group/User Account.")
}
}
}
diff --git a/src/main/scala/gitbucket/core/controller/ApiController.scala b/src/main/scala/gitbucket/core/controller/ApiController.scala
index 2044558..1cf042d 100644
--- a/src/main/scala/gitbucket/core/controller/ApiController.scala
+++ b/src/main/scala/gitbucket/core/controller/ApiController.scala
@@ -20,31 +20,32 @@
import scala.concurrent.Await
import scala.concurrent.duration.Duration
-class ApiController extends ApiControllerBase
- with RepositoryService
- with AccountService
- with ProtectedBranchService
- with IssuesService
- with LabelsService
- with MilestonesService
- with PullRequestService
- with CommitsService
- with CommitStatusService
- with RepositoryCreationService
- with IssueCreationService
- with HandleCommentService
- with WebHookService
- with WebHookPullRequestService
- with WebHookIssueCommentService
- with WikiService
- with ActivityService
- with PrioritiesService
- with OwnerAuthenticator
- with UsersAuthenticator
- with GroupManagerAuthenticator
- with ReferrerAuthenticator
- with ReadableUsersAuthenticator
- with WritableUsersAuthenticator
+class ApiController
+ extends ApiControllerBase
+ with RepositoryService
+ with AccountService
+ with ProtectedBranchService
+ with IssuesService
+ with LabelsService
+ with MilestonesService
+ with PullRequestService
+ with CommitsService
+ with CommitStatusService
+ with RepositoryCreationService
+ with IssueCreationService
+ with HandleCommentService
+ with WebHookService
+ with WebHookPullRequestService
+ with WebHookIssueCommentService
+ with WikiService
+ with ActivityService
+ with PrioritiesService
+ with OwnerAuthenticator
+ with UsersAuthenticator
+ with GroupManagerAuthenticator
+ with ReferrerAuthenticator
+ with ReadableUsersAuthenticator
+ with WritableUsersAuthenticator
trait ApiControllerBase extends ControllerBase {
self: RepositoryService
@@ -68,22 +69,22 @@
with WritableUsersAuthenticator =>
/**
- * 404 for non-implemented api
- */
+ * 404 for non-implemented api
+ */
get("/api/v3/*") {
NotFound()
}
/**
- * https://developer.github.com/v3/#root-endpoint
- */
+ * https://developer.github.com/v3/#root-endpoint
+ */
get("/api/v3") {
JsonFormat(ApiEndPoint())
}
/**
- * https://developer.github.com/v3/orgs/#get-an-organization
- */
+ * https://developer.github.com/v3/orgs/#get-an-organization
+ */
get("/api/v3/orgs/:groupName") {
getAccountByUserName(params("groupName")).filter(account => account.isGroupAccount).map { account =>
JsonFormat(ApiUser(account))
@@ -101,43 +102,59 @@
}
/**
- * https://developer.github.com/v3/repos/#list-organization-repositories
- */
+ * https://developer.github.com/v3/repos/#list-organization-repositories
+ */
get("/api/v3/orgs/:orgName/repos") {
- JsonFormat(getVisibleRepositories(context.loginAccount, Some(params("orgName"))).map{ r => ApiRepository(r, getAccountByUserName(r.owner).get)})
+ JsonFormat(getVisibleRepositories(context.loginAccount, Some(params("orgName"))).map { r =>
+ ApiRepository(r, getAccountByUserName(r.owner).get)
+ })
}
+
/**
* https://developer.github.com/v3/repos/#list-user-repositories
*/
get("/api/v3/users/:userName/repos") {
- JsonFormat(getVisibleRepositories(context.loginAccount, Some(params("userName"))).map{ r => ApiRepository(r, getAccountByUserName(r.owner).get)})
+ JsonFormat(getVisibleRepositories(context.loginAccount, Some(params("userName"))).map { r =>
+ ApiRepository(r, getAccountByUserName(r.owner).get)
+ })
}
/*
* https://developer.github.com/v3/repos/branches/#list-branches
*/
- get ("/api/v3/repos/:owner/:repo/branches")(referrersOnly { repository =>
- JsonFormat(JGitUtil.getBranches(
- owner = repository.owner,
- name = repository.name,
- defaultBranch = repository.repository.defaultBranch,
- origin = repository.repository.originUserName.isEmpty
- ).map { br =>
- ApiBranchForList(br.name, ApiBranchCommit(br.commitId))
- })
+ get("/api/v3/repos/:owner/:repo/branches")(referrersOnly { repository =>
+ JsonFormat(
+ JGitUtil
+ .getBranches(
+ owner = repository.owner,
+ name = repository.name,
+ defaultBranch = repository.repository.defaultBranch,
+ origin = repository.repository.originUserName.isEmpty
+ )
+ .map { br =>
+ ApiBranchForList(br.name, ApiBranchCommit(br.commitId))
+ }
+ )
})
/**
- * https://developer.github.com/v3/repos/branches/#get-branch
- */
- get ("/api/v3/repos/:owner/:repo/branches/*")(referrersOnly { repository =>
+ * https://developer.github.com/v3/repos/branches/#get-branch
+ */
+ get("/api/v3/repos/:owner/:repo/branches/*")(referrersOnly { repository =>
//import gitbucket.core.api._
- (for{
+ (for {
branch <- params.get("splat") if repository.branchList.contains(branch)
- br <- getBranches(repository.owner, repository.name, repository.repository.defaultBranch, repository.repository.originUserName.isEmpty).find(_.name == branch)
+ br <- getBranches(
+ repository.owner,
+ repository.name,
+ repository.repository.defaultBranch,
+ repository.repository.originUserName.isEmpty
+ ).find(_.name == branch)
} yield {
val protection = getProtectedBranchInfo(repository.owner, repository.name, branch)
- JsonFormat(ApiBranch(branch, ApiBranchCommit(br.commitId), ApiBranchProtection(protection))(RepositoryName(repository)))
+ JsonFormat(
+ ApiBranch(branch, ApiBranchCommit(br.commitId), ApiBranchProtection(protection))(RepositoryName(repository))
+ )
}) getOrElse NotFound()
})
@@ -157,65 +174,85 @@
val path = multiParams("splat").head match {
case s if s.isEmpty => "."
- case s => s
+ case s => s
}
val refStr = params.getOrElse("ref", repository.repository.defaultBranch)
- using(Git.open(getRepositoryDir(params("owner"), params("repo")))){ git =>
- val fileList = getFileList(git, refStr, path)
- if (fileList.isEmpty) { // file or NotFound
- getFileInfo(git, refStr, path).flatMap(f => {
- val largeFile = params.get("large_file").exists(s => s.equals("true"))
- val content = getContentFromId(git, f.id, largeFile)
- request.getHeader("Accept") match {
- case "application/vnd.github.v3.raw" => {
- contentType = "application/vnd.github.v3.raw"
- content
- }
- case "application/vnd.github.v3.html" if isRenderable(f.name) => {
- contentType = "application/vnd.github.v3.html"
- content.map(c =>
- List(
- "
", "
",
- renderMarkup(path.split("/").toList, new String(c), refStr, repository, false, false, true).body,
- "", "
"
- ).mkString
- )
- }
- case "application/vnd.github.v3.html" => {
- contentType = "application/vnd.github.v3.html"
- content.map(c =>
- List(
- "", "
", "
",
- play.twirl.api.HtmlFormat.escape(new String(c)).body,
- "
", "
", "
"
- ).mkString
- )
- }
- case _ =>
- Some(JsonFormat(ApiContents(f, RepositoryName(repository), content)))
- }
- }).getOrElse(NotFound())
- } else { // directory
- JsonFormat(fileList.map{f => ApiContents(f, RepositoryName(repository), None)})
- }
+ using(Git.open(getRepositoryDir(params("owner"), params("repo")))) {
+ git =>
+ val fileList = getFileList(git, refStr, path)
+ if (fileList.isEmpty) { // file or NotFound
+ getFileInfo(git, refStr, path)
+ .flatMap(f => {
+ val largeFile = params.get("large_file").exists(s => s.equals("true"))
+ val content = getContentFromId(git, f.id, largeFile)
+ request.getHeader("Accept") match {
+ case "application/vnd.github.v3.raw" => {
+ contentType = "application/vnd.github.v3.raw"
+ content
+ }
+ case "application/vnd.github.v3.html" if isRenderable(f.name) => {
+ contentType = "application/vnd.github.v3.html"
+ content.map(
+ c =>
+ List(
+ "",
+ "
",
+ renderMarkup(path.split("/").toList, new String(c), refStr, repository, false, false, true).body,
+ "",
+ "
"
+ ).mkString
+ )
+ }
+ case "application/vnd.github.v3.html" => {
+ contentType = "application/vnd.github.v3.html"
+ content.map(
+ c =>
+ List(
+ "",
+ "
",
+ "
",
+ play.twirl.api.HtmlFormat.escape(new String(c)).body,
+ "
",
+ "
",
+ "
"
+ ).mkString
+ )
+ }
+ case _ =>
+ Some(JsonFormat(ApiContents(f, RepositoryName(repository), content)))
+ }
+ })
+ .getOrElse(NotFound())
+ } else { // directory
+ JsonFormat(fileList.map { f =>
+ ApiContents(f, RepositoryName(repository), None)
+ })
+ }
}
})
/*
* https://developer.github.com/v3/git/refs/#get-a-reference
*/
- get("/api/v3/repos/:owner/:repo/git/refs/*") (referrersOnly { repository =>
+ get("/api/v3/repos/:owner/:repo/git/refs/*")(referrersOnly { repository =>
val revstr = multiParams("splat").head
using(Git.open(getRepositoryDir(params("owner"), params("repo")))) { git =>
val ref = git.getRepository().findRef(revstr)
- if(ref != null){
+ if (ref != null) {
val sha = ref.getObjectId().name()
JsonFormat(ApiRef(revstr, ApiObject(sha)))
} else {
- val refs = git.getRepository().getAllRefs().asScala
+ val refs = git
+ .getRepository()
+ .getAllRefs()
+ .asScala
.collect { case (str, ref) if str.startsWith("refs/" + revstr) => ref }
JsonFormat(refs.map { ref =>
@@ -229,7 +266,7 @@
/**
* https://developer.github.com/v3/repos/collaborators/#list-collaborators
*/
- get("/api/v3/repos/:owner/:repo/collaborators") (referrersOnly { repository =>
+ get("/api/v3/repos/:owner/:repo/collaborators")(referrersOnly { repository =>
// TODO Should ApiUser take permission? getCollaboratorUserNames does not return owner group members.
JsonFormat(getCollaboratorUserNames(params("owner"), params("repo")).map(u => ApiUser(getAccountByUserName(u).get)))
})
@@ -247,9 +284,9 @@
* List user's own repository
* https://developer.github.com/v3/repos/#list-your-repositories
*/
- get("/api/v3/user/repos")(usersOnly{
- JsonFormat(getVisibleRepositories(context.loginAccount, Option(context.loginAccount.get.userName)).map{
- r => ApiRepository(r, getAccountByUserName(r.owner).get)
+ get("/api/v3/user/repos")(usersOnly {
+ JsonFormat(getVisibleRepositories(context.loginAccount, Option(context.loginAccount.get.userName)).map { r =>
+ ApiRepository(r, getAccountByUserName(r.owner).get)
})
})
@@ -263,8 +300,15 @@
data <- extractFromJsonBody[CreateARepository] if data.isValid
} yield {
LockUtil.lock(s"${owner}/${data.name}") {
- if(getRepository(owner, data.name).isEmpty){
- val f = createRepository(context.loginAccount.get, owner, data.name, data.description, data.`private`, data.auto_init)
+ if (getRepository(owner, data.name).isEmpty) {
+ val f = createRepository(
+ context.loginAccount.get,
+ owner,
+ data.name,
+ data.description,
+ data.`private`,
+ data.auto_init
+ )
Await.result(f, Duration.Inf)
val repository = getRepository(owner, data.name).get
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(owner).get)))
@@ -288,8 +332,15 @@
data <- extractFromJsonBody[CreateARepository] if data.isValid
} yield {
LockUtil.lock(s"${groupName}/${data.name}") {
- if(getRepository(groupName, data.name).isEmpty){
- val f = createRepository(context.loginAccount.get, groupName, data.name, data.description, data.`private`, data.auto_init)
+ if (getRepository(groupName, data.name).isEmpty) {
+ val f = createRepository(
+ context.loginAccount.get,
+ groupName,
+ data.name,
+ data.description,
+ data.`private`,
+ data.auto_init
+ )
Await.result(f, Duration.Inf)
val repository = getRepository(groupName, data.name).get
JsonFormat(ApiRepository(repository, ApiUser(getAccountByUserName(groupName).get)))
@@ -308,13 +359,24 @@
*/
patch("/api/v3/repos/:owner/:repo/branches/*")(ownerOnly { repository =>
import gitbucket.core.api._
- (for{
- branch <- params.get("splat") if repository.branchList.contains(branch)
+ (for {
+ branch <- params.get("splat") if repository.branchList.contains(branch)
protection <- extractFromJsonBody[ApiBranchProtection.EnablingAndDisabling].map(_.protection)
- br <- getBranches(repository.owner, repository.name, repository.repository.defaultBranch, repository.repository.originUserName.isEmpty).find(_.name == branch)
+ br <- getBranches(
+ repository.owner,
+ repository.name,
+ repository.repository.defaultBranch,
+ repository.repository.originUserName.isEmpty
+ ).find(_.name == branch)
} yield {
- if(protection.enabled){
- enableBranchProtection(repository.owner, repository.name, branch, protection.status.enforcement_level == ApiBranchProtection.Everyone, protection.status.contexts)
+ if (protection.enabled) {
+ enableBranchProtection(
+ repository.owner,
+ repository.name,
+ branch,
+ protection.status.enforcement_level == ApiBranchProtection.Everyone,
+ protection.status.contexts
+ )
} else {
disableBranchProtection(repository.owner, repository.name, branch)
}
@@ -326,15 +388,15 @@
* @see https://developer.github.com/v3/rate_limit/#get-your-current-rate-limit-status
* but not enabled.
*/
- get("/api/v3/rate_limit"){
+ get("/api/v3/rate_limit") {
contentType = formats("json")
// this message is same as github enterprise...
org.scalatra.NotFound(ApiError("Rate limiting is not enabled."))
}
/**
- * https://developer.github.com/v3/issues/#list-issues-for-a-repository
- */
+ * https://developer.github.com/v3/issues/#list-issues-for-a-repository
+ */
get("/api/v3/repos/:owner/:repository/issues")(referrersOnly { repository =>
val page = IssueSearchCondition.page(request)
// TODO: more api spec condition
@@ -344,18 +406,20 @@
val issues: List[(Issue, Account)] =
searchIssueByApi(
condition = condition,
- offset = (page - 1) * PullRequestLimit,
- limit = PullRequestLimit,
- repos = repository.owner -> repository.name
+ offset = (page - 1) * PullRequestLimit,
+ limit = PullRequestLimit,
+ repos = repository.owner -> repository.name
)
- JsonFormat(issues.map { case (issue, issueUser) =>
- ApiIssue(
- issue = issue,
- repositoryName = RepositoryName(repository),
- user = ApiUser(issueUser),
- labels = getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))
- )
+ JsonFormat(issues.map {
+ case (issue, issueUser) =>
+ ApiIssue(
+ issue = issue,
+ repositoryName = RepositoryName(repository),
+ user = ApiUser(issueUser),
+ labels = getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository)))
+ )
})
})
@@ -363,22 +427,28 @@
* https://developer.github.com/v3/issues/#get-a-single-issue
*/
get("/api/v3/repos/:owner/:repository/issues/:id")(referrersOnly { repository =>
- (for{
- issueId <- params("id").toIntOpt
+ (for {
+ issueId <- params("id").toIntOpt
issue <- getIssue(repository.owner, repository.name, issueId.toString)
openedUser <- getAccountByUserName(issue.openedUserName)
} yield {
- JsonFormat(ApiIssue(issue, RepositoryName(repository), ApiUser(openedUser),
- getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))))
+ JsonFormat(
+ ApiIssue(
+ issue,
+ RepositoryName(repository),
+ ApiUser(openedUser),
+ getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))
+ )
+ )
}) getOrElse NotFound()
})
/**
- * https://developer.github.com/v3/issues/#create-an-issue
- */
+ * https://developer.github.com/v3/issues/#create-an-issue
+ */
post("/api/v3/repos/:owner/:repository/issues")(readableUsersOnly { repository =>
- if(isIssueEditable(repository)){ // TODO Should this check is provided by authenticator?
- (for{
+ if (isIssueEditable(repository)) { // TODO Should this check is provided by authenticator?
+ (for {
data <- extractFromJsonBody[CreateAnIssue]
loginAccount <- context.loginAccount
} yield {
@@ -391,9 +461,17 @@
milestone.map(_.milestoneId),
None,
data.labels,
- loginAccount)
- JsonFormat(ApiIssue(issue, RepositoryName(repository), ApiUser(loginAccount),
- getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))))
+ loginAccount
+ )
+ JsonFormat(
+ ApiIssue(
+ issue,
+ RepositoryName(repository),
+ ApiUser(loginAccount),
+ getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository)))
+ )
+ )
}) getOrElse NotFound()
} else Unauthorized()
})
@@ -402,11 +480,14 @@
* https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
*/
get("/api/v3/repos/:owner/:repository/issues/:id/comments")(referrersOnly { repository =>
- (for{
- issueId <- params("id").toIntOpt
- comments = getCommentsForApi(repository.owner, repository.name, issueId)
+ (for {
+ issueId <- params("id").toIntOpt
+ comments = getCommentsForApi(repository.owner, repository.name, issueId)
} yield {
- JsonFormat(comments.map{ case (issueComment, user, issue) => ApiComment(issueComment, RepositoryName(repository), issueId, ApiUser(user), issue.isPullRequest) })
+ JsonFormat(comments.map {
+ case (issueComment, user, issue) =>
+ ApiComment(issueComment, RepositoryName(repository), issueId, ApiUser(user), issue.isPullRequest)
+ })
}) getOrElse NotFound()
})
@@ -414,15 +495,23 @@
* https://developer.github.com/v3/issues/comments/#create-a-comment
*/
post("/api/v3/repos/:owner/:repository/issues/:id/comments")(readableUsersOnly { repository =>
- (for{
- issueId <- params("id").toIntOpt
- issue <- getIssue(repository.owner, repository.name, issueId.toString)
- body <- extractFromJsonBody[CreateAComment].map(_.body) if ! body.isEmpty
- action = params.get("action").filter(_ => isEditable(issue.userName, issue.repositoryName, issue.openedUserName))
- (issue, id) <- handleComment(issue, Some(body), repository, action)
+ (for {
+ issueId <- params("id").toIntOpt
+ issue <- getIssue(repository.owner, repository.name, issueId.toString)
+ body <- extractFromJsonBody[CreateAComment].map(_.body) if !body.isEmpty
+ action = params.get("action").filter(_ => isEditable(issue.userName, issue.repositoryName, issue.openedUserName))
+ (issue, id) <- handleComment(issue, Some(body), repository, action)
issueComment <- getComment(repository.owner, repository.name, id.toString())
} yield {
- JsonFormat(ApiComment(issueComment, RepositoryName(repository), issueId, ApiUser(context.loginAccount.get), issue.isPullRequest))
+ JsonFormat(
+ ApiComment(
+ issueComment,
+ RepositoryName(repository),
+ issueId,
+ ApiUser(context.loginAccount.get),
+ issue.isPullRequest
+ )
+ )
}) getOrElse NotFound()
})
@@ -451,7 +540,7 @@
* https://developer.github.com/v3/issues/labels/#create-a-label
*/
post("/api/v3/repos/:owner/:repository/labels")(writableUsersOnly { repository =>
- (for{
+ (for {
data <- extractFromJsonBody[CreateALabel] if data.isValid
} yield {
LockUtil.lock(RepositoryName(repository).fullName) {
@@ -462,10 +551,12 @@
} getOrElse NotFound()
} else {
// TODO ApiError should support errors field to enhance compatibility of GitHub API
- UnprocessableEntity(ApiError(
- "Validation Failed",
- Some("https://developer.github.com/v3/issues/labels/#create-a-label")
- ))
+ UnprocessableEntity(
+ ApiError(
+ "Validation Failed",
+ Some("https://developer.github.com/v3/issues/labels/#create-a-label")
+ )
+ )
}
}
}) getOrElse NotFound()
@@ -476,24 +567,29 @@
* https://developer.github.com/v3/issues/labels/#update-a-label
*/
patch("/api/v3/repos/:owner/:repository/labels/:labelName")(writableUsersOnly { repository =>
- (for{
+ (for {
data <- extractFromJsonBody[CreateALabel] if data.isValid
} yield {
LockUtil.lock(RepositoryName(repository).fullName) {
- getLabel(repository.owner, repository.name, params("labelName")).map { label =>
- if (getLabel(repository.owner, repository.name, data.name).isEmpty) {
- updateLabel(repository.owner, repository.name, label.labelId, data.name, data.color)
- JsonFormat(ApiLabel(
- getLabel(repository.owner, repository.name, label.labelId).get,
- RepositoryName(repository)
- ))
- } else {
- // TODO ApiError should support errors field to enhance compatibility of GitHub API
- UnprocessableEntity(ApiError(
- "Validation Failed",
- Some("https://developer.github.com/v3/issues/labels/#create-a-label")
- ))
- }
+ getLabel(repository.owner, repository.name, params("labelName")).map {
+ label =>
+ if (getLabel(repository.owner, repository.name, data.name).isEmpty) {
+ updateLabel(repository.owner, repository.name, label.labelId, data.name, data.color)
+ JsonFormat(
+ ApiLabel(
+ getLabel(repository.owner, repository.name, label.labelId).get,
+ RepositoryName(repository)
+ )
+ )
+ } else {
+ // TODO ApiError should support errors field to enhance compatibility of GitHub API
+ UnprocessableEntity(
+ ApiError(
+ "Validation Failed",
+ Some("https://developer.github.com/v3/issues/labels/#create-a-label")
+ )
+ )
+ }
} getOrElse NotFound()
}
}) getOrElse NotFound()
@@ -524,22 +620,24 @@
val issues: List[(Issue, Account, Int, PullRequest, Repository, Account, Option[Account])] =
searchPullRequestByApi(
condition = condition,
- offset = (page - 1) * PullRequestLimit,
- limit = PullRequestLimit,
- repos = repository.owner -> repository.name
+ offset = (page - 1) * PullRequestLimit,
+ limit = PullRequestLimit,
+ repos = repository.owner -> repository.name
)
- JsonFormat(issues.map { case (issue, issueUser, commentCount, pullRequest, headRepo, headOwner, assignee) =>
- ApiPullRequest(
- issue = issue,
- pullRequest = pullRequest,
- headRepo = ApiRepository(headRepo, ApiUser(headOwner)),
- baseRepo = ApiRepository(repository, ApiUser(baseOwner)),
- user = ApiUser(issueUser),
- labels = getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository))),
- assignee = assignee.map(ApiUser.apply),
- mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
- )
+ JsonFormat(issues.map {
+ case (issue, issueUser, commentCount, pullRequest, headRepo, headOwner, assignee) =>
+ ApiPullRequest(
+ issue = issue,
+ pullRequest = pullRequest,
+ headRepo = ApiRepository(headRepo, ApiUser(headOwner)),
+ baseRepo = ApiRepository(repository, ApiUser(baseOwner)),
+ user = ApiUser(issueUser),
+ labels = getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository))),
+ assignee = assignee.map(ApiUser.apply),
+ mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
+ )
})
})
@@ -547,26 +645,34 @@
* https://developer.github.com/v3/pulls/#get-a-single-pull-request
*/
get("/api/v3/repos/:owner/:repository/pulls/:id")(referrersOnly { repository =>
- (for{
- issueId <- params("id").toIntOpt
+ (for {
+ issueId <- params("id").toIntOpt
(issue, pullRequest) <- getPullRequest(repository.owner, repository.name, issueId)
- users = getAccountsByUserNames(Set(repository.owner, pullRequest.requestUserName, issue.openedUserName), Set.empty)
+ users = getAccountsByUserNames(
+ Set(repository.owner, pullRequest.requestUserName, issue.openedUserName),
+ Set.empty
+ )
baseOwner <- users.get(repository.owner)
headOwner <- users.get(pullRequest.requestUserName)
issueUser <- users.get(issue.openedUserName)
- assignee = issue.assignedUserName.flatMap { userName => getAccountByUserName(userName, false) }
- headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
+ assignee = issue.assignedUserName.flatMap { userName =>
+ getAccountByUserName(userName, false)
+ }
+ headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
} yield {
- JsonFormat(ApiPullRequest(
- issue = issue,
- pullRequest = pullRequest,
- headRepo = ApiRepository(headRepo, ApiUser(headOwner)),
- baseRepo = ApiRepository(repository, ApiUser(baseOwner)),
- user = ApiUser(issueUser),
- labels = getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository))),
- assignee = assignee.map(ApiUser.apply),
- mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
- ))
+ JsonFormat(
+ ApiPullRequest(
+ issue = issue,
+ pullRequest = pullRequest,
+ headRepo = ApiRepository(headRepo, ApiUser(headOwner)),
+ baseRepo = ApiRepository(repository, ApiUser(baseOwner)),
+ user = ApiUser(issueUser),
+ labels = getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository))),
+ assignee = assignee.map(ApiUser.apply),
+ mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
+ )
+ )
}) getOrElse NotFound()
})
@@ -576,16 +682,26 @@
get("/api/v3/repos/:owner/:repository/pulls/:id/commits")(referrersOnly { repository =>
val owner = repository.owner
val name = repository.name
- params("id").toIntOpt.flatMap{ issueId =>
- getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
- using(Git.open(getRepositoryDir(owner, name))){ git =>
- val oldId = git.getRepository.resolve(pullreq.commitIdFrom)
- val newId = git.getRepository.resolve(pullreq.commitIdTo)
- val repoFullName = RepositoryName(repository)
- val commits = git.log.addRange(oldId, newId).call.iterator.asScala.map { c => ApiCommitListItem(new CommitInfo(c), repoFullName) }.toList
- JsonFormat(commits)
+ params("id").toIntOpt.flatMap {
+ issueId =>
+ getPullRequest(owner, name, issueId) map {
+ case (issue, pullreq) =>
+ using(Git.open(getRepositoryDir(owner, name))) { git =>
+ val oldId = git.getRepository.resolve(pullreq.commitIdFrom)
+ val newId = git.getRepository.resolve(pullreq.commitIdTo)
+ val repoFullName = RepositoryName(repository)
+ val commits = git.log
+ .addRange(oldId, newId)
+ .call
+ .iterator
+ .asScala
+ .map { c =>
+ ApiCommitListItem(new CommitInfo(c), repoFullName)
+ }
+ .toList
+ JsonFormat(commits)
+ }
}
- }
} getOrElse NotFound()
})
@@ -600,15 +716,24 @@
* https://developer.github.com/v3/repos/statuses/#create-a-status
*/
post("/api/v3/repos/:owner/:repo/statuses/:sha")(writableUsersOnly { repository =>
- (for{
- ref <- params.get("sha")
- sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
- data <- extractFromJsonBody[CreateAStatus] if data.isValid
- creator <- context.loginAccount
- state <- CommitState.valueOf(data.state)
- statusId = createCommitStatus(repository.owner, repository.name, sha, data.context.getOrElse("default"),
- state, data.target_url, data.description, new java.util.Date(), creator)
- status <- getCommitStatus(repository.owner, repository.name, statusId)
+ (for {
+ ref <- params.get("sha")
+ sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
+ data <- extractFromJsonBody[CreateAStatus] if data.isValid
+ creator <- context.loginAccount
+ state <- CommitState.valueOf(data.state)
+ statusId = createCommitStatus(
+ repository.owner,
+ repository.name,
+ sha,
+ data.context.getOrElse("default"),
+ state,
+ data.target_url,
+ data.description,
+ new java.util.Date(),
+ creator
+ )
+ status <- getCommitStatus(repository.owner, repository.name, statusId)
} yield {
JsonFormat(ApiCommitStatus(status, ApiUser(creator)))
}) getOrElse NotFound()
@@ -620,12 +745,13 @@
* ref is Ref to list the statuses from. It can be a SHA, a branch name, or a tag name.
*/
val listStatusesRoute = get("/api/v3/repos/:owner/:repo/commits/:ref/statuses")(referrersOnly { repository =>
- (for{
+ (for {
ref <- params.get("ref")
sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
} yield {
- JsonFormat(getCommitStatuesWithCreator(repository.owner, repository.name, sha).map{ case(status, creator) =>
- ApiCommitStatus(status, ApiUser(creator))
+ JsonFormat(getCommitStatuesWithCreator(repository.owner, repository.name, sha).map {
+ case (status, creator) =>
+ ApiCommitStatus(status, ApiUser(creator))
})
}) getOrElse NotFound()
})
@@ -635,7 +761,7 @@
*
* legacy route
*/
- get("/api/v3/repos/:owner/:repo/statuses/:ref"){
+ get("/api/v3/repos/:owner/:repo/statuses/:ref") {
listStatusesRoute.action()
}
@@ -645,10 +771,10 @@
* ref is Ref to list the statuses from. It can be a SHA, a branch name, or a tag name.
*/
get("/api/v3/repos/:owner/:repo/commits/:ref/status")(referrersOnly { repository =>
- (for{
- ref <- params.get("ref")
+ (for {
+ ref <- params.get("ref")
owner <- getAccountByUserName(repository.owner)
- sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
+ sha <- JGitUtil.getShaByRef(repository.owner, repository.name, ref)
} yield {
val statuses = getCommitStatuesWithCreator(repository.owner, repository.name, sha)
JsonFormat(ApiCombinedCommitStatus(sha, statuses, ApiRepository(repository, owner)))
@@ -660,24 +786,27 @@
*/
get("/api/v3/repos/:owner/:repo/commits/:sha")(referrersOnly { repository =>
val owner = repository.owner
- val name = repository.name
- val sha = params("sha")
+ val name = repository.name
+ val sha = params("sha")
- using(Git.open(getRepositoryDir(owner, name))){ git =>
- val repo = git.getRepository
- val objectId = repo.resolve(sha)
- val commitInfo = using(new RevWalk(repo)){ revWalk =>
- new CommitInfo(revWalk.parseCommit(objectId))
- }
+ using(Git.open(getRepositoryDir(owner, name))) {
+ git =>
+ val repo = git.getRepository
+ val objectId = repo.resolve(sha)
+ val commitInfo = using(new RevWalk(repo)) { revWalk =>
+ new CommitInfo(revWalk.parseCommit(objectId))
+ }
- JsonFormat(ApiCommits(
- repositoryName = RepositoryName(repository),
- commitInfo = commitInfo,
- diffs = JGitUtil.getDiffs(git, Some(commitInfo.parents.head), commitInfo.id, false, true),
- author = getAccount(commitInfo.authorName, commitInfo.authorEmailAddress),
- committer = getAccount(commitInfo.committerName, commitInfo.committerEmailAddress),
- commentCount = getCommitComment(repository.owner, repository.name, sha).size
- ))
+ JsonFormat(
+ ApiCommits(
+ repositoryName = RepositoryName(repository),
+ commitInfo = commitInfo,
+ diffs = JGitUtil.getDiffs(git, Some(commitInfo.parents.head), commitInfo.id, false, true),
+ author = getAccount(commitInfo.authorName, commitInfo.authorEmailAddress),
+ committer = getAccount(commitInfo.committerName, commitInfo.committerEmailAddress),
+ commentCount = getCommitComment(repository.owner, repository.name, sha).size
+ )
+ )
}
})
@@ -705,11 +834,11 @@
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
/**
- * non-GitHub compatible API for Jenkins-Plugin
- */
+ * non-GitHub compatible API for Jenkins-Plugin
+ */
get("/api/v3/repos/:owner/:repo/raw/*")(referrersOnly { repository =>
val (id, path) = repository.splitPath(multiParams("splat").head)
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
getPathObjectId(git, path, revCommit).map { objectId =>
@@ -719,10 +848,9 @@
})
/**
- * non-GitHub compatible API for listing plugins
- */
- get("/api/v3/gitbucket/plugins"){
- PluginRegistry().getPlugins().map{ApiPlugin(_)}
+ * non-GitHub compatible API for listing plugins
+ */
+ get("/api/v3/gitbucket/plugins") {
+ PluginRegistry().getPlugins().map { ApiPlugin(_) }
}
}
-
diff --git a/src/main/scala/gitbucket/core/controller/ControllerBase.scala b/src/main/scala/gitbucket/core/controller/ControllerBase.scala
index b4ad4a7..ecb3d13 100644
--- a/src/main/scala/gitbucket/core/controller/ControllerBase.scala
+++ b/src/main/scala/gitbucket/core/controller/ControllerBase.scala
@@ -31,9 +31,14 @@
/**
* Provides generic features for controller implementations.
*/
-abstract class ControllerBase extends ScalatraFilter
- with ValidationSupport with JacksonJsonSupport with I18nSupport with FlashMapSupport with Validations
- with SystemSettingsService {
+abstract class ControllerBase
+ extends ScalatraFilter
+ with ValidationSupport
+ with JacksonJsonSupport
+ with I18nSupport
+ with FlashMapSupport
+ with Validations
+ with SystemSettingsService {
private val logger = LoggerFactory.getLogger(getClass)
@@ -45,31 +50,32 @@
override def requestPath(uri: String, idx: Int): String = {
val path = super.requestPath(uri, idx)
- if(path != "/" && path.endsWith("/")){
+ if (path != "/" && path.endsWith("/")) {
path.substring(0, path.length - 1)
} else {
path
}
}
- override def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain): Unit = try {
- val httpRequest = request.asInstanceOf[HttpServletRequest]
- val context = request.getServletContext.getContextPath
- val path = httpRequest.getRequestURI.substring(context.length)
+ override def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain): Unit =
+ try {
+ val httpRequest = request.asInstanceOf[HttpServletRequest]
+ val context = request.getServletContext.getContextPath
+ val path = httpRequest.getRequestURI.substring(context.length)
- if(path.startsWith("/git/") || path.startsWith("/git-lfs/")){
- // Git repository
- chain.doFilter(request, response)
- } else {
- if(path.startsWith("/api/v3/")){
- httpRequest.setAttribute(Keys.Request.APIv3, true)
+ if (path.startsWith("/git/") || path.startsWith("/git-lfs/")) {
+ // Git repository
+ chain.doFilter(request, response)
+ } else {
+ if (path.startsWith("/api/v3/")) {
+ httpRequest.setAttribute(Keys.Request.APIv3, true)
+ }
+ // Scalatra actions
+ super.doFilter(request, response, chain)
}
- // Scalatra actions
- super.doFilter(request, response, chain)
+ } finally {
+ contextCache.remove();
}
- } finally {
- contextCache.remove();
- }
private val contextCache = new java.lang.ThreadLocal[Context]()
@@ -87,36 +93,37 @@
}
}
- private def LoginAccount: Option[Account] = request.getAs[Account](Keys.Session.LoginAccount).orElse(session.getAs[Account](Keys.Session.LoginAccount))
+ private def LoginAccount: Option[Account] =
+ request.getAs[Account](Keys.Session.LoginAccount).orElse(session.getAs[Account](Keys.Session.LoginAccount))
- def ajaxGet(path : String)(action : => Any) : Route =
- super.get(path){
+ def ajaxGet(path: String)(action: => Any): Route =
+ super.get(path) {
request.setAttribute(Keys.Request.Ajax, "true")
action
}
- override def ajaxGet[T](path : String, form : ValueType[T])(action : T => Any) : Route =
- super.ajaxGet(path, form){ form =>
+ override def ajaxGet[T](path: String, form: ValueType[T])(action: T => Any): Route =
+ super.ajaxGet(path, form) { form =>
request.setAttribute(Keys.Request.Ajax, "true")
action(form)
}
- def ajaxPost(path : String)(action : => Any) : Route =
- super.post(path){
+ def ajaxPost(path: String)(action: => Any): Route =
+ super.post(path) {
request.setAttribute(Keys.Request.Ajax, "true")
action
}
- override def ajaxPost[T](path : String, form : ValueType[T])(action : T => Any) : Route =
- super.ajaxPost(path, form){ form =>
+ override def ajaxPost[T](path: String, form: ValueType[T])(action: T => Any): Route =
+ super.ajaxPost(path, form) { form =>
request.setAttribute(Keys.Request.Ajax, "true")
action(form)
}
protected def NotFound() =
- if(request.hasAttribute(Keys.Request.Ajax)){
+ if (request.hasAttribute(Keys.Request.Ajax)) {
org.scalatra.NotFound()
- } else if(request.hasAttribute(Keys.Request.APIv3)){
+ } else if (request.hasAttribute(Keys.Request.APIv3)) {
contentType = formats("json")
org.scalatra.NotFound(ApiError("Not Found"))
} else {
@@ -124,7 +131,7 @@
}
private def isBrowser(userAgent: String): Boolean = {
- if(userAgent == null || userAgent.isEmpty){
+ if (userAgent == null || userAgent.isEmpty) {
false
} else {
val data = Classifier.parse(userAgent)
@@ -134,35 +141,41 @@
}
protected def Unauthorized()(implicit context: Context) =
- if(request.hasAttribute(Keys.Request.Ajax)){
+ if (request.hasAttribute(Keys.Request.Ajax)) {
org.scalatra.Unauthorized()
- } else if(request.hasAttribute(Keys.Request.APIv3)){
+ } else if (request.hasAttribute(Keys.Request.APIv3)) {
contentType = formats("json")
org.scalatra.Unauthorized(ApiError("Requires authentication"))
- } else if(!isBrowser(request.getHeader("USER-AGENT"))){
+ } else if (!isBrowser(request.getHeader("USER-AGENT"))) {
org.scalatra.Unauthorized()
} else {
- if(context.loginAccount.isDefined){
+ if (context.loginAccount.isDefined) {
org.scalatra.Unauthorized(redirect("/"))
} else {
- if(request.getMethod.toUpperCase == "POST"){
+ if (request.getMethod.toUpperCase == "POST") {
org.scalatra.Unauthorized(redirect("/signin"))
} else {
- org.scalatra.Unauthorized(redirect("/signin?redirect=" + StringUtil.urlEncode(
- defining(request.getQueryString){ queryString =>
- request.getRequestURI.substring(request.getContextPath.length) + (if(queryString != null) "?" + queryString else "")
- }
- )))
+ org.scalatra.Unauthorized(
+ redirect(
+ "/signin?redirect=" + StringUtil.urlEncode(
+ defining(request.getQueryString) { queryString =>
+ request.getRequestURI.substring(request.getContextPath.length) + (if (queryString != null)
+ "?" + queryString
+ else "")
+ }
+ )
+ )
+ )
}
}
}
- error{
+ error {
case e => {
logger.error(s"Catch unhandled error in request: ${request}", e)
- if(request.hasAttribute(Keys.Request.Ajax)){
+ if (request.hasAttribute(Keys.Request.Ajax)) {
org.scalatra.InternalServerError()
- } else if(request.hasAttribute(Keys.Request.APIv3)){
+ } else if (request.hasAttribute(Keys.Request.APIv3)) {
contentType = formats("json")
org.scalatra.InternalServerError(ApiError("Internal Server Error"))
} else {
@@ -171,30 +184,39 @@
}
}
- override def url(path: String, params: Iterable[(String, Any)] = Iterable.empty,
- includeContextPath: Boolean = true, includeServletPath: Boolean = true,
- absolutize: Boolean = true, withSessionId: Boolean = true)
- (implicit request: HttpServletRequest, response: HttpServletResponse): String =
+ override def url(
+ path: String,
+ params: Iterable[(String, Any)] = Iterable.empty,
+ includeContextPath: Boolean = true,
+ includeServletPath: Boolean = true,
+ absolutize: Boolean = true,
+ withSessionId: Boolean = true
+ )(implicit request: HttpServletRequest, response: HttpServletResponse): String =
if (path.startsWith("http")) path
else baseUrl + super.url(path, params, false, false, false)
/**
* Extends scalatra-form's trim rule to eliminate CR and LF.
*/
- protected def trim2[T](valueType: SingleValueType[T]): SingleValueType[T] = new SingleValueType[T](){
+ protected def trim2[T](valueType: SingleValueType[T]): SingleValueType[T] = new SingleValueType[T]() {
def convert(value: String, messages: Messages): T = valueType.convert(trim(value), messages)
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] =
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Seq[(String, String)] =
valueType.validate(name, trim(value), params, messages)
- private def trim(value: String): String = if(value == null) null else value.replace("\r\n", "").trim
+ private def trim(value: String): String = if (value == null) null else value.replace("\r\n", "").trim
}
/**
* Use this method to response the raw data against XSS.
*/
protected def RawData[T](contentType: String, rawData: T): T = {
- if(contentType.split(";").head.trim.toLowerCase.startsWith("text/html")){
+ if (contentType.split(";").head.trim.toLowerCase.startsWith("text/html")) {
this.contentType = "text/plain"
} else {
this.contentType = contentType
@@ -204,35 +226,39 @@
}
// jenkins send message as 'application/x-www-form-urlencoded' but scalatra already parsed as multi-part-request.
- def extractFromJsonBody[A](implicit request:HttpServletRequest, mf:Manifest[A]): Option[A] = {
- (request.contentType.map(_.split(";").head.toLowerCase) match{
+ def extractFromJsonBody[A](implicit request: HttpServletRequest, mf: Manifest[A]): Option[A] = {
+ (request.contentType.map(_.split(";").head.toLowerCase) match {
case Some("application/x-www-form-urlencoded") => multiParams.keys.headOption.map(parse(_))
- case Some("application/json") => Some(parsedBody)
- case _ => Some(parse(request.body))
+ case Some("application/json") => Some(parsedBody)
+ case _ => Some(parse(request.body))
}).filterNot(_ == JNothing).flatMap(j => Try(j.extract[A]).toOption)
}
protected def getPathObjectId(git: Git, path: String, revCommit: RevCommit): Option[ObjectId] = {
@scala.annotation.tailrec
def _getPathObjectId(path: String, walk: TreeWalk): Option[ObjectId] = walk.next match {
- case true if(walk.getPathString == path) => Some(walk.getObjectId(0))
- case true => _getPathObjectId(path, walk)
- case false => None
+ case true if (walk.getPathString == path) => Some(walk.getObjectId(0))
+ case true => _getPathObjectId(path, walk)
+ case false => None
}
- using(new TreeWalk(git.getRepository)){ treeWalk =>
+ using(new TreeWalk(git.getRepository)) { treeWalk =>
treeWalk.addTree(revCommit.getTree)
treeWalk.setRecursive(true)
_getPathObjectId(path, treeWalk)
}
}
- protected def responseRawFile(git: Git, objectId: ObjectId, path: String,
- repository: RepositoryService.RepositoryInfo): Unit = {
- JGitUtil.getObjectLoaderFromId(git, objectId){ loader =>
+ protected def responseRawFile(
+ git: Git,
+ objectId: ObjectId,
+ path: String,
+ repository: RepositoryService.RepositoryInfo
+ ): Unit = {
+ JGitUtil.getObjectLoaderFromId(git, objectId) { loader =>
contentType = FileUtil.getMimeType(path)
- if(loader.isLarge){
+ if (loader.isLarge) {
response.setContentLength(loader.getSize.toInt)
loader.copyTo(response.outputStream)
} else {
@@ -240,11 +266,11 @@
val text = new String(bytes, "UTF-8")
val attrs = JGitUtil.getLfsObjects(text)
- if(attrs.nonEmpty) {
+ if (attrs.nonEmpty) {
response.setContentLength(attrs("size").toInt)
val oid = attrs("oid").split(":")(1)
- using(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))){ in =>
+ using(new FileInputStream(FileUtil.getLfsFilePath(repository.owner, repository.name, oid))) { in =>
IOUtils.copy(in, response.getOutputStream)
}
} else {
@@ -259,17 +285,21 @@
/**
* 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 currentPath = request.getRequestURI.substring(request.getContextPath.length)
val baseUrl = settings.baseUrl(request)
val host = new java.net.URL(baseUrl).getHost
val platform = request.getHeader("User-Agent") match {
- case null => null
- case agent if agent.contains("Mac") => "mac"
+ case null => null
+ case agent if agent.contains("Mac") => "mac"
case agent if agent.contains("Linux") => "linux"
- case agent if agent.contains("Win") => "windows"
- case _ => null
+ case agent if agent.contains("Win") => "windows"
+ case _ => null
}
val sidebarCollapse = request.getSession.getAttribute("sidebar-collapse") != null
@@ -280,7 +310,7 @@
* Cached object are available during a request.
*/
def cache[A](key: String)(action: => A): A =
- defining(Keys.Request.Cache(key)){ cacheKey =>
+ defining(Keys.Request.Cache(key)) { cacheKey =>
Option(request.getAttribute(cacheKey).asInstanceOf[A]).getOrElse {
val newObject = action
request.setAttribute(cacheKey, newObject)
@@ -294,10 +324,10 @@
* Base trait for controllers which manages account information.
*/
trait AccountManagementControllerBase extends ControllerBase {
- self: AccountService =>
+ self: AccountService =>
protected def updateImage(userName: String, fileId: Option[String], clearImage: Boolean): Unit =
- if(clearImage){
+ if (clearImage) {
getAccountByUserName(userName).flatMap(_.image).map { image =>
new java.io.File(getUserUploadDir(userName), image).delete()
updateAvatarImage(userName, None)
@@ -306,36 +336,63 @@
fileId.map { fileId =>
val filename = "avatar." + FileUtil.getExtension(session.getAndRemove(Keys.Session.Upload(fileId)).get)
val uploadDir = getUserUploadDir(userName)
- if(!uploadDir.exists){
+ if (!uploadDir.exists) {
uploadDir.mkdirs()
}
- Thumbnails.of(new java.io.File(getTemporaryDir(session.getId), fileId))
+ Thumbnails
+ .of(new java.io.File(getTemporaryDir(session.getId), fileId))
.size(324, 324)
.toFile(new java.io.File(uploadDir, filename))
updateAvatarImage(userName, Some(filename))
}
}
- protected def uniqueUserName: Constraint = new Constraint(){
+ protected def uniqueUserName: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- getAccountByUserName(value, true).map { _ => "User already exists." }
+ getAccountByUserName(value, true).map { _ =>
+ "User already exists."
+ }
}
- protected def uniqueMailAddress(paramName: String = ""): Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] = {
+ protected def uniqueMailAddress(paramName: String = ""): Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] = {
getAccountByMailAddress(value, true)
- .filter { x => if(paramName.isEmpty) true else Some(x.userName) != params.optionValue(paramName) }
- .map { _ => "Mail address is already registered." }
+ .filter { x =>
+ if (paramName.isEmpty) true else Some(x.userName) != params.optionValue(paramName)
+ }
+ .map { _ =>
+ "Mail address is already registered."
+ }
}
}
- val allReservedNames = Set("git", "admin", "upload", "api", "assets", "plugin-assets", "signin", "signout", "register", "activities.atom", "sidebar-collapse", "groups", "new")
- protected def reservedNames(): Constraint = new Constraint(){
- override def validate(name: String, value: String, messages: Messages): Option[String] = if(allReservedNames.contains(value)){
- Some(s"${value} is reserved")
- } else {
- None
- }
+ val allReservedNames = Set(
+ "git",
+ "admin",
+ "upload",
+ "api",
+ "assets",
+ "plugin-assets",
+ "signin",
+ "signout",
+ "register",
+ "activities.atom",
+ "sidebar-collapse",
+ "groups",
+ "new"
+ )
+ protected def reservedNames(): Constraint = new Constraint() {
+ override def validate(name: String, value: String, messages: Messages): Option[String] =
+ if (allReservedNames.contains(value)) {
+ Some(s"${value} is reserved")
+ } else {
+ None
+ }
}
}
diff --git a/src/main/scala/gitbucket/core/controller/DashboardController.scala b/src/main/scala/gitbucket/core/controller/DashboardController.scala
index f422ba5..2c8a982 100644
--- a/src/main/scala/gitbucket/core/controller/DashboardController.scala
+++ b/src/main/scala/gitbucket/core/controller/DashboardController.scala
@@ -6,13 +6,20 @@
import gitbucket.core.util.Implicits._
import gitbucket.core.service.IssuesService._
-class DashboardController extends DashboardControllerBase
- with IssuesService with PullRequestService with RepositoryService with AccountService with CommitsService
- with LabelsService with PrioritiesService with MilestonesService with UsersAuthenticator
+class DashboardController
+ extends DashboardControllerBase
+ with IssuesService
+ with PullRequestService
+ with RepositoryService
+ with AccountService
+ with CommitsService
+ with LabelsService
+ with PrioritiesService
+ with MilestonesService
+ with UsersAuthenticator
trait DashboardControllerBase extends ControllerBase {
- self: IssuesService with PullRequestService with RepositoryService with AccountService
- with UsersAuthenticator =>
+ self: IssuesService with PullRequestService with RepositoryService with AccountService with UsersAuthenticator =>
get("/dashboard/issues")(usersOnly {
searchIssues("created_by")
@@ -59,51 +66,52 @@
private def searchIssues(filter: String) = {
import IssuesService._
- val userName = context.loginAccount.get.userName
+ val userName = context.loginAccount.get.userName
val condition = getOrCreateCondition(Keys.Session.DashboardIssues, filter, userName)
val userRepos = getUserRepositories(userName, true).map(repo => repo.owner -> repo.name)
- val page = IssueSearchCondition.page(request)
+ val page = IssueSearchCondition.page(request)
html.issues(
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, userRepos: _*),
page,
- countIssue(condition.copy(state = "open" ), false, userRepos: _*),
+ countIssue(condition.copy(state = "open"), false, userRepos: _*),
countIssue(condition.copy(state = "closed"), false, userRepos: _*),
filter match {
- case "assigned" => condition.copy(assigned = Some(Some(userName)))
+ case "assigned" => condition.copy(assigned = Some(Some(userName)))
case "mentioned" => condition.copy(mentioned = Some(userName))
- case _ => condition.copy(author = Some(userName))
+ case _ => condition.copy(author = Some(userName))
},
filter,
getGroupNames(userName),
Nil,
- getUserRepositories(userName, withoutPhysicalInfo = true))
+ getUserRepositories(userName, withoutPhysicalInfo = true)
+ )
}
private def searchPullRequests(filter: String) = {
import IssuesService._
import PullRequestService._
- val userName = context.loginAccount.get.userName
+ val userName = context.loginAccount.get.userName
val condition = getOrCreateCondition(Keys.Session.DashboardPulls, filter, userName)
- val allRepos = getAllRepositories(userName)
- val page = IssueSearchCondition.page(request)
+ val allRepos = getAllRepositories(userName)
+ val page = IssueSearchCondition.page(request)
html.pulls(
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, allRepos: _*),
page,
- countIssue(condition.copy(state = "open" ), true, allRepos: _*),
+ countIssue(condition.copy(state = "open"), true, allRepos: _*),
countIssue(condition.copy(state = "closed"), true, allRepos: _*),
filter match {
- case "assigned" => condition.copy(assigned = Some(Some(userName)))
+ case "assigned" => condition.copy(assigned = Some(Some(userName)))
case "mentioned" => condition.copy(mentioned = Some(userName))
- case _ => condition.copy(author = Some(userName))
+ case _ => condition.copy(author = Some(userName))
},
filter,
getGroupNames(userName),
Nil,
- getUserRepositories(userName, withoutPhysicalInfo = true))
+ getUserRepositories(userName, withoutPhysicalInfo = true)
+ )
}
-
}
diff --git a/src/main/scala/gitbucket/core/controller/FileUploadController.scala b/src/main/scala/gitbucket/core/controller/FileUploadController.scala
index ca00ee2..3df5d8e 100644
--- a/src/main/scala/gitbucket/core/controller/FileUploadController.scala
+++ b/src/main/scala/gitbucket/core/controller/FileUploadController.scala
@@ -19,95 +19,133 @@
*
* This servlet saves uploaded file.
*/
-class FileUploadController extends ScalatraServlet
- with FileUploadSupport
- with RepositoryService
- with AccountService
- with ReleaseService{
+class FileUploadController
+ extends ScalatraServlet
+ with FileUploadSupport
+ with RepositoryService
+ with AccountService
+ with ReleaseService {
configureMultipartHandling(MultipartConfig(maxFileSize = Some(FileUtil.MaxFileSize)))
- post("/image"){
- execute({ (file, fileId) =>
- FileUtils.writeByteArrayToFile(new java.io.File(getTemporaryDir(session.getId), fileId), file.get)
- session += Keys.Session.Upload(fileId) -> file.name
- }, FileUtil.isImage)
+ post("/image") {
+ execute(
+ { (file, fileId) =>
+ FileUtils.writeByteArrayToFile(new java.io.File(getTemporaryDir(session.getId), fileId), file.get)
+ session += Keys.Session.Upload(fileId) -> file.name
+ },
+ FileUtil.isImage
+ )
}
- post("/tmp"){
- execute({ (file, fileId) =>
- FileUtils.writeByteArrayToFile(new java.io.File(getTemporaryDir(session.getId), fileId), file.get)
- session += Keys.Session.Upload(fileId) -> file.name
- }, _ => true)
+ post("/tmp") {
+ execute(
+ { (file, fileId) =>
+ FileUtils.writeByteArrayToFile(new java.io.File(getTemporaryDir(session.getId), fileId), file.get)
+ session += Keys.Session.Upload(fileId) -> file.name
+ },
+ _ => true
+ )
}
- post("/file/:owner/:repository"){
- execute({ (file, fileId) =>
- FileUtils.writeByteArrayToFile(new java.io.File(
- getAttachedDir(params("owner"), params("repository")),
- fileId + "." + FileUtil.getExtension(file.getName)), file.get)
- }, _ => true)
+ post("/file/:owner/:repository") {
+ execute(
+ { (file, fileId) =>
+ FileUtils.writeByteArrayToFile(
+ new java.io.File(
+ getAttachedDir(params("owner"), params("repository")),
+ fileId + "." + FileUtil.getExtension(file.getName)
+ ),
+ file.get
+ )
+ },
+ _ => true
+ )
}
- post("/wiki/:owner/:repository"){
+ post("/wiki/:owner/:repository") {
// Don't accept not logged-in users
- session.get(Keys.Session.LoginAccount).collect { case loginAccount: Account =>
- val owner = params("owner")
- val repository = params("repository")
+ session.get(Keys.Session.LoginAccount).collect {
+ case loginAccount: Account =>
+ val owner = params("owner")
+ val repository = params("repository")
- // Check whether logged-in user is collaborator
- onlyWikiEditable(owner, repository, loginAccount){
- execute({ (file, fileId) =>
- val fileName = file.getName
- LockUtil.lock(s"${owner}/${repository}/wiki") {
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
- val builder = DirCache.newInCore.builder()
- val inserter = git.getRepository.newObjectInserter()
- val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
+ // Check whether logged-in user is collaborator
+ onlyWikiEditable(owner, repository, loginAccount) {
+ execute(
+ { (file, fileId) =>
+ val fileName = file.getName
+ LockUtil.lock(s"${owner}/${repository}/wiki") {
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) {
+ git =>
+ val builder = DirCache.newInCore.builder()
+ val inserter = git.getRepository.newObjectInserter()
+ val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
- if(headId != null){
- JGitUtil.processTree(git, headId){ (path, tree) =>
- if(path != fileName){
- builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
- }
+ if (headId != null) {
+ JGitUtil.processTree(git, headId) { (path, tree) =>
+ if (path != fileName) {
+ builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
+ }
+ }
+ }
+
+ val bytes = IOUtils.toByteArray(file.getInputStream)
+ builder.add(
+ JGitUtil.createDirCacheEntry(
+ fileName,
+ FileMode.REGULAR_FILE,
+ inserter.insert(Constants.OBJ_BLOB, bytes)
+ )
+ )
+ builder.finish()
+
+ val newHeadId = JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headId,
+ builder.getDirCache.writeTree(inserter),
+ Constants.HEAD,
+ loginAccount.fullName,
+ loginAccount.mailAddress,
+ s"Uploaded ${fileName}"
+ )
+
+ fileName
}
}
-
- val bytes = IOUtils.toByteArray(file.getInputStream)
- builder.add(JGitUtil.createDirCacheEntry(fileName, FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, bytes)))
- builder.finish()
-
- val newHeadId = JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
- Constants.HEAD, loginAccount.fullName, loginAccount.mailAddress, s"Uploaded ${fileName}")
-
- fileName
- }
- }
- }, _ => true)
- }
+ },
+ _ => true
+ )
+ }
} getOrElse BadRequest()
}
- post("/release/:owner/:repository/:tag"){
- session.get(Keys.Session.LoginAccount).collect { case _: Account =>
- val owner = params("owner")
- val repository = params("repository")
- val tag = params("tag")
- execute({ (file, fileId) =>
- FileUtils.writeByteArrayToFile(
- new java.io.File(getReleaseFilesDir(owner, repository), tag + "/" + fileId),
- file.get
- )
- }, _ => true)
- }.getOrElse(BadRequest())
+ post("/release/:owner/:repository/:tag") {
+ session
+ .get(Keys.Session.LoginAccount)
+ .collect {
+ case _: Account =>
+ val owner = params("owner")
+ val repository = params("repository")
+ val tag = params("tag")
+ execute({ (file, fileId) =>
+ FileUtils.writeByteArrayToFile(
+ new java.io.File(getReleaseFilesDir(owner, repository), tag + "/" + fileId),
+ file.get
+ )
+ }, _ => true)
+ }
+ .getOrElse(BadRequest())
}
post("/import") {
import JDBCUtil._
- session.get(Keys.Session.LoginAccount).collect { case loginAccount: Account if loginAccount.isAdmin =>
- execute({ (file, fileId) =>
- request2Session(request).conn.importAsSQL(file.getInputStream)
- }, _ => true)
+ session.get(Keys.Session.LoginAccount).collect {
+ case loginAccount: Account if loginAccount.isAdmin =>
+ execute({ (file, fileId) =>
+ request2Session(request).conn.importAsSQL(file.getInputStream)
+ }, _ => true)
}
redirect("/admin/data")
}
@@ -115,24 +153,26 @@
private def onlyWikiEditable(owner: String, repository: String, loginAccount: Account)(action: => Any): Any = {
implicit val session = Database.getSession(request)
getRepository(owner, repository) match {
- case Some(x) => x.repository.options.wikiOption match {
- case "ALL" if !x.repository.isPrivate => action
- case "PUBLIC" if hasGuestRole(owner, repository, Some(loginAccount)) => action
- case "PRIVATE" if hasDeveloperRole(owner, repository, Some(loginAccount)) => action
- case _ => BadRequest()
- }
+ case Some(x) =>
+ x.repository.options.wikiOption match {
+ case "ALL" if !x.repository.isPrivate => action
+ case "PUBLIC" if hasGuestRole(owner, repository, Some(loginAccount)) => action
+ case "PRIVATE" if hasDeveloperRole(owner, repository, Some(loginAccount)) => action
+ case _ => BadRequest()
+ }
case None => BadRequest()
}
}
- private def execute(f: (FileItem, String) => Unit , mimeTypeChcker: (String) => Boolean) = fileParams.get("file") match {
- case Some(file) if(mimeTypeChcker(file.name)) =>
- defining(FileUtil.generateFileId){ fileId =>
- f(file, fileId)
- contentType = "text/plain"
- Ok(fileId)
- }
- case _ => BadRequest()
- }
+ private def execute(f: (FileItem, String) => Unit, mimeTypeChcker: (String) => Boolean) =
+ fileParams.get("file") match {
+ case Some(file) if (mimeTypeChcker(file.name)) =>
+ defining(FileUtil.generateFileId) { fileId =>
+ f(file, fileId)
+ contentType = "text/plain"
+ Ok(fileId)
+ }
+ case _ => BadRequest()
+ }
}
diff --git a/src/main/scala/gitbucket/core/controller/IndexController.scala b/src/main/scala/gitbucket/core/controller/IndexController.scala
index 1cb7838..e6f8311 100644
--- a/src/main/scala/gitbucket/core/controller/IndexController.scala
+++ b/src/main/scala/gitbucket/core/controller/IndexController.scala
@@ -13,22 +13,21 @@
import org.scalatra.Ok
import org.scalatra.forms._
-
-class IndexController extends IndexControllerBase
- with RepositoryService
- with ActivityService
- with AccountService
- with RepositorySearchService
- with IssuesService
- with LabelsService
- with MilestonesService
- with PrioritiesService
- with UsersAuthenticator
- with ReferrerAuthenticator
- with AccessTokenService
- with AccountFederationService
- with OpenIDConnectService
-
+class IndexController
+ extends IndexControllerBase
+ with RepositoryService
+ with ActivityService
+ with AccountService
+ with RepositorySearchService
+ with IssuesService
+ with LabelsService
+ with MilestonesService
+ with PrioritiesService
+ with UsersAuthenticator
+ with ReferrerAuthenticator
+ with AccessTokenService
+ with AccountFederationService
+ with OpenIDConnectService
trait IndexControllerBase extends ControllerBase {
self: RepositoryService
@@ -59,37 +58,43 @@
case class OidcContext(state: State, nonce: Nonce, redirectBackURI: String)
- get("/"){
- context.loginAccount.map { account =>
- val visibleOwnerSet: Set[String] = Set(account.userName) ++ getGroupsByUserName(account.userName)
- gitbucket.core.html.index(
- getRecentActivitiesByOwners(visibleOwnerSet),
- Nil,
- getUserRepositories(account.userName, withoutPhysicalInfo = true),
- showBannerToCreatePersonalAccessToken = hasAccountFederation(account.userName) && !hasAccessToken(account.userName))
- }.getOrElse {
- gitbucket.core.html.index(
- getRecentActivities(),
- getVisibleRepositories(None, withoutPhysicalInfo = true),
- Nil,
- showBannerToCreatePersonalAccessToken = false)
- }
+ get("/") {
+ context.loginAccount
+ .map { account =>
+ val visibleOwnerSet: Set[String] = Set(account.userName) ++ getGroupsByUserName(account.userName)
+ gitbucket.core.html.index(
+ getRecentActivitiesByOwners(visibleOwnerSet),
+ Nil,
+ getUserRepositories(account.userName, withoutPhysicalInfo = true),
+ showBannerToCreatePersonalAccessToken = hasAccountFederation(account.userName) && !hasAccessToken(
+ account.userName
+ )
+ )
+ }
+ .getOrElse {
+ gitbucket.core.html.index(
+ getRecentActivities(),
+ getVisibleRepositories(None, withoutPhysicalInfo = true),
+ Nil,
+ showBannerToCreatePersonalAccessToken = false
+ )
+ }
}
- get("/signin"){
+ get("/signin") {
val redirect = params.get("redirect")
- if(redirect.isDefined && redirect.get.startsWith("/")){
+ if (redirect.isDefined && redirect.get.startsWith("/")) {
flash += Keys.Flash.Redirect -> redirect.get
}
gitbucket.core.html.signin(flash.get("userName"), flash.get("password"), flash.get("error"))
}
- post("/signin", signinForm){ form =>
+ post("/signin", signinForm) { form =>
authenticate(context.settings, form.userName, form.password) match {
case Some(account) =>
flash.get(Keys.Flash.Redirect) match {
case Some(redirectUrl: String) => signin(account, redirectUrl + form.hash.getOrElse(""))
- case _ => signin(account)
+ case _ => signin(account)
}
case None =>
flash += "userName" -> form.userName
@@ -100,17 +105,20 @@
}
/**
- * Initiate an OpenID Connect authentication request.
- */
+ * Initiate an OpenID Connect authentication request.
+ */
post("/signin/oidc") {
context.settings.oidc.map { oidc =>
val redirectURI = new URI(s"$baseUrl/signin/oidc")
val authenticationRequest = createOIDCAuthenticationRequest(oidc.issuer, oidc.clientID, redirectURI)
val redirectBackURI = flash.get(Keys.Flash.Redirect) match {
case Some(redirectBackURI: String) => redirectBackURI + params.getOrElse("hash", "")
- case _ => "/"
+ case _ => "/"
}
- session.setAttribute(Keys.Session.OidcContext, OidcContext(authenticationRequest.getState, authenticationRequest.getNonce, redirectBackURI))
+ session.setAttribute(
+ Keys.Session.OidcContext,
+ OidcContext(authenticationRequest.getState, authenticationRequest.getNonce, redirectBackURI)
+ )
redirect(authenticationRequest.toURI.toString)
} getOrElse {
NotFound()
@@ -118,8 +126,8 @@
}
/**
- * Handle an OpenID Connect authentication response.
- */
+ * Handle an OpenID Connect authentication response.
+ */
get("/signin/oidc") {
context.settings.oidc.map { oidc =>
val redirectURI = new URI(s"$baseUrl/signin/oidc")
@@ -142,33 +150,33 @@
}
}
- get("/signout"){
+ get("/signout") {
session.invalidate
redirect("/")
}
- get("/activities.atom"){
+ get("/activities.atom") {
contentType = "application/atom+xml; type=feed"
xml.feed(getRecentActivities())
}
- post("/sidebar-collapse"){
- if(params("collapse") == "true"){
+ post("/sidebar-collapse") {
+ if (params("collapse") == "true") {
session.setAttribute("sidebar-collapse", "true")
- } else {
+ } else {
session.setAttribute("sidebar-collapse", null)
}
Ok()
}
/**
- * Set account information into HttpSession and redirect.
- */
+ * Set account information into HttpSession and redirect.
+ */
private def signin(account: Account, redirectUrl: String = "/") = {
session.setAttribute(Keys.Session.LoginAccount, account)
updateLastLoginDate(account.userName)
- if(LDAPUtil.isDummyMailAddress(account)) {
+ if (LDAPUtil.isDummyMailAddress(account)) {
redirect("/" + account.userName + "/_edit")
}
@@ -184,23 +192,28 @@
*/
get("/_user/proposals")(usersOnly {
contentType = formats("json")
- val user = params("user").toBoolean
+ val user = params("user").toBoolean
val group = params("group").toBoolean
org.json4s.jackson.Serialization.write(
- Map("options" -> (
- getAllUsers(false)
- .withFilter { t => (user, group) match {
- case (true, true) => true
- case (true, false) => !t.isGroupAccount
- case (false, true) => t.isGroupAccount
- case (false, false) => false
- }}.map { t =>
- Map(
- "label" -> s"@${t.userName} ${t.fullName}",
- "value" -> t.userName
- )
- }
- ))
+ Map(
+ "options" -> (
+ getAllUsers(false)
+ .withFilter { t =>
+ (user, group) match {
+ case (true, true) => true
+ case (true, false) => !t.isGroupAccount
+ case (false, true) => t.isGroupAccount
+ case (false, false) => false
+ }
+ }
+ .map { t =>
+ Map(
+ "label" -> s"@${t.userName} ${t.fullName}",
+ "value" -> t.userName
+ )
+ }
+ )
+ )
)
})
@@ -210,47 +223,68 @@
*/
post("/_user/existence")(usersOnly {
getAccountByUserName(params("userName")).map { account =>
- if(account.isGroupAccount) "group" else "user"
+ if (account.isGroupAccount) "group" else "user"
} getOrElse ""
})
// TODO Move to RepositoryViwerController?
get("/:owner/:repository/search")(referrersOnly { repository =>
- defining(params.getOrElse("q", "").trim, params.getOrElse("type", "code")){ case (query, target) =>
- val page = try {
- val i = params.getOrElse("page", "1").toInt
- if(i <= 0) 1 else i
- } catch {
- case e: NumberFormatException => 1
- }
+ defining(params.getOrElse("q", "").trim, params.getOrElse("type", "code")) {
+ case (query, target) =>
+ val page = try {
+ val i = params.getOrElse("page", "1").toInt
+ if (i <= 0) 1 else i
+ } catch {
+ case e: NumberFormatException => 1
+ }
- target.toLowerCase match {
- case "issue" => gitbucket.core.search.html.issues(
- if(query.nonEmpty) searchIssues(repository.owner, repository.name, query) else Nil,
- query, page, repository)
+ target.toLowerCase match {
+ case "issue" =>
+ gitbucket.core.search.html.issues(
+ if (query.nonEmpty) searchIssues(repository.owner, repository.name, query) else Nil,
+ query,
+ page,
+ repository
+ )
- case "wiki" => gitbucket.core.search.html.wiki(
- if(query.nonEmpty) searchWikiPages(repository.owner, repository.name, query) else Nil,
- query, page, repository)
+ case "wiki" =>
+ gitbucket.core.search.html.wiki(
+ if (query.nonEmpty) searchWikiPages(repository.owner, repository.name, query) else Nil,
+ query,
+ page,
+ repository
+ )
- case _ => gitbucket.core.search.html.code(
- if(query.nonEmpty) searchFiles(repository.owner, repository.name, query) else Nil,
- query, page, repository)
- }
+ case _ =>
+ gitbucket.core.search.html.code(
+ if (query.nonEmpty) searchFiles(repository.owner, repository.name, query) else Nil,
+ query,
+ page,
+ repository
+ )
+ }
}
})
- get("/search"){
+ get("/search") {
val query = params.getOrElse("query", "").trim.toLowerCase
- val visibleRepositories = getVisibleRepositories(context.loginAccount, repositoryUserName = None, withoutPhysicalInfo = true)
+ val visibleRepositories =
+ getVisibleRepositories(context.loginAccount, repositoryUserName = None, withoutPhysicalInfo = true)
val repositories = visibleRepositories.filter { repository =>
repository.name.toLowerCase.indexOf(query) >= 0 || repository.owner.toLowerCase.indexOf(query) >= 0
}
- context.loginAccount.map { account =>
- gitbucket.core.search.html.repositories(query, repositories, Nil, getUserRepositories(account.userName, withoutPhysicalInfo = true))
- }.getOrElse {
- gitbucket.core.search.html.repositories(query, repositories, visibleRepositories, Nil)
- }
+ context.loginAccount
+ .map { account =>
+ gitbucket.core.search.html.repositories(
+ query,
+ repositories,
+ Nil,
+ getUserRepositories(account.userName, withoutPhysicalInfo = true)
+ )
+ }
+ .getOrElse {
+ gitbucket.core.search.html.repositories(query, repositories, visibleRepositories, Nil)
+ }
}
}
diff --git a/src/main/scala/gitbucket/core/controller/IssuesController.scala b/src/main/scala/gitbucket/core/controller/IssuesController.scala
index a23a0d3..8fb441a 100644
--- a/src/main/scala/gitbucket/core/controller/IssuesController.scala
+++ b/src/main/scala/gitbucket/core/controller/IssuesController.scala
@@ -11,23 +11,23 @@
import org.scalatra.forms._
import org.scalatra.{BadRequest, Ok}
-
-class IssuesController extends IssuesControllerBase
- with IssuesService
- with RepositoryService
- with AccountService
- with LabelsService
- with MilestonesService
- with ActivityService
- with HandleCommentService
- with IssueCreationService
- with ReadableUsersAuthenticator
- with ReferrerAuthenticator
- with WritableUsersAuthenticator
- with PullRequestService
- with WebHookIssueCommentService
- with CommitsService
- with PrioritiesService
+class IssuesController
+ extends IssuesControllerBase
+ with IssuesService
+ with RepositoryService
+ with AccountService
+ with LabelsService
+ with MilestonesService
+ with ActivityService
+ with HandleCommentService
+ with IssueCreationService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
+ with PullRequestService
+ with WebHookIssueCommentService
+ with CommitsService
+ with PrioritiesService
trait IssuesControllerBase extends ControllerBase {
self: IssuesService
@@ -45,40 +45,46 @@
with WebHookIssueCommentService
with PrioritiesService =>
- case class IssueCreateForm(title: String, content: Option[String],
- assignedUserName: Option[String], milestoneId: Option[Int], priorityId: Option[Int], labelNames: Option[String])
+ case class IssueCreateForm(
+ title: String,
+ content: Option[String],
+ assignedUserName: Option[String],
+ milestoneId: Option[Int],
+ priorityId: Option[Int],
+ labelNames: Option[String]
+ )
case class CommentForm(issueId: Int, content: String)
case class IssueStateForm(issueId: Int, content: Option[String])
val issueCreateForm = mapping(
- "title" -> trim(label("Title", text(required))),
- "content" -> trim(optional(text())),
- "assignedUserName" -> trim(optional(text())),
- "milestoneId" -> trim(optional(number())),
- "priorityId" -> trim(optional(number())),
- "labelNames" -> trim(optional(text()))
- )(IssueCreateForm.apply)
+ "title" -> trim(label("Title", text(required))),
+ "content" -> trim(optional(text())),
+ "assignedUserName" -> trim(optional(text())),
+ "milestoneId" -> trim(optional(number())),
+ "priorityId" -> trim(optional(number())),
+ "labelNames" -> trim(optional(text()))
+ )(IssueCreateForm.apply)
val issueTitleEditForm = mapping(
"title" -> trim(label("Title", text(required)))
- )(x => x)
+ )(x => x)
val issueEditForm = mapping(
"content" -> trim(optional(text()))
- )(x => x)
+ )(x => x)
val commentForm = mapping(
- "issueId" -> label("Issue Id", number()),
- "content" -> trim(label("Comment", text(required)))
- )(CommentForm.apply)
+ "issueId" -> label("Issue Id", number()),
+ "content" -> trim(label("Comment", text(required)))
+ )(CommentForm.apply)
val issueStateForm = mapping(
- "issueId" -> label("Issue Id", number()),
- "content" -> trim(optional(text()))
- )(IssueStateForm.apply)
+ "issueId" -> label("Issue Id", number()),
+ "content" -> trim(optional(text()))
+ )(IssueStateForm.apply)
get("/:owner/:repository/issues")(referrersOnly { repository =>
val q = request.getParameter("q")
- if(Option(q).exists(_.contains("is:pr"))){
+ if (Option(q).exists(_.contains("is:pr"))) {
redirect(s"/${repository.owner}/${repository.name}/pulls?q=${StringUtil.urlEncode(q)}")
} else {
searchIssues(repository)
@@ -86,45 +92,50 @@
})
get("/:owner/:repository/issues/:id")(referrersOnly { repository =>
- defining(repository.owner, repository.name, params("id")){ case (owner, name, issueId) =>
- getIssue(owner, name, issueId) map { issue =>
- if(issue.isPullRequest){
- redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
- } else {
- html.issue(
- issue,
- getComments(owner, name, issueId.toInt),
- getIssueLabels(owner, name, issueId.toInt),
- getAssignableUserNames(owner, name),
- getMilestonesWithIssueCount(owner, name),
- getPriorities(owner, name),
- getLabels(owner, name),
- isIssueEditable(repository),
- isIssueManageable(repository),
- repository)
- }
- } getOrElse NotFound()
+ defining(repository.owner, repository.name, params("id")) {
+ case (owner, name, issueId) =>
+ getIssue(owner, name, issueId) map {
+ issue =>
+ if (issue.isPullRequest) {
+ redirect(s"/${repository.owner}/${repository.name}/pull/${issueId}")
+ } else {
+ html.issue(
+ issue,
+ getComments(owner, name, issueId.toInt),
+ getIssueLabels(owner, name, issueId.toInt),
+ getAssignableUserNames(owner, name),
+ getMilestonesWithIssueCount(owner, name),
+ getPriorities(owner, name),
+ getLabels(owner, name),
+ isIssueEditable(repository),
+ isIssueManageable(repository),
+ repository
+ )
+ }
+ } getOrElse NotFound()
}
})
get("/:owner/:repository/issues/new")(readableUsersOnly { repository =>
- if(isIssueEditable(repository)){ // TODO Should this check is provided by authenticator?
- defining(repository.owner, repository.name){ case (owner, name) =>
- html.create(
- getAssignableUserNames(owner, name),
- getMilestones(owner, name),
- getPriorities(owner, name),
- getDefaultPriority(owner, name),
- getLabels(owner, name),
- isIssueManageable(repository),
- getContentTemplate(repository, "ISSUE_TEMPLATE"),
- repository)
+ if (isIssueEditable(repository)) { // TODO Should this check is provided by authenticator?
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ html.create(
+ getAssignableUserNames(owner, name),
+ getMilestones(owner, name),
+ getPriorities(owner, name),
+ getDefaultPriority(owner, name),
+ getLabels(owner, name),
+ isIssueManageable(repository),
+ getContentTemplate(repository, "ISSUE_TEMPLATE"),
+ repository
+ )
}
} else Unauthorized()
})
post("/:owner/:repository/issues/new", issueCreateForm)(readableUsersOnly { (form, repository) =>
- if(isIssueEditable(repository)){ // TODO Should this check is provided by authenticator?
+ if (isIssueEditable(repository)) { // TODO Should this check is provided by authenticator?
val issue = createIssue(
repository,
form.title,
@@ -133,133 +144,146 @@
form.milestoneId,
form.priorityId,
form.labelNames.toArray.flatMap(_.split(",")),
- context.loginAccount.get)
+ context.loginAccount.get
+ )
redirect(s"/${issue.userName}/${issue.repositoryName}/issues/${issue.issueId}")
} else Unauthorized()
})
ajaxPost("/:owner/:repository/issues/edit_title/:id", issueTitleEditForm)(readableUsersOnly { (title, repository) =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getIssue(owner, name, params("id")).map { issue =>
- if(isEditableContent(owner, name, issue.openedUserName)){
- // update issue
- updateIssue(owner, name, issue.issueId, title, issue.content)
- // extract references and create refer comment
- createReferComment(owner, name, issue.copy(title = title), title, context.loginAccount.get)
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getIssue(owner, name, params("id")).map { issue =>
+ if (isEditableContent(owner, name, issue.openedUserName)) {
+ // update issue
+ updateIssue(owner, name, issue.issueId, title, issue.content)
+ // extract references and create refer comment
+ createReferComment(owner, name, issue.copy(title = title), title, context.loginAccount.get)
- redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}")
- } else Unauthorized()
- } getOrElse NotFound()
+ redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}")
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
ajaxPost("/:owner/:repository/issues/edit/:id", issueEditForm)(readableUsersOnly { (content, repository) =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getIssue(owner, name, params("id")).map { issue =>
- if(isEditableContent(owner, name, issue.openedUserName)){
- // update issue
- updateIssue(owner, name, issue.issueId, issue.title, content)
- // extract references and create refer comment
- createReferComment(owner, name, issue, content.getOrElse(""), context.loginAccount.get)
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getIssue(owner, name, params("id")).map { issue =>
+ if (isEditableContent(owner, name, issue.openedUserName)) {
+ // update issue
+ updateIssue(owner, name, issue.issueId, issue.title, content)
+ // extract references and create refer comment
+ createReferComment(owner, name, issue, content.getOrElse(""), context.loginAccount.get)
- redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}")
- } else Unauthorized()
- } getOrElse NotFound()
+ redirect(s"/${owner}/${name}/issues/_data/${issue.issueId}")
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
post("/:owner/:repository/issue_comments/new", commentForm)(readableUsersOnly { (form, repository) =>
getIssue(repository.owner, repository.name, form.issueId.toString).flatMap { issue =>
- val actionOpt = params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
- handleComment(issue, Some(form.content), repository, actionOpt) map { case (issue, id) =>
- redirect(s"/${repository.owner}/${repository.name}/${
- if(issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}")
+ val actionOpt =
+ params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
+ handleComment(issue, Some(form.content), repository, actionOpt) map {
+ case (issue, id) =>
+ redirect(
+ s"/${repository.owner}/${repository.name}/${if (issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}"
+ )
}
} getOrElse NotFound()
})
post("/:owner/:repository/issue_comments/state", issueStateForm)(readableUsersOnly { (form, repository) =>
getIssue(repository.owner, repository.name, form.issueId.toString).flatMap { issue =>
- val actionOpt = params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
- handleComment(issue, form.content, repository, actionOpt) map { case (issue, id) =>
- redirect(s"/${repository.owner}/${repository.name}/${
- if(issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}")
+ val actionOpt =
+ params.get("action").filter(_ => isEditableContent(issue.userName, issue.repositoryName, issue.openedUserName))
+ handleComment(issue, form.content, repository, actionOpt) map {
+ case (issue, id) =>
+ redirect(
+ s"/${repository.owner}/${repository.name}/${if (issue.isPullRequest) "pull" else "issues"}/${form.issueId}#comment-${id}"
+ )
}
} getOrElse NotFound()
})
ajaxPost("/:owner/:repository/issue_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getComment(owner, name, params("id")).map { comment =>
- if(isEditableContent(owner, name, comment.commentedUserName)){
- updateComment(comment.issueId, comment.commentId, form.content)
- redirect(s"/${owner}/${name}/issue_comments/_data/${comment.commentId}")
- } else Unauthorized()
- } getOrElse NotFound()
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getComment(owner, name, params("id")).map { comment =>
+ if (isEditableContent(owner, name, comment.commentedUserName)) {
+ updateComment(comment.issueId, comment.commentId, form.content)
+ redirect(s"/${owner}/${name}/issue_comments/_data/${comment.commentId}")
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
ajaxPost("/:owner/:repository/issue_comments/delete/:id")(readableUsersOnly { repository =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getComment(owner, name, params("id")).map { comment =>
- if(isEditableContent(owner, name, comment.commentedUserName)){
- Ok(deleteComment(comment.issueId, comment.commentId))
- } else Unauthorized()
- } getOrElse NotFound()
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getComment(owner, name, params("id")).map { comment =>
+ if (isEditableContent(owner, name, comment.commentedUserName)) {
+ Ok(deleteComment(comment.issueId, comment.commentId))
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
ajaxGet("/:owner/:repository/issues/_data/:id")(readableUsersOnly { repository =>
- getIssue(repository.owner, repository.name, params("id")) map { x =>
- if(isEditableContent(x.userName, x.repositoryName, x.openedUserName)){
- params.get("dataType") collect {
- case t if t == "html" => html.editissue(x.content, x.issueId, repository)
- } getOrElse {
- contentType = formats("json")
- org.json4s.jackson.Serialization.write(
- Map(
- "title" -> x.title,
- "content" -> Markdown.toHtml(
- markdown = x.content getOrElse "No description given.",
- repository = repository,
- enableWikiLink = false,
- enableRefsLink = true,
- enableAnchor = true,
- enableLineBreaks = true,
- enableTaskList = true,
- hasWritePermission = true
+ getIssue(repository.owner, repository.name, params("id")) map {
+ x =>
+ if (isEditableContent(x.userName, x.repositoryName, x.openedUserName)) {
+ params.get("dataType") collect {
+ case t if t == "html" => html.editissue(x.content, x.issueId, repository)
+ } getOrElse {
+ contentType = formats("json")
+ org.json4s.jackson.Serialization.write(
+ Map(
+ "title" -> x.title,
+ "content" -> Markdown.toHtml(
+ markdown = x.content getOrElse "No description given.",
+ repository = repository,
+ enableWikiLink = false,
+ enableRefsLink = true,
+ enableAnchor = true,
+ enableLineBreaks = true,
+ enableTaskList = true,
+ hasWritePermission = true
+ )
)
)
- )
- }
- } else Unauthorized()
+ }
+ } else Unauthorized()
} getOrElse NotFound()
})
ajaxGet("/:owner/:repository/issue_comments/_data/:id")(readableUsersOnly { repository =>
- getComment(repository.owner, repository.name, params("id")) map { x =>
- if(isEditableContent(x.userName, x.repositoryName, x.commentedUserName)){
- params.get("dataType") collect {
- case t if t == "html" => html.editcomment(x.content, x.commentId, repository)
- } getOrElse {
- contentType = formats("json")
- org.json4s.jackson.Serialization.write(
- Map(
- "content" -> view.Markdown.toHtml(
- markdown = x.content,
- repository = repository,
- enableWikiLink = false,
- enableRefsLink = true,
- enableAnchor = true,
- enableLineBreaks = true,
- enableTaskList = true,
- hasWritePermission = true
+ getComment(repository.owner, repository.name, params("id")) map {
+ x =>
+ if (isEditableContent(x.userName, x.repositoryName, x.commentedUserName)) {
+ params.get("dataType") collect {
+ case t if t == "html" => html.editcomment(x.content, x.commentId, repository)
+ } getOrElse {
+ contentType = formats("json")
+ org.json4s.jackson.Serialization.write(
+ Map(
+ "content" -> view.Markdown.toHtml(
+ markdown = x.content,
+ repository = repository,
+ enableWikiLink = false,
+ enableRefsLink = true,
+ enableAnchor = true,
+ enableLineBreaks = true,
+ enableTaskList = true,
+ hasWritePermission = true
+ )
)
)
- )
- }
- } else Unauthorized()
+ }
+ } else Unauthorized()
} getOrElse NotFound()
})
@@ -270,21 +294,27 @@
})
ajaxPost("/:owner/:repository/issues/:id/label/new")(writableUsersOnly { repository =>
- defining(params("id").toInt){ issueId =>
+ defining(params("id").toInt) { issueId =>
registerIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt, true)
html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
})
ajaxPost("/:owner/:repository/issues/:id/label/delete")(writableUsersOnly { repository =>
- defining(params("id").toInt){ issueId =>
+ defining(params("id").toInt) { issueId =>
deleteIssueLabel(repository.owner, repository.name, issueId, params("labelId").toInt, true)
html.labellist(getIssueLabels(repository.owner, repository.name, issueId))
}
})
ajaxPost("/:owner/:repository/issues/:id/assign")(writableUsersOnly { repository =>
- updateAssignedUserName(repository.owner, repository.name, params("id").toInt, assignedUserName("assignedUserName"), true)
+ updateAssignedUserName(
+ repository.owner,
+ repository.name,
+ params("id").toInt,
+ assignedUserName("assignedUserName"),
+ true
+ )
Ok("updated")
})
@@ -292,9 +322,11 @@
updateMilestoneId(repository.owner, repository.name, params("id").toInt, milestoneId("milestoneId"), true)
milestoneId("milestoneId").map { milestoneId =>
getMilestonesWithIssueCount(repository.owner, repository.name)
- .find(_._1.milestoneId == milestoneId).map { case (_, openCount, closeCount) =>
- gitbucket.core.issues.milestones.html.progress(openCount + closeCount, closeCount)
- } getOrElse NotFound()
+ .find(_._1.milestoneId == milestoneId)
+ .map {
+ case (_, openCount, closeCount) =>
+ gitbucket.core.issues.milestones.html.progress(openCount + closeCount, closeCount)
+ } getOrElse NotFound()
} getOrElse Ok()
})
@@ -305,25 +337,28 @@
})
post("/:owner/:repository/issues/batchedit/state")(writableUsersOnly { repository =>
- defining(params.get("value")){ action =>
- action match {
- case Some("open") => executeBatch(repository) { issueId =>
- getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
- handleComment(issue, None, repository, Some("reopen"))
- }
+ defining(params.get("value")) {
+ action =>
+ action match {
+ case Some("open") =>
+ executeBatch(repository) { issueId =>
+ getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
+ handleComment(issue, None, repository, Some("reopen"))
+ }
+ }
+ case Some("close") =>
+ executeBatch(repository) { issueId =>
+ getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
+ handleComment(issue, None, repository, Some("close"))
+ }
+ }
+ case _ => BadRequest()
}
- case Some("close") => executeBatch(repository) { issueId =>
- getIssue(repository.owner, repository.name, issueId.toString).foreach { issue =>
- handleComment(issue, None, repository, Some("close"))
- }
- }
- case _ => BadRequest()
- }
}
})
post("/:owner/:repository/issues/batchedit/label")(writableUsersOnly { repository =>
- params("value").toIntOpt.map{ labelId =>
+ params("value").toIntOpt.map { labelId =>
executeBatch(repository) { issueId =>
getIssueLabel(repository.owner, repository.name, issueId, labelId) getOrElse {
registerIssueLabel(repository.owner, repository.name, issueId, labelId, true)
@@ -333,7 +368,7 @@
})
post("/:owner/:repository/issues/batchedit/assign")(writableUsersOnly { repository =>
- defining(assignedUserName("value")){ value =>
+ defining(assignedUserName("value")) { value =>
executeBatch(repository) {
updateAssignedUserName(repository.owner, repository.name, _, value, true)
}
@@ -341,7 +376,7 @@
})
post("/:owner/:repository/issues/batchedit/milestone")(writableUsersOnly { repository =>
- defining(milestoneId("value")){ value =>
+ defining(milestoneId("value")) { value =>
executeBatch(repository) {
updateMilestoneId(repository.owner, repository.name, _, value, true)
}
@@ -349,7 +384,7 @@
})
post("/:owner/:repository/issues/batchedit/priority")(writableUsersOnly { repository =>
- defining(priorityId("value")){ value =>
+ defining(priorityId("value")) { value =>
executeBatch(repository) {
updatePriorityId(repository.owner, repository.name, _, value, true)
}
@@ -358,7 +393,7 @@
get("/:owner/:repository/_attached/:file")(referrersOnly { repository =>
(Directory.getAttachedDir(repository.owner, repository.name) match {
- case dir if(dir.exists && dir.isDirectory) =>
+ case dir if (dir.exists && dir.isDirectory) =>
dir.listFiles.find(_.getName.startsWith(params("file") + ".")).map { file =>
response.setHeader("Content-Disposition", f"""inline; filename=${file.getName}""")
RawData(FileUtil.getMimeType(file.getName), file)
@@ -372,7 +407,7 @@
val priorityId: String => Option[Int] = (key: String) => params.get(key).flatMap(_.toIntOpt)
private def executeBatch(repository: RepositoryService.RepositoryInfo)(execute: Int => Unit) = {
- params("checked").split(',') map(_.toInt) foreach execute
+ params("checked").split(',') map (_.toInt) foreach execute
params("from") match {
case "issues" => redirect(s"/${repository.owner}/${repository.name}/issues")
case "pulls" => redirect(s"/${repository.owner}/${repository.name}/pulls")
@@ -380,13 +415,14 @@
}
private def searchIssues(repository: RepositoryService.RepositoryInfo) = {
- defining(repository.owner, repository.name){ case (owner, repoName) =>
- val page = IssueSearchCondition.page(request)
+ defining(repository.owner, repository.name) {
+ case (owner, repoName) =>
+ val page = IssueSearchCondition.page(request)
- // retrieve search condition
- val condition = IssueSearchCondition(request)
+ // retrieve search condition
+ val condition = IssueSearchCondition(request)
- html.list(
+ html.list(
"issues",
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
page,
@@ -394,19 +430,22 @@
getMilestones(owner, repoName),
getPriorities(owner, repoName),
getLabels(owner, repoName),
- countIssue(condition.copy(state = "open" ), false, owner -> repoName),
+ countIssue(condition.copy(state = "open"), false, owner -> repoName),
countIssue(condition.copy(state = "closed"), false, owner -> repoName),
condition,
repository,
isIssueEditable(repository),
- isIssueManageable(repository))
+ isIssueManageable(repository)
+ )
}
}
/**
* Tests whether an issue or a comment is editable by a logged-in user.
*/
- private def isEditableContent(owner: String, repository: String, author: String)(implicit context: Context): Boolean = {
+ private def isEditableContent(owner: String, repository: String, author: String)(
+ implicit context: Context
+ ): Boolean = {
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
}
}
diff --git a/src/main/scala/gitbucket/core/controller/LabelsController.scala b/src/main/scala/gitbucket/core/controller/LabelsController.scala
index 9ab083e..224a571 100644
--- a/src/main/scala/gitbucket/core/controller/LabelsController.scala
+++ b/src/main/scala/gitbucket/core/controller/LabelsController.scala
@@ -1,7 +1,14 @@
package gitbucket.core.controller
import gitbucket.core.issues.labels.html
-import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService, MilestonesService, PrioritiesService}
+import gitbucket.core.service.{
+ RepositoryService,
+ AccountService,
+ IssuesService,
+ LabelsService,
+ MilestonesService,
+ PrioritiesService
+}
import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator}
import gitbucket.core.util.Implicits._
import gitbucket.core.util.SyntaxSugars._
@@ -9,29 +16,38 @@
import org.scalatra.i18n.Messages
import org.scalatra.Ok
-class LabelsController extends LabelsControllerBase
- with IssuesService with RepositoryService with AccountService
- with LabelsService with PrioritiesService with MilestonesService
- with ReferrerAuthenticator with WritableUsersAuthenticator
+class LabelsController
+ extends LabelsControllerBase
+ with IssuesService
+ with RepositoryService
+ with AccountService
+ with LabelsService
+ with PrioritiesService
+ with MilestonesService
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
trait LabelsControllerBase extends ControllerBase {
- self: LabelsService with IssuesService with RepositoryService
- with ReferrerAuthenticator with WritableUsersAuthenticator =>
+ self: LabelsService
+ with IssuesService
+ with RepositoryService
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator =>
case class LabelForm(labelName: String, color: String)
val labelForm = mapping(
- "labelName" -> trim(label("Label name", text(required, labelName, uniqueLabelName, maxlength(100)))),
- "labelColor" -> trim(label("Color", text(required, color)))
+ "labelName" -> trim(label("Label name", text(required, labelName, uniqueLabelName, maxlength(100)))),
+ "labelColor" -> trim(label("Color", text(required, color)))
)(LabelForm.apply)
-
get("/:owner/:repository/issues/labels")(referrersOnly { repository =>
html.list(
getLabels(repository.owner, repository.name),
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxGet("/:owner/:repository/issues/labels/new")(writableUsersOnly { repository =>
@@ -45,7 +61,8 @@
// TODO futility
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxGet("/:owner/:repository/issues/labels/:labelId/edit")(writableUsersOnly { repository =>
@@ -61,7 +78,8 @@
// TODO futility
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxPost("/:owner/:repository/issues/labels/:labelId/delete")(writableUsersOnly { repository =>
@@ -72,26 +90,34 @@
/**
* Constraint for the identifier such as user name, repository name or page name.
*/
- private def labelName: Constraint = new Constraint(){
+ private def labelName: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(value.contains(',')){
+ if (value.contains(',')) {
Some(s"${name} contains invalid character.")
- } else if(value.startsWith("_") || value.startsWith("-")){
+ } else if (value.startsWith("_") || value.startsWith("-")) {
Some(s"${name} starts with invalid character.")
} else {
None
}
}
- private def uniqueLabelName: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] = {
- val owner = params.value("owner")
+ private def uniqueLabelName: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] = {
+ val owner = params.value("owner")
val repository = params.value("repository")
- params.optionValue("labelId").map { labelId =>
- getLabel(owner, repository, value).filter(_.labelId != labelId.toInt).map(_ => "Name has already been taken.")
- }.getOrElse {
- getLabel(owner, repository, value).map(_ => "Name has already been taken.")
- }
+ params
+ .optionValue("labelId")
+ .map { labelId =>
+ getLabel(owner, repository, value).filter(_.labelId != labelId.toInt).map(_ => "Name has already been taken.")
+ }
+ .getOrElse {
+ getLabel(owner, repository, value).map(_ => "Name has already been taken.")
+ }
}
}
diff --git a/src/main/scala/gitbucket/core/controller/MilestonesController.scala b/src/main/scala/gitbucket/core/controller/MilestonesController.scala
index b373b1b..3f2f593 100644
--- a/src/main/scala/gitbucket/core/controller/MilestonesController.scala
+++ b/src/main/scala/gitbucket/core/controller/MilestonesController.scala
@@ -6,20 +6,23 @@
import gitbucket.core.util.Implicits._
import org.scalatra.forms._
-class MilestonesController extends MilestonesControllerBase
- with MilestonesService with RepositoryService with AccountService
- with ReferrerAuthenticator with WritableUsersAuthenticator
+class MilestonesController
+ extends MilestonesControllerBase
+ with MilestonesService
+ with RepositoryService
+ with AccountService
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
trait MilestonesControllerBase extends ControllerBase {
- self: MilestonesService with RepositoryService
- with ReferrerAuthenticator with WritableUsersAuthenticator =>
+ self: MilestonesService with RepositoryService with ReferrerAuthenticator with WritableUsersAuthenticator =>
case class MilestoneForm(title: String, description: Option[String], dueDate: Option[java.util.Date])
val milestoneForm = mapping(
- "title" -> trim(label("Title", text(required, maxlength(100)))),
+ "title" -> trim(label("Title", text(required, maxlength(100)))),
"description" -> trim(label("Description", optional(text()))),
- "dueDate" -> trim(label("Due Date", optional(date())))
+ "dueDate" -> trim(label("Due Date", optional(date())))
)(MilestoneForm.apply)
get("/:owner/:repository/issues/milestones")(referrersOnly { repository =>
@@ -27,7 +30,8 @@
params.getOrElse("state", "open"),
getMilestonesWithIssueCount(repository.owner, repository.name),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
get("/:owner/:repository/issues/milestones/new")(writableUsersOnly {
@@ -40,22 +44,23 @@
})
get("/:owner/:repository/issues/milestones/:milestoneId/edit")(writableUsersOnly { repository =>
- params("milestoneId").toIntOpt.map{ milestoneId =>
+ params("milestoneId").toIntOpt.map { milestoneId =>
html.edit(getMilestone(repository.owner, repository.name, milestoneId), repository)
} getOrElse NotFound()
})
- post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(writableUsersOnly { (form, repository) =>
- params("milestoneId").toIntOpt.flatMap{ milestoneId =>
- getMilestone(repository.owner, repository.name, milestoneId).map { milestone =>
- updateMilestone(milestone.copy(title = form.title, description = form.description, dueDate = form.dueDate))
- redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
- }
- } getOrElse NotFound()
+ post("/:owner/:repository/issues/milestones/:milestoneId/edit", milestoneForm)(writableUsersOnly {
+ (form, repository) =>
+ params("milestoneId").toIntOpt.flatMap { milestoneId =>
+ getMilestone(repository.owner, repository.name, milestoneId).map { milestone =>
+ updateMilestone(milestone.copy(title = form.title, description = form.description, dueDate = form.dueDate))
+ redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
+ }
+ } getOrElse NotFound()
})
get("/:owner/:repository/issues/milestones/:milestoneId/close")(writableUsersOnly { repository =>
- params("milestoneId").toIntOpt.flatMap{ milestoneId =>
+ params("milestoneId").toIntOpt.flatMap { milestoneId =>
getMilestone(repository.owner, repository.name, milestoneId).map { milestone =>
closeMilestone(milestone)
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
@@ -64,7 +69,7 @@
})
get("/:owner/:repository/issues/milestones/:milestoneId/open")(writableUsersOnly { repository =>
- params("milestoneId").toIntOpt.flatMap{ milestoneId =>
+ params("milestoneId").toIntOpt.flatMap { milestoneId =>
getMilestone(repository.owner, repository.name, milestoneId).map { milestone =>
openMilestone(milestone)
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
@@ -73,7 +78,7 @@
})
get("/:owner/:repository/issues/milestones/:milestoneId/delete")(writableUsersOnly { repository =>
- params("milestoneId").toIntOpt.flatMap{ milestoneId =>
+ params("milestoneId").toIntOpt.flatMap { milestoneId =>
getMilestone(repository.owner, repository.name, milestoneId).map { milestone =>
deleteMilestone(repository.owner, repository.name, milestone.milestoneId)
redirect(s"/${repository.owner}/${repository.name}/issues/milestones")
diff --git a/src/main/scala/gitbucket/core/controller/PreProcessController.scala b/src/main/scala/gitbucket/core/controller/PreProcessController.scala
index 68ce0e9..766bbb2 100644
--- a/src/main/scala/gitbucket/core/controller/PreProcessController.scala
+++ b/src/main/scala/gitbucket/core/controller/PreProcessController.scala
@@ -28,13 +28,12 @@
* But if it's not allowed, demands authentication except some paths.
*/
get(!context.settings.allowAnonymousAccess, context.loginAccount.isEmpty) {
- if(!context.currentPath.startsWith("/assets") && !context.currentPath.startsWith("/signin") &&
- !context.currentPath.startsWith("/register") && !context.currentPath.endsWith("/info/refs")) {
+ if (!context.currentPath.startsWith("/assets") && !context.currentPath.startsWith("/signin") &&
+ !context.currentPath.startsWith("/register") && !context.currentPath.endsWith("/info/refs")) {
Unauthorized()
} else {
pass()
}
}
-
}
diff --git a/src/main/scala/gitbucket/core/controller/PrioritiesController.scala b/src/main/scala/gitbucket/core/controller/PrioritiesController.scala
index 2141ffe..f34ed63 100644
--- a/src/main/scala/gitbucket/core/controller/PrioritiesController.scala
+++ b/src/main/scala/gitbucket/core/controller/PrioritiesController.scala
@@ -1,7 +1,14 @@
package gitbucket.core.controller
import gitbucket.core.issues.priorities.html
-import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService, MilestonesService, PrioritiesService}
+import gitbucket.core.service.{
+ RepositoryService,
+ AccountService,
+ IssuesService,
+ LabelsService,
+ MilestonesService,
+ PrioritiesService
+}
import gitbucket.core.util.{ReferrerAuthenticator, WritableUsersAuthenticator}
import gitbucket.core.util.Implicits._
import gitbucket.core.util.SyntaxSugars._
@@ -9,30 +16,39 @@
import org.scalatra.i18n.Messages
import org.scalatra.Ok
-class PrioritiesController extends PrioritiesControllerBase
- with IssuesService with RepositoryService with AccountService
- with LabelsService with PrioritiesService with MilestonesService
- with ReferrerAuthenticator with WritableUsersAuthenticator
+class PrioritiesController
+ extends PrioritiesControllerBase
+ with IssuesService
+ with RepositoryService
+ with AccountService
+ with LabelsService
+ with PrioritiesService
+ with MilestonesService
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
trait PrioritiesControllerBase extends ControllerBase {
- self: PrioritiesService with IssuesService with RepositoryService
- with ReferrerAuthenticator with WritableUsersAuthenticator =>
+ self: PrioritiesService
+ with IssuesService
+ with RepositoryService
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator =>
case class PriorityForm(priorityName: String, description: Option[String], color: String)
val priorityForm = mapping(
- "priorityName" -> trim(label("Priority name", text(required, priorityName, uniquePriorityName, maxlength(100)))),
- "description" -> trim(label("Description", optional(text(maxlength(255))))),
+ "priorityName" -> trim(label("Priority name", text(required, priorityName, uniquePriorityName, maxlength(100)))),
+ "description" -> trim(label("Description", optional(text(maxlength(255))))),
"priorityColor" -> trim(label("Color", text(required, color)))
)(PriorityForm.apply)
-
get("/:owner/:repository/issues/priorities")(referrersOnly { repository =>
html.list(
getPriorities(repository.owner, repository.name),
countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxGet("/:owner/:repository/issues/priorities/new")(writableUsersOnly { repository =>
@@ -40,12 +56,14 @@
})
ajaxPost("/:owner/:repository/issues/priorities/new", priorityForm)(writableUsersOnly { (form, repository) =>
- val priorityId = createPriority(repository.owner, repository.name, form.priorityName, form.description, form.color.substring(1))
+ val priorityId =
+ createPriority(repository.owner, repository.name, form.priorityName, form.description, form.color.substring(1))
html.priority(
getPriority(repository.owner, repository.name, priorityId).get,
countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxGet("/:owner/:repository/issues/priorities/:priorityId/edit")(writableUsersOnly { repository =>
@@ -54,21 +72,34 @@
} getOrElse NotFound()
})
- ajaxPost("/:owner/:repository/issues/priorities/:priorityId/edit", priorityForm)(writableUsersOnly { (form, repository) =>
- updatePriority(repository.owner, repository.name, params("priorityId").toInt, form.priorityName, form.description, form.color.substring(1))
- html.priority(
- getPriority(repository.owner, repository.name, params("priorityId").toInt).get,
- countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
- repository,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ ajaxPost("/:owner/:repository/issues/priorities/:priorityId/edit", priorityForm)(writableUsersOnly {
+ (form, repository) =>
+ updatePriority(
+ repository.owner,
+ repository.name,
+ params("priorityId").toInt,
+ form.priorityName,
+ form.description,
+ form.color.substring(1)
+ )
+ html.priority(
+ getPriority(repository.owner, repository.name, params("priorityId").toInt).get,
+ countIssueGroupByPriorities(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
+ repository,
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
ajaxPost("/:owner/:repository/issues/priorities/reorder")(writableUsersOnly { (repository) =>
- reorderPriorities(repository.owner, repository.name, params("order")
- .split(",")
- .map(id => id.toInt)
- .zipWithIndex
- .toMap)
+ reorderPriorities(
+ repository.owner,
+ repository.name,
+ params("order")
+ .split(",")
+ .map(id => id.toInt)
+ .zipWithIndex
+ .toMap
+ )
Ok()
})
@@ -88,26 +119,36 @@
/**
* Constraint for the identifier such as user name, repository name or page name.
*/
- private def priorityName: Constraint = new Constraint(){
+ private def priorityName: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(value.contains(',')){
+ if (value.contains(',')) {
Some(s"${name} contains invalid character.")
- } else if(value.startsWith("_") || value.startsWith("-")){
+ } else if (value.startsWith("_") || value.startsWith("-")) {
Some(s"${name} starts with invalid character.")
} else {
None
}
}
- private def uniquePriorityName: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] = {
- val owner = params.value("owner")
+ private def uniquePriorityName: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] = {
+ val owner = params.value("owner")
val repository = params.value("repository")
- params.optionValue("priorityId").map { priorityId =>
- getPriority(owner, repository, value).filter(_.priorityId != priorityId.toInt).map(_ => "Name has already been taken.")
- }.getOrElse {
- getPriority(owner, repository, value).map(_ => "Name has already been taken.")
- }
+ params
+ .optionValue("priorityId")
+ .map { priorityId =>
+ getPriority(owner, repository, value)
+ .filter(_.priorityId != priorityId.toInt)
+ .map(_ => "Name has already been taken.")
+ }
+ .getOrElse {
+ getPriority(owner, repository, value).map(_ => "Name has already been taken.")
+ }
}
}
}
diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
index a4bef94..8fea200 100644
--- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
+++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala
@@ -21,38 +21,61 @@
import scala.collection.JavaConverters._
-
-class PullRequestsController extends PullRequestsControllerBase
- with RepositoryService with AccountService with IssuesService with PullRequestService with MilestonesService with LabelsService
- with CommitsService with ActivityService with WebHookPullRequestService
- with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
- with CommitStatusService with MergeService with ProtectedBranchService with PrioritiesService
-
+class PullRequestsController
+ extends PullRequestsControllerBase
+ with RepositoryService
+ with AccountService
+ with IssuesService
+ with PullRequestService
+ with MilestonesService
+ with LabelsService
+ with CommitsService
+ with ActivityService
+ with WebHookPullRequestService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
+ with CommitStatusService
+ with MergeService
+ with ProtectedBranchService
+ with PrioritiesService
trait PullRequestsControllerBase extends ControllerBase {
- self: RepositoryService with AccountService with IssuesService with MilestonesService with LabelsService
- with CommitsService with ActivityService with PullRequestService with WebHookPullRequestService
- with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator
- with CommitStatusService with MergeService with ProtectedBranchService with PrioritiesService =>
+ self: RepositoryService
+ with AccountService
+ with IssuesService
+ with MilestonesService
+ with LabelsService
+ with CommitsService
+ with ActivityService
+ with PullRequestService
+ with WebHookPullRequestService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
+ with CommitStatusService
+ with MergeService
+ with ProtectedBranchService
+ with PrioritiesService =>
val pullRequestForm = mapping(
- "title" -> trim(label("Title" , text(required, maxlength(100)))),
- "content" -> trim(label("Content", optional(text()))),
- "targetUserName" -> trim(text(required, maxlength(100))),
- "targetBranch" -> trim(text(required, maxlength(100))),
- "requestUserName" -> trim(text(required, maxlength(100))),
+ "title" -> trim(label("Title", text(required, maxlength(100)))),
+ "content" -> trim(label("Content", optional(text()))),
+ "targetUserName" -> trim(text(required, maxlength(100))),
+ "targetBranch" -> trim(text(required, maxlength(100))),
+ "requestUserName" -> trim(text(required, maxlength(100))),
"requestRepositoryName" -> trim(text(required, maxlength(100))),
- "requestBranch" -> trim(text(required, maxlength(100))),
- "commitIdFrom" -> trim(text(required, maxlength(40))),
- "commitIdTo" -> trim(text(required, maxlength(40))),
- "assignedUserName" -> trim(optional(text())),
- "milestoneId" -> trim(optional(number())),
- "priorityId" -> trim(optional(number())),
- "labelNames" -> trim(optional(text()))
+ "requestBranch" -> trim(text(required, maxlength(100))),
+ "commitIdFrom" -> trim(text(required, maxlength(40))),
+ "commitIdTo" -> trim(text(required, maxlength(40))),
+ "assignedUserName" -> trim(optional(text())),
+ "milestoneId" -> trim(optional(number())),
+ "priorityId" -> trim(optional(number())),
+ "labelNames" -> trim(optional(text()))
)(PullRequestForm.apply)
val mergeForm = mapping(
- "message" -> trim(label("Message", text(required))),
+ "message" -> trim(label("Message", text(required))),
"strategy" -> trim(label("Strategy", text(required)))
)(MergeForm.apply)
@@ -76,7 +99,7 @@
get("/:owner/:repository/pulls")(referrersOnly { repository =>
val q = request.getParameter("q")
- if(Option(q).exists(_.contains("is:issue"))){
+ if (Option(q).exists(_.contains("is:issue"))) {
redirect(s"/${repository.owner}/${repository.name}/issues?q=" + StringUtil.urlEncode(q))
} else {
searchPullRequests(None, repository)
@@ -84,66 +107,90 @@
})
get("/:owner/:repository/pull/:id")(referrersOnly { repository =>
- params("id").toIntOpt.flatMap{ issueId =>
- val owner = repository.owner
- val name = repository.name
- getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
- using(Git.open(getRepositoryDir(owner, name))){ git =>
- val (commits, diffs) =
- getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo)
- html.pullreq(
- issue, pullreq,
- (commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId))
- .sortWith((a, b) => a.registeredDate before b.registeredDate),
- getIssueLabels(owner, name, issueId),
- getAssignableUserNames(owner, name),
- getMilestonesWithIssueCount(owner, name),
- getPriorities(owner, name),
- getLabels(owner, name),
- commits,
- diffs,
- isEditable(repository),
- isManageable(repository),
- hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount),
- repository,
- getRepository(pullreq.requestUserName, pullreq.requestRepositoryName),
- flash.toMap.map(f => f._1 -> f._2.toString))
+ params("id").toIntOpt.flatMap {
+ issueId =>
+ val owner = repository.owner
+ val name = repository.name
+ getPullRequest(owner, name, issueId) map {
+ case (issue, pullreq) =>
+ using(Git.open(getRepositoryDir(owner, name))) {
+ git =>
+ val (commits, diffs) =
+ getRequestCompareInfo(owner, name, pullreq.commitIdFrom, owner, name, pullreq.commitIdTo)
+ html.pullreq(
+ issue,
+ pullreq,
+ (commits.flatten
+ .map(commit => getCommitComments(owner, name, commit.id, true))
+ .flatten
+ .toList ::: getComments(owner, name, issueId))
+ .sortWith((a, b) => a.registeredDate before b.registeredDate),
+ getIssueLabels(owner, name, issueId),
+ getAssignableUserNames(owner, name),
+ getMilestonesWithIssueCount(owner, name),
+ getPriorities(owner, name),
+ getLabels(owner, name),
+ commits,
+ diffs,
+ isEditable(repository),
+ isManageable(repository),
+ hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount),
+ repository,
+ getRepository(pullreq.requestUserName, pullreq.requestRepositoryName),
+ flash.toMap.map(f => f._1 -> f._2.toString)
+ )
+ }
}
- }
} getOrElse NotFound()
})
ajaxGet("/:owner/:repository/pull/:id/mergeguide")(referrersOnly { repository =>
- params("id").toIntOpt.flatMap{ issueId =>
- val owner = repository.owner
- val name = repository.name
- getPullRequest(owner, name, issueId) map { case(issue, pullreq) =>
- val conflictMessage = LockUtil.lock(s"${owner}/${name}"){
- checkConflict(owner, name, pullreq.branch, issueId)
+ params("id").toIntOpt.flatMap {
+ issueId =>
+ val owner = repository.owner
+ val name = repository.name
+ getPullRequest(owner, name, issueId) map {
+ case (issue, pullreq) =>
+ val conflictMessage = LockUtil.lock(s"${owner}/${name}") {
+ checkConflict(owner, name, pullreq.branch, issueId)
+ }
+ val hasMergePermission = hasDeveloperRole(owner, name, context.loginAccount)
+ val branchProtection = getProtectedBranchInfo(owner, name, pullreq.branch)
+ val mergeStatus = PullRequestService.MergeStatus(
+ conflictMessage = conflictMessage,
+ commitStatues = getCommitStatues(owner, name, pullreq.commitIdTo),
+ branchProtection = branchProtection,
+ branchIsOutOfDate = JGitUtil.getShaByRef(owner, name, pullreq.branch) != Some(pullreq.commitIdFrom),
+ needStatusCheck = context.loginAccount
+ .map { u =>
+ branchProtection.needStatusCheck(u.userName)
+ }
+ .getOrElse(true),
+ hasUpdatePermission = hasDeveloperRole(
+ pullreq.requestUserName,
+ pullreq.requestRepositoryName,
+ context.loginAccount
+ ) &&
+ context.loginAccount
+ .map { u =>
+ !getProtectedBranchInfo(
+ pullreq.requestUserName,
+ pullreq.requestRepositoryName,
+ pullreq.requestBranch
+ ).needStatusCheck(u.userName)
+ }
+ .getOrElse(false),
+ hasMergePermission = hasMergePermission,
+ commitIdTo = pullreq.commitIdTo
+ )
+ html.mergeguide(
+ mergeStatus,
+ issue,
+ pullreq,
+ repository,
+ getRepository(pullreq.requestUserName, pullreq.requestRepositoryName).get
+ )
}
- val hasMergePermission = hasDeveloperRole(owner, name, context.loginAccount)
- val branchProtection = getProtectedBranchInfo(owner, name, pullreq.branch)
- val mergeStatus = PullRequestService.MergeStatus(
- conflictMessage = conflictMessage,
- commitStatues = getCommitStatues(owner, name, pullreq.commitIdTo),
- branchProtection = branchProtection,
- branchIsOutOfDate = JGitUtil.getShaByRef(owner, name, pullreq.branch) != Some(pullreq.commitIdFrom),
- needStatusCheck = context.loginAccount.map{ u =>
- branchProtection.needStatusCheck(u.userName)
- }.getOrElse(true),
- hasUpdatePermission = hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount) &&
- context.loginAccount.map{ u =>
- !getProtectedBranchInfo(pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.requestBranch).needStatusCheck(u.userName)
- }.getOrElse(false),
- hasMergePermission = hasMergePermission,
- commitIdTo = pullreq.commitIdTo)
- html.mergeguide(
- mergeStatus,
- issue,
- pullreq,
- repository,
- getRepository(pullreq.requestUserName, pullreq.requestRepositoryName).get)
- }
} getOrElse NotFound()
})
@@ -153,21 +200,28 @@
loginAccount <- context.loginAccount
(issue, pullreq) <- getPullRequest(baseRepository.owner, baseRepository.name, issueId)
owner = pullreq.requestUserName
- name = pullreq.requestRepositoryName
+ name = pullreq.requestRepositoryName
if hasDeveloperRole(owner, name, context.loginAccount)
} yield {
val repository = getRepository(owner, name).get
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
- if(branchProtection.enabled){
+ if (branchProtection.enabled) {
flash += "error" -> s"branch ${pullreq.requestBranch} is protected."
} else {
- if(repository.repository.defaultBranch != pullreq.requestBranch){
+ if (repository.repository.defaultBranch != pullreq.requestBranch) {
val userName = context.loginAccount.get.userName
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
git.branchDelete().setForce(true).setBranchNames(pullreq.requestBranch).call()
recordDeleteBranchActivity(repository.owner, repository.name, userName, pullreq.requestBranch)
}
- createComment(baseRepository.owner, baseRepository.name, userName, issueId, pullreq.requestBranch, "delete_branch")
+ createComment(
+ baseRepository.owner,
+ baseRepository.name,
+ userName,
+ issueId,
+ pullreq.requestBranch,
+ "delete_branch"
+ )
} else {
flash += "error" -> s"""Can't delete the default branch "${pullreq.requestBranch}"."""
}
@@ -182,59 +236,92 @@
loginAccount <- context.loginAccount
(issue, pullreq) <- getPullRequest(baseRepository.owner, baseRepository.name, issueId)
owner = pullreq.requestUserName
- name = pullreq.requestRepositoryName
+ name = pullreq.requestRepositoryName
if hasDeveloperRole(owner, name, context.loginAccount)
} yield {
val repository = getRepository(owner, name).get
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
- if(branchProtection.needStatusCheck(loginAccount.userName)){
+ if (branchProtection.needStatusCheck(loginAccount.userName)) {
flash += "error" -> s"branch ${pullreq.requestBranch} is protected need status check."
} else {
- LockUtil.lock(s"${owner}/${name}"){
- val alias = if(pullreq.repositoryName == pullreq.requestRepositoryName && pullreq.userName == pullreq.requestUserName){
- pullreq.branch
- } else {
- s"${pullreq.userName}:${pullreq.branch}"
- }
- val existIds = using(Git.open(Directory.getRepositoryDir(owner, name))) { git => JGitUtil.getAllCommitIds(git) }.toSet
- pullRemote(owner, name, pullreq.requestBranch, pullreq.userName, pullreq.repositoryName, pullreq.branch, loginAccount,
- s"Merge branch '${alias}' into ${pullreq.requestBranch}") match {
+ LockUtil.lock(s"${owner}/${name}") {
+ val alias =
+ if (pullreq.repositoryName == pullreq.requestRepositoryName && pullreq.userName == pullreq.requestUserName) {
+ pullreq.branch
+ } else {
+ s"${pullreq.userName}:${pullreq.branch}"
+ }
+ val existIds = using(Git.open(Directory.getRepositoryDir(owner, name))) { git =>
+ JGitUtil.getAllCommitIds(git)
+ }.toSet
+ pullRemote(
+ owner,
+ name,
+ pullreq.requestBranch,
+ pullreq.userName,
+ pullreq.repositoryName,
+ pullreq.branch,
+ loginAccount,
+ s"Merge branch '${alias}' into ${pullreq.requestBranch}"
+ ) match {
case None => // conflict
flash += "error" -> s"Can't automatic merging branch '${alias}' into ${pullreq.requestBranch}."
case Some(oldId) =>
// update pull request
updatePullRequests(owner, name, pullreq.requestBranch)
- using(Git.open(Directory.getRepositoryDir(owner, name))) { git =>
- // after update branch
- val newCommitId = git.getRepository.resolve(s"refs/heads/${pullreq.requestBranch}")
- val commits = git.log.addRange(oldId, newCommitId).call.iterator.asScala.map(c => new JGitUtil.CommitInfo(c)).toList
+ using(Git.open(Directory.getRepositoryDir(owner, name))) {
+ git =>
+ // after update branch
+ val newCommitId = git.getRepository.resolve(s"refs/heads/${pullreq.requestBranch}")
+ val commits = git.log
+ .addRange(oldId, newCommitId)
+ .call
+ .iterator
+ .asScala
+ .map(c => new JGitUtil.CommitInfo(c))
+ .toList
- commits.foreach { commit =>
- if(!existIds.contains(commit.id)){
- createIssueComment(owner, name, commit)
+ commits.foreach { commit =>
+ if (!existIds.contains(commit.id)) {
+ createIssueComment(owner, name, commit)
+ }
}
- }
- // record activity
- recordPushActivity(owner, name, loginAccount.userName, pullreq.branch, commits)
+ // record activity
+ recordPushActivity(owner, name, loginAccount.userName, pullreq.branch, commits)
- // close issue by commit message
- if(pullreq.requestBranch == repository.repository.defaultBranch){
- commits.map { commit =>
- closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
+ // close issue by commit message
+ if (pullreq.requestBranch == repository.repository.defaultBranch) {
+ commits.map { commit =>
+ closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
+ }
}
- }
- // call web hook
- callPullRequestWebHookByRequestBranch("synchronize", repository, pullreq.requestBranch, baseUrl, loginAccount)
- callWebHookOf(owner, name, WebHook.Push) {
- for {
- ownerAccount <- getAccountByUserName(owner)
- } yield {
- WebHookService.WebHookPushPayload(git, loginAccount, pullreq.requestBranch, repository, commits, ownerAccount, oldId = oldId, newId = newCommitId)
+ // call web hook
+ callPullRequestWebHookByRequestBranch(
+ "synchronize",
+ repository,
+ pullreq.requestBranch,
+ baseUrl,
+ loginAccount
+ )
+ callWebHookOf(owner, name, WebHook.Push) {
+ for {
+ ownerAccount <- getAccountByUserName(owner)
+ } yield {
+ WebHookService.WebHookPushPayload(
+ git,
+ loginAccount,
+ pullreq.requestBranch,
+ repository,
+ commits,
+ ownerAccount,
+ oldId = oldId,
+ newId = newCommitId
+ )
+ }
}
- }
}
flash += "info" -> s"Merge branch '${alias}' into ${pullreq.requestBranch}"
}
@@ -246,95 +333,130 @@
})
post("/:owner/:repository/pull/:id/merge", mergeForm)(writableUsersOnly { (form, repository) =>
- params("id").toIntOpt.flatMap { issueId =>
- val owner = repository.owner
- val name = repository.name
- if(repository.repository.options.mergeOptions.split(",").contains(form.strategy)){
- LockUtil.lock(s"${owner}/${name}"){
- getPullRequest(owner, name, issueId).map { case (issue, pullreq) =>
- using(Git.open(getRepositoryDir(owner, name))) { git =>
- // mark issue as merged and close.
- val loginAccount = context.loginAccount.get
- val commentId = createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
- createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
- updateClosed(owner, name, issueId, true)
+ params("id").toIntOpt.flatMap {
+ issueId =>
+ val owner = repository.owner
+ val name = repository.name
+ if (repository.repository.options.mergeOptions.split(",").contains(form.strategy)) {
+ LockUtil.lock(s"${owner}/${name}") {
+ getPullRequest(owner, name, issueId).map {
+ case (issue, pullreq) =>
+ using(Git.open(getRepositoryDir(owner, name))) {
+ git =>
+ // mark issue as merged and close.
+ val loginAccount = context.loginAccount.get
+ val commentId = createComment(owner, name, loginAccount.userName, issueId, form.message, "merge")
+ createComment(owner, name, loginAccount.userName, issueId, "Close", "close")
+ updateClosed(owner, name, issueId, true)
- // record activity
- recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
+ // record activity
+ recordMergeActivity(owner, name, loginAccount.userName, issueId, form.message)
- val (commits, _) = getRequestCompareInfo(owner, name, pullreq.commitIdFrom,
- pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo)
+ val (commits, _) = getRequestCompareInfo(
+ owner,
+ name,
+ pullreq.commitIdFrom,
+ pullreq.requestUserName,
+ pullreq.requestRepositoryName,
+ pullreq.commitIdTo
+ )
- val revCommits = using(new RevWalk( git.getRepository )){ revWalk =>
- commits.flatten.map { commit =>
- revWalk.parseCommit(git.getRepository.resolve(commit.id))
+ val revCommits = using(new RevWalk(git.getRepository)) { revWalk =>
+ commits.flatten.map { commit =>
+ revWalk.parseCommit(git.getRepository.resolve(commit.id))
+ }
+ }.reverse
+
+ // merge git repository
+ form.strategy match {
+ case "merge-commit" =>
+ mergePullRequest(
+ git,
+ pullreq.branch,
+ issueId,
+ s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
+ new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
+ )
+ case "rebase" =>
+ rebasePullRequest(
+ git,
+ pullreq.branch,
+ issueId,
+ revCommits,
+ new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
+ )
+ case "squash" =>
+ squashPullRequest(
+ git,
+ pullreq.branch,
+ issueId,
+ s"${issue.title} (#${issueId})\n\n" + form.message,
+ new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
+ )
+ }
+
+ // close issue by content of pull request
+ val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
+ if (pullreq.branch == defaultBranch) {
+ commits.flatten.foreach { commit =>
+ closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
+ }
+ closeIssuesFromMessage(
+ issue.title + " " + issue.content.getOrElse(""),
+ loginAccount.userName,
+ owner,
+ name
+ )
+ closeIssuesFromMessage(form.message, loginAccount.userName, owner, name)
+ }
+
+ updatePullRequests(owner, name, pullreq.branch)
+
+ // call web hook
+ callPullRequestWebHook("closed", repository, issueId, context.baseUrl, context.loginAccount.get)
+
+ // call hooks
+ PluginRegistry().getPullRequestHooks.foreach { h =>
+ h.addedComment(commentId, form.message, issue, repository)
+ h.merged(issue, repository)
+ }
+
+ redirect(s"/${owner}/${name}/pull/${issueId}")
}
- }.reverse
-
- // merge git repository
- form.strategy match {
- case "merge-commit" =>
- mergePullRequest(git, pullreq.branch, issueId,
- s"Merge pull request #${issueId} from ${pullreq.requestUserName}/${pullreq.requestBranch}\n\n" + form.message,
- new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
- case "rebase" =>
- rebasePullRequest(git, pullreq.branch, issueId, revCommits,
- new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
- case "squash" =>
- squashPullRequest(git, pullreq.branch, issueId,
- s"${issue.title} (#${issueId})\n\n" + form.message,
- new PersonIdent(loginAccount.fullName, loginAccount.mailAddress))
- }
-
- // close issue by content of pull request
- val defaultBranch = getRepository(owner, name).get.repository.defaultBranch
- if(pullreq.branch == defaultBranch){
- commits.flatten.foreach { commit =>
- closeIssuesFromMessage(commit.fullMessage, loginAccount.userName, owner, name)
- }
- closeIssuesFromMessage(issue.title + " " + issue.content.getOrElse(""), loginAccount.userName, owner, name)
- closeIssuesFromMessage(form.message, loginAccount.userName, owner, name)
- }
-
- updatePullRequests(owner, name, pullreq.branch)
-
- // call web hook
- callPullRequestWebHook("closed", repository, issueId, context.baseUrl, context.loginAccount.get)
-
- // call hooks
- PluginRegistry().getPullRequestHooks.foreach{ h =>
- h.addedComment(commentId, form.message, issue, repository)
- h.merged(issue, repository)
- }
-
- redirect(s"/${owner}/${name}/pull/${issueId}")
}
}
- }
- } else Some(BadRequest())
+ } else Some(BadRequest())
} getOrElse NotFound()
})
get("/:owner/:repository/compare")(referrersOnly { forkedRepository =>
- val headBranch:Option[String] = params.get("head")
+ val headBranch: Option[String] = params.get("head")
(forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
case (Some(originUserName), Some(originRepositoryName)) => {
- getRepository(originUserName, originRepositoryName).map { originRepository =>
- using(
- Git.open(getRepositoryDir(originUserName, originRepositoryName)),
- Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
- ){ (oldGit, newGit) =>
- val newBranch = headBranch.getOrElse(JGitUtil.getDefaultBranch(newGit, forkedRepository).get._2)
- val oldBranch = originRepository.branchList.find( _ == newBranch).getOrElse(JGitUtil.getDefaultBranch(oldGit, originRepository).get._2)
+ getRepository(originUserName, originRepositoryName).map {
+ originRepository =>
+ using(
+ Git.open(getRepositoryDir(originUserName, originRepositoryName)),
+ Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
+ ) { (oldGit, newGit) =>
+ val newBranch = headBranch.getOrElse(JGitUtil.getDefaultBranch(newGit, forkedRepository).get._2)
+ val oldBranch = originRepository.branchList
+ .find(_ == newBranch)
+ .getOrElse(JGitUtil.getDefaultBranch(oldGit, originRepository).get._2)
- redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${originUserName}:${oldBranch}...${newBranch}")
- }
+ redirect(
+ s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${originUserName}:${oldBranch}...${newBranch}"
+ )
+ }
} getOrElse NotFound()
}
case _ => {
- using(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))){ git =>
- JGitUtil.getDefaultBranch(git, forkedRepository).map { case (_, defaultBranch) =>
- redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${defaultBranch}...${headBranch.getOrElse(defaultBranch)}")
+ using(Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))) { git =>
+ JGitUtil.getDefaultBranch(git, forkedRepository).map {
+ case (_, defaultBranch) =>
+ redirect(
+ s"/${forkedRepository.owner}/${forkedRepository.name}/compare/${defaultBranch}...${headBranch.getOrElse(defaultBranch)}"
+ )
} getOrElse {
redirect(s"/${forkedRepository.owner}/${forkedRepository.name}")
}
@@ -348,91 +470,118 @@
val (originOwner, originId) = parseCompareIdentifier(origin, forkedRepository.owner)
val (forkedOwner, forkedId) = parseCompareIdentifier(forked, forkedRepository.owner)
- (for(
- originRepositoryName <- if(originOwner == forkedOwner) {
- // Self repository
- Some(forkedRepository.name)
- } else if(forkedRepository.repository.originUserName.isEmpty){
- // when ForkedRepository is the original repository
- getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_.userName == originOwner).map(_.repositoryName)
- } else if(Some(originOwner) == forkedRepository.repository.originUserName){
- // Original repository
- forkedRepository.repository.originRepositoryName
- } else {
- // Sibling repository
- getUserRepositories(originOwner).find { x =>
- x.repository.originUserName == forkedRepository.repository.originUserName &&
- x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName
- }.map(_.repository.repositoryName)
- };
- originRepository <- getRepository(originOwner, originRepositoryName)
- ) yield {
+ (for (originRepositoryName <- if (originOwner == forkedOwner) {
+ // Self repository
+ Some(forkedRepository.name)
+ } else if (forkedRepository.repository.originUserName.isEmpty) {
+ // when ForkedRepository is the original repository
+ getForkedRepositories(forkedRepository.owner, forkedRepository.name)
+ .find(_.userName == originOwner)
+ .map(_.repositoryName)
+ } else if (Some(originOwner) == forkedRepository.repository.originUserName) {
+ // Original repository
+ forkedRepository.repository.originRepositoryName
+ } else {
+ // Sibling repository
+ getUserRepositories(originOwner)
+ .find { x =>
+ x.repository.originUserName == forkedRepository.repository.originUserName &&
+ x.repository.originRepositoryName == forkedRepository.repository.originRepositoryName
+ }
+ .map(_.repository.repositoryName)
+ };
+ originRepository <- getRepository(originOwner, originRepositoryName)) yield {
using(
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
- ){ case (oldGit, newGit) =>
- val (oldId, newId) =
- if(originRepository.branchList.contains(originId)){
- val forkedId2 = forkedRepository.tags.collectFirst { case x if x.name == forkedId => x.id }.getOrElse(forkedId)
+ ) {
+ case (oldGit, newGit) =>
+ val (oldId, newId) =
+ if (originRepository.branchList.contains(originId)) {
+ val forkedId2 =
+ forkedRepository.tags.collectFirst { case x if x.name == forkedId => x.id }.getOrElse(forkedId)
- val originId2 = JGitUtil.getForkedCommitId(oldGit, newGit,
- originRepository.owner, originRepository.name, originId,
- forkedRepository.owner, forkedRepository.name, forkedId2)
+ val originId2 = JGitUtil.getForkedCommitId(
+ oldGit,
+ newGit,
+ originRepository.owner,
+ originRepository.name,
+ originId,
+ forkedRepository.owner,
+ forkedRepository.name,
+ forkedId2
+ )
- (Option(oldGit.getRepository.resolve(originId2)), Option(newGit.getRepository.resolve(forkedId2)))
+ (Option(oldGit.getRepository.resolve(originId2)), Option(newGit.getRepository.resolve(forkedId2)))
- } else {
- val originId2 = originRepository.tags.collectFirst { case x if x.name == originId => x.id }.getOrElse(originId)
- val forkedId2 = forkedRepository.tags.collectFirst { case x if x.name == forkedId => x.id }.getOrElse(forkedId)
-
- (Option(oldGit.getRepository.resolve(originId2)), Option(newGit.getRepository.resolve(forkedId2)))
- }
-
- (oldId, newId) match {
- case (Some(oldId), Some(newId)) => {
- val (commits, diffs) = getRequestCompareInfo(
- originRepository.owner, originRepository.name, oldId.getName,
- forkedRepository.owner, forkedRepository.name, newId.getName)
-
- val title = if(commits.flatten.length == 1){
- commits.flatten.head.shortMessage
} else {
- val text = forkedId.replaceAll("[\\-_]", " ")
- text.substring(0, 1).toUpperCase + text.substring(1)
+ val originId2 =
+ originRepository.tags.collectFirst { case x if x.name == originId => x.id }.getOrElse(originId)
+ val forkedId2 =
+ forkedRepository.tags.collectFirst { case x if x.name == forkedId => x.id }.getOrElse(forkedId)
+
+ (Option(oldGit.getRepository.resolve(originId2)), Option(newGit.getRepository.resolve(forkedId2)))
}
- html.compare(
- title,
- commits,
- diffs,
- ((forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
- case (Some(userName), Some(repositoryName)) => getRepository(userName, repositoryName) match {
- case Some(x) => x.repository :: getForkedRepositories(userName, repositoryName)
- case None => getForkedRepositories(userName, repositoryName)
- }
- case _ => forkedRepository.repository :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
- }).map { repository => (repository.userName, repository.repositoryName) },
- commits.flatten.map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false)).flatten.toList,
- originId,
- forkedId,
- oldId.getName,
- newId.getName,
- getContentTemplate(originRepository, "PULL_REQUEST_TEMPLATE"),
- forkedRepository,
- originRepository,
- forkedRepository,
- hasDeveloperRole(originRepository.owner, originRepository.name, context.loginAccount),
- getAssignableUserNames(originRepository.owner, originRepository.name),
- getMilestones(originRepository.owner, originRepository.name),
- getPriorities(originRepository.owner, originRepository.name),
- getLabels(originRepository.owner, originRepository.name)
- )
+ (oldId, newId) match {
+ case (Some(oldId), Some(newId)) => {
+ val (commits, diffs) = getRequestCompareInfo(
+ originRepository.owner,
+ originRepository.name,
+ oldId.getName,
+ forkedRepository.owner,
+ forkedRepository.name,
+ newId.getName
+ )
+
+ val title = if (commits.flatten.length == 1) {
+ commits.flatten.head.shortMessage
+ } else {
+ val text = forkedId.replaceAll("[\\-_]", " ")
+ text.substring(0, 1).toUpperCase + text.substring(1)
+ }
+
+ html.compare(
+ title,
+ commits,
+ diffs,
+ ((forkedRepository.repository.originUserName, forkedRepository.repository.originRepositoryName) match {
+ case (Some(userName), Some(repositoryName)) =>
+ getRepository(userName, repositoryName) match {
+ case Some(x) => x.repository :: getForkedRepositories(userName, repositoryName)
+ case None => getForkedRepositories(userName, repositoryName)
+ }
+ case _ =>
+ forkedRepository.repository :: getForkedRepositories(forkedRepository.owner, forkedRepository.name)
+ }).map { repository =>
+ (repository.userName, repository.repositoryName)
+ },
+ commits.flatten
+ .map(commit => getCommitComments(forkedRepository.owner, forkedRepository.name, commit.id, false))
+ .flatten
+ .toList,
+ originId,
+ forkedId,
+ oldId.getName,
+ newId.getName,
+ getContentTemplate(originRepository, "PULL_REQUEST_TEMPLATE"),
+ forkedRepository,
+ originRepository,
+ forkedRepository,
+ hasDeveloperRole(originRepository.owner, originRepository.name, context.loginAccount),
+ getAssignableUserNames(originRepository.owner, originRepository.name),
+ getMilestones(originRepository.owner, originRepository.name),
+ getPriorities(originRepository.owner, originRepository.name),
+ getLabels(originRepository.owner, originRepository.name)
+ )
+ }
+ case (oldId, newId) =>
+ redirect(
+ s"/${forkedRepository.owner}/${forkedRepository.name}/compare/" +
+ s"${originOwner}:${oldId.map(_ => originId).getOrElse(originRepository.repository.defaultBranch)}..." +
+ s"${forkedOwner}:${newId.map(_ => forkedId).getOrElse(forkedRepository.repository.defaultBranch)}"
+ )
}
- case (oldId, newId) =>
- redirect(s"/${forkedRepository.owner}/${forkedRepository.name}/compare/" +
- s"${originOwner}:${oldId.map(_ => originId).getOrElse(originRepository.repository.defaultBranch)}..." +
- s"${forkedOwner}:${newId.map(_ => forkedId).getOrElse(forkedRepository.repository.defaultBranch)}")
- }
}
}) getOrElse NotFound()
})
@@ -442,102 +591,119 @@
val (originOwner, tmpOriginBranch) = parseCompareIdentifier(origin, forkedRepository.owner)
val (forkedOwner, tmpForkedBranch) = parseCompareIdentifier(forked, forkedRepository.owner)
- (for(
- originRepositoryName <- if(originOwner == forkedOwner){
- Some(forkedRepository.name)
- } else {
- forkedRepository.repository.originRepositoryName.orElse {
- getForkedRepositories(forkedRepository.owner, forkedRepository.name).find(_.userName == originOwner).map(_.repositoryName)
- }
- };
- originRepository <- getRepository(originOwner, originRepositoryName)
- ) yield {
+ (for (originRepositoryName <- if (originOwner == forkedOwner) {
+ Some(forkedRepository.name)
+ } else {
+ forkedRepository.repository.originRepositoryName.orElse {
+ getForkedRepositories(forkedRepository.owner, forkedRepository.name)
+ .find(_.userName == originOwner)
+ .map(_.repositoryName)
+ }
+ };
+ originRepository <- getRepository(originOwner, originRepositoryName)) yield {
using(
Git.open(getRepositoryDir(originRepository.owner, originRepository.name)),
Git.open(getRepositoryDir(forkedRepository.owner, forkedRepository.name))
- ){ case (oldGit, newGit) =>
- val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2
- val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2
- val conflict = LockUtil.lock(s"${originRepository.owner}/${originRepository.name}"){
- checkConflict(originRepository.owner, originRepository.name, originBranch,
- forkedRepository.owner, forkedRepository.name, forkedBranch)
- }
- html.mergecheck(conflict.isDefined)
+ ) {
+ case (oldGit, newGit) =>
+ val originBranch = JGitUtil.getDefaultBranch(oldGit, originRepository, tmpOriginBranch).get._2
+ val forkedBranch = JGitUtil.getDefaultBranch(newGit, forkedRepository, tmpForkedBranch).get._2
+ val conflict = LockUtil.lock(s"${originRepository.owner}/${originRepository.name}") {
+ checkConflict(
+ originRepository.owner,
+ originRepository.name,
+ originBranch,
+ forkedRepository.owner,
+ forkedRepository.name,
+ forkedBranch
+ )
+ }
+ html.mergecheck(conflict.isDefined)
}
}) getOrElse NotFound()
})
post("/:owner/:repository/pulls/new", pullRequestForm)(readableUsersOnly { (form, repository) =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- val manageable = isManageable(repository)
- val loginUserName = context.loginAccount.get.userName
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ val manageable = isManageable(repository)
+ val loginUserName = context.loginAccount.get.userName
- val issueId = insertIssue(
- owner = repository.owner,
- repository = repository.name,
- loginUser = loginUserName,
- title = form.title,
- content = form.content,
- assignedUserName = if (manageable) form.assignedUserName else None,
- milestoneId = if (manageable) form.milestoneId else None,
- priorityId = if (manageable) form.priorityId else None,
- isPullRequest = true)
+ val issueId = insertIssue(
+ owner = repository.owner,
+ repository = repository.name,
+ loginUser = loginUserName,
+ title = form.title,
+ content = form.content,
+ assignedUserName = if (manageable) form.assignedUserName else None,
+ milestoneId = if (manageable) form.milestoneId else None,
+ priorityId = if (manageable) form.priorityId else None,
+ isPullRequest = true
+ )
- createPullRequest(
- originUserName = repository.owner,
- originRepositoryName = repository.name,
- issueId = issueId,
- originBranch = form.targetBranch,
- requestUserName = form.requestUserName,
- requestRepositoryName = form.requestRepositoryName,
- requestBranch = form.requestBranch,
- commitIdFrom = form.commitIdFrom,
- commitIdTo = form.commitIdTo)
+ createPullRequest(
+ originUserName = repository.owner,
+ originRepositoryName = repository.name,
+ issueId = issueId,
+ originBranch = form.targetBranch,
+ requestUserName = form.requestUserName,
+ requestRepositoryName = form.requestRepositoryName,
+ requestBranch = form.requestBranch,
+ commitIdFrom = form.commitIdFrom,
+ commitIdTo = form.commitIdTo
+ )
- // insert labels
- if (manageable) {
- form.labelNames.map { value =>
- val labels = getLabels(owner, name)
- value.split(",").foreach { labelName =>
- labels.find(_.labelName == labelName).map { label =>
- registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
+ // insert labels
+ if (manageable) {
+ form.labelNames.map { value =>
+ val labels = getLabels(owner, name)
+ value.split(",").foreach { labelName =>
+ labels.find(_.labelName == labelName).map { label =>
+ registerIssueLabel(repository.owner, repository.name, issueId, label.labelId)
+ }
}
}
}
- }
- // fetch requested branch
- fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
+ // fetch requested branch
+ fetchAsPullRequest(owner, name, form.requestUserName, form.requestRepositoryName, form.requestBranch, issueId)
- // record activity
- recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)
+ // record activity
+ recordPullRequestActivity(owner, name, loginUserName, issueId, form.title)
- // call web hook
- callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
+ // call web hook
+ callPullRequestWebHook("opened", repository, issueId, context.baseUrl, context.loginAccount.get)
- getIssue(owner, name, issueId.toString) foreach { issue =>
- // extract references and create refer comment
- createReferComment(owner, name, issue, form.title + " " + form.content.getOrElse(""), context.loginAccount.get)
+ getIssue(owner, name, issueId.toString) foreach { issue =>
+ // extract references and create refer comment
+ createReferComment(
+ owner,
+ name,
+ issue,
+ form.title + " " + form.content.getOrElse(""),
+ context.loginAccount.get
+ )
- // call hooks
- PluginRegistry().getPullRequestHooks.foreach(_.created(issue, repository))
- }
+ // call hooks
+ PluginRegistry().getPullRequestHooks.foreach(_.created(issue, repository))
+ }
- redirect(s"/${owner}/${name}/pull/${issueId}")
+ redirect(s"/${owner}/${name}/pull/${issueId}")
}
})
ajaxGet("/:owner/:repository/pulls/proposals")(readableUsersOnly { repository =>
- val branches = JGitUtil.getBranches(
- owner = repository.owner,
- name = repository.name,
- defaultBranch = repository.repository.defaultBranch,
- origin = repository.repository.originUserName.isEmpty
- )
- .filter(x => x.mergeInfo.map(_.ahead).getOrElse(0) > 0 && x.mergeInfo.map(_.behind).getOrElse(0) == 0)
- .sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
- .map(_.name)
- .reverse
+ val branches = JGitUtil
+ .getBranches(
+ owner = repository.owner,
+ name = repository.name,
+ defaultBranch = repository.repository.defaultBranch,
+ origin = repository.repository.originUserName.isEmpty
+ )
+ .filter(x => x.mergeInfo.map(_.ahead).getOrElse(0) > 0 && x.mergeInfo.map(_.behind).getOrElse(0) == 0)
+ .sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
+ .map(_.name)
+ .reverse
val targetRepository = (for {
parentUserName <- repository.repository.parentUserName
@@ -563,7 +729,7 @@
* - "branch" to ("defaultOwner", "branch")
*/
private def parseCompareIdentifier(value: String, defaultOwner: String): (String, String) =
- if(value.contains(':')){
+ if (value.contains(':')) {
val array = value.split(":")
(array(0), array(1))
} else {
@@ -571,26 +737,28 @@
}
private def searchPullRequests(userName: Option[String], repository: RepositoryService.RepositoryInfo) =
- defining(repository.owner, repository.name){ case (owner, repoName) =>
- val page = IssueSearchCondition.page(request)
+ defining(repository.owner, repository.name) {
+ case (owner, repoName) =>
+ val page = IssueSearchCondition.page(request)
- // retrieve search condition
- val condition = IssueSearchCondition(request)
+ // retrieve search condition
+ val condition = IssueSearchCondition(request)
- gitbucket.core.issues.html.list(
- "pulls",
- searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
- page,
- getAssignableUserNames(owner, repoName),
- getMilestones(owner, repoName),
- getPriorities(owner, repoName),
- getLabels(owner, repoName),
- countIssue(condition.copy(state = "open" ), true, owner -> repoName),
- countIssue(condition.copy(state = "closed"), true, owner -> repoName),
- condition,
- repository,
- isEditable(repository),
- isManageable(repository))
+ gitbucket.core.issues.html.list(
+ "pulls",
+ searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
+ page,
+ getAssignableUserNames(owner, repoName),
+ getMilestones(owner, repoName),
+ getPriorities(owner, repoName),
+ getLabels(owner, repoName),
+ countIssue(condition.copy(state = "open"), true, owner -> repoName),
+ countIssue(condition.copy(state = "closed"), true, owner -> repoName),
+ condition,
+ repository,
+ isEditable(repository),
+ isManageable(repository)
+ )
}
/**
diff --git a/src/main/scala/gitbucket/core/controller/ReleasesController.scala b/src/main/scala/gitbucket/core/controller/ReleasesController.scala
index 7bb9753..8ffd023 100644
--- a/src/main/scala/gitbucket/core/controller/ReleasesController.scala
+++ b/src/main/scala/gitbucket/core/controller/ReleasesController.scala
@@ -11,14 +11,15 @@
import org.apache.commons.io.FileUtils
import scala.collection.JavaConverters._
-class ReleaseController extends ReleaseControllerBase
- with RepositoryService
- with AccountService
- with ReleaseService
- with ActivityService
- with ReadableUsersAuthenticator
- with ReferrerAuthenticator
- with WritableUsersAuthenticator
+class ReleaseController
+ extends ReleaseControllerBase
+ with RepositoryService
+ with AccountService
+ with ReleaseService
+ with ActivityService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
trait ReleaseControllerBase extends ControllerBase {
self: RepositoryService
@@ -35,36 +36,45 @@
)
val releaseForm = mapping(
- "name" -> trim(text(required)),
+ "name" -> trim(text(required)),
"content" -> trim(optional(text()))
)(ReleaseForm.apply)
- get("/:owner/:repository/releases")(referrersOnly {repository =>
+ get("/:owner/:repository/releases")(referrersOnly { repository =>
val releases = getReleases(repository.owner, repository.name)
val assets = getReleaseAssetsMap(repository.owner, repository.name)
html.list(
repository,
repository.tags.reverse.map { tag =>
- (tag, releases.find(_.tag == tag.name).map { release => (release, assets(release)) })
+ (tag, releases.find(_.tag == tag.name).map { release =>
+ (release, assets(release))
+ })
},
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
})
get("/:owner/:repository/releases/:tag")(referrersOnly { repository =>
val tagName = params("tag")
- getRelease(repository.owner, repository.name, tagName).map { release =>
- html.release(release, getReleaseAssets(repository.owner, repository.name, tagName),
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
- }.getOrElse(NotFound())
+ getRelease(repository.owner, repository.name, tagName)
+ .map { release =>
+ html.release(
+ release,
+ getReleaseAssets(repository.owner, repository.name, tagName),
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
+ repository
+ )
+ }
+ .getOrElse(NotFound())
})
- get("/:owner/:repository/releases/:tag/assets/:fileId")(referrersOnly {repository =>
+ get("/:owner/:repository/releases/:tag/assets/:fileId")(referrersOnly { repository =>
val tagName = params("tag")
val fileId = params("fileId")
(for {
- _ <- repository.tags.find(_.name == tagName)
- _ <- getRelease(repository.owner, repository.name, tagName)
+ _ <- repository.tags.find(_.name == tagName)
+ _ <- getRelease(repository.owner, repository.name, tagName)
asset <- getReleaseAsset(repository.owner, repository.name, tagName, fileId)
} yield {
response.setHeader("Content-Disposition", s"attachment; filename=${asset.label}")
@@ -75,11 +85,14 @@
}).getOrElse(NotFound())
})
- get("/:owner/:repository/releases/:tag/create")(writableUsersOnly {repository =>
+ get("/:owner/:repository/releases/:tag/create")(writableUsersOnly { repository =>
val tagName = params("tag")
- repository.tags.find(_.name == tagName).map { tag =>
- html.form(repository, tag, None)
- }.getOrElse(NotFound())
+ repository.tags
+ .find(_.name == tagName)
+ .map { tag =>
+ html.form(repository, tag, None)
+ }
+ .getOrElse(NotFound())
})
post("/:owner/:repository/releases/:tag/create", releaseForm)(writableUsersOnly { (form, repository) =>
@@ -90,13 +103,16 @@
createRelease(repository.owner, repository.name, form.name, form.content, tagName, loginAccount)
// Insert into RELEASE_ASSET
- val files = params.collect { case (name, value) if name.startsWith("file:") =>
- val Array(_, fileId) = name.split(":")
- (fileId, value)
+ val files = params.collect {
+ case (name, value) if name.startsWith("file:") =>
+ val Array(_, fileId) = name.split(":")
+ (fileId, value)
}
- files.foreach { case (fileId, fileName) =>
- val size = new java.io.File(getReleaseFilesDir(repository.owner, repository.name), tagName + "/" + fileId).length
- createReleaseAsset(repository.owner, repository.name, tagName, fileId, fileName, size, loginAccount)
+ files.foreach {
+ case (fileId, fileName) =>
+ val size =
+ new java.io.File(getReleaseFilesDir(repository.owner, repository.name), tagName + "/" + fileId).length
+ createReleaseAsset(repository.owner, repository.name, tagName, fileId, fileName, size, loginAccount)
}
recordReleaseActivity(repository.owner, repository.name, loginAccount.userName, form.name)
@@ -104,47 +120,56 @@
redirect(s"/${repository.owner}/${repository.name}/releases/${tagName}")
})
- get("/:owner/:repository/releases/:tag/edit")(writableUsersOnly {repository =>
+ get("/:owner/:repository/releases/:tag/edit")(writableUsersOnly { repository =>
val tagName = params("tag")
(for {
release <- getRelease(repository.owner, repository.name, tagName)
- tag <- repository.tags.find(_.name == tagName)
+ tag <- repository.tags.find(_.name == tagName)
} yield {
html.form(repository, tag, Some(release, getReleaseAssets(repository.owner, repository.name, tagName)))
}).getOrElse(NotFound())
})
- post("/:owner/:repository/releases/:tag/edit", releaseForm)(writableUsersOnly { (form, repository) =>
- val tagName = params("tag")
- val loginAccount = context.loginAccount.get
+ post("/:owner/:repository/releases/:tag/edit", releaseForm)(writableUsersOnly {
+ (form, repository) =>
+ val tagName = params("tag")
+ val loginAccount = context.loginAccount.get
- getRelease(repository.owner, repository.name, tagName).map { release =>
- // Update RELEASE
- updateRelease(repository.owner, repository.name, tagName, form.name, form.content)
+ getRelease(repository.owner, repository.name, tagName)
+ .map { release =>
+ // Update RELEASE
+ updateRelease(repository.owner, repository.name, tagName, form.name, form.content)
- // Delete and Insert RELEASE_ASSET
- val assets = getReleaseAssets(repository.owner, repository.name, tagName)
- deleteReleaseAssets(repository.owner, repository.name, tagName)
+ // Delete and Insert RELEASE_ASSET
+ val assets = getReleaseAssets(repository.owner, repository.name, tagName)
+ deleteReleaseAssets(repository.owner, repository.name, tagName)
- val files = params.collect { case (name, value) if name.startsWith("file:") =>
- val Array(_, fileId) = name.split(":")
- (fileId, value)
- }
- files.foreach { case (fileId, fileName) =>
- val size = new java.io.File(getReleaseFilesDir(repository.owner, repository.name), tagName + "/" + fileId).length
- createReleaseAsset(repository.owner, repository.name, tagName, fileId, fileName, size, loginAccount)
- }
+ val files = params.collect {
+ case (name, value) if name.startsWith("file:") =>
+ val Array(_, fileId) = name.split(":")
+ (fileId, value)
+ }
+ files.foreach {
+ case (fileId, fileName) =>
+ val size =
+ new java.io.File(getReleaseFilesDir(repository.owner, repository.name), tagName + "/" + fileId).length
+ createReleaseAsset(repository.owner, repository.name, tagName, fileId, fileName, size, loginAccount)
+ }
- assets.foreach { asset =>
- if(!files.exists { case (fileId, _) => fileId == asset.fileName }){
- val file = new java.io.File(getReleaseFilesDir(repository.owner, repository.name), release.tag + "/" + asset.fileName)
- FileUtils.forceDelete(file)
+ assets.foreach { asset =>
+ if (!files.exists { case (fileId, _) => fileId == asset.fileName }) {
+ val file = new java.io.File(
+ getReleaseFilesDir(repository.owner, repository.name),
+ release.tag + "/" + asset.fileName
+ )
+ FileUtils.forceDelete(file)
+ }
+ }
+
+ redirect(s"/${release.userName}/${release.repositoryName}/releases/${tagName}")
}
- }
-
- redirect(s"/${release.userName}/${release.repositoryName}/releases/${tagName}")
- }.getOrElse(NotFound())
+ .getOrElse(NotFound())
})
post("/:owner/:repository/releases/:tag/delete")(writableUsersOnly { repository =>
diff --git a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
index b824898..adfdfc4 100644
--- a/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
+++ b/src/main/scala/gitbucket/core/controller/RepositorySettingsController.scala
@@ -21,14 +21,26 @@
import gitbucket.core.model.WebHookContentType
import gitbucket.core.plugin.PluginRegistry
-
-class RepositorySettingsController extends RepositorySettingsControllerBase
- with RepositoryService with AccountService with WebHookService with ProtectedBranchService with CommitStatusService with DeployKeyService
- with OwnerAuthenticator with UsersAuthenticator
+class RepositorySettingsController
+ extends RepositorySettingsControllerBase
+ with RepositoryService
+ with AccountService
+ with WebHookService
+ with ProtectedBranchService
+ with CommitStatusService
+ with DeployKeyService
+ with OwnerAuthenticator
+ with UsersAuthenticator
trait RepositorySettingsControllerBase extends ControllerBase {
- self: RepositoryService with AccountService with WebHookService with ProtectedBranchService with CommitStatusService with DeployKeyService
- with OwnerAuthenticator with UsersAuthenticator =>
+ self: RepositoryService
+ with AccountService
+ with WebHookService
+ with ProtectedBranchService
+ with CommitStatusService
+ with DeployKeyService
+ with OwnerAuthenticator
+ with UsersAuthenticator =>
// for repository options
case class OptionsForm(
@@ -45,18 +57,20 @@
)
val optionsForm = mapping(
- "repositoryName" -> trim(label("Repository Name" , text(required, maxlength(100), repository, renameRepositoryName))),
- "description" -> trim(label("Description" , optional(text()))),
- "isPrivate" -> trim(label("Repository Type" , boolean())),
- "issuesOption" -> trim(label("Issues Option" , text(required, featureOption))),
- "externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
- "wikiOption" -> trim(label("Wiki Option" , text(required, featureOption))),
- "externalWikiUrl" -> trim(label("External Wiki URL" , optional(text(maxlength(200))))),
- "allowFork" -> trim(label("Allow Forking" , boolean())),
- "mergeOptions" -> mergeOptions,
+ "repositoryName" -> trim(
+ label("Repository Name", text(required, maxlength(100), repository, renameRepositoryName))
+ ),
+ "description" -> trim(label("Description", optional(text()))),
+ "isPrivate" -> trim(label("Repository Type", boolean())),
+ "issuesOption" -> trim(label("Issues Option", text(required, featureOption))),
+ "externalIssuesUrl" -> trim(label("External Issues URL", optional(text(maxlength(200))))),
+ "wikiOption" -> trim(label("Wiki Option", text(required, featureOption))),
+ "externalWikiUrl" -> trim(label("External Wiki URL", optional(text(maxlength(200))))),
+ "allowFork" -> trim(label("Allow Forking", boolean())),
+ "mergeOptions" -> mergeOptions,
"defaultMergeOption" -> trim(label("Default merge strategy", text(required)))
)(OptionsForm.apply).verifying { form =>
- if(!form.mergeOptions.contains(form.defaultMergeOption)){
+ if (!form.mergeOptions.contains(form.defaultMergeOption)) {
Seq("defaultMergeOption" -> s"This merge strategy isn't enabled.")
} else Nil
}
@@ -65,30 +79,30 @@
case class DefaultBranchForm(defaultBranch: String)
val defaultBranchForm = mapping(
- "defaultBranch" -> trim(label("Default Branch" , text(required, maxlength(100))))
+ "defaultBranch" -> trim(label("Default Branch", text(required, maxlength(100))))
)(DefaultBranchForm.apply)
-
// for deploy key
case class DeployKeyForm(title: String, publicKey: String, allowWrite: Boolean)
val deployKeyForm = mapping(
- "title" -> trim(label("Title", text(required, maxlength(100)))),
- "publicKey" -> trim2(label("Key" , text(required))), // TODO duplication check in the repository?
- "allowWrite" -> trim(label("Key" , boolean()))
+ "title" -> trim(label("Title", text(required, maxlength(100)))),
+ "publicKey" -> trim2(label("Key", text(required))), // TODO duplication check in the repository?
+ "allowWrite" -> trim(label("Key", boolean()))
)(DeployKeyForm.apply)
// for web hook url addition
case class WebHookForm(url: String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])
- def webHookForm(update:Boolean) = mapping(
- "url" -> trim(label("url", text(required, webHook(update)))),
- "events" -> webhookEvents,
- "ctype" -> label("ctype", text()),
- "token" -> optional(trim(label("token", text(maxlength(100)))))
- )(
- (url, events, ctype, token) => WebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
- )
+ def webHookForm(update: Boolean) =
+ mapping(
+ "url" -> trim(label("url", text(required, webHook(update)))),
+ "events" -> webhookEvents,
+ "ctype" -> label("ctype", text()),
+ "token" -> optional(trim(label("token", text(maxlength(100)))))
+ )(
+ (url, events, ctype, token) => WebHookForm(url, events, WebHookContentType.valueOf(ctype), token)
+ )
// for transfer ownership
case class TransferOwnerShipForm(newOwner: String)
@@ -131,24 +145,24 @@
form.defaultMergeOption
)
// Change repository name
- if(repository.name != form.repositoryName){
+ if (repository.name != form.repositoryName) {
// Update database
renameRepository(repository.owner, repository.name, repository.owner, form.repositoryName)
// Move git repository
- defining(getRepositoryDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory){
+ defining(getRepositoryDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getRepositoryDir(repository.owner, form.repositoryName))
}
}
// Move wiki repository
- defining(getWikiRepositoryDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory) {
+ defining(getWikiRepositoryDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getWikiRepositoryDir(repository.owner, form.repositoryName))
}
}
// Move files directory
- defining(getRepositoryFilesDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory) {
+ defining(getRepositoryFilesDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getRepositoryFilesDir(repository.owner, form.repositoryName))
}
}
@@ -170,7 +184,7 @@
/** Update default branch */
post("/:owner/:repository/settings/update_default_branch", defaultBranchForm)(ownerOnly { (form, repository) =>
- if(!repository.branchList.contains(form.defaultBranch)){
+ if (!repository.branchList.contains(form.defaultBranch)) {
redirect(s"/${repository.owner}/${repository.name}/settings/options")
} else {
saveRepositoryDefaultBranch(repository.owner, repository.name, form.defaultBranch)
@@ -187,12 +201,15 @@
get("/:owner/:repository/settings/branches/:branch")(ownerOnly { repository =>
import gitbucket.core.api._
val branch = params("branch")
- if(!repository.branchList.contains(branch)){
+ if (!repository.branchList.contains(branch)) {
redirect(s"/${repository.owner}/${repository.name}/settings/branches")
} else {
val protection = ApiBranchProtection(getProtectedBranchInfo(repository.owner, repository.name, branch))
- val lastWeeks = getRecentStatuesContexts(repository.owner, repository.name,
- Date.from(LocalDateTime.now.minusWeeks(1).toInstant(ZoneOffset.UTC))).toSet
+ val lastWeeks = getRecentStatuesContexts(
+ repository.owner,
+ repository.name,
+ Date.from(LocalDateTime.now.minusWeeks(1).toInstant(ZoneOffset.UTC))
+ ).toSet
val knownContexts = (lastWeeks ++ protection.status.contexts).toSeq.sortBy(identity)
html.branchprotection(repository, branch, protection, knownContexts, flash.get("info"))
}
@@ -205,7 +222,8 @@
html.collaborators(
getCollaborators(repository.owner, repository.name),
getAccountByUserName(repository.owner).get.isGroupAccount,
- repository)
+ repository
+ )
})
post("/:owner/:repository/settings/collaborators")(ownerOnly { repository =>
@@ -255,62 +273,90 @@
* Send the test request to registered web hook URLs.
*/
ajaxPost("/:owner/:repository/settings/hooks/test")(ownerOnly { repository =>
- def _headers(h: Array[org.apache.http.Header]): Array[Array[String]] = h.map { h => Array(h.getName, h.getValue) }
+ def _headers(h: Array[org.apache.http.Header]): Array[Array[String]] = h.map { h =>
+ Array(h.getName, h.getValue)
+ }
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- import scala.collection.JavaConverters._
- import scala.concurrent.duration._
- import scala.concurrent._
- import scala.util.control.NonFatal
- import org.apache.http.util.EntityUtils
- import scala.concurrent.ExecutionContext.Implicits.global
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ import scala.collection.JavaConverters._
+ import scala.concurrent.duration._
+ import scala.concurrent._
+ import scala.util.control.NonFatal
+ import org.apache.http.util.EntityUtils
+ import scala.concurrent.ExecutionContext.Implicits.global
- val url = params("url")
- val token = Some(params("token"))
- val ctype = WebHookContentType.valueOf(params("ctype"))
- val dummyWebHookInfo = RepositoryWebHook(repository.owner, repository.name, url, ctype, token)
- val dummyPayload = {
- val ownerAccount = getAccountByUserName(repository.owner).get
- val commits = if(JGitUtil.isEmpty(git)) List.empty else git.log
- .add(git.getRepository.resolve(repository.repository.defaultBranch))
- .setMaxCount(4)
- .call.iterator.asScala.map(new CommitInfo(_)).toList
- val pushedCommit = commits.drop(1)
+ val url = params("url")
+ val token = Some(params("token"))
+ val ctype = WebHookContentType.valueOf(params("ctype"))
+ val dummyWebHookInfo = RepositoryWebHook(repository.owner, repository.name, url, ctype, token)
+ val dummyPayload = {
+ val ownerAccount = getAccountByUserName(repository.owner).get
+ val commits =
+ if (JGitUtil.isEmpty(git)) List.empty
+ else
+ git.log
+ .add(git.getRepository.resolve(repository.repository.defaultBranch))
+ .setMaxCount(4)
+ .call
+ .iterator
+ .asScala
+ .map(new CommitInfo(_))
+ .toList
+ val pushedCommit = commits.drop(1)
- WebHookPushPayload(
- git = git,
- sender = ownerAccount,
- refName = "refs/heads/" + repository.repository.defaultBranch,
- repositoryInfo = repository,
- commits = pushedCommit,
- repositoryOwner = ownerAccount,
- oldId = commits.lastOption.map(_.id).map(ObjectId.fromString).getOrElse(ObjectId.zeroId()),
- newId = commits.headOption.map(_.id).map(ObjectId.fromString).getOrElse(ObjectId.zeroId())
+ WebHookPushPayload(
+ git = git,
+ sender = ownerAccount,
+ refName = "refs/heads/" + repository.repository.defaultBranch,
+ repositoryInfo = repository,
+ commits = pushedCommit,
+ repositoryOwner = ownerAccount,
+ oldId = commits.lastOption.map(_.id).map(ObjectId.fromString).getOrElse(ObjectId.zeroId()),
+ newId = commits.headOption.map(_.id).map(ObjectId.fromString).getOrElse(ObjectId.zeroId())
+ )
+ }
+
+ val (webHook, json, reqFuture, resFuture) = callWebHook(WebHook.Push, List(dummyWebHookInfo), dummyPayload).head
+
+ val toErrorMap: PartialFunction[Throwable, Map[String, String]] = {
+ case e: java.net.UnknownHostException => Map("error" -> ("Unknown host " + e.getMessage))
+ case e: java.lang.IllegalArgumentException => Map("error" -> ("invalid url"))
+ case e: org.apache.http.client.ClientProtocolException => Map("error" -> ("invalid url"))
+ case NonFatal(e) => Map("error" -> (e.getClass + " " + e.getMessage))
+ }
+
+ contentType = formats("json")
+ org.json4s.jackson.Serialization.write(
+ Map(
+ "url" -> url,
+ "request" -> Await.result(
+ reqFuture
+ .map(
+ req =>
+ Map(
+ "headers" -> _headers(req.getAllHeaders),
+ "payload" -> json
+ )
+ )
+ .recover(toErrorMap),
+ 20 seconds
+ ),
+ "response" -> Await.result(
+ resFuture
+ .map(
+ res =>
+ Map(
+ "status" -> res.getStatusLine(),
+ "body" -> EntityUtils.toString(res.getEntity()),
+ "headers" -> _headers(res.getAllHeaders())
+ )
+ )
+ .recover(toErrorMap),
+ 20 seconds
+ )
+ )
)
- }
-
- val (webHook, json, reqFuture, resFuture) = callWebHook(WebHook.Push, List(dummyWebHookInfo), dummyPayload).head
-
- val toErrorMap: PartialFunction[Throwable, Map[String,String]] = {
- case e: java.net.UnknownHostException => Map("error"-> ("Unknown host " + e.getMessage))
- case e: java.lang.IllegalArgumentException => Map("error"-> ("invalid url"))
- case e: org.apache.http.client.ClientProtocolException => Map("error"-> ("invalid url"))
- case NonFatal(e) => Map("error"-> (e.getClass + " "+ e.getMessage))
- }
-
- contentType = formats("json")
- org.json4s.jackson.Serialization.write(Map(
- "url" -> url,
- "request" -> Await.result(reqFuture.map(req => Map(
- "headers" -> _headers(req.getAllHeaders),
- "payload" -> json
- )).recover(toErrorMap), 20 seconds),
- "response" -> Await.result(resFuture.map(res => Map(
- "status" -> res.getStatusLine(),
- "body" -> EntityUtils.toString(res.getEntity()),
- "headers" -> _headers(res.getAllHeaders())
- )).recover(toErrorMap), 20 seconds)
- ))
}
})
@@ -318,8 +364,9 @@
* Display the web hook edit page.
*/
get("/:owner/:repository/settings/hooks/edit")(ownerOnly { repository =>
- getWebHook(repository.owner, repository.name, params("url")).map{ case (webhook, events) =>
- html.edithook(webhook, events, repository, false)
+ getWebHook(repository.owner, repository.name, params("url")).map {
+ case (webhook, events) =>
+ html.edithook(webhook, events, repository, false)
} getOrElse NotFound()
})
@@ -344,25 +391,25 @@
*/
post("/:owner/:repository/settings/transfer", transferForm)(ownerOnly { (form, repository) =>
// Change repository owner
- if(repository.owner != form.newOwner){
- LockUtil.lock(s"${repository.owner}/${repository.name}"){
+ if (repository.owner != form.newOwner) {
+ LockUtil.lock(s"${repository.owner}/${repository.name}") {
// Update database
renameRepository(repository.owner, repository.name, form.newOwner, repository.name)
// Move git repository
- defining(getRepositoryDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory){
+ defining(getRepositoryDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getRepositoryDir(form.newOwner, repository.name))
}
}
// Move wiki repository
- defining(getWikiRepositoryDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory) {
+ defining(getWikiRepositoryDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getWikiRepositoryDir(form.newOwner, repository.name))
}
}
// Move files directory
- defining(getRepositoryFilesDir(repository.owner, repository.name)){ dir =>
- if(dir.isDirectory) {
+ defining(getRepositoryFilesDir(repository.owner, repository.name)) { dir =>
+ if (dir.isDirectory) {
FileUtils.moveDirectory(dir, getRepositoryFilesDir(form.newOwner, repository.name))
}
}
@@ -378,7 +425,7 @@
* Delete the repository.
*/
post("/:owner/:repository/settings/delete")(ownerOnly { repository =>
- LockUtil.lock(s"${repository.owner}/${repository.name}"){
+ LockUtil.lock(s"${repository.owner}/${repository.name}") {
// Delete the repository and related files
deleteRepository(repository.owner, repository.name)
@@ -428,10 +475,10 @@
/**
* Provides duplication check for web hook url.
*/
- private def webHook(needExists: Boolean): Constraint = new Constraint(){
+ private def webHook(needExists: Boolean): Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(getWebHook(params("owner"), params("repository"), value).isDefined != needExists){
- Some(if(needExists){
+ if (getWebHook(params("owner"), params("repository"), value).isDefined != needExists) {
+ Some(if (needExists) {
"URL had not been registered yet."
} else {
"URL had been registered already."
@@ -441,17 +488,18 @@
}
}
- private def webhookEvents = new ValueType[Set[WebHook.Event]]{
+ private def webhookEvents = new ValueType[Set[WebHook.Event]] {
def convert(name: String, params: Map[String, Seq[String]], messages: Messages): Set[WebHook.Event] = {
WebHook.Event.values.flatMap { t =>
params.get(name + "." + t.name).map(_ => t)
}.toSet
}
- def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] = if(convert(name,params,messages).isEmpty){
- Seq(name -> messages("error.required").format(name))
- } else {
- Nil
- }
+ def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] =
+ if (convert(name, params, messages).isEmpty) {
+ Seq(name -> messages("error.required").format(name))
+ } else {
+ Nil
+ }
}
// /**
@@ -472,12 +520,17 @@
/**
* Duplicate check for the rename repository name.
*/
- private def renameRepositoryName: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] = {
+ private def renameRepositoryName: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] = {
for {
repoName <- params.optionValue("repository") if repoName != value
userName <- params.optionValue("owner")
- _ <- getRepositoryNamesOfUser(userName).find(_ == value)
+ _ <- getRepositoryNamesOfUser(userName).find(_ == value)
} yield {
"Repository already exists."
}
@@ -487,38 +540,45 @@
/**
*
*/
- private def featureOption: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] =
- if(Seq("DISABLE", "PRIVATE", "PUBLIC", "ALL").contains(value)) None else Some("Option is invalid.")
+ private def featureOption: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] =
+ if (Seq("DISABLE", "PRIVATE", "PUBLIC", "ALL").contains(value)) None else Some("Option is invalid.")
}
-
/**
* Provides Constraint to validate the repository transfer user.
*/
- private def transferUser: Constraint = new Constraint(){
+ private def transferUser: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
getAccountByUserName(value) match {
- case None => Some("User does not exist.")
- case Some(x) => if(x.userName == params("owner")){
- Some("This is current repository owner.")
- } else {
- params.get("repository").flatMap { repositoryName =>
- getRepositoryNamesOfUser(x.userName).find(_ == repositoryName).map{ _ => "User already has same repository." }
+ case None => Some("User does not exist.")
+ case Some(x) =>
+ if (x.userName == params("owner")) {
+ Some("This is current repository owner.")
+ } else {
+ params.get("repository").flatMap { repositoryName =>
+ getRepositoryNamesOfUser(x.userName).find(_ == repositoryName).map { _ =>
+ "User already has same repository."
+ }
+ }
}
- }
}
}
- private def mergeOptions = new ValueType[Seq[String]]{
+ private def mergeOptions = new ValueType[Seq[String]] {
override def convert(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[String] = {
params.get("mergeOptions").getOrElse(Nil)
}
override def validate(name: String, params: Map[String, Seq[String]], messages: Messages): Seq[(String, String)] = {
val mergeOptions = params.get("mergeOptions").getOrElse(Nil)
- if(mergeOptions.isEmpty){
+ if (mergeOptions.isEmpty) {
Seq("mergeOptions" -> "At least one option must be enabled.")
- } else if(!mergeOptions.forall(x => Seq("merge-commit", "squash", "rebase").contains(x))){
+ } else if (!mergeOptions.forall(x => Seq("merge-commit", "squash", "rebase").contains(x))) {
Seq("mergeOptions" -> "mergeOptions are invalid.")
} else {
Nil
diff --git a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
index 312a828..38216c9 100644
--- a/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
+++ b/src/main/scala/gitbucket/core/controller/RepositoryViewerController.scala
@@ -29,20 +29,44 @@
import org.scalatra._
import org.scalatra.i18n.Messages
-
-class RepositoryViewerController extends RepositoryViewerControllerBase
- with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
- with LabelsService with MilestonesService with PrioritiesService
- with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator with PullRequestService with CommitStatusService
- with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBranchService
+class RepositoryViewerController
+ extends RepositoryViewerControllerBase
+ with RepositoryService
+ with AccountService
+ with ActivityService
+ with IssuesService
+ with WebHookService
+ with CommitsService
+ with LabelsService
+ with MilestonesService
+ with PrioritiesService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
+ with PullRequestService
+ with CommitStatusService
+ with WebHookPullRequestService
+ with WebHookPullRequestReviewCommentService
+ with ProtectedBranchService
/**
* The repository viewer.
*/
trait RepositoryViewerControllerBase extends ControllerBase {
- self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
- with ReadableUsersAuthenticator with ReferrerAuthenticator with WritableUsersAuthenticator with PullRequestService with CommitStatusService
- with WebHookPullRequestService with WebHookPullRequestReviewCommentService with ProtectedBranchService =>
+ self: RepositoryService
+ with AccountService
+ with ActivityService
+ with IssuesService
+ with WebHookService
+ with CommitsService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
+ with WritableUsersAuthenticator
+ with PullRequestService
+ with CommitStatusService
+ with WebHookPullRequestService
+ with WebHookPullRequestReviewCommentService
+ with ProtectedBranchService =>
ArchiveCommand.registerFormat("zip", new ZipFormat)
ArchiveCommand.registerFormat("tar.gz", new TgzFormat)
@@ -83,38 +107,38 @@
)
val uploadForm = mapping(
- "branch" -> trim(label("Branch", text(required))),
- "path" -> trim(label("Path", text())),
- "uploadFiles" -> trim(label("Upload files", text(required))),
- "message" -> trim(label("Message", optional(text()))),
+ "branch" -> trim(label("Branch", text(required))),
+ "path" -> trim(label("Path", text())),
+ "uploadFiles" -> trim(label("Upload files", text(required))),
+ "message" -> trim(label("Message", optional(text()))),
)(UploadForm.apply)
val editorForm = mapping(
- "branch" -> trim(label("Branch", text(required))),
- "path" -> trim(label("Path", text())),
- "content" -> trim(label("Content", text(required))),
- "message" -> trim(label("Message", optional(text()))),
- "charset" -> trim(label("Charset", text(required))),
+ "branch" -> trim(label("Branch", text(required))),
+ "path" -> trim(label("Path", text())),
+ "content" -> trim(label("Content", text(required))),
+ "message" -> trim(label("Message", optional(text()))),
+ "charset" -> trim(label("Charset", text(required))),
"lineSeparator" -> trim(label("Line Separator", text(required))),
- "newFileName" -> trim(label("Filename", text(required))),
- "oldFileName" -> trim(label("Old filename", optional(text()))),
- "commit" -> trim(label("Commit", text(required, conflict)))
+ "newFileName" -> trim(label("Filename", text(required))),
+ "oldFileName" -> trim(label("Old filename", optional(text()))),
+ "commit" -> trim(label("Commit", text(required, conflict)))
)(EditorForm.apply)
val deleteForm = mapping(
- "branch" -> trim(label("Branch", text(required))),
- "path" -> trim(label("Path", text())),
- "message" -> trim(label("Message", optional(text()))),
+ "branch" -> trim(label("Branch", text(required))),
+ "path" -> trim(label("Path", text())),
+ "message" -> trim(label("Message", optional(text()))),
"fileName" -> trim(label("Filename", text(required))),
- "commit" -> trim(label("Commit", text(required, conflict)))
+ "commit" -> trim(label("Commit", text(required, conflict)))
)(DeleteForm.apply)
val commentForm = mapping(
- "fileName" -> trim(label("Filename", optional(text()))),
+ "fileName" -> trim(label("Filename", optional(text()))),
"oldLineNumber" -> trim(label("Old line number", optional(number()))),
"newLineNumber" -> trim(label("New line number", optional(number()))),
- "content" -> trim(label("Content", text(required))),
- "issueId" -> trim(label("Issue Id", optional(number())))
+ "content" -> trim(label("Content", text(required))),
+ "issueId" -> trim(label("Issue Id", optional(number())))
)(CommentForm.apply)
/**
@@ -124,7 +148,8 @@
contentType = "text/html"
val filename = params.get("filename")
filename match {
- case Some(f) => helpers.renderMarkup(
+ case Some(f) =>
+ helpers.renderMarkup(
filePath = List(f),
fileContent = params("content"),
branch = "master",
@@ -133,7 +158,8 @@
enableRefsLink = params("enableRefsLink").toBoolean,
enableAnchor = false
)
- case None => helpers.markdown(
+ case None =>
+ helpers.markdown(
markdown = params("content"),
repository = repository,
enableWikiLink = params("enableWikiLink").toBoolean,
@@ -157,9 +183,10 @@
gitbucket.core.repo.html.creating(owner, repository)
} else {
params.get("go-get") match {
- case Some("1") => defining(request.paths) { paths =>
- getRepository(owner, repository).map(gitbucket.core.html.goget(_)) getOrElse NotFound()
- }
+ case Some("1") =>
+ defining(request.paths) { paths =>
+ getRepository(owner, repository).map(gitbucket.core.html.goget(_)) getOrElse NotFound()
+ }
case _ => referrersOnly(fileList(_))
}
}
@@ -170,10 +197,12 @@
val repository = params("repository")
contentType = formats("json")
val creating = RepositoryCreationService.isCreating(owner, repository)
- Serialization.write(Map(
- "creating" -> creating,
- "error" -> (if(creating) None else RepositoryCreationService.getCreationError(owner, repository))
- ))
+ Serialization.write(
+ Map(
+ "creating" -> creating,
+ "error" -> (if (creating) None else RepositoryCreationService.getCreationError(owner, repository))
+ )
+ )
}
/**
@@ -181,7 +210,7 @@
*/
get("/:owner/:repository/tree/*")(referrersOnly { repository =>
val (id, path) = repository.splitPath(multiParams("splat").head)
- if(path.isEmpty){
+ if (path.isEmpty) {
fileList(repository, id)
} else {
fileList(repository, id, path)
@@ -202,45 +231,57 @@
def getSummary(statuses: List[CommitStatus]): (CommitState, String) = {
val stateMap = statuses.groupBy(_.state)
val state = CommitState.combine(stateMap.keySet)
- val summary = stateMap.map{ case (keyState, states) => states.size+" "+keyState.name }.mkString(", ")
+ val summary = stateMap.map { case (keyState, states) => states.size + " " + keyState.name }.mkString(", ")
state -> summary
}
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
- case Right((logs, hasNext)) =>
- html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository,
- logs.splitWith{ (commit1, commit2) =>
- view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
- }, page, hasNext, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), getStatuses, getSummary)
- case Left(_) => NotFound()
- }
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ JGitUtil.getCommitLog(git, branchName, page, 30, path) match {
+ case Right((logs, hasNext)) =>
+ html.commits(
+ if (path.isEmpty) Nil else path.split("/").toList,
+ branchName,
+ repository,
+ logs.splitWith { (commit1, commit2) =>
+ view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
+ },
+ page,
+ hasNext,
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
+ getStatuses,
+ getSummary
+ )
+ case Left(_) => NotFound()
+ }
}
})
get("/:owner/:repository/new/*")(writableUsersOnly { repository =>
val (branch, path) = repository.splitPath(multiParams("splat").head)
- val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch).needStatusCheck(context.loginAccount.get.userName)
+ val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
+ .needStatusCheck(context.loginAccount.get.userName)
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
html.editor(
- branch = branch,
- repository = repository,
- pathList = if (path.length == 0) Nil else path.split("/").toList,
- fileName = None,
- content = JGitUtil.ContentInfo("text", None, None, Some("UTF-8")),
+ branch = branch,
+ repository = repository,
+ pathList = if (path.length == 0) Nil else path.split("/").toList,
+ fileName = None,
+ content = JGitUtil.ContentInfo("text", None, None, Some("UTF-8")),
protectedBranch = protectedBranch,
- commit = revCommit.getName
+ commit = revCommit.getName
)
}
})
get("/:owner/:repository/upload/*")(writableUsersOnly { repository =>
val (branch, path) = repository.splitPath(multiParams("splat").head)
- val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch).needStatusCheck(context.loginAccount.get.userName)
- html.upload(branch, repository, if(path.length == 0) Nil else path.split("/").toList, protectedBranch)
+ val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
+ .needStatusCheck(context.loginAccount.get.userName)
+ html.upload(branch, repository, if (path.length == 0) Nil else path.split("/").toList, protectedBranch)
})
post("/:owner/:repository/upload", uploadForm)(writableUsersOnly { (form, repository) =>
@@ -251,120 +292,126 @@
commitFiles(
repository = repository,
- branch = form.branch,
- path = form.path,
- files = files,
- message = form.message.getOrElse("Add files via upload")
+ branch = form.branch,
+ path = form.path,
+ files = files,
+ message = form.message.getOrElse("Add files via upload")
)
- if(form.path.length == 0){
+ if (form.path.length == 0) {
redirect(s"/${repository.owner}/${repository.name}/tree/${form.branch}")
} else {
redirect(s"/${repository.owner}/${repository.name}/tree/${form.branch}/${form.path}")
}
})
-
get("/:owner/:repository/edit/*")(writableUsersOnly { repository =>
val (branch, path) = repository.splitPath(multiParams("splat").head)
- val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch).needStatusCheck(context.loginAccount.get.userName)
+ val protectedBranch = getProtectedBranchInfo(repository.owner, repository.name, branch)
+ .needStatusCheck(context.loginAccount.get.userName)
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
- getPathObjectId(git, path, revCommit).map { objectId =>
- val paths = path.split("/")
- html.editor(
- branch = branch,
- repository = repository,
- pathList = paths.take(paths.size - 1).toList,
- fileName = Some(paths.last),
- content = JGitUtil.getContentInfo(git, path, objectId),
- protectedBranch = protectedBranch,
- commit = revCommit.getName
- )
- } getOrElse NotFound()
+ getPathObjectId(git, path, revCommit).map { objectId =>
+ val paths = path.split("/")
+ html.editor(
+ branch = branch,
+ repository = repository,
+ pathList = paths.take(paths.size - 1).toList,
+ fileName = Some(paths.last),
+ content = JGitUtil.getContentInfo(git, path, objectId),
+ protectedBranch = protectedBranch,
+ commit = revCommit.getName
+ )
+ } getOrElse NotFound()
}
})
get("/:owner/:repository/remove/*")(writableUsersOnly { repository =>
val (branch, path) = repository.splitPath(multiParams("splat").head)
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(branch))
- getPathObjectId(git, path, revCommit).map { objectId =>
- val paths = path.split("/")
- html.delete(
- branch = branch,
- repository = repository,
- pathList = paths.take(paths.size - 1).toList,
- fileName = paths.last,
- content = JGitUtil.getContentInfo(git, path, objectId),
- commit = revCommit.getName
- )
- } getOrElse NotFound()
+ getPathObjectId(git, path, revCommit).map { objectId =>
+ val paths = path.split("/")
+ html.delete(
+ branch = branch,
+ repository = repository,
+ pathList = paths.take(paths.size - 1).toList,
+ fileName = paths.last,
+ content = JGitUtil.getContentInfo(git, path, objectId),
+ commit = revCommit.getName
+ )
+ } getOrElse NotFound()
}
})
post("/:owner/:repository/create", editorForm)(writableUsersOnly { (form, repository) =>
commitFile(
- repository = repository,
- branch = form.branch,
- path = form.path,
+ repository = repository,
+ branch = form.branch,
+ path = form.path,
newFileName = Some(form.newFileName),
oldFileName = None,
- content = appendNewLine(convertLineSeparator(form.content, form.lineSeparator), form.lineSeparator),
- charset = form.charset,
- message = form.message.getOrElse(s"Create ${form.newFileName}"),
- commit = form.commit
+ content = appendNewLine(convertLineSeparator(form.content, form.lineSeparator), form.lineSeparator),
+ charset = form.charset,
+ message = form.message.getOrElse(s"Create ${form.newFileName}"),
+ commit = form.commit
)
- redirect(s"/${repository.owner}/${repository.name}/blob/${form.branch}/${
- if(form.path.length == 0) urlEncode(form.newFileName) else s"${form.path}/${urlEncode(form.newFileName)}"
- }")
+ redirect(
+ s"/${repository.owner}/${repository.name}/blob/${form.branch}/${if (form.path.length == 0) urlEncode(form.newFileName)
+ else s"${form.path}/${urlEncode(form.newFileName)}"}"
+ )
})
post("/:owner/:repository/update", editorForm)(writableUsersOnly { (form, repository) =>
commitFile(
- repository = repository,
- branch = form.branch,
- path = form.path,
+ repository = repository,
+ branch = form.branch,
+ path = form.path,
newFileName = Some(form.newFileName),
oldFileName = form.oldFileName,
- content = appendNewLine(convertLineSeparator(form.content, form.lineSeparator), form.lineSeparator),
- charset = form.charset,
- message = if (form.oldFileName.contains(form.newFileName)) {
+ content = appendNewLine(convertLineSeparator(form.content, form.lineSeparator), form.lineSeparator),
+ charset = form.charset,
+ message = if (form.oldFileName.contains(form.newFileName)) {
form.message.getOrElse(s"Update ${form.newFileName}")
} else {
form.message.getOrElse(s"Rename ${form.oldFileName.get} to ${form.newFileName}")
},
- commit = form.commit
+ commit = form.commit
)
- redirect(s"/${repository.owner}/${repository.name}/blob/${urlEncode(form.branch)}/${
- if (form.path.length == 0) urlEncode(form.newFileName) else s"${form.path}/${urlEncode(form.newFileName)}"
- }")
+ redirect(
+ s"/${repository.owner}/${repository.name}/blob/${urlEncode(form.branch)}/${if (form.path.length == 0) urlEncode(form.newFileName)
+ else s"${form.path}/${urlEncode(form.newFileName)}"}"
+ )
})
post("/:owner/:repository/remove", deleteForm)(writableUsersOnly { (form, repository) =>
commitFile(
- repository = repository,
- branch = form.branch,
- path = form.path,
+ repository = repository,
+ branch = form.branch,
+ path = form.path,
newFileName = None,
oldFileName = Some(form.fileName),
- content = "",
- charset = "",
- message = form.message.getOrElse(s"Delete ${form.fileName}"),
- commit = form.commit
+ content = "",
+ charset = "",
+ message = form.message.getOrElse(s"Delete ${form.fileName}"),
+ commit = form.commit
)
- redirect(s"/${repository.owner}/${repository.name}/tree/${form.branch}${if(form.path.length == 0) "" else form.path}")
+ redirect(
+ s"/${repository.owner}/${repository.name}/tree/${form.branch}${if (form.path.length == 0) "" else form.path}"
+ )
})
get("/:owner/:repository/raw/*")(referrersOnly { repository =>
val (id, path) = repository.splitPath(multiParams("splat").head)
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
getPathObjectId(git, path, revCommit).map { objectId =>
@@ -379,25 +426,27 @@
val blobRoute = get("/:owner/:repository/blob/*")(referrersOnly { repository =>
val (id, path) = repository.splitPath(multiParams("splat").head)
val raw = params.get("raw").getOrElse("false").toBoolean
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
- getPathObjectId(git, path, revCommit).map { objectId =>
- if(raw){
- // Download (This route is left for backword compatibility)
- responseRawFile(git, objectId, path, repository)
- } else {
- html.blob(
- branch = id,
- repository = repository,
- pathList = path.split("/").toList,
- content = JGitUtil.getContentInfo(git, path, objectId),
- latestCommit = new JGitUtil.CommitInfo(JGitUtil.getLastModifiedCommit(git, revCommit, path)),
- hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
- isBlame = request.paths(2) == "blame",
- isLfsFile = isLfsFile(git, objectId)
- )
- }
- } getOrElse NotFound()
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))
+ getPathObjectId(git, path, revCommit).map {
+ objectId =>
+ if (raw) {
+ // Download (This route is left for backword compatibility)
+ responseRawFile(git, objectId, path, repository)
+ } else {
+ html.blob(
+ branch = id,
+ repository = repository,
+ pathList = path.split("/").toList,
+ content = JGitUtil.getContentInfo(git, path, objectId),
+ latestCommit = new JGitUtil.CommitInfo(JGitUtil.getLastModifiedCommit(git, revCommit, path)),
+ hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
+ isBlame = request.paths(2) == "blame",
+ isLfsFile = isLfsFile(git, objectId)
+ )
+ }
+ } getOrElse NotFound()
}
})
@@ -405,7 +454,7 @@
JGitUtil.getObjectLoaderFromId(git, objectId)(JGitUtil.isLfsPointer).getOrElse(false)
}
- get("/:owner/:repository/blame/*"){
+ get("/:owner/:repository/blame/*") {
blobRoute.action()
}
@@ -415,26 +464,31 @@
ajaxGet("/:owner/:repository/get-blame/*")(referrersOnly { repository =>
val (id, path) = repository.splitPath(multiParams("splat").head)
contentType = formats("json")
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- val last = git.log.add(git.getRepository.resolve(id)).addPath(path).setMaxCount(1).call.iterator.next.name
- Serialization.write(Map(
- "root" -> s"${context.baseUrl}/${repository.owner}/${repository.name}",
- "id" -> id,
- "path" -> path,
- "last" -> last,
- "blame" -> JGitUtil.getBlame(git, id, path).map{ blame =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ val last = git.log.add(git.getRepository.resolve(id)).addPath(path).setMaxCount(1).call.iterator.next.name
+ Serialization.write(
Map(
- "id" -> blame.id,
- "author" -> view.helpers.user(blame.authorName, blame.authorEmailAddress).toString,
- "avatar" -> view.helpers.avatarLink(blame.authorName, 32, blame.authorEmailAddress).toString,
- "authed" -> helper.html.datetimeago(blame.authorTime).toString,
- "prev" -> blame.prev,
- "prevPath" -> blame.prevPath,
- "commited" -> blame.commitTime.getTime,
- "message" -> blame.message,
- "lines" -> blame.lines
+ "root" -> s"${context.baseUrl}/${repository.owner}/${repository.name}",
+ "id" -> id,
+ "path" -> path,
+ "last" -> last,
+ "blame" -> JGitUtil.getBlame(git, id, path).map {
+ blame =>
+ Map(
+ "id" -> blame.id,
+ "author" -> view.helpers.user(blame.authorName, blame.authorEmailAddress).toString,
+ "avatar" -> view.helpers.avatarLink(blame.authorName, 32, blame.authorEmailAddress).toString,
+ "authed" -> helper.html.datetimeago(blame.authorTime).toString,
+ "prev" -> blame.prev,
+ "prevPath" -> blame.prevPath,
+ "commited" -> blame.commitTime.getTime,
+ "message" -> blame.message,
+ "lines" -> blame.lines
+ )
+ }
)
- }))
+ )
}
})
@@ -445,20 +499,28 @@
val id = params("id")
try {
- using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
- defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) { revCommit =>
- val diffs = JGitUtil.getDiffs(git, None, id, true, false)
- val oldCommitId = JGitUtil.getParentCommitId(git, id)
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) {
+ git =>
+ defining(JGitUtil.getRevCommitFromId(git, git.getRepository.resolve(id))) {
+ revCommit =>
+ val diffs = JGitUtil.getDiffs(git, None, id, true, false)
+ val oldCommitId = JGitUtil.getParentCommitId(git, id)
- html.commit(id, new JGitUtil.CommitInfo(revCommit),
- JGitUtil.getBranchesOfCommit(git, revCommit.getName),
- JGitUtil.getTagsOfCommit(git, revCommit.getName),
- getCommitComments(repository.owner, repository.name, id, true),
- repository, diffs, oldCommitId, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
- }
+ html.commit(
+ id,
+ new JGitUtil.CommitInfo(revCommit),
+ JGitUtil.getBranchesOfCommit(git, revCommit.getName),
+ JGitUtil.getTagsOfCommit(git, revCommit.getName),
+ getCommitComments(repository.owner, repository.name, id, true),
+ repository,
+ diffs,
+ oldCommitId,
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
+ )
+ }
}
} catch {
- case e:MissingObjectException => NotFound()
+ case e: MissingObjectException => NotFound()
}
})
@@ -470,7 +532,7 @@
diff
}
} catch {
- case e:MissingObjectException => NotFound()
+ case e: MissingObjectException => NotFound()
}
})
@@ -489,24 +551,50 @@
post("/:owner/:repository/commit/:id/comment/new", commentForm)(readableUsersOnly { (form, repository) =>
val id = params("id")
- createCommitComment(repository.owner, repository.name, id, context.loginAccount.get.userName, form.content,
- form.fileName, form.oldLineNumber, form.newLineNumber, form.issueId)
+ createCommitComment(
+ repository.owner,
+ repository.name,
+ id,
+ context.loginAccount.get.userName,
+ form.content,
+ form.fileName,
+ form.oldLineNumber,
+ form.newLineNumber,
+ form.issueId
+ )
form.issueId match {
- case Some(issueId) => recordCommentPullRequestActivity(repository.owner, repository.name, context.loginAccount.get.userName, issueId, form.content)
- case None => recordCommentCommitActivity(repository.owner, repository.name, context.loginAccount.get.userName, id, form.content)
+ case Some(issueId) =>
+ recordCommentPullRequestActivity(
+ repository.owner,
+ repository.name,
+ context.loginAccount.get.userName,
+ issueId,
+ form.content
+ )
+ case None =>
+ recordCommentCommitActivity(
+ repository.owner,
+ repository.name,
+ context.loginAccount.get.userName,
+ id,
+ form.content
+ )
}
redirect(s"/${repository.owner}/${repository.name}/commit/${id}")
})
ajaxGet("/:owner/:repository/commit/:id/comment/_form")(readableUsersOnly { repository =>
- val id = params("id")
- val fileName = params.get("fileName")
+ val id = params("id")
+ val fileName = params.get("fileName")
val oldLineNumber = params.get("oldLineNumber") map (_.toInt)
val newLineNumber = params.get("newLineNumber") map (_.toInt)
- val issueId = params.get("issueId") map (_.toInt)
+ val issueId = params.get("issueId") map (_.toInt)
html.commentform(
commitId = id,
- fileName, oldLineNumber, newLineNumber, issueId,
+ fileName,
+ oldLineNumber,
+ newLineNumber,
+ issueId,
hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
repository = repository
)
@@ -514,64 +602,99 @@
ajaxPost("/:owner/:repository/commit/:id/comment/_data/new", commentForm)(readableUsersOnly { (form, repository) =>
val id = params("id")
- val commentId = createCommitComment(repository.owner, repository.name, id, context.loginAccount.get.userName,
- form.content, form.fileName, form.oldLineNumber, form.newLineNumber, form.issueId)
+ val commentId = createCommitComment(
+ repository.owner,
+ repository.name,
+ id,
+ context.loginAccount.get.userName,
+ form.content,
+ form.fileName,
+ form.oldLineNumber,
+ form.newLineNumber,
+ form.issueId
+ )
val comment = getCommitComment(repository.owner, repository.name, commentId.toString).get
form.issueId match {
case Some(issueId) =>
- getPullRequest(repository.owner, repository.name, issueId).foreach { case (issue, pullRequest) =>
- recordCommentPullRequestActivity(repository.owner, repository.name, context.loginAccount.get.userName, issueId, form.content)
- PluginRegistry().getPullRequestHooks.foreach(_.addedComment(commentId, form.content, issue, repository))
- callPullRequestReviewCommentWebHook("create", comment, repository, issue, pullRequest, context.baseUrl, context.loginAccount.get)
+ getPullRequest(repository.owner, repository.name, issueId).foreach {
+ case (issue, pullRequest) =>
+ recordCommentPullRequestActivity(
+ repository.owner,
+ repository.name,
+ context.loginAccount.get.userName,
+ issueId,
+ form.content
+ )
+ PluginRegistry().getPullRequestHooks.foreach(_.addedComment(commentId, form.content, issue, repository))
+ callPullRequestReviewCommentWebHook(
+ "create",
+ comment,
+ repository,
+ issue,
+ pullRequest,
+ context.baseUrl,
+ context.loginAccount.get
+ )
}
case None =>
- recordCommentCommitActivity(repository.owner, repository.name, context.loginAccount.get.userName, id, form.content)
+ recordCommentCommitActivity(
+ repository.owner,
+ repository.name,
+ context.loginAccount.get.userName,
+ id,
+ form.content
+ )
}
- helper.html.commitcomment(comment, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
+ helper.html
+ .commitcomment(comment, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
})
ajaxGet("/:owner/:repository/commit_comments/_data/:id")(readableUsersOnly { repository =>
- getCommitComment(repository.owner, repository.name, params("id")) map { x =>
- if(isEditable(x.userName, x.repositoryName, x.commentedUserName)){
- params.get("dataType") collect {
- case t if t == "html" => html.editcomment(x.content, x.commentId, repository)
- } getOrElse {
- contentType = formats("json")
- org.json4s.jackson.Serialization.write(
- Map(
- "content" -> view.Markdown.toHtml(
- markdown = x.content,
- repository = repository,
- enableWikiLink = false,
- enableRefsLink = true,
- enableAnchor = true,
- enableLineBreaks = true,
- hasWritePermission = true
+ getCommitComment(repository.owner, repository.name, params("id")) map {
+ x =>
+ if (isEditable(x.userName, x.repositoryName, x.commentedUserName)) {
+ params.get("dataType") collect {
+ case t if t == "html" => html.editcomment(x.content, x.commentId, repository)
+ } getOrElse {
+ contentType = formats("json")
+ org.json4s.jackson.Serialization.write(
+ Map(
+ "content" -> view.Markdown.toHtml(
+ markdown = x.content,
+ repository = repository,
+ enableWikiLink = false,
+ enableRefsLink = true,
+ enableAnchor = true,
+ enableLineBreaks = true,
+ hasWritePermission = true
+ )
)
- ))
- }
- } else Unauthorized()
+ )
+ }
+ } else Unauthorized()
} getOrElse NotFound()
})
ajaxPost("/:owner/:repository/commit_comments/edit/:id", commentForm)(readableUsersOnly { (form, repository) =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getCommitComment(owner, name, params("id")).map { comment =>
- if(isEditable(owner, name, comment.commentedUserName)){
- updateCommitComment(comment.commentId, form.content)
- redirect(s"/${owner}/${name}/commit_comments/_data/${comment.commentId}")
- } else Unauthorized()
- } getOrElse NotFound()
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getCommitComment(owner, name, params("id")).map { comment =>
+ if (isEditable(owner, name, comment.commentedUserName)) {
+ updateCommitComment(comment.commentId, form.content)
+ redirect(s"/${owner}/${name}/commit_comments/_data/${comment.commentId}")
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
ajaxPost("/:owner/:repository/commit_comments/delete/:id")(readableUsersOnly { repository =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- getCommitComment(owner, name, params("id")).map { comment =>
- if(isEditable(owner, name, comment.commentedUserName)){
- Ok(deleteCommitComment(comment.commentId))
- } else Unauthorized()
- } getOrElse NotFound()
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ getCommitComment(owner, name, params("id")).map { comment =>
+ if (isEditable(owner, name, comment.commentedUserName)) {
+ Ok(deleteCommitComment(comment.commentId))
+ } else Unauthorized()
+ } getOrElse NotFound()
}
})
@@ -580,15 +703,29 @@
*/
get("/:owner/:repository/branches")(referrersOnly { repository =>
val protectedBranches = getProtectedBranchList(repository.owner, repository.name).toSet
- val branches = JGitUtil.getBranches(
- owner = repository.owner,
- name = repository.name,
- defaultBranch = repository.repository.defaultBranch,
- origin = repository.repository.originUserName.isEmpty
- )
- .sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
- .map(br => (br, getPullRequestByRequestCommit(repository.owner, repository.name, repository.repository.defaultBranch, br.name, br.commitId), protectedBranches.contains(br.name)))
- .reverse
+ val branches = JGitUtil
+ .getBranches(
+ owner = repository.owner,
+ name = repository.name,
+ defaultBranch = repository.repository.defaultBranch,
+ origin = repository.repository.originUserName.isEmpty
+ )
+ .sortBy(br => (br.mergeInfo.isEmpty, br.commitTime))
+ .map(
+ br =>
+ (
+ br,
+ getPullRequestByRequestCommit(
+ repository.owner,
+ repository.name,
+ repository.repository.defaultBranch,
+ br.name,
+ br.commitId
+ ),
+ protectedBranches.contains(br.name)
+ )
+ )
+ .reverse
html.branches(branches, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
})
@@ -599,12 +736,14 @@
post("/:owner/:repository/branches")(writableUsersOnly { repository =>
val newBranchName = params.getOrElse("new", halt(400))
val fromBranchName = params.getOrElse("from", halt(400))
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
JGitUtil.createBranch(git, fromBranchName, newBranchName)
} match {
case Right(message) =>
flash += "info" -> message
- redirect(s"/${repository.owner}/${repository.name}/tree/${StringUtil.urlEncode(newBranchName).replace("%2F", "/")}")
+ redirect(
+ s"/${repository.owner}/${repository.name}/tree/${StringUtil.urlEncode(newBranchName).replace("%2F", "/")}"
+ )
case Left(message) =>
flash += "error" -> message
redirect(s"/${repository.owner}/${repository.name}/tree/${fromBranchName}")
@@ -616,9 +755,9 @@
*/
get("/:owner/:repository/delete/*")(writableUsersOnly { repository =>
val branchName = multiParams("splat").head
- val userName = context.loginAccount.get.userName
- if(repository.repository.defaultBranch != branchName){
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ val userName = context.loginAccount.get.userName
+ if (repository.repository.defaultBranch != branchName) {
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
git.branchDelete().setForce(true).setBranchNames(branchName).call()
recordDeleteBranchActivity(repository.owner, repository.name, userName, branchName)
}
@@ -647,20 +786,24 @@
})
get("/:owner/:repository/network/members")(referrersOnly { repository =>
- if(repository.repository.options.allowFork) {
+ if (repository.repository.options.allowFork) {
html.forked(
getRepository(
repository.repository.originUserName.getOrElse(repository.owner),
- repository.repository.originRepositoryName.getOrElse(repository.name)),
+ repository.repository.originRepositoryName.getOrElse(repository.name)
+ ),
getForkedRepositories(
repository.repository.originUserName.getOrElse(repository.owner),
repository.repository.originRepositoryName.getOrElse(repository.name)
- ).map { repository => (repository.userName, repository.repositoryName) },
+ ).map { repository =>
+ (repository.userName, repository.repositoryName)
+ },
context.loginAccount match {
- case None => List()
+ case None => List()
case account: Option[Account] => getGroupsByUserName(account.get.userName)
}, // groups of current user
- repository)
+ repository
+ )
} else BadRequest()
})
@@ -668,9 +811,9 @@
* Displays the file find of branch.
*/
get("/:owner/:repository/find/*")(referrersOnly { repository =>
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val ref = multiParams("splat").head
- JGitUtil.getTreeId(git, ref).map{ treeId =>
+ JGitUtil.getTreeId(git, ref).map { treeId =>
html.find(ref, treeId, repository)
} getOrElse NotFound()
}
@@ -680,73 +823,96 @@
* Get all file list of branch.
*/
ajaxGet("/:owner/:repository/tree-list/:tree")(referrersOnly { repository =>
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val treeId = params("tree")
contentType = formats("json")
Map("paths" -> JGitUtil.getAllFileListByTreeId(git, treeId))
}
})
- case class UploadFiles(branch: String, path: String, fileIds: Map[String,String], message: String) {
+ case class UploadFiles(branch: String, path: String, fileIds: Map[String, String], message: String) {
lazy val isValid: Boolean = fileIds.nonEmpty
}
case class CommitFile(id: String, name: String)
- private def commitFiles(repository: RepositoryService.RepositoryInfo,
- files: Seq[CommitFile],
- branch: String, path: String, message: String) = {
+ private def commitFiles(
+ repository: RepositoryService.RepositoryInfo,
+ files: Seq[CommitFile],
+ branch: String,
+ path: String,
+ message: String
+ ) = {
// prepend path to the filename
val newFiles = files.map { file =>
- file.copy(name = if(path.length == 0) file.name else s"${path}/${file.name}")
+ file.copy(name = if (path.length == 0) file.name else s"${path}/${file.name}")
}
- _commitFile(repository, branch, message) { case (git, headTip, builder, inserter) =>
- JGitUtil.processTree(git, headTip) { (path, tree) =>
- if(!newFiles.exists(_.name.contains(path))) {
- builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
- }
- }
-
- newFiles.foreach { file =>
- val bytes = FileUtils.readFileToByteArray(new File(getTemporaryDir(session.getId), file.id))
- builder.add(JGitUtil.createDirCacheEntry(file.name,
- FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, bytes)))
- builder.finish()
- }
- }
- }
-
- private def commitFile(repository: RepositoryService.RepositoryInfo,
- branch: String, path: String, newFileName: Option[String], oldFileName: Option[String],
- content: String, charset: String, message: String, commit: String) = {
-
- val newPath = newFileName.map { newFileName => if(path.length == 0) newFileName else s"${path}/${newFileName}" }
- val oldPath = oldFileName.map { oldFileName => if(path.length == 0) oldFileName else s"${path}/${oldFileName}" }
-
- _commitFile(repository, branch, message){ case (git, headTip, builder, inserter) =>
- if(headTip.getName == commit){
- val permission = JGitUtil.processTree(git, headTip) { (path, tree) =>
- // Add all entries except the editing file
- if (!newPath.contains(path) && !oldPath.contains(path)) {
+ _commitFile(repository, branch, message) {
+ case (git, headTip, builder, inserter) =>
+ JGitUtil.processTree(git, headTip) { (path, tree) =>
+ if (!newFiles.exists(_.name.contains(path))) {
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
}
- // Retrieve permission if file exists to keep it
- oldPath.collect { case x if x == path => tree.getEntryFileMode.getBits }
- }.flatten.headOption
-
- newPath.foreach { newPath =>
- builder.add(JGitUtil.createDirCacheEntry(newPath,
- permission.map { bits => FileMode.fromBits(bits) } getOrElse FileMode.REGULAR_FILE,
- inserter.insert(Constants.OBJ_BLOB, content.getBytes(charset))))
}
- builder.finish()
- }
+
+ newFiles.foreach { file =>
+ val bytes = FileUtils.readFileToByteArray(new File(getTemporaryDir(session.getId), file.id))
+ builder.add(
+ JGitUtil.createDirCacheEntry(file.name, FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, bytes))
+ )
+ builder.finish()
+ }
}
}
- private def _commitFile(repository: RepositoryService.RepositoryInfo,
- branch: String, message: String)(f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => Unit) = {
+ private def commitFile(
+ repository: RepositoryService.RepositoryInfo,
+ branch: String,
+ path: String,
+ newFileName: Option[String],
+ oldFileName: Option[String],
+ content: String,
+ charset: String,
+ message: String,
+ commit: String
+ ) = {
+
+ val newPath = newFileName.map { newFileName =>
+ if (path.length == 0) newFileName else s"${path}/${newFileName}"
+ }
+ val oldPath = oldFileName.map { oldFileName =>
+ if (path.length == 0) oldFileName else s"${path}/${oldFileName}"
+ }
+
+ _commitFile(repository, branch, message) {
+ case (git, headTip, builder, inserter) =>
+ if (headTip.getName == commit) {
+ val permission = JGitUtil
+ .processTree(git, headTip) { (path, tree) =>
+ // Add all entries except the editing file
+ if (!newPath.contains(path) && !oldPath.contains(path)) {
+ builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
+ }
+ // Retrieve permission if file exists to keep it
+ oldPath.collect { case x if x == path => tree.getEntryFileMode.getBits }
+ }
+ .flatten
+ .headOption
+
+ newPath.foreach { newPath =>
+ builder.add(JGitUtil.createDirCacheEntry(newPath, permission.map { bits =>
+ FileMode.fromBits(bits)
+ } getOrElse FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, content.getBytes(charset))))
+ }
+ builder.finish()
+ }
+ }
+ }
+
+ private def _commitFile(repository: RepositoryService.RepositoryInfo, branch: String, message: String)(
+ f: (Git, ObjectId, DirCacheBuilder, ObjectInserter) => Unit
+ ) = {
LockUtil.lock(s"${repository.owner}/${repository.name}") {
using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
@@ -758,8 +924,16 @@
f(git, headTip, builder, inserter)
- val commitId = JGitUtil.createNewCommit(git, inserter, headTip, builder.getDirCache.writeTree(inserter),
- headName, loginAccount.fullName, loginAccount.mailAddress, message)
+ val commitId = JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headTip,
+ builder.getDirCache.writeTree(inserter),
+ headName,
+ loginAccount.fullName,
+ loginAccount.mailAddress,
+ message
+ )
inserter.flush()
inserter.close()
@@ -811,9 +985,17 @@
callPullRequestWebHookByRequestBranch("synchronize", repository, branch, context.baseUrl, loginAccount)
val commit = new JGitUtil.CommitInfo(JGitUtil.getRevCommitFromId(git, commitId))
callWebHookOf(repository.owner, repository.name, WebHook.Push) {
- getAccountByUserName(repository.owner).map{ ownerAccount =>
- WebHookPushPayload(git, loginAccount, headName, repository, List(commit), ownerAccount,
- oldId = headTip, newId = commitId)
+ getAccountByUserName(repository.owner).map { ownerAccount =>
+ WebHookPushPayload(
+ git,
+ loginAccount,
+ headName,
+ repository,
+ List(commit),
+ ownerAccount,
+ oldId = headTip,
+ newId = commitId
+ )
}
}
}
@@ -834,38 +1016,52 @@
* @return HTML of the file list
*/
private def fileList(repository: RepositoryService.RepositoryInfo, revstr: String = "", path: String = ".") = {
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
- if(JGitUtil.isEmpty(git)){
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
+ if (JGitUtil.isEmpty(git)) {
html.guide(repository, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
} else {
// get specified commit
- JGitUtil.getDefaultBranch(git, repository, revstr).map { case (objectId, revision) =>
- defining(JGitUtil.getRevCommitFromId(git, objectId)) { revCommit =>
- val lastModifiedCommit = if(path == ".") revCommit else JGitUtil.getLastModifiedCommit(git, revCommit, path)
- // get files
- val files = JGitUtil.getFileList(git, revision, path, context.settings.baseUrl)
- val parentPath = if (path == ".") Nil else path.split("/").toList
- // process README.md or README.markdown
- val readme = files.find { file =>
- !file.isDirectory && readmeFiles.contains(file.name.toLowerCase)
- }.map { file =>
- val path = (file.name :: parentPath.reverse).reverse
- path -> StringUtil.convertFromByteArray(JGitUtil.getContentFromId(
- Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get)
- }
+ JGitUtil.getDefaultBranch(git, repository, revstr).map {
+ case (objectId, revision) =>
+ defining(JGitUtil.getRevCommitFromId(git, objectId)) { revCommit =>
+ val lastModifiedCommit =
+ if (path == ".") revCommit else JGitUtil.getLastModifiedCommit(git, revCommit, path)
+ // get files
+ val files = JGitUtil.getFileList(git, revision, path, context.settings.baseUrl)
+ val parentPath = if (path == ".") Nil else path.split("/").toList
+ // process README.md or README.markdown
+ val readme = files
+ .find { file =>
+ !file.isDirectory && readmeFiles.contains(file.name.toLowerCase)
+ }
+ .map { file =>
+ val path = (file.name :: parentPath.reverse).reverse
+ path -> StringUtil.convertFromByteArray(
+ JGitUtil
+ .getContentFromId(Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true)
+ .get
+ )
+ }
- html.files(revision, repository,
- if(path == ".") Nil else path.split("/").toList, // current path
- new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit
- JGitUtil.getCommitCount(repository.owner, repository.name, lastModifiedCommit.getName),
- files,
- readme,
- hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
- getPullRequestFromBranch(repository.owner, repository.name, revstr, repository.repository.defaultBranch),
- flash.get("info"),
- flash.get("error")
- )
- }
+ html.files(
+ revision,
+ repository,
+ if (path == ".") Nil else path.split("/").toList, // current path
+ new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit
+ JGitUtil.getCommitCount(repository.owner, repository.name, lastModifiedCommit.getName),
+ files,
+ readme,
+ hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
+ getPullRequestFromBranch(
+ repository.owner,
+ repository.name,
+ revstr,
+ repository.repository.defaultBranch
+ ),
+ flash.get("info"),
+ flash.get("error")
+ )
+ }
} getOrElse NotFound()
}
}
@@ -874,11 +1070,11 @@
private def archiveRepository(name: String, suffix: String, repository: RepositoryService.RepositoryInfo): Unit = {
val revision = name.stripSuffix(suffix)
- using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getRepositoryDir(repository.owner, repository.name))) { git =>
val oid = git.getRepository.resolve(revision)
val revCommit = JGitUtil.getRevCommitFromId(git, oid)
val sha1 = oid.getName()
- val repositorySuffix = (if(sha1.startsWith(revision)) sha1 else revision).replace('/','-')
+ val repositorySuffix = (if (sha1.startsWith(revision)) sha1 else revision).replace('/', '-')
val filename = repository.name + "-" + repositorySuffix + suffix
contentType = "application/octet-stream"
@@ -886,28 +1082,28 @@
response.setBufferSize(1024 * 1024);
git.archive
- .setFormat(suffix.tail)
- .setPrefix(repository.name + "-" + repositorySuffix + "/")
- .setTree(revCommit)
- .setOutputStream(response.getOutputStream)
- .call()
+ .setFormat(suffix.tail)
+ .setPrefix(repository.name + "-" + repositorySuffix + "/")
+ .setTree(revCommit)
+ .setOutputStream(response.getOutputStream)
+ .call()
}
}
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
- private def conflict: Constraint = new Constraint(){
+ private def conflict: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
- val owner = params("owner")
+ val owner = params("owner")
val repository = params("repository")
- val branch = params("branch")
+ val branch = params("branch")
LockUtil.lock(s"${owner}/${repository}") {
using(Git.open(getRepositoryDir(owner, repository))) { git =>
val headName = s"refs/heads/${branch}"
val headTip = git.getRepository.resolve(headName)
- if(headTip.getName != value){
+ if (headTip.getName != value) {
Some("Someone pushed new commits before you. Please reload this page and re-apply your changes.")
} else {
None
@@ -917,7 +1113,9 @@
}
}
- override protected def renderUncaughtException(e: Throwable)(implicit request: HttpServletRequest, response: HttpServletResponse): Unit = {
+ override protected def renderUncaughtException(
+ e: Throwable
+ )(implicit request: HttpServletRequest, response: HttpServletResponse): Unit = {
e.printStackTrace()
}
diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala
index 5629dec..d2d0649 100644
--- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala
+++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala
@@ -23,8 +23,11 @@
import scala.collection.JavaConverters._
import scala.collection.mutable.ListBuffer
-class SystemSettingsController extends SystemSettingsControllerBase
- with AccountService with RepositoryService with AdminAuthenticator
+class SystemSettingsController
+ extends SystemSettingsControllerBase
+ with AccountService
+ with RepositoryService
+ with AdminAuthenticator
case class Table(name: String, columns: Seq[Column])
case class Column(name: String, primaryKey: Boolean)
@@ -33,72 +36,81 @@
self: AccountService with RepositoryService with AdminAuthenticator =>
private val form = mapping(
- "baseUrl" -> trim(label("Base URL", optional(text()))),
- "information" -> trim(label("Information", optional(text()))),
+ "baseUrl" -> trim(label("Base URL", optional(text()))),
+ "information" -> trim(label("Information", optional(text()))),
"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())),
- "gravatar" -> trim(label("Gravatar", boolean())),
- "notification" -> trim(label("Notification", boolean())),
- "activityLogLimit" -> trim(label("Limit of activity logs", optional(number()))),
- "ssh" -> trim(label("SSH access", boolean())),
- "sshHost" -> trim(label("SSH host", optional(text()))),
- "sshPort" -> trim(label("SSH port", optional(number()))),
- "useSMTP" -> trim(label("SMTP", boolean())),
- "smtp" -> optionalIfNotChecked("useSMTP", mapping(
- "host" -> trim(label("SMTP Host", text(required))),
- "port" -> trim(label("SMTP Port", optional(number()))),
- "user" -> trim(label("SMTP User", optional(text()))),
- "password" -> trim(label("SMTP Password", optional(text()))),
- "ssl" -> trim(label("Enable SSL", optional(boolean()))),
- "starttls" -> trim(label("Enable STARTTLS", optional(boolean()))),
- "fromAddress" -> trim(label("FROM Address", optional(text()))),
- "fromName" -> trim(label("FROM Name", optional(text())))
- )(Smtp.apply)),
- "ldapAuthentication" -> trim(label("LDAP", boolean())),
- "ldap" -> optionalIfNotChecked("ldapAuthentication", mapping(
- "host" -> trim(label("LDAP host", text(required))),
- "port" -> trim(label("LDAP port", optional(number()))),
- "bindDN" -> trim(label("Bind DN", optional(text()))),
- "bindPassword" -> trim(label("Bind Password", optional(text()))),
- "baseDN" -> trim(label("Base DN", text(required))),
- "userNameAttribute" -> trim(label("User name attribute", text(required))),
- "additionalFilterCondition"-> trim(label("Additional filter condition", optional(text()))),
- "fullNameAttribute" -> trim(label("Full name attribute", optional(text()))),
- "mailAttribute" -> trim(label("Mail address attribute", optional(text()))),
- "tls" -> trim(label("Enable TLS", optional(boolean()))),
- "ssl" -> trim(label("Enable SSL", optional(boolean()))),
- "keystore" -> trim(label("Keystore", optional(text())))
- )(Ldap.apply)),
- "oidcAuthentication" -> trim(label("OIDC", boolean())),
- "oidc" -> optionalIfNotChecked("oidcAuthentication", mapping(
- "issuer" -> trim(label("Issuer", text(required))),
- "clientID" -> trim(label("Client ID", text(required))),
- "clientSecret" -> trim(label("Client secret", text(required))),
- "jwsAlgorithm" -> trim(label("Signature algorithm", optional(text())))
- )(OIDC.apply)),
+ "gravatar" -> trim(label("Gravatar", boolean())),
+ "notification" -> trim(label("Notification", boolean())),
+ "activityLogLimit" -> trim(label("Limit of activity logs", optional(number()))),
+ "ssh" -> trim(label("SSH access", boolean())),
+ "sshHost" -> trim(label("SSH host", optional(text()))),
+ "sshPort" -> trim(label("SSH port", optional(number()))),
+ "useSMTP" -> trim(label("SMTP", boolean())),
+ "smtp" -> optionalIfNotChecked(
+ "useSMTP",
+ mapping(
+ "host" -> trim(label("SMTP Host", text(required))),
+ "port" -> trim(label("SMTP Port", optional(number()))),
+ "user" -> trim(label("SMTP User", optional(text()))),
+ "password" -> trim(label("SMTP Password", optional(text()))),
+ "ssl" -> trim(label("Enable SSL", optional(boolean()))),
+ "starttls" -> trim(label("Enable STARTTLS", optional(boolean()))),
+ "fromAddress" -> trim(label("FROM Address", optional(text()))),
+ "fromName" -> trim(label("FROM Name", optional(text())))
+ )(Smtp.apply)
+ ),
+ "ldapAuthentication" -> trim(label("LDAP", boolean())),
+ "ldap" -> optionalIfNotChecked(
+ "ldapAuthentication",
+ mapping(
+ "host" -> trim(label("LDAP host", text(required))),
+ "port" -> trim(label("LDAP port", optional(number()))),
+ "bindDN" -> trim(label("Bind DN", optional(text()))),
+ "bindPassword" -> trim(label("Bind Password", optional(text()))),
+ "baseDN" -> trim(label("Base DN", text(required))),
+ "userNameAttribute" -> trim(label("User name attribute", text(required))),
+ "additionalFilterCondition" -> trim(label("Additional filter condition", optional(text()))),
+ "fullNameAttribute" -> trim(label("Full name attribute", optional(text()))),
+ "mailAttribute" -> trim(label("Mail address attribute", optional(text()))),
+ "tls" -> trim(label("Enable TLS", optional(boolean()))),
+ "ssl" -> trim(label("Enable SSL", optional(boolean()))),
+ "keystore" -> trim(label("Keystore", optional(text())))
+ )(Ldap.apply)
+ ),
+ "oidcAuthentication" -> trim(label("OIDC", boolean())),
+ "oidc" -> optionalIfNotChecked(
+ "oidcAuthentication",
+ mapping(
+ "issuer" -> trim(label("Issuer", text(required))),
+ "clientID" -> trim(label("Client ID", text(required))),
+ "clientSecret" -> trim(label("Client secret", text(required))),
+ "jwsAlgorithm" -> trim(label("Signature algorithm", optional(text())))
+ )(OIDC.apply)
+ ),
"skinName" -> trim(label("AdminLTE skin name", text(required)))
)(SystemSettings.apply).verifying { settings =>
Vector(
- if(settings.ssh && settings.baseUrl.isEmpty){
+ if (settings.ssh && settings.baseUrl.isEmpty) {
Some("baseUrl" -> "Base URL is required if SSH access is enabled.")
} else None,
- if(settings.ssh && settings.sshHost.isEmpty){
+ if (settings.ssh && settings.sshHost.isEmpty) {
Some("sshHost" -> "SSH host is required if SSH access is enabled.")
} else None
).flatten
}
private val sendMailForm = mapping(
- "smtp" -> mapping(
- "host" -> trim(label("SMTP Host", text(required))),
- "port" -> trim(label("SMTP Port", optional(number()))),
- "user" -> trim(label("SMTP User", optional(text()))),
- "password" -> trim(label("SMTP Password", optional(text()))),
- "ssl" -> trim(label("Enable SSL", optional(boolean()))),
- "starttls" -> trim(label("Enable STARTTLS", optional(boolean()))),
+ "smtp" -> mapping(
+ "host" -> trim(label("SMTP Host", text(required))),
+ "port" -> trim(label("SMTP Port", optional(number()))),
+ "user" -> trim(label("SMTP User", optional(text()))),
+ "password" -> trim(label("SMTP Password", optional(text()))),
+ "ssl" -> trim(label("Enable SSL", optional(boolean()))),
+ "starttls" -> trim(label("Enable STARTTLS", optional(boolean()))),
"fromAddress" -> trim(label("FROM Address", optional(text()))),
- "fromName" -> trim(label("FROM Name", optional(text())))
+ "fromName" -> trim(label("FROM Name", optional(text())))
)(Smtp.apply),
"testAddress" -> trim(label("", text(required)))
)(SendMailForm.apply)
@@ -107,126 +119,156 @@
case class DataExportForm(tableNames: List[String])
- case class NewUserForm(userName: String, password: String, fullName: String,
- mailAddress: String, isAdmin: Boolean,
- description: Option[String], url: Option[String], fileId: Option[String])
+ case class NewUserForm(
+ userName: String,
+ password: String,
+ fullName: String,
+ mailAddress: String,
+ isAdmin: Boolean,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String]
+ )
- case class EditUserForm(userName: String, password: Option[String], fullName: String,
- mailAddress: String, isAdmin: Boolean, description: Option[String], url: Option[String],
- fileId: Option[String], clearImage: Boolean, isRemoved: Boolean)
+ case class EditUserForm(
+ userName: String,
+ password: Option[String],
+ fullName: String,
+ mailAddress: String,
+ isAdmin: Boolean,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ clearImage: Boolean,
+ isRemoved: Boolean
+ )
- case class NewGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String],
- members: String)
+ case class NewGroupForm(
+ groupName: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ members: String
+ )
- case class EditGroupForm(groupName: String, description: Option[String], url: Option[String], fileId: Option[String],
- members: String, clearImage: Boolean, isRemoved: Boolean)
-
+ case class EditGroupForm(
+ groupName: String,
+ description: Option[String],
+ url: Option[String],
+ fileId: Option[String],
+ members: String,
+ clearImage: Boolean,
+ isRemoved: Boolean
+ )
val newUserForm = mapping(
- "userName" -> trim(label("Username" ,text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
- "password" -> trim(label("Password" ,text(required, maxlength(20), password))),
- "fullName" -> trim(label("Full Name" ,text(required, maxlength(100)))),
- "mailAddress" -> trim(label("Mail Address" ,text(required, maxlength(100), uniqueMailAddress()))),
- "isAdmin" -> trim(label("User Type" ,boolean())),
- "description" -> trim(label("bio" ,optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text())))
+ "userName" -> trim(label("Username", text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
+ "password" -> trim(label("Password", text(required, maxlength(20), password))),
+ "fullName" -> trim(label("Full Name", text(required, maxlength(100)))),
+ "mailAddress" -> trim(label("Mail Address", text(required, maxlength(100), uniqueMailAddress()))),
+ "isAdmin" -> trim(label("User Type", boolean())),
+ "description" -> trim(label("bio", optional(text()))),
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text())))
)(NewUserForm.apply)
val editUserForm = mapping(
- "userName" -> trim(label("Username" ,text(required, maxlength(100), identifier))),
- "password" -> trim(label("Password" ,optional(text(maxlength(20), password)))),
- "fullName" -> trim(label("Full Name" ,text(required, maxlength(100)))),
- "mailAddress" -> trim(label("Mail Address" ,text(required, maxlength(100), uniqueMailAddress("userName")))),
- "isAdmin" -> trim(label("User Type" ,boolean())),
- "description" -> trim(label("bio" ,optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text()))),
- "clearImage" -> trim(label("Clear image" ,boolean())),
- "removed" -> trim(label("Disable" ,boolean(disableByNotYourself("userName"))))
+ "userName" -> trim(label("Username", text(required, maxlength(100), identifier))),
+ "password" -> trim(label("Password", optional(text(maxlength(20), password)))),
+ "fullName" -> trim(label("Full Name", text(required, maxlength(100)))),
+ "mailAddress" -> trim(label("Mail Address", text(required, maxlength(100), uniqueMailAddress("userName")))),
+ "isAdmin" -> trim(label("User Type", boolean())),
+ "description" -> trim(label("bio", optional(text()))),
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "clearImage" -> trim(label("Clear image", boolean())),
+ "removed" -> trim(label("Disable", boolean(disableByNotYourself("userName"))))
)(EditUserForm.apply)
val newGroupForm = mapping(
- "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
+ "groupName" -> trim(label("Group name", text(required, maxlength(100), identifier, uniqueUserName, reservedNames))),
"description" -> trim(label("Group description", optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text()))),
- "members" -> trim(label("Members" ,text(required, members)))
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "members" -> trim(label("Members", text(required, members)))
)(NewGroupForm.apply)
val editGroupForm = mapping(
- "groupName" -> trim(label("Group name" ,text(required, maxlength(100), identifier))),
+ "groupName" -> trim(label("Group name", text(required, maxlength(100), identifier))),
"description" -> trim(label("Group description", optional(text()))),
- "url" -> trim(label("URL" ,optional(text(maxlength(200))))),
- "fileId" -> trim(label("File ID" ,optional(text()))),
- "members" -> trim(label("Members" ,text(required, members))),
- "clearImage" -> trim(label("Clear image" ,boolean())),
- "removed" -> trim(label("Disable" ,boolean()))
+ "url" -> trim(label("URL", optional(text(maxlength(200))))),
+ "fileId" -> trim(label("File ID", optional(text()))),
+ "members" -> trim(label("Members", text(required, members))),
+ "clearImage" -> trim(label("Clear image", boolean())),
+ "removed" -> trim(label("Disable", boolean()))
)(EditGroupForm.apply)
-
get("/admin/dbviewer")(adminOnly {
val conn = request2Session(request).conn
val meta = conn.getMetaData
val tables = ListBuffer[Table]()
- using(meta.getTables(null, "%", "%", Array("TABLE", "VIEW"))){ rs =>
- while(rs.next()){
- val tableName = rs.getString("TABLE_NAME")
+ using(meta.getTables(null, "%", "%", Array("TABLE", "VIEW"))) {
+ rs =>
+ while (rs.next()) {
+ val tableName = rs.getString("TABLE_NAME")
- val pkColumns = ListBuffer[String]()
- using(meta.getPrimaryKeys(null, null, tableName)){ rs =>
- while(rs.next()){
- pkColumns += rs.getString("COLUMN_NAME").toUpperCase
+ val pkColumns = ListBuffer[String]()
+ using(meta.getPrimaryKeys(null, null, tableName)) { rs =>
+ while (rs.next()) {
+ pkColumns += rs.getString("COLUMN_NAME").toUpperCase
+ }
}
- }
- val columns = ListBuffer[Column]()
- using(meta.getColumns(null, "%", tableName, "%")){ rs =>
- while(rs.next()){
- val columnName = rs.getString("COLUMN_NAME").toUpperCase
- columns += Column(columnName, pkColumns.contains(columnName))
+ val columns = ListBuffer[Column]()
+ using(meta.getColumns(null, "%", tableName, "%")) { rs =>
+ while (rs.next()) {
+ val columnName = rs.getString("COLUMN_NAME").toUpperCase
+ columns += Column(columnName, pkColumns.contains(columnName))
+ }
}
- }
- tables += Table(tableName.toUpperCase, columns)
- }
+ tables += Table(tableName.toUpperCase, columns)
+ }
}
html.dbviewer(tables)
})
post("/admin/dbviewer/_query")(adminOnly {
contentType = formats("json")
- params.get("query").collectFirst { case query if query.trim.nonEmpty =>
- val trimmedQuery = query.trim
- if(trimmedQuery.nonEmpty){
- try {
- val conn = request2Session(request).conn
- using(conn.prepareStatement(query)){ stmt =>
- if(trimmedQuery.toUpperCase.startsWith("SELECT")){
- using(stmt.executeQuery()){ rs =>
- val meta = rs.getMetaData
- val columns = for(i <- 1 to meta.getColumnCount) yield {
- meta.getColumnName(i)
+ params.get("query").collectFirst {
+ case query if query.trim.nonEmpty =>
+ val trimmedQuery = query.trim
+ if (trimmedQuery.nonEmpty) {
+ try {
+ val conn = request2Session(request).conn
+ using(conn.prepareStatement(query)) {
+ stmt =>
+ if (trimmedQuery.toUpperCase.startsWith("SELECT")) {
+ using(stmt.executeQuery()) {
+ rs =>
+ val meta = rs.getMetaData
+ val columns = for (i <- 1 to meta.getColumnCount) yield {
+ meta.getColumnName(i)
+ }
+ val result = ListBuffer[Map[String, String]]()
+ while (rs.next()) {
+ val row = columns.map { columnName =>
+ columnName -> Option(rs.getObject(columnName)).map(_.toString).getOrElse("")
+ }.toMap
+ result += row
+ }
+ Ok(Serialization.write(Map("type" -> "query", "columns" -> columns, "rows" -> result)))
+ }
+ } else {
+ val rows = stmt.executeUpdate()
+ Ok(Serialization.write(Map("type" -> "update", "rows" -> rows)))
}
- val result = ListBuffer[Map[String, String]]()
- while(rs.next()){
- val row = columns.map { columnName =>
- columnName -> Option(rs.getObject(columnName)).map(_.toString).getOrElse("")
- }.toMap
- result += row
- }
- Ok(Serialization.write(Map("type" -> "query", "columns" -> columns, "rows" -> result)))
- }
- } else {
- val rows = stmt.executeUpdate()
- Ok(Serialization.write(Map("type" -> "update", "rows" -> rows)))
}
+ } catch {
+ case e: Exception =>
+ Ok(Serialization.write(Map("type" -> "error", "message" -> e.toString)))
}
- } catch {
- case e: Exception =>
- Ok(Serialization.write(Map("type" -> "error", "message" -> e.toString)))
}
- }
} getOrElse Ok(Serialization.write(Map("type" -> "error", "message" -> "query is empty")))
})
@@ -239,11 +281,10 @@
if (form.sshAddress != context.settings.sshAddress) {
SshServer.stop()
- for {
- sshAddress <- form.sshAddress
- baseUrl <- form.baseUrl
- }
- SshServer.start(sshAddress, baseUrl)
+ for {
+ sshAddress <- form.sshAddress
+ baseUrl <- form.baseUrl
+ } SshServer.start(sshAddress, baseUrl)
}
flash += "info" -> "System settings has been updated."
@@ -253,10 +294,10 @@
post("/admin/system/sendmail", sendMailForm)(adminOnly { form =>
try {
new Mailer(context.settings.copy(smtp = Some(form.smtp), notification = true)).send(
- to = form.testAddress,
- subject = "Test message from GitBucket",
- textMsg = "This is a test message from GitBucket.",
- htmlMsg = None,
+ to = form.testAddress,
+ subject = "Test message from GitBucket",
+ textMsg = "This is a test message from GitBucket.",
+ htmlMsg = None,
loginAccount = context.loginAccount
)
@@ -274,20 +315,27 @@
val gitbucketVersion = Semver.valueOf(GitBucketCoreModule.getVersions.asScala.last.getVersion)
// Plugins in the local repository
- val repositoryPlugins = PluginRepository.getPlugins()
+ val repositoryPlugins = PluginRepository
+ .getPlugins()
.filterNot { meta =>
- enabledPlugins.exists { plugin => plugin.pluginId == meta.id &&
+ enabledPlugins.exists { plugin =>
+ plugin.pluginId == meta.id &&
Semver.valueOf(plugin.pluginVersion).greaterThanOrEqualTo(Semver.valueOf(meta.latestVersion.version))
}
- }.map { meta =>
- (meta, meta.versions.reverse.find { version => gitbucketVersion.satisfies(version.range) })
- }.collect { case (meta, Some(version)) =>
- new PluginInfoBase(
- pluginId = meta.id,
- pluginName = meta.name,
- pluginVersion = version.version,
- description = meta.description
- )
+ }
+ .map { meta =>
+ (meta, meta.versions.reverse.find { version =>
+ gitbucketVersion.satisfies(version.range)
+ })
+ }
+ .collect {
+ case (meta, Some(version)) =>
+ new PluginInfoBase(
+ pluginId = meta.id,
+ pluginName = meta.name,
+ pluginVersion = version.version,
+ description = meta.description
+ )
}
// Merge
@@ -304,11 +352,13 @@
post("/admin/plugins/:pluginId/:version/_uninstall")(adminOnly {
val pluginId = params("pluginId")
- val version = params("version")
- PluginRegistry().getPlugins()
+ val version = params("version")
+ PluginRegistry()
+ .getPlugins()
.collect { case plugin if (plugin.pluginId == pluginId && plugin.pluginVersion == version) => plugin }
.foreach { _ =>
- PluginRegistry.uninstall(pluginId, request.getServletContext, loadSystemSettings(), request2Session(request).conn)
+ PluginRegistry
+ .uninstall(pluginId, request.getServletContext, loadSystemSettings(), request2Session(request).conn)
flash += "info" -> s"${pluginId} was uninstalled."
}
redirect("/admin/plugins")
@@ -316,32 +366,34 @@
post("/admin/plugins/:pluginId/:version/_install")(adminOnly {
val pluginId = params("pluginId")
- val version = params("version")
+ val version = params("version")
/// TODO!!!!
- PluginRepository.getPlugins()
- .collect { case meta if meta.id == pluginId => (meta, meta.versions.find(_.version == version) )}
- .foreach { case (meta, version) =>
- version.foreach { version =>
- // TODO Install version!
- PluginRegistry.install(
- new java.io.File(PluginHome, s".repository/${version.file}"),
- request.getServletContext,
- loadSystemSettings(),
- request2Session(request).conn
- )
- flash += "info" -> s"${pluginId} was installed."
- }
+ PluginRepository
+ .getPlugins()
+ .collect { case meta if meta.id == pluginId => (meta, meta.versions.find(_.version == version)) }
+ .foreach {
+ case (meta, version) =>
+ version.foreach { version =>
+ // TODO Install version!
+ PluginRegistry.install(
+ new java.io.File(PluginHome, s".repository/${version.file}"),
+ request.getServletContext,
+ loadSystemSettings(),
+ request2Session(request).conn
+ )
+ flash += "info" -> s"${pluginId} was installed."
+ }
}
redirect("/admin/plugins")
})
-
get("/admin/users")(adminOnly {
val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false)
val includeGroups = params.get("includeGroups").map(_.toBoolean).getOrElse(false)
- val users = getAllUsers(includeRemoved, includeGroups)
- val members = users.collect { case account if(account.isGroupAccount) =>
- account.userName -> getGroupMembers(account.userName).map(_.userName)
+ val users = getAllUsers(includeRemoved, includeGroups)
+ val members = users.collect {
+ case account if (account.isGroupAccount) =>
+ account.userName -> getGroupMembers(account.userName).map(_.userName)
}.toMap
html.userlist(users, members, includeRemoved, includeGroups)
@@ -352,7 +404,15 @@
})
post("/admin/users/_newuser", newUserForm)(adminOnly { form =>
- createAccount(form.userName, sha1(form.password), form.fullName, form.mailAddress, form.isAdmin, form.description, form.url)
+ createAccount(
+ form.userName,
+ sha1(form.password),
+ form.fullName,
+ form.mailAddress,
+ form.isAdmin,
+ form.description,
+ form.url
+ )
updateImage(form.userName, form.fileId, false)
redirect("/admin/users")
})
@@ -364,39 +424,43 @@
post("/admin/users/:name/_edituser", editUserForm)(adminOnly { form =>
val userName = params("userName")
- getAccountByUserName(userName, true).map { account =>
- if(account.isAdmin && (form.isRemoved || !form.isAdmin) && isLastAdministrator(account)){
- flash += "error" -> "Account can't be turned off because this is last one administrator."
- redirect(s"/admin/users/${userName}/_edituser")
- } else {
- if(form.isRemoved){
- // Remove repositories
- // getRepositoryNamesOfUser(userName).foreach { repositoryName =>
- // deleteRepository(userName, repositoryName)
- // FileUtils.deleteDirectory(getRepositoryDir(userName, repositoryName))
- // FileUtils.deleteDirectory(getWikiRepositoryDir(userName, repositoryName))
- // FileUtils.deleteDirectory(getTemporaryDir(userName, repositoryName))
- // }
- // Remove from GROUP_MEMBER and COLLABORATOR
- removeUserRelatedData(userName)
+ getAccountByUserName(userName, true).map {
+ account =>
+ if (account.isAdmin && (form.isRemoved || !form.isAdmin) && isLastAdministrator(account)) {
+ flash += "error" -> "Account can't be turned off because this is last one administrator."
+ redirect(s"/admin/users/${userName}/_edituser")
+ } else {
+ if (form.isRemoved) {
+ // Remove repositories
+ // getRepositoryNamesOfUser(userName).foreach { repositoryName =>
+ // deleteRepository(userName, repositoryName)
+ // FileUtils.deleteDirectory(getRepositoryDir(userName, repositoryName))
+ // FileUtils.deleteDirectory(getWikiRepositoryDir(userName, repositoryName))
+ // FileUtils.deleteDirectory(getTemporaryDir(userName, repositoryName))
+ // }
+ // Remove from GROUP_MEMBER and COLLABORATOR
+ removeUserRelatedData(userName)
+ }
+
+ updateAccount(
+ account.copy(
+ password = form.password.map(sha1).getOrElse(account.password),
+ fullName = form.fullName,
+ mailAddress = form.mailAddress,
+ isAdmin = form.isAdmin,
+ description = form.description,
+ url = form.url,
+ isRemoved = form.isRemoved
+ )
+ )
+
+ updateImage(userName, form.fileId, form.clearImage)
+
+ // call hooks
+ if (form.isRemoved) PluginRegistry().getAccountHooks.foreach(_.deleted(userName))
+
+ redirect("/admin/users")
}
-
- updateAccount(account.copy(
- password = form.password.map(sha1).getOrElse(account.password),
- fullName = form.fullName,
- mailAddress = form.mailAddress,
- isAdmin = form.isAdmin,
- description = form.description,
- url = form.url,
- isRemoved = form.isRemoved))
-
- updateImage(userName, form.fileId, form.clearImage)
-
- // call hooks
- if(form.isRemoved) PluginRegistry().getAccountHooks.foreach(_.deleted(userName))
-
- redirect("/admin/users")
- }
} getOrElse NotFound()
})
@@ -406,33 +470,47 @@
post("/admin/users/_newgroup", newGroupForm)(adminOnly { form =>
createGroup(form.groupName, form.description, form.url)
- updateGroupMembers(form.groupName, form.members.split(",").map {
- _.split(":") match {
- case Array(userName, isManager) => (userName, isManager.toBoolean)
- }
- }.toList)
+ updateGroupMembers(
+ form.groupName,
+ form.members
+ .split(",")
+ .map {
+ _.split(":") match {
+ case Array(userName, isManager) => (userName, isManager.toBoolean)
+ }
+ }
+ .toList
+ )
updateImage(form.groupName, form.fileId, false)
redirect("/admin/users")
})
get("/admin/users/:groupName/_editgroup")(adminOnly {
- defining(params("groupName")){ groupName =>
+ defining(params("groupName")) { groupName =>
html.usergroup(getAccountByUserName(groupName, true), getGroupMembers(groupName))
}
})
post("/admin/users/:groupName/_editgroup", editGroupForm)(adminOnly { form =>
- defining(params("groupName"), form.members.split(",").map {
- _.split(":") match {
- case Array(userName, isManager) => (userName, isManager.toBoolean)
- }
- }.toList){ case (groupName, members) =>
- getAccountByUserName(groupName, true).map { account =>
- updateGroup(groupName, form.description, form.url, form.isRemoved)
+ defining(
+ params("groupName"),
+ form.members
+ .split(",")
+ .map {
+ _.split(":") match {
+ case Array(userName, isManager) => (userName, isManager.toBoolean)
+ }
+ }
+ .toList
+ ) {
+ case (groupName, members) =>
+ getAccountByUserName(groupName, true).map {
+ account =>
+ updateGroup(groupName, form.description, form.url, form.isRemoved)
- if(form.isRemoved){
- // Remove from GROUP_MEMBER
- updateGroupMembers(form.groupName, Nil)
+ if (form.isRemoved) {
+ // Remove from GROUP_MEMBER
+ updateGroupMembers(form.groupName, Nil)
// // Remove repositories
// getRepositoryNamesOfUser(form.groupName).foreach { repositoryName =>
// deleteRepository(groupName, repositoryName)
@@ -440,9 +518,9 @@
// FileUtils.deleteDirectory(getWikiRepositoryDir(groupName, repositoryName))
// FileUtils.deleteDirectory(getTemporaryDir(groupName, repositoryName))
// }
- } else {
- // Update GROUP_MEMBER
- updateGroupMembers(form.groupName, members)
+ } else {
+ // Update GROUP_MEMBER
+ updateGroupMembers(form.groupName, members)
// // Update COLLABORATOR for group repositories
// getRepositoryNamesOfUser(form.groupName).foreach { repositoryName =>
// removeCollaborators(form.groupName, repositoryName)
@@ -450,12 +528,12 @@
// addCollaborator(form.groupName, repositoryName, userName)
// }
// }
- }
+ }
- updateImage(form.groupName, form.fileId, form.clearImage)
- redirect("/admin/users")
+ updateImage(form.groupName, form.fileId, form.clearImage)
+ redirect("/admin/users")
- } getOrElse NotFound()
+ } getOrElse NotFound()
}
})
@@ -473,25 +551,26 @@
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName)
response.setContentLength(file.length.toInt)
- using(new FileInputStream(file)){ in =>
+ using(new FileInputStream(file)) { in =>
IOUtils.copy(in, response.outputStream)
}
()
})
- private def members: Constraint = new Constraint(){
+ private def members: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
- if(value.split(",").exists {
- _.split(":") match { case Array(userName, isManager) => isManager.toBoolean }
- }) None else Some("Must select one manager at least.")
+ if (value.split(",").exists {
+ _.split(":") match { case Array(userName, isManager) => isManager.toBoolean }
+ }) None
+ else Some("Must select one manager at least.")
}
}
protected def disableByNotYourself(paramName: String): Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
params.get(paramName).flatMap { userName =>
- if(userName == context.loginAccount.get.userName && params.get("removed") == Some("true"))
+ if (userName == context.loginAccount.get.userName && params.get("removed") == Some("true"))
Some("You can't disable your account yourself")
else
None
diff --git a/src/main/scala/gitbucket/core/controller/ValidationSupport.scala b/src/main/scala/gitbucket/core/controller/ValidationSupport.scala
index 9c3e02b..8e403f6 100644
--- a/src/main/scala/gitbucket/core/controller/ValidationSupport.scala
+++ b/src/main/scala/gitbucket/core/controller/ValidationSupport.scala
@@ -14,58 +14,58 @@
def get[T](path: String, form: ValueType[T])(action: T => Any): Route = {
registerValidate(path, form)
- get(path){
+ get(path) {
validate(form)(errors => BadRequest(), form => action(form))
}
}
def post[T](path: String, form: ValueType[T])(action: T => Any): Route = {
registerValidate(path, form)
- post(path){
+ post(path) {
validate(form)(errors => BadRequest(), form => action(form))
}
}
def put[T](path: String, form: ValueType[T])(action: T => Any): Route = {
registerValidate(path, form)
- put(path){
+ put(path) {
validate(form)(errors => BadRequest(), form => action(form))
}
}
def delete[T](path: String, form: ValueType[T])(action: T => Any): Route = {
registerValidate(path, form)
- delete(path){
+ delete(path) {
validate(form)(errors => BadRequest(), form => action(form))
}
}
def ajaxGet[T](path: String, form: ValueType[T])(action: T => Any): Route = {
- get(path){
+ get(path) {
validate(form)(errors => ajaxError(errors), form => action(form))
}
}
def ajaxPost[T](path: String, form: ValueType[T])(action: T => Any): Route = {
- post(path){
+ post(path) {
validate(form)(errors => ajaxError(errors), form => action(form))
}
}
def ajaxDelete[T](path: String, form: ValueType[T])(action: T => Any): Route = {
- delete(path){
+ delete(path) {
validate(form)(errors => ajaxError(errors), form => action(form))
}
}
def ajaxPut[T](path: String, form: ValueType[T])(action: T => Any): Route = {
- put(path){
+ put(path) {
validate(form)(errors => ajaxError(errors), form => action(form))
}
}
private def registerValidate[T](path: String, form: ValueType[T]) = {
- post(path.replaceFirst("/$", "") + "/validate"){
+ post(path.replaceFirst("/$", "") + "/validate") {
contentType = "application/json"
toJson(form.validate("", multiParams, messages))
}
@@ -84,8 +84,9 @@
* Converts errors to JSON.
*/
private def toJson(errors: Seq[(String, String)]): JObject =
- JObject(errors.map { case (key, value) =>
- JField(key, JString(value))
+ JObject(errors.map {
+ case (key, value) =>
+ JField(key, JString(value))
}.toList)
}
diff --git a/src/main/scala/gitbucket/core/controller/WikiController.scala b/src/main/scala/gitbucket/core/controller/WikiController.scala
index 5349fb9..2298971 100644
--- a/src/main/scala/gitbucket/core/controller/WikiController.scala
+++ b/src/main/scala/gitbucket/core/controller/WikiController.scala
@@ -14,38 +14,60 @@
import org.eclipse.jgit.api.Git
import org.scalatra.i18n.Messages
-class WikiController extends WikiControllerBase
- with WikiService with RepositoryService with AccountService with ActivityService with WebHookService
- with ReadableUsersAuthenticator with ReferrerAuthenticator
+class WikiController
+ extends WikiControllerBase
+ with WikiService
+ with RepositoryService
+ with AccountService
+ with ActivityService
+ with WebHookService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator
trait WikiControllerBase extends ControllerBase {
- self: WikiService with RepositoryService with AccountService with ActivityService with WebHookService
- with ReadableUsersAuthenticator with ReferrerAuthenticator =>
+ self: WikiService
+ with RepositoryService
+ with AccountService
+ with ActivityService
+ with WebHookService
+ with ReadableUsersAuthenticator
+ with ReferrerAuthenticator =>
- case class WikiPageEditForm(pageName: String, content: String, message: Option[String], currentPageName: String, id: String)
+ case class WikiPageEditForm(
+ pageName: String,
+ content: String,
+ message: Option[String],
+ currentPageName: String,
+ id: String
+ )
val newForm = mapping(
- "pageName" -> trim(label("Page name" , text(required, maxlength(40), pagename, unique))),
- "content" -> trim(label("Content" , text(required, conflictForNew))),
- "message" -> trim(label("Message" , optional(text()))),
- "currentPageName" -> trim(label("Current page name" , text())),
- "id" -> trim(label("Latest commit id" , text()))
+ "pageName" -> trim(label("Page name", text(required, maxlength(40), pagename, unique))),
+ "content" -> trim(label("Content", text(required, conflictForNew))),
+ "message" -> trim(label("Message", optional(text()))),
+ "currentPageName" -> trim(label("Current page name", text())),
+ "id" -> trim(label("Latest commit id", text()))
)(WikiPageEditForm.apply)
val editForm = mapping(
- "pageName" -> trim(label("Page name" , text(required, maxlength(40), pagename))),
- "content" -> trim(label("Content" , text(required, conflictForEdit))),
- "message" -> trim(label("Message" , optional(text()))),
- "currentPageName" -> trim(label("Current page name" , text(required))),
- "id" -> trim(label("Latest commit id" , text(required)))
+ "pageName" -> trim(label("Page name", text(required, maxlength(40), pagename))),
+ "content" -> trim(label("Content", text(required, conflictForEdit))),
+ "message" -> trim(label("Message", optional(text()))),
+ "currentPageName" -> trim(label("Current page name", text(required))),
+ "id" -> trim(label("Latest commit id", text(required)))
)(WikiPageEditForm.apply)
get("/:owner/:repository/wiki")(referrersOnly { repository =>
getWikiPage(repository.owner, repository.name, "Home").map { page =>
- html.page("Home", page, getWikiPageList(repository.owner, repository.name),
- repository, isEditable(repository),
+ html.page(
+ "Home",
+ page,
+ getWikiPageList(repository.owner, repository.name),
+ repository,
+ isEditable(repository),
getWikiPage(repository.owner, repository.name, "_Sidebar"),
- getWikiPage(repository.owner, repository.name, "_Footer"))
+ getWikiPage(repository.owner, repository.name, "_Footer")
+ )
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/Home/_edit")
})
@@ -53,20 +75,25 @@
val pageName = StringUtil.urlDecode(params("page"))
getWikiPage(repository.owner, repository.name, pageName).map { page =>
- html.page(pageName, page, getWikiPageList(repository.owner, repository.name),
- repository, isEditable(repository),
+ html.page(
+ pageName,
+ page,
+ getWikiPageList(repository.owner, repository.name),
+ repository,
+ isEditable(repository),
getWikiPage(repository.owner, repository.name, "_Sidebar"),
- getWikiPage(repository.owner, repository.name, "_Footer"))
+ getWikiPage(repository.owner, repository.name, "_Footer")
+ )
} getOrElse redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_edit")
})
get("/:owner/:repository/wiki/:page/_history")(referrersOnly { repository =>
val pageName = StringUtil.urlDecode(params("page"))
- using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
JGitUtil.getCommitLog(git, "master", path = pageName + ".md") match {
case Right((logs, hasNext)) => html.history(Some(pageName), logs, repository, isEditable(repository))
- case Left(_) => NotFound()
+ case Left(_) => NotFound()
}
}
})
@@ -75,40 +102,56 @@
val pageName = StringUtil.urlDecode(params("page"))
val Array(from, to) = params("commitId").split("\\.\\.\\.")
- using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
- html.compare(Some(pageName), from, to, JGitUtil.getDiffs(git, Some(from), to, true, false).filter(_.newPath == pageName + ".md"), repository,
- isEditable(repository), flash.get("info"))
+ using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
+ html.compare(
+ Some(pageName),
+ from,
+ to,
+ JGitUtil.getDiffs(git, Some(from), to, true, false).filter(_.newPath == pageName + ".md"),
+ repository,
+ isEditable(repository),
+ flash.get("info")
+ )
}
})
get("/:owner/:repository/wiki/_compare/:commitId")(referrersOnly { repository =>
val Array(from, to) = params("commitId").split("\\.\\.\\.")
- using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
- html.compare(None, from, to, JGitUtil.getDiffs(git, Some(from), to, true, false), repository,
- isEditable(repository), flash.get("info"))
+ using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
+ html.compare(
+ None,
+ from,
+ to,
+ JGitUtil.getDiffs(git, Some(from), to, true, false),
+ repository,
+ isEditable(repository),
+ flash.get("info")
+ )
}
})
get("/:owner/:repository/wiki/:page/_revert/:commitId")(readableUsersOnly { repository =>
- if(isEditable(repository)){
+ if (isEditable(repository)) {
val pageName = StringUtil.urlDecode(params("page"))
val Array(from, to) = params("commitId").split("\\.\\.\\.")
- if(revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, Some(pageName))){
+ if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, Some(pageName))) {
redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}")
} else {
flash += "info" -> "This patch was not able to be reversed."
- redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_compare/${from}...${to}")
+ redirect(
+ s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(pageName)}/_compare/${from}...${to}"
+ )
}
} else Unauthorized()
})
get("/:owner/:repository/wiki/_revert/:commitId")(readableUsersOnly { repository =>
- if(isEditable(repository)){
+ if (isEditable(repository)) {
val Array(from, to) = params("commitId").split("\\.\\.\\.")
- if(revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, None)){
+ if (revertWikiPage(repository.owner, repository.name, from, to, context.loginAccount.get, None)) {
redirect(s"/${repository.owner}/${repository.name}/wiki")
} else {
flash += "info" -> "This patch was not able to be reversed."
@@ -118,85 +161,102 @@
})
get("/:owner/:repository/wiki/:page/_edit")(readableUsersOnly { repository =>
- if(isEditable(repository)){
+ if (isEditable(repository)) {
val pageName = StringUtil.urlDecode(params("page"))
html.edit(pageName, getWikiPage(repository.owner, repository.name, pageName), repository)
} else Unauthorized()
})
post("/:owner/:repository/wiki/_edit", editForm)(readableUsersOnly { (form, repository) =>
- if(isEditable(repository)){
- defining(context.loginAccount.get){ loginAccount =>
- saveWikiPage(
- repository.owner,
- repository.name,
- form.currentPageName,
- form.pageName,
- appendNewLine(convertLineSeparator(form.content, "LF"), "LF"),
- loginAccount,
- form.message.getOrElse(""),
- Some(form.id)
- ).map { commitId =>
- updateLastActivityDate(repository.owner, repository.name)
- recordEditWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName, commitId)
- callWebHookOf(repository.owner, repository.name, WebHook.Gollum){
- getAccountByUserName(repository.owner).map { repositoryUser =>
- WebHookGollumPayload("edited", form.pageName, commitId, repository, repositoryUser, loginAccount)
- }
+ if (isEditable(repository)) {
+ defining(context.loginAccount.get) {
+ loginAccount =>
+ saveWikiPage(
+ repository.owner,
+ repository.name,
+ form.currentPageName,
+ form.pageName,
+ appendNewLine(convertLineSeparator(form.content, "LF"), "LF"),
+ loginAccount,
+ form.message.getOrElse(""),
+ Some(form.id)
+ ).map {
+ commitId =>
+ updateLastActivityDate(repository.owner, repository.name)
+ recordEditWikiPageActivity(
+ repository.owner,
+ repository.name,
+ loginAccount.userName,
+ form.pageName,
+ commitId
+ )
+ callWebHookOf(repository.owner, repository.name, WebHook.Gollum) {
+ getAccountByUserName(repository.owner).map { repositoryUser =>
+ WebHookGollumPayload("edited", form.pageName, commitId, repository, repositoryUser, loginAccount)
+ }
+ }
}
- }
- if(notReservedPageName(form.pageName)) {
- redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
- } else {
- redirect(s"/${repository.owner}/${repository.name}/wiki")
- }
+ if (notReservedPageName(form.pageName)) {
+ redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
+ } else {
+ redirect(s"/${repository.owner}/${repository.name}/wiki")
+ }
}
} else Unauthorized()
})
get("/:owner/:repository/wiki/_new")(readableUsersOnly { repository =>
- if(isEditable(repository)){
+ if (isEditable(repository)) {
html.edit("", None, repository)
} else Unauthorized()
})
post("/:owner/:repository/wiki/_new", newForm)(readableUsersOnly { (form, repository) =>
- if(isEditable(repository)){
- defining(context.loginAccount.get){ loginAccount =>
- saveWikiPage(
- repository.owner,
- repository.name,
- form.currentPageName,
- form.pageName,
- form.content,
- loginAccount,
- form.message.getOrElse(""),
- None
- ).map { commitId =>
- updateLastActivityDate(repository.owner, repository.name)
- recordCreateWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName)
- callWebHookOf(repository.owner, repository.name, WebHook.Gollum){
- getAccountByUserName(repository.owner).map { repositoryUser =>
- WebHookGollumPayload("created", form.pageName, commitId, repository, repositoryUser, loginAccount)
- }
+ if (isEditable(repository)) {
+ defining(context.loginAccount.get) {
+ loginAccount =>
+ saveWikiPage(
+ repository.owner,
+ repository.name,
+ form.currentPageName,
+ form.pageName,
+ form.content,
+ loginAccount,
+ form.message.getOrElse(""),
+ None
+ ).map {
+ commitId =>
+ updateLastActivityDate(repository.owner, repository.name)
+ recordCreateWikiPageActivity(repository.owner, repository.name, loginAccount.userName, form.pageName)
+ callWebHookOf(repository.owner, repository.name, WebHook.Gollum) {
+ getAccountByUserName(repository.owner).map { repositoryUser =>
+ WebHookGollumPayload("created", form.pageName, commitId, repository, repositoryUser, loginAccount)
+ }
+ }
}
- }
- if(notReservedPageName(form.pageName)) {
- redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
- } else {
- redirect(s"/${repository.owner}/${repository.name}/wiki")
- }
+ if (notReservedPageName(form.pageName)) {
+ redirect(s"/${repository.owner}/${repository.name}/wiki/${StringUtil.urlEncode(form.pageName)}")
+ } else {
+ redirect(s"/${repository.owner}/${repository.name}/wiki")
+ }
}
} else Unauthorized()
})
get("/:owner/:repository/wiki/:page/_delete")(readableUsersOnly { repository =>
- if(isEditable(repository)){
+ if (isEditable(repository)) {
val pageName = StringUtil.urlDecode(params("page"))
- defining(context.loginAccount.get){ loginAccount =>
- deleteWikiPage(repository.owner, repository.name, pageName, loginAccount.fullName, loginAccount.mailAddress, s"Destroyed ${pageName}")
+ defining(context.loginAccount.get) { loginAccount =>
+ deleteWikiPage(
+ repository.owner,
+ repository.name,
+ pageName,
+ loginAccount.fullName,
+ loginAccount.mailAddress,
+ s"Destroyed ${pageName}"
+ )
updateLastActivityDate(repository.owner, repository.name)
redirect(s"/${repository.owner}/${repository.name}/wiki")
@@ -209,17 +269,17 @@
})
get("/:owner/:repository/wiki/_history")(referrersOnly { repository =>
- using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
JGitUtil.getCommitLog(git, "master") match {
case Right((logs, hasNext)) => html.history(None, logs, repository, isEditable(repository))
- case Left(_) => NotFound()
+ case Left(_) => NotFound()
}
}
})
get("/:owner/:repository/wiki/_blob/*")(referrersOnly { repository =>
val path = multiParams("splat").head
- using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))){ git =>
+ using(Git.open(getWikiRepositoryDir(repository.owner, repository.name))) { git =>
val revCommit = JGitUtil.getRevCommitFromId(git, git.getRepository.resolve("master"))
getPathObjectId(git, path, revCommit).map { objectId =>
@@ -228,25 +288,32 @@
}
})
- private def unique: Constraint = new Constraint(){
- override def validate(name: String, value: String, params: Map[String, Seq[String]], messages: Messages): Option[String] =
- getWikiPageList(params.value("owner"), params.value("repository")).find(_ == value).map(_ => "Page already exists.")
+ private def unique: Constraint = new Constraint() {
+ override def validate(
+ name: String,
+ value: String,
+ params: Map[String, Seq[String]],
+ messages: Messages
+ ): Option[String] =
+ getWikiPageList(params.value("owner"), params.value("repository"))
+ .find(_ == value)
+ .map(_ => "Page already exists.")
}
- private def pagename: Constraint = new Constraint(){
+ private def pagename: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(value.exists("\\/:*?\"<>|".contains(_))){
+ if (value.exists("\\/:*?\"<>|".contains(_))) {
Some(s"${name} contains invalid character.")
- } else if(notReservedPageName(value) && (value.startsWith("_") || value.startsWith("-"))){
+ } else if (notReservedPageName(value) && (value.startsWith("_") || value.startsWith("-"))) {
Some(s"${name} starts with invalid character.")
} else {
None
}
}
- private def notReservedPageName(value: String) = ! (Array[String]("_Sidebar","_Footer") contains value)
+ private def notReservedPageName(value: String) = !(Array[String]("_Sidebar", "_Footer") contains value)
- private def conflictForNew: Constraint = new Constraint(){
+ private def conflictForNew: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
targetWikiPage.map { _ =>
"Someone has created the wiki since you started. Please reload this page and re-apply your changes."
@@ -254,9 +321,9 @@
}
}
- private def conflictForEdit: Constraint = new Constraint(){
+ private def conflictForEdit: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] = {
- targetWikiPage.filter(_.id != params("id")).map{ _ =>
+ targetWikiPage.filter(_.id != params("id")).map { _ =>
"Someone has edited the wiki since you started. Please reload this page and re-apply your changes."
}
}
diff --git a/src/main/scala/gitbucket/core/model/AccessToken.scala b/src/main/scala/gitbucket/core/model/AccessToken.scala
index a460b90..c952c03 100644
--- a/src/main/scala/gitbucket/core/model/AccessToken.scala
+++ b/src/main/scala/gitbucket/core/model/AccessToken.scala
@@ -1,6 +1,5 @@
package gitbucket.core.model
-
trait AccessTokenComponent { self: Profile =>
import profile.api._
diff --git a/src/main/scala/gitbucket/core/model/Account.scala b/src/main/scala/gitbucket/core/model/Account.scala
index 1f4931e..2379328 100644
--- a/src/main/scala/gitbucket/core/model/Account.scala
+++ b/src/main/scala/gitbucket/core/model/Account.scala
@@ -20,7 +20,22 @@
val groupAccount = column[Boolean]("GROUP_ACCOUNT")
val removed = column[Boolean]("REMOVED")
val description = column[String]("DESCRIPTION")
- def * = (userName, fullName, mailAddress, password, isAdmin, url.?, registeredDate, updatedDate, lastLoginDate.?, image.?, groupAccount, removed, description.?) <> (Account.tupled, Account.unapply)
+ def * =
+ (
+ userName,
+ fullName,
+ mailAddress,
+ password,
+ isAdmin,
+ url.?,
+ registeredDate,
+ updatedDate,
+ lastLoginDate.?,
+ image.?,
+ groupAccount,
+ removed,
+ description.?
+ ) <> (Account.tupled, Account.unapply)
}
}
diff --git a/src/main/scala/gitbucket/core/model/AccountWebHook.scala b/src/main/scala/gitbucket/core/model/AccountWebHook.scala
index df28993..79f0c4b 100644
--- a/src/main/scala/gitbucket/core/model/AccountWebHook.scala
+++ b/src/main/scala/gitbucket/core/model/AccountWebHook.scala
@@ -3,7 +3,8 @@
trait AccountWebHookComponent extends TemplateComponent { self: Profile =>
import profile.api._
- private implicit val whContentTypeColumnType = MappedColumnType.base[WebHookContentType, String](whct => whct.code , code => WebHookContentType.valueOf(code))
+ private implicit val whContentTypeColumnType =
+ MappedColumnType.base[WebHookContentType, String](whct => whct.code, code => WebHookContentType.valueOf(code))
lazy val AccountWebHooks = TableQuery[AccountWebHooks]
diff --git a/src/main/scala/gitbucket/core/model/AccountWebHookEvent.scala b/src/main/scala/gitbucket/core/model/AccountWebHookEvent.scala
index 36ffa3c..f169a36 100644
--- a/src/main/scala/gitbucket/core/model/AccountWebHookEvent.scala
+++ b/src/main/scala/gitbucket/core/model/AccountWebHookEvent.scala
@@ -8,11 +8,13 @@
lazy val AccountWebHookEvents = TableQuery[AccountWebHookEvents]
- class AccountWebHookEvents(tag: Tag) extends Table[AccountWebHookEvent](tag, "ACCOUNT_WEB_HOOK_EVENT") with BasicTemplate {
+ class AccountWebHookEvents(tag: Tag)
+ extends Table[AccountWebHookEvent](tag, "ACCOUNT_WEB_HOOK_EVENT")
+ with BasicTemplate {
val url = column[String]("URL")
val event = column[WebHook.Event]("EVENT")
- def * = (userName, url, event) <> ((AccountWebHookEvent.apply _).tupled, AccountWebHookEvent.unapply)
+ def * = (userName, url, event) <> ((AccountWebHookEvent.apply _).tupled, AccountWebHookEvent.unapply)
def byAccountWebHook(userName: String, url: String) = (this.userName === userName.bind) && (this.url === url.bind)
@@ -28,7 +30,7 @@
}
case class AccountWebHookEvent(
- userName: String,
- url: String,
- event: WebHook.Event
- )
+ userName: String,
+ url: String,
+ event: WebHook.Event
+)
diff --git a/src/main/scala/gitbucket/core/model/Activity.scala b/src/main/scala/gitbucket/core/model/Activity.scala
index 8c5b8bd..35c990e 100644
--- a/src/main/scala/gitbucket/core/model/Activity.scala
+++ b/src/main/scala/gitbucket/core/model/Activity.scala
@@ -13,7 +13,8 @@
val message = column[String]("MESSAGE")
val additionalInfo = column[String]("ADDITIONAL_INFO")
val activityDate = column[java.util.Date]("ACTIVITY_DATE")
- def * = (userName, repositoryName, activityUserName, activityType, message, additionalInfo.?, activityDate, activityId) <> (Activity.tupled, Activity.unapply)
+ def * =
+ (userName, repositoryName, activityUserName, activityType, message, additionalInfo.?, activityDate, activityId) <> (Activity.tupled, Activity.unapply)
}
}
diff --git a/src/main/scala/gitbucket/core/model/BasicTemplate.scala b/src/main/scala/gitbucket/core/model/BasicTemplate.scala
index 5608bbd..7beaf9b 100644
--- a/src/main/scala/gitbucket/core/model/BasicTemplate.scala
+++ b/src/main/scala/gitbucket/core/model/BasicTemplate.scala
@@ -76,9 +76,11 @@
byRepository(userName, repositoryName) && (this.commitId === commitId)
}
- trait BranchTemplate extends BasicTemplate{ self: Table[_] =>
+ trait BranchTemplate extends BasicTemplate { self: Table[_] =>
val branch = column[String]("BRANCH")
- def byBranch(owner: String, repository: String, branchName: String) = byRepository(owner, repository) && (branch === branchName.bind)
- def byBranch(owner: Rep[String], repository: Rep[String], branchName: Rep[String]) = byRepository(owner, repository) && (this.branch === branchName)
+ def byBranch(owner: String, repository: String, branchName: String) =
+ byRepository(owner, repository) && (branch === branchName.bind)
+ def byBranch(owner: Rep[String], repository: Rep[String], branchName: Rep[String]) =
+ byRepository(owner, repository) && (this.branch === branchName)
}
}
diff --git a/src/main/scala/gitbucket/core/model/Comment.scala b/src/main/scala/gitbucket/core/model/Comment.scala
index 310be7e..8f79a52 100644
--- a/src/main/scala/gitbucket/core/model/Comment.scala
+++ b/src/main/scala/gitbucket/core/model/Comment.scala
@@ -18,13 +18,14 @@
val content = column[String]("CONTENT")
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
val updatedDate = column[java.util.Date]("UPDATED_DATE")
- def * = (userName, repositoryName, issueId, commentId, action, commentedUserName, content, registeredDate, updatedDate) <> (IssueComment.tupled, IssueComment.unapply)
+ def * =
+ (userName, repositoryName, issueId, commentId, action, commentedUserName, content, registeredDate, updatedDate) <> (IssueComment.tupled, IssueComment.unapply)
def byPrimaryKey(commentId: Int) = this.commentId === commentId.bind
}
}
-case class IssueComment (
+case class IssueComment(
userName: String,
repositoryName: String,
issueId: Int,
@@ -52,7 +53,21 @@
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
val updatedDate = column[java.util.Date]("UPDATED_DATE")
val issueId = column[Option[Int]]("ISSUE_ID")
- def * = (userName, repositoryName, commitId, commentId, commentedUserName, content, fileName, oldLine, newLine, registeredDate, updatedDate, issueId) <> (CommitComment.tupled, CommitComment.unapply)
+ def * =
+ (
+ userName,
+ repositoryName,
+ commitId,
+ commentId,
+ commentedUserName,
+ content,
+ fileName,
+ oldLine,
+ newLine,
+ registeredDate,
+ updatedDate,
+ issueId
+ ) <> (CommitComment.tupled, CommitComment.unapply)
def byPrimaryKey(commentId: Int) = this.commentId === commentId.bind
}
@@ -71,4 +86,4 @@
registeredDate: java.util.Date,
updatedDate: java.util.Date,
issueId: Option[Int]
- ) extends Comment
+) extends Comment
diff --git a/src/main/scala/gitbucket/core/model/CommitStatus.scala b/src/main/scala/gitbucket/core/model/CommitStatus.scala
index 4bb01e0..c89f4be 100644
--- a/src/main/scala/gitbucket/core/model/CommitStatus.scala
+++ b/src/main/scala/gitbucket/core/model/CommitStatus.scala
@@ -4,7 +4,7 @@
import profile.api._
import self._
- implicit val commitStateColumnType = MappedColumnType.base[CommitState, String](b => b.name , i => CommitState(i))
+ implicit val commitStateColumnType = MappedColumnType.base[CommitState, String](b => b.name, i => CommitState(i))
lazy val CommitStatuses = TableQuery[CommitStatuses]
class CommitStatuses(tag: Tag) extends Table[CommitStatus](tag, "COMMIT_STATUS") with CommitTemplate {
@@ -16,12 +16,24 @@
val creator = column[String]("CREATOR")
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
val updatedDate = column[java.util.Date]("UPDATED_DATE")
- def * = (commitStatusId, userName, repositoryName, commitId, context, state, targetUrl, description, creator, registeredDate, updatedDate) <> ((CommitStatus.apply _).tupled, CommitStatus.unapply)
+ def * =
+ (
+ commitStatusId,
+ userName,
+ repositoryName,
+ commitId,
+ context,
+ state,
+ targetUrl,
+ description,
+ creator,
+ registeredDate,
+ updatedDate
+ ) <> ((CommitStatus.apply _).tupled, CommitStatus.unapply)
def byPrimaryKey(id: Int) = commitStatusId === id.bind
}
}
-
case class CommitStatus(
commitStatusId: Int = 0,
userName: String,
@@ -36,23 +48,24 @@
updatedDate: java.util.Date
)
object CommitStatus {
- def pending(owner: String, repository: String, context: String) = CommitStatus(
- commitStatusId = 0,
- userName = owner,
- repositoryName = repository,
- commitId = "",
- context = context,
- state = CommitState.PENDING,
- targetUrl = None,
- description = Some("Waiting for status to be reported"),
- creator = "",
- registeredDate = new java.util.Date(),
- updatedDate = new java.util.Date())
+ def pending(owner: String, repository: String, context: String) =
+ CommitStatus(
+ commitStatusId = 0,
+ userName = owner,
+ repositoryName = repository,
+ commitId = "",
+ context = context,
+ state = CommitState.PENDING,
+ targetUrl = None,
+ description = Some("Waiting for status to be reported"),
+ creator = "",
+ registeredDate = new java.util.Date(),
+ updatedDate = new java.util.Date()
+ )
}
sealed abstract class CommitState(val name: String)
-
object CommitState {
object ERROR extends CommitState("error")
@@ -76,11 +89,11 @@
* success if the latest status for all contexts is success
*/
def combine(statuses: Set[CommitState]): CommitState = {
- if(statuses.isEmpty){
+ if (statuses.isEmpty) {
PENDING
- } else if(statuses.contains(CommitState.ERROR) || statuses.contains(CommitState.FAILURE)) {
+ } else if (statuses.contains(CommitState.ERROR) || statuses.contains(CommitState.FAILURE)) {
FAILURE
- } else if(statuses.contains(CommitState.PENDING)) {
+ } else if (statuses.contains(CommitState.PENDING)) {
PENDING
} else {
SUCCESS
@@ -88,4 +101,3 @@
}
}
-
diff --git a/src/main/scala/gitbucket/core/model/DeployKey.scala b/src/main/scala/gitbucket/core/model/DeployKey.scala
index 71b80a2..dd13785 100644
--- a/src/main/scala/gitbucket/core/model/DeployKey.scala
+++ b/src/main/scala/gitbucket/core/model/DeployKey.scala
@@ -10,7 +10,8 @@
val title = column[String]("TITLE")
val publicKey = column[String]("PUBLIC_KEY")
val allowWrite = column[Boolean]("ALLOW_WRITE")
- def * = (userName, repositoryName, deployKeyId, title, publicKey, allowWrite) <> (DeployKey.tupled, DeployKey.unapply)
+ def * =
+ (userName, repositoryName, deployKeyId, title, publicKey, allowWrite) <> (DeployKey.tupled, DeployKey.unapply)
def byPrimaryKey(userName: String, repositoryName: String, deployKeyId: Int) =
(this.userName === userName.bind) && (this.repositoryName === repositoryName.bind) && (this.deployKeyId === deployKeyId.bind)
diff --git a/src/main/scala/gitbucket/core/model/Issue.scala b/src/main/scala/gitbucket/core/model/Issue.scala
index 7167195..635e94f 100644
--- a/src/main/scala/gitbucket/core/model/Issue.scala
+++ b/src/main/scala/gitbucket/core/model/Issue.scala
@@ -13,13 +13,19 @@
def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository)
}
- class IssueOutline(tag: Tag) extends Table[(String, String, Int, Int, Int)](tag, "ISSUE_OUTLINE_VIEW") with IssueTemplate {
+ class IssueOutline(tag: Tag)
+ extends Table[(String, String, Int, Int, Int)](tag, "ISSUE_OUTLINE_VIEW")
+ with IssueTemplate {
val commentCount = column[Int]("COMMENT_COUNT")
val priority = column[Int]("PRIORITY")
def * = (userName, repositoryName, issueId, commentCount, priority)
}
- class Issues(tag: Tag) extends Table[Issue](tag, "ISSUE") with IssueTemplate with MilestoneTemplate with PriorityTemplate {
+ class Issues(tag: Tag)
+ extends Table[Issue](tag, "ISSUE")
+ with IssueTemplate
+ with MilestoneTemplate
+ with PriorityTemplate {
val openedUserName = column[String]("OPENED_USER_NAME")
val assignedUserName = column[String]("ASSIGNED_USER_NAME")
val title = column[String]("TITLE")
@@ -28,7 +34,22 @@
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
val updatedDate = column[java.util.Date]("UPDATED_DATE")
val pullRequest = column[Boolean]("PULL_REQUEST")
- def * = (userName, repositoryName, issueId, openedUserName, milestoneId.?, priorityId.?, assignedUserName.?, title, content.?, closed, registeredDate, updatedDate, pullRequest) <> (Issue.tupled, Issue.unapply)
+ def * =
+ (
+ userName,
+ repositoryName,
+ issueId,
+ openedUserName,
+ milestoneId.?,
+ priorityId.?,
+ assignedUserName.?,
+ title,
+ content.?,
+ closed,
+ registeredDate,
+ updatedDate,
+ pullRequest
+ ) <> (Issue.tupled, Issue.unapply)
def byPrimaryKey(owner: String, repository: String, issueId: Int) = byIssue(owner, repository, issueId)
}
diff --git a/src/main/scala/gitbucket/core/model/Labels.scala b/src/main/scala/gitbucket/core/model/Labels.scala
index a9abf8b..70f4ae4 100644
--- a/src/main/scala/gitbucket/core/model/Labels.scala
+++ b/src/main/scala/gitbucket/core/model/Labels.scala
@@ -12,23 +12,19 @@
def * = (userName, repositoryName, labelId, labelName, color) <> (Label.tupled, Label.unapply)
def byPrimaryKey(owner: String, repository: String, labelId: Int) = byLabel(owner, repository, labelId)
- def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], labelId: Rep[Int]) = byLabel(userName, repositoryName, labelId)
+ def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], labelId: Rep[Int]) =
+ byLabel(userName, repositoryName, labelId)
}
}
-case class Label(
- userName: String,
- repositoryName: String,
- labelId: Int = 0,
- labelName: String,
- color: String){
+case class Label(userName: String, repositoryName: String, labelId: Int = 0, labelName: String, color: String) {
val fontColor = {
val r = color.substring(0, 2)
val g = color.substring(2, 4)
val b = color.substring(4, 6)
- if(Integer.parseInt(r, 16) + Integer.parseInt(g, 16) + Integer.parseInt(b, 16) > 408){
+ if (Integer.parseInt(r, 16) + Integer.parseInt(g, 16) + Integer.parseInt(b, 16) > 408) {
"000000"
} else {
"ffffff"
diff --git a/src/main/scala/gitbucket/core/model/Milestone.scala b/src/main/scala/gitbucket/core/model/Milestone.scala
index 491fefd..0074012 100644
--- a/src/main/scala/gitbucket/core/model/Milestone.scala
+++ b/src/main/scala/gitbucket/core/model/Milestone.scala
@@ -12,10 +12,12 @@
val description = column[Option[String]]("DESCRIPTION")
val dueDate = column[Option[java.util.Date]]("DUE_DATE")
val closedDate = column[Option[java.util.Date]]("CLOSED_DATE")
- def * = (userName, repositoryName, milestoneId, title, description, dueDate, closedDate) <> (Milestone.tupled, Milestone.unapply)
+ def * =
+ (userName, repositoryName, milestoneId, title, description, dueDate, closedDate) <> (Milestone.tupled, Milestone.unapply)
def byPrimaryKey(owner: String, repository: String, milestoneId: Int) = byMilestone(owner, repository, milestoneId)
- def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], milestoneId: Rep[Int]) = byMilestone(userName, repositoryName, milestoneId)
+ def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], milestoneId: Rep[Int]) =
+ byMilestone(userName, repositoryName, milestoneId)
}
}
diff --git a/src/main/scala/gitbucket/core/model/Priorities.scala b/src/main/scala/gitbucket/core/model/Priorities.scala
index eb31740..548b32f 100644
--- a/src/main/scala/gitbucket/core/model/Priorities.scala
+++ b/src/main/scala/gitbucket/core/model/Priorities.scala
@@ -12,14 +12,16 @@
val ordering = column[Int]("ORDERING")
val isDefault = column[Boolean]("IS_DEFAULT")
val color = column[String]("COLOR")
- def * = (userName, repositoryName, priorityId, priorityName, description.?, isDefault, ordering, color) <> (Priority.tupled, Priority.unapply)
+ def * =
+ (userName, repositoryName, priorityId, priorityName, description.?, isDefault, ordering, color) <> (Priority.tupled, Priority.unapply)
def byPrimaryKey(owner: String, repository: String, priorityId: Int) = byPriority(owner, repository, priorityId)
- def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], priorityId: Rep[Int]) = byPriority(userName, repositoryName, priorityId)
+ def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], priorityId: Rep[Int]) =
+ byPriority(userName, repositoryName, priorityId)
}
}
-case class Priority (
+case class Priority(
userName: String,
repositoryName: String,
priorityId: Int = 0,
@@ -27,14 +29,15 @@
description: Option[String],
isDefault: Boolean,
ordering: Int = 0,
- color: String){
+ color: String
+) {
val fontColor = {
val r = color.substring(0, 2)
val g = color.substring(2, 4)
val b = color.substring(4, 6)
- if(Integer.parseInt(r, 16) + Integer.parseInt(g, 16) + Integer.parseInt(b, 16) > 408){
+ if (Integer.parseInt(r, 16) + Integer.parseInt(g, 16) + Integer.parseInt(b, 16) > 408) {
"000000"
} else {
"ffffff"
diff --git a/src/main/scala/gitbucket/core/model/Profile.scala b/src/main/scala/gitbucket/core/model/Profile.scala
index f9170a4..f35dec9 100644
--- a/src/main/scala/gitbucket/core/model/Profile.scala
+++ b/src/main/scala/gitbucket/core/model/Profile.scala
@@ -16,15 +16,15 @@
)
/**
- * WebHookBase.Event Column Types
- */
+ * WebHookBase.Event Column Types
+ */
implicit val eventColumnType = MappedColumnType.base[WebHook.Event, String](_.name, WebHook.Event.valueOf(_))
/**
* Extends Column to add conditional condition
*/
- implicit class RichColumn(c1: Rep[Boolean]){
- def &&(c2: => Rep[Boolean], guard: => Boolean): Rep[Boolean] = if(guard) c1 && c2 else c1
+ implicit class RichColumn(c1: Rep[Boolean]) {
+ def &&(c2: => Rep[Boolean], guard: => Boolean): Rep[Boolean] = if (guard) c1 && c2 else c1
}
/**
@@ -40,31 +40,33 @@
}
-trait CoreProfile extends ProfileProvider with Profile
- with AccessTokenComponent
- with AccountComponent
- with ActivityComponent
- with CollaboratorComponent
- with CommitCommentComponent
- with CommitStatusComponent
- with GroupMemberComponent
- with IssueComponent
- with IssueCommentComponent
- with IssueLabelComponent
- with LabelComponent
- with PriorityComponent
- with MilestoneComponent
- with PullRequestComponent
- with RepositoryComponent
- with SshKeyComponent
- with RepositoryWebHookComponent
- with RepositoryWebHookEventComponent
- with AccountWebHookComponent
- with AccountWebHookEventComponent
- with AccountFederationComponent
- with ProtectedBranchComponent
- with DeployKeyComponent
- with ReleaseTagComponent
- with ReleaseAssetComponent
+trait CoreProfile
+ extends ProfileProvider
+ with Profile
+ with AccessTokenComponent
+ with AccountComponent
+ with ActivityComponent
+ with CollaboratorComponent
+ with CommitCommentComponent
+ with CommitStatusComponent
+ with GroupMemberComponent
+ with IssueComponent
+ with IssueCommentComponent
+ with IssueLabelComponent
+ with LabelComponent
+ with PriorityComponent
+ with MilestoneComponent
+ with PullRequestComponent
+ with RepositoryComponent
+ with SshKeyComponent
+ with RepositoryWebHookComponent
+ with RepositoryWebHookEventComponent
+ with AccountWebHookComponent
+ with AccountWebHookEventComponent
+ with AccountFederationComponent
+ with ProtectedBranchComponent
+ with DeployKeyComponent
+ with ReleaseTagComponent
+ with ReleaseAssetComponent
object Profile extends CoreProfile
diff --git a/src/main/scala/gitbucket/core/model/ProtectedBranch.scala b/src/main/scala/gitbucket/core/model/ProtectedBranch.scala
index b143b4f..b101081 100644
--- a/src/main/scala/gitbucket/core/model/ProtectedBranch.scala
+++ b/src/main/scala/gitbucket/core/model/ProtectedBranch.scala
@@ -8,27 +8,22 @@
class ProtectedBranches(tag: Tag) extends Table[ProtectedBranch](tag, "PROTECTED_BRANCH") with BranchTemplate {
val statusCheckAdmin = column[Boolean]("STATUS_CHECK_ADMIN")
def * = (userName, repositoryName, branch, statusCheckAdmin) <> (ProtectedBranch.tupled, ProtectedBranch.unapply)
- def byPrimaryKey(userName: String, repositoryName: String, branch: String) = byBranch(userName, repositoryName, branch)
- def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], branch: Rep[String]) = byBranch(userName, repositoryName, branch)
+ def byPrimaryKey(userName: String, repositoryName: String, branch: String) =
+ byBranch(userName, repositoryName, branch)
+ def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], branch: Rep[String]) =
+ byBranch(userName, repositoryName, branch)
}
lazy val ProtectedBranchContexts = TableQuery[ProtectedBranchContexts]
- class ProtectedBranchContexts(tag: Tag) extends Table[ProtectedBranchContext](tag, "PROTECTED_BRANCH_REQUIRE_CONTEXT") with BranchTemplate {
+ class ProtectedBranchContexts(tag: Tag)
+ extends Table[ProtectedBranchContext](tag, "PROTECTED_BRANCH_REQUIRE_CONTEXT")
+ with BranchTemplate {
val context = column[String]("CONTEXT")
- def * = (userName, repositoryName, branch, context) <> (ProtectedBranchContext.tupled, ProtectedBranchContext.unapply)
+ def * =
+ (userName, repositoryName, branch, context) <> (ProtectedBranchContext.tupled, ProtectedBranchContext.unapply)
}
}
+case class ProtectedBranch(userName: String, repositoryName: String, branch: String, statusCheckAdmin: Boolean)
-case class ProtectedBranch(
- userName: String,
- repositoryName: String,
- branch: String,
- statusCheckAdmin: Boolean)
-
-
-case class ProtectedBranchContext(
- userName: String,
- repositoryName: String,
- branch: String,
- context: String)
+case class ProtectedBranchContext(userName: String, repositoryName: String, branch: String, context: String)
diff --git a/src/main/scala/gitbucket/core/model/PullRequest.scala b/src/main/scala/gitbucket/core/model/PullRequest.scala
index dba1a3f..5c37691 100644
--- a/src/main/scala/gitbucket/core/model/PullRequest.scala
+++ b/src/main/scala/gitbucket/core/model/PullRequest.scala
@@ -12,10 +12,23 @@
val requestBranch = column[String]("REQUEST_BRANCH")
val commitIdFrom = column[String]("COMMIT_ID_FROM")
val commitIdTo = column[String]("COMMIT_ID_TO")
- def * = (userName, repositoryName, issueId, branch, requestUserName, requestRepositoryName, requestBranch, commitIdFrom, commitIdTo) <> (PullRequest.tupled, PullRequest.unapply)
+ def * =
+ (
+ userName,
+ repositoryName,
+ issueId,
+ branch,
+ requestUserName,
+ requestRepositoryName,
+ requestBranch,
+ commitIdFrom,
+ commitIdTo
+ ) <> (PullRequest.tupled, PullRequest.unapply)
- def byPrimaryKey(userName: String, repositoryName: String, issueId: Int) = byIssue(userName, repositoryName, issueId)
- def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], issueId: Rep[Int]) = byIssue(userName, repositoryName, issueId)
+ def byPrimaryKey(userName: String, repositoryName: String, issueId: Int) =
+ byIssue(userName, repositoryName, issueId)
+ def byPrimaryKey(userName: Rep[String], repositoryName: Rep[String], issueId: Rep[Int]) =
+ byIssue(userName, repositoryName, issueId)
}
}
diff --git a/src/main/scala/gitbucket/core/model/ReleaseAsset.scala b/src/main/scala/gitbucket/core/model/ReleaseAsset.scala
index 7bd6697..3bab8ce 100644
--- a/src/main/scala/gitbucket/core/model/ReleaseAsset.scala
+++ b/src/main/scala/gitbucket/core/model/ReleaseAsset.scala
@@ -20,9 +20,12 @@
val registeredDate = column[Date]("REGISTERED_DATE")
val updatedDate = column[Date]("UPDATED_DATE")
- def * = (userName, repositoryName, tag, releaseAssetId, fileName, label, size, uploader, registeredDate, updatedDate) <> (ReleaseAsset.tupled, ReleaseAsset.unapply)
- def byPrimaryKey(owner: String, repository: String, tag: String, fileName: String) = byTag(owner, repository, tag) && (this.fileName === fileName.bind)
- def byTag(owner: String, repository: String, tag: String) = byRepository(owner, repository) && (this.tag === tag.bind)
+ def * =
+ (userName, repositoryName, tag, releaseAssetId, fileName, label, size, uploader, registeredDate, updatedDate) <> (ReleaseAsset.tupled, ReleaseAsset.unapply)
+ def byPrimaryKey(owner: String, repository: String, tag: String, fileName: String) =
+ byTag(owner, repository, tag) && (this.fileName === fileName.bind)
+ def byTag(owner: String, repository: String, tag: String) =
+ byRepository(owner, repository) && (this.tag === tag.bind)
}
}
diff --git a/src/main/scala/gitbucket/core/model/ReleaseTag.scala b/src/main/scala/gitbucket/core/model/ReleaseTag.scala
index d2c92a2..dad2e8b 100644
--- a/src/main/scala/gitbucket/core/model/ReleaseTag.scala
+++ b/src/main/scala/gitbucket/core/model/ReleaseTag.scala
@@ -16,9 +16,11 @@
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
val updatedDate = column[java.util.Date]("UPDATED_DATE")
- def * = (userName, repositoryName, name, tag, author, content, registeredDate, updatedDate) <> (ReleaseTag.tupled, ReleaseTag.unapply)
+ def * =
+ (userName, repositoryName, name, tag, author, content, registeredDate, updatedDate) <> (ReleaseTag.tupled, ReleaseTag.unapply)
def byPrimaryKey(owner: String, repository: String, tag: String) = byTag(owner, repository, tag)
- def byTag(owner: String, repository: String, tag: String) = byRepository(owner, repository) && (this.tag === tag.bind)
+ def byTag(owner: String, repository: String, tag: String) =
+ byRepository(owner, repository) && (this.tag === tag.bind)
}
}
diff --git a/src/main/scala/gitbucket/core/model/Repository.scala b/src/main/scala/gitbucket/core/model/Repository.scala
index 5a24c35..a62047d 100644
--- a/src/main/scala/gitbucket/core/model/Repository.scala
+++ b/src/main/scala/gitbucket/core/model/Repository.scala
@@ -7,62 +7,80 @@
lazy val Repositories = TableQuery[Repositories]
class Repositories(tag: Tag) extends Table[Repository](tag, "REPOSITORY") with BasicTemplate {
- val isPrivate = column[Boolean]("PRIVATE")
- val description = column[String]("DESCRIPTION")
- val defaultBranch = column[String]("DEFAULT_BRANCH")
- val registeredDate = column[java.util.Date]("REGISTERED_DATE")
- val updatedDate = column[java.util.Date]("UPDATED_DATE")
- val lastActivityDate = column[java.util.Date]("LAST_ACTIVITY_DATE")
- val originUserName = column[String]("ORIGIN_USER_NAME")
+ val isPrivate = column[Boolean]("PRIVATE")
+ val description = column[String]("DESCRIPTION")
+ val defaultBranch = column[String]("DEFAULT_BRANCH")
+ val registeredDate = column[java.util.Date]("REGISTERED_DATE")
+ val updatedDate = column[java.util.Date]("UPDATED_DATE")
+ val lastActivityDate = column[java.util.Date]("LAST_ACTIVITY_DATE")
+ val originUserName = column[String]("ORIGIN_USER_NAME")
val originRepositoryName = column[String]("ORIGIN_REPOSITORY_NAME")
- val parentUserName = column[String]("PARENT_USER_NAME")
+ val parentUserName = column[String]("PARENT_USER_NAME")
val parentRepositoryName = column[String]("PARENT_REPOSITORY_NAME")
- val issuesOption = column[String]("ISSUES_OPTION")
- val externalIssuesUrl = column[String]("EXTERNAL_ISSUES_URL")
- val wikiOption = column[String]("WIKI_OPTION")
- val externalWikiUrl = column[String]("EXTERNAL_WIKI_URL")
- val allowFork = column[Boolean]("ALLOW_FORK")
- val mergeOptions = column[String]("MERGE_OPTIONS")
- val defaultMergeOption = column[String]("DEFAULT_MERGE_OPTION")
+ val issuesOption = column[String]("ISSUES_OPTION")
+ val externalIssuesUrl = column[String]("EXTERNAL_ISSUES_URL")
+ val wikiOption = column[String]("WIKI_OPTION")
+ val externalWikiUrl = column[String]("EXTERNAL_WIKI_URL")
+ val allowFork = column[Boolean]("ALLOW_FORK")
+ val mergeOptions = column[String]("MERGE_OPTIONS")
+ val defaultMergeOption = column[String]("DEFAULT_MERGE_OPTION")
- def * = (
- (userName, repositoryName, isPrivate, description.?, defaultBranch,
- registeredDate, updatedDate, lastActivityDate, originUserName.?, originRepositoryName.?, parentUserName.?, parentRepositoryName.?),
- (issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork, mergeOptions, defaultMergeOption)
- ).shaped <> (
- { case (repository, options) =>
- Repository(
- repository._1,
- repository._2,
- repository._3,
- repository._4,
- repository._5,
- repository._6,
- repository._7,
- repository._8,
- repository._9,
- repository._10,
- repository._11,
- repository._12,
- RepositoryOptions.tupled.apply(options)
- )
+ def * =
+ (
+ (
+ userName,
+ repositoryName,
+ isPrivate,
+ description.?,
+ defaultBranch,
+ registeredDate,
+ updatedDate,
+ lastActivityDate,
+ originUserName.?,
+ originRepositoryName.?,
+ parentUserName.?,
+ parentRepositoryName.?
+ ),
+ (issuesOption, externalIssuesUrl.?, wikiOption, externalWikiUrl.?, allowFork, mergeOptions, defaultMergeOption)
+ ).shaped <> ({
+ case (repository, options) =>
+ Repository(
+ repository._1,
+ repository._2,
+ repository._3,
+ repository._4,
+ repository._5,
+ repository._6,
+ repository._7,
+ repository._8,
+ repository._9,
+ repository._10,
+ repository._11,
+ repository._12,
+ RepositoryOptions.tupled.apply(options)
+ )
}, { (r: Repository) =>
- Some(((
- r.userName,
- r.repositoryName,
- r.isPrivate,
- r.description,
- r.defaultBranch,
- r.registeredDate,
- r.updatedDate,
- r.lastActivityDate,
- r.originUserName,
- r.originRepositoryName,
- r.parentUserName,
- r.parentRepositoryName
- ),(
- RepositoryOptions.unapply(r.options).get
- )))
+ Some(
+ (
+ (
+ r.userName,
+ r.repositoryName,
+ r.isPrivate,
+ r.description,
+ r.defaultBranch,
+ r.registeredDate,
+ r.updatedDate,
+ r.lastActivityDate,
+ r.originUserName,
+ r.originRepositoryName,
+ r.parentUserName,
+ r.parentRepositoryName
+ ),
+ (
+ RepositoryOptions.unapply(r.options).get
+ )
+ )
+ )
})
def byPrimaryKey(owner: String, repository: String) = byRepository(owner, repository)
diff --git a/src/main/scala/gitbucket/core/model/RepositoryWebHook.scala b/src/main/scala/gitbucket/core/model/RepositoryWebHook.scala
index 967d067..15ea535 100644
--- a/src/main/scala/gitbucket/core/model/RepositoryWebHook.scala
+++ b/src/main/scala/gitbucket/core/model/RepositoryWebHook.scala
@@ -3,7 +3,8 @@
trait RepositoryWebHookComponent extends TemplateComponent { self: Profile =>
import profile.api._
- implicit val whContentTypeColumnType = MappedColumnType.base[WebHookContentType, String](whct => whct.code , code => WebHookContentType.valueOf(code))
+ implicit val whContentTypeColumnType =
+ MappedColumnType.base[WebHookContentType, String](whct => whct.code, code => WebHookContentType.valueOf(code))
lazy val RepositoryWebHooks = TableQuery[RepositoryWebHooks]
@@ -11,13 +12,14 @@
val url = column[String]("URL")
val token = column[Option[String]]("TOKEN")
val ctype = column[WebHookContentType]("CTYPE")
- def * = (userName, repositoryName, url, ctype, token) <> ((RepositoryWebHook.apply _).tupled, RepositoryWebHook.unapply)
+ def * =
+ (userName, repositoryName, url, ctype, token) <> ((RepositoryWebHook.apply _).tupled, RepositoryWebHook.unapply)
- def byPrimaryKey(owner: String, repository: String, url: String) = byRepository(owner, repository) && (this.url === url.bind)
+ def byPrimaryKey(owner: String, repository: String, url: String) =
+ byRepository(owner, repository) && (this.url === url.bind)
}
}
-
case class RepositoryWebHook(
userName: String,
repositoryName: String,
diff --git a/src/main/scala/gitbucket/core/model/RepositoryWebHookEvent.scala b/src/main/scala/gitbucket/core/model/RepositoryWebHookEvent.scala
index 83cbea5..79ca9a9 100644
--- a/src/main/scala/gitbucket/core/model/RepositoryWebHookEvent.scala
+++ b/src/main/scala/gitbucket/core/model/RepositoryWebHookEvent.scala
@@ -6,17 +6,22 @@
lazy val RepositoryWebHookEvents = TableQuery[RepositoryWebHookEvents]
- class RepositoryWebHookEvents(tag: Tag) extends Table[RepositoryWebHookEvent](tag, "WEB_HOOK_EVENT") with BasicTemplate {
+ class RepositoryWebHookEvents(tag: Tag)
+ extends Table[RepositoryWebHookEvent](tag, "WEB_HOOK_EVENT")
+ with BasicTemplate {
val url = column[String]("URL")
val event = column[WebHook.Event]("EVENT")
- def * = (userName, repositoryName, url, event) <> ((RepositoryWebHookEvent.apply _).tupled, RepositoryWebHookEvent.unapply)
+ def * =
+ (userName, repositoryName, url, event) <> ((RepositoryWebHookEvent.apply _).tupled, RepositoryWebHookEvent.unapply)
- def byRepositoryWebHook(owner: String, repository: String, url: String) = byRepository(owner, repository) && (this.url === url.bind)
+ def byRepositoryWebHook(owner: String, repository: String, url: String) =
+ byRepository(owner, repository) && (this.url === url.bind)
def byRepositoryWebHook(owner: Rep[String], repository: Rep[String], url: Rep[String]) =
byRepository(userName, repositoryName) && (this.url === url)
def byRepositoryWebHook(webhook: RepositoryWebHooks) =
byRepository(webhook.userName, webhook.repositoryName) && (this.url === webhook.url)
- def byPrimaryKey(owner: String, repository: String, url: String, event: WebHook.Event) = byRepositoryWebHook(owner, repository, url) && (this.event === event.bind)
+ def byPrimaryKey(owner: String, repository: String, url: String, event: WebHook.Event) =
+ byRepositoryWebHook(owner, repository, url) && (this.event === event.bind)
}
}
diff --git a/src/main/scala/gitbucket/core/model/SshKey.scala b/src/main/scala/gitbucket/core/model/SshKey.scala
index a5a41f0..d6379ed 100644
--- a/src/main/scala/gitbucket/core/model/SshKey.scala
+++ b/src/main/scala/gitbucket/core/model/SshKey.scala
@@ -12,7 +12,8 @@
val publicKey = column[String]("PUBLIC_KEY")
def * = (userName, sshKeyId, title, publicKey) <> (SshKey.tupled, SshKey.unapply)
- def byPrimaryKey(userName: String, sshKeyId: Int) = (this.userName === userName.bind) && (this.sshKeyId === sshKeyId.bind)
+ def byPrimaryKey(userName: String, sshKeyId: Int) =
+ (this.userName === userName.bind) && (this.sshKeyId === sshKeyId.bind)
}
}
diff --git a/src/main/scala/gitbucket/core/model/WebHook.scala b/src/main/scala/gitbucket/core/model/WebHook.scala
index 3643dfb..f575cf7 100644
--- a/src/main/scala/gitbucket/core/model/WebHook.scala
+++ b/src/main/scala/gitbucket/core/model/WebHook.scala
@@ -16,7 +16,7 @@
def valueOpt(code: String): Option[WebHookContentType] = map.get(code)
}
-trait WebHook{
+trait WebHook {
val url: String
val ctype: WebHookContentType
val token: Option[String]
@@ -45,7 +45,7 @@
case object TeamAdd extends Event("team_add")
case object Watch extends Event("watch")
- object Event{
+ object Event {
val values = List(
CommitComment,
Create,
@@ -68,7 +68,7 @@
Watch
)
- private val map: Map[String,Event] = values.map(e => e.name -> e).toMap
+ private val map: Map[String, Event] = values.map(e => e.name -> e).toMap
def valueOf(name: String): Event = map(name)
def valueOpt(name: String): Option[Event] = map.get(name)
}
diff --git a/src/main/scala/gitbucket/core/plugin/GitRepositoryRouting.scala b/src/main/scala/gitbucket/core/plugin/GitRepositoryRouting.scala
index 61089f0..917beb4 100644
--- a/src/main/scala/gitbucket/core/plugin/GitRepositoryRouting.scala
+++ b/src/main/scala/gitbucket/core/plugin/GitRepositoryRouting.scala
@@ -10,13 +10,18 @@
* @param localPath the string to assemble local file path of repository (e.g. "gist/$1/$2")
* @param filter the filter for request to the Git repository which is defined by this routing
*/
-case class GitRepositoryRouting(urlPattern: String, localPath: String, filter: GitRepositoryFilter){
+case class GitRepositoryRouting(urlPattern: String, localPath: String, filter: GitRepositoryFilter) {
def this(urlPattern: String, localPath: String) = {
- this(urlPattern, localPath, new GitRepositoryFilter(){
- def filter(repositoryName: String, userName: Option[String], settings: SystemSettings, isUpdating: Boolean)
- (implicit session: Session): Boolean = true
- })
+ this(
+ urlPattern,
+ localPath,
+ new GitRepositoryFilter() {
+ def filter(repositoryName: String, userName: Option[String], settings: SystemSettings, isUpdating: Boolean)(
+ implicit session: Session
+ ): Boolean = true
+ }
+ )
}
}
@@ -36,7 +41,8 @@
* @param session the database session
* @return true if allow accessing to repository, otherwise false.
*/
- def filter(path: String, userName: Option[String], settings: SystemSettings, isUpdating: Boolean)
- (implicit session: Session): Boolean
+ def filter(path: String, userName: Option[String], settings: SystemSettings, isUpdating: Boolean)(
+ implicit session: Session
+ ): Boolean
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/gitbucket/core/plugin/IssueHook.scala b/src/main/scala/gitbucket/core/plugin/IssueHook.scala
index 56e7294..12d050a 100644
--- a/src/main/scala/gitbucket/core/plugin/IssueHook.scala
+++ b/src/main/scala/gitbucket/core/plugin/IssueHook.scala
@@ -9,7 +9,10 @@
trait IssueHook {
def created(issue: Issue, repository: RepositoryInfo)(implicit session: Session, context: Context): Unit = ()
- def addedComment(commentId: Int, content: String, issue: Issue, repository: RepositoryInfo)(implicit session: Session, context: Context): Unit = ()
+ def addedComment(commentId: Int, content: String, issue: Issue, repository: RepositoryInfo)(
+ implicit session: Session,
+ context: Context
+ ): Unit = ()
def closed(issue: Issue, repository: RepositoryInfo)(implicit session: Session, context: Context): Unit = ()
def reopened(issue: Issue, repository: RepositoryInfo)(implicit session: Session, context: Context): Unit = ()
diff --git a/src/main/scala/gitbucket/core/plugin/Plugin.scala b/src/main/scala/gitbucket/core/plugin/Plugin.scala
index 3cb5a48..92a51ea 100644
--- a/src/main/scala/gitbucket/core/plugin/Plugin.scala
+++ b/src/main/scala/gitbucket/core/plugin/Plugin.scala
@@ -30,7 +30,8 @@
/**
* Override to declare this plug-in provides images.
*/
- def images(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, Array[Byte])] = Nil
+ def images(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, Array[Byte])] =
+ Nil
/**
* Override to declare this plug-in provides controllers.
@@ -40,7 +41,11 @@
/**
* Override to declare this plug-in provides controllers.
*/
- def controllers(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, ControllerBase)] = Nil
+ def controllers(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(String, ControllerBase)] = Nil
/**
* Override to declare this plug-in provides JavaScript.
@@ -50,7 +55,8 @@
/**
* Override to declare this plug-in provides JavaScript.
*/
- def javaScripts(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, String)] = Nil
+ def javaScripts(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, String)] =
+ Nil
/**
* Override to declare this plug-in provides renderers.
@@ -60,7 +66,8 @@
/**
* Override to declare this plug-in provides renderers.
*/
- def renderers(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, Renderer)] = Nil
+ def renderers(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, Renderer)] =
+ Nil
/**
* Override to add git repository routings.
@@ -70,7 +77,11 @@
/**
* Override to add git repository routings.
*/
- def repositoryRoutings(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[GitRepositoryRouting] = Nil
+ def repositoryRoutings(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[GitRepositoryRouting] = Nil
/**
* Override to add account hooks.
@@ -100,7 +111,11 @@
/**
* Override to add repository hooks.
*/
- def repositoryHooks(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[RepositoryHook] = Nil
+ def repositoryHooks(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[RepositoryHook] = Nil
/**
* Override to add issue hooks.
@@ -120,7 +135,11 @@
/**
* Override to add pull request hooks.
*/
- def pullRequestHooks(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[PullRequestHook] = Nil
+ def pullRequestHooks(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[PullRequestHook] = Nil
/**
* Override to add repository headers.
@@ -130,7 +149,11 @@
/**
* Override to add repository headers.
*/
- def repositoryHeaders(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(RepositoryInfo, Context) => Option[Html]] = Nil
+ def repositoryHeaders(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(RepositoryInfo, Context) => Option[Html]] = Nil
/**
* Override to add global menus.
@@ -140,7 +163,11 @@
/**
* Override to add global menus.
*/
- def globalMenus(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Context) => Option[Link]] = Nil
+ def globalMenus(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Context) => Option[Link]] = Nil
/**
* Override to add repository menus.
@@ -150,7 +177,11 @@
/**
* Override to add repository menus.
*/
- def repositoryMenus(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(RepositoryInfo, Context) => Option[Link]] = Nil
+ def repositoryMenus(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(RepositoryInfo, Context) => Option[Link]] = Nil
/**
* Override to add repository setting tabs.
@@ -160,7 +191,11 @@
/**
* Override to add repository setting tabs.
*/
- def repositorySettingTabs(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(RepositoryInfo, Context) => Option[Link]] = Nil
+ def repositorySettingTabs(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(RepositoryInfo, Context) => Option[Link]] = Nil
/**
* Override to add profile tabs.
@@ -170,7 +205,11 @@
/**
* Override to add profile tabs.
*/
- def profileTabs(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Account, Context) => Option[Link]] = Nil
+ def profileTabs(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Account, Context) => Option[Link]] = Nil
/**
* Override to add system setting menus.
@@ -180,7 +219,11 @@
/**
* Override to add system setting menus.
*/
- def systemSettingMenus(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Context) => Option[Link]] = Nil
+ def systemSettingMenus(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Context) => Option[Link]] = Nil
/**
* Override to add account setting menus.
@@ -190,7 +233,11 @@
/**
* Override to add account setting menus.
*/
- def accountSettingMenus(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Context) => Option[Link]] = Nil
+ def accountSettingMenus(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Context) => Option[Link]] = Nil
/**
* Override to add dashboard tabs.
@@ -200,7 +247,11 @@
/**
* Override to add dashboard tabs.
*/
- def dashboardTabs(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Context) => Option[Link]] = Nil
+ def dashboardTabs(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Context) => Option[Link]] = Nil
/**
* Override to add issue sidebars.
@@ -210,7 +261,11 @@
/**
* Override to add issue sidebars.
*/
- def issueSidebars(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(Issue, RepositoryInfo, Context) => Option[Html]] = Nil
+ def issueSidebars(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(Issue, RepositoryInfo, Context) => Option[Html]] = Nil
/**
* Override to add assets mappings.
@@ -220,7 +275,11 @@
/**
* Override to add assets mappings.
*/
- def assetsMappings(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[(String, String)] = Nil
+ def assetsMappings(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[(String, String)] = Nil
/**
* Override to add text decorators.
@@ -230,7 +289,8 @@
/**
* Override to add text decorators.
*/
- def textDecorators(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[TextDecorator] = Nil
+ def textDecorators(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[TextDecorator] =
+ Nil
/**
* Override to add suggestion provider.
@@ -240,7 +300,11 @@
/**
* Override to add suggestion provider.
*/
- def suggestionProviders(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[SuggestionProvider] = Nil
+ def suggestionProviders(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[SuggestionProvider] = Nil
/**
* Override to add ssh command providers.
@@ -250,25 +314,32 @@
/**
* Override to add ssh command providers.
*/
- def sshCommandProviders(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Seq[PartialFunction[String, Command]] = Nil
-
+ def sshCommandProviders(
+ registry: PluginRegistry,
+ context: ServletContext,
+ settings: SystemSettings
+ ): Seq[PartialFunction[String, Command]] = Nil
/**
* This method is invoked in initialization of plugin system.
* Register plugin functionality to PluginRegistry.
*/
def initialize(registry: PluginRegistry, context: ServletContext, settings: SystemSettings): Unit = {
- (images ++ images(registry, context, settings)).foreach { case (id, in) =>
- registry.addImage(id, in)
+ (images ++ images(registry, context, settings)).foreach {
+ case (id, in) =>
+ registry.addImage(id, in)
}
- (controllers ++ controllers(registry, context, settings)).foreach { case (path, controller) =>
- registry.addController(path, controller)
+ (controllers ++ controllers(registry, context, settings)).foreach {
+ case (path, controller) =>
+ registry.addController(path, controller)
}
- (javaScripts ++ javaScripts(registry, context, settings)).foreach { case (path, script) =>
- registry.addJavaScript(path, script)
+ (javaScripts ++ javaScripts(registry, context, settings)).foreach {
+ case (path, script) =>
+ registry.addJavaScript(path, script)
}
- (renderers ++ renderers(registry, context, settings)).foreach { case (extension, renderer) =>
- registry.addRenderer(extension, renderer)
+ (renderers ++ renderers(registry, context, settings)).foreach {
+ case (extension, renderer) =>
+ registry.addRenderer(extension, renderer)
}
(repositoryRoutings ++ repositoryRoutings(registry, context, settings)).foreach { routing =>
registry.addRepositoryRouting(routing)
@@ -345,7 +416,7 @@
* Helper method to get a resource from classpath.
*/
protected def fromClassPath(path: String): Array[Byte] =
- using(getClass.getClassLoader.getResourceAsStream(path)){ in =>
+ using(getClass.getClassLoader.getResourceAsStream(path)) { in =>
val bytes = new Array[Byte](in.available)
in.read(bytes)
bytes
diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistry.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistry.scala
index 79b85c1..287a5bc 100644
--- a/src/main/scala/gitbucket/core/plugin/PluginRegistry.scala
+++ b/src/main/scala/gitbucket/core/plugin/PluginRegistry.scala
@@ -70,7 +70,7 @@
@deprecated("Use addImage(id: String, bytes: Array[Byte]) instead", "3.4.0")
def addImage(id: String, in: InputStream): Unit = {
- val bytes = using(in){ in =>
+ val bytes = using(in) { in =>
val bytes = new Array[Byte](in.available)
in.read(bytes)
bytes
@@ -87,9 +87,11 @@
def getControllers(): Seq[(ControllerBase, String)] = controllers.asScala.toSeq
- def addJavaScript(path: String, script: String): Unit = javaScripts.add((path, script)) //javaScripts += ((path, script))
+ def addJavaScript(path: String, script: String): Unit =
+ javaScripts.add((path, script)) //javaScripts += ((path, script))
- def getJavaScript(currentPath: String): List[String] = javaScripts.asScala.filter(x => currentPath.matches(x._1)).toList.map(_._2)
+ def getJavaScript(currentPath: String): List[String] =
+ javaScripts.asScala.filter(x => currentPath.matches(x._1)).toList.map(_._2)
def addRenderer(extension: String, renderer: Renderer): Unit = renderers.put(extension, renderer)
@@ -129,7 +131,8 @@
def getPullRequestHooks: Seq[PullRequestHook] = pullRequestHooks.asScala.toSeq
- def addRepositoryHeader(repositoryHeader: (RepositoryInfo, Context) => Option[Html]): Unit = repositoryHeaders.add(repositoryHeader)
+ def addRepositoryHeader(repositoryHeader: (RepositoryInfo, Context) => Option[Html]): Unit =
+ repositoryHeaders.add(repositoryHeader)
def getRepositoryHeaders: Seq[(RepositoryInfo, Context) => Option[Html]] = repositoryHeaders.asScala.toSeq
@@ -137,11 +140,13 @@
def getGlobalMenus: Seq[(Context) => Option[Link]] = globalMenus.asScala.toSeq
- def addRepositoryMenu(repositoryMenu: (RepositoryInfo, Context) => Option[Link]): Unit = repositoryMenus.add(repositoryMenu)
+ def addRepositoryMenu(repositoryMenu: (RepositoryInfo, Context) => Option[Link]): Unit =
+ repositoryMenus.add(repositoryMenu)
def getRepositoryMenus: Seq[(RepositoryInfo, Context) => Option[Link]] = repositoryMenus.asScala.toSeq
- def addRepositorySettingTab(repositorySettingTab: (RepositoryInfo, Context) => Option[Link]): Unit = repositorySettingTabs.add(repositorySettingTab)
+ def addRepositorySettingTab(repositorySettingTab: (RepositoryInfo, Context) => Option[Link]): Unit =
+ repositorySettingTabs.add(repositorySettingTab)
def getRepositorySettingTabs: Seq[(RepositoryInfo, Context) => Option[Link]] = repositorySettingTabs.asScala.toSeq
@@ -149,11 +154,13 @@
def getProfileTabs: Seq[(Account, Context) => Option[Link]] = profileTabs.asScala.toSeq
- def addSystemSettingMenu(systemSettingMenu: (Context) => Option[Link]): Unit = systemSettingMenus.add(systemSettingMenu)
+ def addSystemSettingMenu(systemSettingMenu: (Context) => Option[Link]): Unit =
+ systemSettingMenus.add(systemSettingMenu)
def getSystemSettingMenus: Seq[(Context) => Option[Link]] = systemSettingMenus.asScala.toSeq
- def addAccountSettingMenu(accountSettingMenu: (Context) => Option[Link]): Unit = accountSettingMenus.add(accountSettingMenu)
+ def addAccountSettingMenu(accountSettingMenu: (Context) => Option[Link]): Unit =
+ accountSettingMenus.add(accountSettingMenu)
def getAccountSettingMenus: Seq[(Context) => Option[Link]] = accountSettingMenus.asScala.toSeq
@@ -161,7 +168,8 @@
def getDashboardTabs: Seq[(Context) => Option[Link]] = dashboardTabs.asScala.toSeq
- def addIssueSidebar(issueSidebar: (Issue, RepositoryInfo, Context) => Option[Html]): Unit = issueSidebars.add(issueSidebar)
+ def addIssueSidebar(issueSidebar: (Issue, RepositoryInfo, Context) => Option[Html]): Unit =
+ issueSidebars.add(issueSidebar)
def getIssueSidebars: Seq[(Issue, RepositoryInfo, Context) => Option[Html]] = issueSidebars.asScala.toSeq
@@ -177,7 +185,8 @@
def getSuggestionProviders: Seq[SuggestionProvider] = suggestionProviders.asScala.toSeq
- def addSshCommandProvider(sshCommandProvider: PartialFunction[String, Command]): Unit = sshCommandProviders.add(sshCommandProvider)
+ def addSshCommandProvider(sshCommandProvider: PartialFunction[String, Command]): Unit =
+ sshCommandProviders.add(sshCommandProvider)
def getSshCommandProviders: Seq[PartialFunction[String, Command]] = sshCommandProviders.asScala.toSeq
}
@@ -212,37 +221,44 @@
/**
* Uninstall a specified plugin.
*/
- def uninstall(pluginId: String, context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = synchronized {
- instance.getPlugins()
- .collect { case plugin if plugin.pluginId == pluginId => plugin }
- .foreach { plugin =>
+ def uninstall(pluginId: String, context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit =
+ synchronized {
+ instance
+ .getPlugins()
+ .collect { case plugin if plugin.pluginId == pluginId => plugin }
+ .foreach { plugin =>
// try {
// plugin.pluginClass.uninstall(instance, context, settings)
// } catch {
// case e: Exception =>
// logger.error(s"Error during uninstalling plugin: ${plugin.pluginJar.getName}", e)
// }
- shutdown(context, settings)
- plugin.pluginJar.delete()
- instance = new PluginRegistry()
- initialize(context, settings, conn)
- }
- }
+ shutdown(context, settings)
+ plugin.pluginJar.delete()
+ instance = new PluginRegistry()
+ initialize(context, settings, conn)
+ }
+ }
/**
* Install a plugin from a specified jar file.
*/
- def install(file: File, context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = synchronized {
- shutdown(context, settings)
- FileUtils.copyFile(file, new File(PluginHome, file.getName))
- instance = new PluginRegistry()
- initialize(context, settings, conn)
- }
+ def install(file: File, context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit =
+ synchronized {
+ shutdown(context, settings)
+ FileUtils.copyFile(file, new File(PluginHome, file.getName))
+ instance = new PluginRegistry()
+ initialize(context, settings, conn)
+ }
private def listPluginJars(dir: File): Seq[File] = {
- dir.listFiles(new FilenameFilter {
- override def accept(dir: File, name: String): Boolean = name.endsWith(".jar")
- }).toSeq.sortBy(_.getName).reverse
+ dir
+ .listFiles(new FilenameFilter {
+ override def accept(dir: File, name: String): Boolean = name.endsWith(".jar")
+ })
+ .toSeq
+ .sortBy(_.getName)
+ .reverse
}
lazy val extraPluginDir: Option[String] = Option(System.getProperty("gitbucket.pluginDir"))
@@ -256,13 +272,17 @@
// Clean installed directory
val installedDir = new File(PluginHome, ".installed")
- if(installedDir.exists){
+ if (installedDir.exists) {
FileUtils.deleteDirectory(installedDir)
}
installedDir.mkdirs()
val pluginJars = listPluginJars(pluginDir)
- val extraJars = extraPluginDir.map { extraDir => listPluginJars(new File(extraDir)) }.getOrElse(Nil)
+ val extraJars = extraPluginDir
+ .map { extraDir =>
+ listPluginJars(new File(extraDir))
+ }
+ .getOrElse(Nil)
(extraJars ++ pluginJars).foreach { pluginJar =>
val installedJar = new File(installedDir, pluginJar.getName)
@@ -283,27 +303,32 @@
case None => {
// Migration
val solidbase = new Solidbase()
- solidbase.migrate(conn, classLoader, DatabaseConfig.liquiDriver, new Module(plugin.pluginId, plugin.versions: _*))
+ solidbase
+ .migrate(conn, classLoader, DatabaseConfig.liquiDriver, new Module(plugin.pluginId, plugin.versions: _*))
conn.commit()
// Check database version
val databaseVersion = manager.getCurrentVersion(plugin.pluginId)
val pluginVersion = plugin.versions.last.getVersion
if (databaseVersion != pluginVersion) {
- throw new IllegalStateException(s"Plugin version is ${pluginVersion}, but database version is ${databaseVersion}")
+ throw new IllegalStateException(
+ s"Plugin version is ${pluginVersion}, but database version is ${databaseVersion}"
+ )
}
// Initialize
plugin.initialize(instance, context, settings)
- instance.addPlugin(PluginInfo(
- pluginId = plugin.pluginId,
- pluginName = plugin.pluginName,
- pluginVersion = plugin.versions.last.getVersion,
- description = plugin.description,
- pluginClass = plugin,
- pluginJar = pluginJar,
- classLoader = classLoader
- ))
+ instance.addPlugin(
+ PluginInfo(
+ pluginId = plugin.pluginId,
+ pluginName = plugin.pluginName,
+ pluginVersion = plugin.versions.last.getVersion,
+ description = plugin.description,
+ pluginClass = plugin,
+ pluginJar = pluginJar,
+ classLoader = classLoader
+ )
+ )
}
}
} catch {
@@ -311,13 +336,13 @@
}
}
- if(watcher == null){
+ if (watcher == null) {
watcher = new PluginWatchThread(context, PluginHome)
watcher.start()
}
extraPluginDir.foreach { extraDir =>
- if(extraWatcher == null){
+ if (extraWatcher == null) {
extraWatcher = new PluginWatchThread(context, extraDir)
extraWatcher.start()
}
@@ -328,11 +353,11 @@
instance.getPlugins().foreach { plugin =>
try {
plugin.pluginClass.shutdown(instance, context, settings)
- if(watcher != null){
+ if (watcher != null) {
watcher.interrupt()
watcher = null
}
- if(extraWatcher != null){
+ if (extraWatcher != null) {
extraWatcher.interrupt()
extraWatcher = null
}
@@ -380,17 +405,19 @@
override def run(): Unit = {
val path = Paths.get(dir)
- if(!Files.exists(path)){
+ if (!Files.exists(path)) {
Files.createDirectories(path)
}
val fs = path.getFileSystem
val watcher = fs.newWatchService
- val watchKey = path.register(watcher,
+ val watchKey = path.register(
+ watcher,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY,
StandardWatchEventKinds.ENTRY_DELETE,
- StandardWatchEventKinds.OVERFLOW)
+ StandardWatchEventKinds.OVERFLOW
+ )
logger.info("Start PluginWatchThread: " + path)
@@ -400,13 +427,13 @@
val events = detectedWatchKey.pollEvents.asScala.filter { e =>
e.context.toString != ".installed" && !e.context.toString.endsWith(".bak")
}
- if(events.nonEmpty){
+ if (events.nonEmpty) {
events.foreach { event =>
logger.info(event.kind + ": " + event.context)
}
new Thread {
override def run(): Unit = {
- gitbucket.core.servlet.Database() withTransaction { session =>
+ gitbucket.core.servlet.Database() withTransaction { session =>
logger.info("Reloading plugins...")
PluginRegistry.reload(context, loadSystemSettings(), session.conn)
logger.info("Reloading finished.")
diff --git a/src/main/scala/gitbucket/core/plugin/PluginRepository.scala b/src/main/scala/gitbucket/core/plugin/PluginRepository.scala
index c4cd051..e3d9d1c 100644
--- a/src/main/scala/gitbucket/core/plugin/PluginRepository.scala
+++ b/src/main/scala/gitbucket/core/plugin/PluginRepository.scala
@@ -15,7 +15,7 @@
lazy val LocalRepositoryIndexFile = new java.io.File(LocalRepositoryDir, "plugins.json")
def getPlugins(): Seq[PluginMetadata] = {
- if(LocalRepositoryIndexFile.exists){
+ if (LocalRepositoryIndexFile.exists) {
parsePluginJson(FileUtils.readFileToString(LocalRepositoryIndexFile, "UTF-8"))
} else Nil
}
@@ -29,7 +29,7 @@
description: String,
versions: Seq[VersionDef],
default: Boolean = false
-){
+) {
lazy val latestVersion: VersionDef = versions.last
}
@@ -37,7 +37,6 @@
version: String,
url: String,
range: String
-){
+) {
lazy val file = url.substring(url.lastIndexOf("/") + 1)
}
-
diff --git a/src/main/scala/gitbucket/core/plugin/ReceiveHook.scala b/src/main/scala/gitbucket/core/plugin/ReceiveHook.scala
index 7b76ecc..8452d29 100644
--- a/src/main/scala/gitbucket/core/plugin/ReceiveHook.scala
+++ b/src/main/scala/gitbucket/core/plugin/ReceiveHook.scala
@@ -6,10 +6,12 @@
trait ReceiveHook {
- def preReceive(owner: String, repository: String, receivePack: ReceivePack, command: ReceiveCommand, pusher: String)
- (implicit session: Session): Option[String] = None
+ def preReceive(owner: String, repository: String, receivePack: ReceivePack, command: ReceiveCommand, pusher: String)(
+ implicit session: Session
+ ): Option[String] = None
- def postReceive(owner: String, repository: String, receivePack: ReceivePack, command: ReceiveCommand, pusher: String)
- (implicit session: Session): Unit = ()
+ def postReceive(owner: String, repository: String, receivePack: ReceivePack, command: ReceiveCommand, pusher: String)(
+ implicit session: Session
+ ): Unit = ()
}
diff --git a/src/main/scala/gitbucket/core/plugin/Renderer.scala b/src/main/scala/gitbucket/core/plugin/Renderer.scala
index b4c333e..6c4037b 100644
--- a/src/main/scala/gitbucket/core/plugin/Renderer.scala
+++ b/src/main/scala/gitbucket/core/plugin/Renderer.scala
@@ -21,14 +21,16 @@
object MarkdownRenderer extends Renderer {
override def render(request: RenderRequest): Html = {
import request._
- Html(Markdown.toHtml(
- markdown = fileContent,
- repository = repository,
- enableWikiLink = enableWikiLink,
- enableRefsLink = enableRefsLink,
- enableAnchor = enableAnchor,
- enableLineBreaks = false
- )(context))
+ Html(
+ Markdown.toHtml(
+ markdown = fileContent,
+ repository = repository,
+ enableWikiLink = enableWikiLink,
+ enableRefsLink = enableRefsLink,
+ enableAnchor = enableAnchor,
+ enableLineBreaks = false
+ )(context)
+ )
}
}
diff --git a/src/main/scala/gitbucket/core/plugin/SuggestionProvider.scala b/src/main/scala/gitbucket/core/plugin/SuggestionProvider.scala
index e7d49df..32f5bff 100644
--- a/src/main/scala/gitbucket/core/plugin/SuggestionProvider.scala
+++ b/src/main/scala/gitbucket/core/plugin/SuggestionProvider.scala
@@ -73,7 +73,9 @@
*
* Each element can be accessed as `option` in `template()` or `replace()` method.
*/
- def options(repository: RepositoryInfo): Seq[(String, String)] = values(repository).map { value => (value, value) }
+ def options(repository: RepositoryInfo): Seq[(String, String)] = values(repository).map { value =>
+ (value, value)
+ }
/**
* JavaScript fragment to generate a label of completion proposal. The default is: `option.label`.
diff --git a/src/main/scala/gitbucket/core/service/AccessTokenService.scala b/src/main/scala/gitbucket/core/service/AccessTokenService.scala
index 8c123c5..102240d 100644
--- a/src/main/scala/gitbucket/core/service/AccessTokenService.scala
+++ b/src/main/scala/gitbucket/core/service/AccessTokenService.scala
@@ -7,7 +7,6 @@
import scala.util.Random
-
trait AccessTokenService {
def makeAccessTokenString: String = {
@@ -27,13 +26,10 @@
do {
token = makeAccessTokenString
- hash = tokenToHash(token)
+ hash = tokenToHash(token)
} while (AccessTokens.filter(_.tokenHash === hash.bind).exists.run)
- val newToken = AccessToken(
- userName = userName,
- note = note,
- tokenHash = hash)
+ val newToken = AccessToken(userName = userName, note = note, tokenHash = hash)
val tokenId = (AccessTokens returning AccessTokens.map(_.accessTokenId)) insert newToken
(tokenId, token)
}
@@ -41,8 +37,11 @@
def getAccountByAccessToken(token: String)(implicit s: Session): Option[Account] =
Accounts
.join(AccessTokens)
- .filter { case (ac, t) => (ac.userName === t.userName) && (t.tokenHash === tokenToHash(token).bind) && (ac.removed === false.bind) }
- .map { case (ac, t) => ac }
+ .filter {
+ case (ac, t) =>
+ (ac.userName === t.userName) && (t.tokenHash === tokenToHash(token).bind) && (ac.removed === false.bind)
+ }
+ .map { case (ac, t) => ac }
.firstOption
def getAccessTokens(userName: String)(implicit s: Session): List[AccessToken] =
diff --git a/src/main/scala/gitbucket/core/service/AccountFederationService.scala b/src/main/scala/gitbucket/core/service/AccountFederationService.scala
index a560127..6a3d388 100644
--- a/src/main/scala/gitbucket/core/service/AccountFederationService.scala
+++ b/src/main/scala/gitbucket/core/service/AccountFederationService.scala
@@ -12,20 +12,22 @@
private val logger = LoggerFactory.getLogger(classOf[AccountFederationService])
/**
- * Get or create a user account federated with OIDC or SAML IdP.
- *
- * @param issuer Issuer
- * @param subject Subject
- * @param mailAddress Mail address
- * @param preferredUserName Username (if this is none, username will be generated from the mail address)
- * @param fullName Fullname (defaults to username)
- * @return Account
- */
- def getOrCreateFederatedUser(issuer: String,
- subject: String,
- mailAddress: String,
- preferredUserName: Option[String],
- fullName: Option[String])(implicit s: Session): Option[Account] =
+ * Get or create a user account federated with OIDC or SAML IdP.
+ *
+ * @param issuer Issuer
+ * @param subject Subject
+ * @param mailAddress Mail address
+ * @param preferredUserName Username (if this is none, username will be generated from the mail address)
+ * @param fullName Fullname (defaults to username)
+ * @return Account
+ */
+ def getOrCreateFederatedUser(
+ issuer: String,
+ subject: String,
+ mailAddress: String,
+ preferredUserName: Option[String],
+ fullName: Option[String]
+ )(implicit s: Session): Option[Account] =
getAccountByFederation(issuer, subject) match {
case Some(account) if !account.isRemoved =>
Some(account)
@@ -43,19 +45,25 @@
private def extractSafeStringForUserName(s: String) = """^[a-zA-Z0-9][a-zA-Z0-9\-_.]*""".r.findPrefixOf(s)
/**
- * Find an available username from the preferred username or mail address.
- *
- * @param mailAddress Mail address
- * @param preferredUserName Username
- * @return Available username
- */
- def findAvailableUserName(preferredUserName: Option[String], mailAddress: String)(implicit s: Session): Option[String] = {
- preferredUserName.flatMap(n => extractSafeStringForUserName(n)).orElse(extractSafeStringForUserName(mailAddress)) match {
+ * Find an available username from the preferred username or mail address.
+ *
+ * @param mailAddress Mail address
+ * @param preferredUserName Username
+ * @return Available username
+ */
+ def findAvailableUserName(preferredUserName: Option[String], mailAddress: String)(
+ implicit s: Session
+ ): Option[String] = {
+ preferredUserName
+ .flatMap(n => extractSafeStringForUserName(n))
+ .orElse(extractSafeStringForUserName(mailAddress)) match {
case Some(safeUserName) =>
getAccountByUserName(safeUserName, includeRemoved = true) match {
case None => Some(safeUserName)
case Some(_) =>
- logger.info(s"User ($safeUserName) already exists. preferredUserName=$preferredUserName, mailAddress=$mailAddress")
+ logger.info(
+ s"User ($safeUserName) already exists. preferredUserName=$preferredUserName, mailAddress=$mailAddress"
+ )
None
}
case None =>
@@ -65,8 +73,10 @@
}
def getAccountByFederation(issuer: String, subject: String)(implicit s: Session): Option[Account] =
- AccountFederations.filter(_.byPrimaryKey(issuer, subject))
- .join(Accounts).on { case af ~ ac => af.userName === ac.userName }
+ AccountFederations
+ .filter(_.byPrimaryKey(issuer, subject))
+ .join(Accounts)
+ .on { case af ~ ac => af.userName === ac.userName }
.map { case _ ~ ac => ac }
.firstOption
diff --git a/src/main/scala/gitbucket/core/service/AccountService.scala b/src/main/scala/gitbucket/core/service/AccountService.scala
index e502236..543f743 100644
--- a/src/main/scala/gitbucket/core/service/AccountService.scala
+++ b/src/main/scala/gitbucket/core/service/AccountService.scala
@@ -13,14 +13,16 @@
private val logger = LoggerFactory.getLogger(classOf[AccountService])
- def authenticate(settings: SystemSettings, userName: String, password: String)(implicit s: Session): Option[Account] = {
+ def authenticate(settings: SystemSettings, userName: String, password: String)(
+ implicit s: Session
+ ): Option[Account] = {
val account = if (settings.ldapAuthentication) {
ldapAuthentication(settings, userName, password)
} else {
defaultAuthentication(userName, password)
}
- if(account.isEmpty){
+ if (account.isEmpty) {
logger.info(s"Failed to authenticate: $userName")
}
@@ -32,45 +34,55 @@
*/
private def defaultAuthentication(userName: String, password: String)(implicit s: Session) = {
getAccountByUserName(userName).collect {
- case account if(!account.isGroupAccount && account.password == sha1(password)) => Some(account)
+ case account if (!account.isGroupAccount && account.password == sha1(password)) => Some(account)
} getOrElse None
}
/**
* Authenticate by LDAP.
*/
- private def ldapAuthentication(settings: SystemSettings, userName: String, password: String)
- (implicit s: Session): Option[Account] = {
+ private def ldapAuthentication(settings: SystemSettings, userName: String, password: String)(
+ implicit s: Session
+ ): Option[Account] = {
LDAPUtil.authenticate(settings.ldap.get, userName, password) match {
case Right(ldapUserInfo) => {
// Create or update account by LDAP information
getAccountByUserName(ldapUserInfo.userName, true) match {
- case Some(x) if(!x.isRemoved) => {
- if(settings.ldap.get.mailAttribute.getOrElse("").isEmpty) {
+ case Some(x) if (!x.isRemoved) => {
+ if (settings.ldap.get.mailAttribute.getOrElse("").isEmpty) {
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
} else {
updateAccount(x.copy(mailAddress = ldapUserInfo.mailAddress, fullName = ldapUserInfo.fullName))
}
getAccountByUserName(ldapUserInfo.userName)
}
- case Some(x) if(x.isRemoved) => {
+ case Some(x) if (x.isRemoved) => {
logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
defaultAuthentication(userName, password)
}
- case None => getAccountByMailAddress(ldapUserInfo.mailAddress, true) match {
- case Some(x) if(!x.isRemoved) => {
- updateAccount(x.copy(fullName = ldapUserInfo.fullName))
- getAccountByUserName(ldapUserInfo.userName)
+ case None =>
+ getAccountByMailAddress(ldapUserInfo.mailAddress, true) match {
+ case Some(x) if (!x.isRemoved) => {
+ updateAccount(x.copy(fullName = ldapUserInfo.fullName))
+ getAccountByUserName(ldapUserInfo.userName)
+ }
+ case Some(x) if (x.isRemoved) => {
+ logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
+ defaultAuthentication(userName, password)
+ }
+ case None => {
+ createAccount(
+ ldapUserInfo.userName,
+ "",
+ ldapUserInfo.fullName,
+ ldapUserInfo.mailAddress,
+ false,
+ None,
+ None
+ )
+ getAccountByUserName(ldapUserInfo.userName)
+ }
}
- case Some(x) if(x.isRemoved) => {
- logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
- defaultAuthentication(userName, password)
- }
- case None => {
- createAccount(ldapUserInfo.userName, "", ldapUserInfo.fullName, ldapUserInfo.mailAddress, false, None, None)
- getAccountByUserName(ldapUserInfo.userName)
- }
- }
}
}
case Left(errorMessage) => {
@@ -81,58 +93,90 @@
}
def getAccountByUserName(userName: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] =
- Accounts filter(t => (t.userName === userName.bind) && (t.removed === false.bind, !includeRemoved)) firstOption
+ Accounts filter (t => (t.userName === userName.bind) && (t.removed === false.bind, !includeRemoved)) firstOption
- def getAccountsByUserNames(userNames: Set[String], knowns:Set[Account], includeRemoved: Boolean = false)(implicit s: Session): Map[String, Account] = {
+ def getAccountsByUserNames(userNames: Set[String], knowns: Set[Account], includeRemoved: Boolean = false)(
+ implicit s: Session
+ ): Map[String, Account] = {
val map = knowns.map(a => a.userName -> a).toMap
val needs = userNames -- map.keySet
- if(needs.isEmpty){
+ if (needs.isEmpty) {
map
- }else{
- map ++ Accounts.filter(t => (t.userName inSetBind needs) && (t.removed === false.bind, !includeRemoved)).list.map(a => a.userName -> a).toMap
+ } else {
+ map ++ Accounts
+ .filter(t => (t.userName inSetBind needs) && (t.removed === false.bind, !includeRemoved))
+ .list
+ .map(a => a.userName -> a)
+ .toMap
}
}
- def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] =
- Accounts filter(t => (t.mailAddress.toLowerCase === mailAddress.toLowerCase.bind) && (t.removed === false.bind, !includeRemoved)) firstOption
+ def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false)(
+ implicit s: Session
+ ): Option[Account] =
+ Accounts filter (
+ t => (t.mailAddress.toLowerCase === mailAddress.toLowerCase.bind) && (t.removed === false.bind, !includeRemoved)
+ ) firstOption
- def getAllUsers(includeRemoved: Boolean = true, includeGroups: Boolean = true)(implicit s: Session): List[Account] =
- {
+ def getAllUsers(includeRemoved: Boolean = true, includeGroups: Boolean = true)(implicit s: Session): List[Account] = {
Accounts filter { t =>
(1.bind === 1.bind) &&
- (t.groupAccount === false.bind, !includeGroups) &&
- (t.removed === false.bind, !includeRemoved)
- } sortBy(_.userName) list
+ (t.groupAccount === false.bind, !includeGroups) &&
+ (t.removed === false.bind, !includeRemoved)
+ } sortBy (_.userName) list
}
def isLastAdministrator(account: Account)(implicit s: Session): Boolean = {
- if(account.isAdmin){
+ if (account.isAdmin) {
(Accounts filter (_.removed === false.bind) filter (_.isAdmin === true.bind) map (_.userName.length)).first == 1
} else false
}
- def createAccount(userName: String, password: String, fullName: String, mailAddress: String, isAdmin: Boolean, description: Option[String], url: Option[String])
- (implicit s: Session): Unit =
+ def createAccount(
+ userName: String,
+ password: String,
+ fullName: String,
+ mailAddress: String,
+ isAdmin: Boolean,
+ description: Option[String],
+ url: Option[String]
+ )(implicit s: Session): Unit =
Accounts insert Account(
- userName = userName,
- password = password,
- fullName = fullName,
- mailAddress = mailAddress,
- isAdmin = isAdmin,
- url = url,
+ userName = userName,
+ password = password,
+ fullName = fullName,
+ mailAddress = mailAddress,
+ isAdmin = isAdmin,
+ url = url,
registeredDate = currentDate,
- updatedDate = currentDate,
- lastLoginDate = None,
- image = None,
+ updatedDate = currentDate,
+ lastLoginDate = None,
+ image = None,
isGroupAccount = false,
- isRemoved = false,
- description = description)
+ isRemoved = false,
+ description = description
+ )
def updateAccount(account: Account)(implicit s: Session): Unit =
Accounts
- .filter { a => a.userName === account.userName.bind }
- .map { a => (a.password, a.fullName, a.mailAddress, a.isAdmin, a.url.?, a.registeredDate, a.updatedDate, a.lastLoginDate.?, a.removed, a.description.?) }
- .update (
+ .filter { a =>
+ a.userName === account.userName.bind
+ }
+ .map { a =>
+ (
+ a.password,
+ a.fullName,
+ a.mailAddress,
+ a.isAdmin,
+ a.url.?,
+ a.registeredDate,
+ a.updatedDate,
+ a.lastLoginDate.?,
+ a.removed,
+ a.description.?
+ )
+ }
+ .update(
account.password,
account.fullName,
account.mailAddress,
@@ -142,7 +186,8 @@
currentDate,
account.lastLoginDate,
account.isRemoved,
- account.description)
+ account.description
+ )
def updateAvatarImage(userName: String, image: Option[String])(implicit s: Session): Unit =
Accounts.filter(_.userName === userName.bind).map(_.image.?).update(image)
@@ -152,29 +197,34 @@
def createGroup(groupName: String, description: Option[String], url: Option[String])(implicit s: Session): Unit =
Accounts insert Account(
- userName = groupName,
- password = "",
- fullName = groupName,
- mailAddress = groupName + "@devnull",
- isAdmin = false,
- url = url,
+ userName = groupName,
+ password = "",
+ fullName = groupName,
+ mailAddress = groupName + "@devnull",
+ isAdmin = false,
+ url = url,
registeredDate = currentDate,
- updatedDate = currentDate,
- lastLoginDate = None,
- image = None,
+ updatedDate = currentDate,
+ lastLoginDate = None,
+ image = None,
isGroupAccount = true,
- isRemoved = false,
- description = description)
+ isRemoved = false,
+ description = description
+ )
- def updateGroup(groupName: String, description: Option[String], url: Option[String], removed: Boolean)(implicit s: Session): Unit =
- Accounts.filter(_.userName === groupName.bind)
+ def updateGroup(groupName: String, description: Option[String], url: Option[String], removed: Boolean)(
+ implicit s: Session
+ ): Unit =
+ Accounts
+ .filter(_.userName === groupName.bind)
.map(t => (t.url.?, t.description.?, t.updatedDate, t.removed))
.update(url, description, currentDate, removed)
def updateGroupMembers(groupName: String, members: List[(String, Boolean)])(implicit s: Session): Unit = {
GroupMembers.filter(_.groupName === groupName.bind).delete
- members.foreach { case (userName, isManager) =>
- GroupMembers insert GroupMember (groupName, userName, isManager)
+ members.foreach {
+ case (userName, isManager) =>
+ GroupMembers insert GroupMember(groupName, userName, isManager)
}
}
diff --git a/src/main/scala/gitbucket/core/service/ActivityService.scala b/src/main/scala/gitbucket/core/service/ActivityService.scala
index 54d9d5a..ef83188 100644
--- a/src/main/scala/gitbucket/core/service/ActivityService.scala
+++ b/src/main/scala/gitbucket/core/service/ActivityService.scala
@@ -15,188 +15,356 @@
def getActivitiesByUser(activityUserName: String, isPublic: Boolean)(implicit s: Session): List[Activity] =
Activities
- .join(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
- .filter { case (t1, t2) =>
- if(isPublic){
- (t1.activityUserName === activityUserName.bind) && (t2.isPrivate === false.bind)
- } else {
- (t1.activityUserName === activityUserName.bind)
- }
+ .join(Repositories)
+ .on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
+ .filter {
+ case (t1, t2) =>
+ if (isPublic) {
+ (t1.activityUserName === activityUserName.bind) && (t2.isPrivate === false.bind)
+ } else {
+ (t1.activityUserName === activityUserName.bind)
+ }
}
.sortBy { case (t1, t2) => t1.activityId desc }
- .map { case (t1, t2) => t1 }
+ .map { case (t1, t2) => t1 }
.take(30)
.list
def getRecentActivities()(implicit s: Session): List[Activity] =
Activities
- .join(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
- .filter { case (t1, t2) => t2.isPrivate === false.bind }
+ .join(Repositories)
+ .on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
+ .filter { case (t1, t2) => t2.isPrivate === false.bind }
.sortBy { case (t1, t2) => t1.activityId desc }
- .map { case (t1, t2) => t1 }
+ .map { case (t1, t2) => t1 }
.take(30)
.list
- def getRecentActivitiesByOwners(owners : Set[String])(implicit s: Session): List[Activity] =
+ def getRecentActivitiesByOwners(owners: Set[String])(implicit s: Session): List[Activity] =
Activities
- .join(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
+ .join(Repositories)
+ .on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
.filter { case (t1, t2) => (t2.isPrivate === false.bind) || (t2.userName inSetBind owners) }
.sortBy { case (t1, t2) => t1.activityId desc }
- .map { case (t1, t2) => t1 }
+ .map { case (t1, t2) => t1 }
.take(30)
.list
- def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String)(
+ implicit s: Session
+ ): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"create_repository",
s"[user:${activityUserName}] created [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordCreateIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCreateIssueActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ title: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"open_issue",
s"[user:${activityUserName}] opened issue [issue:${userName}/${repositoryName}#${issueId}]",
Some(title),
- currentDate)
+ currentDate
+ )
- def recordCloseIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCloseIssueActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ title: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"close_issue",
s"[user:${activityUserName}] closed issue [issue:${userName}/${repositoryName}#${issueId}]",
Some(title),
- currentDate)
+ currentDate
+ )
- def recordClosePullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordClosePullRequestActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ title: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"close_issue",
s"[user:${activityUserName}] closed pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
Some(title),
- currentDate)
+ currentDate
+ )
- def recordReopenIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordReopenIssueActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ title: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"reopen_issue",
s"[user:${activityUserName}] reopened issue [issue:${userName}/${repositoryName}#${issueId}]",
Some(title),
- currentDate)
+ currentDate
+ )
- def recordCommentIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCommentIssueActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ comment: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"comment_issue",
s"[user:${activityUserName}] commented on issue [issue:${userName}/${repositoryName}#${issueId}]",
Some(cut(comment, 200)),
- currentDate)
+ currentDate
+ )
- def recordCommentPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCommentPullRequestActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ comment: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"comment_issue",
s"[user:${activityUserName}] commented on pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
Some(cut(comment, 200)),
- currentDate)
+ currentDate
+ )
- def recordCommentCommitActivity(userName: String, repositoryName: String, activityUserName: String, commitId: String, comment: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCommentCommitActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ commitId: String,
+ comment: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"comment_commit",
s"[user:${activityUserName}] commented on commit [commit:${userName}/${repositoryName}@${commitId}]",
Some(cut(comment, 200)),
currentDate
)
- def recordCreateWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCreateWikiPageActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ pageName: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"create_wiki",
s"[user:${activityUserName}] created the [repo:${userName}/${repositoryName}] wiki",
Some(pageName),
- currentDate)
+ currentDate
+ )
- def recordEditWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String, commitId: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordEditWikiPageActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ pageName: String,
+ commitId: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"edit_wiki",
s"[user:${activityUserName}] edited the [repo:${userName}/${repositoryName}] wiki",
Some(pageName + ":" + commitId),
- currentDate)
+ currentDate
+ )
- def recordPushActivity(userName: String, repositoryName: String, activityUserName: String,
- branchName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordPushActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ branchName: String,
+ commits: List[JGitUtil.CommitInfo]
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"push",
s"[user:${activityUserName}] pushed to [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
- Some(commits.take(5).map { commit => commit.id + ":" + commit.shortMessage }.mkString("\n")),
- currentDate)
+ Some(
+ commits
+ .take(5)
+ .map { commit =>
+ commit.id + ":" + commit.shortMessage
+ }
+ .mkString("\n")
+ ),
+ currentDate
+ )
- def recordCreateTagActivity(userName: String, repositoryName: String, activityUserName: String,
- tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCreateTagActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ tagName: String,
+ commits: List[JGitUtil.CommitInfo]
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"create_tag",
s"[user:${activityUserName}] created tag [tag:${userName}/${repositoryName}#${tagName}] at [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordDeleteTagActivity(userName: String, repositoryName: String, activityUserName: String,
- tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordDeleteTagActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ tagName: String,
+ commits: List[JGitUtil.CommitInfo]
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"delete_tag",
s"[user:${activityUserName}] deleted tag ${tagName} at [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordCreateBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordCreateBranchActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ branchName: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"create_branch",
s"[user:${activityUserName}] created branch [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordDeleteBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordDeleteBranchActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ branchName: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"delete_branch",
s"[user:${activityUserName}] deleted branch ${branchName} at [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String)(implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String)(
+ implicit s: Session
+ ): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"fork",
s"[user:${activityUserName}] forked [repo:${userName}/${repositoryName}] to [repo:${forkedUserName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
- def recordPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordPullRequestActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ title: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"open_pullreq",
s"[user:${activityUserName}] opened pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
Some(title),
- currentDate)
+ currentDate
+ )
- def recordMergeActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, message: String)
- (implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordMergeActivity(
+ userName: String,
+ repositoryName: String,
+ activityUserName: String,
+ issueId: Int,
+ message: String
+ )(implicit s: Session): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"merge_pullreq",
s"[user:${activityUserName}] merged pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
Some(message),
- currentDate)
+ currentDate
+ )
- def recordReleaseActivity(userName: String, repositoryName: String, activityUserName: String, name: String)(implicit s: Session): Unit =
- Activities insert Activity(userName, repositoryName, activityUserName,
+ def recordReleaseActivity(userName: String, repositoryName: String, activityUserName: String, name: String)(
+ implicit s: Session
+ ): Unit =
+ Activities insert Activity(
+ userName,
+ repositoryName,
+ activityUserName,
"release",
s"[user:${activityUserName}] released ${name} at [repo:${userName}/${repositoryName}]",
None,
- currentDate)
+ currentDate
+ )
private def cut(value: String, length: Int): String =
- if(value.length > length) value.substring(0, length) + "..." else value
+ if (value.length > length) value.substring(0, length) + "..." else value
}
diff --git a/src/main/scala/gitbucket/core/service/CommitStatusService.scala b/src/main/scala/gitbucket/core/service/CommitStatusService.scala
index ca24ff9..25a9b6b 100644
--- a/src/main/scala/gitbucket/core/service/CommitStatusService.scala
+++ b/src/main/scala/gitbucket/core/service/CommitStatusService.scala
@@ -6,47 +6,77 @@
import gitbucket.core.model.{CommitState, CommitStatus, Account}
trait CommitStatusService {
- /** insert or update */
- def createCommitStatus(userName: String, repositoryName: String, sha: String, context: String, state: CommitState,
- targetUrl: Option[String], description: Option[String], now: java.util.Date, creator: Account)(implicit s: Session): Int =
- CommitStatuses
- .filter(t => t.byCommit(userName, repositoryName, sha) && t.context === context.bind )
- .map(_.commitStatusId).firstOption match {
- case Some(id: Int) => {
- CommitStatuses.filter(_.byPrimaryKey(id)).map { t =>
- (t.state , t.targetUrl , t.updatedDate , t.creator, t.description)
- }.update((state, targetUrl, now, creator.userName, description))
- id
- }
- case None => (CommitStatuses returning CommitStatuses.map(_.commitStatusId)) insert CommitStatus(
- userName = userName,
- repositoryName = repositoryName,
- commitId = sha,
- context = context,
- state = state,
- targetUrl = targetUrl,
- description = description,
- creator = creator.userName,
- registeredDate = now,
- updatedDate = now)
- }
- def getCommitStatus(userName: String, repositoryName: String, id: Int)(implicit s: Session) :Option[CommitStatus] =
+ /** insert or update */
+ def createCommitStatus(
+ userName: String,
+ repositoryName: String,
+ sha: String,
+ context: String,
+ state: CommitState,
+ targetUrl: Option[String],
+ description: Option[String],
+ now: java.util.Date,
+ creator: Account
+ )(implicit s: Session): Int =
+ CommitStatuses
+ .filter(t => t.byCommit(userName, repositoryName, sha) && t.context === context.bind)
+ .map(_.commitStatusId)
+ .firstOption match {
+ case Some(id: Int) => {
+ CommitStatuses
+ .filter(_.byPrimaryKey(id))
+ .map { t =>
+ (t.state, t.targetUrl, t.updatedDate, t.creator, t.description)
+ }
+ .update((state, targetUrl, now, creator.userName, description))
+ id
+ }
+ case None =>
+ (CommitStatuses returning CommitStatuses.map(_.commitStatusId)) insert CommitStatus(
+ userName = userName,
+ repositoryName = repositoryName,
+ commitId = sha,
+ context = context,
+ state = state,
+ targetUrl = targetUrl,
+ description = description,
+ creator = creator.userName,
+ registeredDate = now,
+ updatedDate = now
+ )
+ }
+
+ def getCommitStatus(userName: String, repositoryName: String, id: Int)(implicit s: Session): Option[CommitStatus] =
CommitStatuses.filter(t => t.byPrimaryKey(id) && t.byRepository(userName, repositoryName)).firstOption
- def getCommitStatus(userName: String, repositoryName: String, sha: String, context: String)(implicit s: Session) :Option[CommitStatus] =
+ def getCommitStatus(userName: String, repositoryName: String, sha: String, context: String)(
+ implicit s: Session
+ ): Option[CommitStatus] =
CommitStatuses.filter(t => t.byCommit(userName, repositoryName, sha) && t.context === context.bind).firstOption
- def getCommitStatues(userName: String, repositoryName: String, sha: String)(implicit s: Session) :List[CommitStatus] =
+ def getCommitStatues(userName: String, repositoryName: String, sha: String)(implicit s: Session): List[CommitStatus] =
byCommitStatues(userName, repositoryName, sha).list
- def getRecentStatuesContexts(userName: String, repositoryName: String, time: java.util.Date)(implicit s: Session) :List[String] =
- CommitStatuses.filter(t => t.byRepository(userName, repositoryName)).filter(t => t.updatedDate > time.bind).groupBy(_.context).map(_._1).list
+ def getRecentStatuesContexts(userName: String, repositoryName: String, time: java.util.Date)(
+ implicit s: Session
+ ): List[String] =
+ CommitStatuses
+ .filter(t => t.byRepository(userName, repositoryName))
+ .filter(t => t.updatedDate > time.bind)
+ .groupBy(_.context)
+ .map(_._1)
+ .list
- def getCommitStatuesWithCreator(userName: String, repositoryName: String, sha: String)(implicit s: Session) :List[(CommitStatus, Account)] =
- byCommitStatues(userName, repositoryName, sha).join(Accounts).filter { case (t, a) => t.creator === a.userName }.list
+ def getCommitStatuesWithCreator(userName: String, repositoryName: String, sha: String)(
+ implicit s: Session
+ ): List[(CommitStatus, Account)] =
+ byCommitStatues(userName, repositoryName, sha)
+ .join(Accounts)
+ .filter { case (t, a) => t.creator === a.userName }
+ .list
- protected def byCommitStatues(userName: String, repositoryName: String, sha: String)(implicit s: Session) =
+ protected def byCommitStatues(userName: String, repositoryName: String, sha: String)(implicit s: Session) =
CommitStatuses.filter(t => t.byCommit(userName, repositoryName, sha)).sortBy(_.updatedDate desc)
}
diff --git a/src/main/scala/gitbucket/core/service/CommitsService.scala b/src/main/scala/gitbucket/core/service/CommitsService.scala
index 3e28f45..c3142c7 100644
--- a/src/main/scala/gitbucket/core/service/CommitsService.scala
+++ b/src/main/scala/gitbucket/core/service/CommitsService.scala
@@ -7,9 +7,11 @@
trait CommitsService {
- def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean)(implicit s: Session) =
- CommitComments filter {
- t => t.byCommit(owner, repository, commitId) && (t.issueId.isEmpty || includePullRequest)
+ def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean)(
+ implicit s: Session
+ ) =
+ CommitComments filter { t =>
+ t.byCommit(owner, repository, commitId) && (t.issueId.isEmpty || includePullRequest)
} list
def getCommitComment(owner: String, repository: String, commentId: String)(implicit s: Session) =
@@ -20,33 +22,48 @@
else
None
- def createCommitComment(owner: String, repository: String, commitId: String, loginUser: String,
- content: String, fileName: Option[String], oldLine: Option[Int], newLine: Option[Int],
- issueId: Option[Int])(implicit s: Session): Int =
+ def createCommitComment(
+ owner: String,
+ repository: String,
+ commitId: String,
+ loginUser: String,
+ content: String,
+ fileName: Option[String],
+ oldLine: Option[Int],
+ newLine: Option[Int],
+ issueId: Option[Int]
+ )(implicit s: Session): Int =
CommitComments returning CommitComments.map(_.commentId) insert CommitComment(
- userName = owner,
- repositoryName = repository,
- commitId = commitId,
+ userName = owner,
+ repositoryName = repository,
+ commitId = commitId,
commentedUserName = loginUser,
- content = content,
- fileName = fileName,
- oldLine = oldLine,
- newLine = newLine,
- registeredDate = currentDate,
- updatedDate = currentDate,
- issueId = issueId)
+ content = content,
+ fileName = fileName,
+ oldLine = oldLine,
+ newLine = newLine,
+ registeredDate = currentDate,
+ updatedDate = currentDate,
+ issueId = issueId
+ )
- def updateCommitCommentPosition(commentId: Int, commitId: String, oldLine: Option[Int], newLine: Option[Int])(implicit s: Session): Unit =
- CommitComments.filter(_.byPrimaryKey(commentId))
+ def updateCommitCommentPosition(commentId: Int, commitId: String, oldLine: Option[Int], newLine: Option[Int])(
+ implicit s: Session
+ ): Unit =
+ CommitComments
+ .filter(_.byPrimaryKey(commentId))
.map { t =>
(t.commitId, t.oldLine, t.newLine)
- }.update(commitId, oldLine, newLine)
+ }
+ .update(commitId, oldLine, newLine)
def updateCommitComment(commentId: Int, content: String)(implicit s: Session) = {
CommitComments
- .filter (_.byPrimaryKey(commentId))
- .map { t => (t.content, t.updatedDate) }
- .update (content, currentDate)
+ .filter(_.byPrimaryKey(commentId))
+ .map { t =>
+ (t.content, t.updatedDate)
+ }
+ .update(content, currentDate)
}
def deleteCommitComment(commentId: Int)(implicit s: Session) =
diff --git a/src/main/scala/gitbucket/core/service/DeployKeyService.scala b/src/main/scala/gitbucket/core/service/DeployKeyService.scala
index 7313bc6..13885a6 100644
--- a/src/main/scala/gitbucket/core/service/DeployKeyService.scala
+++ b/src/main/scala/gitbucket/core/service/DeployKeyService.scala
@@ -6,20 +6,24 @@
trait DeployKeyService {
- def addDeployKey(userName: String, repositoryName: String, title: String, publicKey: String, allowWrite: Boolean)
- (implicit s: Session): Unit =
- DeployKeys.insert(DeployKey(
- userName = userName,
- repositoryName = repositoryName,
- title = title,
- publicKey = publicKey,
- allowWrite = allowWrite
- ))
+ def addDeployKey(userName: String, repositoryName: String, title: String, publicKey: String, allowWrite: Boolean)(
+ implicit s: Session
+ ): Unit =
+ DeployKeys.insert(
+ DeployKey(
+ userName = userName,
+ repositoryName = repositoryName,
+ title = title,
+ publicKey = publicKey,
+ allowWrite = allowWrite
+ )
+ )
def getDeployKeys(userName: String, repositoryName: String)(implicit s: Session): List[DeployKey] =
DeployKeys
.filter(x => (x.userName === userName.bind) && (x.repositoryName === repositoryName.bind))
- .sortBy(_.deployKeyId).list
+ .sortBy(_.deployKeyId)
+ .list
def getAllDeployKeys()(implicit s: Session): List[DeployKey] =
DeployKeys.filter(_.publicKey.trim =!= "").list
@@ -27,5 +31,4 @@
def deleteDeployKey(userName: String, repositoryName: String, deployKeyId: Int)(implicit s: Session): Unit =
DeployKeys.filter(_.byPrimaryKey(userName, repositoryName, deployKeyId)).delete
-
}
diff --git a/src/main/scala/gitbucket/core/service/HandleCommentService.scala b/src/main/scala/gitbucket/core/service/HandleCommentService.scala
index 3ef52e6..edd968f 100644
--- a/src/main/scala/gitbucket/core/service/HandleCommentService.scala
+++ b/src/main/scala/gitbucket/core/service/HandleCommentService.scala
@@ -8,85 +8,111 @@
import gitbucket.core.util.Implicits._
trait HandleCommentService {
- self: RepositoryService with IssuesService with ActivityService
- with WebHookService with WebHookIssueCommentService with WebHookPullRequestService =>
+ self: RepositoryService
+ with IssuesService
+ with ActivityService
+ with WebHookService
+ with WebHookIssueCommentService
+ with WebHookPullRequestService =>
/**
* @see [[https://github.com/gitbucket/gitbucket/wiki/CommentAction]]
*/
- def handleComment(issue: Issue, content: Option[String], repository: RepositoryService.RepositoryInfo, actionOpt: Option[String])
- (implicit context: Context, s: Session) = {
+ def handleComment(
+ issue: Issue,
+ content: Option[String],
+ repository: RepositoryService.RepositoryInfo,
+ actionOpt: Option[String]
+ )(implicit context: Context, s: Session) = {
context.loginAccount.flatMap { loginAccount =>
- defining(repository.owner, repository.name){ case (owner, name) =>
- val userName = loginAccount.userName
+ defining(repository.owner, repository.name) {
+ case (owner, name) =>
+ val userName = loginAccount.userName
- val (action, actionActivity) = actionOpt
- .collect {
- case "close" if(!issue.closed) => true ->
- (Some("close") -> Some(if(issue.isPullRequest) recordClosePullRequestActivity _ else recordCloseIssueActivity _))
- case "reopen" if(issue.closed) => false ->
- (Some("reopen") -> Some(recordReopenIssueActivity _))
- }
- .map { case (closed, t) =>
- updateClosed(owner, name, issue.issueId, closed)
- t
- }
- .getOrElse(None -> None)
-
- val commentId = (content, action) match {
- case (None, None) => None
- case (None, Some(action)) =>
- Some(createComment(owner, name, userName, issue.issueId, action.capitalize, action))
- case (Some(content), _) =>
- val id = Some(createComment(owner, name, userName, issue.issueId, content, action.map(_+ "_comment").getOrElse("comment")))
-
- // record comment activity
- if(issue.isPullRequest) recordCommentPullRequestActivity(owner, name, userName, issue.issueId, content)
- else recordCommentIssueActivity(owner, name, userName, issue.issueId, content)
-
- // extract references and create refer comment
- createReferComment(owner, name, issue, content, loginAccount)
-
- id
- }
-
- actionActivity.foreach { f => f(owner, name, userName, issue.issueId, issue.title) }
-
- // call web hooks
- action match {
- case None => commentId foreach (callIssueCommentWebHook(repository, issue, _, loginAccount))
- case Some(act) =>
- val webHookAction = act match {
- case "close" => "closed"
- case "reopen" => "reopened"
+ val (action, actionActivity) = actionOpt
+ .collect {
+ case "close" if (!issue.closed) =>
+ true ->
+ (Some("close") -> Some(
+ if (issue.isPullRequest) recordClosePullRequestActivity _
+ else recordCloseIssueActivity _
+ ))
+ case "reopen" if (issue.closed) =>
+ false ->
+ (Some("reopen") -> Some(recordReopenIssueActivity _))
}
- if(issue.isPullRequest)
- callPullRequestWebHook(webHookAction, repository, issue.issueId, context.baseUrl, loginAccount)
- else
- callIssuesWebHook(webHookAction, repository, issue, context.baseUrl, loginAccount)
- }
+ .map {
+ case (closed, t) =>
+ updateClosed(owner, name, issue.issueId, closed)
+ t
+ }
+ .getOrElse(None -> None)
- // call hooks
- content foreach { x =>
- if(issue.isPullRequest)
- PluginRegistry().getPullRequestHooks.foreach(_.addedComment(commentId.get, x, issue, repository))
- else
- PluginRegistry().getIssueHooks.foreach(_.addedComment(commentId.get, x, issue, repository))
- }
- action foreach {
- case "close" =>
- if(issue.isPullRequest)
- PluginRegistry().getPullRequestHooks.foreach(_.closed(issue, repository))
- else
- PluginRegistry().getIssueHooks.foreach(_.closed(issue, repository))
- case "reopen" =>
- if(issue.isPullRequest)
- PluginRegistry().getPullRequestHooks.foreach(_.reopened(issue, repository))
- else
- PluginRegistry().getIssueHooks.foreach(_.reopened(issue, repository))
- }
+ val commentId = (content, action) match {
+ case (None, None) => None
+ case (None, Some(action)) =>
+ Some(createComment(owner, name, userName, issue.issueId, action.capitalize, action))
+ case (Some(content), _) =>
+ val id = Some(
+ createComment(
+ owner,
+ name,
+ userName,
+ issue.issueId,
+ content,
+ action.map(_ + "_comment").getOrElse("comment")
+ )
+ )
- commentId.map( issue -> _ )
+ // record comment activity
+ if (issue.isPullRequest) recordCommentPullRequestActivity(owner, name, userName, issue.issueId, content)
+ else recordCommentIssueActivity(owner, name, userName, issue.issueId, content)
+
+ // extract references and create refer comment
+ createReferComment(owner, name, issue, content, loginAccount)
+
+ id
+ }
+
+ actionActivity.foreach { f =>
+ f(owner, name, userName, issue.issueId, issue.title)
+ }
+
+ // call web hooks
+ action match {
+ case None => commentId foreach (callIssueCommentWebHook(repository, issue, _, loginAccount))
+ case Some(act) =>
+ val webHookAction = act match {
+ case "close" => "closed"
+ case "reopen" => "reopened"
+ }
+ if (issue.isPullRequest)
+ callPullRequestWebHook(webHookAction, repository, issue.issueId, context.baseUrl, loginAccount)
+ else
+ callIssuesWebHook(webHookAction, repository, issue, context.baseUrl, loginAccount)
+ }
+
+ // call hooks
+ content foreach { x =>
+ if (issue.isPullRequest)
+ PluginRegistry().getPullRequestHooks.foreach(_.addedComment(commentId.get, x, issue, repository))
+ else
+ PluginRegistry().getIssueHooks.foreach(_.addedComment(commentId.get, x, issue, repository))
+ }
+ action foreach {
+ case "close" =>
+ if (issue.isPullRequest)
+ PluginRegistry().getPullRequestHooks.foreach(_.closed(issue, repository))
+ else
+ PluginRegistry().getIssueHooks.foreach(_.closed(issue, repository))
+ case "reopen" =>
+ if (issue.isPullRequest)
+ PluginRegistry().getPullRequestHooks.foreach(_.reopened(issue, repository))
+ else
+ PluginRegistry().getIssueHooks.foreach(_.reopened(issue, repository))
+ }
+
+ commentId.map(issue -> _)
}
}
}
diff --git a/src/main/scala/gitbucket/core/service/IssueCreationService.scala b/src/main/scala/gitbucket/core/service/IssueCreationService.scala
index ad67266..a769fb8 100644
--- a/src/main/scala/gitbucket/core/service/IssueCreationService.scala
+++ b/src/main/scala/gitbucket/core/service/IssueCreationService.scala
@@ -11,20 +11,33 @@
self: RepositoryService with WebHookIssueCommentService with LabelsService with IssuesService with ActivityService =>
- def createIssue(repository: RepositoryInfo, title:String, body:Option[String],
- assignee: Option[String], milestoneId: Option[Int], priorityId: Option[Int], labelNames: Seq[String],
- loginAccount: Account)(implicit context: Context, s: Session) : Issue = {
+ def createIssue(
+ repository: RepositoryInfo,
+ title: String,
+ body: Option[String],
+ assignee: Option[String],
+ milestoneId: Option[Int],
+ priorityId: Option[Int],
+ labelNames: Seq[String],
+ loginAccount: Account
+ )(implicit context: Context, s: Session): Issue = {
val owner = repository.owner
- val name = repository.name
- val userName = loginAccount.userName
+ val name = repository.name
+ val userName = loginAccount.userName
val manageable = isIssueManageable(repository)
// insert issue
- val issueId = insertIssue(owner, name, userName, title, body,
+ val issueId = insertIssue(
+ owner,
+ name,
+ userName,
+ title,
+ body,
if (manageable) assignee else None,
if (manageable) milestoneId else None,
- if (manageable) priorityId else None)
+ if (manageable) priorityId else None
+ )
val issue: Issue = getIssue(owner, name, issueId.toString).get
// insert labels
diff --git a/src/main/scala/gitbucket/core/service/IssuesService.scala b/src/main/scala/gitbucket/core/service/IssuesService.scala
index f081d9c..8f665c6 100644
--- a/src/main/scala/gitbucket/core/service/IssuesService.scala
+++ b/src/main/scala/gitbucket/core/service/IssuesService.scala
@@ -5,7 +5,17 @@
import gitbucket.core.util.Implicits._
import gitbucket.core.util.SyntaxSugars._
import gitbucket.core.controller.Context
-import gitbucket.core.model.{Issue, PullRequest, IssueComment, IssueLabel, Label, Account, Repository, CommitState, Role}
+import gitbucket.core.model.{
+ Issue,
+ PullRequest,
+ IssueComment,
+ IssueLabel,
+ Label,
+ Account,
+ Repository,
+ CommitState,
+ Role
+}
import gitbucket.core.model.Profile._
import gitbucket.core.model.Profile.profile._
import gitbucket.core.model.Profile.profile.blockingApi._
@@ -21,22 +31,31 @@
else None
def getComments(owner: String, repository: String, issueId: Int)(implicit s: Session) =
- IssueComments filter (_.byIssue(owner, repository, issueId)) sortBy(_.commentId asc) list
+ IssueComments filter (_.byIssue(owner, repository, issueId)) sortBy (_.commentId asc) list
/** @return IssueComment and commentedUser and Issue */
- def getCommentsForApi(owner: String, repository: String, issueId: Int)(implicit s: Session): List[(IssueComment, Account, Issue)] =
- IssueComments.filter(_.byIssue(owner, repository, issueId))
- .filter(_.action inSetBind Set("comment" , "close_comment", "reopen_comment"))
- .join(Accounts).on { case t1 ~ t2 => t1.commentedUserName === t2.userName }
- .join(Issues).on { case t1 ~ t2 ~ t3 => t3.byIssue(t1.userName, t1.repositoryName, t1.issueId) }
- .map { case t1 ~ t2 ~ t3 => (t1, t2, t3) }
- .list
+ def getCommentsForApi(owner: String, repository: String, issueId: Int)(
+ implicit s: Session
+ ): List[(IssueComment, Account, Issue)] =
+ IssueComments
+ .filter(_.byIssue(owner, repository, issueId))
+ .filter(_.action inSetBind Set("comment", "close_comment", "reopen_comment"))
+ .join(Accounts)
+ .on { case t1 ~ t2 => t1.commentedUserName === t2.userName }
+ .join(Issues)
+ .on { case t1 ~ t2 ~ t3 => t3.byIssue(t1.userName, t1.repositoryName, t1.issueId) }
+ .map { case t1 ~ t2 ~ t3 => (t1, t2, t3) }
+ .list
- def getMergedComment(owner: String, repository: String, issueId: Int)(implicit s: Session): Option[(IssueComment, Account)] = {
- IssueComments.filter(_.byIssue(owner, repository, issueId))
+ def getMergedComment(owner: String, repository: String, issueId: Int)(
+ implicit s: Session
+ ): Option[(IssueComment, Account)] = {
+ IssueComments
+ .filter(_.byIssue(owner, repository, issueId))
.filter(_.action === "merge".bind)
- .join(Accounts).on { case t1 ~ t2 => t1.commentedUserName === t2.userName }
- .map { case t1 ~ t2 => (t1, t2)}
+ .join(Accounts)
+ .on { case t1 ~ t2 => t1.commentedUserName === t2.userName }
+ .map { case t1 ~ t2 => (t1, t2) }
.firstOption
}
@@ -50,15 +69,19 @@
def getIssueLabels(owner: String, repository: String, issueId: Int)(implicit s: Session): List[Label] = {
IssueLabels
- .join(Labels).on { case t1 ~ t2 =>
- t1.byLabel(t2.userName, t2.repositoryName, t2.labelId)
+ .join(Labels)
+ .on {
+ case t1 ~ t2 =>
+ t1.byLabel(t2.userName, t2.repositoryName, t2.labelId)
}
.filter { case t1 ~ t2 => t1.byIssue(owner, repository, issueId) }
.map { case t1 ~ t2 => t2 }
.list
}
- def getIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int)(implicit s: Session): Option[IssueLabel] = {
+ def getIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int)(
+ implicit s: Session
+ ): Option[IssueLabel] = {
IssueLabels filter (_.byPrimaryKey(owner, repository, issueId, labelId)) firstOption
}
@@ -70,7 +93,9 @@
* @param repos Tuple of the repository owner and the repository name
* @return the count of the search result
*/
- def countIssue(condition: IssueSearchCondition, onlyPullRequest: Boolean, repos: (String, String)*)(implicit s: Session): Int = {
+ def countIssue(condition: IssueSearchCondition, onlyPullRequest: Boolean, repos: (String, String)*)(
+ implicit s: Session
+ ): Int = {
Query(searchIssueQuery(repos, condition, onlyPullRequest).length).first
}
@@ -82,69 +107,95 @@
* @param condition the search condition
* @return the Map which contains issue count for each labels (key is label name, value is issue count)
*/
- def countIssueGroupByLabels(owner: String, repository: String, condition: IssueSearchCondition,
- filterUser: Map[String, String])(implicit s: Session): Map[String, Int] = {
+ def countIssueGroupByLabels(
+ owner: String,
+ repository: String,
+ condition: IssueSearchCondition,
+ filterUser: Map[String, String]
+ )(implicit s: Session): Map[String, Int] = {
searchIssueQuery(Seq(owner -> repository), condition.copy(labels = Set.empty), false)
- .join(IssueLabels).on { case t1 ~ t2 =>
- t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
+ .join(IssueLabels)
+ .on {
+ case t1 ~ t2 =>
+ t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
}
- .join(Labels).on { case t1 ~ t2 ~ t3 =>
- t2.byLabel(t3.userName, t3.repositoryName, t3.labelId)
+ .join(Labels)
+ .on {
+ case t1 ~ t2 ~ t3 =>
+ t2.byLabel(t3.userName, t3.repositoryName, t3.labelId)
}
- .groupBy { case t1 ~ t2 ~ t3 =>
- t3.labelName
+ .groupBy {
+ case t1 ~ t2 ~ t3 =>
+ t3.labelName
}
- .map { case labelName ~ t =>
- labelName -> t.length
+ .map {
+ case labelName ~ t =>
+ labelName -> t.length
}
- .list.toMap
+ .list
+ .toMap
}
/**
- * Returns the Map which contains issue count for each priority.
- *
- * @param owner the repository owner
- * @param repository the repository name
- * @param condition the search condition
- * @return the Map which contains issue count for each priority (key is priority name, value is issue count)
- */
- def countIssueGroupByPriorities(owner: String, repository: String, condition: IssueSearchCondition,
- filterUser: Map[String, String])(implicit s: Session): Map[String, Int] = {
+ * Returns the Map which contains issue count for each priority.
+ *
+ * @param owner the repository owner
+ * @param repository the repository name
+ * @param condition the search condition
+ * @return the Map which contains issue count for each priority (key is priority name, value is issue count)
+ */
+ def countIssueGroupByPriorities(
+ owner: String,
+ repository: String,
+ condition: IssueSearchCondition,
+ filterUser: Map[String, String]
+ )(implicit s: Session): Map[String, Int] = {
searchIssueQuery(Seq(owner -> repository), condition.copy(labels = Set.empty), false)
- .join(Priorities).on { case t1 ~ t2 =>
- t1.byPriority(t2.userName, t2.repositoryName, t2.priorityId)
+ .join(Priorities)
+ .on {
+ case t1 ~ t2 =>
+ t1.byPriority(t2.userName, t2.repositoryName, t2.priorityId)
}
- .groupBy { case t1 ~ t2 =>
- t2.priorityName
+ .groupBy {
+ case t1 ~ t2 =>
+ t2.priorityName
}
- .map { case priorityName ~ t =>
- priorityName -> t.length
+ .map {
+ case priorityName ~ t =>
+ priorityName -> t.length
}
- .list.toMap
+ .list
+ .toMap
}
- def getCommitStatues(userName: String, repositoryName: String, issueId: Int)(implicit s: Session): Option[CommitStatusInfo] = {
+ def getCommitStatues(userName: String, repositoryName: String, issueId: Int)(
+ implicit s: Session
+ ): Option[CommitStatusInfo] = {
val status = PullRequests
.filter { pr =>
pr.userName === userName.bind && pr.repositoryName === repositoryName.bind && pr.issueId === issueId.bind
}
- .join(CommitStatuses).on { case pr ~ cs =>
- pr.userName === cs.userName && pr.repositoryName === cs.repositoryName && pr.commitIdTo === cs.commitId
+ .join(CommitStatuses)
+ .on {
+ case pr ~ cs =>
+ pr.userName === cs.userName && pr.repositoryName === cs.repositoryName && pr.commitIdTo === cs.commitId
}
.list
- if(status.nonEmpty){
+ if (status.nonEmpty) {
val (_, cs) = status.head
- Some(CommitStatusInfo(
- count = status.length,
- successCount = status.count(_._2.state == CommitState.SUCCESS),
- context = (if(status.length == 1) Some(cs.context) else None),
- state = (if(status.length == 1) Some(cs.state) else None),
- targetUrl = (if(status.length == 1) cs.targetUrl else None),
- description = (if(status.length == 1) cs.description else None)
- ))
+ Some(
+ CommitStatusInfo(
+ count = status.length,
+ successCount = status.count(_._2.state == CommitState.SUCCESS),
+ context = (if (status.length == 1) Some(cs.context) else None),
+ state = (if (status.length == 1) Some(cs.state) else None),
+ targetUrl = (if (status.length == 1) cs.targetUrl else None),
+ description = (if (status.length == 1) cs.description else None)
+ )
+ )
} else {
None
}
@@ -160,104 +211,154 @@
* @param repos Tuple of the repository owner and the repository name
* @return the search result (list of tuples which contain issue, labels and comment count)
*/
- def searchIssue(condition: IssueSearchCondition, pullRequest: Boolean, offset: Int, limit: Int, repos: (String, String)*)
- (implicit s: Session): List[IssueInfo] = {
+ def searchIssue(
+ condition: IssueSearchCondition,
+ pullRequest: Boolean,
+ offset: Int,
+ limit: Int,
+ repos: (String, String)*
+ )(implicit s: Session): List[IssueInfo] = {
// get issues and comment count and labels
val result = searchIssueQueryBase(condition, pullRequest, offset, limit, repos)
- .joinLeft (IssueLabels) .on { case t1 ~ t2 ~ i ~ t3 => t1.byIssue(t3.userName, t3.repositoryName, t3.issueId) }
- .joinLeft (Labels) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t3.map(_.byLabel(t4.userName, t4.repositoryName, t4.labelId)) }
- .joinLeft (Milestones) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t1.byMilestone(t5.userName, t5.repositoryName, t5.milestoneId) }
- .joinLeft (Priorities) .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => t1.byPriority(t6.userName, t6.repositoryName, t6.priorityId) }
- .sortBy { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => i asc }
- .map { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 =>
- (t1, t2.commentCount, t4.map(_.labelId), t4.map(_.labelName), t4.map(_.color), t5.map(_.title), t6.map(_.priorityName))
- }
- .list
- .splitWith { (c1, c2) => c1._1.userName == c2._1.userName && c1._1.repositoryName == c2._1.repositoryName && c1._1.issueId == c2._1.issueId }
+ .joinLeft(IssueLabels)
+ .on { case t1 ~ t2 ~ i ~ t3 => t1.byIssue(t3.userName, t3.repositoryName, t3.issueId) }
+ .joinLeft(Labels)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t3.map(_.byLabel(t4.userName, t4.repositoryName, t4.labelId)) }
+ .joinLeft(Milestones)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t1.byMilestone(t5.userName, t5.repositoryName, t5.milestoneId) }
+ .joinLeft(Priorities)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => t1.byPriority(t6.userName, t6.repositoryName, t6.priorityId) }
+ .sortBy { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => i asc }
+ .map {
+ case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 =>
+ (
+ t1,
+ t2.commentCount,
+ t4.map(_.labelId),
+ t4.map(_.labelName),
+ t4.map(_.color),
+ t5.map(_.title),
+ t6.map(_.priorityName)
+ )
+ }
+ .list
+ .splitWith { (c1, c2) =>
+ c1._1.userName == c2._1.userName && c1._1.repositoryName == c2._1.repositoryName && c1._1.issueId == c2._1.issueId
+ }
- result.map { issues => issues.head match {
- case (issue, commentCount, _, _, _, milestone, priority) =>
- IssueInfo(issue,
- issues.flatMap { t => t._3.map (Label(issue.userName, issue.repositoryName, _, t._4.get, t._5.get))} toList,
- milestone,
- priority,
- commentCount,
- getCommitStatues(issue.userName, issue.repositoryName, issue.issueId))
- }} toList
+ result.map { issues =>
+ issues.head match {
+ case (issue, commentCount, _, _, _, milestone, priority) =>
+ IssueInfo(
+ issue,
+ issues.flatMap { t =>
+ t._3.map(Label(issue.userName, issue.repositoryName, _, t._4.get, t._5.get))
+ } toList,
+ milestone,
+ priority,
+ commentCount,
+ getCommitStatues(issue.userName, issue.repositoryName, issue.issueId)
+ )
+ }
+ } toList
}
/** for api
* @return (issue, issueUser, commentCount)
*/
- def searchIssueByApi(condition: IssueSearchCondition, offset: Int, limit: Int, repos: (String, String)*)
- (implicit s: Session): List[(Issue, Account)] = {
+ def searchIssueByApi(condition: IssueSearchCondition, offset: Int, limit: Int, repos: (String, String)*)(
+ implicit s: Session
+ ): List[(Issue, Account)] = {
// get issues and comment count and labels
searchIssueQueryBase(condition, false, offset, limit, repos)
- .join(Accounts).on { case t1 ~ t2 ~ i ~ t3 => t3.userName === t1.openedUserName }
+ .join(Accounts)
+ .on { case t1 ~ t2 ~ i ~ t3 => t3.userName === t1.openedUserName }
.sortBy { case t1 ~ t2 ~ i ~ t3 => i asc }
- .map { case t1 ~ t2 ~ i ~ t3 => (t1, t3) }
+ .map { case t1 ~ t2 ~ i ~ t3 => (t1, t3) }
.list
}
/** for api
* @return (issue, issueUser, commentCount, pullRequest, headRepo, headOwner)
*/
- def searchPullRequestByApi(condition: IssueSearchCondition, offset: Int, limit: Int, repos: (String, String)*)
- (implicit s: Session): List[(Issue, Account, Int, PullRequest, Repository, Account, Option[Account])] = {
+ def searchPullRequestByApi(condition: IssueSearchCondition, offset: Int, limit: Int, repos: (String, String)*)(
+ implicit s: Session
+ ): List[(Issue, Account, Int, PullRequest, Repository, Account, Option[Account])] = {
// get issues and comment count and labels
searchIssueQueryBase(condition, true, offset, limit, repos)
- .join (PullRequests).on { case t1 ~ t2 ~ i ~ t3 => t3.byPrimaryKey(t1.userName, t1.repositoryName, t1.issueId) }
- .join (Repositories).on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t4.byRepository(t1.userName, t1.repositoryName) }
- .join (Accounts ).on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t5.userName === t1.openedUserName }
- .join (Accounts ).on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => t6.userName === t4.userName }
- .joinLeft(Accounts ).on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 ~ t7 => t7.userName === t1.assignedUserName}
+ .join(PullRequests)
+ .on { case t1 ~ t2 ~ i ~ t3 => t3.byPrimaryKey(t1.userName, t1.repositoryName, t1.issueId) }
+ .join(Repositories)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 => t4.byRepository(t1.userName, t1.repositoryName) }
+ .join(Accounts)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 => t5.userName === t1.openedUserName }
+ .join(Accounts)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 => t6.userName === t4.userName }
+ .joinLeft(Accounts)
+ .on { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 ~ t7 => t7.userName === t1.assignedUserName }
.sortBy { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 ~ t7 => i asc }
- .map { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 ~ t7 => (t1, t5, t2.commentCount, t3, t4, t6, t7) }
+ .map { case t1 ~ t2 ~ i ~ t3 ~ t4 ~ t5 ~ t6 ~ t7 => (t1, t5, t2.commentCount, t3, t4, t6, t7) }
.list
}
- private def searchIssueQueryBase(condition: IssueSearchCondition, pullRequest: Boolean, offset: Int, limit: Int, repos: Seq[(String, String)])
- (implicit s: Session) =
+ private def searchIssueQueryBase(
+ condition: IssueSearchCondition,
+ pullRequest: Boolean,
+ offset: Int,
+ limit: Int,
+ repos: Seq[(String, String)]
+ )(implicit s: Session) =
searchIssueQuery(repos, condition, pullRequest)
- .join(IssueOutline).on { (t1, t2) => t1.byIssue(t2.userName, t2.repositoryName, t2.issueId) }
- .sortBy { case (t1, t2) => t1.issueId desc }
- .sortBy { case (t1, t2) =>
- condition.sort match {
- case "created" => condition.direction match {
- case "asc" => t1.registeredDate asc
- case "desc" => t1.registeredDate desc
- }
- case "comments" => condition.direction match {
- case "asc" => t2.commentCount asc
- case "desc" => t2.commentCount desc
- }
- case "updated" => condition.direction match {
- case "asc" => t1.updatedDate asc
- case "desc" => t1.updatedDate desc
- }
- case "priority" => condition.direction match {
- case "asc" => t2.priority asc
- case "desc" => t2.priority desc
- }
- }
+ .join(IssueOutline)
+ .on { (t1, t2) =>
+ t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
}
- .drop(offset).take(limit).zipWithIndex
-
+ .sortBy { case (t1, t2) => t1.issueId desc }
+ .sortBy {
+ case (t1, t2) =>
+ condition.sort match {
+ case "created" =>
+ condition.direction match {
+ case "asc" => t1.registeredDate asc
+ case "desc" => t1.registeredDate desc
+ }
+ case "comments" =>
+ condition.direction match {
+ case "asc" => t2.commentCount asc
+ case "desc" => t2.commentCount desc
+ }
+ case "updated" =>
+ condition.direction match {
+ case "asc" => t1.updatedDate asc
+ case "desc" => t1.updatedDate desc
+ }
+ case "priority" =>
+ condition.direction match {
+ case "asc" => t2.priority asc
+ case "desc" => t2.priority desc
+ }
+ }
+ }
+ .drop(offset)
+ .take(limit)
+ .zipWithIndex
/**
* Assembles query for conditional issue searching.
*/
- private def searchIssueQuery(repos: Seq[(String, String)], condition: IssueSearchCondition, pullRequest: Boolean)(implicit s: Session) =
+ private def searchIssueQuery(repos: Seq[(String, String)], condition: IssueSearchCondition, pullRequest: Boolean)(
+ implicit s: Session
+ ) =
Issues filter { t1 =>
repos
.map { case (owner, repository) => t1.byRepository(owner, repository) }
- .foldLeft[Rep[Boolean]](false) ( _ || _ ) &&
- (t1.closed === (condition.state == "closed").bind) &&
- (t1.milestoneId.? isEmpty, condition.milestone == Some(None)) &&
- (t1.priorityId.? isEmpty, condition.priority == Some(None)) &&
- (t1.assignedUserName.? isEmpty, condition.assigned == Some(None)) &&
- (t1.openedUserName === condition.author.get.bind, condition.author.isDefined) &&
- (t1.pullRequest === pullRequest.bind) &&
+ .foldLeft[Rep[Boolean]](false)(_ || _) &&
+ (t1.closed === (condition.state == "closed").bind) &&
+ (t1.milestoneId.? isEmpty, condition.milestone == Some(None)) &&
+ (t1.priorityId.? isEmpty, condition.priority == Some(None)) &&
+ (t1.assignedUserName.? isEmpty, condition.assigned == Some(None)) &&
+ (t1.openedUserName === condition.author.get.bind, condition.author.isDefined) &&
+ (t1.pullRequest === pullRequest.bind) &&
// Milestone filter
(Milestones filter { t2 =>
(t2.byPrimaryKey(t1.userName, t1.repositoryName, t1.milestoneId)) &&
@@ -266,7 +367,7 @@
// Priority filter
(Priorities filter { t2 =>
(t2.byPrimaryKey(t1.userName, t1.repositoryName, t1.priorityId)) &&
- (t2.priorityName === condition.priority.get.get.bind)
+ (t2.priorityName === condition.priority.get.get.bind)
} exists, condition.priority.flatten.isDefined) &&
// Assignee filter
(t1.assignedUserName === condition.assigned.get.get.bind, condition.assigned.flatten.isDefined) &&
@@ -277,7 +378,7 @@
(Labels filter { t3 =>
(t3.byRepository(t1.userName, t1.repositoryName)) &&
(t3.labelName inSetBind condition.labels)
- } map(_.labelId)))
+ } map (_.labelId)))
} exists, condition.labels.nonEmpty) &&
// Visibility filter
(Repositories filter { t2 =>
@@ -288,41 +389,55 @@
(t1.userName inSetBind condition.groups, condition.groups.nonEmpty) &&
// Mentioned filter
((t1.openedUserName === condition.mentioned.get.bind) || t1.assignedUserName === condition.mentioned.get.bind ||
- (IssueComments filter { t2 =>
- (t2.byIssue(t1.userName, t1.repositoryName, t1.issueId)) && (t2.commentedUserName === condition.mentioned.get.bind)
- } exists), condition.mentioned.isDefined)
+ (IssueComments filter { t2 =>
+ (t2.byIssue(t1.userName, t1.repositoryName, t1.issueId)) && (t2.commentedUserName === condition.mentioned.get.bind)
+ } exists), condition.mentioned.isDefined)
}
- def insertIssue(owner: String, repository: String, loginUser: String, title: String, content: Option[String],
- assignedUserName: Option[String], milestoneId: Option[Int], priorityId: Option[Int],
- isPullRequest: Boolean = false)(implicit s: Session): Int = {
+ def insertIssue(
+ owner: String,
+ repository: String,
+ loginUser: String,
+ title: String,
+ content: Option[String],
+ assignedUserName: Option[String],
+ milestoneId: Option[Int],
+ priorityId: Option[Int],
+ isPullRequest: Boolean = false
+ )(implicit s: Session): Int = {
// next id number
- sql"SELECT ISSUE_ID + 1 FROM ISSUE_ID WHERE USER_NAME = $owner AND REPOSITORY_NAME = $repository FOR UPDATE".as[Int]
- .firstOption.filter { id =>
- Issues insert Issue(
- owner,
- repository,
- id,
- loginUser,
- milestoneId,
- priorityId,
- assignedUserName,
- title,
- content,
- false,
- currentDate,
- currentDate,
- isPullRequest)
+ sql"SELECT ISSUE_ID + 1 FROM ISSUE_ID WHERE USER_NAME = $owner AND REPOSITORY_NAME = $repository FOR UPDATE"
+ .as[Int]
+ .firstOption
+ .filter { id =>
+ Issues insert Issue(
+ owner,
+ repository,
+ id,
+ loginUser,
+ milestoneId,
+ priorityId,
+ assignedUserName,
+ title,
+ content,
+ false,
+ currentDate,
+ currentDate,
+ isPullRequest
+ )
- // increment issue id
- IssueId
- .filter(_.byPrimaryKey(owner, repository))
- .map(_.issueId)
- .update(id) > 0
+ // increment issue id
+ IssueId
+ .filter(_.byPrimaryKey(owner, repository))
+ .map(_.issueId)
+ .update(id) > 0
} get
}
- def registerIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(implicit context: Context, s: Session): Int = {
+ def registerIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(
+ implicit context: Context,
+ s: Session
+ ): Int = {
if (insertComment) {
IssueComments insert IssueComment(
userName = owner,
@@ -338,7 +453,10 @@
IssueLabels insert IssueLabel(owner, repository, issueId, labelId)
}
- def deleteIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(implicit context: Context, s: Session): Int = {
+ def deleteIssueLabel(owner: String, repository: String, issueId: Int, labelId: Int, insertComment: Boolean = false)(
+ implicit context: Context,
+ s: Session
+ ): Int = {
if (insertComment) {
IssueComments insert IssueComment(
userName = owner,
@@ -351,31 +469,48 @@
updatedDate = currentDate
)
}
- IssueLabels filter(_.byPrimaryKey(owner, repository, issueId, labelId)) delete
+ IssueLabels filter (_.byPrimaryKey(owner, repository, issueId, labelId)) delete
}
- def createComment(owner: String, repository: String, loginUser: String,
- issueId: Int, content: String, action: String)(implicit s: Session): Int = {
+ def createComment(
+ owner: String,
+ repository: String,
+ loginUser: String,
+ issueId: Int,
+ content: String,
+ action: String
+ )(implicit s: Session): Int = {
Issues.filter(_.issueId === issueId.bind).map(_.updatedDate).update(currentDate)
IssueComments returning IssueComments.map(_.commentId) insert IssueComment(
- userName = owner,
- repositoryName = repository,
- issueId = issueId,
- action = action,
+ userName = owner,
+ repositoryName = repository,
+ issueId = issueId,
+ action = action,
commentedUserName = loginUser,
- content = content,
- registeredDate = currentDate,
- updatedDate = currentDate)
+ content = content,
+ registeredDate = currentDate,
+ updatedDate = currentDate
+ )
}
- def updateIssue(owner: String, repository: String, issueId: Int, title: String, content: Option[String])(implicit s: Session): Int = {
+ def updateIssue(owner: String, repository: String, issueId: Int, title: String, content: Option[String])(
+ implicit s: Session
+ ): Int = {
Issues
- .filter (_.byPrimaryKey(owner, repository, issueId))
- .map { t => (t.title, t.content.?, t.updatedDate) }
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map { t =>
+ (t.title, t.content.?, t.updatedDate)
+ }
.update(title, content, currentDate)
}
- def updateAssignedUserName(owner: String, repository: String, issueId: Int, assignedUserName: Option[String], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = {
+ def updateAssignedUserName(
+ owner: String,
+ repository: String,
+ issueId: Int,
+ assignedUserName: Option[String],
+ insertComment: Boolean = false
+ )(implicit context: Context, s: Session): Int = {
if (insertComment) {
val oldAssigned = getIssue(owner, repository, s"${issueId}").get.assignedUserName.getOrElse("Not assigned")
val assigned = assignedUserName.getOrElse("Not assigned")
@@ -390,13 +525,26 @@
updatedDate = currentDate
)
}
- Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.assignedUserName?, t.updatedDate)).update(assignedUserName, currentDate)
+ Issues
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map(t => (t.assignedUserName ?, t.updatedDate))
+ .update(assignedUserName, currentDate)
}
- def updateMilestoneId(owner: String, repository: String, issueId: Int, milestoneId: Option[Int], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = {
+ def updateMilestoneId(
+ owner: String,
+ repository: String,
+ issueId: Int,
+ milestoneId: Option[Int],
+ insertComment: Boolean = false
+ )(implicit context: Context, s: Session): Int = {
if (insertComment) {
- val oldMilestoneName = getIssue(owner, repository, s"${issueId}").get.milestoneId.map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone")).getOrElse("No milestone")
- val milestoneName = milestoneId.map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone")).getOrElse("No milestone")
+ val oldMilestoneName = getIssue(owner, repository, s"${issueId}").get.milestoneId
+ .map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone"))
+ .getOrElse("No milestone")
+ val milestoneName = milestoneId
+ .map(getMilestone(owner, repository, _).map(_.title).getOrElse("Unknown milestone"))
+ .getOrElse("No milestone")
IssueComments insert IssueComment(
userName = owner,
repositoryName = repository,
@@ -408,13 +556,26 @@
updatedDate = currentDate
)
}
- Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.milestoneId?, t.updatedDate)).update(milestoneId, currentDate)
+ Issues
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map(t => (t.milestoneId ?, t.updatedDate))
+ .update(milestoneId, currentDate)
}
- def updatePriorityId(owner: String, repository: String, issueId: Int, priorityId: Option[Int], insertComment: Boolean = false)(implicit context: Context, s: Session): Int = {
+ def updatePriorityId(
+ owner: String,
+ repository: String,
+ issueId: Int,
+ priorityId: Option[Int],
+ insertComment: Boolean = false
+ )(implicit context: Context, s: Session): Int = {
if (insertComment) {
- val oldPriorityName = getIssue(owner, repository, s"${issueId}").get.priorityId.map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority")).getOrElse("No priority")
- val priorityName = priorityId.map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority")).getOrElse("No priority")
+ val oldPriorityName = getIssue(owner, repository, s"${issueId}").get.priorityId
+ .map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority"))
+ .getOrElse("No priority")
+ val priorityName = priorityId
+ .map(getPriority(owner, repository, _).map(_.priorityName).getOrElse("Unknown priority"))
+ .getOrElse("No priority")
IssueComments insert IssueComment(
userName = owner,
repositoryName = repository,
@@ -426,7 +587,10 @@
updatedDate = currentDate
)
}
- Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.priorityId?, t.updatedDate)).update(priorityId, currentDate)
+ Issues
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map(t => (t.priorityId ?, t.updatedDate))
+ .update(priorityId, currentDate)
}
def updateComment(issueId: Int, commentId: Int, content: String)(implicit s: Session): Int = {
@@ -447,7 +611,10 @@
}
def updateClosed(owner: String, repository: String, issueId: Int, closed: Boolean)(implicit s: Session): Int = {
- Issues.filter(_.byPrimaryKey(owner, repository, issueId)).map(t => (t.closed, t.updatedDate)).update(closed, currentDate)
+ Issues
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map(t => (t.closed, t.updatedDate))
+ .update(closed, currentDate)
}
/**
@@ -458,69 +625,100 @@
* @param query the keywords separated by whitespace.
* @return issues with comment count and matched content of issue or comment
*/
- def searchIssuesByKeyword(owner: String, repository: String, query: String)(implicit s: Session): List[(Issue, Int, String)] = {
+ def searchIssuesByKeyword(owner: String, repository: String, query: String)(
+ implicit s: Session
+ ): List[(Issue, Int, String)] = {
//import slick.driver.JdbcDriver.likeEncode
val keywords = splitWords(query.toLowerCase)
// Search Issue
val issues = Issues
.filter(_.byRepository(owner, repository))
- .join(IssueOutline).on { case (t1, t2) =>
- t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
+ .join(IssueOutline)
+ .on {
+ case (t1, t2) =>
+ t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
}
- .filter { case (t1, t2) =>
- keywords.map { keyword =>
- (t1.title.toLowerCase like (s"%${likeEncode(keyword)}%", '^')) ||
- (t1.content.toLowerCase like (s"%${likeEncode(keyword)}%", '^'))
- } .reduceLeft(_ && _)
+ .filter {
+ case (t1, t2) =>
+ keywords
+ .map { keyword =>
+ (t1.title.toLowerCase like (s"%${likeEncode(keyword)}%", '^')) ||
+ (t1.content.toLowerCase like (s"%${likeEncode(keyword)}%", '^'))
+ }
+ .reduceLeft(_ && _)
}
- .map { case (t1, t2) =>
- (t1, 0, t1.content.?, t2.commentCount)
+ .map {
+ case (t1, t2) =>
+ (t1, 0, t1.content.?, t2.commentCount)
}
// Search IssueComment
val comments = IssueComments
.filter(_.byRepository(owner, repository))
- .join(Issues).on { case (t1, t2) =>
- t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
+ .join(Issues)
+ .on {
+ case (t1, t2) =>
+ t1.byIssue(t2.userName, t2.repositoryName, t2.issueId)
}
- .join(IssueOutline).on { case ((t1, t2), t3) =>
- t2.byIssue(t3.userName, t3.repositoryName, t3.issueId)
+ .join(IssueOutline)
+ .on {
+ case ((t1, t2), t3) =>
+ t2.byIssue(t3.userName, t3.repositoryName, t3.issueId)
}
- .filter { case ((t1, t2), t3) =>
- keywords.map { query =>
- t1.content.toLowerCase like (s"%${likeEncode(query)}%", '^')
- }.reduceLeft(_ && _)
+ .filter {
+ case ((t1, t2), t3) =>
+ keywords
+ .map { query =>
+ t1.content.toLowerCase like (s"%${likeEncode(query)}%", '^')
+ }
+ .reduceLeft(_ && _)
}
- .map { case ((t1, t2), t3) =>
- (t2, t1.commentId, t1.content.?, t3.commentCount)
+ .map {
+ case ((t1, t2), t3) =>
+ (t2, t1.commentId, t1.content.?, t3.commentCount)
}
- issues.union(comments).sortBy { case (issue, commentId, _, _) =>
- issue.issueId -> commentId
- }.list.splitWith { case ((issue1, _, _, _), (issue2, _, _, _)) =>
- issue1.issueId == issue2.issueId
- }.map { _.head match {
- case (issue, _, content, commentCount) => (issue, commentCount, content.getOrElse(""))
+ issues
+ .union(comments)
+ .sortBy {
+ case (issue, commentId, _, _) =>
+ issue.issueId -> commentId
}
- }.toList
+ .list
+ .splitWith {
+ case ((issue1, _, _, _), (issue2, _, _, _)) =>
+ issue1.issueId == issue2.issueId
+ }
+ .map {
+ _.head match {
+ case (issue, _, content, commentCount) => (issue, commentCount, content.getOrElse(""))
+ }
+ }
+ .toList
}
- def closeIssuesFromMessage(message: String, userName: String, owner: String, repository: String)(implicit s: Session): Unit = {
+ def closeIssuesFromMessage(message: String, userName: String, owner: String, repository: String)(
+ implicit s: Session
+ ): Unit = {
extractCloseId(message).foreach { issueId =>
- for(issue <- getIssue(owner, repository, issueId) if !issue.closed){
+ for (issue <- getIssue(owner, repository, issueId) if !issue.closed) {
createComment(owner, repository, userName, issue.issueId, "Close", "close")
updateClosed(owner, repository, issue.issueId, true)
}
}
}
- def createReferComment(owner: String, repository: String, fromIssue: Issue, message: String, loginAccount: Account)(implicit s: Session): Unit = {
+ def createReferComment(owner: String, repository: String, fromIssue: Issue, message: String, loginAccount: Account)(
+ implicit s: Session
+ ): Unit = {
extractIssueId(message).foreach { issueId =>
val content = fromIssue.issueId + ":" + fromIssue.title
- if(getIssue(owner, repository, issueId).isDefined){
+ if (getIssue(owner, repository, issueId).isDefined) {
// Not add if refer comment already exist.
- if(!getComments(owner, repository, issueId.toInt).exists { x => x.action == "refer" && x.content == content }) {
+ if (!getComments(owner, repository, issueId.toInt).exists { x =>
+ x.action == "refer" && x.content == content
+ }) {
createComment(owner, repository, loginAccount.userName, issueId.toInt, content, "refer")
}
}
@@ -529,8 +727,9 @@
def createIssueComment(owner: String, repository: String, commit: CommitInfo)(implicit s: Session): Unit = {
extractIssueId(commit.fullMessage).foreach { issueId =>
- if(getIssue(owner, repository, issueId).isDefined){
- val userName = getAccountByMailAddress(commit.committerEmailAddress).map(_.userName).getOrElse(commit.committerName)
+ if (getIssue(owner, repository, issueId).isDefined) {
+ val userName =
+ getAccountByMailAddress(commit.committerEmailAddress).map(_.userName).getOrElse(commit.committerName)
createComment(owner, repository, userName, issueId.toInt, commit.fullMessage + " " + commit.id, "commit")
}
}
@@ -539,13 +738,13 @@
def getAssignableUserNames(owner: String, repository: String)(implicit s: Session): List[String] = {
(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER)) :::
(getAccountByUserName(owner) match {
- case Some(x) if x.isGroupAccount =>
- getGroupMembers(owner).map(_.userName)
- case Some(_) =>
- List(owner)
- case None =>
- Nil
- })).distinct.sorted
+ case Some(x) if x.isGroupAccount =>
+ getGroupMembers(owner).map(_.userName)
+ case Some(_) =>
+ List(owner)
+ case None =>
+ Nil
+ })).distinct.sorted
}
}
@@ -556,61 +755,63 @@
val IssueLimit = 25
case class IssueSearchCondition(
- labels: Set[String] = Set.empty,
- milestone: Option[Option[String]] = None,
- priority: Option[Option[String]] = None,
- author: Option[String] = None,
- assigned: Option[Option[String]] = None,
- mentioned: Option[String] = None,
- state: String = "open",
- sort: String = "created",
- direction: String = "desc",
- visibility: Option[String] = None,
- groups: Set[String] = Set.empty){
+ labels: Set[String] = Set.empty,
+ milestone: Option[Option[String]] = None,
+ priority: Option[Option[String]] = None,
+ author: Option[String] = None,
+ assigned: Option[Option[String]] = None,
+ mentioned: Option[String] = None,
+ state: String = "open",
+ sort: String = "created",
+ direction: String = "desc",
+ visibility: Option[String] = None,
+ groups: Set[String] = Set.empty
+ ) {
def isEmpty: Boolean = {
labels.isEmpty && milestone.isEmpty && author.isEmpty && assigned.isEmpty &&
- state == "open" && sort == "created" && direction == "desc" && visibility.isEmpty
+ state == "open" && sort == "created" && direction == "desc" && visibility.isEmpty
}
def nonEmpty: Boolean = !isEmpty
- def toFilterString: String = (
- List(
- Some(s"is:${state}"),
- author.map(author => s"author:${author}"),
- assigned.map(assignee => s"assignee:${assignee}"),
- mentioned.map(mentioned => s"mentions:${mentioned}")
- ).flatten ++
- labels.map(label => s"label:${label}") ++
- List(
- milestone.map {
- case Some(x) => s"milestone:${x}"
- case None => "no:milestone"
- },
- priority.map {
- case Some(x) => s"priority:${x}"
- case None => "no:priority"
- },
- (sort, direction) match {
- case ("created" , "desc") => None
- case ("created" , "asc" ) => Some("sort:created-asc")
- case ("comments", "desc") => Some("sort:comments-desc")
- case ("comments", "asc" ) => Some("sort:comments-asc")
- case ("updated" , "desc") => Some("sort:updated-desc")
- case ("updated" , "asc" ) => Some("sort:updated-asc")
- case ("priority", "desc") => Some("sort:priority-desc")
- case ("priority", "asc" ) => Some("sort:priority-asc")
- case x => throw new MatchError(x)
- },
- visibility.map(visibility => s"visibility:${visibility}")
- ).flatten ++
- groups.map(group => s"group:${group}")
- ).mkString(" ")
+ def toFilterString: String =
+ (
+ List(
+ Some(s"is:${state}"),
+ author.map(author => s"author:${author}"),
+ assigned.map(assignee => s"assignee:${assignee}"),
+ mentioned.map(mentioned => s"mentions:${mentioned}")
+ ).flatten ++
+ labels.map(label => s"label:${label}") ++
+ List(
+ milestone.map {
+ case Some(x) => s"milestone:${x}"
+ case None => "no:milestone"
+ },
+ priority.map {
+ case Some(x) => s"priority:${x}"
+ case None => "no:priority"
+ },
+ (sort, direction) match {
+ case ("created", "desc") => None
+ case ("created", "asc") => Some("sort:created-asc")
+ case ("comments", "desc") => Some("sort:comments-desc")
+ case ("comments", "asc") => Some("sort:comments-asc")
+ case ("updated", "desc") => Some("sort:updated-desc")
+ case ("updated", "asc") => Some("sort:updated-asc")
+ case ("priority", "desc") => Some("sort:priority-desc")
+ case ("priority", "asc") => Some("sort:priority-asc")
+ case x => throw new MatchError(x)
+ },
+ visibility.map(visibility => s"visibility:${visibility}")
+ ).flatten ++
+ groups.map(group => s"group:${group}")
+ ).mkString(" ")
def toURL: String =
"?" + List(
- if(labels.isEmpty) None else Some("labels=" + urlEncode(labels.mkString(","))),
+ if (labels.isEmpty) None else Some("labels=" + urlEncode(labels.mkString(","))),
milestone.map {
case Some(x) => "milestone=" + urlEncode(x)
case None => "milestone=none"
@@ -619,17 +820,17 @@
case Some(x) => "priority=" + urlEncode(x)
case None => "priority=none"
},
- author .map(x => "author=" + urlEncode(x)),
+ author.map(x => "author=" + urlEncode(x)),
assigned.map {
- case Some(x) => "assigned=" + urlEncode(x)
+ case Some(x) => "assigned=" + urlEncode(x)
case None => "assigned=none"
},
mentioned.map(x => "mentioned=" + urlEncode(x)),
- Some("state=" + urlEncode(state)),
- Some("sort=" + urlEncode(sort)),
+ Some("state=" + urlEncode(state)),
+ Some("sort=" + urlEncode(sort)),
Some("direction=" + urlEncode(direction)),
visibility.map(x => "visibility=" + urlEncode(x)),
- if(groups.isEmpty) None else Some("groups=" + urlEncode(groups.mkString(",")))
+ if (groups.isEmpty) None else Some("groups=" + urlEncode(groups.mkString(",")))
).flatten.mkString("&")
}
@@ -638,7 +839,7 @@
private def param(request: HttpServletRequest, name: String, allow: Seq[String] = Nil): Option[String] = {
val value = request.getParameter(name)
- if(value == null || value.isEmpty || (allow.nonEmpty && !allow.contains(value))) None else Some(value)
+ if (value == null || value.isEmpty || (allow.nonEmpty && !allow.contains(value))) None else Some(value)
}
/**
@@ -661,23 +862,38 @@
case x => Some(x)
},
param(request, "mentioned"),
- param(request, "state", Seq("open", "closed")).getOrElse("open"),
- param(request, "sort", Seq("created", "comments", "updated", "priority")).getOrElse("created"),
+ param(request, "state", Seq("open", "closed")).getOrElse("open"),
+ param(request, "sort", Seq("created", "comments", "updated", "priority")).getOrElse("created"),
param(request, "direction", Seq("asc", "desc")).getOrElse("desc"),
param(request, "visibility"),
param(request, "groups").map(_.split(",").toSet).getOrElse(Set.empty)
)
- def page(request: HttpServletRequest) = try {
- val i = param(request, "page").getOrElse("1").toInt
- if(i <= 0) 1 else i
- } catch {
- case e: NumberFormatException => 1
- }
+ def page(request: HttpServletRequest) =
+ try {
+ val i = param(request, "page").getOrElse("1").toInt
+ if (i <= 0) 1 else i
+ } catch {
+ case e: NumberFormatException => 1
+ }
}
- case class CommitStatusInfo(count: Int, successCount: Int, context: Option[String], state: Option[CommitState], targetUrl: Option[String], description: Option[String])
+ case class CommitStatusInfo(
+ count: Int,
+ successCount: Int,
+ context: Option[String],
+ state: Option[CommitState],
+ targetUrl: Option[String],
+ description: Option[String]
+ )
- case class IssueInfo(issue: Issue, labels: List[Label], milestone: Option[String], priority: Option[String], commentCount: Int, status:Option[CommitStatusInfo])
+ case class IssueInfo(
+ issue: Issue,
+ labels: List[Label],
+ milestone: Option[String],
+ priority: Option[String],
+ commentCount: Int,
+ status: Option[CommitStatusInfo]
+ )
}
diff --git a/src/main/scala/gitbucket/core/service/LabelsService.scala b/src/main/scala/gitbucket/core/service/LabelsService.scala
index e95fa06..4bbd5d8 100644
--- a/src/main/scala/gitbucket/core/service/LabelsService.scala
+++ b/src/main/scala/gitbucket/core/service/LabelsService.scala
@@ -17,18 +17,20 @@
def createLabel(owner: String, repository: String, labelName: String, color: String)(implicit s: Session): Int = {
Labels returning Labels.map(_.labelId) insert Label(
- userName = owner,
+ userName = owner,
repositoryName = repository,
- labelName = labelName,
- color = color
+ labelName = labelName,
+ color = color
)
}
- def updateLabel(owner: String, repository: String, labelId: Int, labelName: String, color: String)
- (implicit s: Session): Unit =
- Labels.filter(_.byPrimaryKey(owner, repository, labelId))
- .map(t => t.labelName -> t.color)
- .update(labelName, color)
+ def updateLabel(owner: String, repository: String, labelId: Int, labelName: String, color: String)(
+ implicit s: Session
+ ): Unit =
+ Labels
+ .filter(_.byPrimaryKey(owner, repository, labelId))
+ .map(t => t.labelName -> t.color)
+ .update(labelName, color)
def deleteLabel(owner: String, repository: String, labelId: Int)(implicit s: Session): Unit = {
IssueLabels.filter(_.byLabel(owner, repository, labelId)).delete
diff --git a/src/main/scala/gitbucket/core/service/MergeService.scala b/src/main/scala/gitbucket/core/service/MergeService.scala
index ed2b4b4..0ea90f7 100644
--- a/src/main/scala/gitbucket/core/service/MergeService.scala
+++ b/src/main/scala/gitbucket/core/service/MergeService.scala
@@ -31,7 +31,12 @@
* Returns Some(true) if conflict will be caused.
* Returns None if cache has not created yet.
*/
- def checkConflictCache(userName: String, repositoryName: String, branch: String, issueId: Int): Option[Option[String]] = {
+ def checkConflictCache(
+ userName: String,
+ repositoryName: String,
+ branch: String,
+ issueId: Int
+ ): Option[Option[String]] = {
using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
new MergeCacheInfo(git, branch, issueId).checkConflictCache()
}
@@ -43,7 +48,13 @@
}
/** rebase to the head of the pull request branch */
- def rebasePullRequest(git: Git, branch: String, issueId: Int, commits: Seq[RevCommit], committer: PersonIdent): Unit = {
+ def rebasePullRequest(
+ git: Git,
+ branch: String,
+ issueId: Int,
+ commits: Seq[RevCommit],
+ committer: PersonIdent
+ ): Unit = {
new MergeCacheInfo(git, branch, issueId).rebase(committer, commits)
}
@@ -53,8 +64,15 @@
}
/** fetch remote branch to my repository refs/pull/{issueId}/head */
- def fetchAsPullRequest(userName: String, repositoryName: String, requestUserName: String, requestRepositoryName: String, requestBranch:String, issueId:Int){
- using(Git.open(getRepositoryDir(userName, repositoryName))){ git =>
+ def fetchAsPullRequest(
+ userName: String,
+ repositoryName: String,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestBranch: String,
+ issueId: Int
+ ) {
+ using(Git.open(getRepositoryDir(userName, repositoryName))) { git =>
git.fetch
.setRemote(getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString)
.setRefSpecs(new RefSpec(s"refs/heads/${requestBranch}:refs/pull/${issueId}/head"))
@@ -65,8 +83,14 @@
/**
* Checks whether conflict will be caused in merging. Returns true if conflict will be caused.
*/
- def tryMergeRemote(localUserName: String, localRepositoryName: String, localBranch: String,
- remoteUserName: String, remoteRepositoryName: String, remoteBranch: String): Either[String, (ObjectId, ObjectId, ObjectId)] = {
+ def tryMergeRemote(
+ localUserName: String,
+ localRepositoryName: String,
+ localBranch: String,
+ remoteUserName: String,
+ remoteRepositoryName: String,
+ remoteBranch: String
+ ): Either[String, (ObjectId, ObjectId, ObjectId)] = {
using(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
val remoteRefName = s"refs/heads/${remoteBranch}"
val tmpRefName = s"refs/remote-temp/${remoteUserName}/${remoteRepositoryName}/${remoteBranch}"
@@ -74,15 +98,15 @@
try {
// fetch objects from origin repository branch
git.fetch
- .setRemote(getRepositoryDir(remoteUserName, remoteRepositoryName).toURI.toString)
- .setRefSpecs(refSpec)
- .call
+ .setRemote(getRepositoryDir(remoteUserName, remoteRepositoryName).toURI.toString)
+ .setRefSpecs(refSpec)
+ .call
// merge conflict check
val merger = MergeStrategy.RECURSIVE.newMerger(git.getRepository, true)
val mergeBaseTip = git.getRepository.resolve(s"refs/heads/${localBranch}")
val mergeTip = git.getRepository.resolve(tmpRefName)
try {
- if(merger.merge(mergeBaseTip, mergeTip)){
+ if (merger.merge(mergeBaseTip, mergeTip)) {
Right((merger.getResultTreeId, mergeBaseTip, mergeTip))
} else {
Left(createConflictMessage(mergeTip, mergeBaseTip, merger))
@@ -101,45 +125,73 @@
/**
* Checks whether conflict will be caused in merging. Returns `Some(errorMessage)` if conflict will be caused.
*/
- def checkConflict(userName: String, repositoryName: String, branch: String,
- requestUserName: String, requestRepositoryName: String, requestBranch: String): Option[String] =
+ def checkConflict(
+ userName: String,
+ repositoryName: String,
+ branch: String,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestBranch: String
+ ): Option[String] =
tryMergeRemote(userName, repositoryName, branch, requestUserName, requestRepositoryName, requestBranch).left.toOption
- def pullRemote(localUserName: String, localRepositoryName: String, localBranch: String,
- remoteUserName: String, remoteRepositoryName: String, remoteBranch: String,
- loginAccount: Account, message: String): Option[ObjectId] = {
- tryMergeRemote(localUserName, localRepositoryName, localBranch, remoteUserName, remoteRepositoryName, remoteBranch).map { case (newTreeId, oldBaseId, oldHeadId) =>
- using(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
- val committer = new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
- val newCommit = Util.createMergeCommit(git.getRepository, newTreeId, committer, message, Seq(oldBaseId, oldHeadId))
- Util.updateRefs(git.getRepository, s"refs/heads/${localBranch}", newCommit, false, committer, Some("merge"))
- }
- oldBaseId
+ def pullRemote(
+ localUserName: String,
+ localRepositoryName: String,
+ localBranch: String,
+ remoteUserName: String,
+ remoteRepositoryName: String,
+ remoteBranch: String,
+ loginAccount: Account,
+ message: String
+ ): Option[ObjectId] = {
+ tryMergeRemote(localUserName, localRepositoryName, localBranch, remoteUserName, remoteRepositoryName, remoteBranch).map {
+ case (newTreeId, oldBaseId, oldHeadId) =>
+ using(Git.open(getRepositoryDir(localUserName, localRepositoryName))) { git =>
+ val committer = new PersonIdent(loginAccount.fullName, loginAccount.mailAddress)
+ val newCommit =
+ Util.createMergeCommit(git.getRepository, newTreeId, committer, message, Seq(oldBaseId, oldHeadId))
+ Util.updateRefs(git.getRepository, s"refs/heads/${localBranch}", newCommit, false, committer, Some("merge"))
+ }
+ oldBaseId
}.toOption
}
}
-object MergeService{
+object MergeService {
- object Util{
+ object Util {
// return merge commit id
- def createMergeCommit(repository: Repository, treeId: ObjectId, committer: PersonIdent, message: String, parents: Seq[ObjectId]): ObjectId = {
+ def createMergeCommit(
+ repository: Repository,
+ treeId: ObjectId,
+ committer: PersonIdent,
+ message: String,
+ parents: Seq[ObjectId]
+ ): ObjectId = {
val mergeCommit = new CommitBuilder()
mergeCommit.setTreeId(treeId)
- mergeCommit.setParentIds(parents:_*)
+ mergeCommit.setParentIds(parents: _*)
mergeCommit.setAuthor(committer)
mergeCommit.setCommitter(committer)
mergeCommit.setMessage(message)
// insertObject and got mergeCommit Object Id
- using(repository.newObjectInserter){ inserter =>
+ using(repository.newObjectInserter) { inserter =>
val mergeCommitId = inserter.insert(mergeCommit)
inserter.flush()
mergeCommitId
}
}
- def updateRefs(repository: Repository, ref: String, newObjectId: ObjectId, force: Boolean, committer: PersonIdent, refLogMessage: Option[String] = None): Unit = {
+ def updateRefs(
+ repository: Repository,
+ ref: String,
+ newObjectId: ObjectId,
+ force: Boolean,
+ committer: PersonIdent,
+ refLogMessage: Option[String] = None
+ ): Unit = {
val refUpdate = repository.updateRef(ref)
refUpdate.setNewObjectId(newObjectId)
refUpdate.setForceUpdate(force)
@@ -149,56 +201,58 @@
}
}
- class MergeCacheInfo(git: Git, branch: String, issueId: Int){
+ class MergeCacheInfo(git: Git, branch: String, issueId: Int) {
private val repository = git.getRepository
- private val mergedBranchName = s"refs/pull/${issueId}/merge"
+ private val mergedBranchName = s"refs/pull/${issueId}/merge"
private val conflictedBranchName = s"refs/pull/${issueId}/conflict"
lazy val mergeBaseTip = repository.resolve(s"refs/heads/${branch}")
- lazy val mergeTip = repository.resolve(s"refs/pull/${issueId}/head")
+ lazy val mergeTip = repository.resolve(s"refs/pull/${issueId}/head")
def checkConflictCache(): Option[Option[String]] = {
- Option(repository.resolve(mergedBranchName)).flatMap { merged =>
- if(parseCommit(merged).getParents().toSet == Set( mergeBaseTip, mergeTip )){
+ Option(repository.resolve(mergedBranchName))
+ .flatMap { merged =>
+ if (parseCommit(merged).getParents().toSet == Set(mergeBaseTip, mergeTip)) {
// merged branch exists
Some(None)
} else {
None
}
- }.orElse(Option(repository.resolve(conflictedBranchName)).flatMap{ conflicted =>
- val commit = parseCommit(conflicted)
- if(commit.getParents().toSet == Set( mergeBaseTip, mergeTip )){
- // conflict branch exists
- Some(Some(commit.getFullMessage))
- } else {
- None
}
- })
+ .orElse(Option(repository.resolve(conflictedBranchName)).flatMap { conflicted =>
+ val commit = parseCommit(conflicted)
+ if (commit.getParents().toSet == Set(mergeBaseTip, mergeTip)) {
+ // conflict branch exists
+ Some(Some(commit.getFullMessage))
+ } else {
+ None
+ }
+ })
}
- def checkConflict(): Option[String] ={
+ def checkConflict(): Option[String] = {
checkConflictCache.getOrElse(checkConflictForce)
}
- def checkConflictForce(): Option[String] ={
+ def checkConflictForce(): Option[String] = {
val merger = MergeStrategy.RECURSIVE.newMerger(repository, true)
val conflicted = try {
!merger.merge(mergeBaseTip, mergeTip)
} catch {
case e: NoMergeBaseException => true
}
- val mergeTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeTip ))
+ val mergeTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeTip))
val committer = mergeTipCommit.getCommitterIdent
- def _updateBranch(treeId: ObjectId, message: String, branchName: String){
+ def _updateBranch(treeId: ObjectId, message: String, branchName: String) {
// creates merge commit
val mergeCommitId = createMergeCommit(treeId, committer, message)
Util.updateRefs(repository, branchName, mergeCommitId, true, committer)
}
- if(!conflicted){
+ if (!conflicted) {
_updateBranch(merger.getResultTreeId, s"Merge ${mergeTip.name} into ${mergeBaseTip.name}", mergedBranchName)
git.branchDelete().setForce(true).setBranchNames(conflictedBranchName).call()
None
@@ -212,7 +266,7 @@
// update branch from cache
def merge(message: String, committer: PersonIdent) = {
- if(checkConflict().isDefined){
+ if (checkConflict().isDefined) {
throw new RuntimeException("This pull request can't merge automatically.")
}
val mergeResultCommit = parseCommit(Option(repository.resolve(mergedBranchName)).getOrElse {
@@ -225,7 +279,7 @@
}
def rebase(committer: PersonIdent, commits: Seq[RevCommit]): Unit = {
- if(checkConflict().isDefined){
+ if (checkConflict().isDefined) {
throw new RuntimeException("This pull request can't merge automatically.")
}
@@ -242,10 +296,10 @@
newCommit
}
- val mergeBaseTipCommit = using(new RevWalk( repository ))(_.parseCommit( mergeBaseTip ))
+ val mergeBaseTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
var previousId = mergeBaseTipCommit.getId
- using(repository.newObjectInserter){ inserter =>
+ using(repository.newObjectInserter) { inserter =>
commits.foreach { commit =>
val nextCommit = _cloneCommit(commit, previousId, mergeBaseTipCommit.getId)
previousId = inserter.insert(nextCommit)
@@ -257,12 +311,12 @@
}
def squash(message: String, committer: PersonIdent): Unit = {
- if(checkConflict().isDefined){
+ if (checkConflict().isDefined) {
throw new RuntimeException("This pull request can't merge automatically.")
}
- val mergeBaseTipCommit = using(new RevWalk( repository ))(_.parseCommit(mergeBaseTip))
- val mergeBranchHeadCommit = using(new RevWalk( repository ))(_.parseCommit(repository.resolve(mergedBranchName)))
+ val mergeBaseTipCommit = using(new RevWalk(repository))(_.parseCommit(mergeBaseTip))
+ val mergeBranchHeadCommit = using(new RevWalk(repository))(_.parseCommit(repository.resolve(mergedBranchName)))
// Create squash commit
val mergeCommit = new CommitBuilder()
@@ -273,7 +327,7 @@
mergeCommit.setMessage(message)
// insertObject and got squash commit Object Id
- val newCommitId = using(repository.newObjectInserter){ inserter =>
+ val newCommitId = using(repository.newObjectInserter) { inserter =>
val newCommitId = inserter.insert(mergeCommit)
inserter.flush()
newCommitId
@@ -282,14 +336,21 @@
Util.updateRefs(repository, mergedBranchName, newCommitId, true, committer)
// rebase to squash commit
- Util.updateRefs(repository, s"refs/heads/${branch}", repository.resolve(mergedBranchName), false, committer, Some("squashed"))
+ Util.updateRefs(
+ repository,
+ s"refs/heads/${branch}",
+ repository.resolve(mergedBranchName),
+ false,
+ committer,
+ Some("squashed")
+ )
}
// return treeId
private def createMergeCommit(treeId: ObjectId, committer: PersonIdent, message: String) =
Util.createMergeCommit(repository, treeId, committer, message, Seq[ObjectId](mergeBaseTip, mergeTip))
- private def parseCommit(id: ObjectId) = using(new RevWalk( repository ))(_.parseCommit(id))
+ private def parseCommit(id: ObjectId) = using(new RevWalk(repository))(_.parseCommit(id))
}
diff --git a/src/main/scala/gitbucket/core/service/MilestonesService.scala b/src/main/scala/gitbucket/core/service/MilestonesService.scala
index 276aa7c..ae1ce1e 100644
--- a/src/main/scala/gitbucket/core/service/MilestonesService.scala
+++ b/src/main/scala/gitbucket/core/service/MilestonesService.scala
@@ -7,22 +7,27 @@
trait MilestonesService {
- def createMilestone(owner: String, repository: String, title: String, description: Option[String],
- dueDate: Option[java.util.Date])(implicit s: Session): Unit =
+ def createMilestone(
+ owner: String,
+ repository: String,
+ title: String,
+ description: Option[String],
+ dueDate: Option[java.util.Date]
+ )(implicit s: Session): Unit =
Milestones insert Milestone(
- userName = owner,
+ userName = owner,
repositoryName = repository,
- title = title,
- description = description,
- dueDate = dueDate,
- closedDate = None
+ title = title,
+ description = description,
+ dueDate = dueDate,
+ closedDate = None
)
def updateMilestone(milestone: Milestone)(implicit s: Session): Unit =
Milestones
- .filter (t => t.byPrimaryKey(milestone.userName, milestone.repositoryName, milestone.milestoneId))
- .map (t => (t.title, t.description, t.dueDate, t.closedDate))
- .update (milestone.title, milestone.description, milestone.dueDate, milestone.closedDate)
+ .filter(t => t.byPrimaryKey(milestone.userName, milestone.repositoryName, milestone.milestoneId))
+ .map(t => (t.title, t.description, t.dueDate, t.closedDate))
+ .update(milestone.title, milestone.description, milestone.dueDate, milestone.closedDate)
def openMilestone(milestone: Milestone)(implicit s: Session): Unit =
updateMilestone(milestone.copy(closedDate = None))
@@ -38,20 +43,33 @@
def getMilestone(owner: String, repository: String, milestoneId: Int)(implicit s: Session): Option[Milestone] =
Milestones.filter(_.byPrimaryKey(owner, repository, milestoneId)).firstOption
- def getMilestonesWithIssueCount(owner: String, repository: String)(implicit s: Session): List[(Milestone, Int, Int)] = {
+ def getMilestonesWithIssueCount(owner: String, repository: String)(
+ implicit s: Session
+ ): List[(Milestone, Int, Int)] = {
val counts = Issues
- .filter { t => t.byRepository(owner, repository) && (t.milestoneId.? isDefined) }
- .groupBy { t => t.milestoneId -> t.closed }
- .map { case (t1, t2) => t1._1 -> t1._2 -> t2.length }
+ .filter { t =>
+ t.byRepository(owner, repository) && (t.milestoneId.? isDefined)
+ }
+ .groupBy { t =>
+ t.milestoneId -> t.closed
+ }
+ .map { case (t1, t2) => t1._1 -> t1._2 -> t2.length }
.list
.toMap
getMilestones(owner, repository).map { milestone =>
- (milestone, counts.getOrElse((milestone.milestoneId, false), 0), counts.getOrElse((milestone.milestoneId, true), 0))
+ (
+ milestone,
+ counts.getOrElse((milestone.milestoneId, false), 0),
+ counts.getOrElse((milestone.milestoneId, true), 0)
+ )
}
}
def getMilestones(owner: String, repository: String)(implicit s: Session): List[Milestone] =
- Milestones.filter(_.byRepository(owner, repository)).sortBy(t => (t.dueDate.asc, t.closedDate.desc, t.milestoneId.desc)).list
+ Milestones
+ .filter(_.byRepository(owner, repository))
+ .sortBy(t => (t.dueDate.asc, t.closedDate.desc, t.milestoneId.desc))
+ .list
}
diff --git a/src/main/scala/gitbucket/core/service/OpenIDConnectService.scala b/src/main/scala/gitbucket/core/service/OpenIDConnectService.scala
index c767111..2b60dce 100644
--- a/src/main/scala/gitbucket/core/service/OpenIDConnectService.scala
+++ b/src/main/scala/gitbucket/core/service/OpenIDConnectService.scala
@@ -20,8 +20,8 @@
import scala.collection.JavaConverters.{asScalaSet, mapAsJavaMap}
/**
- * Service class for the OpenID Connect authentication.
- */
+ * Service class for the OpenID Connect authentication.
+ */
trait OpenIDConnectService {
self: AccountFederationService =>
@@ -29,22 +29,17 @@
private val JWK_REQUEST_TIMEOUT = 5000
- private val OIDC_SCOPE = new Scope(
- OIDCScopeValue.OPENID,
- OIDCScopeValue.EMAIL,
- OIDCScopeValue.PROFILE)
+ private val OIDC_SCOPE = new Scope(OIDCScopeValue.OPENID, OIDCScopeValue.EMAIL, OIDCScopeValue.PROFILE)
/**
- * Obtain the OIDC metadata from discovery and create an authentication request.
- *
- * @param issuer Issuer, used to construct the discovery endpoint URL, e.g. https://accounts.google.com
- * @param clientID Client ID (given by the issuer)
- * @param redirectURI Redirect URI
- * @return Authentication request
- */
- def createOIDCAuthenticationRequest(issuer: Issuer,
- clientID: ClientID,
- redirectURI: URI): AuthenticationRequest = {
+ * Obtain the OIDC metadata from discovery and create an authentication request.
+ *
+ * @param issuer Issuer, used to construct the discovery endpoint URL, e.g. https://accounts.google.com
+ * @param clientID Client ID (given by the issuer)
+ * @param redirectURI Redirect URI
+ * @return Authentication request
+ */
+ def createOIDCAuthenticationRequest(issuer: Issuer, clientID: ClientID, redirectURI: URI): AuthenticationRequest = {
val metadata = OIDCProviderMetadata.resolve(issuer)
new AuthenticationRequest(
metadata.getAuthorizationEndpointURI,
@@ -53,29 +48,38 @@
clientID,
redirectURI,
new State(),
- new Nonce())
+ new Nonce()
+ )
}
/**
- * Proceed the OpenID Connect authentication.
- *
- * @param params Query parameters of the authentication response
- * @param redirectURI Redirect URI
- * @param state State saved in the session
- * @param nonce Nonce saved in the session
- * @param oidc OIDC settings
- * @return ID token
- */
- def authenticate(params: Map[String, String],
- redirectURI: URI,
- state: State,
- nonce: Nonce,
- oidc: SystemSettingsService.OIDC)(implicit s: Session): Option[Account] =
+ * Proceed the OpenID Connect authentication.
+ *
+ * @param params Query parameters of the authentication response
+ * @param redirectURI Redirect URI
+ * @param state State saved in the session
+ * @param nonce Nonce saved in the session
+ * @param oidc OIDC settings
+ * @return ID token
+ */
+ def authenticate(
+ params: Map[String, String],
+ redirectURI: URI,
+ state: State,
+ nonce: Nonce,
+ oidc: SystemSettingsService.OIDC
+ )(implicit s: Session): Option[Account] =
validateOIDCAuthenticationResponse(params, state, redirectURI) flatMap { authenticationResponse =>
obtainOIDCToken(authenticationResponse.getAuthorizationCode, nonce, redirectURI, oidc) flatMap { claims =>
Seq("email", "preferred_username", "name").map(k => Option(claims.getStringClaim(k))) match {
case Seq(Some(email), preferredUsername, name) =>
- getOrCreateFederatedUser(claims.getIssuer.getValue, claims.getSubject.getValue, email, preferredUsername, name)
+ getOrCreateFederatedUser(
+ claims.getIssuer.getValue,
+ claims.getSubject.getValue,
+ email,
+ preferredUsername,
+ name
+ )
case _ =>
logger.info(s"OIDC ID token must have an email claim: claims=${claims.toJSONObject}")
None
@@ -84,14 +88,18 @@
}
/**
- * Validate the authentication response.
- *
- * @param params Query parameters of the authentication response
- * @param state State saved in the session
- * @param redirectURI Redirect URI
- * @return Authentication response
- */
- def validateOIDCAuthenticationResponse(params: Map[String, String], state: State, redirectURI: URI): Option[AuthenticationSuccessResponse] =
+ * Validate the authentication response.
+ *
+ * @param params Query parameters of the authentication response
+ * @param state State saved in the session
+ * @param redirectURI Redirect URI
+ * @return Authentication response
+ */
+ def validateOIDCAuthenticationResponse(
+ params: Map[String, String],
+ state: State,
+ redirectURI: URI
+ ): Option[AuthenticationSuccessResponse] =
try {
AuthenticationResponseParser.parse(redirectURI, mapAsJavaMap(params)) match {
case response: AuthenticationSuccessResponse =>
@@ -112,23 +120,27 @@
}
/**
- * Obtain the ID token from the OpenID Provider.
- *
- * @param authorizationCode Authorization code in the query string
- * @param nonce Nonce
- * @param redirectURI Redirect URI
- * @param oidc OIDC settings
- * @return Token response
- */
- def obtainOIDCToken(authorizationCode: AuthorizationCode,
- nonce: Nonce,
- redirectURI: URI,
- oidc: SystemSettingsService.OIDC): Option[IDTokenClaimsSet] = {
+ * Obtain the ID token from the OpenID Provider.
+ *
+ * @param authorizationCode Authorization code in the query string
+ * @param nonce Nonce
+ * @param redirectURI Redirect URI
+ * @param oidc OIDC settings
+ * @return Token response
+ */
+ def obtainOIDCToken(
+ authorizationCode: AuthorizationCode,
+ nonce: Nonce,
+ redirectURI: URI,
+ oidc: SystemSettingsService.OIDC
+ ): Option[IDTokenClaimsSet] = {
val metadata = OIDCProviderMetadata.resolve(oidc.issuer)
- val tokenRequest = new TokenRequest(metadata.getTokenEndpointURI,
+ val tokenRequest = new TokenRequest(
+ metadata.getTokenEndpointURI,
new ClientSecretBasic(oidc.clientID, oidc.clientSecret),
new AuthorizationCodeGrant(authorizationCode, redirectURI),
- OIDC_SCOPE)
+ OIDC_SCOPE
+ )
val httpResponse = tokenRequest.toHTTPRequest.send()
try {
OIDCTokenResponseParser.parse(httpResponse) match {
@@ -146,29 +158,36 @@
}
/**
- * Validate the token response.
- *
- * @param response Token response
- * @param metadata OpenID Provider metadata
- * @param nonce Nonce
- * @return Claims
- */
- def validateOIDCTokenResponse(response: OIDCTokenResponse,
- metadata: OIDCProviderMetadata,
- nonce: Nonce,
- oidc: SystemSettingsService.OIDC): Option[IDTokenClaimsSet] =
+ * Validate the token response.
+ *
+ * @param response Token response
+ * @param metadata OpenID Provider metadata
+ * @param nonce Nonce
+ * @return Claims
+ */
+ def validateOIDCTokenResponse(
+ response: OIDCTokenResponse,
+ metadata: OIDCProviderMetadata,
+ nonce: Nonce,
+ oidc: SystemSettingsService.OIDC
+ ): Option[IDTokenClaimsSet] =
Option(response.getOIDCTokens.getIDToken) match {
case Some(jwt) =>
val validator = oidc.jwsAlgorithm map { jwsAlgorithm =>
- new IDTokenValidator(metadata.getIssuer, oidc.clientID, jwsAlgorithm, metadata.getJWKSetURI.toURL,
- new DefaultResourceRetriever(JWK_REQUEST_TIMEOUT, JWK_REQUEST_TIMEOUT))
+ new IDTokenValidator(
+ metadata.getIssuer,
+ oidc.clientID,
+ jwsAlgorithm,
+ metadata.getJWKSetURI.toURL,
+ new DefaultResourceRetriever(JWK_REQUEST_TIMEOUT, JWK_REQUEST_TIMEOUT)
+ )
} getOrElse {
new IDTokenValidator(metadata.getIssuer, oidc.clientID)
}
try {
Some(validator.validate(jwt, nonce))
} catch {
- case e@(_: BadJOSEException | _: JOSEException) =>
+ case e @ (_: BadJOSEException | _: JOSEException) =>
logger.info(s"OIDC ID token has error: $e")
None
}
@@ -179,9 +198,10 @@
}
object OpenIDConnectService {
+
/**
- * All signature algorithms.
- */
+ * All signature algorithms.
+ */
val JWS_ALGORITHMS: Map[String, Set[JWSAlgorithm]] = Seq(
"HMAC" -> Family.HMAC_SHA,
"RSA" -> Family.RSA,
diff --git a/src/main/scala/gitbucket/core/service/PrioritiesService.scala b/src/main/scala/gitbucket/core/service/PrioritiesService.scala
index cafff4b..22037e7 100644
--- a/src/main/scala/gitbucket/core/service/PrioritiesService.scala
+++ b/src/main/scala/gitbucket/core/service/PrioritiesService.scala
@@ -16,8 +16,15 @@
def getPriority(owner: String, repository: String, priorityName: String)(implicit s: Session): Option[Priority] =
Priorities.filter(_.byPriority(owner, repository, priorityName)).firstOption
- def createPriority(owner: String, repository: String, priorityName: String, description: Option[String], color: String)(implicit s: Session): Int = {
- val ordering = Priorities.filter(_.byRepository(owner, repository))
+ def createPriority(
+ owner: String,
+ repository: String,
+ priorityName: String,
+ description: Option[String],
+ color: String
+ )(implicit s: Session): Int = {
+ val ordering = Priorities
+ .filter(_.byRepository(owner, repository))
.list
.map(p => p.ordering)
.reduceOption(_ max _)
@@ -25,37 +32,48 @@
.getOrElse(0)
Priorities returning Priorities.map(_.priorityId) insert Priority(
- userName = owner,
+ userName = owner,
repositoryName = repository,
- priorityName = priorityName,
- description = description,
- isDefault = false,
- ordering = ordering,
- color = color
+ priorityName = priorityName,
+ description = description,
+ isDefault = false,
+ ordering = ordering,
+ color = color
)
}
- def updatePriority(owner: String, repository: String, priorityId: Int, priorityName: String, description: Option[String], color: String)
- (implicit s: Session): Unit =
- Priorities.filter(_.byPrimaryKey(owner, repository, priorityId))
- .map(t => (t.priorityName, t.description.?, t.color))
- .update(priorityName, description, color)
+ def updatePriority(
+ owner: String,
+ repository: String,
+ priorityId: Int,
+ priorityName: String,
+ description: Option[String],
+ color: String
+ )(implicit s: Session): Unit =
+ Priorities
+ .filter(_.byPrimaryKey(owner, repository, priorityId))
+ .map(t => (t.priorityName, t.description.?, t.color))
+ .update(priorityName, description, color)
- def reorderPriorities(owner: String, repository: String, order: Map[Int, Int])
- (implicit s: Session): Unit = {
+ def reorderPriorities(owner: String, repository: String, order: Map[Int, Int])(implicit s: Session): Unit = {
- Priorities.filter(_.byRepository(owner, repository))
+ Priorities
+ .filter(_.byRepository(owner, repository))
.list
- .foreach(p => Priorities
- .filter(_.byPrimaryKey(owner, repository, p.priorityId))
- .map(_.ordering)
- .update(order.get(p.priorityId).get))
+ .foreach(
+ p =>
+ Priorities
+ .filter(_.byPrimaryKey(owner, repository, p.priorityId))
+ .map(_.ordering)
+ .update(order.get(p.priorityId).get)
+ )
}
def deletePriority(owner: String, repository: String, priorityId: Int)(implicit s: Session): Unit = {
- Issues.filter(_.byRepository(owner, repository))
+ Issues
+ .filter(_.byRepository(owner, repository))
.filter(_.priorityId === priorityId)
- .map(_.priorityId?)
+ .map(_.priorityId ?)
.update(None)
Priorities.filter(_.byPrimaryKey(owner, repository, priorityId)).delete
@@ -76,9 +94,12 @@
.map(_.isDefault)
.update(false)
- priorityId.foreach(id => Priorities
- .filter(_.byPrimaryKey(owner, repository, id))
- .map(_.isDefault)
- .update(true))
+ priorityId.foreach(
+ id =>
+ Priorities
+ .filter(_.byPrimaryKey(owner, repository, id))
+ .map(_.isDefault)
+ .update(true)
+ )
}
}
diff --git a/src/main/scala/gitbucket/core/service/ProtectedBranchService.scala b/src/main/scala/gitbucket/core/service/ProtectedBranchService.scala
index 65d0aaa..8befb2f 100644
--- a/src/main/scala/gitbucket/core/service/ProtectedBranchService.scala
+++ b/src/main/scala/gitbucket/core/service/ProtectedBranchService.scala
@@ -6,55 +6,81 @@
import gitbucket.core.model.Profile.profile.blockingApi._
import org.eclipse.jgit.transport.{ReceiveCommand, ReceivePack}
-
trait ProtectedBranchService {
import ProtectedBranchService._
- private def getProtectedBranchInfoOpt(owner: String, repository: String, branch: String)(implicit session: Session): Option[ProtectedBranchInfo] =
+ private def getProtectedBranchInfoOpt(owner: String, repository: String, branch: String)(
+ implicit session: Session
+ ): Option[ProtectedBranchInfo] =
ProtectedBranches
.joinLeft(ProtectedBranchContexts)
- .on { case (pb, c) => pb.byBranch(c.userName, c.repositoryName, c.branch) }
+ .on { case (pb, c) => pb.byBranch(c.userName, c.repositoryName, c.branch) }
.map { case (pb, c) => pb -> c.map(_.context) }
.filter(_._1.byPrimaryKey(owner, repository, branch))
.list
.groupBy(_._1)
.headOption
- .map { p => p._1 -> p._2.flatMap(_._2) }
- .map { case (t1, contexts) =>
- new ProtectedBranchInfo(t1.userName, t1.repositoryName, true, contexts, t1.statusCheckAdmin)
+ .map { p =>
+ p._1 -> p._2.flatMap(_._2)
+ }
+ .map {
+ case (t1, contexts) =>
+ new ProtectedBranchInfo(t1.userName, t1.repositoryName, true, contexts, t1.statusCheckAdmin)
}
- def getProtectedBranchInfo(owner: String, repository: String, branch: String)(implicit session: Session): ProtectedBranchInfo =
+ def getProtectedBranchInfo(owner: String, repository: String, branch: String)(
+ implicit session: Session
+ ): ProtectedBranchInfo =
getProtectedBranchInfoOpt(owner, repository, branch).getOrElse(ProtectedBranchInfo.disabled(owner, repository))
def getProtectedBranchList(owner: String, repository: String)(implicit session: Session): List[String] =
ProtectedBranches.filter(_.byRepository(owner, repository)).map(_.branch).list
- def enableBranchProtection(owner: String, repository: String, branch:String, includeAdministrators: Boolean, contexts: Seq[String])
- (implicit session: Session): Unit = {
+ def enableBranchProtection(
+ owner: String,
+ repository: String,
+ branch: String,
+ includeAdministrators: Boolean,
+ contexts: Seq[String]
+ )(implicit session: Session): Unit = {
disableBranchProtection(owner, repository, branch)
ProtectedBranches.insert(new ProtectedBranch(owner, repository, branch, includeAdministrators && contexts.nonEmpty))
- contexts.map{ context =>
+ contexts.map { context =>
ProtectedBranchContexts.insert(new ProtectedBranchContext(owner, repository, branch, context))
}
}
- def disableBranchProtection(owner: String, repository: String, branch:String)(implicit session: Session): Unit =
+ def disableBranchProtection(owner: String, repository: String, branch: String)(implicit session: Session): Unit =
ProtectedBranches.filter(_.byPrimaryKey(owner, repository, branch)).delete
}
object ProtectedBranchService {
- class ProtectedBranchReceiveHook extends ReceiveHook with ProtectedBranchService with RepositoryService with AccountService {
- override def preReceive(owner: String, repository: String, receivePack: ReceivePack, command: ReceiveCommand, pusher: String)
- (implicit session: Session): Option[String] = {
+ class ProtectedBranchReceiveHook
+ extends ReceiveHook
+ with ProtectedBranchService
+ with RepositoryService
+ with AccountService {
+ override def preReceive(
+ owner: String,
+ repository: String,
+ receivePack: ReceivePack,
+ command: ReceiveCommand,
+ pusher: String
+ )(implicit session: Session): Option[String] = {
val branch = command.getRefName.stripPrefix("refs/heads/")
- if(branch != command.getRefName){
+ if (branch != command.getRefName) {
val repositoryInfo = getRepository(owner, repository)
- if(command.getType == ReceiveCommand.Type.DELETE && repositoryInfo.exists(_.repository.defaultBranch == branch)){
+ if (command.getType == ReceiveCommand.Type.DELETE && repositoryInfo.exists(
+ _.repository.defaultBranch == branch
+ )) {
Some(s"refusing to delete the branch: ${command.getRefName}.")
} else {
- getProtectedBranchInfo(owner, repository, branch).getStopReason(receivePack.isAllowNonFastForwards, command, pusher)
+ getProtectedBranchInfo(owner, repository, branch).getStopReason(
+ receivePack.isAllowNonFastForwards,
+ command,
+ pusher
+ )
}
} else {
None
@@ -62,7 +88,6 @@
}
}
-
case class ProtectedBranchInfo(
owner: String,
repository: String,
@@ -78,18 +103,22 @@
* Include administrators
* Enforce required status checks for repository administrators.
*/
- includeAdministrators: Boolean) extends AccountService with RepositoryService with CommitStatusService {
+ includeAdministrators: Boolean
+ ) extends AccountService
+ with RepositoryService
+ with CommitStatusService {
def isAdministrator(pusher: String)(implicit session: Session): Boolean =
pusher == owner || getGroupMembers(owner).exists(gm => gm.userName == pusher && gm.isManager) ||
- getCollaborators(owner, repository).exists { case (collaborator, isGroup) =>
- if(collaborator.role == Role.ADMIN.name){
- if(isGroup){
- getGroupMembers(collaborator.collaboratorName).exists(gm => gm.userName == pusher)
- } else {
- collaborator.collaboratorName == pusher
- }
- } else false
+ getCollaborators(owner, repository).exists {
+ case (collaborator, isGroup) =>
+ if (collaborator.role == Role.ADMIN.name) {
+ if (isGroup) {
+ getGroupMembers(collaborator.collaboratorName).exists(gm => gm.userName == pusher)
+ } else {
+ collaborator.collaboratorName == pusher
+ }
+ } else false
}
/**
@@ -97,16 +126,18 @@
* Can't be deleted
* Can't have changes merged into them until required status checks pass
*/
- def getStopReason(isAllowNonFastForwards: Boolean, command: ReceiveCommand, pusher: String)(implicit session: Session): Option[String] = {
- if(enabled){
+ def getStopReason(isAllowNonFastForwards: Boolean, command: ReceiveCommand, pusher: String)(
+ implicit session: Session
+ ): Option[String] = {
+ if (enabled) {
command.getType() match {
case ReceiveCommand.Type.UPDATE_NONFASTFORWARD if isAllowNonFastForwards =>
Some("Cannot force-push to a protected branch")
- case ReceiveCommand.Type.UPDATE|ReceiveCommand.Type.UPDATE_NONFASTFORWARD if needStatusCheck(pusher) =>
+ case ReceiveCommand.Type.UPDATE | ReceiveCommand.Type.UPDATE_NONFASTFORWARD if needStatusCheck(pusher) =>
unSuccessedContexts(command.getNewId.name) match {
case s if s.size == 1 => Some(s"""Required status check "${s.toSeq(0)}" is expected""")
case s if s.size >= 1 => Some(s"${s.size} of ${contexts.size} required status checks are expected")
- case _ => None
+ case _ => None
}
case ReceiveCommand.Type.DELETE =>
Some("Cannot delete a protected branch")
@@ -116,11 +147,15 @@
None
}
}
- def unSuccessedContexts(sha1: String)(implicit session: Session): Set[String] = if(contexts.isEmpty){
- Set.empty
- } else {
- contexts.toSet -- getCommitStatues(owner, repository, sha1).filter(_.state == CommitState.SUCCESS).map(_.context).toSet
- }
+ def unSuccessedContexts(sha1: String)(implicit session: Session): Set[String] =
+ if (contexts.isEmpty) {
+ Set.empty
+ } else {
+ contexts.toSet -- getCommitStatues(owner, repository, sha1)
+ .filter(_.state == CommitState.SUCCESS)
+ .map(_.context)
+ .toSet
+ }
def needStatusCheck(pusher: String)(implicit session: Session): Boolean = pusher match {
case _ if !enabled => false
case _ if contexts.isEmpty => false
@@ -129,7 +164,8 @@
case _ => true
}
}
- object ProtectedBranchInfo{
- def disabled(owner: String, repository: String): ProtectedBranchInfo = ProtectedBranchInfo(owner, repository, false, Nil, false)
+ object ProtectedBranchInfo {
+ def disabled(owner: String, repository: String): ProtectedBranchInfo =
+ ProtectedBranchInfo(owner, repository, false, Nil, false)
}
}
diff --git a/src/main/scala/gitbucket/core/service/PullRequestService.scala b/src/main/scala/gitbucket/core/service/PullRequestService.scala
index b6c009a..ddcb345 100644
--- a/src/main/scala/gitbucket/core/service/PullRequestService.scala
+++ b/src/main/scala/gitbucket/core/service/PullRequestService.scala
@@ -14,38 +14,47 @@
import org.eclipse.jgit.api.Git
import scala.collection.JavaConverters._
-
trait PullRequestService { self: IssuesService with CommitsService =>
import PullRequestService._
- def getPullRequest(owner: String, repository: String, issueId: Int)
- (implicit s: Session): Option[(Issue, PullRequest)] =
- getIssue(owner, repository, issueId.toString).flatMap{ issue =>
- PullRequests.filter(_.byPrimaryKey(owner, repository, issueId)).firstOption.map{
- pullreq => (issue, pullreq)
+ def getPullRequest(owner: String, repository: String, issueId: Int)(
+ implicit s: Session
+ ): Option[(Issue, PullRequest)] =
+ getIssue(owner, repository, issueId.toString).flatMap { issue =>
+ PullRequests.filter(_.byPrimaryKey(owner, repository, issueId)).firstOption.map { pullreq =>
+ (issue, pullreq)
}
}
- def updateCommitId(owner: String, repository: String, issueId: Int, commitIdTo: String, commitIdFrom: String)
- (implicit s: Session): Unit =
- PullRequests.filter(_.byPrimaryKey(owner, repository, issueId))
- .map(pr => pr.commitIdTo -> pr.commitIdFrom)
- .update((commitIdTo, commitIdFrom))
-
- def getPullRequestCountGroupByUser(closed: Boolean, owner: Option[String], repository: Option[String])
- (implicit s: Session): List[PullRequestCount] =
+ def updateCommitId(owner: String, repository: String, issueId: Int, commitIdTo: String, commitIdFrom: String)(
+ implicit s: Session
+ ): Unit =
PullRequests
- .join(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) }
- .filter { case (t1, t2) =>
- (t2.closed === closed.bind) &&
- (t1.userName === owner.get.bind, owner.isDefined) &&
- (t1.repositoryName === repository.get.bind, repository.isDefined)
+ .filter(_.byPrimaryKey(owner, repository, issueId))
+ .map(pr => pr.commitIdTo -> pr.commitIdFrom)
+ .update((commitIdTo, commitIdFrom))
+
+ def getPullRequestCountGroupByUser(closed: Boolean, owner: Option[String], repository: Option[String])(
+ implicit s: Session
+ ): List[PullRequestCount] =
+ PullRequests
+ .join(Issues)
+ .on { (t1, t2) =>
+ t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId)
+ }
+ .filter {
+ case (t1, t2) =>
+ (t2.closed === closed.bind) &&
+ (t1.userName === owner.get.bind, owner.isDefined) &&
+ (t1.repositoryName === repository.get.bind, repository.isDefined)
}
.groupBy { case (t1, t2) => t2.openedUserName }
.map { case (userName, t) => userName -> t.length }
.sortBy(_._2 desc)
.list
- .map { x => PullRequestCount(x._1, x._2) }
+ .map { x =>
+ PullRequestCount(x._1, x._2)
+ }
// def getAllPullRequestCountGroupByUser(closed: Boolean, userName: String)(implicit s: Session): List[PullRequestCount] =
// PullRequests
@@ -65,9 +74,17 @@
// .list
// .map { x => PullRequestCount(x._1, x._2) }
- def createPullRequest(originUserName: String, originRepositoryName: String, issueId: Int,
- originBranch: String, requestUserName: String, requestRepositoryName: String, requestBranch: String,
- commitIdFrom: String, commitIdTo: String)(implicit s: Session): Unit =
+ def createPullRequest(
+ originUserName: String,
+ originRepositoryName: String,
+ issueId: Int,
+ originBranch: String,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestBranch: String,
+ commitIdFrom: String,
+ commitIdTo: String
+ )(implicit s: Session): Unit =
PullRequests insert PullRequest(
originUserName,
originRepositoryName,
@@ -77,17 +94,23 @@
requestRepositoryName,
requestBranch,
commitIdFrom,
- commitIdTo)
+ commitIdTo
+ )
- def getPullRequestsByRequest(userName: String, repositoryName: String, branch: String, closed: Option[Boolean])
- (implicit s: Session): List[PullRequest] =
+ def getPullRequestsByRequest(userName: String, repositoryName: String, branch: String, closed: Option[Boolean])(
+ implicit s: Session
+ ): List[PullRequest] =
PullRequests
- .join(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) }
- .filter { case (t1, t2) =>
- (t1.requestUserName === userName.bind) &&
- (t1.requestRepositoryName === repositoryName.bind) &&
- (t1.requestBranch === branch.bind) &&
- (t2.closed === closed.get.bind, closed.isDefined)
+ .join(Issues)
+ .on { (t1, t2) =>
+ t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId)
+ }
+ .filter {
+ case (t1, t2) =>
+ (t1.requestUserName === userName.bind) &&
+ (t1.requestRepositoryName === repositoryName.bind) &&
+ (t1.requestBranch === branch.bind) &&
+ (t2.closed === closed.get.bind, closed.isDefined)
}
.map { case (t1, t2) => t1 }
.list
@@ -99,19 +122,24 @@
* 2. return if exists pull request to other branch
* 2. return None
*/
- def getPullRequestFromBranch(userName: String, repositoryName: String, branch: String, defaultBranch: String)
- (implicit s: Session): Option[(PullRequest, Issue)] =
+ def getPullRequestFromBranch(userName: String, repositoryName: String, branch: String, defaultBranch: String)(
+ implicit s: Session
+ ): Option[(PullRequest, Issue)] =
PullRequests
- .join(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) }
- .filter { case (t1, t2) =>
- (t1.requestUserName === userName.bind) &&
- (t1.requestRepositoryName === repositoryName.bind) &&
- (t1.requestBranch === branch.bind) &&
- (t1.userName === userName.bind) &&
- (t1.repositoryName === repositoryName.bind) &&
- (t2.closed === false.bind)
+ .join(Issues)
+ .on { (t1, t2) =>
+ t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId)
}
- .sortBy{ case (t1, t2) => t1.branch =!= defaultBranch.bind }
+ .filter {
+ case (t1, t2) =>
+ (t1.requestUserName === userName.bind) &&
+ (t1.requestRepositoryName === repositoryName.bind) &&
+ (t1.requestBranch === branch.bind) &&
+ (t1.userName === userName.bind) &&
+ (t1.repositoryName === repositoryName.bind) &&
+ (t2.closed === false.bind)
+ }
+ .sortBy { case (t1, t2) => t1.branch =!= defaultBranch.bind }
.firstOption
/**
@@ -119,116 +147,172 @@
*/
def updatePullRequests(owner: String, repository: String, branch: String)(implicit s: Session): Unit =
getPullRequestsByRequest(owner, repository, branch, Some(false)).foreach { pullreq =>
- if(Repositories.filter(_.byRepository(pullreq.userName, pullreq.repositoryName)).exists.run){
+ if (Repositories.filter(_.byRepository(pullreq.userName, pullreq.repositoryName)).exists.run) {
// Update the git repository
val (commitIdTo, commitIdFrom) = JGitUtil.updatePullRequest(
- pullreq.userName, pullreq.repositoryName, pullreq.branch, pullreq.issueId,
- pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.requestBranch)
+ pullreq.userName,
+ pullreq.repositoryName,
+ pullreq.branch,
+ pullreq.issueId,
+ pullreq.requestUserName,
+ pullreq.requestRepositoryName,
+ pullreq.requestBranch
+ )
// Collect comment positions
val positions = getCommitComments(pullreq.userName, pullreq.repositoryName, pullreq.commitIdTo, true)
.collect {
- case CommitComment(_, _, _, commentId, _, _, Some(file), None, Some(newLine), _, _, _) => (file, commentId, Right(newLine))
- case CommitComment(_, _, _, commentId, _, _, Some(file), Some(oldLine), None, _, _, _) => (file, commentId, Left(oldLine))
+ case CommitComment(_, _, _, commentId, _, _, Some(file), None, Some(newLine), _, _, _) =>
+ (file, commentId, Right(newLine))
+ case CommitComment(_, _, _, commentId, _, _, Some(file), Some(oldLine), None, _, _, _) =>
+ (file, commentId, Left(oldLine))
}
.groupBy { case (file, _, _) => file }
- .map { case (file, comments) => file ->
- comments.map { case (_, commentId, lineNumber) => (commentId, lineNumber) }
+ .map {
+ case (file, comments) =>
+ file ->
+ comments.map { case (_, commentId, lineNumber) => (commentId, lineNumber) }
}
// Update comments position
- updatePullRequestCommentPositions(positions, pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.commitIdTo, commitIdTo)
+ updatePullRequestCommentPositions(
+ positions,
+ pullreq.requestUserName,
+ pullreq.requestRepositoryName,
+ pullreq.commitIdTo,
+ commitIdTo
+ )
// Update commit id in the PULL_REQUEST table
updateCommitId(pullreq.userName, pullreq.repositoryName, pullreq.issueId, commitIdTo, commitIdFrom)
}
}
- def getPullRequestByRequestCommit(userName: String, repositoryName: String, toBranch:String, fromBranch: String, commitId: String)
- (implicit s: Session): Option[(PullRequest, Issue)] = {
- if(toBranch == fromBranch){
+ def getPullRequestByRequestCommit(
+ userName: String,
+ repositoryName: String,
+ toBranch: String,
+ fromBranch: String,
+ commitId: String
+ )(implicit s: Session): Option[(PullRequest, Issue)] = {
+ if (toBranch == fromBranch) {
None
} else {
PullRequests
- .join(Issues).on { (t1, t2) => t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId) }
- .filter { case (t1, t2) =>
- (t1.userName === userName.bind) &&
- (t1.repositoryName === repositoryName.bind) &&
- (t1.branch === toBranch.bind) &&
- (t1.requestUserName === userName.bind) &&
- (t1.requestRepositoryName === repositoryName.bind) &&
- (t1.requestBranch === fromBranch.bind) &&
- (t1.commitIdTo === commitId.bind)
+ .join(Issues)
+ .on { (t1, t2) =>
+ t1.byPrimaryKey(t2.userName, t2.repositoryName, t2.issueId)
+ }
+ .filter {
+ case (t1, t2) =>
+ (t1.userName === userName.bind) &&
+ (t1.repositoryName === repositoryName.bind) &&
+ (t1.branch === toBranch.bind) &&
+ (t1.requestUserName === userName.bind) &&
+ (t1.requestRepositoryName === repositoryName.bind) &&
+ (t1.requestBranch === fromBranch.bind) &&
+ (t1.commitIdTo === commitId.bind)
}
.firstOption
}
}
- private def updatePullRequestCommentPositions(positions: Map[String, Seq[(Int, Either[Int, Int])]], userName: String, repositoryName: String,
- oldCommitId: String, newCommitId: String)(implicit s: Session): Unit = {
+ private def updatePullRequestCommentPositions(
+ positions: Map[String, Seq[(Int, Either[Int, Int])]],
+ userName: String,
+ repositoryName: String,
+ oldCommitId: String,
+ newCommitId: String
+ )(implicit s: Session): Unit = {
val (_, diffs) = getRequestCompareInfo(userName, repositoryName, oldCommitId, userName, repositoryName, newCommitId)
- val patchs = positions.map { case (file, _) =>
- diffs.find(x => x.oldPath == file).map { diff =>
- (diff.oldContent, diff.newContent) match {
- case (Some(oldContent), Some(newContent)) => {
- val oldLines = oldContent.replace("\r\n", "\n").split("\n")
- val newLines = newContent.replace("\r\n", "\n").split("\n")
- file -> Option(DiffUtils.diff(oldLines.toList.asJava, newLines.toList.asJava))
+ val patchs = positions.map {
+ case (file, _) =>
+ diffs
+ .find(x => x.oldPath == file)
+ .map { diff =>
+ (diff.oldContent, diff.newContent) match {
+ case (Some(oldContent), Some(newContent)) => {
+ val oldLines = oldContent.replace("\r\n", "\n").split("\n")
+ val newLines = newContent.replace("\r\n", "\n").split("\n")
+ file -> Option(DiffUtils.diff(oldLines.toList.asJava, newLines.toList.asJava))
+ }
+ case _ =>
+ file -> None
+ }
}
- case _ =>
+ .getOrElse {
file -> None
- }
- }.getOrElse {
- file -> None
- }
+ }
}
- positions.foreach { case (file, comments) =>
- patchs(file) match {
- case Some(patch) => file -> comments.foreach { case (commentId, lineNumber) => lineNumber match {
- case Left(oldLine) => updateCommitCommentPosition(commentId, newCommitId, Some(oldLine), None)
- case Right(newLine) =>
- var counter = newLine
- patch.getDeltas.asScala.filter(_.getOriginal.getPosition < newLine).foreach { delta =>
- delta.getType match {
- case Delta.TYPE.CHANGE =>
- if(delta.getOriginal.getPosition <= newLine - 1 && newLine <= delta.getOriginal.getPosition + delta.getRevised.getLines.size){
- counter = -1
- } else {
- counter = counter + (delta.getRevised.getLines.size - delta.getOriginal.getLines.size)
- }
- case Delta.TYPE.INSERT => counter = counter + delta.getRevised.getLines.size
- case Delta.TYPE.DELETE => counter = counter - delta.getOriginal.getLines.size
- }
+ positions.foreach {
+ case (file, comments) =>
+ patchs(file) match {
+ case Some(patch) =>
+ file -> comments.foreach {
+ case (commentId, lineNumber) =>
+ lineNumber match {
+ case Left(oldLine) => updateCommitCommentPosition(commentId, newCommitId, Some(oldLine), None)
+ case Right(newLine) =>
+ var counter = newLine
+ patch.getDeltas.asScala.filter(_.getOriginal.getPosition < newLine).foreach { delta =>
+ delta.getType match {
+ case Delta.TYPE.CHANGE =>
+ if (delta.getOriginal.getPosition <= newLine - 1 && newLine <= delta.getOriginal.getPosition + delta.getRevised.getLines.size) {
+ counter = -1
+ } else {
+ counter = counter + (delta.getRevised.getLines.size - delta.getOriginal.getLines.size)
+ }
+ case Delta.TYPE.INSERT => counter = counter + delta.getRevised.getLines.size
+ case Delta.TYPE.DELETE => counter = counter - delta.getOriginal.getLines.size
+ }
+ }
+ if (counter >= 0) {
+ updateCommitCommentPosition(commentId, newCommitId, None, Some(counter))
+ }
+ }
}
- if(counter >= 0){
- updateCommitCommentPosition(commentId, newCommitId, None, Some(counter))
+ case _ =>
+ comments.foreach {
+ case (commentId, lineNumber) =>
+ lineNumber match {
+ case Right(oldLine) => updateCommitCommentPosition(commentId, newCommitId, Some(oldLine), None)
+ case Left(newLine) => updateCommitCommentPosition(commentId, newCommitId, None, Some(newLine))
+ }
}
- }}
- case _ => comments.foreach { case (commentId, lineNumber) => lineNumber match {
- case Right(oldLine) => updateCommitCommentPosition(commentId, newCommitId, Some(oldLine), None)
- case Left(newLine) => updateCommitCommentPosition(commentId, newCommitId, None, Some(newLine))
- }}
- }
+ }
}
}
- def getRequestCompareInfo(userName: String, repositoryName: String, branch: String,
- requestUserName: String, requestRepositoryName: String, requestCommitId: String): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
+ def getRequestCompareInfo(
+ userName: String,
+ repositoryName: String,
+ branch: String,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestCommitId: String
+ ): (Seq[Seq[CommitInfo]], Seq[DiffInfo]) =
using(
Git.open(getRepositoryDir(userName, repositoryName)),
Git.open(getRepositoryDir(requestUserName, requestRepositoryName))
- ){ (oldGit, newGit) =>
+ ) { (oldGit, newGit) =>
val oldId = oldGit.getRepository.resolve(branch)
val newId = newGit.getRepository.resolve(requestCommitId)
- val commits = newGit.log.addRange(oldId, newId).call.iterator.asScala.map { revCommit =>
- new CommitInfo(revCommit)
- }.toList.splitWith { (commit1, commit2) =>
- helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
- }
+ val commits = newGit.log
+ .addRange(oldId, newId)
+ .call
+ .iterator
+ .asScala
+ .map { revCommit =>
+ new CommitInfo(revCommit)
+ }
+ .toList
+ .splitWith { (commit1, commit2) =>
+ helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
+ }
val diffs = JGitUtil.getDiffs(newGit, Some(oldId.getName), newId.getName, true, false)
@@ -251,22 +335,30 @@
hasUpdatePermission: Boolean,
needStatusCheck: Boolean,
hasMergePermission: Boolean,
- commitIdTo: String){
+ commitIdTo: String
+ ) {
val hasConflict = conflictMessage.isDefined
val statuses: List[CommitStatus] =
- commitStatues ++ (branchProtection.contexts.toSet -- commitStatues.map(_.context).toSet).map(CommitStatus.pending(branchProtection.owner, branchProtection.repository, _))
- val hasRequiredStatusProblem = needStatusCheck && branchProtection.contexts.exists(context => statuses.find(_.context == context).map(_.state) != Some(CommitState.SUCCESS))
- val hasProblem = hasRequiredStatusProblem || hasConflict || (statuses.nonEmpty && CommitState.combine(statuses.map(_.state).toSet) != CommitState.SUCCESS)
- val canUpdate = branchIsOutOfDate && !hasConflict
- val canMerge = hasMergePermission && !hasConflict && !hasRequiredStatusProblem
- lazy val commitStateSummary:(CommitState, String) = {
+ commitStatues ++ (branchProtection.contexts.toSet -- commitStatues.map(_.context).toSet)
+ .map(CommitStatus.pending(branchProtection.owner, branchProtection.repository, _))
+ val hasRequiredStatusProblem = needStatusCheck && branchProtection.contexts.exists(
+ context => statuses.find(_.context == context).map(_.state) != Some(CommitState.SUCCESS)
+ )
+ val hasProblem = hasRequiredStatusProblem || hasConflict || (statuses.nonEmpty && CommitState.combine(
+ statuses.map(_.state).toSet
+ ) != CommitState.SUCCESS)
+ val canUpdate = branchIsOutOfDate && !hasConflict
+ val canMerge = hasMergePermission && !hasConflict && !hasRequiredStatusProblem
+ lazy val commitStateSummary: (CommitState, String) = {
val stateMap = statuses.groupBy(_.state)
val state = CommitState.combine(stateMap.keySet)
- val summary = stateMap.map{ case (keyState, states) => states.size+" "+keyState.name }.mkString(", ")
+ val summary = stateMap.map { case (keyState, states) => states.size + " " + keyState.name }.mkString(", ")
state -> summary
}
- lazy val statusesAndRequired:List[(CommitStatus, Boolean)] = statuses.map{ s => s -> branchProtection.contexts.contains(s.context) }
- lazy val isAllSuccess = commitStateSummary._1==CommitState.SUCCESS
+ lazy val statusesAndRequired: List[(CommitStatus, Boolean)] = statuses.map { s =>
+ s -> branchProtection.contexts.contains(s.context)
+ }
+ lazy val isAllSuccess = commitStateSummary._1 == CommitState.SUCCESS
}
}
diff --git a/src/main/scala/gitbucket/core/service/ReleaseService.scala b/src/main/scala/gitbucket/core/service/ReleaseService.scala
index 26941d3..0a8df2f 100644
--- a/src/main/scala/gitbucket/core/service/ReleaseService.scala
+++ b/src/main/scala/gitbucket/core/service/ReleaseService.scala
@@ -9,17 +9,25 @@
trait ReleaseService {
self: AccountService with RepositoryService =>
- def createReleaseAsset(owner: String, repository: String, tag: String, fileName: String, label: String, size: Long, loginAccount: Account)(implicit s: Session): Unit = {
+ def createReleaseAsset(
+ owner: String,
+ repository: String,
+ tag: String,
+ fileName: String,
+ label: String,
+ size: Long,
+ loginAccount: Account
+ )(implicit s: Session): Unit = {
ReleaseAssets insert ReleaseAsset(
- userName = owner,
+ userName = owner,
repositoryName = repository,
- tag = tag,
- fileName = fileName,
- label = label,
- size = size,
- uploader = loginAccount.userName,
+ tag = tag,
+ fileName = fileName,
+ label = label,
+ size = size,
+ uploader = loginAccount.userName,
registeredDate = currentDate,
- updatedDate = currentDate
+ updatedDate = currentDate
)
}
@@ -27,12 +35,16 @@
ReleaseAssets.filter(x => x.byTag(owner, repository, tag)).list
}
- def getReleaseAssetsMap(owner: String, repository: String)(implicit s: Session): Map[ReleaseTag, Seq[ReleaseAsset]] = {
+ def getReleaseAssetsMap(owner: String, repository: String)(
+ implicit s: Session
+ ): Map[ReleaseTag, Seq[ReleaseAsset]] = {
val releases = getReleases(owner, repository)
releases.map(rel => (rel -> getReleaseAssets(owner, repository, rel.tag))).toMap
}
- def getReleaseAsset(owner: String, repository: String, tag: String, fileId: String)(implicit s: Session): Option[ReleaseAsset] = {
+ def getReleaseAsset(owner: String, repository: String, tag: String, fileId: String)(
+ implicit s: Session
+ ): Option[ReleaseAsset] = {
ReleaseAssets.filter(x => x.byPrimaryKey(owner, repository, tag, fileId)) firstOption
}
@@ -40,17 +52,23 @@
ReleaseAssets.filter(x => x.byTag(owner, repository, tag)) delete
}
- def createRelease(owner: String, repository: String, name: String, content: Option[String], tag: String,
- loginAccount: Account)(implicit context: Context, s: Session): Int = {
+ def createRelease(
+ owner: String,
+ repository: String,
+ name: String,
+ content: Option[String],
+ tag: String,
+ loginAccount: Account
+ )(implicit context: Context, s: Session): Int = {
ReleaseTags insert ReleaseTag(
- userName = owner,
+ userName = owner,
repositoryName = repository,
- name = name,
- tag = tag,
- author = loginAccount.userName,
- content = content,
+ name = name,
+ tag = tag,
+ author = loginAccount.userName,
+ content = content,
registeredDate = currentDate,
- updatedDate = currentDate
+ updatedDate = currentDate
)
}
@@ -73,11 +91,15 @@
// else None
// }
- def updateRelease(owner: String, repository: String, tag: String, title: String, content: Option[String])(implicit s: Session): Int = {
+ def updateRelease(owner: String, repository: String, tag: String, title: String, content: Option[String])(
+ implicit s: Session
+ ): Int = {
ReleaseTags
- .filter (_.byPrimaryKey(owner, repository, tag))
- .map { t => (t.name, t.content, t.updatedDate) }
- .update (title, content, currentDate)
+ .filter(_.byPrimaryKey(owner, repository, tag))
+ .map { t =>
+ (t.name, t.content, t.updatedDate)
+ }
+ .update(title, content, currentDate)
}
def deleteRelease(owner: String, repository: String, tag: String)(implicit s: Session): Unit = {
diff --git a/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala b/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala
index 88a777d..8e7a662 100644
--- a/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala
+++ b/src/main/scala/gitbucket/core/service/RepositoryCreationService.scala
@@ -33,7 +33,7 @@
def endCreation(owner: String, repository: String, error: Option[String]): Unit = {
error match {
- case None => Creating.remove(s"${owner}/${repository}")
+ case None => Creating.remove(s"${owner}/${repository}")
case Some(error) => Creating.put(s"${owner}/${repository}", Some(error))
}
}
@@ -45,15 +45,33 @@
}
trait RepositoryCreationService {
- self: AccountService with RepositoryService with LabelsService with WikiService with ActivityService with PrioritiesService =>
+ self: AccountService
+ with RepositoryService
+ with LabelsService
+ with WikiService
+ with ActivityService
+ with PrioritiesService =>
- def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String],
- isPrivate: Boolean, createReadme: Boolean): Future[Unit] = {
+ def createRepository(
+ loginAccount: Account,
+ owner: String,
+ name: String,
+ description: Option[String],
+ isPrivate: Boolean,
+ createReadme: Boolean
+ ): Future[Unit] = {
createRepository(loginAccount, owner, name, description, isPrivate, if (createReadme) "README" else "EMPTY", None)
}
- def createRepository(loginAccount: Account, owner: String, name: String, description: Option[String],
- isPrivate: Boolean, initOption: String, sourceUrl: Option[String]): Future[Unit] = Future {
+ def createRepository(
+ loginAccount: Account,
+ owner: String,
+ name: String,
+ description: Option[String],
+ isPrivate: Boolean,
+ initOption: String,
+ sourceUrl: Option[String]
+ ): Future[Unit] = Future {
RepositoryCreationService.startCreation(owner, name)
try {
Database() withTransaction { implicit session =>
@@ -68,7 +86,6 @@
}
} else None
-
// Insert to the database at first
insertRepository(name, owner, description, isPrivate)
@@ -106,13 +123,26 @@
"===============\n"
}
- builder.add(JGitUtil.createDirCacheEntry("README.md", FileMode.REGULAR_FILE,
- inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
+ builder.add(
+ JGitUtil.createDirCacheEntry(
+ "README.md",
+ FileMode.REGULAR_FILE,
+ inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))
+ )
+ )
}
builder.finish()
- JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
- Constants.HEAD, loginAccount.fullName, loginAccount.mailAddress, "Initial commit")
+ JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headId,
+ builder.getDirCache.writeTree(inserter),
+ Constants.HEAD,
+ loginAccount.fullName,
+ loginAccount.mailAddress,
+ "Initial commit"
+ )
}
}
@@ -165,8 +195,9 @@
// Set default collaborators for the private fork
if (repository.repository.isPrivate) {
// Copy collaborators from the source repository
- getCollaborators(repository.owner, repository.name).foreach { case (collaborator, _) =>
- addCollaborator(accountName, repository.name, collaborator.collaboratorName, collaborator.role)
+ getCollaborators(repository.owner, repository.name).foreach {
+ case (collaborator, _) =>
+ addCollaborator(accountName, repository.name, collaborator.collaboratorName, collaborator.role)
}
// Register an owner of the source repository as a collaborator
addCollaborator(accountName, repository.name, repository.owner, Role.ADMIN.name)
@@ -180,11 +211,14 @@
// clone repository actually
JGitUtil.cloneRepository(
getRepositoryDir(repository.owner, repository.name),
- FileUtil.deleteIfExists(getRepositoryDir(accountName, repository.name)))
+ FileUtil.deleteIfExists(getRepositoryDir(accountName, repository.name))
+ )
// Create Wiki repository
- JGitUtil.cloneRepository(getWikiRepositoryDir(repository.owner, repository.name),
- FileUtil.deleteIfExists(getWikiRepositoryDir(accountName, repository.name)))
+ JGitUtil.cloneRepository(
+ getWikiRepositoryDir(repository.owner, repository.name),
+ FileUtil.deleteIfExists(getWikiRepositoryDir(accountName, repository.name))
+ )
// Copy LFS files
val lfsDir = getLfsDir(repository.owner, repository.name)
@@ -216,10 +250,36 @@
}
def insertDefaultPriorities(userName: String, repositoryName: String)(implicit s: Session): Unit = {
- createPriority(userName, repositoryName, "highest", Some("All defects at this priority must be fixed before any public product is delivered."), "fc2929")
- createPriority(userName, repositoryName, "very high", Some("Issues must be addressed before a final product is delivered."), "fc5629")
- createPriority(userName, repositoryName, "high", Some("Issues should be addressed before a final product is delivered. If the issue cannot be resolved before delivery, it should be prioritized for the next release."), "fc9629")
- createPriority(userName, repositoryName, "important", Some("Issues can be shipped with a final product, but should be reviewed before the next release."), "fccd29")
+ createPriority(
+ userName,
+ repositoryName,
+ "highest",
+ Some("All defects at this priority must be fixed before any public product is delivered."),
+ "fc2929"
+ )
+ createPriority(
+ userName,
+ repositoryName,
+ "very high",
+ Some("Issues must be addressed before a final product is delivered."),
+ "fc5629"
+ )
+ createPriority(
+ userName,
+ repositoryName,
+ "high",
+ Some(
+ "Issues should be addressed before a final product is delivered. If the issue cannot be resolved before delivery, it should be prioritized for the next release."
+ ),
+ "fc9629"
+ )
+ createPriority(
+ userName,
+ repositoryName,
+ "important",
+ Some("Issues can be shipped with a final product, but should be reviewed before the next release."),
+ "fccd29"
+ )
createPriority(userName, repositoryName, "default", Some("Default."), "acacac")
setDefaultPriority(userName, repositoryName, getPriority(userName, repositoryName, "default").map(_.priorityId))
diff --git a/src/main/scala/gitbucket/core/service/RepositorySearchService.scala b/src/main/scala/gitbucket/core/service/RepositorySearchService.scala
index 11be724..4c53792 100644
--- a/src/main/scala/gitbucket/core/service/RepositorySearchService.scala
+++ b/src/main/scala/gitbucket/core/service/RepositorySearchService.scala
@@ -17,69 +17,72 @@
def countIssues(owner: String, repository: String, query: String)(implicit session: Session): Int =
searchIssuesByKeyword(owner, repository, query).length
- def searchIssues(owner: String, repository: String, query: String)(implicit session: Session): List[IssueSearchResult] =
- searchIssuesByKeyword(owner, repository, query).map { case (issue, commentCount, content) =>
- IssueSearchResult(
- issue.issueId,
- issue.isPullRequest,
- issue.title,
- issue.openedUserName,
- issue.registeredDate,
- commentCount,
- getHighlightText(content, query)._1)
+ def searchIssues(owner: String, repository: String, query: String)(
+ implicit session: Session
+ ): List[IssueSearchResult] =
+ searchIssuesByKeyword(owner, repository, query).map {
+ case (issue, commentCount, content) =>
+ IssueSearchResult(
+ issue.issueId,
+ issue.isPullRequest,
+ issue.title,
+ issue.openedUserName,
+ issue.registeredDate,
+ commentCount,
+ getHighlightText(content, query)._1
+ )
}
def countFiles(owner: String, repository: String, query: String): Int =
- using(Git.open(getRepositoryDir(owner, repository))){ git =>
- if(JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
+ using(Git.open(getRepositoryDir(owner, repository))) { git =>
+ if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
}
def searchFiles(owner: String, repository: String, query: String): List[FileSearchResult] =
- using(Git.open(getRepositoryDir(owner, repository))){ git =>
- if(JGitUtil.isEmpty(git)){
+ using(Git.open(getRepositoryDir(owner, repository))) { git =>
+ if (JGitUtil.isEmpty(git)) {
Nil
} else {
val files = searchRepositoryFiles(git, query)
val commits = JGitUtil.getLatestCommitFromPaths(git, files.map(_._1), "HEAD")
- files.map { case (path, text) =>
- val (highlightText, lineNumber) = getHighlightText(text, query)
- FileSearchResult(
- path,
- commits(path).getCommitterIdent.getWhen,
- highlightText,
- lineNumber)
+ files.map {
+ case (path, text) =>
+ val (highlightText, lineNumber) = getHighlightText(text, query)
+ FileSearchResult(path, commits(path).getCommitterIdent.getWhen, highlightText, lineNumber)
}
}
}
def countWikiPages(owner: String, repository: String, query: String): Int =
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- if(JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ if (JGitUtil.isEmpty(git)) 0 else searchRepositoryFiles(git, query).length
}
def searchWikiPages(owner: String, repository: String, query: String): List[FileSearchResult] =
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- if(JGitUtil.isEmpty(git)){
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ if (JGitUtil.isEmpty(git)) {
Nil
} else {
val files = searchRepositoryFiles(git, query)
val commits = JGitUtil.getLatestCommitFromPaths(git, files.map(_._1), "HEAD")
- files.map { case (path, text) =>
- val (highlightText, lineNumber) = getHighlightText(text, query)
- FileSearchResult(
- path.stripSuffix(".md"),
- commits(path).getCommitterIdent.getWhen,
- highlightText,
- lineNumber)
+ files.map {
+ case (path, text) =>
+ val (highlightText, lineNumber) = getHighlightText(text, query)
+ FileSearchResult(
+ path.stripSuffix(".md"),
+ commits(path).getCommitterIdent.getWhen,
+ highlightText,
+ lineNumber
+ )
}
}
}
def searchRepositoryFiles(git: Git, query: String): List[(String, String)] = {
- val revWalk = new RevWalk(git.getRepository)
- val objectId = git.getRepository.resolve("HEAD")
+ val revWalk = new RevWalk(git.getRepository)
+ val objectId = git.getRepository.resolve("HEAD")
val revCommit = revWalk.parseCommit(objectId)
- val treeWalk = new TreeWalk(git.getRepository)
+ val treeWalk = new TreeWalk(git.getRepository)
treeWalk.setRecursive(true)
treeWalk.addTree(revCommit.getTree)
@@ -88,13 +91,13 @@
while (treeWalk.next()) {
val mode = treeWalk.getFileMode(0)
- if(mode == FileMode.REGULAR_FILE || mode == FileMode.EXECUTABLE_FILE){
+ if (mode == FileMode.REGULAR_FILE || mode == FileMode.EXECUTABLE_FILE) {
JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).foreach { bytes =>
- if(FileUtil.isText(bytes)){
- val text = StringUtil.convertFromByteArray(bytes)
+ if (FileUtil.isText(bytes)) {
+ val text = StringUtil.convertFromByteArray(bytes)
val lowerText = text.toLowerCase
- val indices = keywords.map(lowerText.indexOf _)
- if(!indices.exists(_ < 0)){
+ val indices = keywords.map(lowerText.indexOf _)
+ if (!indices.exists(_ < 0)) {
list.append((treeWalk.getPathString, text))
}
}
@@ -111,28 +114,29 @@
object RepositorySearchService {
- val CodeLimit = 10
+ val CodeLimit = 10
val IssueLimit = 10
def getHighlightText(content: String, query: String): (String, Int) = {
- val keywords = StringUtil.splitWords(query.toLowerCase)
+ val keywords = StringUtil.splitWords(query.toLowerCase)
val lowerText = content.toLowerCase
- val indices = keywords.map(lowerText.indexOf _)
+ val indices = keywords.map(lowerText.indexOf _)
- if(!indices.exists(_ < 0)){
+ if (!indices.exists(_ < 0)) {
val lineNumber = content.substring(0, indices.min).split("\n").size - 1
- val highlightText = StringUtil.escapeHtml(content.split("\n").drop(lineNumber).take(5).mkString("\n"))
- .replaceAll("(?i)(" + keywords.map("\\Q" + _ + "\\E").mkString("|") + ")",
- "$1")
+ val highlightText = StringUtil
+ .escapeHtml(content.split("\n").drop(lineNumber).take(5).mkString("\n"))
+ .replaceAll(
+ "(?i)(" + keywords.map("\\Q" + _ + "\\E").mkString("|") + ")",
+ "$1"
+ )
(highlightText, lineNumber + 1)
} else {
(content.split("\n").take(5).mkString("\n"), 1)
}
}
- case class SearchResult(
- files : List[(String, String)],
- issues: List[(Issue, Int, String)])
+ case class SearchResult(files: List[(String, String)], issues: List[(Issue, Int, String)])
case class IssueSearchResult(
issueId: Int,
@@ -141,12 +145,14 @@
openedUserName: String,
registeredDate: java.util.Date,
commentCount: Int,
- highlightText: String)
+ highlightText: String
+ )
case class FileSearchResult(
- path: String,
- lastModified: java.util.Date,
- highlightText: String,
- highlightLineNumber: Int)
+ path: String,
+ lastModified: java.util.Date,
+ highlightText: String,
+ highlightLineNumber: Int
+ )
}
diff --git a/src/main/scala/gitbucket/core/service/RepositoryService.scala b/src/main/scala/gitbucket/core/service/RepositoryService.scala
index f8ddf17..912af55 100644
--- a/src/main/scala/gitbucket/core/service/RepositoryService.scala
+++ b/src/main/scala/gitbucket/core/service/RepositoryService.scala
@@ -23,188 +23,276 @@
* @param originRepositoryName specify for the forked repository. (default is None)
* @param originUserName specify for the forked repository. (default is None)
*/
- def insertRepository(repositoryName: String, userName: String, description: Option[String], isPrivate: Boolean,
- originRepositoryName: Option[String] = None, originUserName: Option[String] = None,
- parentRepositoryName: Option[String] = None, parentUserName: Option[String] = None)
- (implicit s: Session): Unit = {
+ def insertRepository(
+ repositoryName: String,
+ userName: String,
+ description: Option[String],
+ isPrivate: Boolean,
+ originRepositoryName: Option[String] = None,
+ originUserName: Option[String] = None,
+ parentRepositoryName: Option[String] = None,
+ parentUserName: Option[String] = None
+ )(implicit s: Session): Unit = {
Repositories insert
Repository(
- userName = userName,
- repositoryName = repositoryName,
- isPrivate = isPrivate,
- description = description,
- defaultBranch = "master",
- registeredDate = currentDate,
- updatedDate = currentDate,
- lastActivityDate = currentDate,
- originUserName = originUserName,
+ userName = userName,
+ repositoryName = repositoryName,
+ isPrivate = isPrivate,
+ description = description,
+ defaultBranch = "master",
+ registeredDate = currentDate,
+ updatedDate = currentDate,
+ lastActivityDate = currentDate,
+ originUserName = originUserName,
originRepositoryName = originRepositoryName,
- parentUserName = parentUserName,
+ parentUserName = parentUserName,
parentRepositoryName = parentRepositoryName,
- options = RepositoryOptions(
- issuesOption = "PUBLIC", // TODO DISABLE for the forked repository?
- externalIssuesUrl = None,
- wikiOption = "PUBLIC", // TODO DISABLE for the forked repository?
- externalWikiUrl = None,
- allowFork = true,
- mergeOptions = "merge-commit,squash,rebase",
- defaultMergeOption = "merge-commit"
+ options = RepositoryOptions(
+ issuesOption = "PUBLIC", // TODO DISABLE for the forked repository?
+ externalIssuesUrl = None,
+ wikiOption = "PUBLIC", // TODO DISABLE for the forked repository?
+ externalWikiUrl = None,
+ allowFork = true,
+ mergeOptions = "merge-commit,squash,rebase",
+ defaultMergeOption = "merge-commit"
)
)
IssueId insert (userName, repositoryName, 0)
}
- def renameRepository(oldUserName: String, oldRepositoryName: String, newUserName: String, newRepositoryName: String)
- (implicit s: Session): Unit = {
+ def renameRepository(oldUserName: String, oldRepositoryName: String, newUserName: String, newRepositoryName: String)(
+ implicit s: Session
+ ): Unit = {
getAccountByUserName(newUserName).foreach { account =>
- (Repositories filter { t => t.byRepository(oldUserName, oldRepositoryName) } firstOption).map { repository =>
+ (Repositories filter { t =>
+ t.byRepository(oldUserName, oldRepositoryName)
+ } firstOption).map { repository =>
Repositories insert repository.copy(userName = newUserName, repositoryName = newRepositoryName)
- val webHooks = RepositoryWebHooks .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val webHookEvents = RepositoryWebHookEvents.filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val milestones = Milestones .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val issueId = IssueId .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val issues = Issues .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val pullRequests = PullRequests .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val labels = Labels .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val priorities = Priorities .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val issueComments = IssueComments .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val issueLabels = IssueLabels .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val commitComments = CommitComments .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val commitStatuses = CommitStatuses .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val collaborators = Collaborators .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val protectedBranches = ProtectedBranches .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val protectedBranchContexts = ProtectedBranchContexts.filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val deployKeys = DeployKeys .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val releases = ReleaseTags .filter(_.byRepository(oldUserName, oldRepositoryName)).list
- val releaseAssets = ReleaseAssets .filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val webHooks = RepositoryWebHooks.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val webHookEvents = RepositoryWebHookEvents.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val milestones = Milestones.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val issueId = IssueId.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val issues = Issues.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val pullRequests = PullRequests.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val labels = Labels.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val priorities = Priorities.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val issueComments = IssueComments.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val issueLabels = IssueLabels.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val commitComments = CommitComments.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val commitStatuses = CommitStatuses.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val collaborators = Collaborators.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val protectedBranches = ProtectedBranches.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val protectedBranchContexts =
+ ProtectedBranchContexts.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val deployKeys = DeployKeys.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val releases = ReleaseTags.filter(_.byRepository(oldUserName, oldRepositoryName)).list
+ val releaseAssets = ReleaseAssets.filter(_.byRepository(oldUserName, oldRepositoryName)).list
- Repositories.filter { t =>
- (t.originUserName === oldUserName.bind) && (t.originRepositoryName === oldRepositoryName.bind)
- }.map { t => t.originUserName -> t.originRepositoryName }.update(newUserName, newRepositoryName)
+ Repositories
+ .filter { t =>
+ (t.originUserName === oldUserName.bind) && (t.originRepositoryName === oldRepositoryName.bind)
+ }
+ .map { t =>
+ t.originUserName -> t.originRepositoryName
+ }
+ .update(newUserName, newRepositoryName)
- Repositories.filter { t =>
- (t.parentUserName === oldUserName.bind) && (t.parentRepositoryName === oldRepositoryName.bind)
- }.map { t => t.parentUserName -> t.parentRepositoryName }.update(newUserName, newRepositoryName)
+ Repositories
+ .filter { t =>
+ (t.parentUserName === oldUserName.bind) && (t.parentRepositoryName === oldRepositoryName.bind)
+ }
+ .map { t =>
+ t.parentUserName -> t.parentRepositoryName
+ }
+ .update(newUserName, newRepositoryName)
// Updates activity fk before deleting repository because activity is sorted by activityId
// and it can't be changed by deleting-and-inserting record.
Activities.filter(_.byRepository(oldUserName, oldRepositoryName)).list.foreach { activity =>
- Activities.filter(_.activityId === activity.activityId.bind)
- .map(x => (x.userName, x.repositoryName)).update(newUserName, newRepositoryName)
+ Activities
+ .filter(_.activityId === activity.activityId.bind)
+ .map(x => (x.userName, x.repositoryName))
+ .update(newUserName, newRepositoryName)
}
deleteRepository(oldUserName, oldRepositoryName)
- RepositoryWebHooks .insertAll(webHooks .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- RepositoryWebHookEvents.insertAll(webHookEvents .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- Milestones .insertAll(milestones .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- Priorities .insertAll(priorities .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- IssueId .insertAll(issueId .map(_.copy(_1 = newUserName, _2 = newRepositoryName)) :_*)
+ RepositoryWebHooks.insertAll(
+ webHooks.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ RepositoryWebHookEvents.insertAll(
+ webHookEvents.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ Milestones.insertAll(milestones.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ Priorities.insertAll(priorities.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ IssueId.insertAll(issueId.map(_.copy(_1 = newUserName, _2 = newRepositoryName)): _*)
val newMilestones = Milestones.filter(_.byRepository(newUserName, newRepositoryName)).list
val newPriorities = Priorities.filter(_.byRepository(newUserName, newRepositoryName)).list
- Issues.insertAll(issues.map { x => x.copy(
- userName = newUserName,
- repositoryName = newRepositoryName,
- milestoneId = x.milestoneId.map { id =>
- newMilestones.find(_.title == milestones.find(_.milestoneId == id).get.title).get.milestoneId
- },
- priorityId = x.priorityId.map { id =>
- newPriorities.find(_.priorityName == priorities.find(_.priorityId == id).get.priorityName).get.priorityId
- }
- )} :_*)
+ Issues.insertAll(issues.map { x =>
+ x.copy(
+ userName = newUserName,
+ repositoryName = newRepositoryName,
+ milestoneId = x.milestoneId.map { id =>
+ newMilestones.find(_.title == milestones.find(_.milestoneId == id).get.title).get.milestoneId
+ },
+ priorityId = x.priorityId.map { id =>
+ newPriorities.find(_.priorityName == priorities.find(_.priorityId == id).get.priorityName).get.priorityId
+ }
+ )
+ }: _*)
- PullRequests .insertAll(pullRequests .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- IssueComments .insertAll(issueComments .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- Labels .insertAll(labels .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- CommitComments .insertAll(commitComments.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- CommitStatuses .insertAll(commitStatuses.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- ProtectedBranches .insertAll(protectedBranches.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- ProtectedBranchContexts.insertAll(protectedBranchContexts.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- DeployKeys .insertAll(deployKeys .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- ReleaseTags .insertAll(releases .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
- ReleaseAssets .insertAll(releaseAssets .map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
+ PullRequests.insertAll(pullRequests.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ IssueComments.insertAll(
+ issueComments.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ Labels.insertAll(labels.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ CommitComments.insertAll(
+ commitComments.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ CommitStatuses.insertAll(
+ commitStatuses.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ ProtectedBranches.insertAll(
+ protectedBranches.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ ProtectedBranchContexts.insertAll(
+ protectedBranchContexts.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
+ DeployKeys.insertAll(deployKeys.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ ReleaseTags.insertAll(releases.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*)
+ ReleaseAssets.insertAll(
+ releaseAssets.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
// Update source repository of pull requests
- PullRequests.filter { t =>
- (t.requestUserName === oldUserName.bind) && (t.requestRepositoryName === oldRepositoryName.bind)
- }.map { t => t.requestUserName -> t.requestRepositoryName }.update(newUserName, newRepositoryName)
+ PullRequests
+ .filter { t =>
+ (t.requestUserName === oldUserName.bind) && (t.requestRepositoryName === oldRepositoryName.bind)
+ }
+ .map { t =>
+ t.requestUserName -> t.requestRepositoryName
+ }
+ .update(newUserName, newRepositoryName)
// Convert labelId
val oldLabelMap = labels.map(x => (x.labelId, x.labelName)).toMap
- val newLabelMap = Labels.filter(_.byRepository(newUserName, newRepositoryName)).map(x => (x.labelName, x.labelId)).list.toMap
- IssueLabels.insertAll(issueLabels.map(x => x.copy(
- labelId = newLabelMap(oldLabelMap(x.labelId)),
- userName = newUserName,
- repositoryName = newRepositoryName
- )) :_*)
+ val newLabelMap =
+ Labels.filter(_.byRepository(newUserName, newRepositoryName)).map(x => (x.labelName, x.labelId)).list.toMap
+ IssueLabels.insertAll(
+ issueLabels.map(
+ x =>
+ x.copy(
+ labelId = newLabelMap(oldLabelMap(x.labelId)),
+ userName = newUserName,
+ repositoryName = newRepositoryName
+ )
+ ): _*
+ )
// TODO Drop transferred owner from collaborators?
- Collaborators.insertAll(collaborators.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
+ Collaborators.insertAll(
+ collaborators.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)): _*
+ )
// Update activity messages
- Activities.filter { t =>
- (t.message like s"%:${oldUserName}/${oldRepositoryName}]%") ||
- (t.message like s"%:${oldUserName}/${oldRepositoryName}#%") ||
- (t.message like s"%:${oldUserName}/${oldRepositoryName}@%")
- }.map { t => t.activityId -> t.message }.list.foreach { case (activityId, message) =>
- Activities.filter(_.activityId === activityId.bind).map(_.message).update(
- message
- .replace(s"[repo:${oldUserName}/${oldRepositoryName}]" ,s"[repo:${newUserName}/${newRepositoryName}]")
- .replace(s"[branch:${oldUserName}/${oldRepositoryName}#" ,s"[branch:${newUserName}/${newRepositoryName}#")
- .replace(s"[tag:${oldUserName}/${oldRepositoryName}#" ,s"[tag:${newUserName}/${newRepositoryName}#")
- .replace(s"[pullreq:${oldUserName}/${oldRepositoryName}#",s"[pullreq:${newUserName}/${newRepositoryName}#")
- .replace(s"[issue:${oldUserName}/${oldRepositoryName}#" ,s"[issue:${newUserName}/${newRepositoryName}#")
- .replace(s"[commit:${oldUserName}/${oldRepositoryName}@" ,s"[commit:${newUserName}/${newRepositoryName}@")
- )
- }
+ Activities
+ .filter { t =>
+ (t.message like s"%:${oldUserName}/${oldRepositoryName}]%") ||
+ (t.message like s"%:${oldUserName}/${oldRepositoryName}#%") ||
+ (t.message like s"%:${oldUserName}/${oldRepositoryName}@%")
+ }
+ .map { t =>
+ t.activityId -> t.message
+ }
+ .list
+ .foreach {
+ case (activityId, message) =>
+ Activities
+ .filter(_.activityId === activityId.bind)
+ .map(_.message)
+ .update(
+ message
+ .replace(
+ s"[repo:${oldUserName}/${oldRepositoryName}]",
+ s"[repo:${newUserName}/${newRepositoryName}]"
+ )
+ .replace(
+ s"[branch:${oldUserName}/${oldRepositoryName}#",
+ s"[branch:${newUserName}/${newRepositoryName}#"
+ )
+ .replace(s"[tag:${oldUserName}/${oldRepositoryName}#", s"[tag:${newUserName}/${newRepositoryName}#")
+ .replace(
+ s"[pullreq:${oldUserName}/${oldRepositoryName}#",
+ s"[pullreq:${newUserName}/${newRepositoryName}#"
+ )
+ .replace(
+ s"[issue:${oldUserName}/${oldRepositoryName}#",
+ s"[issue:${newUserName}/${newRepositoryName}#"
+ )
+ .replace(
+ s"[commit:${oldUserName}/${oldRepositoryName}@",
+ s"[commit:${newUserName}/${newRepositoryName}@"
+ )
+ )
+ }
}
}
}
def deleteRepository(userName: String, repositoryName: String)(implicit s: Session): Unit = {
- Activities .filter(_.byRepository(userName, repositoryName)).delete
- Collaborators .filter(_.byRepository(userName, repositoryName)).delete
- CommitComments .filter(_.byRepository(userName, repositoryName)).delete
- IssueLabels .filter(_.byRepository(userName, repositoryName)).delete
- Labels .filter(_.byRepository(userName, repositoryName)).delete
- IssueComments .filter(_.byRepository(userName, repositoryName)).delete
- PullRequests .filter(_.byRepository(userName, repositoryName)).delete
- Issues .filter(_.byRepository(userName, repositoryName)).delete
- Priorities .filter(_.byRepository(userName, repositoryName)).delete
- IssueId .filter(_.byRepository(userName, repositoryName)).delete
- Milestones .filter(_.byRepository(userName, repositoryName)).delete
- RepositoryWebHooks .filter(_.byRepository(userName, repositoryName)).delete
- RepositoryWebHookEvents .filter(_.byRepository(userName, repositoryName)).delete
- DeployKeys .filter(_.byRepository(userName, repositoryName)).delete
- ReleaseAssets .filter(_.byRepository(userName, repositoryName)).delete
- ReleaseTags .filter(_.byRepository(userName, repositoryName)).delete
- Repositories .filter(_.byRepository(userName, repositoryName)).delete
+ Activities.filter(_.byRepository(userName, repositoryName)).delete
+ Collaborators.filter(_.byRepository(userName, repositoryName)).delete
+ CommitComments.filter(_.byRepository(userName, repositoryName)).delete
+ IssueLabels.filter(_.byRepository(userName, repositoryName)).delete
+ Labels.filter(_.byRepository(userName, repositoryName)).delete
+ IssueComments.filter(_.byRepository(userName, repositoryName)).delete
+ PullRequests.filter(_.byRepository(userName, repositoryName)).delete
+ Issues.filter(_.byRepository(userName, repositoryName)).delete
+ Priorities.filter(_.byRepository(userName, repositoryName)).delete
+ IssueId.filter(_.byRepository(userName, repositoryName)).delete
+ Milestones.filter(_.byRepository(userName, repositoryName)).delete
+ RepositoryWebHooks.filter(_.byRepository(userName, repositoryName)).delete
+ RepositoryWebHookEvents.filter(_.byRepository(userName, repositoryName)).delete
+ DeployKeys.filter(_.byRepository(userName, repositoryName)).delete
+ ReleaseAssets.filter(_.byRepository(userName, repositoryName)).delete
+ ReleaseTags.filter(_.byRepository(userName, repositoryName)).delete
+ Repositories.filter(_.byRepository(userName, repositoryName)).delete
// Update ORIGIN_USER_NAME and ORIGIN_REPOSITORY_NAME
Repositories
- .filter { x => (x.originUserName === userName.bind) && (x.originRepositoryName === repositoryName.bind) }
- .map { x => (x.userName, x.repositoryName) }
+ .filter { x =>
+ (x.originUserName === userName.bind) && (x.originRepositoryName === repositoryName.bind)
+ }
+ .map { x =>
+ (x.userName, x.repositoryName)
+ }
.list
- .foreach { case (userName, repositoryName) =>
- Repositories
- .filter(_.byRepository(userName, repositoryName))
- .map(x => (x.originUserName?, x.originRepositoryName?))
- .update(None, None)
+ .foreach {
+ case (userName, repositoryName) =>
+ Repositories
+ .filter(_.byRepository(userName, repositoryName))
+ .map(x => (x.originUserName ?, x.originRepositoryName ?))
+ .update(None, None)
}
// Update PARENT_USER_NAME and PARENT_REPOSITORY_NAME
Repositories
- .filter { x => (x.parentUserName === userName.bind) && (x.parentRepositoryName === repositoryName.bind) }
- .map { x => (x.userName, x.repositoryName) }
+ .filter { x =>
+ (x.parentUserName === userName.bind) && (x.parentRepositoryName === repositoryName.bind)
+ }
+ .map { x =>
+ (x.userName, x.repositoryName)
+ }
.list
- .foreach { case (userName, repositoryName) =>
- Repositories
- .filter(_.byRepository(userName, repositoryName))
- .map(x => (x.parentUserName?, x.parentRepositoryName?))
- .update(None, None)
+ .foreach {
+ case (userName, repositoryName) =>
+ Repositories
+ .filter(_.byRepository(userName, repositoryName))
+ .map(x => (x.parentUserName ?, x.parentRepositoryName ?))
+ .update(None, None)
}
}
@@ -215,7 +303,7 @@
* @return the list of repository names
*/
def getRepositoryNamesOfUser(userName: String)(implicit s: Session): List[String] =
- Repositories filter(_.userName === userName.bind) map (_.repositoryName) list
+ Repositories filter (_.userName === userName.bind) map (_.repositoryName) list
/**
* Returns the specified repository information.
@@ -225,11 +313,16 @@
* @return the repository information
*/
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
- val issues = Issues.filter { t =>
- t.byRepository(repository.userName, repository.repositoryName) && (t.closed === false.bind)
- }.map(_.pullRequest).list
+ val issues = Issues
+ .filter { t =>
+ t.byRepository(repository.userName, repository.repositoryName) && (t.closed === false.bind)
+ }
+ .map(_.pullRequest)
+ .list
new RepositoryInfo(
JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName),
@@ -240,7 +333,8 @@
repository.originUserName.getOrElse(repository.userName),
repository.originRepositoryName.getOrElse(repository.repositoryName)
),
- getRepositoryManagers(repository.userName))
+ getRepositoryManagers(repository.userName)
+ )
}
}
@@ -252,45 +346,66 @@
* @return the repository information list
*/
def getAllRepositories(userName: String)(implicit s: Session): List[(String, String)] = {
- Repositories.filter { t1 =>
- (t1.isPrivate === false.bind) ||
- (t1.userName === userName.bind) || (t1.userName in (GroupMembers.filter(_.userName === userName.bind).map(_.groupName))) ||
- (Collaborators.filter { t2 => t2.byRepository(t1.userName, t1.repositoryName) &&
- ((t2.collaboratorName === userName.bind) || (t2.collaboratorName in GroupMembers.filter(_.userName === userName.bind).map(_.groupName)))
- } exists)
- }.sortBy(_.lastActivityDate desc).map{ t =>
- (t.userName, t.repositoryName)
- }.list
+ Repositories
+ .filter { t1 =>
+ (t1.isPrivate === false.bind) ||
+ (t1.userName === userName.bind) || (t1.userName in (GroupMembers
+ .filter(_.userName === userName.bind)
+ .map(_.groupName))) ||
+ (Collaborators.filter { t2 =>
+ t2.byRepository(t1.userName, t1.repositoryName) &&
+ ((t2.collaboratorName === userName.bind) || (t2.collaboratorName in GroupMembers
+ .filter(_.userName === userName.bind)
+ .map(_.groupName)))
+ } exists)
+ }
+ .sortBy(_.lastActivityDate desc)
+ .map { t =>
+ (t.userName, t.repositoryName)
+ }
+ .list
}
- def getUserRepositories(userName: String, withoutPhysicalInfo: Boolean = false)(implicit s: Session): List[RepositoryInfo] = {
- Repositories.filter { t1 =>
- (t1.userName === userName.bind) || (t1.userName in (GroupMembers.filter(_.userName === userName.bind).map(_.groupName))) ||
- (Collaborators.filter { t2 => t2.byRepository(t1.userName, t1.repositoryName) &&
- ((t2.collaboratorName === userName.bind) || (t2.collaboratorName in GroupMembers.filter(_.userName === userName.bind).map(_.groupName)))
- } exists)
- }.sortBy(_.lastActivityDate desc).list.map{ repository =>
- new RepositoryInfo(
- if(withoutPhysicalInfo){
- new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
- } else {
- JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
- },
- repository,
- if(withoutPhysicalInfo){
- -1
- } else {
- getForkedCount(
- repository.originUserName.getOrElse(repository.userName),
- repository.originRepositoryName.getOrElse(repository.repositoryName)
- )
- },
- if(withoutPhysicalInfo){
- Nil
- } else {
- getRepositoryManagers(repository.userName)
- })
- }
+ def getUserRepositories(userName: String, withoutPhysicalInfo: Boolean = false)(
+ implicit s: Session
+ ): List[RepositoryInfo] = {
+ Repositories
+ .filter { t1 =>
+ (t1.userName === userName.bind) || (t1.userName in (GroupMembers
+ .filter(_.userName === userName.bind)
+ .map(_.groupName))) ||
+ (Collaborators.filter { t2 =>
+ t2.byRepository(t1.userName, t1.repositoryName) &&
+ ((t2.collaboratorName === userName.bind) || (t2.collaboratorName in GroupMembers
+ .filter(_.userName === userName.bind)
+ .map(_.groupName)))
+ } exists)
+ }
+ .sortBy(_.lastActivityDate desc)
+ .list
+ .map { repository =>
+ new RepositoryInfo(
+ if (withoutPhysicalInfo) {
+ new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
+ } else {
+ JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
+ },
+ repository,
+ if (withoutPhysicalInfo) {
+ -1
+ } else {
+ getForkedCount(
+ repository.originUserName.getOrElse(repository.userName),
+ repository.originRepositoryName.getOrElse(repository.repositoryName)
+ )
+ },
+ if (withoutPhysicalInfo) {
+ Nil
+ } else {
+ getRepositoryManagers(repository.userName)
+ }
+ )
+ }
}
/**
@@ -303,53 +418,63 @@
* branches and tags
* @return the repository information which is sorted in descending order of lastActivityDate.
*/
- def getVisibleRepositories(loginAccount: Option[Account], repositoryUserName: Option[String] = None,
- withoutPhysicalInfo: Boolean = false)
- (implicit s: Session): List[RepositoryInfo] = {
+ def getVisibleRepositories(
+ loginAccount: Option[Account],
+ repositoryUserName: Option[String] = None,
+ withoutPhysicalInfo: Boolean = false
+ )(implicit s: Session): List[RepositoryInfo] = {
(loginAccount match {
// for Administrators
- case Some(x) if(x.isAdmin) => Repositories
+ case Some(x) if (x.isAdmin) => Repositories
// for Normal Users
- case Some(x) if(!x.isAdmin) =>
+ case Some(x) if (!x.isAdmin) =>
Repositories filter { t =>
(t.isPrivate === false.bind) || (t.userName === x.userName) ||
(t.userName in GroupMembers.filter(_.userName === x.userName.bind).map(_.groupName)) ||
(Collaborators.filter { t2 =>
t2.byRepository(t.userName, t.repositoryName) &&
- ((t2.collaboratorName === x.userName.bind) || (t2.collaboratorName in GroupMembers.filter(_.userName === x.userName.bind).map(_.groupName)))
+ ((t2.collaboratorName === x.userName.bind) || (t2.collaboratorName in GroupMembers
+ .filter(_.userName === x.userName.bind)
+ .map(_.groupName)))
} exists)
}
// for Guests
- case None => Repositories filter(_.isPrivate === false.bind)
+ case None => Repositories filter (_.isPrivate === false.bind)
}).filter { t =>
- repositoryUserName.map { userName => t.userName === userName.bind } getOrElse LiteralColumn(true)
- }.sortBy(_.lastActivityDate desc).list.map { repository =>
- new RepositoryInfo(
- if(withoutPhysicalInfo){
- new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
- } else {
- JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
- },
- repository,
- if(withoutPhysicalInfo){
- -1
- } else {
- getForkedCount(
- repository.originUserName.getOrElse(repository.userName),
- repository.originRepositoryName.getOrElse(repository.repositoryName)
- )
- },
- if(withoutPhysicalInfo) {
- Nil
- } else {
- getRepositoryManagers(repository.userName)
- })
- }
+ repositoryUserName.map { userName =>
+ t.userName === userName.bind
+ } getOrElse LiteralColumn(true)
+ }
+ .sortBy(_.lastActivityDate desc)
+ .list
+ .map { repository =>
+ new RepositoryInfo(
+ if (withoutPhysicalInfo) {
+ new JGitUtil.RepositoryInfo(repository.userName, repository.repositoryName)
+ } else {
+ JGitUtil.getRepositoryInfo(repository.userName, repository.repositoryName)
+ },
+ repository,
+ if (withoutPhysicalInfo) {
+ -1
+ } else {
+ getForkedCount(
+ repository.originUserName.getOrElse(repository.userName),
+ repository.originRepositoryName.getOrElse(repository.repositoryName)
+ )
+ },
+ if (withoutPhysicalInfo) {
+ Nil
+ } else {
+ getRepositoryManagers(repository.userName)
+ }
+ )
+ }
}
private def getRepositoryManagers(userName: String)(implicit s: Session): Seq[String] =
- if(getAccountByUserName(userName).exists(_.isGroupAccount)){
- getGroupMembers(userName).collect { case x if(x.isManager) => x.userName }
+ if (getAccountByUserName(userName).exists(_.isGroupAccount)) {
+ getGroupMembers(userName).collect { case x if (x.isManager) => x.userName }
} else {
Seq(userName)
}
@@ -364,24 +489,37 @@
/**
* Save repository options.
*/
- def saveRepositoryOptions(userName: String, repositoryName: String, description: Option[String], isPrivate: Boolean,
- issuesOption: String, externalIssuesUrl: Option[String], wikiOption: String, externalWikiUrl: Option[String],
- allowFork: Boolean, mergeOptions: Seq[String], defaultMergeOption: String)(implicit s: Session): Unit = {
+ def saveRepositoryOptions(
+ userName: String,
+ repositoryName: String,
+ description: Option[String],
+ isPrivate: Boolean,
+ issuesOption: String,
+ externalIssuesUrl: Option[String],
+ wikiOption: String,
+ externalWikiUrl: Option[String],
+ allowFork: Boolean,
+ mergeOptions: Seq[String],
+ defaultMergeOption: String
+ )(implicit s: Session): Unit = {
- Repositories.filter(_.byRepository(userName, repositoryName))
- .map { r => (
- r.description.?,
- r.isPrivate,
- r.issuesOption,
- r.externalIssuesUrl.?,
- r.wikiOption,
- r.externalWikiUrl.?,
- r.allowFork,
- r.mergeOptions,
- r.defaultMergeOption,
- r.updatedDate
- ) }
- .update (
+ Repositories
+ .filter(_.byRepository(userName, repositoryName))
+ .map { r =>
+ (
+ r.description.?,
+ r.isPrivate,
+ r.issuesOption,
+ r.externalIssuesUrl.?,
+ r.wikiOption,
+ r.externalWikiUrl.?,
+ r.allowFork,
+ r.mergeOptions,
+ r.defaultMergeOption,
+ r.updatedDate
+ )
+ }
+ .update(
description,
isPrivate,
issuesOption,
@@ -395,16 +533,22 @@
)
}
- def saveRepositoryDefaultBranch(userName: String, repositoryName: String,
- defaultBranch: String)(implicit s: Session): Unit =
- Repositories.filter(_.byRepository(userName, repositoryName))
- .map { r => r.defaultBranch }
- .update (defaultBranch)
+ def saveRepositoryDefaultBranch(userName: String, repositoryName: String, defaultBranch: String)(
+ implicit s: Session
+ ): Unit =
+ Repositories
+ .filter(_.byRepository(userName, repositoryName))
+ .map { r =>
+ r.defaultBranch
+ }
+ .update(defaultBranch)
/**
* Add collaborator (user or group) to the repository.
*/
- def addCollaborator(userName: String, repositoryName: String, collaboratorName: String, role: String)(implicit s: Session): Unit =
+ def addCollaborator(userName: String, repositoryName: String, collaboratorName: String, role: String)(
+ implicit s: Session
+ ): Unit =
Collaborators insert Collaborator(userName, repositoryName, collaboratorName, role)
/**
@@ -418,9 +562,10 @@
*/
def getCollaborators(userName: String, repositoryName: String)(implicit s: Session): List[(Collaborator, Boolean)] =
Collaborators
- .join(Accounts).on(_.collaboratorName === _.userName)
+ .join(Accounts)
+ .on(_.collaboratorName === _.userName)
.filter { case (t1, t2) => t1.byRepository(userName, repositoryName) }
- .map { case (t1, t2) => (t1, t2.groupAccount) }
+ .map { case (t1, t2) => (t1, t2.groupAccount) }
.sortBy { case (t1, t2) => t1.collaboratorName }
.list
@@ -428,60 +573,79 @@
* Returns the list of all collaborator name and permission which is sorted with ascending order.
* If a group is added as a collaborator, this method returns users who are belong to that group.
*/
- def getCollaboratorUserNames(userName: String, repositoryName: String, filter: Seq[Role] = Nil)(implicit s: Session): List[String] = {
+ def getCollaboratorUserNames(userName: String, repositoryName: String, filter: Seq[Role] = Nil)(
+ implicit s: Session
+ ): List[String] = {
val q1 = Collaborators
- .join(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === false.bind) }
+ .join(Accounts)
+ .on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === false.bind) }
.filter { case (t1, t2) => t1.byRepository(userName, repositoryName) }
- .map { case (t1, t2) => (t1.collaboratorName, t1.role) }
+ .map { case (t1, t2) => (t1.collaboratorName, t1.role) }
val q2 = Collaborators
- .join(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === true.bind) }
- .join(GroupMembers).on { case ((t1, t2), t3) => t2.userName === t3.groupName }
+ .join(Accounts)
+ .on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === true.bind) }
+ .join(GroupMembers)
+ .on { case ((t1, t2), t3) => t2.userName === t3.groupName }
.filter { case ((t1, t2), t3) => t1.byRepository(userName, repositoryName) }
- .map { case ((t1, t2), t3) => (t3.userName, t1.role) }
+ .map { case ((t1, t2), t3) => (t3.userName, t1.role) }
- q1.union(q2).list.filter { x => filter.isEmpty || filter.exists(_.name == x._2) }.map(_._1)
+ q1.union(q2)
+ .list
+ .filter { x =>
+ filter.isEmpty || filter.exists(_.name == x._2)
+ }
+ .map(_._1)
}
def hasOwnerRole(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
loginAccount match {
- case Some(a) if(a.isAdmin) => true
- case Some(a) if(a.userName == owner) => true
- case Some(a) if(getGroupMembers(owner).exists(_.userName == a.userName)) => true
- case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN)).contains(a.userName)) => true
- case _ => false
+ case Some(a) if (a.isAdmin) => true
+ case Some(a) if (a.userName == owner) => true
+ case Some(a) if (getGroupMembers(owner).exists(_.userName == a.userName)) => true
+ case Some(a) if (getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN)).contains(a.userName)) => true
+ case _ => false
}
}
- def hasDeveloperRole(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
+ def hasDeveloperRole(owner: String, repository: String, loginAccount: Option[Account])(
+ implicit s: Session
+ ): Boolean = {
loginAccount match {
- case Some(a) if(a.isAdmin) => true
- case Some(a) if(a.userName == owner) => true
- case Some(a) if(getGroupMembers(owner).exists(_.userName == a.userName)) => true
- case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER)).contains(a.userName)) => true
+ case Some(a) if (a.isAdmin) => true
+ case Some(a) if (a.userName == owner) => true
+ case Some(a) if (getGroupMembers(owner).exists(_.userName == a.userName)) => true
+ case Some(a)
+ if (getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER)).contains(a.userName)) =>
+ true
case _ => false
}
}
def hasGuestRole(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
loginAccount match {
- case Some(a) if(a.isAdmin) => true
- case Some(a) if(a.userName == owner) => true
- case Some(a) if(getGroupMembers(owner).exists(_.userName == a.userName)) => true
- case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER, Role.GUEST)).contains(a.userName)) => true
+ case Some(a) if (a.isAdmin) => true
+ case Some(a) if (a.userName == owner) => true
+ case Some(a) if (getGroupMembers(owner).exists(_.userName == a.userName)) => true
+ case Some(a)
+ if (getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER, Role.GUEST))
+ .contains(a.userName)) =>
+ true
case _ => false
}
}
def isReadable(repository: Repository, loginAccount: Option[Account])(implicit s: Session): Boolean = {
- if(!repository.isPrivate){
+ if (!repository.isPrivate) {
true
} else {
loginAccount match {
- case Some(x) if(x.isAdmin) => true
- case Some(x) if(repository.userName == x.userName) => true
- case Some(x) if(getGroupMembers(repository.userName).exists(_.userName == x.userName)) => true
- case Some(x) if(getCollaboratorUserNames(repository.userName, repository.repositoryName).contains(x.userName)) => true
+ case Some(x) if (x.isAdmin) => true
+ case Some(x) if (repository.userName == x.userName) => true
+ case Some(x) if (getGroupMembers(repository.userName).exists(_.userName == x.userName)) => true
+ case Some(x)
+ if (getCollaboratorUserNames(repository.userName, repository.repositoryName).contains(x.userName)) =>
+ true
case _ => false
}
}
@@ -492,61 +656,81 @@
(t.originUserName === userName.bind) && (t.originRepositoryName === repositoryName.bind)
}.length).first
-
def getForkedRepositories(userName: String, repositoryName: String)(implicit s: Session): List[Repository] =
- Repositories.filter { t =>
- (t.originUserName === userName.bind) && (t.originRepositoryName === repositoryName.bind)
- }
- .sortBy(_.userName asc).list//.map(t => t.userName -> t.repositoryName).list
+ Repositories
+ .filter { t =>
+ (t.originUserName === userName.bind) && (t.originRepositoryName === repositoryName.bind)
+ }
+ .sortBy(_.userName asc)
+ .list //.map(t => t.userName -> t.repositoryName).list
private val templateExtensions = Seq("md", "markdown")
/**
- * Returns content of template set per repository.
- *
- * @param repository the repository information
- * @param fileBaseName the file basename without extension of template
- * @return The content of template if the repository has it, otherwise empty string.
+ * Returns content of template set per repository.
+ *
+ * @param repository the repository information
+ * @param fileBaseName the file basename without extension of template
+ * @return The content of template if the repository has it, otherwise empty string.
*/
def getContentTemplate(repository: RepositoryInfo, fileBaseName: String)(implicit s: Session): String = {
val withExtFilenames = templateExtensions.map(extension => s"${fileBaseName.toLowerCase()}.${extension}")
def choiceTemplate(files: List[FileInfo]): Option[FileInfo] =
- files.find { f =>
- f.name.toLowerCase() == fileBaseName
- }.orElse {
- files.find(f => withExtFilenames.contains(f.name.toLowerCase()))
- }
+ files
+ .find { f =>
+ f.name.toLowerCase() == fileBaseName
+ }
+ .orElse {
+ files.find(f => withExtFilenames.contains(f.name.toLowerCase()))
+ }
// Get template file from project root. When didn't find, will lookup default folder.
using(Git.open(Directory.getRepositoryDir(repository.owner, repository.name))) { git =>
- choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, ".")).orElse {
- choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, ".gitbucket"))
- }.map { file =>
- JGitUtil.getContentFromId(git, file.id, true).collect {
- case bytes if FileUtil.isText(bytes) => StringUtil.convertFromByteArray(bytes)
+ choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, "."))
+ .orElse {
+ choiceTemplate(JGitUtil.getFileList(git, repository.repository.defaultBranch, ".gitbucket"))
}
- } getOrElse None
+ .map { file =>
+ JGitUtil.getContentFromId(git, file.id, true).collect {
+ case bytes if FileUtil.isText(bytes) => StringUtil.convertFromByteArray(bytes)
+ }
+ } getOrElse None
} getOrElse ""
}
}
object RepositoryService {
- case class RepositoryInfo(owner: String, name: String, repository: Repository,
- issueCount: Int, pullCount: Int, forkedCount: Int,
- branchList: Seq[String], tags: Seq[JGitUtil.TagInfo], managers: Seq[String]) {
+ case class RepositoryInfo(
+ owner: String,
+ name: String,
+ repository: Repository,
+ issueCount: Int,
+ pullCount: Int,
+ forkedCount: Int,
+ branchList: Seq[String],
+ tags: Seq[JGitUtil.TagInfo],
+ managers: Seq[String]
+ ) {
/**
* 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, model, issueCount, pullCount, forkedCount, repo.branchList, repo.tags, managers)
/**
* Creates instance without issue 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, model, 0, 0, forkedCount, repo.branchList, repo.tags, managers)
def httpUrl(implicit context: Context): String = RepositoryService.httpUrl(owner, name)
@@ -554,19 +738,23 @@
def splitPath(path: String): (String, String) = {
val id = branchList.collectFirst {
- case branch if(path == branch || path.startsWith(branch + "/")) => branch
+ case branch if (path == branch || path.startsWith(branch + "/")) => branch
} orElse tags.collectFirst {
- case tag if(path == tag.name || path.startsWith(tag.name + "/")) => tag.name
+ case tag if (path == tag.name || path.startsWith(tag.name + "/")) => tag.name
} getOrElse path.split("/")(0)
(id, path.substring(id.length).stripPrefix("/"))
}
}
- def httpUrl(owner: String, name: String)(implicit context: Context): String = s"${context.baseUrl}/git/${owner}/${name}.git"
+ def httpUrl(owner: String, name: String)(implicit context: Context): String =
+ s"${context.baseUrl}/git/${owner}/${name}.git"
def sshUrl(owner: String, name: String)(implicit context: Context): Option[String] =
- if(context.settings.ssh){
- context.settings.sshAddress.map { x => s"ssh://${x.genericUser}@${x.host}:${x.port}/${owner}/${name}.git" }
+ if (context.settings.ssh) {
+ context.settings.sshAddress.map { x =>
+ s"ssh://${x.genericUser}@${x.host}:${x.port}/${owner}/${name}.git"
+ }
} else None
- def openRepoUrl(openUrl: String)(implicit context: Context): String = s"github-${context.platform}://openRepo/${openUrl}"
+ def openRepoUrl(openUrl: String)(implicit context: Context): String =
+ s"github-${context.platform}://openRepo/${openUrl}"
}
diff --git a/src/main/scala/gitbucket/core/service/RequestCache.scala b/src/main/scala/gitbucket/core/service/RequestCache.scala
index 5e2e754..d1b12de 100644
--- a/src/main/scala/gitbucket/core/service/RequestCache.scala
+++ b/src/main/scala/gitbucket/core/service/RequestCache.scala
@@ -11,26 +11,32 @@
* It may be called many times in one request, so each method stores
* its result into the cache which available during a request.
*/
-trait RequestCache extends SystemSettingsService with AccountService with IssuesService with RepositoryService
- with LabelsService with MilestonesService with PrioritiesService {
+trait RequestCache
+ extends SystemSettingsService
+ with AccountService
+ with IssuesService
+ with RepositoryService
+ with LabelsService
+ with MilestonesService
+ with PrioritiesService {
private implicit def context2Session(implicit context: Context): Session =
request2Session(context.request)
def getIssue(userName: String, repositoryName: String, issueId: String)(implicit context: Context): Option[Issue] = {
- context.cache(s"issue.${userName}/${repositoryName}#${issueId}"){
+ context.cache(s"issue.${userName}/${repositoryName}#${issueId}") {
super.getIssue(userName, repositoryName, issueId)
}
}
def getAccountByUserName(userName: String)(implicit context: Context): Option[Account] = {
- context.cache(s"account.${userName}"){
+ context.cache(s"account.${userName}") {
super.getAccountByUserName(userName)
}
}
def getAccountByMailAddress(mailAddress: String)(implicit context: Context): Option[Account] = {
- context.cache(s"account.${mailAddress}"){
+ context.cache(s"account.${mailAddress}") {
super.getAccountByMailAddress(mailAddress)
}
}
diff --git a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala
index 2ad682b..76eb761 100644
--- a/src/main/scala/gitbucket/core/service/SystemSettingsService.scala
+++ b/src/main/scala/gitbucket/core/service/SystemSettingsService.scala
@@ -15,7 +15,7 @@
def baseUrl(implicit request: HttpServletRequest): String = loadSystemSettings().baseUrl(request)
def saveSystemSettings(settings: SystemSettings): Unit = {
- defining(new java.util.Properties()){ props =>
+ defining(new java.util.Properties()) { props =>
settings.baseUrl.foreach(x => props.setProperty(BaseURL, x.replaceFirst("/\\Z", "")))
settings.information.foreach(x => props.setProperty(Information, x))
props.setProperty(AllowAccountRegistration, settings.allowAccountRegistration.toString)
@@ -28,7 +28,7 @@
settings.sshHost.foreach(x => props.setProperty(SshHost, x.trim))
settings.sshPort.foreach(x => props.setProperty(SshPort, x.toString))
props.setProperty(UseSMTP, settings.useSMTP.toString)
- if(settings.useSMTP) {
+ if (settings.useSMTP) {
settings.smtp.foreach { smtp =>
props.setProperty(SmtpHost, smtp.host)
smtp.port.foreach(x => props.setProperty(SmtpPort, x.toString))
@@ -41,7 +41,7 @@
}
}
props.setProperty(LdapAuthentication, settings.ldapAuthentication.toString)
- if(settings.ldapAuthentication){
+ if (settings.ldapAuthentication) {
settings.ldap.map { ldap =>
props.setProperty(LdapHost, ldap.host)
ldap.port.foreach(x => props.setProperty(LdapPort, x.toString))
@@ -63,21 +63,22 @@
props.setProperty(OidcIssuer, oidc.issuer.getValue)
props.setProperty(OidcClientId, oidc.clientID.getValue)
props.setProperty(OidcClientSecret, oidc.clientSecret.getValue)
- oidc.jwsAlgorithm.map { x => props.setProperty(OidcJwsAlgorithm, x.getName) }
+ oidc.jwsAlgorithm.map { x =>
+ props.setProperty(OidcJwsAlgorithm, x.getName)
+ }
}
}
props.setProperty(SkinName, settings.skinName.toString)
- using(new java.io.FileOutputStream(GitBucketConf)){ out =>
+ using(new java.io.FileOutputStream(GitBucketConf)) { out =>
props.store(out, null)
}
}
}
-
def loadSystemSettings(): SystemSettings = {
- defining(new java.util.Properties()){ props =>
- if(GitBucketConf.exists){
- using(new java.io.FileInputStream(GitBucketConf)){ in =>
+ defining(new java.util.Properties()) { props =>
+ if (GitBucketConf.exists) {
+ using(new java.io.FileInputStream(GitBucketConf)) { in =>
props.load(in)
}
}
@@ -93,46 +94,54 @@
getValue(props, Ssh, false),
getOptionValue[String](props, SshHost, None).map(_.trim),
getOptionValue(props, SshPort, Some(DefaultSshPort)),
- getValue(props, UseSMTP, getValue(props, Notification, false)), // handle migration scenario from only notification to useSMTP
- if(getValue(props, UseSMTP, getValue(props, Notification, false))){
- Some(Smtp(
- getValue(props, SmtpHost, ""),
- getOptionValue(props, SmtpPort, Some(DefaultSmtpPort)),
- getOptionValue(props, SmtpUser, None),
- getOptionValue(props, SmtpPassword, None),
- getOptionValue[Boolean](props, SmtpSsl, None),
- getOptionValue[Boolean](props, SmtpStarttls, None),
- getOptionValue(props, SmtpFromAddress, None),
- getOptionValue(props, SmtpFromName, None)))
+ getValue(props, UseSMTP, getValue(props, Notification, false)), // handle migration scenario from only notification to useSMTP
+ if (getValue(props, UseSMTP, getValue(props, Notification, false))) {
+ Some(
+ Smtp(
+ getValue(props, SmtpHost, ""),
+ getOptionValue(props, SmtpPort, Some(DefaultSmtpPort)),
+ getOptionValue(props, SmtpUser, None),
+ getOptionValue(props, SmtpPassword, None),
+ getOptionValue[Boolean](props, SmtpSsl, None),
+ getOptionValue[Boolean](props, SmtpStarttls, None),
+ getOptionValue(props, SmtpFromAddress, None),
+ getOptionValue(props, SmtpFromName, None)
+ )
+ )
} else {
None
},
getValue(props, LdapAuthentication, false),
- if(getValue(props, LdapAuthentication, false)){
- Some(Ldap(
- getValue(props, LdapHost, ""),
- getOptionValue(props, LdapPort, Some(DefaultLdapPort)),
- getOptionValue(props, LdapBindDN, None),
- getOptionValue(props, LdapBindPassword, None),
- getValue(props, LdapBaseDN, ""),
- getValue(props, LdapUserNameAttribute, ""),
- getOptionValue(props, LdapAdditionalFilterCondition, None),
- getOptionValue(props, LdapFullNameAttribute, None),
- getOptionValue(props, LdapMailAddressAttribute, None),
- getOptionValue[Boolean](props, LdapTls, None),
- getOptionValue[Boolean](props, LdapSsl, None),
- getOptionValue(props, LdapKeystore, None)))
+ if (getValue(props, LdapAuthentication, false)) {
+ Some(
+ Ldap(
+ getValue(props, LdapHost, ""),
+ getOptionValue(props, LdapPort, Some(DefaultLdapPort)),
+ getOptionValue(props, LdapBindDN, None),
+ getOptionValue(props, LdapBindPassword, None),
+ getValue(props, LdapBaseDN, ""),
+ getValue(props, LdapUserNameAttribute, ""),
+ getOptionValue(props, LdapAdditionalFilterCondition, None),
+ getOptionValue(props, LdapFullNameAttribute, None),
+ getOptionValue(props, LdapMailAddressAttribute, None),
+ getOptionValue[Boolean](props, LdapTls, None),
+ getOptionValue[Boolean](props, LdapSsl, None),
+ getOptionValue(props, LdapKeystore, None)
+ )
+ )
} else {
None
},
getValue(props, OidcAuthentication, false),
if (getValue(props, OidcAuthentication, false)) {
- Some(OIDC(
- getValue(props, OidcIssuer, ""),
- getValue(props, OidcClientId, ""),
- getValue(props, OidcClientSecret, ""),
- getOptionValue(props, OidcJwsAlgorithm, None)
- ))
+ Some(
+ OIDC(
+ getValue(props, OidcIssuer, ""),
+ getValue(props, OidcClientId, ""),
+ getValue(props, OidcClientSecret, ""),
+ getOptionValue(props, OidcJwsAlgorithm, None)
+ )
+ )
} else {
None
},
@@ -164,16 +173,19 @@
ldap: Option[Ldap],
oidcAuthentication: Boolean,
oidc: Option[OIDC],
- skinName: String){
+ skinName: String
+ ) {
- def baseUrl(request: HttpServletRequest): String = baseUrl.fold {
- val url = request.getRequestURL.toString
- val len = url.length - (request.getRequestURI.length - request.getContextPath.length)
- url.substring(0, len).stripSuffix("/")
- } (_.stripSuffix("/"))
+ def baseUrl(request: HttpServletRequest): String =
+ baseUrl.fold {
+ val url = request.getRequestURL.toString
+ val len = url.length - (request.getRequestURI.length - request.getContextPath.length)
+ url.substring(0, len).stripSuffix("/")
+ }(_.stripSuffix("/"))
- def sshAddress:Option[SshAddress] = sshHost.collect { case host if ssh =>
- SshAddress(host, sshPort.getOrElse(DefaultSshPort), "git")
+ def sshAddress: Option[SshAddress] = sshHost.collect {
+ case host if ssh =>
+ SshAddress(host, sshPort.getOrElse(DefaultSshPort), "git")
}
}
@@ -189,16 +201,18 @@
mailAttribute: Option[String],
tls: Option[Boolean],
ssl: Option[Boolean],
- keystore: Option[String])
+ keystore: Option[String]
+ )
- case class OIDC(
- issuer: Issuer,
- clientID: ClientID,
- clientSecret: Secret,
- jwsAlgorithm: Option[JWSAlgorithm])
+ case class OIDC(issuer: Issuer, clientID: ClientID, clientSecret: Secret, jwsAlgorithm: Option[JWSAlgorithm])
object OIDC {
def apply(issuer: String, clientID: String, clientSecret: String, jwsAlgorithm: Option[String]): OIDC =
- new OIDC(new Issuer(issuer), new ClientID(clientID), new Secret(clientSecret), jwsAlgorithm.map(JWSAlgorithm.parse))
+ new OIDC(
+ new Issuer(issuer),
+ new ClientID(clientID),
+ new Secret(clientSecret),
+ jwsAlgorithm.map(JWSAlgorithm.parse)
+ )
}
case class Smtp(
@@ -209,15 +223,12 @@
ssl: Option[Boolean],
starttls: Option[Boolean],
fromAddress: Option[String],
- fromName: Option[String])
+ fromName: Option[String]
+ )
- case class SshAddress(
- host: String,
- port: Int,
- genericUser: String)
+ case class SshAddress(host: String, port: Int, genericUser: String)
- case class Lfs(
- serverUrl: Option[String])
+ case class Lfs(serverUrl: Option[String])
val DefaultSshPort = 29418
val DefaultSmtpPort = 25
@@ -265,8 +276,8 @@
private def getValue[A: ClassTag](props: java.util.Properties, key: String, default: A): A = {
getSystemProperty(key).getOrElse(getEnvironmentVariable(key).getOrElse {
- defining(props.getProperty(key)){ value =>
- if(value == null || value.isEmpty){
+ defining(props.getProperty(key)) { value =>
+ if (value == null || value.isEmpty) {
default
} else {
convertType(value).asInstanceOf[A]
@@ -277,8 +288,8 @@
private def getOptionValue[A: ClassTag](props: java.util.Properties, key: String, default: Option[A]): Option[A] = {
getSystemProperty(key).orElse(getEnvironmentVariable(key).orElse {
- defining(props.getProperty(key)){ value =>
- if(value == null || value.isEmpty){
+ defining(props.getProperty(key)) { value =>
+ if (value == null || value.isEmpty) {
default
} else {
Some(convertType(value)).asInstanceOf[Option[A]]
diff --git a/src/main/scala/gitbucket/core/service/WebHookService.scala b/src/main/scala/gitbucket/core/service/WebHookService.scala
index 2dfca94..d8c0e48 100644
--- a/src/main/scala/gitbucket/core/service/WebHookService.scala
+++ b/src/main/scala/gitbucket/core/service/WebHookService.scala
@@ -3,7 +3,19 @@
import fr.brouillard.oss.security.xhub.XHub
import fr.brouillard.oss.security.xhub.XHub.{XHubConverter, XHubDigest}
import gitbucket.core.api._
-import gitbucket.core.model.{Account, CommitComment, Issue, IssueComment, Label, PullRequest, WebHook, RepositoryWebHook, RepositoryWebHookEvent, AccountWebHook, AccountWebHookEvent}
+import gitbucket.core.model.{
+ Account,
+ CommitComment,
+ Issue,
+ IssueComment,
+ Label,
+ PullRequest,
+ WebHook,
+ RepositoryWebHook,
+ RepositoryWebHookEvent,
+ AccountWebHook,
+ AccountWebHookEvent
+}
import gitbucket.core.model.Profile._
import gitbucket.core.model.Profile.profile.blockingApi._
import org.apache.http.client.utils.URLEncodedUtils
@@ -25,84 +37,156 @@
import org.apache.http.client.entity.EntityBuilder
import org.apache.http.entity.ContentType
-
trait WebHookService {
import WebHookService._
private val logger = LoggerFactory.getLogger(classOf[WebHookService])
/** get All WebHook informations of repository */
- def getWebHooks(owner: String, repository: String)(implicit s: Session): List[(RepositoryWebHook, Set[WebHook.Event])] =
- RepositoryWebHooks.filter(_.byRepository(owner, repository))
- .join(RepositoryWebHookEvents).on { (w, t) => t.byRepositoryWebHook(w) }
+ def getWebHooks(owner: String, repository: String)(
+ implicit s: Session
+ ): List[(RepositoryWebHook, Set[WebHook.Event])] =
+ RepositoryWebHooks
+ .filter(_.byRepository(owner, repository))
+ .join(RepositoryWebHookEvents)
+ .on { (w, t) =>
+ t.byRepositoryWebHook(w)
+ }
.map { case (w, t) => w -> t.event }
- .list.groupBy(_._1).mapValues(_.map(_._2).toSet).toList.sortBy(_._1.url)
+ .list
+ .groupBy(_._1)
+ .mapValues(_.map(_._2).toSet)
+ .toList
+ .sortBy(_._1.url)
/** get All WebHook informations of repository event */
- def getWebHooksByEvent(owner: String, repository: String, event: WebHook.Event)(implicit s: Session): List[RepositoryWebHook] =
- RepositoryWebHooks.filter(_.byRepository(owner, repository))
- .join(RepositoryWebHookEvents).on { (wh, whe) => whe.byRepositoryWebHook(wh) }
- .filter { case (wh, whe) => whe.event === event.bind}
- .map{ case (wh, whe) => wh }
- .list.distinct
+ def getWebHooksByEvent(owner: String, repository: String, event: WebHook.Event)(
+ implicit s: Session
+ ): List[RepositoryWebHook] =
+ RepositoryWebHooks
+ .filter(_.byRepository(owner, repository))
+ .join(RepositoryWebHookEvents)
+ .on { (wh, whe) =>
+ whe.byRepositoryWebHook(wh)
+ }
+ .filter { case (wh, whe) => whe.event === event.bind }
+ .map { case (wh, whe) => wh }
+ .list
+ .distinct
/** get All WebHook information from repository to url */
- def getWebHook(owner: String, repository: String, url: String)(implicit s: Session): Option[(RepositoryWebHook, Set[WebHook.Event])] =
+ def getWebHook(owner: String, repository: String, url: String)(
+ implicit s: Session
+ ): Option[(RepositoryWebHook, Set[WebHook.Event])] =
RepositoryWebHooks
.filter(_.byPrimaryKey(owner, repository, url))
- .join(RepositoryWebHookEvents).on { (w, t) => t.byRepositoryWebHook(w) }
+ .join(RepositoryWebHookEvents)
+ .on { (w, t) =>
+ t.byRepositoryWebHook(w)
+ }
.map { case (w, t) => w -> t.event }
- .list.groupBy(_._1).mapValues(_.map(_._2).toSet).headOption
+ .list
+ .groupBy(_._1)
+ .mapValues(_.map(_._2).toSet)
+ .headOption
- def addWebHook(owner: String, repository: String, url :String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])(implicit s: Session): Unit = {
+ def addWebHook(
+ owner: String,
+ repository: String,
+ url: String,
+ events: Set[WebHook.Event],
+ ctype: WebHookContentType,
+ token: Option[String]
+ )(implicit s: Session): Unit = {
RepositoryWebHooks insert RepositoryWebHook(owner, repository, url, ctype, token)
events.map { event: WebHook.Event =>
RepositoryWebHookEvents insert RepositoryWebHookEvent(owner, repository, url, event)
}
}
- def updateWebHook(owner: String, repository: String, url :String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])(implicit s: Session): Unit = {
- RepositoryWebHooks.filter(_.byPrimaryKey(owner, repository, url)).map(w => (w.ctype, w.token)).update((ctype, token))
+ def updateWebHook(
+ owner: String,
+ repository: String,
+ url: String,
+ events: Set[WebHook.Event],
+ ctype: WebHookContentType,
+ token: Option[String]
+ )(implicit s: Session): Unit = {
+ RepositoryWebHooks
+ .filter(_.byPrimaryKey(owner, repository, url))
+ .map(w => (w.ctype, w.token))
+ .update((ctype, token))
RepositoryWebHookEvents.filter(_.byRepositoryWebHook(owner, repository, url)).delete
events.map { event: WebHook.Event =>
RepositoryWebHookEvents insert RepositoryWebHookEvent(owner, repository, url, event)
}
}
- def deleteWebHook(owner: String, repository: String, url :String)(implicit s: Session): Unit =
+ def deleteWebHook(owner: String, repository: String, url: String)(implicit s: Session): Unit =
RepositoryWebHooks.filter(_.byPrimaryKey(owner, repository, url)).delete
/** get All AccountWebHook informations of user */
def getAccountWebHooks(owner: String)(implicit s: Session): List[(AccountWebHook, Set[WebHook.Event])] =
- AccountWebHooks.filter(_.byAccount(owner))
- .join(AccountWebHookEvents).on { (w, t) => t.byAccountWebHook(w) }
+ AccountWebHooks
+ .filter(_.byAccount(owner))
+ .join(AccountWebHookEvents)
+ .on { (w, t) =>
+ t.byAccountWebHook(w)
+ }
.map { case (w, t) => w -> t.event }
- .list.groupBy(_._1).mapValues(_.map(_._2).toSet).toList.sortBy(_._1.url)
+ .list
+ .groupBy(_._1)
+ .mapValues(_.map(_._2).toSet)
+ .toList
+ .sortBy(_._1.url)
/** get All AccountWebHook informations of repository event */
def getAccountWebHooksByEvent(owner: String, event: WebHook.Event)(implicit s: Session): List[AccountWebHook] =
- AccountWebHooks.filter(_.byAccount(owner))
- .join(AccountWebHookEvents).on { (wh, whe) => whe.byAccountWebHook(wh) }
- .filter { case (wh, whe) => whe.event === event.bind}
- .map{ case (wh, whe) => wh }
- .list.distinct
+ AccountWebHooks
+ .filter(_.byAccount(owner))
+ .join(AccountWebHookEvents)
+ .on { (wh, whe) =>
+ whe.byAccountWebHook(wh)
+ }
+ .filter { case (wh, whe) => whe.event === event.bind }
+ .map { case (wh, whe) => wh }
+ .list
+ .distinct
/** get All AccountWebHook information from repository to url */
def getAccountWebHook(owner: String, url: String)(implicit s: Session): Option[(AccountWebHook, Set[WebHook.Event])] =
AccountWebHooks
.filter(_.byPrimaryKey(owner, url))
- .join(AccountWebHookEvents).on { (w, t) => t.byAccountWebHook(w) }
+ .join(AccountWebHookEvents)
+ .on { (w, t) =>
+ t.byAccountWebHook(w)
+ }
.map { case (w, t) => w -> t.event }
- .list.groupBy(_._1).mapValues(_.map(_._2).toSet).headOption
+ .list
+ .groupBy(_._1)
+ .mapValues(_.map(_._2).toSet)
+ .headOption
- def addAccountWebHook(owner: String, url :String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])(implicit s: Session): Unit = {
+ def addAccountWebHook(
+ owner: String,
+ url: String,
+ events: Set[WebHook.Event],
+ ctype: WebHookContentType,
+ token: Option[String]
+ )(implicit s: Session): Unit = {
AccountWebHooks insert AccountWebHook(owner, url, ctype, token)
events.map { event: WebHook.Event =>
AccountWebHookEvents insert AccountWebHookEvent(owner, url, event)
}
}
- def updateAccountWebHook(owner: String, url :String, events: Set[WebHook.Event], ctype: WebHookContentType, token: Option[String])(implicit s: Session): Unit = {
+ def updateAccountWebHook(
+ owner: String,
+ url: String,
+ events: Set[WebHook.Event],
+ ctype: WebHookContentType,
+ token: Option[String]
+ )(implicit s: Session): Unit = {
AccountWebHooks.filter(_.byPrimaryKey(owner, url)).map(w => (w.ctype, w.token)).update((ctype, token))
AccountWebHookEvents.filter(_.byAccountWebHook(owner, url)).delete
events.map { event: WebHook.Event =>
@@ -110,29 +194,31 @@
}
}
- def deleteAccountWebHook(owner: String, url :String)(implicit s: Session): Unit =
+ def deleteAccountWebHook(owner: String, url: String)(implicit s: Session): Unit =
AccountWebHooks.filter(_.byPrimaryKey(owner, url)).delete
- def callWebHookOf(owner: String, repository: String, event: WebHook.Event)(makePayload: => Option[WebHookPayload])
- (implicit s: Session, c: JsonFormat.Context): Unit = {
+ def callWebHookOf(owner: String, repository: String, event: WebHook.Event)(
+ makePayload: => Option[WebHookPayload]
+ )(implicit s: Session, c: JsonFormat.Context): Unit = {
val webHooks = getWebHooksByEvent(owner, repository, event)
- if(webHooks.nonEmpty){
+ if (webHooks.nonEmpty) {
makePayload.map(callWebHook(event, webHooks, _))
}
val accountWebHooks = getAccountWebHooksByEvent(owner, event)
- if(accountWebHooks.nonEmpty){
+ if (accountWebHooks.nonEmpty) {
makePayload.map(callWebHook(event, accountWebHooks, _))
}
}
- def callWebHook(event: WebHook.Event, webHooks: List[WebHook], payload: WebHookPayload)
- (implicit c: JsonFormat.Context): List[(WebHook, String, Future[HttpRequest], Future[HttpResponse])] = {
+ def callWebHook(event: WebHook.Event, webHooks: List[WebHook], payload: WebHookPayload)(
+ implicit c: JsonFormat.Context
+ ): List[(WebHook, String, Future[HttpRequest], Future[HttpResponse])] = {
import org.apache.http.impl.client.HttpClientBuilder
import ExecutionContext.Implicits.global // TODO Shouldn't use the default execution context
import org.apache.http.protocol.HttpContext
import org.apache.http.client.methods.HttpPost
- if(webHooks.nonEmpty){
+ if (webHooks.nonEmpty) {
val json = JsonFormat(payload)
webHooks.map { webHook =>
@@ -143,7 +229,7 @@
reqPromise.success(res)
}
}
- try{
+ try {
val httpClient = HttpClientBuilder.create.useSystemProperties.addInterceptorLast(itcp).build
logger.debug(s"start web hook invocation for ${webHook.url}")
val httpPost = new HttpPost(webHook.url)
@@ -154,20 +240,38 @@
webHook.ctype match {
case WebHookContentType.FORM => {
- val params: java.util.List[NameValuePair] = new java.util.ArrayList()
+ val params: java.util.List[NameValuePair] = new java.util.ArrayList()
params.add(new BasicNameValuePair("payload", json))
def postContent = new UrlEncodedFormEntity(params, "UTF-8")
httpPost.setEntity(postContent)
if (webHook.token.exists(_.trim.nonEmpty)) {
// TODO find a better way and see how to extract content from postContent
val contentAsBytes = URLEncodedUtils.format(params, "UTF-8").getBytes("UTF-8")
- httpPost.addHeader("X-Hub-Signature", XHub.generateHeaderXHubToken(XHubConverter.HEXA_LOWERCASE, XHubDigest.SHA1, webHook.token.get, contentAsBytes))
+ httpPost.addHeader(
+ "X-Hub-Signature",
+ XHub.generateHeaderXHubToken(
+ XHubConverter.HEXA_LOWERCASE,
+ XHubDigest.SHA1,
+ webHook.token.get,
+ contentAsBytes
+ )
+ )
}
}
case WebHookContentType.JSON => {
- httpPost.setEntity(EntityBuilder.create().setContentType(ContentType.APPLICATION_JSON).setText(json).build())
+ httpPost.setEntity(
+ EntityBuilder.create().setContentType(ContentType.APPLICATION_JSON).setText(json).build()
+ )
if (webHook.token.exists(_.trim.nonEmpty)) {
- httpPost.addHeader("X-Hub-Signature", XHub.generateHeaderXHubToken(XHubConverter.HEXA_LOWERCASE, XHubDigest.SHA1, webHook.token.orNull, json.getBytes("UTF-8")))
+ httpPost.addHeader(
+ "X-Hub-Signature",
+ XHub.generateHeaderXHubToken(
+ XHubConverter.HEXA_LOWERCASE,
+ XHubDigest.SHA1,
+ webHook.token.orNull,
+ json.getBytes("UTF-8")
+ )
+ )
}
}
}
@@ -178,7 +282,7 @@
res
} catch {
case e: Throwable => {
- if(!reqPromise.isCompleted){
+ if (!reqPromise.isCompleted) {
reqPromise.failure(e)
}
throw e
@@ -198,103 +302,138 @@
}
}
-
trait WebHookPullRequestService extends WebHookService {
self: AccountService with RepositoryService with PullRequestService with IssuesService =>
import WebHookService._
// https://developer.github.com/v3/activity/events/types/#issuesevent
- def callIssuesWebHook(action: String, repository: RepositoryService.RepositoryInfo, issue: Issue, baseUrl: String, sender: Account)
- (implicit s: Session, context: JsonFormat.Context): Unit = {
- callWebHookOf(repository.owner, repository.name, WebHook.Issues){
+ def callIssuesWebHook(
+ action: String,
+ repository: RepositoryService.RepositoryInfo,
+ issue: Issue,
+ baseUrl: String,
+ sender: Account
+ )(implicit s: Session, context: JsonFormat.Context): Unit = {
+ callWebHookOf(repository.owner, repository.name, WebHook.Issues) {
val users = getAccountsByUserNames(Set(repository.owner, issue.openedUserName), Set(sender))
- for{
+ for {
repoOwner <- users.get(repository.owner)
issueUser <- users.get(issue.openedUserName)
} yield {
WebHookIssuesPayload(
- action = action,
- number = issue.issueId,
+ action = action,
+ number = issue.issueId,
repository = ApiRepository(repository, ApiUser(repoOwner)),
- issue = ApiIssue(issue, RepositoryName(repository), ApiUser(issueUser),
- getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))),
- sender = ApiUser(sender))
+ issue = ApiIssue(
+ issue,
+ RepositoryName(repository),
+ ApiUser(issueUser),
+ getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository)))
+ ),
+ sender = ApiUser(sender)
+ )
}
}
}
- def callPullRequestWebHook(action: String, repository: RepositoryService.RepositoryInfo, issueId: Int, baseUrl: String, sender: Account)
- (implicit s: Session, c: JsonFormat.Context): Unit = {
+ def callPullRequestWebHook(
+ action: String,
+ repository: RepositoryService.RepositoryInfo,
+ issueId: Int,
+ baseUrl: String,
+ sender: Account
+ )(implicit s: Session, c: JsonFormat.Context): Unit = {
import WebHookService._
- callWebHookOf(repository.owner, repository.name, WebHook.PullRequest){
- for{
+ callWebHookOf(repository.owner, repository.name, WebHook.PullRequest) {
+ for {
(issue, pullRequest) <- getPullRequest(repository.owner, repository.name, issueId)
- users = getAccountsByUserNames(Set(repository.owner, pullRequest.requestUserName, issue.openedUserName), Set(sender))
+ users = getAccountsByUserNames(
+ Set(repository.owner, pullRequest.requestUserName, issue.openedUserName),
+ Set(sender)
+ )
baseOwner <- users.get(repository.owner)
headOwner <- users.get(pullRequest.requestUserName)
issueUser <- users.get(issue.openedUserName)
- assignee = issue.assignedUserName.flatMap { userName => getAccountByUserName(userName, false) }
- headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
- labels = getIssueLabels(repository.owner, repository.name, issue.issueId).map(ApiLabel(_, RepositoryName(repository)))
+ assignee = issue.assignedUserName.flatMap { userName =>
+ getAccountByUserName(userName, false)
+ }
+ headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
+ labels = getIssueLabels(repository.owner, repository.name, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(repository)))
} yield {
WebHookPullRequestPayload(
- action = action,
- issue = issue,
- issueUser = issueUser,
- assignee = assignee,
- pullRequest = pullRequest,
+ action = action,
+ issue = issue,
+ issueUser = issueUser,
+ assignee = assignee,
+ pullRequest = pullRequest,
headRepository = headRepo,
- headOwner = headOwner,
+ headOwner = headOwner,
baseRepository = repository,
- baseOwner = baseOwner,
- labels = labels,
- sender = sender,
- mergedComment = getMergedComment(repository.owner, repository.name, issueId)
+ baseOwner = baseOwner,
+ labels = labels,
+ sender = sender,
+ mergedComment = getMergedComment(repository.owner, repository.name, issueId)
)
}
}
}
/** @return Map[(issue, issueUser, pullRequest, baseOwner, headOwner), webHooks] */
- def getPullRequestsByRequestForWebhook(userName:String, repositoryName:String, branch:String)
- (implicit s: Session): Map[(Issue, Account, PullRequest, Account, Account), List[RepositoryWebHook]] =
- (for{
- is <- Issues if is.closed === false.bind
+ def getPullRequestsByRequestForWebhook(userName: String, repositoryName: String, branch: String)(
+ implicit s: Session
+ ): Map[(Issue, Account, PullRequest, Account, Account), List[RepositoryWebHook]] =
+ (for {
+ is <- Issues if is.closed === false.bind
pr <- PullRequests if pr.byPrimaryKey(is.userName, is.repositoryName, is.issueId)
- if pr.requestUserName === userName.bind
- if pr.requestRepositoryName === repositoryName.bind
- if pr.requestBranch === branch.bind
+ if pr.requestUserName === userName.bind
+ if pr.requestRepositoryName === repositoryName.bind
+ if pr.requestBranch === branch.bind
bu <- Accounts if bu.userName === pr.userName
ru <- Accounts if ru.userName === pr.requestUserName
iu <- Accounts if iu.userName === is.openedUserName
- wh <- RepositoryWebHooks if wh.byRepository(is.userName , is.repositoryName)
- wht <- RepositoryWebHookEvents if wht.event === WebHook.PullRequest.asInstanceOf[WebHook.Event].bind && wht.byRepositoryWebHook(wh)
+ wh <- RepositoryWebHooks if wh.byRepository(is.userName, is.repositoryName)
+ wht <- RepositoryWebHookEvents
+ if wht.event === WebHook.PullRequest.asInstanceOf[WebHook.Event].bind && wht.byRepositoryWebHook(wh)
} yield {
((is, iu, pr, bu, ru), wh)
}).list.groupBy(_._1).mapValues(_.map(_._2))
- def callPullRequestWebHookByRequestBranch(action: String, requestRepository: RepositoryService.RepositoryInfo, requestBranch: String, baseUrl: String, sender: Account)
- (implicit s: Session, c: JsonFormat.Context): Unit = {
+ def callPullRequestWebHookByRequestBranch(
+ action: String,
+ requestRepository: RepositoryService.RepositoryInfo,
+ requestBranch: String,
+ baseUrl: String,
+ sender: Account
+ )(implicit s: Session, c: JsonFormat.Context): Unit = {
import WebHookService._
- for{
- ((issue, issueUser, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(requestRepository.owner, requestRepository.name, requestBranch)
- assignee = issue.assignedUserName.flatMap { userName => getAccountByUserName(userName, false) }
+ for {
+ ((issue, issueUser, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(
+ requestRepository.owner,
+ requestRepository.name,
+ requestBranch
+ )
+ assignee = issue.assignedUserName.flatMap { userName =>
+ getAccountByUserName(userName, false)
+ }
baseRepo <- getRepository(pullRequest.userName, pullRequest.repositoryName)
- labels = getIssueLabels(pullRequest.userName, pullRequest.repositoryName, issue.issueId).map(ApiLabel(_, RepositoryName(pullRequest.userName, pullRequest.repositoryName)))
+ labels = getIssueLabels(pullRequest.userName, pullRequest.repositoryName, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(pullRequest.userName, pullRequest.repositoryName)))
} yield {
val payload = WebHookPullRequestPayload(
- action = action,
- issue = issue,
- issueUser = issueUser,
- assignee = assignee,
- pullRequest = pullRequest,
+ action = action,
+ issue = issue,
+ issueUser = issueUser,
+ assignee = assignee,
+ pullRequest = pullRequest,
headRepository = requestRepository,
- headOwner = headOwner,
+ headOwner = headOwner,
baseRepository = baseRepo,
- baseOwner = baseOwner,
- labels = labels,
- sender = sender,
- mergedComment = getMergedComment(baseRepo.owner, baseRepo.name, issue.issueId)
+ baseOwner = baseOwner,
+ labels = labels,
+ sender = sender,
+ mergedComment = getMergedComment(baseRepo.owner, baseRepo.name, issue.issueId)
)
callWebHook(WebHook.PullRequest, webHooks, payload)
@@ -305,34 +444,44 @@
trait WebHookPullRequestReviewCommentService extends WebHookService {
self: AccountService with RepositoryService with PullRequestService with IssuesService with CommitsService =>
- def callPullRequestReviewCommentWebHook(action: String, comment: CommitComment, repository: RepositoryService.RepositoryInfo,
- issue: Issue, pullRequest: PullRequest, baseUrl: String, sender: Account)
- (implicit s: Session, c: JsonFormat.Context): Unit = {
+ def callPullRequestReviewCommentWebHook(
+ action: String,
+ comment: CommitComment,
+ repository: RepositoryService.RepositoryInfo,
+ issue: Issue,
+ pullRequest: PullRequest,
+ baseUrl: String,
+ sender: Account
+ )(implicit s: Session, c: JsonFormat.Context): Unit = {
import WebHookService._
- callWebHookOf(repository.owner, repository.name, WebHook.PullRequestReviewComment){
- val users = getAccountsByUserNames(Set(repository.owner, pullRequest.requestUserName, issue.openedUserName), Set(sender))
- for{
+ callWebHookOf(repository.owner, repository.name, WebHook.PullRequestReviewComment) {
+ val users =
+ getAccountsByUserNames(Set(repository.owner, pullRequest.requestUserName, issue.openedUserName), Set(sender))
+ for {
baseOwner <- users.get(repository.owner)
headOwner <- users.get(pullRequest.requestUserName)
issueUser <- users.get(issue.openedUserName)
- assignee = issue.assignedUserName.flatMap { userName => getAccountByUserName(userName, false) }
- headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
- labels = getIssueLabels(pullRequest.userName, pullRequest.repositoryName, issue.issueId).map(ApiLabel(_, RepositoryName(pullRequest.userName, pullRequest.repositoryName)))
+ assignee = issue.assignedUserName.flatMap { userName =>
+ getAccountByUserName(userName, false)
+ }
+ headRepo <- getRepository(pullRequest.requestUserName, pullRequest.requestRepositoryName)
+ labels = getIssueLabels(pullRequest.userName, pullRequest.repositoryName, issue.issueId)
+ .map(ApiLabel(_, RepositoryName(pullRequest.userName, pullRequest.repositoryName)))
} yield {
WebHookPullRequestReviewCommentPayload(
- action = action,
- comment = comment,
- issue = issue,
- issueUser = issueUser,
- assignee = assignee,
- pullRequest = pullRequest,
+ action = action,
+ comment = comment,
+ issue = issue,
+ issueUser = issueUser,
+ assignee = assignee,
+ pullRequest = pullRequest,
headRepository = headRepo,
- headOwner = headOwner,
+ headOwner = headOwner,
baseRepository = repository,
- baseOwner = baseOwner,
- labels = labels,
- sender = sender,
- mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
+ baseOwner = baseOwner,
+ labels = labels,
+ sender = sender,
+ mergedComment = getMergedComment(repository.owner, repository.name, issue.issueId)
)
}
}
@@ -343,26 +492,34 @@
self: AccountService with RepositoryService with PullRequestService with IssuesService =>
import WebHookService._
- def callIssueCommentWebHook(repository: RepositoryService.RepositoryInfo, issue: Issue, issueCommentId: Int, sender: Account)
- (implicit s: Session, c: JsonFormat.Context): Unit = {
- callWebHookOf(repository.owner, repository.name, WebHook.IssueComment){
- for{
+ def callIssueCommentWebHook(
+ repository: RepositoryService.RepositoryInfo,
+ issue: Issue,
+ issueCommentId: Int,
+ sender: Account
+ )(implicit s: Session, c: JsonFormat.Context): Unit = {
+ callWebHookOf(repository.owner, repository.name, WebHook.IssueComment) {
+ for {
issueComment <- getComment(repository.owner, repository.name, issueCommentId.toString())
- users = getAccountsByUserNames(Set(issue.openedUserName, repository.owner, issueComment.commentedUserName), Set(sender))
+ users = getAccountsByUserNames(
+ Set(issue.openedUserName, repository.owner, issueComment.commentedUserName),
+ Set(sender)
+ )
issueUser <- users.get(issue.openedUserName)
repoOwner <- users.get(repository.owner)
commenter <- users.get(issueComment.commentedUserName)
labels = getIssueLabels(repository.owner, repository.name, issue.issueId)
} yield {
WebHookIssueCommentPayload(
- issue = issue,
- issueUser = issueUser,
- comment = issueComment,
- commentUser = commenter,
- repository = repository,
+ issue = issue,
+ issueUser = issueUser,
+ comment = issueComment,
+ commentUser = commenter,
+ repository = repository,
repositoryUser = repoOwner,
- sender = sender,
- labels = labels)
+ sender = sender,
+ labels = labels
+ )
}
}
}
@@ -379,24 +536,30 @@
ref_type: String,
master_branch: String,
repository: ApiRepository
- ) extends FieldSerializable with WebHookPayload {
+ ) extends FieldSerializable
+ with WebHookPayload {
val pusher_type = "user"
}
object WebHookCreatePayload {
- def apply(git: Git, sender: Account, refName: String, repositoryInfo: RepositoryInfo,
- commits: List[CommitInfo], repositoryOwner: Account,
- ref: String, refType: String): WebHookCreatePayload =
+ def apply(
+ git: Git,
+ sender: Account,
+ refName: String,
+ repositoryInfo: RepositoryInfo,
+ commits: List[CommitInfo],
+ repositoryOwner: Account,
+ ref: String,
+ refType: String
+ ): WebHookCreatePayload =
WebHookCreatePayload(
- sender = ApiUser(sender),
- ref = ref,
- ref_type = refType,
- description = repositoryInfo.repository.description.getOrElse(""),
+ sender = ApiUser(sender),
+ ref = ref,
+ ref_type = refType,
+ description = repositoryInfo.repository.description.getOrElse(""),
master_branch = repositoryInfo.repository.defaultBranch,
- repository = ApiRepository.forWebhookPayload(
- repositoryInfo,
- owner= ApiUser(repositoryOwner))
+ repository = ApiRepository.forWebhookPayload(repositoryInfo, owner = ApiUser(repositoryOwner))
)
}
@@ -409,30 +572,38 @@
after: String,
commits: List[ApiCommit],
repository: ApiRepository
- ) extends FieldSerializable with WebHookPayload {
+ ) extends FieldSerializable
+ with WebHookPayload {
val compare = commits.size match {
- case 0 => ApiPath(s"/${repository.full_name}") // maybe test hook on un-initialized repository
- case 1 => ApiPath(s"/${repository.full_name}/commit/${after}")
- case _ if before.forall(_=='0') => ApiPath(s"/${repository.full_name}/compare/${commits.head.id}^...${after}")
- case _ => ApiPath(s"/${repository.full_name}/compare/${before}...${after}")
+ case 0 => ApiPath(s"/${repository.full_name}") // maybe test hook on un-initialized repository
+ case 1 => ApiPath(s"/${repository.full_name}/commit/${after}")
+ case _ if before.forall(_ == '0') => ApiPath(s"/${repository.full_name}/compare/${commits.head.id}^...${after}")
+ case _ => ApiPath(s"/${repository.full_name}/compare/${before}...${after}")
}
val head_commit = commits.lastOption
}
object WebHookPushPayload {
- def apply(git: Git, sender: Account, refName: String, repositoryInfo: RepositoryInfo,
- commits: List[CommitInfo], repositoryOwner: Account,
- newId: ObjectId, oldId: ObjectId): WebHookPushPayload =
+ def apply(
+ git: Git,
+ sender: Account,
+ refName: String,
+ repositoryInfo: RepositoryInfo,
+ commits: List[CommitInfo],
+ repositoryOwner: Account,
+ newId: ObjectId,
+ oldId: ObjectId
+ ): WebHookPushPayload =
WebHookPushPayload(
- pusher = ApiPusher(sender),
- sender = ApiUser(sender),
- ref = refName,
- before = ObjectId.toString(oldId),
- after = ObjectId.toString(newId),
- commits = commits.map{ commit => ApiCommit.forWebhookPayload(git, RepositoryName(repositoryInfo), commit) },
- repository = ApiRepository.forWebhookPayload(
- repositoryInfo,
- owner= ApiUser(repositoryOwner))
+ pusher = ApiPusher(sender),
+ sender = ApiUser(sender),
+ ref = refName,
+ before = ObjectId.toString(oldId),
+ after = ObjectId.toString(newId),
+ commits = commits.map { commit =>
+ ApiCommit.forWebhookPayload(git, RepositoryName(repositoryInfo), commit)
+ },
+ repository = ApiRepository.forWebhookPayload(repositoryInfo, owner = ApiUser(repositoryOwner))
)
def createDummyPayload(sender: Account): WebHookPushPayload =
@@ -453,7 +624,8 @@
number: Int,
repository: ApiRepository,
issue: ApiIssue,
- sender: ApiUser) extends WebHookPayload
+ sender: ApiUser
+ ) extends WebHookPayload
// https://developer.github.com/v3/activity/events/types/#pullrequestevent
case class WebHookPullRequestPayload(
@@ -464,40 +636,42 @@
sender: ApiUser
) extends WebHookPayload
- object WebHookPullRequestPayload{
- def apply(action: String,
- issue: Issue,
- issueUser: Account,
- assignee: Option[Account],
- pullRequest: PullRequest,
- headRepository: RepositoryInfo,
- headOwner: Account,
- baseRepository: RepositoryInfo,
- baseOwner: Account,
- labels: List[ApiLabel],
- sender: Account,
- mergedComment: Option[(IssueComment, Account)]): WebHookPullRequestPayload = {
+ object WebHookPullRequestPayload {
+ def apply(
+ action: String,
+ issue: Issue,
+ issueUser: Account,
+ assignee: Option[Account],
+ pullRequest: PullRequest,
+ headRepository: RepositoryInfo,
+ headOwner: Account,
+ baseRepository: RepositoryInfo,
+ baseOwner: Account,
+ labels: List[ApiLabel],
+ sender: Account,
+ mergedComment: Option[(IssueComment, Account)]
+ ): WebHookPullRequestPayload = {
val headRepoPayload = ApiRepository(headRepository, headOwner)
val baseRepoPayload = ApiRepository(baseRepository, baseOwner)
val senderPayload = ApiUser(sender)
val pr = ApiPullRequest(
- issue = issue,
- pullRequest = pullRequest,
- headRepo = headRepoPayload,
- baseRepo = baseRepoPayload,
- user = ApiUser(issueUser),
- labels = labels,
- assignee = assignee.map(ApiUser.apply),
+ issue = issue,
+ pullRequest = pullRequest,
+ headRepo = headRepoPayload,
+ baseRepo = baseRepoPayload,
+ user = ApiUser(issueUser),
+ labels = labels,
+ assignee = assignee.map(ApiUser.apply),
mergedComment = mergedComment
)
WebHookPullRequestPayload(
- action = action,
- number = issue.issueId,
- repository = pr.base.repo,
+ action = action,
+ number = issue.issueId,
+ repository = pr.base.repo,
pull_request = pr,
- sender = senderPayload
+ sender = senderPayload
)
}
}
@@ -513,20 +687,28 @@
object WebHookIssueCommentPayload {
def apply(
- issue: Issue,
- issueUser: Account,
- comment: IssueComment,
- commentUser: Account,
- repository: RepositoryInfo,
- repositoryUser: Account,
- sender: Account,
- labels: List[Label]): WebHookIssueCommentPayload =
+ issue: Issue,
+ issueUser: Account,
+ comment: IssueComment,
+ commentUser: Account,
+ repository: RepositoryInfo,
+ repositoryUser: Account,
+ sender: Account,
+ labels: List[Label]
+ ): WebHookIssueCommentPayload =
WebHookIssueCommentPayload(
- action = "created",
- repository = ApiRepository(repository, repositoryUser),
- issue = ApiIssue(issue, RepositoryName(repository), ApiUser(issueUser), labels.map(ApiLabel(_, RepositoryName(repository)))),
- comment = ApiComment(comment, RepositoryName(repository), issue.issueId, ApiUser(commentUser), issue.isPullRequest),
- sender = ApiUser(sender))
+ action = "created",
+ repository = ApiRepository(repository, repositoryUser),
+ issue = ApiIssue(
+ issue,
+ RepositoryName(repository),
+ ApiUser(issueUser),
+ labels.map(ApiLabel(_, RepositoryName(repository)))
+ ),
+ comment =
+ ApiComment(comment, RepositoryName(repository), issue.issueId, ApiUser(commentUser), issue.isPullRequest),
+ sender = ApiUser(sender)
+ )
}
// https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
@@ -559,25 +741,26 @@
val senderPayload = ApiUser(sender)
WebHookPullRequestReviewCommentPayload(
- action = action,
- comment = ApiPullRequestReviewComment(
- comment = comment,
- commentedUser = senderPayload,
+ action = action,
+ comment = ApiPullRequestReviewComment(
+ comment = comment,
+ commentedUser = senderPayload,
repositoryName = RepositoryName(baseRepository),
- issueId = issue.issueId
+ issueId = issue.issueId
),
pull_request = ApiPullRequest(
- issue = issue,
- pullRequest = pullRequest,
- headRepo = headRepoPayload,
- baseRepo = baseRepoPayload,
- user = ApiUser(issueUser),
- labels = labels,
- assignee = assignee.map(ApiUser.apply),
+ issue = issue,
+ pullRequest = pullRequest,
+ headRepo = headRepoPayload,
+ baseRepo = baseRepoPayload,
+ user = ApiUser(issueUser),
+ labels = labels,
+ assignee = assignee.map(ApiUser.apply),
mergedComment = mergedComment
),
- repository = baseRepoPayload,
- sender = senderPayload)
+ repository = baseRepoPayload,
+ sender = senderPayload
+ )
}
}
@@ -614,14 +797,15 @@
sender: Account
): WebHookGollumPayload = {
WebHookGollumPayload(
- pages = pages.map { case (action, pageName, sha) =>
- WebHookGollumPagePayload(
- action = action,
- page_name = pageName,
- title = pageName,
- sha = sha,
- html_url = ApiPath(s"/${RepositoryName(repository).fullName}/wiki/${StringUtil.urlDecode(pageName)}")
- )
+ pages = pages.map {
+ case (action, pageName, sha) =>
+ WebHookGollumPagePayload(
+ action = action,
+ page_name = pageName,
+ title = pageName,
+ sha = sha,
+ html_url = ApiPath(s"/${RepositoryName(repository).fullName}/wiki/${StringUtil.urlDecode(pageName)}")
+ )
},
repository = ApiRepository(repository, repositoryUser),
sender = ApiUser(sender)
diff --git a/src/main/scala/gitbucket/core/service/WikiService.scala b/src/main/scala/gitbucket/core/service/WikiService.scala
index 921db3f..9330fa4 100644
--- a/src/main/scala/gitbucket/core/service/WikiService.scala
+++ b/src/main/scala/gitbucket/core/service/WikiService.scala
@@ -39,12 +39,11 @@
*/
case class WikiPageHistoryInfo(name: String, committer: String, message: String, date: Date)
+ def wikiHttpUrl(repositoryInfo: RepositoryInfo)(implicit context: Context): String =
+ RepositoryService.httpUrl(repositoryInfo.owner, repositoryInfo.name + ".wiki")
- def wikiHttpUrl(repositoryInfo: RepositoryInfo)(implicit context: Context): String
- = RepositoryService.httpUrl(repositoryInfo.owner, repositoryInfo.name + ".wiki")
-
- def wikiSshUrl(repositoryInfo: RepositoryInfo)(implicit context: Context): Option[String]
- = RepositoryService.sshUrl(repositoryInfo.owner, repositoryInfo.name + ".wiki")
+ def wikiSshUrl(repositoryInfo: RepositoryInfo)(implicit context: Context): Option[String] =
+ RepositoryService.sshUrl(repositoryInfo.owner, repositoryInfo.name + ".wiki")
}
@@ -52,11 +51,20 @@
import WikiService._
def createWikiRepository(loginAccount: Account, owner: String, repository: String): Unit =
- LockUtil.lock(s"${owner}/${repository}/wiki"){
- defining(Directory.getWikiRepositoryDir(owner, repository)){ dir =>
- if(!dir.exists){
+ LockUtil.lock(s"${owner}/${repository}/wiki") {
+ defining(Directory.getWikiRepositoryDir(owner, repository)) { dir =>
+ if (!dir.exists) {
JGitUtil.initRepository(dir)
- saveWikiPage(owner, repository, "Home", "Home", s"Welcome to the ${repository} wiki!!", loginAccount, "Initial Commit", None)
+ saveWikiPage(
+ owner,
+ repository,
+ "Home",
+ "Home",
+ s"Welcome to the ${repository} wiki!!",
+ loginAccount,
+ "Initial Commit",
+ None
+ )
}
}
}
@@ -65,11 +73,16 @@
* Returns the wiki page.
*/
def getWikiPage(owner: String, repository: String, pageName: String): Option[WikiPageInfo] = {
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- if(!JGitUtil.isEmpty(git)){
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ if (!JGitUtil.isEmpty(git)) {
JGitUtil.getFileList(git, "master", ".").find(_.name == pageName + ".md").map { file =>
- WikiPageInfo(file.name, StringUtil.convertFromByteArray(git.getRepository.open(file.id).getBytes),
- file.author, file.time, file.commitId)
+ WikiPageInfo(
+ file.name,
+ StringUtil.convertFromByteArray(git.getRepository.open(file.id).getBytes),
+ file.author,
+ file.time,
+ file.commitId
+ )
}
} else None
}
@@ -79,9 +92,11 @@
* Returns the list of wiki page names.
*/
def getWikiPageList(owner: String, repository: String): List[String] = {
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- JGitUtil.getFileList(git, "master", ".")
- .filter(_.name.endsWith(".md")).filterNot(_.name.startsWith("_"))
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ JGitUtil
+ .getFileList(git, "master", ".")
+ .filter(_.name.endsWith(".md"))
+ .filterNot(_.name.startsWith("_"))
.map(_.name.stripSuffix(".md"))
.sortBy(x => x)
}
@@ -90,15 +105,20 @@
/**
* Reverts specified changes.
*/
- def revertWikiPage(owner: String, repository: String, from: String, to: String,
- committer: Account, pageName: Option[String]): Boolean = {
+ def revertWikiPage(
+ owner: String,
+ repository: String,
+ from: String,
+ to: String,
+ committer: Account,
+ pageName: Option[String]
+ ): Boolean = {
case class RevertInfo(operation: String, filePath: String, source: String)
try {
- LockUtil.lock(s"${owner}/${repository}/wiki"){
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
-
+ LockUtil.lock(s"${owner}/${repository}/wiki") {
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
val reader = git.getRepository.newObjectReader
val oldTreeIter = new CanonicalTreeParser
oldTreeIter.reset(reader, git.getRepository.resolve(from + "^{tree}"))
@@ -113,7 +133,7 @@
}
}
- val patch = using(new java.io.ByteArrayOutputStream()){ out =>
+ val patch = using(new java.io.ByteArrayOutputStream()) { out =>
val formatter = new DiffFormatter(out)
formatter.setRepository(git.getRepository)
formatter.format(diffs.asJava)
@@ -122,21 +142,22 @@
val p = new Patch()
p.parse(new ByteArrayInputStream(patch.getBytes("UTF-8")))
- if(!p.getErrors.isEmpty){
+ if (!p.getErrors.isEmpty) {
throw new PatchFormatException(p.getErrors())
}
val revertInfo = (p.getFiles.asScala.map { fh =>
fh.getChangeType match {
case DiffEntry.ChangeType.MODIFY => {
- val source = getWikiPage(owner, repository, fh.getNewPath.stripSuffix(".md")).map(_.content).getOrElse("")
+ val source =
+ getWikiPage(owner, repository, fh.getNewPath.stripSuffix(".md")).map(_.content).getOrElse("")
val applied = PatchUtil.apply(source, patch, fh)
- if(applied != null){
+ if (applied != null) {
Seq(RevertInfo("ADD", fh.getNewPath, applied))
} else Nil
}
case DiffEntry.ChangeType.ADD => {
val applied = PatchUtil.apply("", patch, fh)
- if(applied != null){
+ if (applied != null) {
Seq(RevertInfo("ADD", fh.getNewPath, applied))
} else Nil
}
@@ -145,7 +166,7 @@
}
case DiffEntry.ChangeType.RENAME => {
val applied = PatchUtil.apply("", patch, fh)
- if(applied != null){
+ if (applied != null) {
Seq(RevertInfo("DELETE", fh.getOldPath, ""), RevertInfo("ADD", fh.getNewPath, applied))
} else {
Seq(RevertInfo("DELETE", fh.getOldPath, ""))
@@ -155,28 +176,41 @@
}
}).flatten
- if(revertInfo.nonEmpty){
- val builder = DirCache.newInCore.builder()
+ if (revertInfo.nonEmpty) {
+ val builder = DirCache.newInCore.builder()
val inserter = git.getRepository.newObjectInserter()
- val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
+ val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
- JGitUtil.processTree(git, headId){ (path, tree) =>
- if(!revertInfo.exists(x => x.filePath == path)){
+ JGitUtil.processTree(git, headId) { (path, tree) =>
+ if (!revertInfo.exists(x => x.filePath == path)) {
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
}
}
revertInfo.filter(_.operation == "ADD").foreach { x =>
- builder.add(JGitUtil.createDirCacheEntry(x.filePath, FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, x.source.getBytes("UTF-8"))))
+ builder.add(
+ JGitUtil.createDirCacheEntry(
+ x.filePath,
+ FileMode.REGULAR_FILE,
+ inserter.insert(Constants.OBJ_BLOB, x.source.getBytes("UTF-8"))
+ )
+ )
}
builder.finish()
- JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
- Constants.HEAD, committer.fullName, committer.mailAddress,
+ JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headId,
+ builder.getDirCache.writeTree(inserter),
+ Constants.HEAD,
+ committer.fullName,
+ committer.mailAddress,
pageName match {
case Some(x) => s"Revert ${from} ... ${to} on ${x}"
case None => s"Revert ${from} ... ${to}"
- })
+ }
+ )
}
}
}
@@ -192,46 +226,70 @@
/**
* Save the wiki page and return the commit id.
*/
- def saveWikiPage(owner: String, repository: String, currentPageName: String, newPageName: String,
- content: String, committer: Account, message: String, currentId: Option[String]): Option[String] = {
- LockUtil.lock(s"${owner}/${repository}/wiki"){
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- val builder = DirCache.newInCore.builder()
+ def saveWikiPage(
+ owner: String,
+ repository: String,
+ currentPageName: String,
+ newPageName: String,
+ content: String,
+ committer: Account,
+ message: String,
+ currentId: Option[String]
+ ): Option[String] = {
+ LockUtil.lock(s"${owner}/${repository}/wiki") {
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ val builder = DirCache.newInCore.builder()
val inserter = git.getRepository.newObjectInserter()
- val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
- var created = true
- var updated = false
- var removed = false
+ val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
+ var created = true
+ var updated = false
+ var removed = false
- if(headId != null){
- JGitUtil.processTree(git, headId){ (path, tree) =>
- if(path == currentPageName + ".md" && currentPageName != newPageName){
+ if (headId != null) {
+ JGitUtil.processTree(git, headId) { (path, tree) =>
+ if (path == currentPageName + ".md" && currentPageName != newPageName) {
removed = true
- } else if(path != newPageName + ".md"){
+ } else if (path != newPageName + ".md") {
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
} else {
created = false
- updated = JGitUtil.getContentFromId(git, tree.getEntryObjectId, true).map(new String(_, "UTF-8") != content).getOrElse(false)
+ updated = JGitUtil
+ .getContentFromId(git, tree.getEntryObjectId, true)
+ .map(new String(_, "UTF-8") != content)
+ .getOrElse(false)
}
}
}
- if(created || updated || removed){
- builder.add(JGitUtil.createDirCacheEntry(newPageName + ".md", FileMode.REGULAR_FILE, inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))))
+ if (created || updated || removed) {
+ builder.add(
+ JGitUtil.createDirCacheEntry(
+ newPageName + ".md",
+ FileMode.REGULAR_FILE,
+ inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))
+ )
+ )
builder.finish()
- val newHeadId = JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
- Constants.HEAD, committer.fullName, committer.mailAddress,
- if(message.trim.isEmpty) {
- if(removed){
+ val newHeadId = JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headId,
+ builder.getDirCache.writeTree(inserter),
+ Constants.HEAD,
+ committer.fullName,
+ committer.mailAddress,
+ if (message.trim.isEmpty) {
+ if (removed) {
s"Rename ${currentPageName} to ${newPageName}"
- } else if(created){
+ } else if (created) {
s"Created ${newPageName}"
} else {
s"Updated ${newPageName}"
}
} else {
message
- })
+ }
+ )
Some(newHeadId.getName)
} else None
@@ -242,26 +300,40 @@
/**
* Delete the wiki page.
*/
- def deleteWikiPage(owner: String, repository: String, pageName: String,
- committer: String, mailAddress: String, message: String): Unit = {
- LockUtil.lock(s"${owner}/${repository}/wiki"){
- using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
- val builder = DirCache.newInCore.builder()
+ def deleteWikiPage(
+ owner: String,
+ repository: String,
+ pageName: String,
+ committer: String,
+ mailAddress: String,
+ message: String
+ ): Unit = {
+ LockUtil.lock(s"${owner}/${repository}/wiki") {
+ using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ val builder = DirCache.newInCore.builder()
val inserter = git.getRepository.newObjectInserter()
- val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
- var removed = false
+ val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
+ var removed = false
- JGitUtil.processTree(git, headId){ (path, tree) =>
- if(path != pageName + ".md"){
+ JGitUtil.processTree(git, headId) { (path, tree) =>
+ if (path != pageName + ".md") {
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
} else {
removed = true
}
}
- if(removed){
+ if (removed) {
builder.finish()
- JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter),
- Constants.HEAD, committer, mailAddress, message)
+ JGitUtil.createNewCommit(
+ git,
+ inserter,
+ headId,
+ builder.getDirCache.writeTree(inserter),
+ Constants.HEAD,
+ committer,
+ mailAddress,
+ message
+ )
}
}
}
diff --git a/src/main/scala/gitbucket/core/servlet/ApiAuthenticationFilter.scala b/src/main/scala/gitbucket/core/servlet/ApiAuthenticationFilter.scala
index c3bd85c..cca7d7b 100644
--- a/src/main/scala/gitbucket/core/servlet/ApiAuthenticationFilter.scala
+++ b/src/main/scala/gitbucket/core/servlet/ApiAuthenticationFilter.scala
@@ -8,7 +8,6 @@
import gitbucket.core.service.{AccessTokenService, AccountService, SystemSettingsService}
import gitbucket.core.util.{AuthUtil, Keys}
-
class ApiAuthenticationFilter extends Filter with AccessTokenService with AccountService with SystemSettingsService {
override def init(filterConfig: FilterConfig): Unit = {}
@@ -19,15 +18,18 @@
implicit val request = req.asInstanceOf[HttpServletRequest]
implicit val session = req.getAttribute(Keys.Request.DBSession).asInstanceOf[slick.jdbc.JdbcBackend#Session]
val response = res.asInstanceOf[HttpServletResponse]
- Option(request.getHeader("Authorization")).map{
- case auth if auth.startsWith("token ") => AccessTokenService.getAccountByAccessToken(auth.substring(6).trim).toRight(())
- case auth if auth.startsWith("Basic ") => doBasicAuth(auth, loadSystemSettings(), request).toRight(())
- case _ => Left(())
- }.orElse{
- Option(request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]).map(Right(_))
- } match {
+ Option(request.getHeader("Authorization"))
+ .map {
+ case auth if auth.startsWith("token ") =>
+ AccessTokenService.getAccountByAccessToken(auth.substring(6).trim).toRight(())
+ case auth if auth.startsWith("Basic ") => doBasicAuth(auth, loadSystemSettings(), request).toRight(())
+ case _ => Left(())
+ }
+ .orElse {
+ Option(request.getSession.getAttribute(Keys.Session.LoginAccount).asInstanceOf[Account]).map(Right(_))
+ } match {
case Some(Right(account)) => request.setAttribute(Keys.Session.LoginAccount, account); chain.doFilter(req, res)
- case None => chain.doFilter(req, res)
+ case None => chain.doFilter(req, res)
case Some(Left(_)) => {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED)
response.setContentType("application/json; charset=utf-8")
diff --git a/src/main/scala/gitbucket/core/servlet/CompositeScalatraFilter.scala b/src/main/scala/gitbucket/core/servlet/CompositeScalatraFilter.scala
index beff25d..56bf848 100644
--- a/src/main/scala/gitbucket/core/servlet/CompositeScalatraFilter.scala
+++ b/src/main/scala/gitbucket/core/servlet/CompositeScalatraFilter.scala
@@ -16,43 +16,46 @@
}
override def init(filterConfig: FilterConfig): Unit = {
- filters.foreach { case (filter, _) =>
- filter.init(filterConfig)
+ filters.foreach {
+ case (filter, _) =>
+ filter.init(filterConfig)
}
}
override def destroy(): Unit = {
- filters.foreach { case (filter, _) =>
- filter.destroy()
+ filters.foreach {
+ case (filter, _) =>
+ filter.destroy()
}
}
override def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain): Unit = {
val contextPath = request.getServletContext.getContextPath
val requestPath = request.asInstanceOf[HttpServletRequest].getRequestURI.substring(contextPath.length)
- val checkPath = if(requestPath.endsWith("/")){
+ val checkPath = if (requestPath.endsWith("/")) {
requestPath
} else {
requestPath + "/"
}
- if(!checkPath.startsWith("/upload/") && !checkPath.startsWith("/git/") && !checkPath.startsWith("/git-lfs/") &&
- !checkPath.startsWith("/plugin-assets/")){
+ if (!checkPath.startsWith("/upload/") && !checkPath.startsWith("/git/") && !checkPath.startsWith("/git-lfs/") &&
+ !checkPath.startsWith("/plugin-assets/")) {
filters
- .filter { case (_, path) =>
- val start = path.replaceFirst("/\\*$", "/")
- checkPath.startsWith(start)
+ .filter {
+ case (_, path) =>
+ val start = path.replaceFirst("/\\*$", "/")
+ checkPath.startsWith(start)
}
- .foreach { case (filter, _) =>
- val mockChain = new MockFilterChain()
- filter.doFilter(request, response, mockChain)
- if(mockChain.continue == false){
- return ()
- }
+ .foreach {
+ case (filter, _) =>
+ val mockChain = new MockFilterChain()
+ filter.doFilter(request, response, mockChain)
+ if (mockChain.continue == false) {
+ return ()
+ }
}
}
-
chain.doFilter(request, response)
}
diff --git a/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala b/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala
index 2febc4e..f542230 100644
--- a/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala
+++ b/src/main/scala/gitbucket/core/servlet/GitAuthenticationFilter.scala
@@ -24,25 +24,31 @@
def destroy(): Unit = {}
def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
- val request = req.asInstanceOf[HttpServletRequest]
+ val request = req.asInstanceOf[HttpServletRequest]
val response = res.asInstanceOf[HttpServletResponse]
- val wrappedResponse = new HttpServletResponseWrapper(response){
+ val wrappedResponse = new HttpServletResponseWrapper(response) {
override def setCharacterEncoding(encoding: String) = {}
}
- val isUpdating = request.getRequestURI.endsWith("/git-receive-pack") || "service=git-receive-pack".equals(request.getQueryString)
+ val isUpdating = request.getRequestURI.endsWith("/git-receive-pack") || "service=git-receive-pack".equals(
+ request.getQueryString
+ )
val settings = loadSystemSettings()
try {
- PluginRegistry().getRepositoryRouting(request.gitRepositoryPath).map { case GitRepositoryRouting(_, _, filter) =>
- // served by plug-ins
- pluginRepository(request, wrappedResponse, chain, settings, isUpdating, filter)
+ PluginRegistry()
+ .getRepositoryRouting(request.gitRepositoryPath)
+ .map {
+ case GitRepositoryRouting(_, _, filter) =>
+ // served by plug-ins
+ pluginRepository(request, wrappedResponse, chain, settings, isUpdating, filter)
- }.getOrElse {
- // default repositories
- defaultRepository(request, wrappedResponse, chain, settings, isUpdating)
- }
+ }
+ .getOrElse {
+ // default repositories
+ defaultRepository(request, wrappedResponse, chain, settings, isUpdating)
+ }
} catch {
case ex: Exception => {
logger.error("error", ex)
@@ -51,8 +57,14 @@
}
}
- private def pluginRepository(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain,
- settings: SystemSettings, isUpdating: Boolean, filter: GitRepositoryFilter): Unit = {
+ private def pluginRepository(
+ request: HttpServletRequest,
+ response: HttpServletResponse,
+ chain: FilterChain,
+ settings: SystemSettings,
+ isUpdating: Boolean,
+ filter: GitRepositoryFilter
+ ): Unit = {
Database() withSession { implicit session =>
val account = for {
authorizationHeader <- Option(request.getHeader("Authorization"))
@@ -70,8 +82,13 @@
}
}
- private def defaultRepository(request: HttpServletRequest, response: HttpServletResponse, chain: FilterChain,
- settings: SystemSettings, isUpdating: Boolean): Unit = {
+ private def defaultRepository(
+ request: HttpServletRequest,
+ response: HttpServletResponse,
+ chain: FilterChain,
+ settings: SystemSettings,
+ isUpdating: Boolean
+ ): Unit = {
val action = request.paths match {
case Array(_, repositoryOwner, repositoryName, _*) =>
Database() withSession { implicit session =>
@@ -85,59 +102,65 @@
val passed = for {
authorizationHeader <- Option(request.getHeader("Authorization"))
account <- authenticateByHeader(authorizationHeader, settings)
- } yield if (isUpdating) {
- if (hasDeveloperRole(repository.owner, repository.name, Some(account))) {
- request.setAttribute(Keys.Request.UserName, account.userName)
- true
- } else false
- } else if(repository.repository.isPrivate){
- if (hasGuestRole(repository.owner, repository.name, Some(account))) {
- request.setAttribute(Keys.Request.UserName, account.userName)
- true
- } else false
- } else true
+ } yield
+ if (isUpdating) {
+ if (hasDeveloperRole(repository.owner, repository.name, Some(account))) {
+ request.setAttribute(Keys.Request.UserName, account.userName)
+ true
+ } else false
+ } else if (repository.repository.isPrivate) {
+ if (hasGuestRole(repository.owner, repository.name, Some(account))) {
+ request.setAttribute(Keys.Request.UserName, account.userName)
+ true
+ } else false
+ } else true
passed.getOrElse(false)
}
- if (execute) {
- () => chain.doFilter(request, response)
- } else {
- () => AuthUtil.requireAuth(response)
+ if (execute) { () =>
+ chain.doFilter(request, response)
+ } else { () =>
+ AuthUtil.requireAuth(response)
}
}
- case None => () => {
- logger.debug(s"Repository ${repositoryOwner}/${repositoryName} is not found.")
- response.sendError(HttpServletResponse.SC_NOT_FOUND)
- }
+ case None =>
+ () =>
+ {
+ logger.debug(s"Repository ${repositoryOwner}/${repositoryName} is not found.")
+ response.sendError(HttpServletResponse.SC_NOT_FOUND)
+ }
}
}
- case _ => () => {
- logger.debug(s"Not enough path arguments: ${request.paths}")
- response.sendError(HttpServletResponse.SC_NOT_FOUND)
- }
+ case _ =>
+ () =>
+ {
+ logger.debug(s"Not enough path arguments: ${request.paths}")
+ response.sendError(HttpServletResponse.SC_NOT_FOUND)
+ }
}
action()
}
/**
- * Authenticate by an Authorization header.
- * This accepts one of the following credentials:
- * - username and password
- * - username and personal access token
- *
- * @param authorizationHeader Authorization header
- * @param settings system settings
- * @param s database session
- * @return an account or none
- */
- private def authenticateByHeader(authorizationHeader: String,
- settings: SystemSettings)(implicit s: Session): Option[Account] = {
+ * Authenticate by an Authorization header.
+ * This accepts one of the following credentials:
+ * - username and password
+ * - username and personal access token
+ *
+ * @param authorizationHeader Authorization header
+ * @param settings system settings
+ * @param s database session
+ * @return an account or none
+ */
+ private def authenticateByHeader(authorizationHeader: String, settings: SystemSettings)(
+ implicit s: Session
+ ): Option[Account] = {
val Array(username, password) = AuthUtil.decodeAuthHeader(authorizationHeader).split(":", 2)
authenticate(settings, username, password).orElse {
AccessTokenService.getAccountByAccessToken(password) match {
case Some(account) if account.userName == username => Some(account)
- case _ => None
+ case _ => None
}
}
}
diff --git a/src/main/scala/gitbucket/core/servlet/GitLfsTransferServlet.scala b/src/main/scala/gitbucket/core/servlet/GitLfsTransferServlet.scala
index 903a1d9..f9f66dd 100644
--- a/src/main/scala/gitbucket/core/servlet/GitLfsTransferServlet.scala
+++ b/src/main/scala/gitbucket/core/servlet/GitLfsTransferServlet.scala
@@ -25,17 +25,16 @@
(owner, repository, oid) <- getPathInfo(req, res) if checkToken(req, oid)
} yield {
val file = new File(FileUtil.getLfsFilePath(owner, repository, oid))
- if(file.exists()){
+ if (file.exists()) {
res.setStatus(HttpStatus.SC_OK)
res.setContentType("application/octet-stream")
res.setContentLength(file.length.toInt)
- using(new FileInputStream(file), res.getOutputStream){ (in, out) =>
+ using(new FileInputStream(file), res.getOutputStream) { (in, out) =>
IOUtils.copy(in, out)
out.flush()
}
} else {
- sendError(res, HttpStatus.SC_NOT_FOUND,
- MessageFormat.format("Object ''{0}'' not found", oid))
+ sendError(res, HttpStatus.SC_NOT_FOUND, MessageFormat.format("Object ''{0}'' not found", oid))
}
}
}
@@ -46,7 +45,7 @@
} yield {
val file = new File(FileUtil.getLfsFilePath(owner, repository, oid))
FileUtils.forceMkdir(file.getParentFile)
- using(req.getInputStream, new FileOutputStream(file)){ (in, out) =>
+ using(req.getInputStream, new FileOutputStream(file)) { (in, out) =>
IOUtils.copy(in, out)
}
res.setStatus(HttpStatus.SC_OK)
@@ -55,7 +54,7 @@
private def checkToken(req: HttpServletRequest, oid: String): Boolean = {
val token = req.getHeader("Authorization")
- if(token != null){
+ if (token != null) {
val Array(expireAt, targetOid) = StringUtil.decodeBlowfish(token).split(" ")
oid == targetOid && expireAt.toLong > System.currentTimeMillis
} else {
@@ -66,18 +65,16 @@
private def getPathInfo(req: HttpServletRequest, res: HttpServletResponse): Option[(String, String, String)] = {
req.getRequestURI.substring(1).split("/").reverse match {
case Array(oid, repository, owner, _*) => Some((owner, repository, oid))
- case _ => None
+ case _ => None
}
}
private def sendError(res: HttpServletResponse, status: Int, message: String): Unit = {
res.setStatus(status)
- using(res.getWriter()){ out =>
+ using(res.getWriter()) { out =>
out.write(write(GitLfs.Error(message)))
out.flush()
}
}
}
-
-
diff --git a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala
index eac61a0..0a8d956 100644
--- a/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala
+++ b/src/main/scala/gitbucket/core/servlet/GitRepositoryServlet.scala
@@ -26,7 +26,6 @@
import org.eclipse.jgit.diff.DiffEntry.ChangeType
import org.json4s.jackson.Serialization._
-
/**
* Provides Git repository via HTTP.
*
@@ -50,12 +49,12 @@
override def service(req: HttpServletRequest, res: HttpServletResponse): Unit = {
val agent = req.getHeader("USER-AGENT")
val index = req.getRequestURI.indexOf(".git")
- if(index >= 0 && (agent == null || agent.toLowerCase.indexOf("git") < 0)){
+ if (index >= 0 && (agent == null || agent.toLowerCase.indexOf("git") < 0)) {
// redirect for browsers
val paths = req.getRequestURI.substring(0, index).split("/")
res.sendRedirect(baseUrl(req) + "/" + paths.dropRight(1).last + "/" + paths.last)
- } else if(req.getMethod.toUpperCase == "POST" && req.getRequestURI.endsWith("/info/lfs/objects/batch")){
+ } else if (req.getMethod.toUpperCase == "POST" && req.getRequestURI.endsWith("/info/lfs/objects/batch")) {
serviceGitLfsBatchAPI(req, res)
} else {
@@ -78,39 +77,57 @@
}
case Some(baseUrl) => {
val index = req.getRequestURI.indexOf(".git")
- if(index >= 0){
+ if (index >= 0) {
req.getRequestURI.substring(0, index).split("/").reverse match {
case Array(repository, owner, _*) =>
val timeout = System.currentTimeMillis + (60000 * 10) // 10 min.
val batchResponse = batchRequest.operation match {
case "upload" =>
- GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
- GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
- GitLfs.Actions(
- upload = Some(GitLfs.Action(
- href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
- header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
- expires_at = new Date(timeout)
- ))
+ GitLfs.BatchUploadResponse(
+ "basic",
+ batchRequest.objects.map { requestObject =>
+ GitLfs.BatchResponseObject(
+ requestObject.oid,
+ requestObject.size,
+ true,
+ GitLfs.Actions(
+ upload = Some(
+ GitLfs.Action(
+ href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
+ header =
+ Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
+ expires_at = new Date(timeout)
+ )
+ )
+ )
)
- )
- })
+ }
+ )
case "download" =>
- GitLfs.BatchUploadResponse("basic", batchRequest.objects.map { requestObject =>
- GitLfs.BatchResponseObject(requestObject.oid, requestObject.size, true,
- GitLfs.Actions(
- download = Some(GitLfs.Action(
- href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
- header = Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
- expires_at = new Date(timeout)
- ))
+ GitLfs.BatchUploadResponse(
+ "basic",
+ batchRequest.objects.map { requestObject =>
+ GitLfs.BatchResponseObject(
+ requestObject.oid,
+ requestObject.size,
+ true,
+ GitLfs.Actions(
+ download = Some(
+ GitLfs.Action(
+ href = baseUrl + "/git-lfs/" + owner + "/" + repository + "/" + requestObject.oid,
+ header =
+ Map("Authorization" -> StringUtil.encodeBlowfish(timeout + " " + requestObject.oid)),
+ expires_at = new Date(timeout)
+ )
+ )
+ )
)
- )
- })
+ }
+ )
}
res.setContentType("application/vnd.git-lfs+json")
- using(res.getWriter){ out =>
+ using(res.getWriter) { out =>
out.print(write(batchResponse))
out.flush()
}
@@ -121,18 +138,23 @@
}
}
-class GitBucketRepositoryResolver(parent: FileResolver[HttpServletRequest]) extends RepositoryResolver[HttpServletRequest] {
+class GitBucketRepositoryResolver(parent: FileResolver[HttpServletRequest])
+ extends RepositoryResolver[HttpServletRequest] {
private val resolver = new FileResolver[HttpServletRequest](new File(Directory.GitBucketHome), true)
override def open(req: HttpServletRequest, name: String): Repository = {
// Rewrite repository path if routing is marched
- PluginRegistry().getRepositoryRouting("/" + name).map { case GitRepositoryRouting(urlPattern, localPath, _) =>
- val path = urlPattern.r.replaceFirstIn(name, localPath)
- resolver.open(req, path)
- }.getOrElse {
- parent.open(req, name)
- }
+ PluginRegistry()
+ .getRepositoryRouting("/" + name)
+ .map {
+ case GitRepositoryRouting(urlPattern, localPath, _) =>
+ val path = urlPattern.r.replaceFirstIn(name, localPath)
+ resolver.open(req, path)
+ }
+ .getOrElse {
+ parent.open(req, name)
+ }
}
}
@@ -144,23 +166,25 @@
override def create(request: HttpServletRequest, db: Repository): ReceivePack = {
val receivePack = new ReceivePack(db)
- if(PluginRegistry().getRepositoryRouting(request.gitRepositoryPath).isEmpty){
+ if (PluginRegistry().getRepositoryRouting(request.gitRepositoryPath).isEmpty) {
val pusher = request.getAttribute(Keys.Request.UserName).asInstanceOf[String]
logger.debug("requestURI: " + request.getRequestURI)
logger.debug("pusher:" + pusher)
- defining(request.paths){ paths =>
- val owner = paths(1)
+ defining(request.paths) { paths =>
+ val owner = paths(1)
val repository = paths(2).stripSuffix(".git")
logger.debug("repository:" + owner + "/" + repository)
val settings = loadSystemSettings()
val baseUrl = settings.baseUrl(request)
- val sshUrl = settings.sshAddress.map { x => s"${x.genericUser}@${x.host}:${x.port}" }
+ val sshUrl = settings.sshAddress.map { x =>
+ s"${x.genericUser}@${x.host}:${x.port}"
+ }
- if(!repository.endsWith(".wiki")){
+ if (!repository.endsWith(".wiki")) {
defining(request) { implicit r =>
val hook = new CommitLogHook(owner, repository, pusher, baseUrl, sshUrl)
receivePack.setPreReceiveHook(hook)
@@ -168,9 +192,11 @@
}
}
- if(repository.endsWith(".wiki")){
+ if (repository.endsWith(".wiki")) {
defining(request) { implicit r =>
- receivePack.setPostReceiveHook(new WikiCommitHook(owner, repository.stripSuffix(".wiki"), pusher, baseUrl, sshUrl))
+ receivePack.setPostReceiveHook(
+ new WikiCommitHook(owner, repository.stripSuffix(".wiki"), pusher, baseUrl, sshUrl)
+ )
}
}
}
@@ -183,10 +209,19 @@
import scala.collection.JavaConverters._
class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String, sshUrl: Option[String])
- extends PostReceiveHook with PreReceiveHook
- with RepositoryService with AccountService with IssuesService with ActivityService with PullRequestService with WebHookService
- with LabelsService with PrioritiesService with MilestonesService
- with WebHookPullRequestService with CommitsService {
+ extends PostReceiveHook
+ with PreReceiveHook
+ with RepositoryService
+ with AccountService
+ with IssuesService
+ with ActivityService
+ with PullRequestService
+ with WebHookService
+ with LabelsService
+ with PrioritiesService
+ with MilestonesService
+ with WebHookPullRequestService
+ with CommitsService {
private val logger = LoggerFactory.getLogger(classOf[CommitLogHook])
private var existIds: Seq[String] = Nil
@@ -232,14 +267,14 @@
} else {
command.getType match {
case ReceiveCommand.Type.DELETE => Nil
- case _ => JGitUtil.getCommitLog(git, command.getOldId.name, command.getNewId.name)
+ case _ => JGitUtil.getCommitLog(git, command.getOldId.name, command.getNewId.name)
}
}
val repositoryInfo = getRepository(owner, repository).get
// Update default branch if repository is empty and pushed branch is not current default branch
- if(JGitUtil.isEmpty(git) && commits.nonEmpty && branchName != repositoryInfo.repository.defaultBranch){
+ if (JGitUtil.isEmpty(git) && commits.nonEmpty && branchName != repositoryInfo.repository.defaultBranch) {
saveRepositoryDefaultBranch(owner, repository, branchName)
// Change repository HEAD
using(Git.open(Directory.getRepositoryDir(owner, repository))) { git =>
@@ -274,24 +309,31 @@
case ReceiveCommand.Type.CREATE => recordCreateBranchActivity(owner, repository, pusher, branchName)
case ReceiveCommand.Type.UPDATE => recordPushActivity(owner, repository, pusher, branchName, newCommits)
case ReceiveCommand.Type.DELETE => recordDeleteBranchActivity(owner, repository, pusher, branchName)
- case _ =>
+ case _ =>
}
} else if (refName(1) == "tags") {
command.getType match {
- case ReceiveCommand.Type.CREATE => recordCreateTagActivity(owner, repository, pusher, branchName, newCommits)
- case ReceiveCommand.Type.DELETE => recordDeleteTagActivity(owner, repository, pusher, branchName, newCommits)
+ case ReceiveCommand.Type.CREATE =>
+ recordCreateTagActivity(owner, repository, pusher, branchName, newCommits)
+ case ReceiveCommand.Type.DELETE =>
+ recordDeleteTagActivity(owner, repository, pusher, branchName, newCommits)
case _ =>
}
}
if (refName(1) == "heads") {
command.getType match {
- case ReceiveCommand.Type.CREATE |
- ReceiveCommand.Type.UPDATE |
- ReceiveCommand.Type.UPDATE_NONFASTFORWARD =>
+ case ReceiveCommand.Type.CREATE | ReceiveCommand.Type.UPDATE |
+ ReceiveCommand.Type.UPDATE_NONFASTFORWARD =>
updatePullRequests(owner, repository, branchName)
getAccountByUserName(pusher).map { pusherAccount =>
- callPullRequestWebHookByRequestBranch("synchronize", repositoryInfo, branchName, baseUrl, pusherAccount)
+ callPullRequestWebHookByRequestBranch(
+ "synchronize",
+ repositoryInfo,
+ branchName,
+ baseUrl,
+ pusherAccount
+ )
}
case _ =>
}
@@ -301,21 +343,37 @@
callWebHookOf(owner, repository, WebHook.Push) {
for {
pusherAccount <- getAccountByUserName(pusher)
- ownerAccount <- getAccountByUserName(owner)
+ ownerAccount <- getAccountByUserName(owner)
} yield {
- WebHookPushPayload(git, pusherAccount, command.getRefName, repositoryInfo, newCommits, ownerAccount,
- newId = command.getNewId(), oldId = command.getOldId())
+ WebHookPushPayload(
+ git,
+ pusherAccount,
+ command.getRefName,
+ repositoryInfo,
+ newCommits,
+ ownerAccount,
+ newId = command.getNewId(),
+ oldId = command.getOldId()
+ )
}
}
- if (command.getType == ReceiveCommand.Type.CREATE) {
+ if (command.getType == ReceiveCommand.Type.CREATE) {
callWebHookOf(owner, repository, WebHook.Create) {
for {
pusherAccount <- getAccountByUserName(pusher)
- ownerAccount <- getAccountByUserName(owner)
+ ownerAccount <- getAccountByUserName(owner)
} yield {
val refType = if (refName(1) == "tags") "tag" else "branch"
- WebHookCreatePayload(git, pusherAccount, command.getRefName, repositoryInfo, newCommits, ownerAccount,
- ref = branchName, refType = refType)
+ WebHookCreatePayload(
+ git,
+ pusherAccount,
+ command.getRefName,
+ repositoryInfo,
+ newCommits,
+ ownerAccount,
+ ref = branchName,
+ refType = refType
+ )
}
}
}
@@ -338,7 +396,10 @@
}
class WikiCommitHook(owner: String, repository: String, pusher: String, baseUrl: String, sshUrl: Option[String])
- extends PostReceiveHook with WebHookService with AccountService with RepositoryService {
+ extends PostReceiveHook
+ with WebHookService
+ with AccountService
+ with RepositoryService {
private val logger = LoggerFactory.getLogger(classOf[WikiCommitHook])
@@ -353,37 +414,40 @@
} else {
command.getType match {
case ReceiveCommand.Type.DELETE => None
- case _ => Some((command.getOldId.getName, command.getNewId.name))
+ case _ => Some((command.getOldId.getName, command.getNewId.name))
}
}
- commitIds.map { case (oldCommitId, newCommitId) =>
- val commits = using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
- JGitUtil.getCommitLog(git, oldCommitId, newCommitId).flatMap { commit =>
- val diffs = JGitUtil.getDiffs(git, None, commit.id, false, false)
- diffs.collect { case diff if diff.newPath.toLowerCase.endsWith(".md") =>
- val action = if(diff.changeType == ChangeType.ADD) "created" else "edited"
- val fileName = diff.newPath
- (action, fileName, commit.id)
+ commitIds.map {
+ case (oldCommitId, newCommitId) =>
+ val commits = using(Git.open(Directory.getWikiRepositoryDir(owner, repository))) { git =>
+ JGitUtil.getCommitLog(git, oldCommitId, newCommitId).flatMap { commit =>
+ val diffs = JGitUtil.getDiffs(git, None, commit.id, false, false)
+ diffs.collect {
+ case diff if diff.newPath.toLowerCase.endsWith(".md") =>
+ val action = if (diff.changeType == ChangeType.ADD) "created" else "edited"
+ val fileName = diff.newPath
+ (action, fileName, commit.id)
+ }
}
}
- }
- val pages = commits
- .groupBy { case (action, fileName, commitId) => fileName }
- .map { case (fileName, commits) =>
- (commits.head._1, fileName, commits.last._3)
- }
+ val pages = commits
+ .groupBy { case (action, fileName, commitId) => fileName }
+ .map {
+ case (fileName, commits) =>
+ (commits.head._1, fileName, commits.last._3)
+ }
- callWebHookOf(owner, repository, WebHook.Gollum) {
- for {
- pusherAccount <- getAccountByUserName(pusher)
- repositoryUser <- getAccountByUserName(owner)
- repositoryInfo <- getRepository(owner, repository)
- } yield {
- WebHookGollumPayload(pages.toSeq, repositoryInfo, repositoryUser, pusherAccount)
+ callWebHookOf(owner, repository, WebHook.Gollum) {
+ for {
+ pusherAccount <- getAccountByUserName(pusher)
+ repositoryUser <- getAccountByUserName(owner)
+ repositoryInfo <- getRepository(owner, repository)
+ } yield {
+ WebHookGollumPayload(pages.toSeq, repositoryInfo, repositoryUser, pusherAccount)
+ }
}
- }
}
}
} catch {
diff --git a/src/main/scala/gitbucket/core/servlet/InitializeListener.scala b/src/main/scala/gitbucket/core/servlet/InitializeListener.scala
index 93ec28f..326608b 100644
--- a/src/main/scala/gitbucket/core/servlet/InitializeListener.scala
+++ b/src/main/scala/gitbucket/core/servlet/InitializeListener.scala
@@ -24,7 +24,6 @@
import scala.collection.JavaConverters._
-
/**
* Initialize GitBucket system.
* Update database schema and load plug-ins automatically in the context initializing.
@@ -34,8 +33,9 @@
private val logger = LoggerFactory.getLogger(classOf[InitializeListener])
// ActorSystem for Quartz scheduler
- private val system = ActorSystem("job", ConfigFactory.parseString(
- """
+ private val system = ActorSystem(
+ "job",
+ ConfigFactory.parseString("""
|akka {
| daemonic = on
| coordinated-shutdown.run-by-jvm-shutdown-hook = off
@@ -47,11 +47,12 @@
| }
| }
|}
- """.stripMargin))
+ """.stripMargin)
+ )
override def contextInitialized(event: ServletContextEvent): Unit = {
val dataDir = event.getServletContext.getInitParameter("gitbucket.home")
- if(dataDir != null){
+ if (dataDir != null) {
System.setProperty("gitbucket.home", dataDir)
}
org.h2.Driver.load()
@@ -65,19 +66,22 @@
// Run normal migration
logger.info("Start schema update")
- new Solidbase().migrate(conn, Thread.currentThread.getContextClassLoader, DatabaseConfig.liquiDriver, GitBucketCoreModule)
+ new Solidbase()
+ .migrate(conn, Thread.currentThread.getContextClassLoader, DatabaseConfig.liquiDriver, GitBucketCoreModule)
// Rescue code for users who updated from 3.14 to 4.0.0
// https://github.com/gitbucket/gitbucket/issues/1227
val currentVersion = manager.getCurrentVersion(GitBucketCoreModule.getModuleId)
- val databaseVersion = if(currentVersion == "4.0"){
+ val databaseVersion = if (currentVersion == "4.0") {
manager.updateVersion(GitBucketCoreModule.getModuleId, "4.0.0")
"4.0.0"
} else currentVersion
val gitbucketVersion = GitBucketCoreModule.getVersions.asScala.last.getVersion
- if(databaseVersion != gitbucketVersion){
- throw new IllegalStateException(s"Initialization failed. GitBucket version is ${gitbucketVersion}, but database version is ${databaseVersion}.")
+ if (databaseVersion != gitbucketVersion) {
+ throw new IllegalStateException(
+ s"Initialization failed. GitBucket version is ${gitbucketVersion}, but database version is ${databaseVersion}."
+ )
}
// Install bundled plugins
@@ -98,26 +102,26 @@
logger.info("Check version")
val versionFile = new File(GitBucketHome, "version")
- if(versionFile.exists()){
+ if (versionFile.exists()) {
val version = FileUtils.readFileToString(versionFile, "UTF-8")
- if(version == "3.14"){
+ if (version == "3.14") {
// Initialization for GitBucket 3.14
logger.info("Migration to GitBucket 4.x start")
// Backup current data
val dataMvFile = new File(GitBucketHome, "data.mv.db")
- if(dataMvFile.exists) {
+ if (dataMvFile.exists) {
FileUtils.copyFile(dataMvFile, new File(GitBucketHome, "data.mv.db_3.14"))
}
val dataTraceFile = new File(GitBucketHome, "data.trace.db")
- if(dataTraceFile.exists) {
+ if (dataTraceFile.exists) {
FileUtils.copyFile(dataTraceFile, new File(GitBucketHome, "data.trace.db_3.14"))
}
// Change form
manager.initialize()
manager.updateVersion(GitBucketCoreModule.getModuleId, "4.0.0")
- conn.select("SELECT PLUGIN_ID, VERSION FROM PLUGIN"){ rs =>
+ conn.select("SELECT PLUGIN_ID, VERSION FROM PLUGIN") { rs =>
manager.updateVersion(rs.getString("PLUGIN_ID"), rs.getString("VERSION"))
}
conn.update("DROP TABLE PLUGIN")
@@ -135,8 +139,8 @@
logger.info("Extract bundled plugins")
val cl = Thread.currentThread.getContextClassLoader
try {
- using(cl.getResourceAsStream("plugins/plugins.json")){ pluginsFile =>
- if(pluginsFile != null){
+ using(cl.getResourceAsStream("plugins/plugins.json")) { pluginsFile =>
+ if (pluginsFile != null) {
val pluginsJson = IOUtils.toString(pluginsFile, "UTF-8")
FileUtils.forceMkdir(PluginRepository.LocalRepositoryDir)
@@ -144,19 +148,28 @@
val plugins = PluginRepository.parsePluginJson(pluginsJson)
plugins.foreach { plugin =>
- plugin.versions.sortBy { x => Semver.valueOf(x.version) }.reverse.zipWithIndex.foreach { case (version, i) =>
- val file = new File(PluginRepository.LocalRepositoryDir, version.file)
- if(!file.exists) {
- logger.info(s"Copy ${plugin} to ${file.getAbsolutePath}")
- FileUtils.forceMkdirParent(file)
- using(cl.getResourceAsStream("plugins/" + version.file), new FileOutputStream(file)){ case (in, out) => IOUtils.copy(in, out) }
-
- if(plugin.default && i == 0){
- logger.info(s"Enable ${file.getName} in default")
- FileUtils.copyFile(file, new File(PluginHome, version.file))
- }
+ plugin.versions
+ .sortBy { x =>
+ Semver.valueOf(x.version)
}
- }
+ .reverse
+ .zipWithIndex
+ .foreach {
+ case (version, i) =>
+ val file = new File(PluginRepository.LocalRepositoryDir, version.file)
+ if (!file.exists) {
+ logger.info(s"Copy ${plugin} to ${file.getAbsolutePath}")
+ FileUtils.forceMkdirParent(file)
+ using(cl.getResourceAsStream("plugins/" + version.file), new FileOutputStream(file)) {
+ case (in, out) => IOUtils.copy(in, out)
+ }
+
+ if (plugin.default && i == 0) {
+ logger.info(s"Enable ${file.getName} in default")
+ FileUtils.copyFile(file, new File(PluginHome, version.file))
+ }
+ }
+ }
}
}
}
@@ -183,7 +196,7 @@
def receive = {
case s: String => {
loadSystemSettings().activityLogLimit.foreach { limit =>
- if(limit > 0){
+ if (limit > 0) {
Database() withTransaction { implicit session =>
val rows = deleteOldActivities(limit)
logger.info(s"Deleted ${rows} activity logs")
diff --git a/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala b/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala
index e2261a1..016d2ea 100644
--- a/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala
+++ b/src/main/scala/gitbucket/core/servlet/PluginAssetsServlet.scala
@@ -16,10 +16,11 @@
val path = req.getRequestURI.substring(req.getContextPath.length)
assetsMappings
- .find { case (prefix, _, _) => path.startsWith("/plugin-assets" + prefix) }
- .flatMap { case (prefix, resourcePath, classLoader) =>
- val resourceName = path.substring(("/plugin-assets" + prefix).length)
- Option(classLoader.getResourceAsStream(resourcePath.stripPrefix("/") + resourceName))
+ .find { case (prefix, _, _) => path.startsWith("/plugin-assets" + prefix) }
+ .flatMap {
+ case (prefix, resourcePath, classLoader) =>
+ val resourceName = path.substring(("/plugin-assets" + prefix).length)
+ Option(classLoader.getResourceAsStream(resourcePath.stripPrefix("/") + resourceName))
}
.map { in =>
try {
diff --git a/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala
index 66837e2..9137c15 100644
--- a/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala
+++ b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala
@@ -15,8 +15,9 @@
}
override def destroy(): Unit = {
- PluginRegistry().getControllers().foreach { case (controller, _) =>
- controller.destroy()
+ PluginRegistry().getControllers().foreach {
+ case (controller, _) =>
+ controller.destroy()
}
}
@@ -24,22 +25,25 @@
val contextPath = request.getServletContext.getContextPath
val requestUri = request.asInstanceOf[HttpServletRequest].getRequestURI.substring(contextPath.length)
- PluginRegistry().getControllers()
- .filter { case (_, path) =>
- val start = path.replaceFirst("/\\*$", "/")
- (requestUri + "/").startsWith(start)
+ PluginRegistry()
+ .getControllers()
+ .filter {
+ case (_, path) =>
+ val start = path.replaceFirst("/\\*$", "/")
+ (requestUri + "/").startsWith(start)
}
- .foreach { case (controller, _) =>
- controller match {
- case x: ControllerBase if(x.config == null) => x.init(filterConfig)
- case _ => ()
- }
- val mockChain = new MockFilterChain()
- controller.doFilter(request, response, mockChain)
+ .foreach {
+ case (controller, _) =>
+ controller match {
+ case x: ControllerBase if (x.config == null) => x.init(filterConfig)
+ case _ => ()
+ }
+ val mockChain = new MockFilterChain()
+ controller.doFilter(request, response, mockChain)
- if(mockChain.continue == false){
- return ()
- }
+ if (mockChain.continue == false) {
+ return ()
+ }
}
chain.doFilter(request, response)
diff --git a/src/main/scala/gitbucket/core/servlet/TransactionFilter.scala b/src/main/scala/gitbucket/core/servlet/TransactionFilter.scala
index d6677d1..8c4f335 100644
--- a/src/main/scala/gitbucket/core/servlet/TransactionFilter.scala
+++ b/src/main/scala/gitbucket/core/servlet/TransactionFilter.scala
@@ -23,7 +23,7 @@
def doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain): Unit = {
val servletPath = req.asInstanceOf[HttpServletRequest].getServletPath()
- if(servletPath.startsWith("/assets/") || servletPath == "/git" || servletPath == "/git-lfs"){
+ if (servletPath.startsWith("/assets/") || servletPath == "/git" || servletPath == "/git-lfs") {
// assets and git-lfs don't need transaction
chain.doFilter(req, res)
} else {
diff --git a/src/main/scala/gitbucket/core/ssh/GitCommand.scala b/src/main/scala/gitbucket/core/ssh/GitCommand.scala
index 59a0b1f..0087915 100644
--- a/src/main/scala/gitbucket/core/ssh/GitCommand.scala
+++ b/src/main/scala/gitbucket/core/ssh/GitCommand.scala
@@ -20,7 +20,7 @@
object GitCommand {
val DefaultCommandRegex = """\Agit-(upload|receive)-pack '/([a-zA-Z0-9\-_.]+)/([a-zA-Z0-9\-\+_.]+).git'\Z""".r
- val SimpleCommandRegex = """\Agit-(upload|receive)-pack '/(.+\.git)'\Z""".r
+ val SimpleCommandRegex = """\Agit-(upload|receive)-pack '/(.+\.git)'\Z""".r
}
abstract class GitCommand extends Command with SessionAware {
@@ -80,7 +80,7 @@
}
override def setSession(serverSession: ServerSession) {
- this.authType = PublicKeyAuthenticator.getAuthType(serverSession)
+ this.authType = PublicKeyAuthenticator.getAuthType(serverSession)
}
}
@@ -91,41 +91,43 @@
protected def userName(authType: AuthType): String = {
authType match {
case AuthType.UserAuthType(userName) => userName
- case AuthType.DeployKeyType(_) => owner
+ case AuthType.DeployKeyType(_) => owner
}
}
- protected def isReadableUser(authType: AuthType, repositoryInfo: RepositoryService.RepositoryInfo)
- (implicit session: Session): Boolean = {
+ protected def isReadableUser(authType: AuthType, repositoryInfo: RepositoryService.RepositoryInfo)(
+ implicit session: Session
+ ): Boolean = {
authType match {
case AuthType.UserAuthType(username) => {
getAccountByUserName(username) match {
case Some(account) => hasGuestRole(owner, repoName, Some(account))
- case None => false
+ case None => false
}
}
case AuthType.DeployKeyType(key) => {
getDeployKeys(owner, repoName).filter(sshKey => SshUtil.str2PublicKey(sshKey.publicKey).contains(key)) match {
case List(_) => true
- case _ => false
+ case _ => false
}
}
}
}
- protected def isWritableUser(authType: AuthType, repositoryInfo: RepositoryService.RepositoryInfo)
- (implicit session: Session): Boolean = {
+ protected def isWritableUser(authType: AuthType, repositoryInfo: RepositoryService.RepositoryInfo)(
+ implicit session: Session
+ ): Boolean = {
authType match {
case AuthType.UserAuthType(username) => {
getAccountByUserName(username) match {
case Some(account) => hasDeveloperRole(owner, repoName, Some(account))
- case None => false
+ case None => false
}
}
case AuthType.DeployKeyType(key) => {
getDeployKeys(owner, repoName).filter(sshKey => SshUtil.str2PublicKey(sshKey.publicKey).contains(key)) match {
case List(x) if x.allowWrite => true
- case _ => false
+ case _ => false
}
}
}
@@ -133,18 +135,22 @@
}
-
-class DefaultGitUploadPack(owner: String, repoName: String) extends DefaultGitCommand(owner, repoName)
- with RepositoryService with AccountService with DeployKeyService {
+class DefaultGitUploadPack(owner: String, repoName: String)
+ extends DefaultGitCommand(owner, repoName)
+ with RepositoryService
+ with AccountService
+ with DeployKeyService {
override protected def runTask(authType: AuthType): Unit = {
val execute = Database() withSession { implicit session =>
- getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).map { repositoryInfo =>
- !repositoryInfo.repository.isPrivate || isReadableUser(authType, repositoryInfo)
- }.getOrElse(false)
+ getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", ""))
+ .map { repositoryInfo =>
+ !repositoryInfo.repository.isPrivate || isReadableUser(authType, repositoryInfo)
+ }
+ .getOrElse(false)
}
- if(execute){
+ if (execute) {
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
val repository = git.getRepository
val upload = new UploadPack(repository)
@@ -154,17 +160,22 @@
}
}
-class DefaultGitReceivePack(owner: String, repoName: String, baseUrl: String, sshUrl: Option[String]) extends DefaultGitCommand(owner, repoName)
- with RepositoryService with AccountService with DeployKeyService {
+class DefaultGitReceivePack(owner: String, repoName: String, baseUrl: String, sshUrl: Option[String])
+ extends DefaultGitCommand(owner, repoName)
+ with RepositoryService
+ with AccountService
+ with DeployKeyService {
override protected def runTask(authType: AuthType): Unit = {
val execute = Database() withSession { implicit session =>
- getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).map { repositoryInfo =>
- isWritableUser(authType, repositoryInfo)
- }.getOrElse(false)
+ getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", ""))
+ .map { repositoryInfo =>
+ isWritableUser(authType, repositoryInfo)
+ }
+ .getOrElse(false)
}
- if(execute) {
+ if (execute) {
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
val repository = git.getRepository
val receive = new ReceivePack(repository)
@@ -179,16 +190,18 @@
}
}
-class PluginGitUploadPack(repoName: String, routing: GitRepositoryRouting) extends GitCommand with SystemSettingsService {
+class PluginGitUploadPack(repoName: String, routing: GitRepositoryRouting)
+ extends GitCommand
+ with SystemSettingsService {
override protected def runTask(authType: AuthType): Unit = {
val execute = Database() withSession { implicit session =>
routing.filter.filter("/" + repoName, AuthType.userName(authType), loadSystemSettings(), false)
}
- if(execute){
+ if (execute) {
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
- using(Git.open(new File(Directory.GitBucketHome, path))){ git =>
+ using(Git.open(new File(Directory.GitBucketHome, path))) { git =>
val repository = git.getRepository
val upload = new UploadPack(repository)
upload.upload(in, out, err)
@@ -197,16 +210,18 @@
}
}
-class PluginGitReceivePack(repoName: String, routing: GitRepositoryRouting) extends GitCommand with SystemSettingsService {
+class PluginGitReceivePack(repoName: String, routing: GitRepositoryRouting)
+ extends GitCommand
+ with SystemSettingsService {
override protected def runTask(authType: AuthType): Unit = {
val execute = Database() withSession { implicit session =>
routing.filter.filter("/" + repoName, AuthType.userName(authType), loadSystemSettings(), true)
}
- if(execute){
+ if (execute) {
val path = routing.urlPattern.r.replaceFirstIn(repoName, routing.localPath)
- using(Git.open(new File(Directory.GitBucketHome, path))){ git =>
+ using(Git.open(new File(Directory.GitBucketHome, path))) { git =>
val repository = git.getRepository
val receive = new ReceivePack(repository)
receive.receive(in, out, err)
@@ -215,7 +230,6 @@
}
}
-
class GitCommandFactory(baseUrl: String, sshUrl: Option[String]) extends CommandFactory {
private val logger = LoggerFactory.getLogger(classOf[GitCommandFactory])
@@ -229,17 +243,23 @@
pluginCommand match {
case Some(x) => x
- case None => command match {
- case SimpleCommandRegex ("upload" , repoName) if(pluginRepository(repoName)) => new PluginGitUploadPack (repoName, routing(repoName))
- case SimpleCommandRegex ("receive", repoName) if(pluginRepository(repoName)) => new PluginGitReceivePack(repoName, routing(repoName))
- case DefaultCommandRegex("upload" , owner, repoName) => new DefaultGitUploadPack (owner, repoName)
- case DefaultCommandRegex("receive", owner, repoName) => new DefaultGitReceivePack(owner, repoName, baseUrl, sshUrl)
- case _ => new UnknownCommand(command)
- }
+ case None =>
+ command match {
+ case SimpleCommandRegex("upload", repoName) if (pluginRepository(repoName)) =>
+ new PluginGitUploadPack(repoName, routing(repoName))
+ case SimpleCommandRegex("receive", repoName) if (pluginRepository(repoName)) =>
+ new PluginGitReceivePack(repoName, routing(repoName))
+ case DefaultCommandRegex("upload", owner, repoName) => new DefaultGitUploadPack(owner, repoName)
+ case DefaultCommandRegex("receive", owner, repoName) =>
+ new DefaultGitReceivePack(owner, repoName, baseUrl, sshUrl)
+ case _ => new UnknownCommand(command)
+ }
}
}
- private def pluginRepository(repoName: String): Boolean = PluginRegistry().getRepositoryRouting("/" + repoName).isDefined
- private def routing(repoName: String): GitRepositoryRouting = PluginRegistry().getRepositoryRouting("/" + repoName).get
+ private def pluginRepository(repoName: String): Boolean =
+ PluginRegistry().getRepositoryRouting("/" + repoName).isDefined
+ private def routing(repoName: String): GitRepositoryRouting =
+ PluginRegistry().getRepositoryRouting("/" + repoName).get
}
diff --git a/src/main/scala/gitbucket/core/ssh/NoShell.scala b/src/main/scala/gitbucket/core/ssh/NoShell.scala
index 065bee0..45130e4 100644
--- a/src/main/scala/gitbucket/core/ssh/NoShell.scala
+++ b/src/main/scala/gitbucket/core/ssh/NoShell.scala
@@ -6,7 +6,7 @@
import java.io.{OutputStream, InputStream}
import org.eclipse.jgit.lib.Constants
-class NoShell(sshAddress:SshAddress) extends Factory[Command] {
+class NoShell(sshAddress: SshAddress) extends Factory[Command] {
override def create(): Command = new Command() {
private var in: InputStream = null
private var out: OutputStream = null
diff --git a/src/main/scala/gitbucket/core/ssh/PublicKeyAuthenticator.scala b/src/main/scala/gitbucket/core/ssh/PublicKeyAuthenticator.scala
index e3be40d..2f79f4e 100644
--- a/src/main/scala/gitbucket/core/ssh/PublicKeyAuthenticator.scala
+++ b/src/main/scala/gitbucket/core/ssh/PublicKeyAuthenticator.scala
@@ -16,7 +16,7 @@
// put in the ServerSession here to be read by GitCommand later
private val authTypeSessionKey = new AttributeStore.AttributeKey[AuthType]
- def putAuthType(serverSession: ServerSession, authType: AuthType):Unit =
+ def putAuthType(serverSession: ServerSession, authType: AuthType): Unit =
serverSession.setAttribute(authTypeSessionKey, authType)
def getAuthType(serverSession: ServerSession): Option[AuthType] =
@@ -34,13 +34,16 @@
def userName(authType: AuthType): Option[String] = {
authType match {
case UserAuthType(userName) => Some(userName)
- case _ => None
+ case _ => None
}
}
}
}
-class PublicKeyAuthenticator(genericUser: String) extends PublickeyAuthenticator with SshKeyService with DeployKeyService {
+class PublicKeyAuthenticator(genericUser: String)
+ extends PublickeyAuthenticator
+ with SshKeyService
+ with DeployKeyService {
private val logger = LoggerFactory.getLogger(classOf[PublicKeyAuthenticator])
override def authenticate(username: String, key: PublicKey, session: ServerSession): Boolean = {
@@ -53,7 +56,9 @@
}
}
- private def authenticateLoginUser(userName: String, key: PublicKey, session: ServerSession)(implicit s: Session): Boolean = {
+ private def authenticateLoginUser(userName: String, key: PublicKey, session: ServerSession)(
+ implicit s: Session
+ ): Boolean = {
val authenticated = getPublicKeys(userName).map(_.publicKey).flatMap(SshUtil.str2PublicKey).contains(key)
if (authenticated) {
@@ -65,11 +70,16 @@
authenticated
}
- private def authenticateGenericUser(userName: String, key: PublicKey, session: ServerSession, genericUser: String)(implicit s: Session): Boolean = {
+ private def authenticateGenericUser(userName: String, key: PublicKey, session: ServerSession, genericUser: String)(
+ implicit s: Session
+ ): Boolean = {
// find all users having the key we got from ssh
- val possibleUserNames = getAllKeys().filter { sshKey =>
- SshUtil.str2PublicKey(sshKey.publicKey).contains(key)
- }.map(_.userName).distinct
+ val possibleUserNames = getAllKeys()
+ .filter { sshKey =>
+ SshUtil.str2PublicKey(sshKey.publicKey).contains(key)
+ }
+ .map(_.userName)
+ .distinct
// determine the user - if different accounts share the same key, tough luck
val uniqueUserName = possibleUserNames match {
@@ -77,27 +87,29 @@
case _ => None
}
- uniqueUserName.map { userName =>
- // found public key for user
- logger.info(s"authentication as generic user ${genericUser} succeeded, identified ${userName}")
- PublicKeyAuthenticator.putAuthType(session, AuthType.UserAuthType(userName))
- true
- }.getOrElse {
- // search deploy keys
- val existsDeployKey = getAllDeployKeys().exists { sshKey =>
- SshUtil.str2PublicKey(sshKey.publicKey).contains(key)
- }
- if(existsDeployKey){
- // found deploy key for repository
- PublicKeyAuthenticator.putAuthType(session, AuthType.DeployKeyType(key))
- logger.info(s"authentication as generic user ${genericUser} succeeded, deploy key was found")
+ uniqueUserName
+ .map { userName =>
+ // found public key for user
+ logger.info(s"authentication as generic user ${genericUser} succeeded, identified ${userName}")
+ PublicKeyAuthenticator.putAuthType(session, AuthType.UserAuthType(userName))
true
- } else {
- // public key not found
- logger.info(s"authentication by generic user ${genericUser} failed")
- false
}
- }
+ .getOrElse {
+ // search deploy keys
+ val existsDeployKey = getAllDeployKeys().exists { sshKey =>
+ SshUtil.str2PublicKey(sshKey.publicKey).contains(key)
+ }
+ if (existsDeployKey) {
+ // found deploy key for repository
+ PublicKeyAuthenticator.putAuthType(session, AuthType.DeployKeyType(key))
+ logger.info(s"authentication as generic user ${genericUser} succeeded, deploy key was found")
+ true
+ } else {
+ // public key not found
+ logger.info(s"authentication by generic user ${genericUser} failed")
+ false
+ }
+ }
}
}
diff --git a/src/main/scala/gitbucket/core/ssh/SshServerListener.scala b/src/main/scala/gitbucket/core/ssh/SshServerListener.scala
index 857db45..fe04b9f 100644
--- a/src/main/scala/gitbucket/core/ssh/SshServerListener.scala
+++ b/src/main/scala/gitbucket/core/ssh/SshServerListener.scala
@@ -22,12 +22,14 @@
provider.setOverwriteAllowed(false)
server.setKeyPairProvider(provider)
server.setPublickeyAuthenticator(new PublicKeyAuthenticator(sshAddress.genericUser))
- server.setCommandFactory(new GitCommandFactory(baseUrl, Some(s"${sshAddress.genericUser}@${sshAddress.host}:${sshAddress.port}")))
+ server.setCommandFactory(
+ new GitCommandFactory(baseUrl, Some(s"${sshAddress.genericUser}@${sshAddress.host}:${sshAddress.port}"))
+ )
server.setShellFactory(new NoShell(sshAddress))
}
def start(sshAddress: SshAddress, baseUrl: String) = {
- if(active.compareAndSet(false, true)){
+ if (active.compareAndSet(false, true)) {
configure(sshAddress, baseUrl)
server.start()
logger.info(s"Start SSH Server Listen on ${server.getPort}")
@@ -35,7 +37,7 @@
}
def stop() = {
- if(active.compareAndSet(true, false)){
+ if (active.compareAndSet(true, false)) {
server.stop(true)
logger.info("SSH Server is stopped.")
}
@@ -57,13 +59,12 @@
override def contextInitialized(sce: ServletContextEvent): Unit = {
val settings = loadSystemSettings()
if (settings.sshAddress.isDefined && settings.baseUrl.isEmpty) {
- logger.error("Could not start SshServer because the baseUrl is not configured.")
+ logger.error("Could not start SshServer because the baseUrl is not configured.")
}
for {
sshAddress <- settings.sshAddress
- baseUrl <- settings.baseUrl
- }
- SshServer.start(sshAddress, baseUrl)
+ baseUrl <- settings.baseUrl
+ } SshServer.start(sshAddress, baseUrl)
}
override def contextDestroyed(sce: ServletContextEvent): Unit = {
diff --git a/src/main/scala/gitbucket/core/ssh/SshUtil.scala b/src/main/scala/gitbucket/core/ssh/SshUtil.scala
index 9563ab3..9a7f7ed 100644
--- a/src/main/scala/gitbucket/core/ssh/SshUtil.scala
+++ b/src/main/scala/gitbucket/core/ssh/SshUtil.scala
@@ -8,7 +8,6 @@
import org.eclipse.jgit.lib.Constants
import org.slf4j.LoggerFactory
-
object SshUtil {
private val logger = LoggerFactory.getLogger(SshUtil.getClass)
diff --git a/src/main/scala/gitbucket/core/util/Authenticator.scala b/src/main/scala/gitbucket/core/util/Authenticator.scala
index 8065130..c555ec4 100644
--- a/src/main/scala/gitbucket/core/util/Authenticator.scala
+++ b/src/main/scala/gitbucket/core/util/Authenticator.scala
@@ -16,11 +16,11 @@
private def authenticate(action: => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
context.loginAccount match {
- case Some(x) if(x.isAdmin) => action
- case Some(x) if(paths(0) == x.userName) => action
- case _ => Unauthorized()
+ case Some(x) if (x.isAdmin) => action
+ case Some(x) if (paths(0) == x.userName) => action
+ case _ => Unauthorized()
}
}
}
@@ -36,14 +36,18 @@
private def authenticate(action: (RepositoryInfo) => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
getRepository(paths(0), paths(1)).map { repository =>
context.loginAccount match {
- case Some(x) if(x.isAdmin) => action(repository)
- case Some(x) if(repository.owner == x.userName) => action(repository)
+ case Some(x) if (x.isAdmin) => action(repository)
+ case Some(x) if (repository.owner == x.userName) => action(repository)
// TODO Repository management is allowed for only group managers?
- case Some(x) if(getGroupMembers(repository.owner).exists { m => m.userName == x.userName && m.isManager == true }) => action(repository)
- case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN)).contains(x.userName)) => action(repository)
+ case Some(x) if (getGroupMembers(repository.owner).exists { m =>
+ m.userName == x.userName && m.isManager == true
+ }) =>
+ action(repository)
+ case Some(x) if (getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN)).contains(x.userName)) =>
+ action(repository)
case _ => Unauthorized()
}
} getOrElse NotFound()
@@ -63,7 +67,7 @@
{
context.loginAccount match {
case Some(x) => action
- case None => Unauthorized()
+ case None => Unauthorized()
}
}
}
@@ -79,8 +83,8 @@
private def authenticate(action: => Any) = {
{
context.loginAccount match {
- case Some(x) if(x.isAdmin) => action
- case _ => Unauthorized()
+ case Some(x) if (x.isAdmin) => action
+ case _ => Unauthorized()
}
}
}
@@ -95,9 +99,9 @@
private def authenticate(action: (RepositoryInfo) => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
getRepository(paths(0), paths(1)).map { repository =>
- if(isReadable(repository.repository, context.loginAccount)){
+ if (isReadable(repository.repository, context.loginAccount)) {
action(repository)
} else {
Unauthorized()
@@ -113,19 +117,21 @@
*/
trait ReadableUsersAuthenticator { self: ControllerBase with RepositoryService with AccountService =>
protected def readableUsersOnly(action: (RepositoryInfo) => Any) = { authenticate(action) }
- protected def readableUsersOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => { authenticate(action(form, _)) }
+ protected def readableUsersOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => {
+ authenticate(action(form, _))
+ }
private def authenticate(action: (RepositoryInfo) => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
getRepository(paths(0), paths(1)).map { repository =>
context.loginAccount match {
- case Some(x) if(x.isAdmin) => action(repository)
- case Some(x) if(!repository.repository.isPrivate) => action(repository)
- case Some(x) if(paths(0) == x.userName) => action(repository)
- case Some(x) if(getGroupMembers(repository.owner).exists(_.userName == x.userName)) => action(repository)
- case Some(x) if(getCollaboratorUserNames(paths(0), paths(1)).contains(x.userName)) => action(repository)
- case _ => Unauthorized()
+ case Some(x) if (x.isAdmin) => action(repository)
+ case Some(x) if (!repository.repository.isPrivate) => action(repository)
+ case Some(x) if (paths(0) == x.userName) => action(repository)
+ case Some(x) if (getGroupMembers(repository.owner).exists(_.userName == x.userName)) => action(repository)
+ case Some(x) if (getCollaboratorUserNames(paths(0), paths(1)).contains(x.userName)) => action(repository)
+ case _ => Unauthorized()
}
} getOrElse NotFound()
}
@@ -138,17 +144,22 @@
*/
trait WritableUsersAuthenticator { self: ControllerBase with RepositoryService with AccountService =>
protected def writableUsersOnly(action: (RepositoryInfo) => Any) = { authenticate(action) }
- protected def writableUsersOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => { authenticate(action(form, _)) }
+ protected def writableUsersOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => {
+ authenticate(action(form, _))
+ }
private def authenticate(action: (RepositoryInfo) => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
getRepository(paths(0), paths(1)).map { repository =>
context.loginAccount match {
- case Some(x) if(x.isAdmin) => action(repository)
- case Some(x) if(paths(0) == x.userName) => action(repository)
- case Some(x) if(getGroupMembers(repository.owner).exists(_.userName == x.userName)) => action(repository)
- case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN, Role.DEVELOPER)).contains(x.userName)) => action(repository)
+ case Some(x) if (x.isAdmin) => action(repository)
+ case Some(x) if (paths(0) == x.userName) => action(repository)
+ case Some(x) if (getGroupMembers(repository.owner).exists(_.userName == x.userName)) => action(repository)
+ case Some(x)
+ if (getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN, Role.DEVELOPER))
+ .contains(x.userName)) =>
+ action(repository)
case _ => Unauthorized()
}
} getOrElse NotFound()
@@ -166,11 +177,12 @@
private def authenticate(action: => Any) = {
{
- defining(request.paths){ paths =>
+ defining(request.paths) { paths =>
context.loginAccount match {
- case Some(x) if(getGroupMembers(paths(0)).exists { member =>
- member.userName == x.userName && member.isManager
- }) => action
+ case Some(x) if (getGroupMembers(paths(0)).exists { member =>
+ member.userName == x.userName && member.isManager
+ }) =>
+ action
case _ => Unauthorized()
}
}
diff --git a/src/main/scala/gitbucket/core/util/DatabaseConfig.scala b/src/main/scala/gitbucket/core/util/DatabaseConfig.scala
index 1ef20dc..a2f6682 100644
--- a/src/main/scala/gitbucket/core/util/DatabaseConfig.scala
+++ b/src/main/scala/gitbucket/core/util/DatabaseConfig.scala
@@ -17,8 +17,9 @@
private lazy val config = {
val file = new File(GitBucketHome, "database.conf")
- if(!file.exists){
- FileUtils.write(file,
+ if (!file.exists) {
+ FileUtils.write(
+ file,
"""db {
| url = "jdbc:h2:${DatabaseHome};MVCC=true"
| user = "sa"
@@ -29,7 +30,9 @@
|# minimumIdle = 10
|# maximumPoolSize = 10
|}
- |""".stripMargin, "UTF-8")
+ |""".stripMargin,
+ "UTF-8"
+ )
}
ConfigFactory.parseFile(file)
}
@@ -39,27 +42,27 @@
def url(directory: Option[String]): String =
dbUrl.replace("${DatabaseHome}", directory.getOrElse(DatabaseHome))
- lazy val url : String = url(None)
- lazy val user : String = getValue("db.user", config.getString)
- lazy val password : String = getValue("db.password", config.getString)
- lazy val jdbcDriver : String = DatabaseType(url).jdbcDriver
- lazy val slickDriver : BlockingJdbcProfile = DatabaseType(url).slickDriver
- lazy val liquiDriver : AbstractJdbcDatabase = DatabaseType(url).liquiDriver
- lazy val connectionTimeout : Option[Long] = getOptionValue("db.connectionTimeout", config.getLong)
- lazy val idleTimeout : Option[Long] = getOptionValue("db.idleTimeout" , config.getLong)
- lazy val maxLifetime : Option[Long] = getOptionValue("db.maxLifetime" , config.getLong)
- lazy val minimumIdle : Option[Int] = getOptionValue("db.minimumIdle" , config.getInt)
- lazy val maximumPoolSize : Option[Int] = getOptionValue("db.maximumPoolSize" , config.getInt)
+ lazy val url: String = url(None)
+ lazy val user: String = getValue("db.user", config.getString)
+ lazy val password: String = getValue("db.password", config.getString)
+ lazy val jdbcDriver: String = DatabaseType(url).jdbcDriver
+ lazy val slickDriver: BlockingJdbcProfile = DatabaseType(url).slickDriver
+ lazy val liquiDriver: AbstractJdbcDatabase = DatabaseType(url).liquiDriver
+ lazy val connectionTimeout: Option[Long] = getOptionValue("db.connectionTimeout", config.getLong)
+ lazy val idleTimeout: Option[Long] = getOptionValue("db.idleTimeout", config.getLong)
+ lazy val maxLifetime: Option[Long] = getOptionValue("db.maxLifetime", config.getLong)
+ lazy val minimumIdle: Option[Int] = getOptionValue("db.minimumIdle", config.getInt)
+ lazy val maximumPoolSize: Option[Int] = getOptionValue("db.maximumPoolSize", config.getInt)
private def getValue[T](path: String, f: String => T): T = {
- getSystemProperty(path).getOrElse(getEnvironmentVariable(path).getOrElse{
+ getSystemProperty(path).getOrElse(getEnvironmentVariable(path).getOrElse {
f(path)
})
}
private def getOptionValue[T](path: String, f: String => T): Option[T] = {
getSystemProperty(path).orElse(getEnvironmentVariable(path).orElse {
- if(config.hasPath(path)) Some(f(path)) else None
+ if (config.hasPath(path)) Some(f(path)) else None
})
}
@@ -74,11 +77,11 @@
object DatabaseType {
def apply(url: String): DatabaseType = {
- if(url.startsWith("jdbc:h2:")){
+ if (url.startsWith("jdbc:h2:")) {
H2
- } else if(url.startsWith("jdbc:mysql:")){
+ } else if (url.startsWith("jdbc:mysql:")) {
MySQL
- } else if(url.startsWith("jdbc:postgresql:")){
+ } else if (url.startsWith("jdbc:postgresql:")) {
PostgreSQL
} else {
throw new IllegalArgumentException(s"${url} is not supported.")
@@ -106,7 +109,7 @@
object BlockingPostgresDriver extends slick.jdbc.PostgresProfile with BlockingJdbcProfile {
override def quoteIdentifier(id: String): String = {
val s = new StringBuilder(id.length + 4) append '"'
- for(c <- id) if(c == '"') s append "\"\"" else s append c.toLower
+ for (c <- id) if (c == '"') s append "\"\"" else s append c.toLower
(s append '"').toString
}
}
@@ -116,7 +119,7 @@
def getEnvironmentVariable[A](key: String): Option[A] = {
val value = System.getenv("GITBUCKET_" + key.toUpperCase.replace('.', '_'))
- if(value != null && value.nonEmpty){
+ if (value != null && value.nonEmpty) {
Some(convertType(value)).asInstanceOf[Option[A]]
} else {
None
@@ -125,7 +128,7 @@
def getSystemProperty[A](key: String): Option[A] = {
val value = System.getProperty("gitbucket." + key)
- if(value != null && value.nonEmpty){
+ if (value != null && value.nonEmpty) {
Some(convertType(value)).asInstanceOf[Option[A]]
} else {
None
@@ -133,10 +136,10 @@
}
def convertType[A: ClassTag](value: String) =
- defining(implicitly[ClassTag[A]].runtimeClass){ c =>
- if(c == classOf[Boolean]) value.toBoolean
- else if(c == classOf[Long]) value.toLong
- else if(c == classOf[Int]) value.toInt
+ defining(implicitly[ClassTag[A]].runtimeClass) { c =>
+ if (c == classOf[Boolean]) value.toBoolean
+ else if (c == classOf[Long]) value.toLong
+ else if (c == classOf[Int]) value.toInt
else value
}
diff --git a/src/main/scala/gitbucket/core/util/Directory.scala b/src/main/scala/gitbucket/core/util/Directory.scala
index b30b455..6e8a0b8 100644
--- a/src/main/scala/gitbucket/core/util/Directory.scala
+++ b/src/main/scala/gitbucket/core/util/Directory.scala
@@ -9,21 +9,22 @@
val GitBucketHome = (System.getProperty("gitbucket.home") match {
// -Dgitbucket.home=
- case path if(path != null) => new File(path)
- case _ => scala.util.Properties.envOrNone("GITBUCKET_HOME") match {
- // environment variable GITBUCKET_HOME
- case Some(env) => new File(env)
- // default is HOME/.gitbucket
- case None => {
- val oldHome = new File(System.getProperty("user.home"), "gitbucket")
- if(oldHome.exists && oldHome.isDirectory && new File(oldHome, "version").exists){
- //FileUtils.moveDirectory(oldHome, newHome)
- oldHome
- } else {
- new File(System.getProperty("user.home"), ".gitbucket")
+ case path if (path != null) => new File(path)
+ case _ =>
+ scala.util.Properties.envOrNone("GITBUCKET_HOME") match {
+ // environment variable GITBUCKET_HOME
+ case Some(env) => new File(env)
+ // default is HOME/.gitbucket
+ case None => {
+ val oldHome = new File(System.getProperty("user.home"), "gitbucket")
+ if (oldHome.exists && oldHome.isDirectory && new File(oldHome, "version").exists) {
+ //FileUtils.moveDirectory(oldHome, newHome)
+ oldHome
+ } else {
+ new File(System.getProperty("user.home"), ".gitbucket")
+ }
}
}
- }
}).getAbsolutePath
val GitBucketConf = new File(GitBucketHome, "gitbucket.conf")
@@ -55,8 +56,8 @@
new File(getRepositoryFilesDir(owner, repository), "comments")
/**
- * Directory for released files
- */
+ * Directory for released files
+ */
def getReleaseFilesDir(owner: String, repository: String): File =
new File(getRepositoryFilesDir(owner, repository), "releases")
diff --git a/src/main/scala/gitbucket/core/util/FileUtil.scala b/src/main/scala/gitbucket/core/util/FileUtil.scala
index 070beef..d399f77 100644
--- a/src/main/scala/gitbucket/core/util/FileUtil.scala
+++ b/src/main/scala/gitbucket/core/util/FileUtil.scala
@@ -9,7 +9,7 @@
object FileUtil {
def getMimeType(name: String): String =
- defining(new Tika()){ tika =>
+ defining(new Tika()) { tika =>
tika.detect(name) match {
case null => "application/octet-stream"
case mimeType => mimeType
@@ -17,8 +17,8 @@
}
def getContentType(name: String, bytes: Array[Byte]): String = {
- defining(getMimeType(name)){ mimeType =>
- if(mimeType == "application/octet-stream" && isText(bytes)){
+ defining(getMimeType(name)) { mimeType =>
+ if (mimeType == "application/octet-stream" && isText(bytes)) {
"text/plain"
} else {
mimeType
@@ -36,12 +36,12 @@
def getExtension(name: String): String =
name.lastIndexOf('.') match {
- case i if(i >= 0) => name.substring(i + 1)
- case _ => ""
+ case i if (i >= 0) => name.substring(i + 1)
+ case _ => ""
}
def withTmpDir[A](dir: File)(action: File => A): A = {
- if(dir.exists()){
+ if (dir.exists()) {
FileUtils.deleteDirectory(dir)
}
try {
@@ -61,7 +61,7 @@
* Do nothing if the given File is not a directory or not empty.
*/
def deleteDirectoryIfEmpty(dir: File): Unit = {
- if(dir.isDirectory() && dir.list().isEmpty) {
+ if (dir.isDirectory() && dir.list().isEmpty) {
FileUtils.deleteDirectory(dir)
}
}
@@ -70,15 +70,16 @@
* Delete file or directory forcibly.
*/
def deleteIfExists(file: java.io.File): java.io.File = {
- if(file.exists){
+ if (file.exists) {
FileUtils.forceDelete(file)
}
file
}
- lazy val MaxFileSize = if (System.getProperty("gitbucket.maxFileSize") != null)
- System.getProperty("gitbucket.maxFileSize").toLong
- else
- 3 * 1024 * 1024
+ lazy val MaxFileSize =
+ if (System.getProperty("gitbucket.maxFileSize") != null)
+ System.getProperty("gitbucket.maxFileSize").toLong
+ else
+ 3 * 1024 * 1024
}
diff --git a/src/main/scala/gitbucket/core/util/Implicits.scala b/src/main/scala/gitbucket/core/util/Implicits.scala
index 393dbbf..de701ca 100644
--- a/src/main/scala/gitbucket/core/util/Implicits.scala
+++ b/src/main/scala/gitbucket/core/util/Implicits.scala
@@ -13,7 +13,6 @@
import slick.jdbc.JdbcBackend
-
/**
* Provides some usable implicit conversions.
*/
@@ -23,7 +22,9 @@
implicit def request2Session(implicit request: HttpServletRequest): JdbcBackend#Session = Database.getSession(request)
implicit def context2ApiJsonFormatContext(implicit context: Context): JsonFormat.Context =
- JsonFormat.Context(context.baseUrl, context.settings.sshAddress.map { x => s"${x.genericUser}@${x.host}:${x.port}" })
+ JsonFormat.Context(context.baseUrl, context.settings.sshAddress.map { x =>
+ s"${x.genericUser}@${x.host}:${x.port}"
+ })
implicit class RichSeq[A](private val seq: Seq[A]) extends AnyVal {
@@ -53,7 +54,7 @@
case None => sb.append(m.matched)
}
}
- if(i < value.length){
+ if (i < value.length) {
sb.append(value.substring(i))
}
sb.toString
@@ -66,24 +67,26 @@
implicit class RichRequest(private val request: HttpServletRequest) extends AnyVal {
- def paths: Array[String] = (request.getRequestURI.substring(request.getContextPath.length + 1) match{
- case path if path.startsWith("api/v3/repos/") => path.substring(13/* "/api/v3/repos".length */)
- case path if path.startsWith("api/v3/orgs/") => path.substring(12/* "/api/v3/orgs".length */)
- case path => path
- }).split("/")
+ def paths: Array[String] =
+ (request.getRequestURI.substring(request.getContextPath.length + 1) match {
+ case path if path.startsWith("api/v3/repos/") => path.substring(13 /* "/api/v3/repos".length */ )
+ case path if path.startsWith("api/v3/orgs/") => path.substring(12 /* "/api/v3/orgs".length */ )
+ case path => path
+ }).split("/")
def hasQueryString: Boolean = request.getQueryString != null
def hasAttribute(name: String): Boolean = request.getAttribute(name) != null
- def gitRepositoryPath: String = request.getRequestURI.replaceFirst("^" + quote(request.getContextPath) + "/git/", "/")
+ def gitRepositoryPath: String =
+ request.getRequestURI.replaceFirst("^" + quote(request.getContextPath) + "/git/", "/")
}
implicit class RichSession(private val session: HttpSession) extends AnyVal {
def getAndRemove[T](key: String): Option[T] = {
val value = session.getAttribute(key).asInstanceOf[T]
- if(value == null){
+ if (value == null) {
session.removeAttribute(key)
}
Option(value)
diff --git a/src/main/scala/gitbucket/core/util/JDBCUtil.scala b/src/main/scala/gitbucket/core/util/JDBCUtil.scala
index 8a8574c..bb3b160 100644
--- a/src/main/scala/gitbucket/core/util/JDBCUtil.scala
+++ b/src/main/scala/gitbucket/core/util/JDBCUtil.scala
@@ -19,24 +19,24 @@
implicit class RichConnection(private val conn: Connection) extends AnyVal {
def update(sql: String, params: Any*): Int = {
- execute(sql, params: _*){ stmt =>
+ execute(sql, params: _*) { stmt =>
stmt.executeUpdate()
}
}
def find[T](sql: String, params: Any*)(f: ResultSet => T): Option[T] = {
- execute(sql, params: _*){ stmt =>
- using(stmt.executeQuery()){ rs =>
- if(rs.next) Some(f(rs)) else None
+ execute(sql, params: _*) { stmt =>
+ using(stmt.executeQuery()) { rs =>
+ if (rs.next) Some(f(rs)) else None
}
}
}
def select[T](sql: String, params: Any*)(f: ResultSet => T): Seq[T] = {
- execute(sql, params: _*){ stmt =>
- using(stmt.executeQuery()){ rs =>
+ execute(sql, params: _*) { stmt =>
+ using(stmt.executeQuery()) { rs =>
val list = new ListBuffer[T]
- while(rs.next){
+ while (rs.next) {
list += f(rs)
}
list.toSeq
@@ -45,20 +45,21 @@
}
def selectInt(sql: String, params: Any*): Int = {
- execute(sql, params: _*){ stmt =>
- using(stmt.executeQuery()){ rs =>
- if(rs.next) rs.getInt(1) else 0
+ execute(sql, params: _*) { stmt =>
+ using(stmt.executeQuery()) { rs =>
+ if (rs.next) rs.getInt(1) else 0
}
}
}
private def execute[T](sql: String, params: Any*)(f: (PreparedStatement) => T): T = {
- using(conn.prepareStatement(sql)){ stmt =>
- params.zipWithIndex.foreach { case (p, i) =>
- p match {
- case x: Int => stmt.setInt(i + 1, x)
- case x: String => stmt.setString(i + 1, x)
- }
+ using(conn.prepareStatement(sql)) { stmt =>
+ params.zipWithIndex.foreach {
+ case (p, i) =>
+ p match {
+ case x: Int => stmt.setInt(i + 1, x)
+ case x: String => stmt.setString(i + 1, x)
+ }
}
f(stmt)
}
@@ -67,20 +68,20 @@
def importAsSQL(in: InputStream): Unit = {
conn.setAutoCommit(false)
try {
- using(in){ in =>
+ using(in) { in =>
var out = new ByteArrayOutputStream()
var length = 0
val bytes = new scala.Array[Byte](1024 * 8)
var stringLiteral = false
- while({ length = in.read(bytes); length != -1 }){
- for(i <- 0 until length){
+ while ({ length = in.read(bytes); length != -1 }) {
+ for (i <- 0 until length) {
val c = bytes(i)
- if(c == '\''){
+ if (c == '\'') {
stringLiteral = !stringLiteral
}
- if(c == ';' && !stringLiteral){
+ if (c == ';' && !stringLiteral) {
val sql = new String(out.toByteArray, "UTF-8")
conn.update(sql.trim)
out = new ByteArrayOutputStream()
@@ -91,7 +92,7 @@
}
val remain = out.toByteArray
- if(remain.length != 0){
+ if (remain.length != 0) {
val sql = new String(remain, "UTF-8")
conn.update(sql.trim)
}
@@ -133,20 +134,21 @@
sb.append(columns.map(_._1).mkString(", "))
sb.append(") VALUES (")
- val values = columns.map { case (columnName, columnType) =>
- if(rs.getObject(columnName) == null){
- null
- } else {
- columnType match {
- case Types.BOOLEAN | Types.BIT => rs.getBoolean(columnName)
- case Types.VARCHAR | Types.CLOB | Types.CHAR | Types.LONGVARCHAR => rs.getString(columnName)
- case Types.INTEGER => rs.getInt(columnName)
- case Types.TIMESTAMP => rs.getTimestamp(columnName)
+ val values = columns.map {
+ case (columnName, columnType) =>
+ if (rs.getObject(columnName) == null) {
+ null
+ } else {
+ columnType match {
+ case Types.BOOLEAN | Types.BIT => rs.getBoolean(columnName)
+ case Types.VARCHAR | Types.CLOB | Types.CHAR | Types.LONGVARCHAR => rs.getString(columnName)
+ case Types.INTEGER => rs.getInt(columnName)
+ case Types.TIMESTAMP => rs.getTimestamp(columnName)
+ }
}
- }
}
- val columnValues = values.map {
+ val columnValues = values.map {
case x: String => "'" + x.replace("'", "''") + "'"
case x: Timestamp => "'" + dateFormat.format(x) + "'"
case null => "NULL"
@@ -179,7 +181,7 @@
private def childTables(meta: DatabaseMetaData, tableName: String): Seq[String] = {
val normalizedTableName =
- if(meta.getDatabaseProductName == "PostgreSQL"){
+ if (meta.getDatabaseProductName == "PostgreSQL") {
tableName.toLowerCase
} else {
tableName
@@ -189,7 +191,7 @@
val children = new ListBuffer[String]
while (rs.next) {
val childTableName = rs.getString("FKTABLE_NAME").toUpperCase
- if(!children.contains(childTableName)){
+ if (!children.contains(childTableName)) {
children += childTableName
children ++= childTables(meta, childTableName)
}
@@ -198,7 +200,6 @@
}
}
-
private def allTablesOrderByDependencies(meta: DatabaseMetaData): Seq[String] = {
val tables = allTableNames.map { tableName =>
val result = TableDependency(tableName, childTables(meta, tableName))
@@ -206,13 +207,14 @@
}
val edges = tables.flatMap { table =>
- table.children.map { child => (table.tableName, child) }
+ table.children.map { child =>
+ (table.tableName, child)
+ }
}
tsort(edges).toSeq
}
-
def tsort[A](edges: Traversable[(A, A)]): Iterable[A] = {
@tailrec
def tsort(toPreds: Map[A, Set[A]], done: Iterable[A]): Iterable[A] = {
diff --git a/src/main/scala/gitbucket/core/util/JGitUtil.scala b/src/main/scala/gitbucket/core/util/JGitUtil.scala
index 3b54730..bb33431 100644
--- a/src/main/scala/gitbucket/core/util/JGitUtil.scala
+++ b/src/main/scala/gitbucket/core/util/JGitUtil.scala
@@ -23,7 +23,12 @@
import java.util.function.Consumer
import org.cache2k.Cache2kBuilder
-import org.eclipse.jgit.api.errors.{InvalidRefNameException, JGitInternalException, NoHeadException, RefAlreadyExistsException}
+import org.eclipse.jgit.api.errors.{
+ InvalidRefNameException,
+ JGitInternalException,
+ NoHeadException,
+ RefAlreadyExistsException
+}
import org.eclipse.jgit.diff.{DiffEntry, DiffFormatter, RawTextComparator}
import org.eclipse.jgit.dircache.DirCacheEntry
import org.eclipse.jgit.util.io.DisabledOutputStream
@@ -44,7 +49,7 @@
* @param branchList the list of branch names
* @param tags the list of tags
*/
- case class RepositoryInfo(owner: String, name: String, branchList: List[String], tags: List[TagInfo]){
+ case class RepositoryInfo(owner: String, name: String, branchList: List[String], tags: List[TagInfo]) {
def this(owner: String, name: String) = this(owner, name, Nil, Nil)
}
@@ -62,8 +67,18 @@
* @param mailAddress the committer's mail address
* @param linkUrl the url of submodule
*/
- case class FileInfo(id: ObjectId, isDirectory: Boolean, name: String, path: String, message: String, commitId: String,
- time: Date, author: String, mailAddress: String, linkUrl: Option[String])
+ case class FileInfo(
+ id: ObjectId,
+ isDirectory: Boolean,
+ name: String,
+ path: String,
+ message: String,
+ commitId: String,
+ time: Date,
+ author: String,
+ mailAddress: String,
+ linkUrl: Option[String]
+ )
/**
* The commit data.
@@ -79,11 +94,21 @@
* @param committerName the committer name
* @param committerEmailAddress the mail address of the committer
*/
- case class CommitInfo(id: String, shortMessage: String, fullMessage: String, parents: List[String],
- authorTime: Date, authorName: String, authorEmailAddress: String,
- commitTime: Date, committerName: String, committerEmailAddress: String){
+ case class CommitInfo(
+ id: String,
+ shortMessage: String,
+ fullMessage: String,
+ parents: List[String],
+ authorTime: Date,
+ authorName: String,
+ authorEmailAddress: String,
+ commitTime: Date,
+ committerName: String,
+ committerEmailAddress: String
+ ) {
- def this(rev: org.eclipse.jgit.revwalk.RevCommit) = this(
+ def this(rev: org.eclipse.jgit.revwalk.RevCommit) =
+ this(
rev.getName,
rev.getShortMessage,
rev.getFullMessage,
@@ -93,12 +118,13 @@
rev.getAuthorIdent.getEmailAddress,
rev.getCommitterIdent.getWhen,
rev.getCommitterIdent.getName,
- rev.getCommitterIdent.getEmailAddress)
+ rev.getCommitterIdent.getEmailAddress
+ )
val summary = getSummaryMessage(fullMessage, shortMessage)
- val description = defining(fullMessage.trim.indexOf('\n')){ i =>
- if(i >= 0){
+ val description = defining(fullMessage.trim.indexOf('\n')) { i =>
+ if (i >= 0) {
Some(fullMessage.trim.substring(i).trim)
} else None
}
@@ -130,11 +156,12 @@
* @param content the string content
* @param charset the character encoding
*/
- case class ContentInfo(viewType: String, size: Option[Long], content: Option[String], charset: Option[String]){
+ case class ContentInfo(viewType: String, size: Option[Long], content: Option[String], charset: Option[String]) {
+
/**
* the line separator of this content ("LF" or "CRLF")
*/
- val lineSeparator: String = if(content.exists(_.indexOf("\r\n") >= 0)) "CRLF" else "LF"
+ val lineSeparator: String = if (content.exists(_.indexOf("\r\n") >= 0)) "CRLF" else "LF"
}
/**
@@ -159,10 +186,26 @@
case class BranchMergeInfo(ahead: Int, behind: Int, isMerged: Boolean)
- case class BranchInfo(name: String, committerName: String, commitTime: Date, committerEmailAddress:String, mergeInfo: Option[BranchMergeInfo], commitId: String)
+ case class BranchInfo(
+ name: String,
+ committerName: String,
+ commitTime: Date,
+ committerEmailAddress: String,
+ mergeInfo: Option[BranchMergeInfo],
+ commitId: String
+ )
- case class BlameInfo(id: String, authorName: String, authorEmailAddress: String, authorTime:java.util.Date,
- prev: Option[String], prevPath: Option[String], commitTime:java.util.Date, message:String, lines:Set[Int])
+ case class BlameInfo(
+ id: String,
+ authorName: String,
+ authorEmailAddress: String,
+ authorTime: java.util.Date,
+ prev: Option[String],
+ prevPath: Option[String],
+ commitTime: java.util.Date,
+ message: String,
+ lines: Set[Int]
+ )
/**
* Returns RevCommit from the commit or tag id.
@@ -207,7 +250,7 @@
val key = dir.getAbsolutePath + "@" + branch
val entry = cache.getEntry(key)
- if(entry == null) {
+ if (entry == null) {
using(Git.open(dir)) { git =>
val commitId = git.getRepository.resolve(branch)
val commitCount = git.log.add(commitId).call.iterator.asScala.take(10001).size
@@ -223,23 +266,35 @@
* Returns the repository information. It contains branch names and tag names.
*/
def getRepositoryInfo(owner: String, repository: String): RepositoryInfo = {
- using(Git.open(getRepositoryDir(owner, repository))){ git =>
+ using(Git.open(getRepositoryDir(owner, repository))) { git =>
try {
- RepositoryInfo(owner, repository,
+ RepositoryInfo(
+ owner,
+ repository,
// branches
git.branchList.call.asScala.map { ref =>
ref.getName.stripPrefix("refs/heads/")
}.toList,
// tags
- git.tagList.call.asScala.flatMap { ref =>
- try {
- val revCommit = getRevCommitFromId(git, ref.getObjectId)
- Some(TagInfo(ref.getName.stripPrefix("refs/tags/"), revCommit.getCommitterIdent.getWhen, revCommit.getName, revCommit.getShortMessage))
- } catch {
- case _: IncorrectObjectTypeException =>
- None
+ git.tagList.call.asScala
+ .flatMap { ref =>
+ try {
+ val revCommit = getRevCommitFromId(git, ref.getObjectId)
+ Some(
+ TagInfo(
+ ref.getName.stripPrefix("refs/tags/"),
+ revCommit.getCommitterIdent.getWhen,
+ revCommit.getName,
+ revCommit.getShortMessage
+ )
+ )
+ } catch {
+ case _: IncorrectObjectTypeException =>
+ None
+ }
}
- }.sortBy(_.time).toList
+ .sortBy(_.time)
+ .toList
)
} catch {
// not initialized
@@ -258,81 +313,101 @@
* @return HTML of the file list
*/
def getFileList(git: Git, revision: String, path: String = ".", baseUrl: Option[String] = None): List[FileInfo] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
val objectId = git.getRepository.resolve(revision)
- if(objectId == null) return Nil
+ if (objectId == null) return Nil
val revCommit = revWalk.parseCommit(objectId)
- def useTreeWalk(rev:RevCommit)(f:TreeWalk => Any): Unit = if (path == ".") {
- val treeWalk = new TreeWalk(git.getRepository)
- treeWalk.addTree(rev.getTree)
- using(treeWalk)(f)
- } else {
- val treeWalk = TreeWalk.forPath(git.getRepository, path, rev.getTree)
- if(treeWalk != null){
- treeWalk.enterSubtree
+ def useTreeWalk(rev: RevCommit)(f: TreeWalk => Any): Unit =
+ if (path == ".") {
+ val treeWalk = new TreeWalk(git.getRepository)
+ treeWalk.addTree(rev.getTree)
using(treeWalk)(f)
+ } else {
+ val treeWalk = TreeWalk.forPath(git.getRepository, path, rev.getTree)
+ if (treeWalk != null) {
+ treeWalk.enterSubtree
+ using(treeWalk)(f)
+ }
}
- }
@tailrec
- def simplifyPath(tuple: (ObjectId, FileMode, String, String, Option[String], RevCommit)): (ObjectId, FileMode, String, String, Option[String], RevCommit) = tuple match {
- case (oid, FileMode.TREE, name, path, _, commit ) =>
+ def simplifyPath(
+ tuple: (ObjectId, FileMode, String, String, Option[String], RevCommit)
+ ): (ObjectId, FileMode, String, String, Option[String], RevCommit) = tuple match {
+ case (oid, FileMode.TREE, name, path, _, commit) =>
(using(new TreeWalk(git.getRepository)) { walk =>
walk.addTree(oid)
// single tree child, or None
- if(walk.next() && walk.getFileMode(0) == FileMode.TREE){
- Some((walk.getObjectId(0), walk.getFileMode(0), name + "/" + walk.getNameString, path + "/" + walk.getNameString, None, commit)).filterNot(_ => walk.next())
+ if (walk.next() && walk.getFileMode(0) == FileMode.TREE) {
+ Some(
+ (
+ walk.getObjectId(0),
+ walk.getFileMode(0),
+ name + "/" + walk.getNameString,
+ path + "/" + walk.getNameString,
+ None,
+ commit
+ )
+ ).filterNot(_ => walk.next())
} else {
None
}
}) match {
case Some(child) => simplifyPath(child)
- case _ => tuple
+ case _ => tuple
}
case _ => tuple
}
- def tupleAdd(tuple:(ObjectId, FileMode, String, String, Option[String]), rev:RevCommit) = tuple match {
+ def tupleAdd(tuple: (ObjectId, FileMode, String, String, Option[String]), rev: RevCommit) = tuple match {
case (oid, fmode, name, path, opt) => (oid, fmode, name, path, opt, rev)
}
@tailrec
- def findLastCommits(result:List[(ObjectId, FileMode, String, String, Option[String], RevCommit)],
- restList:List[((ObjectId, FileMode, String, String, Option[String]), Map[RevCommit, RevCommit])],
- revIterator:java.util.Iterator[RevCommit]): List[(ObjectId, FileMode, String, String, Option[String], RevCommit)] = {
- if(restList.isEmpty){
+ def findLastCommits(
+ result: List[(ObjectId, FileMode, String, String, Option[String], RevCommit)],
+ restList: List[((ObjectId, FileMode, String, String, Option[String]), Map[RevCommit, RevCommit])],
+ revIterator: java.util.Iterator[RevCommit]
+ ): List[(ObjectId, FileMode, String, String, Option[String], RevCommit)] = {
+ if (restList.isEmpty) {
result
- } else if(!revIterator.hasNext){ // maybe, revCommit has only 1 log. other case, restList be empty
+ } else if (!revIterator.hasNext) { // maybe, revCommit has only 1 log. other case, restList be empty
result ++ restList.map { case (tuple, map) => tupleAdd(tuple, map.values.headOption.getOrElse(revCommit)) }
} else {
val newCommit = revIterator.next
- val (thisTimeChecks,skips) = restList.partition { case (tuple, parentsMap) => parentsMap.contains(newCommit) }
- if(thisTimeChecks.isEmpty){
+ val (thisTimeChecks, skips) = restList.partition {
+ case (tuple, parentsMap) => parentsMap.contains(newCommit)
+ }
+ if (thisTimeChecks.isEmpty) {
findLastCommits(result, restList, revIterator)
} else {
var nextRest = skips
var nextResult = result
// Map[(name, oid), (tuple, parentsMap)]
- val rest = scala.collection.mutable.Map(thisTimeChecks.map{ t => (t._1._3 -> t._1._1) -> t }:_*)
+ val rest = scala.collection.mutable.Map(thisTimeChecks.map { t =>
+ (t._1._3 -> t._1._1) -> t
+ }: _*)
lazy val newParentsMap = newCommit.getParents.map(_ -> newCommit).toMap
- useTreeWalk(newCommit){ walk =>
- while(walk.next){
- rest.remove(walk.getNameString -> walk.getObjectId(0)).map { case (tuple, _) =>
- if(newParentsMap.isEmpty){
- nextResult +:= tupleAdd(tuple, newCommit)
- } else {
- nextRest +:= tuple -> newParentsMap
- }
+ useTreeWalk(newCommit) { walk =>
+ while (walk.next) {
+ rest.remove(walk.getNameString -> walk.getObjectId(0)).map {
+ case (tuple, _) =>
+ if (newParentsMap.isEmpty) {
+ nextResult +:= tupleAdd(tuple, newCommit)
+ } else {
+ nextRest +:= tuple -> newParentsMap
+ }
}
}
}
- rest.values.map { case (tuple, parentsMap) =>
- val restParentsMap = parentsMap - newCommit
- if(restParentsMap.isEmpty){
- nextResult +:= tupleAdd(tuple, parentsMap(newCommit))
- } else {
- nextRest +:= tuple -> restParentsMap
- }
+ rest.values.map {
+ case (tuple, parentsMap) =>
+ val restParentsMap = parentsMap - newCommit
+ if (restParentsMap.isEmpty) {
+ nextResult +:= tupleAdd(tuple, parentsMap(newCommit))
+ } else {
+ nextRest +:= tuple -> restParentsMap
+ }
}
findLastCommits(nextResult, nextRest, revIterator)
}
@@ -340,7 +415,7 @@
}
var fileList: List[(ObjectId, FileMode, String, String, Option[String])] = Nil
- useTreeWalk(revCommit){ treeWalk =>
+ useTreeWalk(revCommit) { treeWalk =>
while (treeWalk.next()) {
val linkUrl = if (treeWalk.getFileMode(0) == FileMode.GITLINK) {
getSubmodules(git, revCommit.getTree, baseUrl).find(_.path == treeWalk.getPathString).map(_.viewerUrl)
@@ -354,23 +429,26 @@
val nextParentsMap = Option(lastCommit).map(_.getParents.map(_ -> lastCommit).toMap).getOrElse(Map())
findLastCommits(List.empty, fileList.map(a => a -> nextParentsMap), it)
.map(simplifyPath)
- .map { case (objectId, fileMode, name, path, linkUrl, commit) =>
- FileInfo(
- objectId,
- fileMode == FileMode.TREE || fileMode == FileMode.GITLINK,
- name,
- path,
- getSummaryMessage(commit.getFullMessage, commit.getShortMessage),
- commit.getName,
- commit.getAuthorIdent.getWhen,
- commit.getAuthorIdent.getName,
- commit.getAuthorIdent.getEmailAddress,
- linkUrl)
- }.sortWith { (file1, file2) =>
+ .map {
+ case (objectId, fileMode, name, path, linkUrl, commit) =>
+ FileInfo(
+ objectId,
+ fileMode == FileMode.TREE || fileMode == FileMode.GITLINK,
+ name,
+ path,
+ getSummaryMessage(commit.getFullMessage, commit.getShortMessage),
+ commit.getName,
+ commit.getAuthorIdent.getWhen,
+ commit.getAuthorIdent.getName,
+ commit.getAuthorIdent.getEmailAddress,
+ linkUrl
+ )
+ }
+ .sortWith { (file1, file2) =>
(file1.isDirectory, file2.isDirectory) match {
- case (true , false) => true
- case (false, true ) => false
- case _ => file1.name.compareTo(file2.name) < 0
+ case (true, false) => true
+ case (false, true) => false
+ case _ => file1.name.compareTo(file2.name) < 0
}
}
}
@@ -380,9 +458,9 @@
* Returns the first line of the commit message.
*/
private def getSummaryMessage(fullMessage: String, shortMessage: String): String = {
- defining(fullMessage.trim.indexOf('\n')){ i =>
- defining(if(i >= 0) fullMessage.trim.substring(0, i).trim else fullMessage){ firstLine =>
- if(firstLine.length > shortMessage.length) shortMessage else firstLine
+ defining(fullMessage.trim.indexOf('\n')) { i =>
+ defining(if (i >= 0) fullMessage.trim.substring(0, i).trim else fullMessage) { firstLine =>
+ if (firstLine.length > shortMessage.length) shortMessage else firstLine
}
}
}
@@ -391,9 +469,9 @@
* get all file list by revision. only file.
*/
def getTreeId(git: Git, revision: String): Option[String] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
- val objectId = git.getRepository.resolve(revision)
- if(objectId == null) return None
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ val objectId = git.getRepository.resolve(revision)
+ if (objectId == null) return None
val revCommit = revWalk.parseCommit(objectId)
Some(revCommit.getTree.name)
}
@@ -403,14 +481,14 @@
* get all file list by tree object id.
*/
def getAllFileListByTreeId(git: Git, treeId: String): List[String] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
- val objectId = git.getRepository.resolve(treeId+"^{tree}")
- if(objectId == null) return Nil
- using(new TreeWalk(git.getRepository)){ treeWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ val objectId = git.getRepository.resolve(treeId + "^{tree}")
+ if (objectId == null) return Nil
+ using(new TreeWalk(git.getRepository)) { treeWalk =>
treeWalk.addTree(objectId)
treeWalk.setRecursive(true)
var ret: List[String] = Nil
- if(treeWalk != null){
+ if (treeWalk != null) {
while (treeWalk.next()) {
ret +:= treeWalk.getPathString
}
@@ -430,26 +508,40 @@
* @param path filters by this path. default is no filter.
* @return a tuple of the commit list and whether has next, or the error message
*/
- def getCommitLog(git: Git, revision: String, page: Int = 1, limit: Int = 0, path: String = ""): Either[String, (List[CommitInfo], Boolean)] = {
- val fixedPage = if(page <= 0) 1 else page
+ def getCommitLog(
+ git: Git,
+ revision: String,
+ page: Int = 1,
+ limit: Int = 0,
+ path: String = ""
+ ): Either[String, (List[CommitInfo], Boolean)] = {
+ val fixedPage = if (page <= 0) 1 else page
@scala.annotation.tailrec
- def getCommitLog(i: java.util.Iterator[RevCommit], count: Int, logs: List[CommitInfo]): (List[CommitInfo], Boolean) =
+ def getCommitLog(
+ i: java.util.Iterator[RevCommit],
+ count: Int,
+ logs: List[CommitInfo]
+ ): (List[CommitInfo], Boolean) =
i.hasNext match {
- case true if(limit <= 0 || logs.size < limit) => {
+ case true if (limit <= 0 || logs.size < limit) => {
val commit = i.next
- getCommitLog(i, count + 1, if(limit <= 0 || (fixedPage - 1) * limit <= count) logs :+ new CommitInfo(commit) else logs)
+ getCommitLog(
+ i,
+ count + 1,
+ if (limit <= 0 || (fixedPage - 1) * limit <= count) logs :+ new CommitInfo(commit) else logs
+ )
}
case _ => (logs, i.hasNext)
}
- using(new RevWalk(git.getRepository)){ revWalk =>
- defining(git.getRepository.resolve(revision)){ objectId =>
- if(objectId == null){
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ defining(git.getRepository.resolve(revision)) { objectId =>
+ if (objectId == null) {
Left(s"${revision} can't be resolved.")
} else {
revWalk.markStart(revWalk.parseCommit(objectId))
- if(path.nonEmpty){
+ if (path.nonEmpty) {
revWalk.setTreeFilter(AndTreeFilter.create(PathFilter.create(path), TreeFilter.ANY_DIFF))
}
Right(getCommitLog(revWalk.iterator, 0, Nil))
@@ -458,15 +550,16 @@
}
}
- def getCommitLogs(git: Git, begin: String, includesLastCommit: Boolean = false)
- (endCondition: RevCommit => Boolean): List[CommitInfo] = {
+ def getCommitLogs(git: Git, begin: String, includesLastCommit: Boolean = false)(
+ endCondition: RevCommit => Boolean
+ ): List[CommitInfo] = {
@scala.annotation.tailrec
def getCommitLog(i: java.util.Iterator[RevCommit], logs: List[CommitInfo]): List[CommitInfo] =
i.hasNext match {
- case true => {
+ case true => {
val revCommit = i.next
- if(endCondition(revCommit)){
- if(includesLastCommit) logs :+ new CommitInfo(revCommit) else logs
+ if (endCondition(revCommit)) {
+ if (includesLastCommit) logs :+ new CommitInfo(revCommit) else logs
} else {
getCommitLog(i, logs :+ new CommitInfo(revCommit))
}
@@ -474,13 +567,12 @@
case false => logs
}
- using(new RevWalk(git.getRepository)){ revWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
revWalk.markStart(revWalk.parseCommit(git.getRepository.resolve(begin)))
getCommitLog(revWalk.iterator, Nil).reverse
}
}
-
/**
* Returns the commit list between two revisions.
*
@@ -531,7 +623,7 @@
}
private def getDiffEntries(git: Git, from: Option[String], to: String): Seq[DiffEntry] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
val df = new DiffFormatter(DisabledOutputStream.INSTANCE)
df.setRepository(git.getRepository)
@@ -539,7 +631,12 @@
from match {
case None => {
toCommit.getParentCount match {
- case 0 => df.scan(new EmptyTreeIterator(), new CanonicalTreeParser(null, git.getRepository.newObjectReader(), toCommit.getTree)).asScala
+ case 0 =>
+ df.scan(
+ new EmptyTreeIterator(),
+ new CanonicalTreeParser(null, git.getRepository.newObjectReader(), toCommit.getTree)
+ )
+ .asScala
case _ => df.scan(toCommit.getParent(0), toCommit.getTree).asScala
}
}
@@ -552,7 +649,7 @@
}
def getParentCommitId(git: Git, id: String): Option[String] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
val commit = revWalk.parseCommit(git.getRepository.resolve(id))
commit.getParentCount match {
case 0 => None
@@ -561,59 +658,71 @@
}
}
- def getDiffs(git: Git, from: Option[String], to: String, fetchContent: Boolean, makePatch: Boolean): List[DiffInfo] = {
+ def getDiffs(
+ git: Git,
+ from: Option[String],
+ to: String,
+ fetchContent: Boolean,
+ makePatch: Boolean
+ ): List[DiffInfo] = {
val diffs = getDiffEntries(git, from, to)
diffs.map { diff =>
- if(diffs.size > 100){
+ if (diffs.size > 100) {
DiffInfo(
- changeType = diff.getChangeType,
- oldPath = diff.getOldPath,
- newPath = diff.getNewPath,
- oldContent = None,
- newContent = None,
- oldIsImage = false,
- newIsImage = false,
+ changeType = diff.getChangeType,
+ oldPath = diff.getOldPath,
+ newPath = diff.getNewPath,
+ oldContent = None,
+ newContent = None,
+ oldIsImage = false,
+ newIsImage = false,
oldObjectId = Option(diff.getOldId).map(_.name),
newObjectId = Option(diff.getNewId).map(_.name),
- oldMode = diff.getOldMode.toString,
- newMode = diff.getNewMode.toString,
- tooLarge = true,
- patch = None
+ oldMode = diff.getOldMode.toString,
+ newMode = diff.getNewMode.toString,
+ tooLarge = true,
+ patch = None
)
} else {
val oldIsImage = FileUtil.isImage(diff.getOldPath)
val newIsImage = FileUtil.isImage(diff.getNewPath)
- if(!fetchContent || oldIsImage || newIsImage){
+ if (!fetchContent || oldIsImage || newIsImage) {
DiffInfo(
- changeType = diff.getChangeType,
- oldPath = diff.getOldPath,
- newPath = diff.getNewPath,
- oldContent = None,
- newContent = None,
- oldIsImage = oldIsImage,
- newIsImage = newIsImage,
+ changeType = diff.getChangeType,
+ oldPath = diff.getOldPath,
+ newPath = diff.getNewPath,
+ oldContent = None,
+ newContent = None,
+ oldIsImage = oldIsImage,
+ newIsImage = newIsImage,
oldObjectId = Option(diff.getOldId).map(_.name),
newObjectId = Option(diff.getNewId).map(_.name),
- oldMode = diff.getOldMode.toString,
- newMode = diff.getNewMode.toString,
- tooLarge = false,
- patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter
+ oldMode = diff.getOldMode.toString,
+ newMode = diff.getNewMode.toString,
+ tooLarge = false,
+ patch = (if (makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter
)
} else {
DiffInfo(
- changeType = diff.getChangeType,
- oldPath = diff.getOldPath,
- newPath = diff.getNewPath,
- oldContent = JGitUtil.getContentFromId(git, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
- newContent = JGitUtil.getContentFromId(git, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
- oldIsImage = oldIsImage,
- newIsImage = newIsImage,
+ changeType = diff.getChangeType,
+ oldPath = diff.getOldPath,
+ newPath = diff.getNewPath,
+ oldContent = JGitUtil
+ .getContentFromId(git, diff.getOldId.toObjectId, false)
+ .filter(FileUtil.isText)
+ .map(convertFromByteArray),
+ newContent = JGitUtil
+ .getContentFromId(git, diff.getNewId.toObjectId, false)
+ .filter(FileUtil.isText)
+ .map(convertFromByteArray),
+ oldIsImage = oldIsImage,
+ newIsImage = newIsImage,
oldObjectId = Option(diff.getOldId).map(_.name),
newObjectId = Option(diff.getNewId).map(_.name),
- oldMode = diff.getOldMode.toString,
- newMode = diff.getNewMode.toString,
- tooLarge = false,
- patch = (if(makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter
+ oldMode = diff.getOldMode.toString,
+ newMode = diff.getNewMode.toString,
+ tooLarge = false,
+ patch = (if (makePatch) Some(makePatchFromDiffEntry(git, diff)) else None) // TODO use DiffFormatter
)
}
}
@@ -622,7 +731,7 @@
private def makePatchFromDiffEntry(git: Git, diff: DiffEntry): String = {
val out = new ByteArrayOutputStream()
- using(new DiffFormatter(out)){ formatter =>
+ using(new DiffFormatter(out)) { formatter =>
formatter.setRepository(git.getRepository)
formatter.format(diff)
val patch = new String(out.toByteArray) // TODO charset???
@@ -634,13 +743,20 @@
* Returns the list of branch names of the specified commit.
*/
def getBranchesOfCommit(git: Git, commitId: String): List[String] =
- using(new RevWalk(git.getRepository)){ revWalk =>
- defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))){ commit =>
- git.getRepository.getAllRefs.entrySet.asScala.filter { e =>
- (e.getKey.startsWith(Constants.R_HEADS) && revWalk.isMergedInto(commit, revWalk.parseCommit(e.getValue.getObjectId)))
- }.map { e =>
- e.getValue.getName.substring(org.eclipse.jgit.lib.Constants.R_HEADS.length)
- }.toList.sorted
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
+ git.getRepository.getAllRefs.entrySet.asScala
+ .filter { e =>
+ (e.getKey.startsWith(Constants.R_HEADS) && revWalk.isMergedInto(
+ commit,
+ revWalk.parseCommit(e.getValue.getObjectId)
+ ))
+ }
+ .map { e =>
+ e.getValue.getName.substring(org.eclipse.jgit.lib.Constants.R_HEADS.length)
+ }
+ .toList
+ .sorted
}
}
@@ -648,44 +764,56 @@
* Returns the list of tags of the specified commit.
*/
def getTagsOfCommit(git: Git, commitId: String): List[String] =
- using(new RevWalk(git.getRepository)){ revWalk =>
- defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))){ commit =>
- git.getRepository.getAllRefs.entrySet.asScala.filter { e =>
- (e.getKey.startsWith(Constants.R_TAGS) && revWalk.isMergedInto(commit, revWalk.parseCommit(e.getValue.getObjectId)))
- }.map { e =>
- e.getValue.getName.substring(org.eclipse.jgit.lib.Constants.R_TAGS.length)
- }.toList.sorted.reverse
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ defining(revWalk.parseCommit(git.getRepository.resolve(commitId + "^0"))) { commit =>
+ git.getRepository.getAllRefs.entrySet.asScala
+ .filter { e =>
+ (e.getKey.startsWith(Constants.R_TAGS) && revWalk.isMergedInto(
+ commit,
+ revWalk.parseCommit(e.getValue.getObjectId)
+ ))
+ }
+ .map { e =>
+ e.getValue.getName.substring(org.eclipse.jgit.lib.Constants.R_TAGS.length)
+ }
+ .toList
+ .sorted
+ .reverse
}
}
def initRepository(dir: java.io.File): Unit =
- using(new RepositoryBuilder().setGitDir(dir).setBare.build){ repository =>
+ using(new RepositoryBuilder().setGitDir(dir).setBare.build) { repository =>
repository.create(true)
setReceivePack(repository)
}
def cloneRepository(from: java.io.File, to: java.io.File): Unit =
- using(Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).setBare(true).call){ git =>
+ using(Git.cloneRepository.setURI(from.toURI.toString).setDirectory(to).setBare(true).call) { git =>
setReceivePack(git.getRepository)
}
def isEmpty(git: Git): Boolean = git.getRepository.resolve(Constants.HEAD) == null
private def setReceivePack(repository: org.eclipse.jgit.lib.Repository): Unit =
- defining(repository.getConfig){ config =>
+ defining(repository.getConfig) { config =>
config.setBoolean("http", null, "receivepack", true)
config.save
}
- def getDefaultBranch(git: Git, repository: RepositoryService.RepositoryInfo,
- revstr: String = ""): Option[(ObjectId, String)] = {
+ def getDefaultBranch(
+ git: Git,
+ repository: RepositoryService.RepositoryInfo,
+ revstr: String = ""
+ ): Option[(ObjectId, String)] = {
Seq(
- Some(if(revstr.isEmpty) repository.repository.defaultBranch else revstr),
+ Some(if (revstr.isEmpty) repository.repository.defaultBranch else revstr),
repository.branchList.headOption
).flatMap {
- case Some(rev) => Some((git.getRepository.resolve(rev), rev))
- case None => None
- }.find(_._1 != null)
+ case Some(rev) => Some((git.getRepository.resolve(rev), rev))
+ case None => None
+ }
+ .find(_._1 != null)
}
def createBranch(git: Git, fromBranch: String, newBranch: String) = {
@@ -706,13 +834,21 @@
entry
}
- def createNewCommit(git: Git, inserter: ObjectInserter, headId: AnyObjectId, treeId: AnyObjectId,
- ref: String, fullName: String, mailAddress: String, message: String): ObjectId = {
+ def createNewCommit(
+ git: Git,
+ inserter: ObjectInserter,
+ headId: AnyObjectId,
+ treeId: AnyObjectId,
+ ref: String,
+ fullName: String,
+ mailAddress: String,
+ message: String
+ ): ObjectId = {
val newCommit = new CommitBuilder()
newCommit.setCommitter(new PersonIdent(fullName, mailAddress))
newCommit.setAuthor(new PersonIdent(fullName, mailAddress))
newCommit.setMessage(message)
- if(headId != null){
+ if (headId != null) {
newCommit.setParentIds(List(headId).asJava)
}
newCommit.setTreeId(treeId)
@@ -740,7 +876,7 @@
val config = new BlobBasedConfig(repository.getConfig(), bytes)
config.getSubsections("submodule").asScala.map { module =>
val path = config.getString("submodule", module, "path")
- val url = config.getString("submodule", module, "url")
+ val url = config.getString("submodule", module, "url")
SubmoduleInfo(module, path, url, StringUtil.getRepositoryViewerUrl(url, baseUrl))
}
} catch {
@@ -750,7 +886,7 @@
}
}).toList
} getOrElse Nil
- }
+ }
/**
* Get object content of the given path as byte array from the Git repository.
@@ -764,12 +900,12 @@
def getContentFromPath(git: Git, revTree: RevTree, path: String, fetchLargeFile: Boolean): Option[Array[Byte]] = {
@scala.annotation.tailrec
def getPathObjectId(path: String, walk: TreeWalk): Option[ObjectId] = walk.next match {
- case true if(walk.getPathString == path) => Some(walk.getObjectId(0))
- case true => getPathObjectId(path, walk)
- case false => None
+ case true if (walk.getPathString == path) => Some(walk.getObjectId(0))
+ case true => getPathObjectId(path, walk)
+ case false => None
}
- using(new TreeWalk(git.getRepository)){ treeWalk =>
+ using(new TreeWalk(git.getRepository)) { treeWalk =>
treeWalk.addTree(revTree)
treeWalk.setRecursive(true)
getPathObjectId(path, treeWalk)
@@ -779,19 +915,22 @@
}
def getLfsObjects(text: String): Map[String, String] = {
- if(text.startsWith("version https://git-lfs.github.com/spec/v1")){
- // LFS objects
- text.split("\n").map { line =>
+ if (text.startsWith("version https://git-lfs.github.com/spec/v1")) {
+ // LFS objects
+ text
+ .split("\n")
+ .map { line =>
val dim = line.split(" ")
dim(0) -> dim(1)
- }.toMap
- } else {
- Map.empty
- }
+ }
+ .toMap
+ } else {
+ Map.empty
+ }
}
def getContentSize(loader: ObjectLoader): Long = {
- if(loader.isLarge) {
+ if (loader.isLarge) {
loader.getSize
} else {
val bytes = loader.getCachedBytes
@@ -800,7 +939,7 @@
val attr = getLfsObjects(text)
attr.get("size") match {
case Some(size) => size.toLong
- case None => loader.getSize
+ case None => loader.getSize
}
}
}
@@ -811,18 +950,23 @@
def getContentInfo(git: Git, path: String, objectId: ObjectId): ContentInfo = {
// Viewer
- using(git.getRepository.getObjectDatabase){ db =>
+ using(git.getRepository.getObjectDatabase) { db =>
val loader = db.open(objectId)
- val isLfs = isLfsPointer(loader)
- val large = FileUtil.isLarge(loader.getSize)
- val viewer = if(FileUtil.isImage(path)) "image" else if(large) "large" else "other"
- val bytes = if(viewer == "other") JGitUtil.getContentFromId(git, objectId, false) else None
+ val isLfs = isLfsPointer(loader)
+ val large = FileUtil.isLarge(loader.getSize)
+ val viewer = if (FileUtil.isImage(path)) "image" else if (large) "large" else "other"
+ val bytes = if (viewer == "other") JGitUtil.getContentFromId(git, objectId, false) else None
val size = Some(getContentSize(loader))
- if(viewer == "other"){
- if(!isLfs && bytes.isDefined && FileUtil.isText(bytes.get)){
+ if (viewer == "other") {
+ if (!isLfs && bytes.isDefined && FileUtil.isText(bytes.get)) {
// text
- ContentInfo("text", size, Some(StringUtil.convertFromByteArray(bytes.get)), Some(StringUtil.detectEncoding(bytes.get)))
+ ContentInfo(
+ "text",
+ size,
+ Some(StringUtil.convertFromByteArray(bytes.get)),
+ Some(StringUtil.detectEncoding(bytes.get))
+ )
} else {
// binary
ContentInfo("binary", size, None, None)
@@ -842,18 +986,19 @@
* @param fetchLargeFile if false then returns None for the large file
* @return the byte array of content or None if object does not exist
*/
- def getContentFromId(git: Git, id: ObjectId, fetchLargeFile: Boolean): Option[Array[Byte]] = try {
- using(git.getRepository.getObjectDatabase){ db =>
- val loader = db.open(id)
- if(loader.isLarge || (fetchLargeFile == false && FileUtil.isLarge(loader.getSize))){
- None
- } else {
- Some(loader.getBytes)
+ def getContentFromId(git: Git, id: ObjectId, fetchLargeFile: Boolean): Option[Array[Byte]] =
+ try {
+ using(git.getRepository.getObjectDatabase) { db =>
+ val loader = db.open(id)
+ if (loader.isLarge || (fetchLargeFile == false && FileUtil.isLarge(loader.getSize))) {
+ None
+ } else {
+ Some(loader.getBytes)
+ }
}
+ } catch {
+ case e: MissingObjectException => None
}
- } catch {
- case e: MissingObjectException => None
- }
/**
* Get objectLoader of the given object id from the Git repository.
@@ -863,35 +1008,37 @@
* @param f the function process ObjectLoader
* @return None if object does not exist
*/
- def getObjectLoaderFromId[A](git: Git, id: ObjectId)(f: ObjectLoader => A):Option[A] = try {
- using(git.getRepository.getObjectDatabase){ db =>
- Some(f(db.open(id)))
+ def getObjectLoaderFromId[A](git: Git, id: ObjectId)(f: ObjectLoader => A): Option[A] =
+ try {
+ using(git.getRepository.getObjectDatabase) { db =>
+ Some(f(db.open(id)))
+ }
+ } catch {
+ case e: MissingObjectException => None
}
- } catch {
- case e: MissingObjectException => None
- }
/**
* Returns all commit id in the specified repository.
*/
- def getAllCommitIds(git: Git): Seq[String] = if(isEmpty(git)) {
- Nil
- } else {
- val existIds = new scala.collection.mutable.ListBuffer[String]()
- val i = git.log.all.call.iterator
- while(i.hasNext){
- existIds += i.next.name
+ def getAllCommitIds(git: Git): Seq[String] =
+ if (isEmpty(git)) {
+ Nil
+ } else {
+ val existIds = new scala.collection.mutable.ListBuffer[String]()
+ val i = git.log.all.call.iterator
+ while (i.hasNext) {
+ existIds += i.next.name
+ }
+ existIds.toSeq
}
- existIds.toSeq
- }
def processTree[T](git: Git, id: ObjectId)(f: (String, CanonicalTreeParser) => T): Seq[T] = {
- using(new RevWalk(git.getRepository)){ revWalk =>
- using(new TreeWalk(git.getRepository)){ treeWalk =>
+ using(new RevWalk(git.getRepository)) { revWalk =>
+ using(new TreeWalk(git.getRepository)) { treeWalk =>
val index = treeWalk.addTree(revWalk.parseTree(id))
treeWalk.setRecursive(true)
val result = new collection.mutable.ListBuffer[T]()
- while(treeWalk.next){
+ while (treeWalk.next) {
result += f(treeWalk.getPathString, treeWalk.getTree(index, classOf[CanonicalTreeParser]))
}
result.toSeq
@@ -902,10 +1049,17 @@
/**
* Returns the identifier of the root commit (or latest merge commit) of the specified branch.
*/
- def getForkedCommitId(oldGit: Git, newGit: Git,
- userName: String, repositoryName: String, branch: String,
- requestUserName: String, requestRepositoryName: String, requestBranch: String): String =
- defining(getAllCommitIds(oldGit)){ existIds =>
+ def getForkedCommitId(
+ oldGit: Git,
+ newGit: Git,
+ userName: String,
+ repositoryName: String,
+ branch: String,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestBranch: String
+ ): String =
+ defining(getAllCommitIds(oldGit)) { existIds =>
getCommitLogs(newGit, requestBranch, true) { commit =>
existIds.contains(commit.name) && getBranchesOfCommit(oldGit, commit.getName).contains(branch)
}.head.id
@@ -914,19 +1068,35 @@
/**
* Fetch pull request contents into refs/pull/${issueId}/head and return (commitIdTo, commitIdFrom)
*/
- def updatePullRequest(userName: String, repositoryName:String, branch: String, issueId: Int,
- requestUserName: String, requestRepositoryName: String, requestBranch: String):(String, String) =
- using(Git.open(Directory.getRepositoryDir(userName, repositoryName)),
- Git.open(Directory.getRepositoryDir(requestUserName, requestRepositoryName))){ (oldGit, newGit) =>
+ def updatePullRequest(
+ userName: String,
+ repositoryName: String,
+ branch: String,
+ issueId: Int,
+ requestUserName: String,
+ requestRepositoryName: String,
+ requestBranch: String
+ ): (String, String) =
+ using(
+ Git.open(Directory.getRepositoryDir(userName, repositoryName)),
+ Git.open(Directory.getRepositoryDir(requestUserName, requestRepositoryName))
+ ) { (oldGit, newGit) =>
oldGit.fetch
.setRemote(Directory.getRepositoryDir(requestUserName, requestRepositoryName).toURI.toString)
.setRefSpecs(new RefSpec(s"refs/heads/${requestBranch}:refs/pull/${issueId}/head").setForceUpdate(true))
.call
val commitIdTo = oldGit.getRepository.resolve(s"refs/pull/${issueId}/head").getName
- val commitIdFrom = getForkedCommitId(oldGit, newGit,
- userName, repositoryName, branch,
- requestUserName, requestRepositoryName, requestBranch)
+ val commitIdFrom = getForkedCommitId(
+ oldGit,
+ newGit,
+ userName,
+ repositoryName,
+ branch,
+ requestUserName,
+ requestRepositoryName,
+ requestBranch
+ )
(commitIdTo, commitIdFrom)
}
@@ -943,20 +1113,20 @@
}
def getBranches(owner: String, name: String, defaultBranch: String, origin: Boolean): Seq[BranchInfo] = {
- using(Git.open(getRepositoryDir(owner, name))){ git =>
+ using(Git.open(getRepositoryDir(owner, name))) { git =>
val repo = git.getRepository
val defaultObject = repo.resolve(defaultBranch)
git.branchList.call.asScala.map { ref =>
val walk = new RevWalk(repo)
try {
- val defaultCommit = walk.parseCommit(defaultObject)
- val branchName = ref.getName.stripPrefix("refs/heads/")
- val branchCommit = walk.parseCommit(ref.getObjectId)
- val when = branchCommit.getCommitterIdent.getWhen
- val committer = branchCommit.getCommitterIdent.getName
+ val defaultCommit = walk.parseCommit(defaultObject)
+ val branchName = ref.getName.stripPrefix("refs/heads/")
+ val branchCommit = walk.parseCommit(ref.getObjectId)
+ val when = branchCommit.getCommitterIdent.getWhen
+ val committer = branchCommit.getCommitterIdent.getName
val committerEmail = branchCommit.getCommitterIdent.getEmailAddress
- val mergeInfo = if(origin && branchName == defaultBranch){
+ val mergeInfo = if (origin && branchName == defaultBranch) {
None
} else {
walk.reset()
@@ -966,10 +1136,13 @@
val mergeBase = walk.next()
walk.reset()
walk.setRevFilter(RevFilter.ALL)
- Some(BranchMergeInfo(
- ahead = RevWalkUtils.count(walk, branchCommit, mergeBase),
- behind = RevWalkUtils.count(walk, defaultCommit, mergeBase),
- isMerged = walk.isMergedInto(branchCommit, defaultCommit)))
+ Some(
+ BranchMergeInfo(
+ ahead = RevWalkUtils.count(walk, branchCommit, mergeBase),
+ behind = RevWalkUtils.count(walk, defaultCommit, mergeBase),
+ isMerged = walk.isMergedInto(branchCommit, defaultCommit)
+ )
+ )
}
BranchInfo(branchName, committer, when, committerEmail, mergeInfo, ref.getObjectId.name)
} finally {
@@ -980,33 +1153,38 @@
}
def getBlame(git: Git, id: String, path: String): Iterable[BlameInfo] = {
- Option(git.getRepository.resolve(id)).map{ commitId =>
- val blamer = new org.eclipse.jgit.api.BlameCommand(git.getRepository)
- blamer.setStartCommit(commitId)
- blamer.setFilePath(path)
- val blame = blamer.call()
- var blameMap = Map[String, JGitUtil.BlameInfo]()
- var idLine = List[(String, Int)]()
- val commits = 0.to(blame.getResultContents().size() - 1).map { i =>
- val c = blame.getSourceCommit(i)
- if(!blameMap.contains(c.name)){
- blameMap += c.name -> JGitUtil.BlameInfo(
- c.name,
- c.getAuthorIdent.getName,
- c.getAuthorIdent.getEmailAddress,
- c.getAuthorIdent.getWhen,
- Option(git.log.add(c).addPath(blame.getSourcePath(i)).setSkip(1).setMaxCount(2).call.iterator.next)
- .map(_.name),
- if(blame.getSourcePath(i)==path){ None } else { Some(blame.getSourcePath(i)) },
- c.getCommitterIdent.getWhen,
- c.getShortMessage,
- Set.empty)
+ Option(git.getRepository.resolve(id))
+ .map { commitId =>
+ val blamer = new org.eclipse.jgit.api.BlameCommand(git.getRepository)
+ blamer.setStartCommit(commitId)
+ blamer.setFilePath(path)
+ val blame = blamer.call()
+ var blameMap = Map[String, JGitUtil.BlameInfo]()
+ var idLine = List[(String, Int)]()
+ val commits = 0.to(blame.getResultContents().size() - 1).map { i =>
+ val c = blame.getSourceCommit(i)
+ if (!blameMap.contains(c.name)) {
+ blameMap += c.name -> JGitUtil.BlameInfo(
+ c.name,
+ c.getAuthorIdent.getName,
+ c.getAuthorIdent.getEmailAddress,
+ c.getAuthorIdent.getWhen,
+ Option(git.log.add(c).addPath(blame.getSourcePath(i)).setSkip(1).setMaxCount(2).call.iterator.next)
+ .map(_.name),
+ if (blame.getSourcePath(i) == path) { None } else { Some(blame.getSourcePath(i)) },
+ c.getCommitterIdent.getWhen,
+ c.getShortMessage,
+ Set.empty
+ )
+ }
+ idLine :+= (c.name, i)
}
- idLine :+= (c.name, i)
+ val limeMap = idLine.groupBy(_._1).mapValues(_.map(_._2).toSet)
+ blameMap.values.map { b =>
+ b.copy(lines = limeMap(b.id))
+ }
}
- val limeMap = idLine.groupBy(_._1).mapValues(_.map(_._2).toSet)
- blameMap.values.map{b => b.copy(lines=limeMap(b.id))}
- }.getOrElse(Seq.empty)
+ .getOrElse(Seq.empty)
}
/**
@@ -1017,8 +1195,8 @@
* @param revstr A git object references expression
* @return sha1
*/
- def getShaByRef(owner:String, name:String,revstr: String): Option[String] = {
- using(Git.open(getRepositoryDir(owner, name))){ git =>
+ def getShaByRef(owner: String, name: String, revstr: String): Option[String] = {
+ using(Git.open(getRepositoryDir(owner, name))) { git =>
Option(git.getRepository.resolve(revstr)).map(ObjectId.toString(_))
}
}
diff --git a/src/main/scala/gitbucket/core/util/Keys.scala b/src/main/scala/gitbucket/core/util/Keys.scala
index 4fd8e42..cf3135c 100644
--- a/src/main/scala/gitbucket/core/util/Keys.scala
+++ b/src/main/scala/gitbucket/core/util/Keys.scala
@@ -26,8 +26,8 @@
val DashboardPulls = "dashboard/pulls"
/**
- * Session key for the OpenID Connect authentication.
- */
+ * Session key for the OpenID Connect authentication.
+ */
val OidcContext = "oidcContext"
/**
diff --git a/src/main/scala/gitbucket/core/util/LDAPUtil.scala b/src/main/scala/gitbucket/core/util/LDAPUtil.scala
index 65d2279..9facd51 100644
--- a/src/main/scala/gitbucket/core/util/LDAPUtil.scala
+++ b/src/main/scala/gitbucket/core/util/LDAPUtil.scala
@@ -43,48 +43,70 @@
*/
def authenticate(ldapSettings: Ldap, userName: String, password: String): Either[String, LDAPUserInfo] = {
bind(
- host = ldapSettings.host,
- port = ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
- dn = ldapSettings.bindDN.getOrElse(""),
+ host = ldapSettings.host,
+ port = ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
+ dn = ldapSettings.bindDN.getOrElse(""),
password = ldapSettings.bindPassword.getOrElse(""),
- tls = ldapSettings.tls.getOrElse(false),
- ssl = ldapSettings.ssl.getOrElse(false),
+ tls = ldapSettings.tls.getOrElse(false),
+ ssl = ldapSettings.ssl.getOrElse(false),
keystore = ldapSettings.keystore.getOrElse(""),
- error = "System LDAP authentication failed."
- ){ conn =>
- findUser(conn, userName, ldapSettings.baseDN, ldapSettings.userNameAttribute, ldapSettings.additionalFilterCondition) match {
+ error = "System LDAP authentication failed."
+ ) { conn =>
+ findUser(
+ conn,
+ userName,
+ ldapSettings.baseDN,
+ ldapSettings.userNameAttribute,
+ ldapSettings.additionalFilterCondition
+ ) match {
case Some(userDN) => userAuthentication(ldapSettings, userDN, userName, password)
case None => Left("User does not exist.")
}
}
}
- private def userAuthentication(ldapSettings: Ldap, userDN: String, userName: String, password: String): Either[String, LDAPUserInfo] = {
+ private def userAuthentication(
+ ldapSettings: Ldap,
+ userDN: String,
+ userName: String,
+ password: String
+ ): Either[String, LDAPUserInfo] = {
bind(
- host = ldapSettings.host,
- port = ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
- dn = userDN,
+ host = ldapSettings.host,
+ port = ldapSettings.port.getOrElse(SystemSettingsService.DefaultLdapPort),
+ dn = userDN,
password = password,
- tls = ldapSettings.tls.getOrElse(false),
- ssl = ldapSettings.ssl.getOrElse(false),
+ tls = ldapSettings.tls.getOrElse(false),
+ ssl = ldapSettings.ssl.getOrElse(false),
keystore = ldapSettings.keystore.getOrElse(""),
- error = "User LDAP Authentication Failed."
- ){ conn =>
- if(ldapSettings.mailAttribute.getOrElse("").isEmpty) {
- Right(LDAPUserInfo(
- userName = userName,
- fullName = ldapSettings.fullNameAttribute.flatMap { fullNameAttribute =>
- findFullName(conn, userDN, ldapSettings.userNameAttribute, userName, fullNameAttribute)
- }.getOrElse(userName),
- mailAddress = createDummyMailAddress(userName)))
+ error = "User LDAP Authentication Failed."
+ ) { conn =>
+ if (ldapSettings.mailAttribute.getOrElse("").isEmpty) {
+ Right(
+ LDAPUserInfo(
+ userName = userName,
+ fullName = ldapSettings.fullNameAttribute
+ .flatMap { fullNameAttribute =>
+ findFullName(conn, userDN, ldapSettings.userNameAttribute, userName, fullNameAttribute)
+ }
+ .getOrElse(userName),
+ mailAddress = createDummyMailAddress(userName)
+ )
+ )
} else {
findMailAddress(conn, userDN, ldapSettings.userNameAttribute, userName, ldapSettings.mailAttribute.get) match {
- case Some(mailAddress) => Right(LDAPUserInfo(
- userName = getUserNameFromMailAddress(userName),
- fullName = ldapSettings.fullNameAttribute.flatMap { fullNameAttribute =>
- findFullName(conn, userDN, ldapSettings.userNameAttribute, userName, fullNameAttribute)
- }.getOrElse(userName),
- mailAddress = mailAddress))
+ case Some(mailAddress) =>
+ Right(
+ LDAPUserInfo(
+ userName = getUserNameFromMailAddress(userName),
+ fullName = ldapSettings.fullNameAttribute
+ .flatMap { fullNameAttribute =>
+ findFullName(conn, userDN, ldapSettings.userNameAttribute, userName, fullNameAttribute)
+ }
+ .getOrElse(userName),
+ mailAddress = mailAddress
+ )
+ )
case None => Left("Can't find mail address.")
}
}
@@ -98,8 +120,16 @@
}).replaceAll("[^a-zA-Z0-9\\-_.]", "").replaceAll("^[_\\-]", "")
}
- private def bind[A](host: String, port: Int, dn: String, password: String, tls: Boolean, ssl: Boolean, keystore: String, error: String)
- (f: LDAPConnection => Either[String, A]): Either[String, A] = {
+ private def bind[A](
+ host: String,
+ port: Int,
+ dn: String,
+ password: String,
+ tls: Boolean,
+ ssl: Boolean,
+ keystore: String,
+ error: String
+ )(f: LDAPConnection => Either[String, A]): Either[String, A] = {
if (tls) {
// Dynamically set Sun as the security provider
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider())
@@ -112,11 +142,11 @@
}
val conn: LDAPConnection =
- if(ssl) {
- new LDAPConnection(new LDAPJSSESecureSocketFactory())
- }else {
- new LDAPConnection(new LDAPJSSEStartTLSFactory())
- }
+ if (ssl) {
+ new LDAPConnection(new LDAPJSSESecureSocketFactory())
+ } else {
+ new LDAPConnection(new LDAPJSSEStartTLSFactory())
+ }
try {
// Connect to the server
@@ -150,15 +180,24 @@
/**
* Search a specified user and returns userDN if exists.
*/
- private def findUser(conn: LDAPConnection, userName: String, baseDN: String, userNameAttribute: String, additionalFilterCondition: Option[String]): Option[String] = {
+ private def findUser(
+ conn: LDAPConnection,
+ userName: String,
+ baseDN: String,
+ userNameAttribute: String,
+ additionalFilterCondition: Option[String]
+ ): Option[String] = {
@tailrec
def getEntries(results: LDAPSearchResults, entries: List[Option[LDAPEntry]] = Nil): List[LDAPEntry] = {
- if(results.hasMore){
- getEntries(results, entries :+ (try {
- Option(results.next)
- } catch {
- case ex: LDAPReferralException => None // NOTE(tanacasino): Referral follow is off. so ignores it.(for AD)
- }))
+ if (results.hasMore) {
+ getEntries(
+ results,
+ entries :+ (try {
+ Option(results.next)
+ } catch {
+ case ex: LDAPReferralException => None // NOTE(tanacasino): Referral follow is off. so ignores it.(for AD)
+ })
+ )
} else {
entries.flatten
}
@@ -166,7 +205,7 @@
val filterCond = additionalFilterCondition.getOrElse("") match {
case "" => userNameAttribute + "=" + userName
- case x => "(&(" + x + ")(" + userNameAttribute + "=" + userName + "))"
+ case x => "(&(" + x + ")(" + userNameAttribute + "=" + userName + "))"
}
getEntries(conn.search(baseDN, LDAPConnection.SCOPE_SUB, filterCond, null, false)).collectFirst {
@@ -174,16 +213,44 @@
}
}
- private def findMailAddress(conn: LDAPConnection, userDN: String, userNameAttribute: String, userName: String, mailAttribute: String): Option[String] =
- defining(conn.search(userDN, LDAPConnection.SCOPE_BASE, userNameAttribute + "=" + userName, Array[String](mailAttribute), false)){ results =>
- if(results.hasMore) {
+ private def findMailAddress(
+ conn: LDAPConnection,
+ userDN: String,
+ userNameAttribute: String,
+ userName: String,
+ mailAttribute: String
+ ): Option[String] =
+ defining(
+ conn.search(
+ userDN,
+ LDAPConnection.SCOPE_BASE,
+ userNameAttribute + "=" + userName,
+ Array[String](mailAttribute),
+ false
+ )
+ ) { results =>
+ if (results.hasMore) {
Option(results.next.getAttribute(mailAttribute)).map(_.getStringValue)
} else None
}
- private def findFullName(conn: LDAPConnection, userDN: String, userNameAttribute: String, userName: String, nameAttribute: String): Option[String] =
- defining(conn.search(userDN, LDAPConnection.SCOPE_BASE, userNameAttribute + "=" + userName, Array[String](nameAttribute), false)){ results =>
- if(results.hasMore) {
+ private def findFullName(
+ conn: LDAPConnection,
+ userDN: String,
+ userNameAttribute: String,
+ userName: String,
+ nameAttribute: String
+ ): Option[String] =
+ defining(
+ conn.search(
+ userDN,
+ LDAPConnection.SCOPE_BASE,
+ userNameAttribute + "=" + userName,
+ Array[String](nameAttribute),
+ false
+ )
+ ) { results =>
+ if (results.hasMore) {
Option(results.next.getAttribute(nameAttribute)).map(_.getStringValue)
} else None
}
diff --git a/src/main/scala/gitbucket/core/util/LockUtil.scala b/src/main/scala/gitbucket/core/util/LockUtil.scala
index 0924719..75c4e33 100644
--- a/src/main/scala/gitbucket/core/util/LockUtil.scala
+++ b/src/main/scala/gitbucket/core/util/LockUtil.scala
@@ -15,7 +15,7 @@
* Returns the lock object for the specified repository.
*/
private def getLockObject(key: String): Lock = synchronized {
- if(!locks.containsKey(key)){
+ if (!locks.containsKey(key)) {
locks.put(key, new ReentrantLock())
}
locks.get(key)
@@ -24,7 +24,7 @@
/**
* Synchronizes a given function which modifies the working copy of the wiki repository.
*/
- def lock[T](key: String)(f: => T): T = defining(getLockObject(key)){ lock =>
+ def lock[T](key: String)(f: => T): T = defining(getLockObject(key)) { lock =>
try {
lock.lock()
f
diff --git a/src/main/scala/gitbucket/core/util/Mailer.scala b/src/main/scala/gitbucket/core/util/Mailer.scala
index 703f4b4..91d063a 100644
--- a/src/main/scala/gitbucket/core/util/Mailer.scala
+++ b/src/main/scala/gitbucket/core/util/Mailer.scala
@@ -6,15 +6,27 @@
import org.apache.commons.mail.{DefaultAuthenticator, HtmlEmail}
import SystemSettingsService.SystemSettings
-class Mailer(settings: SystemSettings){
+class Mailer(settings: SystemSettings) {
- def send(to: String, subject: String, textMsg: String, htmlMsg: Option[String] = None, loginAccount: Option[Account] = None): Unit = {
+ def send(
+ to: String,
+ subject: String,
+ textMsg: String,
+ htmlMsg: Option[String] = None,
+ loginAccount: Option[Account] = None
+ ): Unit = {
createMail(subject, textMsg, htmlMsg, loginAccount).foreach { email =>
email.addTo(to).send
}
}
- def sendBcc(bcc: Seq[String], subject: String, textMsg: String, htmlMsg: Option[String] = None, loginAccount: Option[Account] = None): Unit = {
+ def sendBcc(
+ bcc: Seq[String],
+ subject: String,
+ textMsg: String,
+ htmlMsg: Option[String] = None,
+ loginAccount: Option[Account] = None
+ ): Unit = {
createMail(subject, textMsg, htmlMsg, loginAccount).foreach { email =>
bcc.foreach { address =>
email.addBcc(address)
@@ -23,8 +35,13 @@
}
}
- def createMail(subject: String, textMsg: String, htmlMsg: Option[String] = None, loginAccount: Option[Account] = None): Option[HtmlEmail] = {
- if(settings.notification == true){
+ def createMail(
+ subject: String,
+ textMsg: String,
+ htmlMsg: Option[String] = None,
+ loginAccount: Option[Account] = None
+ ): Option[HtmlEmail] = {
+ if (settings.notification == true) {
settings.smtp.map { smtp =>
val email = new HtmlEmail
email.setHostName(smtp.host)
@@ -34,7 +51,7 @@
}
smtp.ssl.foreach { ssl =>
email.setSSLOnConnect(ssl)
- if(ssl == true) {
+ if (ssl == true) {
email.setSslSmtpPort(smtp.port.get.toString)
}
}
@@ -43,10 +60,11 @@
email.setStartTLSRequired(starttls)
}
smtp.fromAddress
- .map (_ -> smtp.fromName.getOrElse(loginAccount.map(_.userName).getOrElse("GitBucket")))
- .orElse (Some("notifications@gitbucket.com" -> loginAccount.map(_.userName).getOrElse("GitBucket")))
- .foreach { case (address, name) =>
- email.setFrom(address, name)
+ .map(_ -> smtp.fromName.getOrElse(loginAccount.map(_.userName).getOrElse("GitBucket")))
+ .orElse(Some("notifications@gitbucket.com" -> loginAccount.map(_.userName).getOrElse("GitBucket")))
+ .foreach {
+ case (address, name) =>
+ email.setFrom(address, name)
}
email.setCharset("UTF-8")
email.setSubject(subject)
diff --git a/src/main/scala/gitbucket/core/util/RepositoryName.scala b/src/main/scala/gitbucket/core/util/RepositoryName.scala
index 9f0825b..b3f41a4 100644
--- a/src/main/scala/gitbucket/core/util/RepositoryName.scala
+++ b/src/main/scala/gitbucket/core/util/RepositoryName.scala
@@ -1,19 +1,23 @@
package gitbucket.core.util
// TODO Move to gitbucket.core.api package?
-case class RepositoryName(owner: String, name: String){
+case class RepositoryName(owner: String, name: String) {
val fullName = s"${owner}/${name}"
}
-object RepositoryName{
+object RepositoryName {
def apply(fullName: String): RepositoryName = {
fullName.split("/").toList match {
case owner :: name :: Nil => RepositoryName(owner, name)
- case _ => throw new IllegalArgumentException(s"${fullName} is not repositoryName (only 'owner/name')")
+ case _ => throw new IllegalArgumentException(s"${fullName} is not repositoryName (only 'owner/name')")
}
}
- def apply(repository: gitbucket.core.model.Repository): RepositoryName = RepositoryName(repository.userName, repository.repositoryName)
- def apply(repository: gitbucket.core.util.JGitUtil.RepositoryInfo): RepositoryName = RepositoryName(repository.owner, repository.name)
- def apply(repository: gitbucket.core.service.RepositoryService.RepositoryInfo): RepositoryName = RepositoryName(repository.owner, repository.name)
- def apply(repository: gitbucket.core.model.CommitStatus): RepositoryName = RepositoryName(repository.userName, repository.repositoryName)
+ def apply(repository: gitbucket.core.model.Repository): RepositoryName =
+ RepositoryName(repository.userName, repository.repositoryName)
+ def apply(repository: gitbucket.core.util.JGitUtil.RepositoryInfo): RepositoryName =
+ RepositoryName(repository.owner, repository.name)
+ def apply(repository: gitbucket.core.service.RepositoryService.RepositoryInfo): RepositoryName =
+ RepositoryName(repository.owner, repository.name)
+ def apply(repository: gitbucket.core.model.CommitStatus): RepositoryName =
+ RepositoryName(repository.userName, repository.repositoryName)
}
diff --git a/src/main/scala/gitbucket/core/util/StringUtil.scala b/src/main/scala/gitbucket/core/util/StringUtil.scala
index bf79ebf..f61c898 100644
--- a/src/main/scala/gitbucket/core/util/StringUtil.scala
+++ b/src/main/scala/gitbucket/core/util/StringUtil.scala
@@ -19,7 +19,7 @@
}
def sha1(value: String): String =
- defining(java.security.MessageDigest.getInstance("SHA-1")){ md =>
+ defining(java.security.MessageDigest.getInstance("SHA-1")) { md =>
md.update(value.getBytes)
md.digest.map(b => "%02x".format(b)).mkString
}
@@ -50,7 +50,7 @@
def splitWords(value: String): Array[String] = value.split("[ \\t ]+")
- def isInteger(value: String): Boolean = allCatch opt { value.toInt } map(_ => true) getOrElse(false)
+ def isInteger(value: String): Boolean = allCatch opt { value.toInt } map (_ => true) getOrElse (false)
def escapeHtml(value: String): String =
value.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """)
@@ -63,7 +63,7 @@
IOUtils.toString(new BOMInputStream(new java.io.ByteArrayInputStream(content)), detectEncoding(content))
def detectEncoding(content: Array[Byte]): String =
- defining(new UniversalDetector(null)){ detector =>
+ defining(new UniversalDetector(null)) { detector =>
detector.handleData(content, 0, content.length)
detector.dataEnd()
detector.getDetectedCharset match {
@@ -81,7 +81,7 @@
*/
def convertLineSeparator(content: String, lineSeparator: String): String = {
val lf = content.replace("\r\n", "\n").replace("\r", "\n")
- if(lineSeparator == "CRLF"){
+ if (lineSeparator == "CRLF") {
lf.replace("\n", "\r\n")
} else {
lf
@@ -96,7 +96,7 @@
* @return the converted content
*/
def appendNewLine(content: String, lineSeparator: String): String = {
- if(lineSeparator == "CRLF") {
+ if (lineSeparator == "CRLF") {
if (content.endsWith("\r\n")) content else content + "\r\n"
} else {
if (content.endsWith("\n")) content else content + "\n"
@@ -111,7 +111,11 @@
*/
def extractIssueId(message: String): Seq[String] =
"(^|\\W)#(\\d+)(\\W|$)".r
- .findAllIn(message).matchData.map(_.group(2)).toSeq.distinct
+ .findAllIn(message)
+ .matchData
+ .map(_.group(2))
+ .toSeq
+ .distinct
/**
* Extract close issue id like ```close #issueId ``` from the given message.
@@ -121,23 +125,28 @@
*/
def extractCloseId(message: String): Seq[String] =
"(?i)(? s"${removeUserName(base)}/$user/$repository"
- case GitHubUrlPattern (_, user, repository) => s"https://github.com/$user/$repository"
+ case GitBucketUrlPattern(base, user, repository)
+ if baseUrl.map(removeUserName(base).startsWith).getOrElse(false) =>
+ s"${removeUserName(base)}/$user/$repository"
+ case GitHubUrlPattern(_, user, repository) => s"https://github.com/$user/$repository"
case BitBucketUrlPattern(_, user, repository) => s"https://bitbucket.org/$user/$repository"
- case GitLabUrlPattern (_, user, repository) => s"https://gitlab.com/$user/$repository"
- case _ => gitRepositoryUrl
+ case GitLabUrlPattern(_, user, repository) => s"https://gitlab.com/$user/$repository"
+ case _ => gitRepositoryUrl
}
}
diff --git a/src/main/scala/gitbucket/core/util/SyntaxSugars.scala b/src/main/scala/gitbucket/core/util/SyntaxSugars.scala
index 74d39cb..def4c3a 100644
--- a/src/main/scala/gitbucket/core/util/SyntaxSugars.scala
+++ b/src/main/scala/gitbucket/core/util/SyntaxSugars.scala
@@ -12,8 +12,9 @@
def defining[A, B](value: A)(f: A => B): B = f(value)
def using[A <% { def close(): Unit }, B](resource: A)(f: A => B): B =
- try f(resource) finally {
- if(resource != null){
+ try f(resource)
+ finally {
+ if (resource != null) {
ignoring(classOf[Throwable]) {
resource.close()
}
@@ -21,13 +22,14 @@
}
def using[A <% { def close(): Unit }, B <% { def close(): Unit }, C](resource1: A, resource2: B)(f: (A, B) => C): C =
- try f(resource1, resource2) finally {
- if(resource1 != null){
+ try f(resource1, resource2)
+ finally {
+ if (resource1 != null) {
ignoring(classOf[Throwable]) {
resource1.close()
}
}
- if(resource2 != null){
+ if (resource2 != null) {
ignoring(classOf[Throwable]) {
resource2.close()
}
@@ -35,19 +37,22 @@
}
def using[T](git: Git)(f: Git => T): T =
- try f(git) finally git.getRepository.close()
+ try f(git)
+ finally git.getRepository.close()
def using[T](git1: Git, git2: Git)(f: (Git, Git) => T): T =
- try f(git1, git2) finally {
+ try f(git1, git2)
+ finally {
git1.getRepository.close()
git2.getRepository.close()
}
- def ignore[T](f: => Unit): Unit = try {
- f
- } catch {
- case _: Exception => ()
- }
+ def ignore[T](f: => Unit): Unit =
+ try {
+ f
+ } catch {
+ case _: Exception => ()
+ }
object ~ {
def unapply[A, B](t: (A, B)): Option[(A, B)] = Some(t)
@@ -57,7 +62,7 @@
* Provides easier and explicit ways to access to a head value of `Map[String, Seq[String]]`.
* This is intended to use in implementations of scalatra-forms's `Constraint` or `ValueType`.
*/
- implicit class HeadValueAccessibleMap(map: Map[String, Seq[String]]){
+ implicit class HeadValueAccessibleMap(map: Map[String, Seq[String]]) {
def value(key: String): String = map(key).head
def optionValue(key: String): Option[String] = map.get(key).flatMap(_.headOption)
def values(key: String): Seq[String] = map.get(key).getOrElse(Seq.empty)
diff --git a/src/main/scala/gitbucket/core/util/TextAvatarUtil.scala b/src/main/scala/gitbucket/core/util/TextAvatarUtil.scala
index 48c0317..0f6d7ce 100644
--- a/src/main/scala/gitbucket/core/util/TextAvatarUtil.scala
+++ b/src/main/scala/gitbucket/core/util/TextAvatarUtil.scala
@@ -7,7 +7,6 @@
import java.awt.font.{FontRenderContext, TextLayout}
import java.awt.geom.AffineTransform
-
object TextAvatarUtil {
private val iconSize = 200
private val fontSize = 180
@@ -21,7 +20,9 @@
// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
private def relativeLuminance(c: Color): Double = {
- val rgb = Seq(c.getRed, c.getGreen, c.getBlue).map{_/255.0}.map{x => if (x <= 0.03928) x / 12.92 else math.pow((x + 0.055) / 1.055, 2.4)}
+ val rgb = Seq(c.getRed, c.getGreen, c.getBlue).map { _ / 255.0 }.map { x =>
+ if (x <= 0.03928) x / 12.92 else math.pow((x + 0.055) / 1.055, 2.4)
+ }
0.2126 * rgb(0) + 0.7152 * rgb(1) + 0.0722 * rgb(2)
}
diff --git a/src/main/scala/gitbucket/core/util/Validations.scala b/src/main/scala/gitbucket/core/util/Validations.scala
index be580d7..0402c72 100644
--- a/src/main/scala/gitbucket/core/util/Validations.scala
+++ b/src/main/scala/gitbucket/core/util/Validations.scala
@@ -8,11 +8,11 @@
/**
* Constraint for the identifier such as user name or page name.
*/
- def identifier: Constraint = new Constraint(){
+ def identifier: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(!value.matches("[a-zA-Z0-9\\-_.]+")){
+ if (!value.matches("[a-zA-Z0-9\\-_.]+")) {
Some(s"${name} contains invalid character.")
- } else if(value.startsWith("_") || value.startsWith("-")){
+ } else if (value.startsWith("_") || value.startsWith("-")) {
Some(s"${name} starts with invalid character.")
} else {
None
@@ -22,24 +22,23 @@
/**
* Constraint for the password.
*/
- def password: Constraint = new Constraint(){
+ def password: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(System.getProperty("gitbucket.validate.password") != "false" && !value.matches("[a-zA-Z0-9\\-_.]+")){
+ if (System.getProperty("gitbucket.validate.password") != "false" && !value.matches("[a-zA-Z0-9\\-_.]+")) {
Some(s"${name} contains invalid character.")
} else {
None
}
}
-
/**
* Constraint for the repository identifier.
*/
- def repository: Constraint = new Constraint(){
+ def repository: Constraint = new Constraint() {
override def validate(name: String, value: String, messages: Messages): Option[String] =
- if(!value.matches("[a-zA-Z0-9\\-\\+_.]+")){
+ if (!value.matches("[a-zA-Z0-9\\-\\+_.]+")) {
Some(s"${name} contains invalid character.")
- } else if(value.startsWith("_") || value.startsWith("-")){
+ } else if (value.startsWith("_") || value.startsWith("-")) {
Some(s"${name} starts with invalid character.")
} else {
None
@@ -55,8 +54,9 @@
* ValueType for the java.util.Date property.
*/
def date(constraints: Constraint*): SingleValueType[java.util.Date] =
- new SingleValueType[java.util.Date]((pattern("\\d{4}-\\d{2}-\\d{2}") +: constraints): _*){
- def convert(value: String, messages: Messages): java.util.Date = new java.text.SimpleDateFormat("yyyy-MM-dd").parse(value)
+ new SingleValueType[java.util.Date]((pattern("\\d{4}-\\d{2}-\\d{2}") +: constraints): _*) {
+ def convert(value: String, messages: Messages): java.util.Date =
+ new java.text.SimpleDateFormat("yyyy-MM-dd").parse(value)
}
}
diff --git a/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala b/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala
index 8cd64d0..1c233e9 100644
--- a/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala
+++ b/src/main/scala/gitbucket/core/view/AvatarImageProvider.scala
@@ -11,13 +11,14 @@
* Returns <img> which displays the avatar icon.
* Looks up Gravatar if avatar icon has not been configured in user settings.
*/
- protected def getAvatarImageHtml(userName: String, size: Int,
- mailAddress: String = "", tooltip: Boolean = false)(implicit context: Context): Html = {
+ protected def getAvatarImageHtml(userName: String, size: Int, mailAddress: String = "", tooltip: Boolean = false)(
+ implicit context: Context
+ ): Html = {
- val src = if(mailAddress.isEmpty){
+ val src = if (mailAddress.isEmpty) {
// by user name
getAccountByUserName(userName).map { account =>
- if(account.image.isEmpty && context.settings.gravatar){
+ if (account.image.isEmpty && context.settings.gravatar) {
s"""https://www.gravatar.com/avatar/${StringUtil.md5(account.mailAddress.toLowerCase)}?s=${size}&d=retro&r=g"""
} else {
s"""${context.path}/${account.userName}/_avatar?${helpers.hashDate(account.updatedDate)}"""
@@ -28,13 +29,13 @@
} else {
// by mail address
getAccountByMailAddress(mailAddress).map { account =>
- if(account.image.isEmpty && context.settings.gravatar){
+ if (account.image.isEmpty && context.settings.gravatar) {
s"""https://www.gravatar.com/avatar/${StringUtil.md5(account.mailAddress.toLowerCase)}?s=${size}&d=retro&r=g"""
} else {
s"""${context.path}/${account.userName}/_avatar?${helpers.hashDate(account.updatedDate)}"""
}
} getOrElse {
- if(context.settings.gravatar){
+ if (context.settings.gravatar) {
s"""https://www.gravatar.com/avatar/${StringUtil.md5(mailAddress.toLowerCase)}?s=${size}&d=retro&r=g"""
} else {
s"""${context.path}/_unknown/_avatar"""
@@ -42,10 +43,14 @@
}
}
- if(tooltip){
- Html(s"""
""")
+ if (tooltip) {
+ Html(
+ s"""
"""
+ )
} else {
- Html(s"""
""")
+ Html(
+ s"""
"""
+ )
}
}
diff --git a/src/main/scala/gitbucket/core/view/LinkConverter.scala b/src/main/scala/gitbucket/core/view/LinkConverter.scala
index 00d4e88..5b689d9 100644
--- a/src/main/scala/gitbucket/core/view/LinkConverter.scala
+++ b/src/main/scala/gitbucket/core/view/LinkConverter.scala
@@ -9,8 +9,10 @@
/**
* Creates a link to the issue or the pull request from the issue id.
*/
- protected def createIssueLink(repository: RepositoryService.RepositoryInfo, issueId: Int)(implicit context: Context): String = {
- val userName = repository.repository.userName
+ protected def createIssueLink(repository: RepositoryService.RepositoryInfo, issueId: Int)(
+ implicit context: Context
+ ): String = {
+ val userName = repository.repository.userName
val repositoryName = repository.repository.repositoryName
getIssue(userName, repositoryName, issueId.toString) match {
@@ -23,78 +25,96 @@
}
}
-
/**
* Converts issue id, username and commit id to link in the given text.
*/
- protected def convertRefsLinks(text: String, repository: RepositoryService.RepositoryInfo,
- issueIdPrefix: String = "#", escapeHtml: Boolean = true)(implicit context: Context): String = {
+ protected def convertRefsLinks(
+ text: String,
+ repository: RepositoryService.RepositoryInfo,
+ issueIdPrefix: String = "#",
+ escapeHtml: Boolean = true
+ )(implicit context: Context): String = {
// escape HTML tags
- val escaped = if(escapeHtml) text.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """) else text
+ val escaped =
+ if (escapeHtml) text.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """)
+ else text
escaped
- // convert username/project@SHA to link
- .replaceBy("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)@([a-f0-9]{40})(?=(\\W|$))".r){ m =>
+ // convert username/project@SHA to link
+ .replaceBy("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)@([a-f0-9]{40})(?=(\\W|$))".r) { m =>
getAccountByUserName(m.group(2)).map { _ =>
- s"""${m.group(2)}/${m.group(3)}@${m.group(4).substring(0, 7)}
"""
+ s"""${m.group(2)}/${m.group(
+ 3
+ )}@${m.group(4).substring(0, 7)}
"""
}
}
// convert username/project#Num to link
- .replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r){ m =>
- getIssue(m.group(2), m.group(3), m.group(4)) match {
- case Some(issue) if (issue.isPullRequest) =>
- Some(s"""${m.group(2)}/${m.group(3)}#${m.group(4)}""")
- case Some(_) =>
- Some(s"""${m.group(2)}/${m.group(3)}#${m.group(4)}""")
- case None =>
- Some(s"""${m.group(2)}/${m.group(3)}#${m.group(4)}""")
- }
+ .replaceBy(("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)/([a-zA-Z0-9\\-_\\.]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r) {
+ m =>
+ getIssue(m.group(2), m.group(3), m.group(4)) match {
+ case Some(issue) if (issue.isPullRequest) =>
+ Some(s"""${m.group(2)}/${m.group(
+ 3
+ )}#${m.group(4)}""")
+ case Some(_) =>
+ Some(s"""${m.group(2)}/${m
+ .group(3)}#${m.group(4)}""")
+ case None =>
+ Some(s"""${m.group(2)}/${m.group(3)}#${m.group(4)}""")
+ }
}
// convert username@SHA to link
- .replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)@([a-f0-9]{40})(?=(\\W|$))").r ) { m =>
+ .replaceBy(("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)@([a-f0-9]{40})(?=(\\W|$))").r) { m =>
getAccountByUserName(m.group(2)).map { _ =>
- s"""${m.group(2)}@${m.group(3).substring(0, 7)}
"""
+ s"""${m.group(2)}@${m
+ .group(3)
+ .substring(0, 7)}
"""
}
}
// convert username#Num to link
- .replaceBy( ("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r ) { m =>
+ .replaceBy(("(?<=(^|\\W))([a-zA-Z0-9\\-_]+)" + issueIdPrefix + "([0-9]+)(?=(\\W|$))").r) { m =>
getIssue(m.group(2), repository.name, m.group(3)) match {
- case Some(issue) if(issue.isPullRequest) =>
- Some(s"""${m.group(2)}#${m.group(3)}""")
+ case Some(issue) if (issue.isPullRequest) =>
+ Some(s"""${m.group(2)}#${m
+ .group(3)}""")
case Some(_) =>
- Some(s"""${m.group(2)}#${m.group(3)}""")
+ Some(s"""${m.group(2)}#${m
+ .group(3)}""")
case None =>
Some(s"""${m.group(2)}#${m.group(3)}""")
}
}
// convert issue id to link
- .replaceBy(("(?<=(^|\\W))(GH-|(?
- val prefix = if(m.group(2) == "issue:") "#" else m.group(2)
+ .replaceBy(("(?<=(^|\\W))(GH-|(?
+ val prefix = if (m.group(2) == "issue:") "#" else m.group(2)
getIssue(repository.owner, repository.name, m.group(3)) match {
- case Some(issue) if(issue.isPullRequest) =>
- Some(s"""${prefix}${m.group(3)}""")
+ case Some(issue) if (issue.isPullRequest) =>
+ Some(s"""${prefix}${m
+ .group(3)}""")
case Some(_) =>
- Some(s"""${prefix}${m.group(3)}""")
+ Some(s"""${prefix}${m
+ .group(3)}""")
case None =>
Some(s"""${m.group(2)}${m.group(3)}""")
}
}
// convert @username to link
- .replaceBy("(?<=(^|\\W))@([a-zA-Z0-9\\-_\\.]+)(?=(\\W|$))".r){ m =>
+ .replaceBy("(?<=(^|\\W))@([a-zA-Z0-9\\-_\\.]+)(?=(\\W|$))".r) { m =>
getAccountByUserName(m.group(2)).map { _ =>
s"""@${m.group(2)}"""
}
}
// convert commit id to link
- .replaceBy("(?<=(^|[^\\w/@]))([a-f0-9]{40})(?=(\\W|$))".r){ m =>
- Some(s"""${m.group(2).substring(0, 7)}
""")
+ .replaceBy("(?<=(^|[^\\w/@]))([a-f0-9]{40})(?=(\\W|$))".r) { m =>
+ Some(s"""${m.group(2).substring(0, 7)}
""")
}
}
}
diff --git a/src/main/scala/gitbucket/core/view/Markdown.scala b/src/main/scala/gitbucket/core/view/Markdown.scala
index a4d05b6..4eac137 100644
--- a/src/main/scala/gitbucket/core/view/Markdown.scala
+++ b/src/main/scala/gitbucket/core/view/Markdown.scala
@@ -24,24 +24,34 @@
* @param hasWritePermission true if user has writable to ths given repository
* @param pages the list of existing Wiki pages
*/
- def toHtml(markdown: String,
- repository: RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean,
- enableRefsLink: Boolean,
- enableAnchor: Boolean,
- enableLineBreaks: Boolean,
- enableTaskList: Boolean = false,
- hasWritePermission: Boolean = false,
- pages: List[String] = Nil)(implicit context: Context): String = {
+ def toHtml(
+ markdown: String,
+ repository: RepositoryService.RepositoryInfo,
+ enableWikiLink: Boolean,
+ enableRefsLink: Boolean,
+ enableAnchor: Boolean,
+ enableLineBreaks: Boolean,
+ enableTaskList: Boolean = false,
+ hasWritePermission: Boolean = false,
+ pages: List[String] = Nil
+ )(implicit context: Context): String = {
// escape task list
- val source = if(enableTaskList) escapeTaskList(markdown) else markdown
+ val source = if (enableTaskList) escapeTaskList(markdown) else markdown
val options = new Options()
options.setBreaks(enableLineBreaks)
- val renderer = new GitBucketMarkedRenderer(options, repository,
- enableWikiLink, enableRefsLink, enableAnchor, enableTaskList, hasWritePermission, pages)
+ val renderer = new GitBucketMarkedRenderer(
+ options,
+ repository,
+ enableWikiLink,
+ enableRefsLink,
+ enableAnchor,
+ enableTaskList,
+ hasWritePermission,
+ pages
+ )
Marked.marked(source, options, renderer)
}
@@ -49,25 +59,31 @@
/**
* Extends markedj Renderer for GitBucket
*/
- class GitBucketMarkedRenderer(options: Options,
- repository: RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean,
- enableRefsLink: Boolean,
- enableAnchor: Boolean,
- enableTaskList: Boolean,
- hasWritePermission: Boolean,
- pages: List[String])
- (implicit val context: Context) extends Renderer(options) with LinkConverter with RequestCache {
+ class GitBucketMarkedRenderer(
+ options: Options,
+ repository: RepositoryService.RepositoryInfo,
+ enableWikiLink: Boolean,
+ enableRefsLink: Boolean,
+ enableAnchor: Boolean,
+ enableTaskList: Boolean,
+ hasWritePermission: Boolean,
+ pages: List[String]
+ )(implicit val context: Context)
+ extends Renderer(options)
+ with LinkConverter
+ with RequestCache {
- 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 out = new StringBuilder()
out.append("")
- out.append("")
+ out.append(
+ ""
+ )
out.append("")
} else {
out.append(">")
@@ -79,8 +95,8 @@
}
override def code(code: String, lang: String, escaped: Boolean): String = {
- "" +
- (if(escaped) code else escape(code, true)) + "
"
+ "" +
+ (if (escaped) code else escape(code, true)) + "
"
}
override def list(body: String, ordered: Boolean): String = {
@@ -90,7 +106,7 @@
} else {
listType = "ul"
}
- if(body.contains("""class="task-list-item-checkbox"""")){
+ if (body.contains("""class="task-list-item-checkbox"""")) {
"<" + listType + " class=\"task-list\">\n" + body + "" + listType + ">\n"
} else {
"<" + listType + ">\n" + body + "" + listType + ">\n"
@@ -98,7 +114,7 @@
}
override def listitem(text: String): String = {
- if(text.contains("""class="task-list-item-checkbox" """)){
+ if (text.contains("""class="task-list-item-checkbox" """)) {
"" + text + "\n"
} else {
"" + text + "\n"
@@ -107,9 +123,9 @@
override def text(text: String): String = {
// convert commit id and username to link.
- val t1 = if(enableRefsLink) convertRefsLinks(text, repository, "#", false) else text
+ val t1 = if (enableRefsLink) convertRefsLinks(text, repository, "#", false) else text
// convert task list to checkbox.
- val t2 = if(enableTaskList) convertCheckBox(t1, hasWritePermission) else t1
+ val t2 = if (enableTaskList) convertCheckBox(t1, hasWritePermission) else t1
// decorate by TextDecorator plugins
helpers.decorateHtml(t2, repository)
}
@@ -123,18 +139,20 @@
}
override def nolink(text: String): String = {
- if(enableWikiLink && text.startsWith("[[") && text.endsWith("]]")){
+ if (enableWikiLink && text.startsWith("[[") && text.endsWith("]]")) {
val link = text.replaceAll("(^\\[\\[|\\]\\]$)", "")
- val (label, page) = if(link.contains('|')){
+ val (label, page) = if (link.contains('|')) {
val i = link.indexOf('|')
(link.substring(0, i), link.substring(i + 1))
} else {
(link, link)
}
- val url = repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/" + StringUtil.urlEncode(page)
- if(pages.contains(page)){
+ val url = repository.httpUrl.replaceFirst("/git/", "/").stripSuffix(".git") + "/wiki/" + StringUtil.urlEncode(
+ page
+ )
+ if (pages.contains(page)) {
"" + escape(label) + ""
} else {
"" + escape(label) + ""
@@ -145,22 +163,22 @@
}
private def fixUrl(url: String, isImage: Boolean = false): String = {
- lazy val urlWithRawParam: String = url + (if(isImage && !url.endsWith("?raw=true")) "?raw=true" else "")
+ lazy val urlWithRawParam: String = url + (if (isImage && !url.endsWith("?raw=true")) "?raw=true" else "")
- if(url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:") || url.startsWith("/")){
+ if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:") || url.startsWith("/")) {
url
- } else if(url.startsWith("#")){
+ } else if (url.startsWith("#")) {
("#" + generateAnchorName(url.substring(1)))
- } else if(!enableWikiLink){
- if(context.currentPath.contains("/blob/")){
+ } else if (!enableWikiLink) {
+ if (context.currentPath.contains("/blob/")) {
urlWithRawParam
- } else if(context.currentPath.contains("/tree/")){
+ } else if (context.currentPath.contains("/tree/")) {
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 + "/" + urlWithRawParam
} else {
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 + "/" + urlWithRawParam
}
} else {
@@ -176,15 +194,18 @@
def generateAnchorName(text: String): String = {
val normalized = Normalizer.normalize(text.replaceAll("<.*>", "").replaceAll("[\\s]", "-"), Normalizer.Form.NFD)
- val encoded = StringUtil.urlEncode(normalized)
+ val encoded = StringUtil.urlEncode(normalized)
encoded.toLowerCase(Locale.ENGLISH)
}
def convertCheckBox(text: String, hasWritePermission: Boolean): String = {
val disabled = if (hasWritePermission) "" else "disabled"
- text.replaceAll("task:x:", """")
+ text
+ .replaceAll(
+ "task:x:",
+ """"
+ )
.replaceAll("task: :", """")
}
}
-
diff --git a/src/main/scala/gitbucket/core/view/Pagination.scala b/src/main/scala/gitbucket/core/view/Pagination.scala
index ad91368..c415132 100644
--- a/src/main/scala/gitbucket/core/view/Pagination.scala
+++ b/src/main/scala/gitbucket/core/view/Pagination.scala
@@ -9,7 +9,7 @@
* @param limit the limit record count per one page
* @param width the width (number of cells) of the paginator
*/
-case class Pagination(page: Int, count: Int, limit: Int, width: Int){
+case class Pagination(page: Int, count: Int, limit: Int, width: Int) {
/**
* max page number
@@ -19,7 +19,7 @@
/**
* whether to omit the left side
*/
- val omitLeft = width / 2 < page
+ val omitLeft = width / 2 < page
/**
* whether to omit the right side
@@ -30,15 +30,15 @@
* Returns true if given page number is visible.
*/
def visibleFor(i: Int): Boolean = {
- if(i == 1 || i == max){
+ if (i == 1 || i == max) {
true
} else {
- val leftRange = page - width / 2 + (if(omitLeft) 2 else 0)
- val rightRange = page + width / 2 - (if(omitRight) 2 else 0)
+ val leftRange = page - width / 2 + (if (omitLeft) 2 else 0)
+ val rightRange = page + width / 2 - (if (omitRight) 2 else 0)
- val fixedRange = if(leftRange < 1){
+ val fixedRange = if (leftRange < 1) {
(1, rightRange + (leftRange * -1) + 1)
- } else if(rightRange > max){
+ } else if (rightRange > max) {
(leftRange - (rightRange - max), max)
} else {
(leftRange, rightRange)
diff --git a/src/main/scala/gitbucket/core/view/helpers.scala b/src/main/scala/gitbucket/core/view/helpers.scala
index 41088aa..c5f1a40 100644
--- a/src/main/scala/gitbucket/core/view/helpers.scala
+++ b/src/main/scala/gitbucket/core/view/helpers.scala
@@ -51,7 +51,7 @@
val duration = new Date().getTime - date.getTime
timeUnits.find(tuple => duration / tuple._1 > 0) match {
case Some((_, "month")) => s"on ${new SimpleDateFormat("d MMM", Locale.ENGLISH).format(date)}"
- case Some((_, "year")) => s"on ${new SimpleDateFormat("d MMM yyyy", Locale.ENGLISH).format(date)}"
+ case Some((_, "year")) => s"on ${new SimpleDateFormat("d MMM yyyy", Locale.ENGLISH).format(date)}"
case Some((unitValue, unitString)) =>
val value = duration / unitValue
s"${value} ${unitString}${if (value > 1) "s" else ""} ago"
@@ -59,7 +59,6 @@
}
}
-
/**
* Format java.util.Date to "yyyy-MM-dd'T'hh:mm:ss'Z'".
*/
@@ -94,44 +93,56 @@
* If plural is not specified, returns singular + "s" as plural.
*/
def plural(count: Int, singular: String, plural: String = ""): String =
- if(count == 1) singular else if(plural.isEmpty) singular + "s" else plural
+ if (count == 1) singular else if (plural.isEmpty) singular + "s" else plural
/**
* Converts Markdown of Wiki pages to HTML.
*/
- def markdown(markdown: String,
- repository: RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean,
- enableRefsLink: Boolean,
- enableLineBreaks: Boolean,
- enableAnchor: Boolean = true,
- enableTaskList: Boolean = false,
- hasWritePermission: Boolean = false,
- pages: List[String] = Nil)(implicit context: Context): Html =
- Html(Markdown.toHtml(
- markdown = markdown,
- repository = repository,
- enableWikiLink = enableWikiLink,
- enableRefsLink = enableRefsLink,
- enableAnchor = enableAnchor,
- enableLineBreaks = enableLineBreaks,
- enableTaskList = enableTaskList,
- hasWritePermission = hasWritePermission,
- pages = pages
- ))
+ def markdown(
+ markdown: String,
+ repository: RepositoryService.RepositoryInfo,
+ enableWikiLink: Boolean,
+ enableRefsLink: Boolean,
+ enableLineBreaks: Boolean,
+ enableAnchor: Boolean = true,
+ enableTaskList: Boolean = false,
+ hasWritePermission: Boolean = false,
+ pages: List[String] = Nil
+ )(implicit context: Context): Html =
+ Html(
+ Markdown.toHtml(
+ markdown = markdown,
+ repository = repository,
+ enableWikiLink = enableWikiLink,
+ enableRefsLink = enableRefsLink,
+ enableAnchor = enableAnchor,
+ enableLineBreaks = enableLineBreaks,
+ enableTaskList = enableTaskList,
+ hasWritePermission = hasWritePermission,
+ pages = pages
+ )
+ )
/**
* Render the given source (only markdown is supported in default) as HTML.
* You can test if a file is renderable in this method by [[isRenderable()]].
*/
- def renderMarkup(filePath: List[String], fileContent: String, branch: String,
- repository: RepositoryService.RepositoryInfo,
- enableWikiLink: Boolean, enableRefsLink: Boolean, enableAnchor: Boolean)(implicit context: Context): Html = {
+ def renderMarkup(
+ filePath: List[String],
+ fileContent: String,
+ branch: String,
+ repository: RepositoryService.RepositoryInfo,
+ enableWikiLink: Boolean,
+ enableRefsLink: Boolean,
+ enableAnchor: Boolean
+ )(implicit context: Context): Html = {
- val fileName = filePath.last.toLowerCase
+ val fileName = filePath.last.toLowerCase
val extension = FileUtil.getExtension(fileName)
- val renderer = PluginRegistry().getRenderer(extension)
- renderer.render(RenderRequest(filePath, fileContent, branch, repository, enableWikiLink, enableRefsLink, enableAnchor, context))
+ val renderer = PluginRegistry().getRenderer(extension)
+ renderer.render(
+ RenderRequest(filePath, fileContent, branch, repository, enableWikiLink, enableRefsLink, enableAnchor, context)
+ )
}
/**
@@ -152,7 +163,9 @@
* Returns <img> which displays the avatar icon for the given user name.
* This method looks up Gravatar if avatar icon has not been configured in user settings.
*/
- def avatar(userName: String, size: Int, tooltip: Boolean = false, mailAddress: String = "")(implicit context: Context): Html =
+ def avatar(userName: String, size: Int, tooltip: Boolean = false, mailAddress: String = "")(
+ implicit context: Context
+ ): Html =
getAvatarImageHtml(userName, size, mailAddress, tooltip)
/**
@@ -169,7 +182,7 @@
Html(decorateHtml(convertRefsLinks(value, repository), repository))
def cut(value: String, length: Int): String =
- if(value.length > length){
+ if (value.length > length) {
value.substring(0, length) + "..."
} else {
value
@@ -186,14 +199,36 @@
* Convert link notations in the activity message.
*/
def activityMessage(message: String)(implicit context: Context): Html =
- Html(message
- .replaceAll("\\[issue:([^\\s]+?)/([^\\s]+?)#((\\d+))\\]" , s"""$$1/$$2#$$3""")
- .replaceAll("\\[pullreq:([^\\s]+?)/([^\\s]+?)#((\\d+))\\]" , s"""$$1/$$2#$$3""")
- .replaceAll("\\[repo:([^\\s]+?)/([^\\s]+?)\\]" , s"""$$1/$$2""")
- .replaceAll("\\[branch:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]" , (m: Match) => s"""${m.group(3)}""")
- .replaceAll("\\[tag:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]" , (m: Match) => s"""${m.group(3)}""")
- .replaceAll("\\[user:([^\\s]+?)\\]" , (m: Match) => user(m.group(1)).body)
- .replaceAll("\\[commit:([^\\s]+?)/([^\\s]+?)\\@([^\\s]+?)\\]", (m: Match) => s"""${m.group(1)}/${m.group(2)}@${m.group(3).substring(0, 7)}""")
+ Html(
+ message
+ .replaceAll(
+ "\\[issue:([^\\s]+?)/([^\\s]+?)#((\\d+))\\]",
+ s"""$$1/$$2#$$3"""
+ )
+ .replaceAll(
+ "\\[pullreq:([^\\s]+?)/([^\\s]+?)#((\\d+))\\]",
+ s"""$$1/$$2#$$3"""
+ )
+ .replaceAll("\\[repo:([^\\s]+?)/([^\\s]+?)\\]", s"""$$1/$$2""")
+ .replaceAll(
+ "\\[branch:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
+ (m: Match) =>
+ s"""${m
+ .group(3)}"""
+ )
+ .replaceAll(
+ "\\[tag:([^\\s]+?)/([^\\s]+?)#([^\\s]+?)\\]",
+ (m: Match) =>
+ s"""${m
+ .group(3)}"""
+ )
+ .replaceAll("\\[user:([^\\s]+?)\\]", (m: Match) => user(m.group(1)).body)
+ .replaceAll(
+ "\\[commit:([^\\s]+?)/([^\\s]+?)\\@([^\\s]+?)\\]",
+ (m: Match) =>
+ s"""${m.group(1)}/${m
+ .group(2)}@${m.group(3).substring(0, 7)}"""
+ )
)
/**
@@ -243,33 +278,38 @@
* Generates the avatar link to the account page.
* If user does not exist or disabled, this method returns avatar image without link.
*/
- def avatarLink(userName: String, size: Int, mailAddress: String = "", tooltip: Boolean = false, label: Boolean = false)
- (implicit context: Context): Html = {
+ def avatarLink(
+ userName: String,
+ size: Int,
+ mailAddress: String = "",
+ tooltip: Boolean = false,
+ label: Boolean = false
+ )(implicit context: Context): Html = {
val avatarHtml = avatar(userName, size, tooltip, mailAddress)
- val contentHtml = if(label == true) Html(avatarHtml.body + " " + userName) else avatarHtml
+ val contentHtml = if (label == true) Html(avatarHtml.body + " " + userName) else avatarHtml
userWithContent(userName, mailAddress)(contentHtml)
}
/**
- * Generates the avatar link to the account page.
- * If user does not exist or disabled, this method returns avatar image without link.
- */
+ * Generates the avatar link to the account page.
+ * If user does not exist or disabled, this method returns avatar image without link.
+ */
def avatarLink(commit: JGitUtil.CommitInfo, size: Int)(implicit context: Context): Html =
userWithContent(commit.authorName, commit.authorEmailAddress)(avatar(commit, size))
- private def userWithContent(userName: String, mailAddress: String = "", styleClass: String = "")(content: Html)
- (implicit context: Context): Html =
- (if(mailAddress.isEmpty){
- getAccountByUserName(userName)
- } else {
- getAccountByMailAddress(mailAddress)
- }).map { account =>
+ private def userWithContent(userName: String, mailAddress: String = "", styleClass: String = "")(
+ content: Html
+ )(implicit context: Context): Html =
+ (if (mailAddress.isEmpty) {
+ getAccountByUserName(userName)
+ } else {
+ getAccountByMailAddress(mailAddress)
+ }).map { account =>
Html(s"""${content}""")
} getOrElse content
-
/**
* Test whether the given Date is past date.
*/
@@ -280,36 +320,36 @@
*/
def editorType(fileName: String): String = {
fileName.toLowerCase match {
- case x if(x.endsWith(".bat")) => "batchfile"
- case x if(x.endsWith(".java")) => "java"
- case x if(x.endsWith(".scala")) => "scala"
- case x if(x.endsWith(".js")) => "javascript"
- case x if(x.endsWith(".css")) => "css"
- case x if(x.endsWith(".md")) => "markdown"
- case x if(x.endsWith(".html")) => "html"
- case x if(x.endsWith(".xml")) => "xml"
- case x if(x.endsWith(".c")) => "c_cpp"
- case x if(x.endsWith(".cpp")) => "c_cpp"
- case x if(x.endsWith(".coffee")) => "coffee"
- case x if(x.endsWith(".ejs")) => "ejs"
- case x if(x.endsWith(".hs")) => "haskell"
- case x if(x.endsWith(".json")) => "json"
- case x if(x.endsWith(".jsp")) => "jsp"
- case x if(x.endsWith(".jsx")) => "jsx"
- case x if(x.endsWith(".cl")) => "lisp"
- case x if(x.endsWith(".clojure")) => "lisp"
- case x if(x.endsWith(".lua")) => "lua"
- case x if(x.endsWith(".php")) => "php"
- case x if(x.endsWith(".py")) => "python"
- case x if(x.endsWith(".rdoc")) => "rdoc"
- case x if(x.endsWith(".rhtml")) => "rhtml"
- case x if(x.endsWith(".ruby")) => "ruby"
- case x if(x.endsWith(".sh")) => "sh"
- case x if(x.endsWith(".sql")) => "sql"
- case x if(x.endsWith(".tcl")) => "tcl"
- case x if(x.endsWith(".vbs")) => "vbscript"
- case x if(x.endsWith(".yml")) => "yaml"
- case _ => "plain_text"
+ case x if (x.endsWith(".bat")) => "batchfile"
+ case x if (x.endsWith(".java")) => "java"
+ case x if (x.endsWith(".scala")) => "scala"
+ case x if (x.endsWith(".js")) => "javascript"
+ case x if (x.endsWith(".css")) => "css"
+ case x if (x.endsWith(".md")) => "markdown"
+ case x if (x.endsWith(".html")) => "html"
+ case x if (x.endsWith(".xml")) => "xml"
+ case x if (x.endsWith(".c")) => "c_cpp"
+ case x if (x.endsWith(".cpp")) => "c_cpp"
+ case x if (x.endsWith(".coffee")) => "coffee"
+ case x if (x.endsWith(".ejs")) => "ejs"
+ case x if (x.endsWith(".hs")) => "haskell"
+ case x if (x.endsWith(".json")) => "json"
+ case x if (x.endsWith(".jsp")) => "jsp"
+ case x if (x.endsWith(".jsx")) => "jsx"
+ case x if (x.endsWith(".cl")) => "lisp"
+ case x if (x.endsWith(".clojure")) => "lisp"
+ case x if (x.endsWith(".lua")) => "lua"
+ case x if (x.endsWith(".php")) => "php"
+ case x if (x.endsWith(".py")) => "python"
+ case x if (x.endsWith(".rdoc")) => "rdoc"
+ case x if (x.endsWith(".rhtml")) => "rhtml"
+ case x if (x.endsWith(".ruby")) => "ruby"
+ case x if (x.endsWith(".sh")) => "sh"
+ case x if (x.endsWith(".sql")) => "sql"
+ case x if (x.endsWith(".tcl")) => "tcl"
+ case x if (x.endsWith(".vbs")) => "vbscript"
+ case x if (x.endsWith(".yml")) => "yaml"
+ case _ => "plain_text"
}
}
@@ -323,15 +363,20 @@
def mkHtml(separator: scala.xml.Elem) = Html(seq.mkString(separator.toString))
}
- def commitStateIcon(state: CommitState) = Html(state match {
- case CommitState.PENDING => """"""
- case CommitState.SUCCESS => """"""
- case CommitState.ERROR => """"""
- case CommitState.FAILURE => """"""
- })
+ def commitStateIcon(state: CommitState) =
+ Html(state match {
+ case CommitState.PENDING =>
+ """"""
+ case CommitState.SUCCESS =>
+ """"""
+ case CommitState.ERROR =>
+ """"""
+ case CommitState.FAILURE =>
+ """"""
+ })
- def commitStateText(state: CommitState, commitId:String) = state match {
- case CommitState.PENDING => "Waiting to hear about "+commitId.substring(0,8)
+ def commitStateText(state: CommitState, commitId: String) = state match {
+ case CommitState.PENDING => "Waiting to hear about " + commitId.substring(0, 8)
case CommitState.SUCCESS => "All is well"
case CommitState.ERROR => "Failed"
case CommitState.FAILURE => "Failed"
@@ -346,18 +391,23 @@
}
// This pattern comes from: http://stackoverflow.com/a/4390768/1771641 (extract-url-from-string)
- private[this] val urlRegex = """(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,13}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""".r
+ private[this] val urlRegex =
+ """(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,13}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))""".r
def urlLink(text: String): String = {
val matches = urlRegex.findAllMatchIn(text).toSeq
- val (x, pos) = matches.foldLeft((collection.immutable.Seq.empty[Html], 0)){ case ((x, pos), m) =>
- val url = m.group(0)
- val href = url.replace("\"", """)
- (x ++ (Seq(
- if(pos < m.start) Some(HtmlFormat.escape(text.substring(pos, m.start))) else None,
- Some(Html(s"""${url}"""))
- ).flatten), m.end)
+ val (x, pos) = matches.foldLeft((collection.immutable.Seq.empty[Html], 0)) {
+ case ((x, pos), m) =>
+ val url = m.group(0)
+ val href = url.replace("\"", """)
+ (
+ x ++ (Seq(
+ if (pos < m.start) Some(HtmlFormat.escape(text.substring(pos, m.start))) else None,
+ Some(Html(s"""${url}"""))
+ ).flatten),
+ m.end
+ )
}
// append rest fragment
val out = if (pos < text.length) x :+ HtmlFormat.escape(text.substring(pos)) else x
@@ -369,38 +419,39 @@
* TextDecorators are applied to only text parts of a given HTML.
*/
def decorateHtml(html: String, repository: RepositoryInfo)(implicit context: Context): String = {
- PluginRegistry().getTextDecorators.foldLeft(html){ case (html, decorator) =>
- val text = new StringBuilder()
- val result = new StringBuilder()
- var tag = false
+ PluginRegistry().getTextDecorators.foldLeft(html) {
+ case (html, decorator) =>
+ val text = new StringBuilder()
+ val result = new StringBuilder()
+ var tag = false
- html.foreach { c =>
- c match {
- case '<' if tag == false => {
- tag = true
- if(text.nonEmpty){
- result.append(decorator.decorate(text.toString, repository))
- text.setLength(0)
+ html.foreach { c =>
+ c match {
+ case '<' if tag == false => {
+ tag = true
+ if (text.nonEmpty) {
+ result.append(decorator.decorate(text.toString, repository))
+ text.setLength(0)
+ }
+ result.append(c)
}
- result.append(c)
- }
- case '>' if tag == true => {
- tag = false
- result.append(c)
- }
- case _ if tag == false => {
- text.append(c)
- }
- case _ if tag == true => {
- result.append(c)
+ case '>' if tag == true => {
+ tag = false
+ result.append(c)
+ }
+ case _ if tag == false => {
+ text.append(c)
+ }
+ case _ if tag == true => {
+ result.append(c)
+ }
}
}
- }
- if(text.nonEmpty){
- result.append(decorator.decorate(text.toString, repository))
- }
+ if (text.nonEmpty) {
+ result.append(decorator.decorate(text.toString, repository))
+ }
- result.toString
+ result.toString
}
}