mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 19:45:57 +01:00
Compare commits
8 Commits
optimize-c
...
quill
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a9588f17f | ||
|
|
682f3a4c10 | ||
|
|
dad29d93c2 | ||
|
|
fc99de8a65 | ||
|
|
bc4af8e7c1 | ||
|
|
cb3a79c9b3 | ||
|
|
b775ce157f | ||
|
|
cfcd250914 |
@@ -38,6 +38,7 @@ libraryDependencies ++= Seq(
|
|||||||
"com.mchange" % "c3p0" % "0.9.5.2",
|
"com.mchange" % "c3p0" % "0.9.5.2",
|
||||||
"com.typesafe" % "config" % "1.3.0",
|
"com.typesafe" % "config" % "1.3.0",
|
||||||
"com.typesafe.akka" %% "akka-actor" % "2.3.14",
|
"com.typesafe.akka" %% "akka-actor" % "2.3.14",
|
||||||
|
"io.getquill" %% "quill-jdbc" % "0.4.1",
|
||||||
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.0.0",
|
"fr.brouillard.oss.security.xhub" % "xhub4j-core" % "1.0.0",
|
||||||
"com.enragedginger" %% "akka-quartz-scheduler" % "1.4.0-akka-2.3.x" exclude("c3p0","c3p0"),
|
"com.enragedginger" %% "akka-quartz-scheduler" % "1.4.0-akka-2.3.x" exclude("c3p0","c3p0"),
|
||||||
"org.eclipse.jetty" % "jetty-webapp" % JettyVersion % "provided",
|
"org.eclipse.jetty" % "jetty-webapp" % JettyVersion % "provided",
|
||||||
|
|||||||
8
src/main/resources/application.conf
Normal file
8
src/main/resources/application.conf
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
db.dataSourceClassName="org.h2.jdbcx.JdbcDataSource"
|
||||||
|
db.dataSource.url="jdbc:h2:~/.gitbucket/data;MVCC=true"
|
||||||
|
db.dataSource.user="sa"
|
||||||
|
db.dataSource.password="sa"
|
||||||
|
#db.dataSource.cachePrepStmts=true
|
||||||
|
#db.dataSource.prepStmtCacheSize=250
|
||||||
|
#db.dataSource.prepStmtCacheSqlLimit=2048
|
||||||
|
#db.connectionTimeout=30000
|
||||||
@@ -39,7 +39,7 @@ object ApiRepository{
|
|||||||
description = repository.description.getOrElse(""),
|
description = repository.description.getOrElse(""),
|
||||||
watchers = 0,
|
watchers = 0,
|
||||||
forks = forkedCount,
|
forks = forkedCount,
|
||||||
`private` = repository.isPrivate,
|
`private` = repository.`private`,
|
||||||
default_branch = repository.defaultBranch,
|
default_branch = repository.defaultBranch,
|
||||||
owner = owner
|
owner = owner
|
||||||
)(urlIsHtmlUrl)
|
)(urlIsHtmlUrl)
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ object ApiUser{
|
|||||||
def apply(user: Account): ApiUser = ApiUser(
|
def apply(user: Account): ApiUser = ApiUser(
|
||||||
login = user.userName,
|
login = user.userName,
|
||||||
email = user.mailAddress,
|
email = user.mailAddress,
|
||||||
`type` = if(user.isGroupAccount){ "Organization" }else{ "User" },
|
`type` = if(user.groupAccount){ "Organization" }else{ "User" },
|
||||||
site_admin = user.isAdmin,
|
site_admin = user.administrator,
|
||||||
created_at = user.registeredDate
|
created_at = user.registeredDate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,23 +114,23 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
// Public Activity
|
// Public Activity
|
||||||
case "activity" =>
|
case "activity" =>
|
||||||
gitbucket.core.account.html.activity(account,
|
gitbucket.core.account.html.activity(account,
|
||||||
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
if(account.groupAccount) Nil else getGroupsByUserName(userName),
|
||||||
getActivitiesByUser(userName, true))
|
getActivitiesByUser(userName, true))
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
case "members" if(account.isGroupAccount) => {
|
case "members" if(account.groupAccount) => {
|
||||||
val members = getGroupMembers(account.userName)
|
val members = getGroupMembers(account.userName)
|
||||||
gitbucket.core.account.html.members(account, members.map(_.userName),
|
gitbucket.core.account.html.members(account, members.map(_.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.manager }))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repositories
|
// Repositories
|
||||||
case _ => {
|
case _ => {
|
||||||
val members = getGroupMembers(account.userName)
|
val members = getGroupMembers(account.userName)
|
||||||
gitbucket.core.account.html.repositories(account,
|
gitbucket.core.account.html.repositories(account,
|
||||||
if(account.isGroupAccount) Nil else getGroupsByUserName(userName),
|
if(account.groupAccount) Nil else getGroupsByUserName(userName),
|
||||||
getVisibleRepositories(context.loginAccount, Some(userName)),
|
getVisibleRepositories(context.loginAccount, Some(userName)),
|
||||||
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.isManager }))
|
context.loginAccount.exists(x => members.exists { member => member.userName == x.userName && member.manager }))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} getOrElse NotFound
|
} getOrElse NotFound
|
||||||
@@ -190,7 +190,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
// removeUserRelatedData(userName)
|
// removeUserRelatedData(userName)
|
||||||
|
|
||||||
removeUserRelatedData(userName)
|
removeUserRelatedData(userName)
|
||||||
updateAccount(account.copy(isRemoved = true))
|
updateAccount(account.copy(removed = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
session.invalidate
|
session.invalidate
|
||||||
@@ -360,7 +360,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
case _: List[String] =>
|
case _: List[String] =>
|
||||||
val managerPermissions = groups.map { group =>
|
val managerPermissions = groups.map { group =>
|
||||||
val members = getGroupMembers(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.manager })
|
||||||
}
|
}
|
||||||
helper.html.forkrepository(
|
helper.html.forkrepository(
|
||||||
repository,
|
repository,
|
||||||
@@ -389,7 +389,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
repositoryName = repository.name,
|
repositoryName = repository.name,
|
||||||
userName = accountName,
|
userName = accountName,
|
||||||
description = repository.repository.description,
|
description = repository.repository.description,
|
||||||
isPrivate = repository.repository.isPrivate,
|
isPrivate = repository.repository.`private`,
|
||||||
originRepositoryName = Some(originRepositoryName),
|
originRepositoryName = Some(originRepositoryName),
|
||||||
originUserName = Some(originUserName),
|
originUserName = Some(originUserName),
|
||||||
parentRepositoryName = Some(repository.name),
|
parentRepositoryName = Some(repository.name),
|
||||||
@@ -398,7 +398,7 @@ trait AccountControllerBase extends AccountManagementControllerBase {
|
|||||||
|
|
||||||
// Add collaborators for group repository
|
// Add collaborators for group repository
|
||||||
val ownerAccount = getAccountByUserName(accountName).get
|
val ownerAccount = getAccountByUserName(accountName).get
|
||||||
if(ownerAccount.isGroupAccount){
|
if(ownerAccount.groupAccount){
|
||||||
getGroupMembers(accountName).foreach { member =>
|
getGroupMembers(accountName).foreach { member =>
|
||||||
addCollaborator(accountName, repository.name, member.userName)
|
addCollaborator(accountName, repository.name, member.userName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ abstract class ControllerBase extends ScalatraFilter
|
|||||||
if(account == null){
|
if(account == null){
|
||||||
// Redirect to login form
|
// Redirect to login form
|
||||||
httpResponse.sendRedirect(baseUrl + "/signin?redirect=" + StringUtil.urlEncode(path))
|
httpResponse.sendRedirect(baseUrl + "/signin?redirect=" + StringUtil.urlEncode(path))
|
||||||
} else if(account.isAdmin){
|
} else if(account.administrator){
|
||||||
// H2 Console (administrators only)
|
// H2 Console (administrators only)
|
||||||
chain.doFilter(request, response)
|
chain.doFilter(request, response)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ trait IndexControllerBase extends ControllerBase {
|
|||||||
get("/_user/proposals")(usersOnly {
|
get("/_user/proposals")(usersOnly {
|
||||||
contentType = formats("json")
|
contentType = formats("json")
|
||||||
org.json4s.jackson.Serialization.write(
|
org.json4s.jackson.Serialization.write(
|
||||||
Map("options" -> getAllUsers(false).filter(!_.isGroupAccount).map(_.userName).toArray)
|
Map("options" -> getAllUsers(false).filter(!_.groupAccount).map(_.userName).toArray)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
_,
|
_,
|
||||||
getComments(owner, name, issueId.toInt),
|
getComments(owner, name, issueId.toInt),
|
||||||
getIssueLabels(owner, name, issueId.toInt),
|
getIssueLabels(owner, name, issueId.toInt),
|
||||||
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted,
|
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted,
|
||||||
getMilestonesWithIssueCount(owner, name),
|
getMilestonesWithIssueCount(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
hasWritePermission(owner, name, context.loginAccount),
|
hasWritePermission(owner, name, context.loginAccount),
|
||||||
@@ -79,7 +79,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/issues/new")(readableUsersOnly { repository =>
|
get("/:owner/:repository/issues/new")(readableUsersOnly { repository =>
|
||||||
defining(repository.owner, repository.name){ case (owner, name) =>
|
defining(repository.owner, repository.name){ case (owner, name) =>
|
||||||
html.create(
|
html.create(
|
||||||
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted,
|
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted,
|
||||||
getMilestones(owner, name),
|
getMilestones(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
hasWritePermission(owner, name, context.loginAccount),
|
hasWritePermission(owner, name, context.loginAccount),
|
||||||
@@ -380,7 +380,7 @@ trait IssuesControllerBase extends ControllerBase {
|
|||||||
"issues",
|
"issues",
|
||||||
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
|
searchIssue(condition, false, (page - 1) * IssueLimit, IssueLimit, owner -> repoName),
|
||||||
page,
|
page,
|
||||||
if(!getAccountByUserName(owner).exists(_.isGroupAccount)){
|
if(!getAccountByUserName(owner).exists(_.groupAccount)){
|
||||||
(getCollaborators(owner, repoName) :+ owner).sorted
|
(getCollaborators(owner, repoName) :+ owner).sorted
|
||||||
} else {
|
} else {
|
||||||
getCollaborators(owner, repoName)
|
getCollaborators(owner, repoName)
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
(commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId))
|
(commits.flatten.map(commit => getCommitComments(owner, name, commit.id, true)).flatten.toList ::: getComments(owner, name, issueId))
|
||||||
.sortWith((a, b) => a.registeredDate before b.registeredDate),
|
.sortWith((a, b) => a.registeredDate before b.registeredDate),
|
||||||
getIssueLabels(owner, name, issueId),
|
getIssueLabels(owner, name, issueId),
|
||||||
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.isGroupAccount) Nil else List(owner))).sorted,
|
(getCollaborators(owner, name) ::: (if(getAccountByUserName(owner).get.groupAccount) Nil else List(owner))).sorted,
|
||||||
getMilestonesWithIssueCount(owner, name),
|
getMilestonesWithIssueCount(owner, name),
|
||||||
getLabels(owner, name),
|
getLabels(owner, name),
|
||||||
commits,
|
commits,
|
||||||
@@ -370,7 +370,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
originRepository,
|
originRepository,
|
||||||
forkedRepository,
|
forkedRepository,
|
||||||
hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount),
|
hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount),
|
||||||
(getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.isGroupAccount) Nil else List(originRepository.owner))).sorted,
|
(getCollaborators(originRepository.owner, originRepository.name) ::: (if(getAccountByUserName(originRepository.owner).get.groupAccount) Nil else List(originRepository.owner))).sorted,
|
||||||
getMilestones(originRepository.owner, originRepository.name),
|
getMilestones(originRepository.owner, originRepository.name),
|
||||||
getLabels(originRepository.owner, originRepository.name)
|
getLabels(originRepository.owner, originRepository.name)
|
||||||
)
|
)
|
||||||
@@ -524,7 +524,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
|||||||
"pulls",
|
"pulls",
|
||||||
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
|
searchIssue(condition, true, (page - 1) * PullRequestLimit, PullRequestLimit, owner -> repoName),
|
||||||
page,
|
page,
|
||||||
if(!getAccountByUserName(owner).exists(_.isGroupAccount)){
|
if(!getAccountByUserName(owner).exists(_.groupAccount)){
|
||||||
(getCollaborators(owner, repoName) :+ owner).sorted
|
(getCollaborators(owner, repoName) :+ owner).sorted
|
||||||
} else {
|
} else {
|
||||||
getCollaborators(owner, repoName)
|
getCollaborators(owner, repoName)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
repository.name,
|
repository.name,
|
||||||
form.description,
|
form.description,
|
||||||
repository.repository.parentUserName.map { _ =>
|
repository.repository.parentUserName.map { _ =>
|
||||||
repository.repository.isPrivate
|
repository.repository.`private`
|
||||||
} getOrElse form.isPrivate
|
} getOrElse form.isPrivate
|
||||||
)
|
)
|
||||||
// Change repository name
|
// Change repository name
|
||||||
@@ -148,7 +148,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
get("/:owner/:repository/settings/collaborators")(ownerOnly { repository =>
|
get("/:owner/:repository/settings/collaborators")(ownerOnly { repository =>
|
||||||
html.collaborators(
|
html.collaborators(
|
||||||
getCollaborators(repository.owner, repository.name),
|
getCollaborators(repository.owner, repository.name),
|
||||||
getAccountByUserName(repository.owner).get.isGroupAccount,
|
getAccountByUserName(repository.owner).get.groupAccount,
|
||||||
repository)
|
repository)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
* Add the collaborator.
|
* Add the collaborator.
|
||||||
*/
|
*/
|
||||||
post("/:owner/:repository/settings/collaborators/add", collaboratorForm)(ownerOnly { (form, repository) =>
|
post("/:owner/:repository/settings/collaborators/add", collaboratorForm)(ownerOnly { (form, repository) =>
|
||||||
if(!getAccountByUserName(repository.owner).get.isGroupAccount){
|
if(!getAccountByUserName(repository.owner).get.groupAccount){
|
||||||
addCollaborator(repository.owner, repository.name, form.userName)
|
addCollaborator(repository.owner, repository.name, form.userName)
|
||||||
}
|
}
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
|
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
|
||||||
@@ -166,7 +166,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
* Add the collaborator.
|
* Add the collaborator.
|
||||||
*/
|
*/
|
||||||
get("/:owner/:repository/settings/collaborators/remove")(ownerOnly { repository =>
|
get("/:owner/:repository/settings/collaborators/remove")(ownerOnly { repository =>
|
||||||
if(!getAccountByUserName(repository.owner).get.isGroupAccount){
|
if(!getAccountByUserName(repository.owner).get.groupAccount){
|
||||||
removeCollaborator(repository.owner, repository.name, params("name"))
|
removeCollaborator(repository.owner, repository.name, params("name"))
|
||||||
}
|
}
|
||||||
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
|
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
|
||||||
@@ -364,7 +364,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
|||||||
override def validate(name: String, value: String, messages: Messages): Option[String] =
|
override def validate(name: String, value: String, messages: Messages): Option[String] =
|
||||||
getAccountByUserName(value) match {
|
getAccountByUserName(value) match {
|
||||||
case None => Some("User does not exist.")
|
case None => Some("User does not exist.")
|
||||||
case Some(x) if(x.isGroupAccount)
|
case Some(x) if(x.groupAccount)
|
||||||
=> Some("User does not exist.")
|
=> Some("User does not exist.")
|
||||||
case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName))
|
case Some(x) if(x.userName == params("owner") || getCollaborators(params("owner"), params("repository")).contains(x.userName))
|
||||||
=> Some("User can access this repository already.")
|
=> Some("User can access this repository already.")
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
get("/admin/users")(adminOnly {
|
get("/admin/users")(adminOnly {
|
||||||
val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false)
|
val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false)
|
||||||
val users = getAllUsers(includeRemoved)
|
val users = getAllUsers(includeRemoved)
|
||||||
val members = users.collect { case account if(account.isGroupAccount) =>
|
val members = users.collect { case account if(account.groupAccount) =>
|
||||||
account.userName -> getGroupMembers(account.userName).map(_.userName)
|
account.userName -> getGroupMembers(account.userName).map(_.userName)
|
||||||
}.toMap
|
}.toMap
|
||||||
|
|
||||||
@@ -196,12 +196,12 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateAccount(account.copy(
|
updateAccount(account.copy(
|
||||||
password = form.password.map(sha1).getOrElse(account.password),
|
password = form.password.map(sha1).getOrElse(account.password),
|
||||||
fullName = form.fullName,
|
fullName = form.fullName,
|
||||||
mailAddress = form.mailAddress,
|
mailAddress = form.mailAddress,
|
||||||
isAdmin = form.isAdmin,
|
administrator = form.isAdmin,
|
||||||
url = form.url,
|
url = form.url,
|
||||||
isRemoved = form.isRemoved))
|
removed = form.isRemoved))
|
||||||
|
|
||||||
updateImage(userName, form.fileId, form.clearImage)
|
updateImage(userName, form.fileId, form.clearImage)
|
||||||
redirect("/admin/users")
|
redirect("/admin/users")
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ trait AccountComponent { self: Profile =>
|
|||||||
val fullName = column[String]("FULL_NAME")
|
val fullName = column[String]("FULL_NAME")
|
||||||
val mailAddress = column[String]("MAIL_ADDRESS")
|
val mailAddress = column[String]("MAIL_ADDRESS")
|
||||||
val password = column[String]("PASSWORD")
|
val password = column[String]("PASSWORD")
|
||||||
val isAdmin = column[Boolean]("ADMINISTRATOR")
|
val administrator = column[Boolean]("ADMINISTRATOR")
|
||||||
val url = column[String]("URL")
|
val url = column[String]("URL")
|
||||||
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
|
val registeredDate = column[java.util.Date]("REGISTERED_DATE")
|
||||||
val updatedDate = column[java.util.Date]("UPDATED_DATE")
|
val updatedDate = column[java.util.Date]("UPDATED_DATE")
|
||||||
@@ -19,7 +19,7 @@ trait AccountComponent { self: Profile =>
|
|||||||
val image = column[String]("IMAGE")
|
val image = column[String]("IMAGE")
|
||||||
val groupAccount = column[Boolean]("GROUP_ACCOUNT")
|
val groupAccount = column[Boolean]("GROUP_ACCOUNT")
|
||||||
val removed = column[Boolean]("REMOVED")
|
val removed = column[Boolean]("REMOVED")
|
||||||
def * = (userName, fullName, mailAddress, password, isAdmin, url.?, registeredDate, updatedDate, lastLoginDate.?, image.?, groupAccount, removed) <> (Account.tupled, Account.unapply)
|
def * = (userName, fullName, mailAddress, password, administrator, url.?, registeredDate, updatedDate, lastLoginDate.?, image.?, groupAccount, removed) <> (Account.tupled, Account.unapply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +28,12 @@ case class Account(
|
|||||||
fullName: String,
|
fullName: String,
|
||||||
mailAddress: String,
|
mailAddress: String,
|
||||||
password: String,
|
password: String,
|
||||||
isAdmin: Boolean,
|
administrator: Boolean,
|
||||||
url: Option[String],
|
url: Option[String],
|
||||||
registeredDate: java.util.Date,
|
registeredDate: java.util.Date,
|
||||||
updatedDate: java.util.Date,
|
updatedDate: java.util.Date,
|
||||||
lastLoginDate: Option[java.util.Date],
|
lastLoginDate: Option[java.util.Date],
|
||||||
image: Option[String],
|
image: Option[String],
|
||||||
isGroupAccount: Boolean,
|
groupAccount: Boolean,
|
||||||
isRemoved: Boolean
|
removed: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ trait GroupMemberComponent { self: Profile =>
|
|||||||
class GroupMembers(tag: Tag) extends Table[GroupMember](tag, "GROUP_MEMBER") {
|
class GroupMembers(tag: Tag) extends Table[GroupMember](tag, "GROUP_MEMBER") {
|
||||||
val groupName = column[String]("GROUP_NAME", O PrimaryKey)
|
val groupName = column[String]("GROUP_NAME", O PrimaryKey)
|
||||||
val userName = column[String]("USER_NAME", O PrimaryKey)
|
val userName = column[String]("USER_NAME", O PrimaryKey)
|
||||||
val isManager = column[Boolean]("MANAGER")
|
val manager = column[Boolean]("MANAGER")
|
||||||
def * = (groupName, userName, isManager) <> (GroupMember.tupled, GroupMember.unapply)
|
def * = (groupName, userName, manager) <> (GroupMember.tupled, GroupMember.unapply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case class GroupMember(
|
case class GroupMember(
|
||||||
groupName: String,
|
groupName: String,
|
||||||
userName: String,
|
userName: String,
|
||||||
isManager: Boolean
|
manager: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ trait RepositoryComponent extends TemplateComponent { self: Profile =>
|
|||||||
case class Repository(
|
case class Repository(
|
||||||
userName: String,
|
userName: String,
|
||||||
repositoryName: String,
|
repositoryName: String,
|
||||||
isPrivate: Boolean,
|
`private`: Boolean,
|
||||||
description: Option[String],
|
description: Option[String],
|
||||||
defaultBranch: String,
|
defaultBranch: String,
|
||||||
registeredDate: java.util.Date,
|
registeredDate: java.util.Date,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import profile.simple._
|
|||||||
|
|
||||||
import gitbucket.core.model.{Account, AccessToken}
|
import gitbucket.core.model.{Account, AccessToken}
|
||||||
import gitbucket.core.util.StringUtil
|
import gitbucket.core.util.StringUtil
|
||||||
|
import gitbucket.core.servlet.Database._
|
||||||
|
import io.getquill._
|
||||||
|
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
|
|
||||||
@@ -27,28 +29,36 @@ trait AccessTokenService {
|
|||||||
var hash: String = null
|
var hash: String = null
|
||||||
do{
|
do{
|
||||||
token = makeAccessTokenString
|
token = makeAccessTokenString
|
||||||
hash = tokenToHash(token)
|
hash = tokenToHash(token)
|
||||||
}while(AccessTokens.filter(_.tokenHash === hash.bind).exists.run)
|
} while (
|
||||||
|
db.run(quote { (hash: String) => query[AccessToken].filter(_.tokenHash == hash).nonEmpty })(hash).head
|
||||||
|
)
|
||||||
val newToken = AccessToken(
|
val newToken = AccessToken(
|
||||||
userName = userName,
|
userName = userName,
|
||||||
note = note,
|
note = note,
|
||||||
tokenHash = hash)
|
tokenHash = hash)
|
||||||
|
|
||||||
|
// TODO Remain Slick code
|
||||||
val tokenId = (AccessTokens returning AccessTokens.map(_.accessTokenId)) += newToken
|
val tokenId = (AccessTokens returning AccessTokens.map(_.accessTokenId)) += newToken
|
||||||
(tokenId, token)
|
(tokenId, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAccountByAccessToken(token: String)(implicit s: Session): Option[Account] =
|
def getAccountByAccessToken(token: String): Option[Account] =
|
||||||
Accounts
|
db.run(quote { (tokenHash: String) =>
|
||||||
.innerJoin(AccessTokens)
|
query[AccessToken].filter(_.tokenHash == tokenHash)
|
||||||
.filter{ case (ac, t) => (ac.userName === t.userName) && (t.tokenHash === tokenToHash(token).bind) && (ac.removed === false.bind) }
|
.join(query[Account]).on { (t, a) => t.userName == a.userName && a.registeredDate == false }
|
||||||
.map{ case (ac, t) => ac }
|
.map { case (t, a) => a }
|
||||||
.firstOption
|
})(tokenToHash(token)).headOption
|
||||||
|
|
||||||
def getAccessTokens(userName: String)(implicit s: Session): List[AccessToken] =
|
def getAccessTokens(userName: String): List[AccessToken] =
|
||||||
AccessTokens.filter(_.userName === userName.bind).sortBy(_.accessTokenId.desc).list
|
db.run(quote { (userName: String) =>
|
||||||
|
query[AccessToken].filter(_.userName == userName).sortBy(_.accessTokenId)(Ord.desc)
|
||||||
|
})(userName)
|
||||||
|
|
||||||
def deleteAccessToken(userName: String, accessTokenId: Int)(implicit s: Session): Unit =
|
def deleteAccessToken(userName: String, accessTokenId: Int): Unit =
|
||||||
AccessTokens filter (t => t.userName === userName.bind && t.accessTokenId === accessTokenId) delete
|
db.run(quote { (userName: String, accessTokenId: Int) =>
|
||||||
|
query[AccessToken].filter { t => t.userName == userName && t.accessTokenId == accessTokenId }.delete
|
||||||
|
})(List((userName, accessTokenId)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import gitbucket.core.model.{GroupMember, Account}
|
import java.util.Date
|
||||||
|
|
||||||
|
import gitbucket.core.model.{GroupMember, Account, Collaborator, Repository}
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import gitbucket.core.util.{StringUtil, LDAPUtil}
|
import gitbucket.core.util.{StringUtil, LDAPUtil}
|
||||||
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
import gitbucket.core.service.SystemSettingsService.SystemSettings
|
||||||
import profile.simple._
|
import profile.simple._
|
||||||
import StringUtil._
|
import StringUtil._
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
// TODO Why is direct import required?
|
|
||||||
import gitbucket.core.model.Profile.dateColumnType
|
import gitbucket.core.servlet.Database._
|
||||||
|
import io.getquill._
|
||||||
|
|
||||||
trait AccountService {
|
trait AccountService {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(classOf[AccountService])
|
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): Option[Account] =
|
||||||
if(settings.ldapAuthentication){
|
if(settings.ldapAuthentication){
|
||||||
ldapAuthentication(settings, userName, password)
|
ldapAuthentication(settings, userName, password)
|
||||||
} else {
|
} else {
|
||||||
@@ -24,22 +27,21 @@ trait AccountService {
|
|||||||
/**
|
/**
|
||||||
* Authenticate by internal database.
|
* Authenticate by internal database.
|
||||||
*/
|
*/
|
||||||
private def defaultAuthentication(userName: String, password: String)(implicit s: Session) = {
|
private def defaultAuthentication(userName: String, password: String) = {
|
||||||
getAccountByUserName(userName).collect {
|
getAccountByUserName(userName).collect {
|
||||||
case account if(!account.isGroupAccount && account.password == sha1(password)) => Some(account)
|
case account if(!account.groupAccount && account.password == sha1(password)) => Some(account)
|
||||||
} getOrElse None
|
} getOrElse None
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticate by LDAP.
|
* Authenticate by LDAP.
|
||||||
*/
|
*/
|
||||||
private def ldapAuthentication(settings: SystemSettings, userName: String, password: String)
|
private def ldapAuthentication(settings: SystemSettings, userName: String, password: String): Option[Account] = {
|
||||||
(implicit s: Session): Option[Account] = {
|
|
||||||
LDAPUtil.authenticate(settings.ldap.get, userName, password) match {
|
LDAPUtil.authenticate(settings.ldap.get, userName, password) match {
|
||||||
case Right(ldapUserInfo) => {
|
case Right(ldapUserInfo) => {
|
||||||
// Create or update account by LDAP information
|
// Create or update account by LDAP information
|
||||||
getAccountByUserName(ldapUserInfo.userName, true) match {
|
getAccountByUserName(ldapUserInfo.userName, true) match {
|
||||||
case Some(x) if(!x.isRemoved) => {
|
case Some(x) if(!x.removed) => {
|
||||||
if(settings.ldap.get.mailAttribute.getOrElse("").isEmpty) {
|
if(settings.ldap.get.mailAttribute.getOrElse("").isEmpty) {
|
||||||
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
|
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
|
||||||
} else {
|
} else {
|
||||||
@@ -47,16 +49,16 @@ trait AccountService {
|
|||||||
}
|
}
|
||||||
getAccountByUserName(ldapUserInfo.userName)
|
getAccountByUserName(ldapUserInfo.userName)
|
||||||
}
|
}
|
||||||
case Some(x) if(x.isRemoved) => {
|
case Some(x) if(x.removed) => {
|
||||||
logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
|
logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
|
||||||
defaultAuthentication(userName, password)
|
defaultAuthentication(userName, password)
|
||||||
}
|
}
|
||||||
case None => getAccountByMailAddress(ldapUserInfo.mailAddress, true) match {
|
case None => getAccountByMailAddress(ldapUserInfo.mailAddress, true) match {
|
||||||
case Some(x) if(!x.isRemoved) => {
|
case Some(x) if(!x.removed) => {
|
||||||
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
|
updateAccount(x.copy(fullName = ldapUserInfo.fullName))
|
||||||
getAccountByUserName(ldapUserInfo.userName)
|
getAccountByUserName(ldapUserInfo.userName)
|
||||||
}
|
}
|
||||||
case Some(x) if(x.isRemoved) => {
|
case Some(x) if(x.removed) => {
|
||||||
logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
|
logger.info("LDAP Authentication Failed: Account is already registered but disabled.")
|
||||||
defaultAuthentication(userName, password)
|
defaultAuthentication(userName, password)
|
||||||
}
|
}
|
||||||
@@ -74,113 +76,163 @@ trait AccountService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAccountByUserName(userName: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] =
|
def getAccountByUserName(userName: String, includeRemoved: Boolean = false): Option[Account] = {
|
||||||
Accounts filter(t => (t.userName === userName.bind) && (t.removed === false.bind, !includeRemoved)) firstOption
|
db.run(quote { (userName: String, includeRemoved: Boolean) =>
|
||||||
|
query[Account].filter { t =>
|
||||||
|
if(includeRemoved){
|
||||||
|
t.userName == userName
|
||||||
|
} else {
|
||||||
|
t.userName == userName && t.removed == false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(userName, includeRemoved).headOption
|
||||||
|
}
|
||||||
|
|
||||||
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): Map[String, Account] = {
|
||||||
val map = knowns.map(a => a.userName -> a).toMap
|
val map = knowns.map(a => a.userName -> a).toMap
|
||||||
val needs = userNames -- map.keySet
|
val needs = userNames -- map.keySet
|
||||||
if(needs.isEmpty){
|
if(needs.isEmpty){
|
||||||
map
|
map
|
||||||
}else{
|
} else {
|
||||||
map ++ Accounts.filter(t => (t.userName inSetBind needs) && (t.removed === false.bind, !includeRemoved)).list.map(a => a.userName -> a).toMap
|
map ++ db.run(quote { (userNames: Set[String]) =>
|
||||||
|
query[Account].filter { t => userNames.contains(t.userName) && t.removed == false }
|
||||||
|
})(userNames.toSet).map { a => a.userName -> a }.toMap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false)(implicit s: Session): Option[Account] =
|
def getAccountByMailAddress(mailAddress: String, includeRemoved: Boolean = false): Option[Account] = {
|
||||||
Accounts filter(t => (t.mailAddress.toLowerCase === mailAddress.toLowerCase.bind) && (t.removed === false.bind, !includeRemoved)) firstOption
|
db.run(quote { (mailAddress: String, includeRemoved: Boolean) =>
|
||||||
|
query[Account].filter { t =>
|
||||||
|
if(includeRemoved){
|
||||||
|
t.mailAddress.toLowerCase == mailAddress.toLowerCase
|
||||||
|
} else {
|
||||||
|
t.mailAddress.toLowerCase == mailAddress.toLowerCase && t.removed == false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(mailAddress, includeRemoved).headOption
|
||||||
|
}
|
||||||
|
|
||||||
def getAllUsers(includeRemoved: Boolean = true)(implicit s: Session): List[Account] =
|
def getAllUsers(includeRemoved: Boolean = true): List[Account] = {
|
||||||
if(includeRemoved){
|
db.run(
|
||||||
Accounts sortBy(_.userName) list
|
if(includeRemoved){
|
||||||
} else {
|
quote { query[Account].sortBy(_.userName) }
|
||||||
Accounts filter (_.removed === false.bind) sortBy(_.userName) list
|
} else {
|
||||||
}
|
quote { query[Account].filter(_.removed == false).sortBy(_.userName) }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
def createAccount(userName: String, password: String, fullName: String, mailAddress: String, isAdmin: Boolean, url: Option[String])
|
def createAccount(userName: String, password: String, fullName: String, mailAddress: String, isAdmin: Boolean, url: Option[String]): Unit = {
|
||||||
(implicit s: Session): Unit =
|
db.run(quote { query[Account].insert })(Account(
|
||||||
Accounts insert Account(
|
|
||||||
userName = userName,
|
userName = userName,
|
||||||
password = password,
|
password = password,
|
||||||
fullName = fullName,
|
fullName = fullName,
|
||||||
mailAddress = mailAddress,
|
mailAddress = mailAddress,
|
||||||
isAdmin = isAdmin,
|
administrator = isAdmin,
|
||||||
url = url,
|
url = url,
|
||||||
registeredDate = currentDate,
|
registeredDate = currentDate,
|
||||||
updatedDate = currentDate,
|
updatedDate = currentDate,
|
||||||
lastLoginDate = None,
|
lastLoginDate = None,
|
||||||
image = None,
|
image = None,
|
||||||
isGroupAccount = false,
|
groupAccount = false,
|
||||||
isRemoved = false)
|
removed = false
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
def updateAccount(account: Account)(implicit s: Session): Unit =
|
def updateAccount(account: Account): Unit = {
|
||||||
Accounts
|
db.run(quote { (userName: String, password: String, fullName: String, mailAddress: String, administrator: Boolean,
|
||||||
.filter { a => a.userName === account.userName.bind }
|
url: Option[String], registeredDate: Date, updatedDate: Date, lastLoginDate: Option[Date], removed: Boolean) =>
|
||||||
.map { a => (a.password, a.fullName, a.mailAddress, a.isAdmin, a.url.?, a.registeredDate, a.updatedDate, a.lastLoginDate.?, a.removed) }
|
query[Account].filter(_.userName == userName).update(
|
||||||
.update (
|
_.password -> password,
|
||||||
account.password,
|
_.fullName -> fullName,
|
||||||
account.fullName,
|
_.mailAddress -> mailAddress,
|
||||||
account.mailAddress,
|
_.administrator -> administrator,
|
||||||
account.isAdmin,
|
_.url -> url,
|
||||||
account.url,
|
_.registeredDate -> registeredDate,
|
||||||
account.registeredDate,
|
_.updatedDate -> updatedDate,
|
||||||
currentDate,
|
_.lastLoginDate -> lastLoginDate,
|
||||||
account.lastLoginDate,
|
_.removed -> removed
|
||||||
account.isRemoved)
|
)
|
||||||
|
})((
|
||||||
|
account.userName,
|
||||||
|
account.password,
|
||||||
|
account.fullName,
|
||||||
|
account.mailAddress,
|
||||||
|
account.administrator,
|
||||||
|
account.url,
|
||||||
|
account.registeredDate,
|
||||||
|
currentDate,
|
||||||
|
account.lastLoginDate,
|
||||||
|
account.removed
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
def updateAvatarImage(userName: String, image: Option[String])(implicit s: Session): Unit =
|
def updateAvatarImage(userName: String, image: Option[String]): Unit = {
|
||||||
Accounts.filter(_.userName === userName.bind).map(_.image.?).update(image)
|
db.run(quote { (userName: String, image: Option[String]) =>
|
||||||
|
query[Account].filter(_.userName == userName).update(_.image -> image)
|
||||||
|
})((userName, image))
|
||||||
|
}
|
||||||
|
|
||||||
def updateLastLoginDate(userName: String)(implicit s: Session): Unit =
|
def updateLastLoginDate(userName: String): Unit = {
|
||||||
Accounts.filter(_.userName === userName.bind).map(_.lastLoginDate).update(currentDate)
|
db.run(quote { (userName: String, lastLoginDate: Option[Date]) =>
|
||||||
|
query[Account].filter(_.userName == userName).update(_.lastLoginDate -> lastLoginDate)
|
||||||
|
})((userName, Some(currentDate)))
|
||||||
|
}
|
||||||
|
|
||||||
def createGroup(groupName: String, url: Option[String])(implicit s: Session): Unit =
|
def createGroup(groupName: String, url: Option[String]): Unit = {
|
||||||
Accounts insert Account(
|
db.run( quote { query[Account].insert })(List(Account(
|
||||||
userName = groupName,
|
userName = groupName,
|
||||||
password = "",
|
password = "",
|
||||||
fullName = groupName,
|
fullName = groupName,
|
||||||
mailAddress = groupName + "@devnull",
|
mailAddress = groupName + "@devnull",
|
||||||
isAdmin = false,
|
administrator = false,
|
||||||
url = url,
|
url = url,
|
||||||
registeredDate = currentDate,
|
registeredDate = currentDate,
|
||||||
updatedDate = currentDate,
|
updatedDate = currentDate,
|
||||||
lastLoginDate = None,
|
lastLoginDate = None,
|
||||||
image = None,
|
image = None,
|
||||||
isGroupAccount = true,
|
groupAccount = true,
|
||||||
isRemoved = false)
|
removed = false
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
def updateGroup(groupName: String, url: Option[String], removed: Boolean)(implicit s: Session): Unit =
|
def updateGroup(groupName: String, url: Option[String], removed: Boolean): Unit = {
|
||||||
Accounts.filter(_.userName === groupName.bind).map(t => t.url.? -> t.removed).update(url, removed)
|
db.run(quote { (groupName: String, url: Option[String], removed: Boolean) =>
|
||||||
|
query[Account].filter(_.userName == groupName).update(_.url -> url, _.removed -> removed)
|
||||||
|
})(List((groupName, url, removed)))
|
||||||
|
}
|
||||||
|
|
||||||
|
def updateGroupMembers(groupName: String, members: List[(String, Boolean)]): Unit = {
|
||||||
|
db.run(quote { (groupName: String) => query[GroupMember].filter(_.groupName == groupName).delete })(groupName)
|
||||||
|
|
||||||
def updateGroupMembers(groupName: String, members: List[(String, Boolean)])(implicit s: Session): Unit = {
|
|
||||||
GroupMembers.filter(_.groupName === groupName.bind).delete
|
|
||||||
members.foreach { case (userName, isManager) =>
|
members.foreach { case (userName, isManager) =>
|
||||||
GroupMembers insert GroupMember (groupName, userName, isManager)
|
db.run(quote { query[GroupMember].insert })(GroupMember(groupName, userName, isManager))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getGroupMembers(groupName: String)(implicit s: Session): List[GroupMember] =
|
def getGroupMembers(groupName: String): List[GroupMember] = {
|
||||||
GroupMembers
|
db.run(quote { (groupName: String) =>
|
||||||
.filter(_.groupName === groupName.bind)
|
query[GroupMember].filter(_.groupName == groupName).sortBy(_.userName)
|
||||||
.sortBy(_.userName)
|
})(groupName)
|
||||||
.list
|
|
||||||
|
|
||||||
def getGroupsByUserName(userName: String)(implicit s: Session): List[String] =
|
|
||||||
GroupMembers
|
|
||||||
.filter(_.userName === userName.bind)
|
|
||||||
.sortBy(_.groupName)
|
|
||||||
.map(_.groupName)
|
|
||||||
.list
|
|
||||||
|
|
||||||
def removeUserRelatedData(userName: String)(implicit s: Session): Unit = {
|
|
||||||
GroupMembers.filter(_.userName === userName.bind).delete
|
|
||||||
Collaborators.filter(_.collaboratorName === userName.bind).delete
|
|
||||||
Repositories.filter(_.userName === userName.bind).delete
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def getGroupNames(userName: String)(implicit s: Session): List[String] = {
|
def getGroupsByUserName(userName: String): List[String] = {
|
||||||
List(userName) ++
|
db.run(quote { (userName: String) =>
|
||||||
Collaborators.filter(_.collaboratorName === userName.bind).sortBy(_.userName).map(_.userName).list
|
query[GroupMember].filter(_.userName == userName).sortBy(_.groupName).map(_.groupName)
|
||||||
|
})(userName)
|
||||||
|
}
|
||||||
|
|
||||||
|
def removeUserRelatedData(userName: String): Unit = {
|
||||||
|
db.run(quote { (userName: String) => query[GroupMember].filter(_.userName == userName).delete })(userName)
|
||||||
|
db.run(quote { (userName: String) => query[Collaborator].filter(_.collaboratorName == userName).delete })(userName)
|
||||||
|
db.run(quote { (userName: String) => query[Repository].filter(_.userName == userName).delete })(userName)
|
||||||
|
}
|
||||||
|
|
||||||
|
def getGroupNames(userName: String): List[String] = {
|
||||||
|
List(userName) ++ db.run(quote { (userName: String) =>
|
||||||
|
query[Collaborator].filter(_.collaboratorName == userName).sortBy(_.userName).map(_.userName)
|
||||||
|
})(userName)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,194 +1,180 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import gitbucket.core.model.Activity
|
import gitbucket.core.model._
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import gitbucket.core.util.JGitUtil
|
import gitbucket.core.util.JGitUtil
|
||||||
import profile.simple._
|
import profile.simple._
|
||||||
|
|
||||||
|
import gitbucket.core.servlet.Database._
|
||||||
|
import io.getquill._
|
||||||
|
|
||||||
trait ActivityService {
|
trait ActivityService {
|
||||||
|
|
||||||
def deleteOldActivities(limit: Int)(implicit s: Session): Int = {
|
def deleteOldActivities(limit: Int): Int =
|
||||||
Activities.map(_.activityId).sortBy(_ desc).drop(limit).firstOption.map { id =>
|
db.run (quote { (limit: Int) =>
|
||||||
Activities.filter(_.activityId <= id.bind).delete
|
query[Activity].map(_.activityId).sortBy(x => x)(Ord.desc).drop(limit)
|
||||||
|
})(limit).headOption.map { activityId =>
|
||||||
|
db.run (
|
||||||
|
quote { (activityId: Int) => query[Activity].filter(_.activityId <= activityId).delete }
|
||||||
|
)(activityId)
|
||||||
} getOrElse 0
|
} getOrElse 0
|
||||||
}
|
|
||||||
|
|
||||||
def getActivitiesByUser(activityUserName: String, isPublic: Boolean)(implicit s: Session): List[Activity] =
|
def getActivitiesByUser(activityUserName: String, isPublic: Boolean): List[Activity] =
|
||||||
Activities
|
db.run(quote { (activityUserName: String, isPublic: Boolean) =>
|
||||||
.innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
|
query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName)
|
||||||
.filter { case (t1, t2) =>
|
.filter { case (a, r) =>
|
||||||
if(isPublic){
|
if(isPublic){
|
||||||
(t1.activityUserName === activityUserName.bind) && (t2.isPrivate === false.bind)
|
a.activityUserName == activityUserName
|
||||||
} else {
|
} else {
|
||||||
(t1.activityUserName === activityUserName.bind)
|
a.activityUserName == activityUserName && r.`private` == false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
.sortBy { case (a, r) => a.activityId }(Ord.desc)
|
||||||
.sortBy { case (t1, t2) => t1.activityId desc }
|
.map { case (a, r) => a }
|
||||||
.map { case (t1, t2) => t1 }
|
.take(30)
|
||||||
.take(30)
|
})(activityUserName, isPublic)
|
||||||
.list
|
|
||||||
|
|
||||||
def getRecentActivities()(implicit s: Session): List[Activity] =
|
def getRecentActivities(): List[Activity] =
|
||||||
Activities
|
db.run(quote {
|
||||||
.innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
|
query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName)
|
||||||
.filter { case (t1, t2) => t2.isPrivate === false.bind }
|
.filter { case (a, r) => r.`private` == false}
|
||||||
.sortBy { case (t1, t2) => t1.activityId desc }
|
.sortBy { case (a, r) => a.activityId }(Ord.desc)
|
||||||
.map { case (t1, t2) => t1 }
|
.map { case (a, r) => a }
|
||||||
.take(30)
|
.take(30)
|
||||||
.list
|
})
|
||||||
|
|
||||||
def getRecentActivitiesByOwners(owners : Set[String])(implicit s: Session): List[Activity] =
|
def getRecentActivitiesByOwners(owners : Set[String]): List[Activity] =
|
||||||
Activities
|
db.run(quote { (owners: Set[String]) =>
|
||||||
.innerJoin(Repositories).on((t1, t2) => t1.byRepository(t2.userName, t2.repositoryName))
|
query[Activity].join(query[Repository]).on((a, r) => a.userName == r.userName && a.repositoryName == r.repositoryName)
|
||||||
.filter { case (t1, t2) => (t2.isPrivate === false.bind) || (t2.userName inSetBind owners) }
|
.filter { case (a, r) => r.`private` == false || owners.contains(r.userName) }
|
||||||
.sortBy { case (t1, t2) => t1.activityId desc }
|
.sortBy { case (a, r) => a.activityId }(Ord.desc)
|
||||||
.map { case (t1, t2) => t1 }
|
.map { case (a, r) => a }
|
||||||
.take(30)
|
.take(30)
|
||||||
.list
|
})(owners)
|
||||||
|
|
||||||
def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String)
|
def recordCreateRepositoryActivity(userName: String, repositoryName: String, activityUserName: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"create_repository",
|
"create_repository",
|
||||||
s"[user:${activityUserName}] created [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] created [repo:${userName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCreateIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
|
def recordCreateIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"open_issue",
|
"open_issue",
|
||||||
s"[user:${activityUserName}] opened issue [issue:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] opened issue [issue:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(title),
|
Some(title))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCloseIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
|
def recordCloseIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"close_issue",
|
"close_issue",
|
||||||
s"[user:${activityUserName}] closed issue [issue:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] closed issue [issue:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(title),
|
Some(title))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordClosePullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
|
def recordClosePullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"close_issue",
|
"close_issue",
|
||||||
s"[user:${activityUserName}] closed pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] closed pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(title),
|
Some(title))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordReopenIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
|
def recordReopenIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"reopen_issue",
|
"reopen_issue",
|
||||||
s"[user:${activityUserName}] reopened issue [issue:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] reopened issue [issue:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(title),
|
Some(title))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCommentIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String)
|
def recordCommentIssueActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"comment_issue",
|
"comment_issue",
|
||||||
s"[user:${activityUserName}] commented on issue [issue:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] commented on issue [issue:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(cut(comment, 200)),
|
Some(cut(comment, 200)))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCommentPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String)
|
def recordCommentPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, comment: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"comment_issue",
|
"comment_issue",
|
||||||
s"[user:${activityUserName}] commented on pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] commented on pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(cut(comment, 200)),
|
Some(cut(comment, 200)))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCommentCommitActivity(userName: String, repositoryName: String, activityUserName: String, commitId: String, comment: String)
|
def recordCommentCommitActivity(userName: String, repositoryName: String, activityUserName: String, commitId: String, comment: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"comment_commit",
|
"comment_commit",
|
||||||
s"[user:${activityUserName}] commented on commit [commit:${userName}/${repositoryName}@${commitId}]",
|
s"[user:${activityUserName}] commented on commit [commit:${userName}/${repositoryName}@${commitId}]",
|
||||||
Some(cut(comment, 200)),
|
Some(cut(comment, 200)))
|
||||||
currentDate
|
|
||||||
)
|
|
||||||
|
|
||||||
def recordCreateWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String)
|
def recordCreateWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"create_wiki",
|
"create_wiki",
|
||||||
s"[user:${activityUserName}] created the [repo:${userName}/${repositoryName}] wiki",
|
s"[user:${activityUserName}] created the [repo:${userName}/${repositoryName}] wiki",
|
||||||
Some(pageName),
|
Some(pageName))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordEditWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String, commitId: String)
|
def recordEditWikiPageActivity(userName: String, repositoryName: String, activityUserName: String, pageName: String, commitId: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"edit_wiki",
|
"edit_wiki",
|
||||||
s"[user:${activityUserName}] edited the [repo:${userName}/${repositoryName}] wiki",
|
s"[user:${activityUserName}] edited the [repo:${userName}/${repositoryName}] wiki",
|
||||||
Some(pageName + ":" + commitId),
|
Some(pageName + ":" + commitId))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordPushActivity(userName: String, repositoryName: String, activityUserName: String,
|
def recordPushActivity(userName: String, repositoryName: String, activityUserName: String,
|
||||||
branchName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
|
branchName: String, commits: List[JGitUtil.CommitInfo]): Unit =
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
"push",
|
"push",
|
||||||
s"[user:${activityUserName}] pushed to [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] pushed to [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
|
||||||
Some(commits.map { commit => commit.id + ":" + commit.shortMessage }.mkString("\n")),
|
Some(commits.map { commit => commit.id + ":" + commit.shortMessage }.mkString("\n")))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCreateTagActivity(userName: String, repositoryName: String, activityUserName: String,
|
def recordCreateTagActivity(userName: String, repositoryName: String, activityUserName: String,
|
||||||
tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
|
tagName: String, commits: List[JGitUtil.CommitInfo]): Unit =
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
"create_tag",
|
"create_tag",
|
||||||
s"[user:${activityUserName}] created tag [tag:${userName}/${repositoryName}#${tagName}] at [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] created tag [tag:${userName}/${repositoryName}#${tagName}] at [repo:${userName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordDeleteTagActivity(userName: String, repositoryName: String, activityUserName: String,
|
def recordDeleteTagActivity(userName: String, repositoryName: String, activityUserName: String,
|
||||||
tagName: String, commits: List[JGitUtil.CommitInfo])(implicit s: Session): Unit =
|
tagName: String, commits: List[JGitUtil.CommitInfo]): Unit =
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
"delete_tag",
|
"delete_tag",
|
||||||
s"[user:${activityUserName}] deleted tag ${tagName} at [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] deleted tag ${tagName} at [repo:${userName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordCreateBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String)
|
def recordCreateBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"create_branch",
|
"create_branch",
|
||||||
s"[user:${activityUserName}] created branch [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] created branch [branch:${userName}/${repositoryName}#${branchName}] at [repo:${userName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordDeleteBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String)
|
def recordDeleteBranchActivity(userName: String, repositoryName: String, activityUserName: String, branchName: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"delete_branch",
|
"delete_branch",
|
||||||
s"[user:${activityUserName}] deleted branch ${branchName} at [repo:${userName}/${repositoryName}]",
|
s"[user:${activityUserName}] deleted branch ${branchName} at [repo:${userName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String)(implicit s: Session): Unit =
|
def recordForkActivity(userName: String, repositoryName: String, activityUserName: String, forkedUserName: String): Unit =
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
"fork",
|
"fork",
|
||||||
s"[user:${activityUserName}] forked [repo:${userName}/${repositoryName}] to [repo:${forkedUserName}/${repositoryName}]",
|
s"[user:${activityUserName}] forked [repo:${userName}/${repositoryName}] to [repo:${forkedUserName}/${repositoryName}]",
|
||||||
None,
|
None)
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String)
|
def recordPullRequestActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, title: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"open_pullreq",
|
"open_pullreq",
|
||||||
s"[user:${activityUserName}] opened pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] opened pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(title),
|
Some(title))
|
||||||
currentDate)
|
|
||||||
|
|
||||||
def recordMergeActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, message: String)
|
def recordMergeActivity(userName: String, repositoryName: String, activityUserName: String, issueId: Int, message: String): Unit =
|
||||||
(implicit s: Session): Unit =
|
insertActivity(userName, repositoryName, activityUserName,
|
||||||
Activities insert Activity(userName, repositoryName, activityUserName,
|
|
||||||
"merge_pullreq",
|
"merge_pullreq",
|
||||||
s"[user:${activityUserName}] merged pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
s"[user:${activityUserName}] merged pull request [pullreq:${userName}/${repositoryName}#${issueId}]",
|
||||||
Some(message),
|
Some(message))
|
||||||
currentDate)
|
|
||||||
|
private def insertActivity(userName: String, repositoryName: String, activityUserName: String, activityType: String,
|
||||||
|
message: String, additionalInfo: Option[String]): Unit = {
|
||||||
|
db.run(quote { query[Activity].insert })(Activity(
|
||||||
|
userName = userName,
|
||||||
|
repositoryName = repositoryName,
|
||||||
|
activityUserName = activityUserName,
|
||||||
|
activityType = activityType,
|
||||||
|
message = message,
|
||||||
|
additionalInfo = additionalInfo,
|
||||||
|
activityDate = currentDate
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
private def cut(value: String, length: Int): String =
|
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
|
||||||
|
|||||||
@@ -1,35 +1,34 @@
|
|||||||
package gitbucket.core.service
|
package gitbucket.core.service
|
||||||
|
|
||||||
import gitbucket.core.model.CommitComment
|
import gitbucket.core.model.CommitComment
|
||||||
import gitbucket.core.util.{StringUtil, Implicits}
|
|
||||||
|
|
||||||
import scala.slick.jdbc.{StaticQuery => Q}
|
|
||||||
import Q.interpolation
|
|
||||||
import gitbucket.core.model.Profile._
|
import gitbucket.core.model.Profile._
|
||||||
import profile.simple._
|
import profile.simple._
|
||||||
import Implicits._
|
|
||||||
import StringUtil._
|
import gitbucket.core.servlet.Database._
|
||||||
|
import io.getquill._
|
||||||
|
|
||||||
|
|
||||||
trait CommitsService {
|
trait CommitsService {
|
||||||
|
|
||||||
def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean)(implicit s: Session) =
|
def getCommitComments(owner: String, repository: String, commitId: String, includePullRequest: Boolean) =
|
||||||
CommitComments filter {
|
db.run(quote { (owner: String, repository: String, commitId: String, includePullRequest: Boolean) =>
|
||||||
t => t.byCommit(owner, repository, commitId) && (t.issueId.isEmpty || includePullRequest)
|
query[CommitComment].filter { t =>
|
||||||
} list
|
t.userName == owner && t.repositoryName == repository && t.commitId == commitId && (t.issueId.isEmpty || includePullRequest)
|
||||||
|
}
|
||||||
|
})(owner, repository, commitId, includePullRequest)
|
||||||
|
|
||||||
def getCommitComment(owner: String, repository: String, commentId: String)(implicit s: Session) =
|
def getCommitComment(owner: String, repository: String, commentId: String) =
|
||||||
if (commentId forall (_.isDigit))
|
if (commentId forall (_.isDigit))
|
||||||
CommitComments filter { t =>
|
db.run(quote { (owner: String, repository: String, commentId: Int) =>
|
||||||
t.byPrimaryKey(commentId.toInt) && t.byRepository(owner, repository)
|
query[CommitComment].filter(t => t.userName == owner && t.repositoryName == repository && t.commentId == commentId)
|
||||||
} firstOption
|
})(owner, repository, commentId.toInt).headOption
|
||||||
else
|
else
|
||||||
None
|
None
|
||||||
|
|
||||||
def createCommitComment(owner: String, repository: String, commitId: String, loginUser: String,
|
def createCommitComment(owner: String, repository: String, commitId: String, loginUser: String,
|
||||||
content: String, fileName: Option[String], oldLine: Option[Int], newLine: Option[Int],
|
content: String, fileName: Option[String], oldLine: Option[Int], newLine: Option[Int],
|
||||||
issueId: Option[Int])(implicit s: Session): Int =
|
issueId: Option[Int])(implicit s: Session): Int =
|
||||||
CommitComments.autoInc insert CommitComment(
|
CommitComments.autoInc insert CommitComment( // TODO Remain Slick code
|
||||||
userName = owner,
|
userName = owner,
|
||||||
repositoryName = repository,
|
repositoryName = repository,
|
||||||
commitId = commitId,
|
commitId = commitId,
|
||||||
@@ -42,13 +41,12 @@ trait CommitsService {
|
|||||||
updatedDate = currentDate,
|
updatedDate = currentDate,
|
||||||
issueId = issueId)
|
issueId = issueId)
|
||||||
|
|
||||||
def updateCommitComment(commentId: Int, content: String)(implicit s: Session) =
|
def updateCommitComment(commentId: Int, content: String) =
|
||||||
CommitComments
|
db.run(quote { (commentId: Int, content: String, updatedDate: java.util.Date) =>
|
||||||
.filter (_.byPrimaryKey(commentId))
|
query[CommitComment].filter(_.commentId == commentId).update(_.content -> content, _.updatedDate -> updatedDate)
|
||||||
.map { t =>
|
})(commentId, content, currentDate)
|
||||||
t.content -> t.updatedDate
|
|
||||||
}.update (content, currentDate)
|
def deleteCommitComment(commentId: Int) =
|
||||||
|
db.run(quote { (commentId: Int) => query[CommitComment].filter(_.commentId == commentId).delete })(commentId)
|
||||||
|
|
||||||
def deleteCommitComment(commentId: Int)(implicit s: Session) =
|
|
||||||
CommitComments filter (_.byPrimaryKey(commentId)) delete
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ object ProtectedBranchService {
|
|||||||
includeAdministrators: Boolean) extends AccountService with CommitStatusService {
|
includeAdministrators: Boolean) extends AccountService with CommitStatusService {
|
||||||
|
|
||||||
def isAdministrator(pusher: String)(implicit session: Session): Boolean =
|
def isAdministrator(pusher: String)(implicit session: Session): Boolean =
|
||||||
pusher == owner || getGroupMembers(owner).filter(gm => gm.userName == pusher && gm.isManager).nonEmpty
|
pusher == owner || getGroupMembers(owner).filter(gm => gm.userName == pusher && gm.manager).nonEmpty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can't be force pushed
|
* Can't be force pushed
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ trait RepositoryCreationService {
|
|||||||
insertRepository(name, owner, description, isPrivate)
|
insertRepository(name, owner, description, isPrivate)
|
||||||
|
|
||||||
// Add collaborators for group repository
|
// Add collaborators for group repository
|
||||||
if(ownerAccount.isGroupAccount){
|
if(ownerAccount.groupAccount){
|
||||||
getGroupMembers(owner).foreach { member =>
|
getGroupMembers(owner).foreach { member =>
|
||||||
addCollaborator(owner, name, member.userName)
|
addCollaborator(owner, name, member.userName)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ trait RepositoryService { self: AccountService =>
|
|||||||
Repository(
|
Repository(
|
||||||
userName = userName,
|
userName = userName,
|
||||||
repositoryName = repositoryName,
|
repositoryName = repositoryName,
|
||||||
isPrivate = isPrivate,
|
`private` = isPrivate,
|
||||||
description = description,
|
description = description,
|
||||||
defaultBranch = "master",
|
defaultBranch = "master",
|
||||||
registeredDate = currentDate,
|
registeredDate = currentDate,
|
||||||
@@ -115,7 +115,7 @@ trait RepositoryService { self: AccountService =>
|
|||||||
repositoryName = newRepositoryName
|
repositoryName = newRepositoryName
|
||||||
)) :_*)
|
)) :_*)
|
||||||
|
|
||||||
if(account.isGroupAccount){
|
if(account.groupAccount){
|
||||||
Collaborators.insertAll(getGroupMembers(newUserName).map(m => Collaborator(newUserName, newRepositoryName, m.userName)) :_*)
|
Collaborators.insertAll(getGroupMembers(newUserName).map(m => Collaborator(newUserName, newRepositoryName, m.userName)) :_*)
|
||||||
} else {
|
} else {
|
||||||
Collaborators.insertAll(collaborators.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
|
Collaborators.insertAll(collaborators.map(_.copy(userName = newUserName, repositoryName = newRepositoryName)) :_*)
|
||||||
@@ -270,9 +270,9 @@ trait RepositoryService { self: AccountService =>
|
|||||||
(implicit s: Session): List[RepositoryInfo] = {
|
(implicit s: Session): List[RepositoryInfo] = {
|
||||||
(loginAccount match {
|
(loginAccount match {
|
||||||
// for Administrators
|
// for Administrators
|
||||||
case Some(x) if(x.isAdmin) => Repositories
|
case Some(x) if(x.administrator) => Repositories
|
||||||
// for Normal Users
|
// for Normal Users
|
||||||
case Some(x) if(!x.isAdmin) =>
|
case Some(x) if(!x.administrator) =>
|
||||||
Repositories filter { t => (t.isPrivate === false.bind) || (t.userName === x.userName) ||
|
Repositories filter { t => (t.isPrivate === false.bind) || (t.userName === x.userName) ||
|
||||||
(Collaborators.filter { t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName === x.userName.bind)} exists)
|
(Collaborators.filter { t2 => t2.byRepository(t.userName, t.repositoryName) && (t2.collaboratorName === x.userName.bind)} exists)
|
||||||
}
|
}
|
||||||
@@ -297,8 +297,8 @@ trait RepositoryService { self: AccountService =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def getRepositoryManagers(userName: String)(implicit s: Session): Seq[String] =
|
private def getRepositoryManagers(userName: String)(implicit s: Session): Seq[String] =
|
||||||
if(getAccountByUserName(userName).exists(_.isGroupAccount)){
|
if(getAccountByUserName(userName).exists(_.groupAccount)){
|
||||||
getGroupMembers(userName).collect { case x if(x.isManager) => x.userName }
|
getGroupMembers(userName).collect { case x if(x.manager) => x.userName }
|
||||||
} else {
|
} else {
|
||||||
Seq(userName)
|
Seq(userName)
|
||||||
}
|
}
|
||||||
@@ -365,7 +365,7 @@ trait RepositoryService { self: AccountService =>
|
|||||||
|
|
||||||
def hasWritePermission(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
def hasWritePermission(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
||||||
loginAccount match {
|
loginAccount match {
|
||||||
case Some(a) if(a.isAdmin) => true
|
case Some(a) if(a.administrator) => true
|
||||||
case Some(a) if(a.userName == owner) => true
|
case Some(a) if(a.userName == owner) => true
|
||||||
case Some(a) if(getCollaborators(owner, repository).contains(a.userName)) => true
|
case Some(a) if(getCollaborators(owner, repository).contains(a.userName)) => true
|
||||||
case _ => false
|
case _ => false
|
||||||
|
|||||||
@@ -76,14 +76,14 @@ class BasicAuthenticationFilter extends Filter with RepositoryService with Accou
|
|||||||
case Array(_, repositoryOwner, repositoryName, _*) =>
|
case Array(_, repositoryOwner, repositoryName, _*) =>
|
||||||
getRepository(repositoryOwner, repositoryName.replaceFirst("\\.wiki\\.git$|\\.git$", "")) match {
|
getRepository(repositoryOwner, repositoryName.replaceFirst("\\.wiki\\.git$|\\.git$", "")) match {
|
||||||
case Some(repository) => {
|
case Some(repository) => {
|
||||||
if(!isUpdating && !repository.repository.isPrivate && settings.allowAnonymousAccess){
|
if(!isUpdating && !repository.repository.`private` && settings.allowAnonymousAccess){
|
||||||
chain.doFilter(request, response)
|
chain.doFilter(request, response)
|
||||||
} else {
|
} else {
|
||||||
val passed = for {
|
val passed = for {
|
||||||
auth <- Option(request.getHeader("Authorization"))
|
auth <- Option(request.getHeader("Authorization"))
|
||||||
Array(username, password) = decodeAuthHeader(auth).split(":", 2)
|
Array(username, password) = decodeAuthHeader(auth).split(":", 2)
|
||||||
account <- authenticate(settings, username, password)
|
account <- authenticate(settings, username, password)
|
||||||
} yield if(isUpdating || repository.repository.isPrivate){
|
} yield if(isUpdating || repository.repository.`private`){
|
||||||
if(hasWritePermission(repository.owner, repository.name, Some(account))){
|
if(hasWritePermission(repository.owner, repository.name, Some(account))){
|
||||||
request.setAttribute(Keys.Request.UserName, account.userName)
|
request.setAttribute(Keys.Request.UserName, account.userName)
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ import javax.servlet._
|
|||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.HttpServletRequest
|
||||||
import com.mchange.v2.c3p0.ComboPooledDataSource
|
import com.mchange.v2.c3p0.ComboPooledDataSource
|
||||||
import gitbucket.core.util.DatabaseConfig
|
import gitbucket.core.util.DatabaseConfig
|
||||||
|
import io.getquill._
|
||||||
|
import io.getquill.naming.SnakeCase
|
||||||
|
import io.getquill.sources.sql.idiom.H2Dialect
|
||||||
import org.scalatra.ScalatraBase
|
import org.scalatra.ScalatraBase
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import slick.jdbc.JdbcBackend.{Database => SlickDatabase, Session}
|
import slick.jdbc.JdbcBackend.{Database => SlickDatabase, Session}
|
||||||
import gitbucket.core.util.Keys
|
import gitbucket.core.util.Keys
|
||||||
|
import Database._
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controls the transaction with the open session in view pattern.
|
* Controls the transaction with the open session in view pattern.
|
||||||
@@ -25,17 +29,20 @@ class TransactionFilter extends Filter {
|
|||||||
// assets don't need transaction
|
// assets don't need transaction
|
||||||
chain.doFilter(req, res)
|
chain.doFilter(req, res)
|
||||||
} else {
|
} else {
|
||||||
Database() withTransaction { session =>
|
db.transaction {
|
||||||
// Register Scalatra error callback to rollback transaction
|
// TODO Delete after moving to quill
|
||||||
ScalatraBase.onFailure { _ =>
|
Database() withTransaction { session =>
|
||||||
logger.debug("Rolled back transaction")
|
// Register Scalatra error callback to rollback transaction
|
||||||
session.rollback()
|
ScalatraBase.onFailure { _ =>
|
||||||
}(req.asInstanceOf[HttpServletRequest])
|
logger.debug("Rolled back transaction")
|
||||||
|
session.rollback()
|
||||||
|
}(req.asInstanceOf[HttpServletRequest])
|
||||||
|
|
||||||
logger.debug("begin transaction")
|
logger.debug("begin transaction")
|
||||||
req.setAttribute(Keys.Request.DBSession, session)
|
req.setAttribute(Keys.Request.DBSession, session)
|
||||||
chain.doFilter(req, res)
|
chain.doFilter(req, res)
|
||||||
logger.debug("end transaction")
|
logger.debug("end transaction")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,6 +53,9 @@ object Database {
|
|||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(Database.getClass)
|
private val logger = LoggerFactory.getLogger(Database.getClass)
|
||||||
|
|
||||||
|
lazy val db = source(new JdbcSourceConfig[H2Dialect, SnakeCase]("db"))
|
||||||
|
|
||||||
|
// TODO Delete after moving to quill
|
||||||
private val dataSource: ComboPooledDataSource = {
|
private val dataSource: ComboPooledDataSource = {
|
||||||
val ds = new ComboPooledDataSource
|
val ds = new ComboPooledDataSource
|
||||||
ds.setDriverClass(DatabaseConfig.driver)
|
ds.setDriverClass(DatabaseConfig.driver)
|
||||||
@@ -56,15 +66,19 @@ object Database {
|
|||||||
ds
|
ds
|
||||||
}
|
}
|
||||||
|
|
||||||
private val db: SlickDatabase = {
|
// TODO Delete after moving to quill
|
||||||
|
private val slickDatabase: SlickDatabase = {
|
||||||
SlickDatabase.forDataSource(dataSource)
|
SlickDatabase.forDataSource(dataSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(): SlickDatabase = db
|
// TODO Delete after moving to quill
|
||||||
|
def apply(): SlickDatabase = slickDatabase
|
||||||
|
|
||||||
|
// TODO Delete after moving to quill
|
||||||
def getSession(req: ServletRequest): Session =
|
def getSession(req: ServletRequest): Session =
|
||||||
req.getAttribute(Keys.Request.DBSession).asInstanceOf[Session]
|
req.getAttribute(Keys.Request.DBSession).asInstanceOf[Session]
|
||||||
|
|
||||||
|
// TODO Delete after moving to quill
|
||||||
def closeDataSource(): Unit = dataSource.close
|
def closeDataSource(): Unit = dataSource.close
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class DefaultGitUploadPack(owner: String, repoName: String) extends DefaultGitCo
|
|||||||
|
|
||||||
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
override protected def runTask(user: String)(implicit session: Session): Unit = {
|
||||||
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).foreach { repositoryInfo =>
|
getRepository(owner, repoName.replaceFirst("\\.wiki\\Z", "")).foreach { repositoryInfo =>
|
||||||
if(!repositoryInfo.repository.isPrivate || isWritableUser(user, repositoryInfo)){
|
if(!repositoryInfo.repository.`private` || isWritableUser(user, repositoryInfo)){
|
||||||
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
using(Git.open(getRepositoryDir(owner, repoName))) { git =>
|
||||||
val repository = git.getRepository
|
val repository = git.getRepository
|
||||||
val upload = new UploadPack(repository)
|
val upload = new UploadPack(repository)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ trait OneselfAuthenticator { self: ControllerBase =>
|
|||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action
|
case Some(x) if(x.administrator) => action
|
||||||
case Some(x) if(paths(0) == x.userName) => action
|
case Some(x) if(paths(0) == x.userName) => action
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,10 @@ trait OwnerAuthenticator { self: ControllerBase with RepositoryService with Acco
|
|||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1)).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.administrator) => action(repository)
|
||||||
case Some(x) if(repository.owner == x.userName) => action(repository)
|
case Some(x) if(repository.owner == x.userName) => action(repository)
|
||||||
case Some(x) if(getGroupMembers(repository.owner).exists { member =>
|
case Some(x) if(getGroupMembers(repository.owner).exists { member =>
|
||||||
member.userName == x.userName && member.isManager == true
|
member.userName == x.userName && member.manager == true
|
||||||
}) => action(repository)
|
}) => action(repository)
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
}
|
}
|
||||||
@@ -78,7 +78,7 @@ trait AdminAuthenticator { self: ControllerBase =>
|
|||||||
private def authenticate(action: => Any) = {
|
private def authenticate(action: => Any) = {
|
||||||
{
|
{
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action
|
case Some(x) if(x.administrator) => action
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ trait CollaboratorsAuthenticator { self: ControllerBase with RepositoryService =
|
|||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1)).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.administrator) => action(repository)
|
||||||
case Some(x) if(paths(0) == x.userName) => action(repository)
|
case Some(x) if(paths(0) == x.userName) => action(repository)
|
||||||
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
@@ -119,11 +119,11 @@ trait ReferrerAuthenticator { self: ControllerBase with RepositoryService =>
|
|||||||
{
|
{
|
||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1)).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
if(!repository.repository.isPrivate){
|
if(!repository.repository.`private`){
|
||||||
action(repository)
|
action(repository)
|
||||||
} else {
|
} else {
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.administrator) => action(repository)
|
||||||
case Some(x) if(paths(0) == x.userName) => action(repository)
|
case Some(x) if(paths(0) == x.userName) => action(repository)
|
||||||
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
@@ -147,8 +147,8 @@ trait ReadableUsersAuthenticator { self: ControllerBase with RepositoryService =
|
|||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
getRepository(paths(0), paths(1)).map { repository =>
|
getRepository(paths(0), paths(1)).map { repository =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(x.isAdmin) => action(repository)
|
case Some(x) if(x.administrator) => action(repository)
|
||||||
case Some(x) if(!repository.repository.isPrivate) => action(repository)
|
case Some(x) if(!repository.repository.`private`) => action(repository)
|
||||||
case Some(x) if(paths(0) == x.userName) => action(repository)
|
case Some(x) if(paths(0) == x.userName) => action(repository)
|
||||||
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
case Some(x) if(getCollaborators(paths(0), paths(1)).contains(x.userName)) => action(repository)
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
@@ -171,7 +171,7 @@ trait GroupManagerAuthenticator { self: ControllerBase with AccountService =>
|
|||||||
defining(request.paths){ paths =>
|
defining(request.paths){ paths =>
|
||||||
context.loginAccount match {
|
context.loginAccount match {
|
||||||
case Some(x) if(getGroupMembers(paths(0)).exists { member =>
|
case Some(x) if(getGroupMembers(paths(0)).exists { member =>
|
||||||
member.userName == x.userName && member.isManager
|
member.userName == x.userName && member.manager
|
||||||
}) => action
|
}) => action
|
||||||
case _ => Unauthorized()
|
case _ => Unauthorized()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ trait Notifier extends RepositoryService with AccountService with IssuesService
|
|||||||
)
|
)
|
||||||
.distinct
|
.distinct
|
||||||
.withFilter ( _ != context.loginAccount.get.userName ) // the operation in person is excluded
|
.withFilter ( _ != context.loginAccount.get.userName ) // the operation in person is excluded
|
||||||
.foreach ( getAccountByUserName(_) filterNot (_.isGroupAccount) filterNot (LDAPUtil.isDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) )
|
.foreach ( getAccountByUserName(_) filterNot (_.groupAccount) filterNot (LDAPUtil.isDummyMailAddress(_)) foreach (x => notify(x.mailAddress)) )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
@helper.html.account("memberName", 200)
|
@helper.html.account("memberName", 200)
|
||||||
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
||||||
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/>
|
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.manager).mkString(",")"/>
|
||||||
<div>
|
<div>
|
||||||
<span class="error" id="error-members"></span>
|
<span class="error" id="error-members"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,7 +103,7 @@ $(function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
@members.map { member =>
|
@members.map { member =>
|
||||||
addMemberHTML('@member.userName', @member.isManager);
|
addMemberHTML('@member.userName', @member.manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMemberHTML(userName, isManager){
|
function addMemberHTML(userName, isManager){
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<ul class="nav nav-tabs" style="margin-bottom: 5px;">
|
<ul class="nav nav-tabs" style="margin-bottom: 5px;">
|
||||||
<li@if(active == "repositories"){ class="active"}><a href="@url(account.userName)?tab=repositories">Repositories</a></li>
|
<li@if(active == "repositories"){ class="active"}><a href="@url(account.userName)?tab=repositories">Repositories</a></li>
|
||||||
@if(account.isGroupAccount){
|
@if(account.groupAccount){
|
||||||
<li@if(active == "members"){ class="active"}><a href="@url(account.userName)?tab=members">Members</a></li>
|
<li@if(active == "members"){ class="active"}><a href="@url(account.userName)?tab=members">Members</a></li>
|
||||||
} else {
|
} else {
|
||||||
<li@if(active == "activity"){ class="active"}><a href="@url(account.userName)?tab=activity">Public Activity</a></li>
|
<li@if(active == "activity"){ class="active"}><a href="@url(account.userName)?tab=activity">Public Activity</a></li>
|
||||||
@@ -43,9 +43,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@if(loginAccount.isDefined && account.isGroupAccount && isGroupManager){
|
@if(loginAccount.isDefined && account.groupAccount && isGroupManager){
|
||||||
<li class="pull-right">
|
<li class="pull-right">
|
||||||
<div class="button-group">
|
<div class="button-groRepiosup">
|
||||||
<a href="@url(account.userName)/_editgroup" class="btn btn-default">Edit Group</a>
|
<a href="@url(account.userName)/_editgroup" class="btn btn-default">Edit Group</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<div class="repository-content">
|
<div class="repository-content">
|
||||||
<div class="block-header">
|
<div class="block-header">
|
||||||
<a href="@url(repository)">@repository.name</a>
|
<a href="@url(repository)">@repository.name</a>
|
||||||
@if(repository.repository.isPrivate){
|
@if(repository.repository.`private`){
|
||||||
<i class="octicon octicon-lock"></i>
|
<i class="octicon octicon-lock"></i>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<input type="text" name="userName" id="userName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/>
|
<input type="text" name="userName" id="userName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/>
|
||||||
@if(account.isDefined){
|
@if(account.isDefined){
|
||||||
<label for="removed">
|
<label for="removed">
|
||||||
<input type="checkbox" name="removed" id="removed" value="true" @if(account.get.isRemoved){checked}/>
|
<input type="checkbox" name="removed" id="removed" value="true" @if(account.get.removed){checked}/>
|
||||||
Disable
|
Disable
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div>
|
||||||
@@ -53,10 +53,10 @@
|
|||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
<label class="strong">User Type:</label>
|
<label class="strong">User Type:</label>
|
||||||
<label class="radio" for="userType_Normal">
|
<label class="radio" for="userType_Normal">
|
||||||
<input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.isAdmin){ checked}/> Normal
|
<input type="radio" name="isAdmin" id="userType_Normal" value="false"@if(account.isEmpty || !account.get.administrator){ checked}/> Normal
|
||||||
</label>
|
</label>
|
||||||
<label class="radio" for="userType_Admin">
|
<label class="radio" for="userType_Admin">
|
||||||
<input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.isAdmin){ checked}/> Administrator
|
<input type="radio" name="isAdmin" id="userType_Admin" value="true"@if(account.isDefined && account.get.administrator){ checked}/> Administrator
|
||||||
</label>
|
</label>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset class="form-group">
|
<fieldset class="form-group">
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<input type="text" name="groupName" id="groupName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/>
|
<input type="text" name="groupName" id="groupName" class="form-control" value="@account.map(_.userName)"@if(account.isDefined){ readonly}/>
|
||||||
@if(account.isDefined){
|
@if(account.isDefined){
|
||||||
<label for="removed">
|
<label for="removed">
|
||||||
<input type="checkbox" name="removed" id="removed" value="true" @if(account.get.isRemoved){checked}/>
|
<input type="checkbox" name="removed" id="removed" value="true" @if(account.get.removed){checked}/>
|
||||||
Disable
|
Disable
|
||||||
</label>
|
</label>
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
@helper.html.account("memberName", 200)
|
@helper.html.account("memberName", 200)
|
||||||
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
<input type="button" class="btn btn-default" value="Add" id="addMember"/>
|
||||||
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.isManager).mkString(",")"/>
|
<input type="hidden" id="members" name="members" value="@members.map(member => member.userName + ":" + member.manager).mkString(",")"/>
|
||||||
<div>
|
<div>
|
||||||
<span class="error" id="error-members"></span>
|
<span class="error" id="error-members"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,7 +98,7 @@ $(function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
@members.map { member =>
|
@members.map { member =>
|
||||||
addMemberHTML('@member.userName', @member.isManager);
|
addMemberHTML('@member.userName', @member.manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addMemberHTML(userName, isManager){
|
function addMemberHTML(userName, isManager){
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
<table class="table table-bordered table-hover">
|
<table class="table table-bordered table-hover">
|
||||||
@users.map { account =>
|
@users.map { account =>
|
||||||
<tr>
|
<tr>
|
||||||
<td @if(account.isRemoved){style="background-color: #dddddd;"}>
|
<td @if(account.removed){style="background-color: #dddddd;"}>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
@if(account.isGroupAccount){
|
@if(account.groupAccount){
|
||||||
<a href="@path/admin/users/@account.userName/_editgroup">Edit</a>
|
<a href="@path/admin/users/@account.userName/_editgroup">Edit</a>
|
||||||
} else {
|
} else {
|
||||||
<a href="@path/admin/users/@account.userName/_edituser">Edit</a>
|
<a href="@path/admin/users/@account.userName/_edituser">Edit</a>
|
||||||
@@ -25,16 +25,16 @@
|
|||||||
<div class="strong">
|
<div class="strong">
|
||||||
@avatar(account.userName, 20)
|
@avatar(account.userName, 20)
|
||||||
<a href="@url(account.userName)">@account.userName</a>
|
<a href="@url(account.userName)">@account.userName</a>
|
||||||
@if(account.isGroupAccount){
|
@if(account.groupAccount){
|
||||||
(Group)
|
(Group)
|
||||||
} else {
|
} else {
|
||||||
@if(account.isAdmin){
|
@if(account.administrator){
|
||||||
(Administrator)
|
(Administrator)
|
||||||
} else {
|
} else {
|
||||||
(Normal)
|
(Normal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@if(account.isGroupAccount){
|
@if(account.groupAccount){
|
||||||
@members(account.userName).map { userName =>
|
@members(account.userName).map { userName =>
|
||||||
@avatar(userName, 20, tooltip = true)
|
@avatar(userName, 20, tooltip = true)
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<hr>
|
<hr>
|
||||||
@if(!account.isGroupAccount){
|
@if(!account.groupAccount){
|
||||||
<i class="octicon octicon-mail"></i> @account.mailAddress
|
<i class="octicon octicon-mail"></i> @account.mailAddress
|
||||||
}
|
}
|
||||||
@account.url.map { url =>
|
@account.url.map { url =>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<span class="muted">Registered:</span> @datetime(account.registeredDate)
|
<span class="muted">Registered:</span> @datetime(account.registeredDate)
|
||||||
<span class="muted">Updated:</span> @datetime(account.updatedDate)
|
<span class="muted">Updated:</span> @datetime(account.updatedDate)
|
||||||
@if(!account.isGroupAccount){
|
@if(!account.groupAccount){
|
||||||
<span class="muted">Last Login:</span> @account.lastLoginDate.map(datetime)
|
<span class="muted">Last Login:</span> @account.lastLoginDate.map(datetime)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
@import gitbucket.core.service.RepositoryService
|
@import gitbucket.core.service.RepositoryService
|
||||||
@import context._
|
@import context._
|
||||||
@import gitbucket.core.view.helpers._
|
@import gitbucket.core.view.helpers._
|
||||||
@if(repository.repository.isPrivate){
|
@if(repository.repository.`private`){
|
||||||
<i class="@{if(large){"mega-"}}octicon octicon-lock"></i>
|
<i class="@{if(large){"mega-"}}octicon octicon-lock"></i>
|
||||||
} else {
|
} else {
|
||||||
@if(repository.repository.originUserName.isDefined){
|
@if(repository.repository.originUserName.isDefined){
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<script src="@assets/vendors/facebox/facebox.js"></script>
|
<script src="@assets/vendors/facebox/facebox.js"></script>
|
||||||
<script src="@assets/vendors/jquery-hotkeys/jquery.hotkeys.js"></script>
|
<script src="@assets/vendors/jquery-hotkeys/jquery.hotkeys.js"></script>
|
||||||
@repository.map { repository =>
|
@repository.map { repository =>
|
||||||
@if(!repository.repository.isPrivate){
|
@if(!repository.repository.`private`){
|
||||||
<meta name="go-import" content="@context.baseUrl.replaceFirst("^https?://", "")/@repository.owner/@repository.name git @repository.httpUrl" />
|
<meta name="go-import" content="@context.baseUrl.replaceFirst("^https?://", "")/@repository.owner/@repository.name git @repository.httpUrl" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
<ul class="dropdown-menu pull-right">
|
<ul class="dropdown-menu pull-right">
|
||||||
<li><a href="@url(loginAccount.get.userName)">Your profile</a></li>
|
<li><a href="@url(loginAccount.get.userName)">Your profile</a></li>
|
||||||
<li><a href="@url(loginAccount.get.userName)/_edit">Account settings</a></li>
|
<li><a href="@url(loginAccount.get.userName)/_edit">Account settings</a></li>
|
||||||
@if(loginAccount.get.isAdmin){
|
@if(loginAccount.get.administrator){
|
||||||
<li><a href="@path/admin/users">System administration</a></li>
|
<li><a href="@path/admin/users">System administration</a></li>
|
||||||
}
|
}
|
||||||
<li><a href="@path/signout">Sign out</a></li>
|
<li><a href="@path/signout">Sign out</a></li>
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
@menuitem("/issues", "issues" , "issue-opened" , "Issues", repository.issueCount)
|
@menuitem("/issues", "issues" , "issue-opened" , "Issues", repository.issueCount)
|
||||||
@menuitem("/pulls" , "pulls" , "git-pull-request" , "Pull Requests", repository.pullCount)
|
@menuitem("/pulls" , "pulls" , "git-pull-request" , "Pull Requests", repository.pullCount)
|
||||||
@menuitem("/wiki" , "wiki" , "book" , "Wiki")
|
@menuitem("/wiki" , "wiki" , "book" , "Wiki")
|
||||||
@if(loginAccount.isDefined && (loginAccount.get.isAdmin || repository.managers.contains(loginAccount.get.userName))){
|
@if(loginAccount.isDefined && (loginAccount.get.administrator || repository.managers.contains(loginAccount.get.userName))){
|
||||||
@menuitem("/settings" , "settings" , "tools", "Settings")
|
@menuitem("/settings" , "settings" , "tools", "Settings")
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
<fieldset class="margin">
|
<fieldset class="margin">
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="isPrivate" value="false"
|
<input type="radio" name="isPrivate" value="false"
|
||||||
@if(!repository.repository.isPrivate ){ checked }
|
@if(!repository.repository.`private` ){ checked }
|
||||||
@if(repository.repository.parentUserName.isDefined){ disabled }
|
@if(repository.repository.parentUserName.isDefined){ disabled }
|
||||||
>
|
>
|
||||||
<span class="strong"><i class="octicon octicon-repo"></i> Public</span><br>
|
<span class="strong"><i class="octicon octicon-repo"></i> Public</span><br>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</label>
|
</label>
|
||||||
<label class="radio">
|
<label class="radio">
|
||||||
<input type="radio" name="isPrivate" value="true"
|
<input type="radio" name="isPrivate" value="true"
|
||||||
@if(repository.repository.isPrivate ){ checked }
|
@if(repository.repository.`private` ){ checked }
|
||||||
@if(repository.repository.parentUserName.isDefined){ disabled }
|
@if(repository.repository.parentUserName.isDefined){ disabled }
|
||||||
>
|
>
|
||||||
<span class="strong"><i class="octicon octicon-lock"></i> Private</span><br>
|
<span class="strong"><i class="octicon octicon-lock"></i> Private</span><br>
|
||||||
|
|||||||
@@ -84,14 +84,14 @@ class AvatarImageProviderSpec extends FunSpec with MockitoSugar {
|
|||||||
fullName = "user@localhost",
|
fullName = "user@localhost",
|
||||||
mailAddress = "",
|
mailAddress = "",
|
||||||
password = "",
|
password = "",
|
||||||
isAdmin = false,
|
administrator = false,
|
||||||
url = None,
|
url = None,
|
||||||
registeredDate = new Date(),
|
registeredDate = new Date(),
|
||||||
updatedDate = new Date(),
|
updatedDate = new Date(),
|
||||||
lastLoginDate = None,
|
lastLoginDate = None,
|
||||||
image = image,
|
image = image,
|
||||||
isGroupAccount = false,
|
groupAccount = false,
|
||||||
isRemoved = false)
|
removed = false)
|
||||||
|
|
||||||
private def createSystemSettings(useGravatar: Boolean) =
|
private def createSystemSettings(useGravatar: Boolean) =
|
||||||
SystemSettings(
|
SystemSettings(
|
||||||
|
|||||||
Reference in New Issue
Block a user