mirror of
https://github.com/gitbucket/gitbucket.git
synced 2026-01-07 16:12:17 +01:00
Refactor new permission system
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<changeSet>
|
||||
<addColumn tableName="COLLABORATOR">
|
||||
<column name="PERMISSION" type="varchar(10)" nullable="false" defaultValue="ADMIN"/>
|
||||
<column name="ROLE" type="varchar(10)" nullable="false" defaultValue="ADMIN"/>
|
||||
</addColumn>
|
||||
<addColumn tableName="REPOSITORY">
|
||||
<column name="WIKI_OPTION" type="varchar(10)" nullable="false" defaultValue="DISABLE"/>
|
||||
|
||||
@@ -524,7 +524,7 @@ trait ApiControllerBase extends ControllerBase {
|
||||
})
|
||||
|
||||
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
|
||||
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
getAssignableUserNames(owner, name),
|
||||
getMilestones(owner, name),
|
||||
getLabels(owner, name),
|
||||
hasWritePermission(owner, name, context.loginAccount),
|
||||
isManageable(repository),
|
||||
repository)
|
||||
}
|
||||
} else Unauthorized()
|
||||
@@ -386,7 +386,7 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
* Tests whether an logged-in user can manage issues.
|
||||
*/
|
||||
private def isManageable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,8 +394,9 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
*/
|
||||
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
|
||||
repository.repository.options.issuesOption match {
|
||||
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "ALL" => !repository.repository.isPrivate && context.loginAccount.isDefined
|
||||
case "PUBLIC" => hasGuestRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "DISABLE" => false
|
||||
}
|
||||
}
|
||||
@@ -404,7 +405,7 @@ trait IssuesControllerBase extends ControllerBase {
|
||||
* Tests whether an issue or a comment is editable by a logged-in user.
|
||||
*/
|
||||
private def isEditableContent(owner: String, repository: String, author: String)(implicit context: Context): Boolean = {
|
||||
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ trait LabelsControllerBase extends ControllerBase {
|
||||
getLabels(repository.owner, repository.name),
|
||||
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||
repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
})
|
||||
|
||||
ajaxGet("/:owner/:repository/issues/labels/new")(writableUsersOnly { repository =>
|
||||
@@ -43,7 +43,7 @@ trait LabelsControllerBase extends ControllerBase {
|
||||
// TODO futility
|
||||
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||
repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
})
|
||||
|
||||
ajaxGet("/:owner/:repository/issues/labels/:labelId/edit")(writableUsersOnly { repository =>
|
||||
@@ -59,7 +59,7 @@ trait LabelsControllerBase extends ControllerBase {
|
||||
// TODO futility
|
||||
countIssueGroupByLabels(repository.owner, repository.name, IssuesService.IssueSearchCondition(), Map.empty),
|
||||
repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
})
|
||||
|
||||
ajaxPost("/:owner/:repository/issues/labels/:labelId/delete")(writableUsersOnly { repository =>
|
||||
|
||||
@@ -27,7 +27,7 @@ trait MilestonesControllerBase extends ControllerBase {
|
||||
params.getOrElse("state", "open"),
|
||||
getMilestonesWithIssueCount(repository.owner, repository.name),
|
||||
repository,
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
})
|
||||
|
||||
get("/:owner/:repository/issues/milestones/new")(writableUsersOnly {
|
||||
|
||||
@@ -115,7 +115,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
val hasConflict = LockUtil.lock(s"${owner}/${name}"){
|
||||
checkConflict(owner, name, pullreq.branch, issueId)
|
||||
}
|
||||
val hasMergePermission = hasWritePermission(owner, name, context.loginAccount)
|
||||
val hasMergePermission = hasDeveloperRole(owner, name, context.loginAccount)
|
||||
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.branch)
|
||||
val mergeStatus = PullRequestService.MergeStatus(
|
||||
hasConflict = hasConflict,
|
||||
@@ -125,7 +125,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
needStatusCheck = context.loginAccount.map{ u =>
|
||||
branchProtection.needStatusCheck(u.userName)
|
||||
}.getOrElse(true),
|
||||
hasUpdatePermission = hasWritePermission(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount) &&
|
||||
hasUpdatePermission = hasDeveloperRole(pullreq.requestUserName, pullreq.requestRepositoryName, context.loginAccount) &&
|
||||
context.loginAccount.map{ u =>
|
||||
!getProtectedBranchInfo(pullreq.requestUserName, pullreq.requestRepositoryName, pullreq.requestBranch).needStatusCheck(u.userName)
|
||||
}.getOrElse(false),
|
||||
@@ -163,7 +163,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
(issue, pullreq) <- getPullRequest(baseRepository.owner, baseRepository.name, issueId)
|
||||
owner = pullreq.requestUserName
|
||||
name = pullreq.requestRepositoryName
|
||||
if hasWritePermission(owner, name, context.loginAccount)
|
||||
if hasDeveloperRole(owner, name, context.loginAccount)
|
||||
} yield {
|
||||
val branchProtection = getProtectedBranchInfo(owner, name, pullreq.requestBranch)
|
||||
if(branchProtection.needStatusCheck(loginAccount.userName)){
|
||||
@@ -374,7 +374,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
forkedRepository,
|
||||
originRepository,
|
||||
forkedRepository,
|
||||
hasWritePermission(originRepository.owner, originRepository.name, context.loginAccount),
|
||||
hasDeveloperRole(originRepository.owner, originRepository.name, context.loginAccount),
|
||||
getAssignableUserNames(originRepository.owner, originRepository.name),
|
||||
getMilestones(originRepository.owner, originRepository.name),
|
||||
getLabels(originRepository.owner, originRepository.name)
|
||||
@@ -389,7 +389,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
}) getOrElse NotFound()
|
||||
})
|
||||
|
||||
ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(writableUsersOnly { forkedRepository =>
|
||||
ajaxGet("/:owner/:repository/compare/*...*/mergecheck")(readableUsersOnly { forkedRepository =>
|
||||
val Seq(origin, forked) = multiParams("splat")
|
||||
val (originOwner, tmpOriginBranch) = parseCompareIdentifie(origin, forkedRepository.owner)
|
||||
val (forkedOwner, tmpForkedBranch) = parseCompareIdentifie(forked, forkedRepository.owner)
|
||||
@@ -544,7 +544,7 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
* Tests whether an logged-in user can manage pull requests.
|
||||
*/
|
||||
private def isManageable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,8 +552,9 @@ trait PullRequestsControllerBase extends ControllerBase {
|
||||
*/
|
||||
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
|
||||
repository.repository.options.issuesOption match {
|
||||
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "ALL" => !repository.repository.isPrivate && context.loginAccount.isDefined
|
||||
case "PUBLIC" => hasGuestRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "DISABLE" => false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,8 +179,8 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
val collaborators = params("collaborators")
|
||||
removeCollaborators(repository.owner, repository.name)
|
||||
collaborators.split(",").withFilter(_.nonEmpty).map { collaborator =>
|
||||
val userName :: permission :: Nil = collaborator.split(":").toList
|
||||
addCollaborator(repository.owner, repository.name, userName, permission)
|
||||
val userName :: role :: Nil = collaborator.split(":").toList
|
||||
addCollaborator(repository.owner, repository.name, userName, role)
|
||||
}
|
||||
redirect(s"/${repository.owner}/${repository.name}/settings/collaborators")
|
||||
})
|
||||
@@ -416,7 +416,7 @@ trait RepositorySettingsControllerBase extends ControllerBase {
|
||||
*/
|
||||
private def featureOption: Constraint = new Constraint(){
|
||||
override def validate(name: String, value: String, params: Map[String, String], messages: Messages): Option[String] =
|
||||
if(Seq("DISABLE", "PRIVATE", "PUBLIC").contains(value)) None else Some("Option is invalid.")
|
||||
if(Seq("DISABLE", "PRIVATE", "PUBLIC", "ALL").contains(value)) None else Some("Option is invalid.")
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
enableLineBreaks = params("enableLineBreaks").toBoolean,
|
||||
enableTaskList = params("enableTaskList").toBoolean,
|
||||
enableAnchor = false,
|
||||
hasWritePermission = hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
)
|
||||
})
|
||||
|
||||
@@ -151,7 +151,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
html.commits(if(path.isEmpty) Nil else path.split("/").toList, branchName, repository,
|
||||
logs.splitWith{ (commit1, commit2) =>
|
||||
view.helpers.date(commit1.commitTime) == view.helpers.date(commit2.commitTime)
|
||||
}, page, hasNext, hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
}, page, hasNext, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
case Left(_) => NotFound()
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
html.blob(id, repository, path.split("/").toList,
|
||||
JGitUtil.getContentInfo(git, path, objectId),
|
||||
new JGitUtil.CommitInfo(JGitUtil.getLastModifiedCommit(git, revCommit, path)),
|
||||
hasWritePermission(repository.owner, repository.name, context.loginAccount),
|
||||
hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
|
||||
request.paths(2) == "blame")
|
||||
}
|
||||
} getOrElse NotFound()
|
||||
@@ -329,7 +329,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
JGitUtil.getBranchesOfCommit(git, revCommit.getName),
|
||||
JGitUtil.getTagsOfCommit(git, revCommit.getName),
|
||||
getCommitComments(repository.owner, repository.name, id, false),
|
||||
repository, diffs, oldCommitId, hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
repository, diffs, oldCommitId, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -358,7 +358,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
html.commentform(
|
||||
commitId = id,
|
||||
fileName, oldLineNumber, newLineNumber, issueId,
|
||||
hasWritePermission = hasWritePermission(repository.owner, repository.name, context.loginAccount),
|
||||
hasWritePermission = hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
|
||||
repository = repository
|
||||
)
|
||||
})
|
||||
@@ -374,7 +374,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
callPullRequestReviewCommentWebHook("create", comment, repository, issueId, context.baseUrl, context.loginAccount.get)
|
||||
case None => recordCommentCommitActivity(repository.owner, repository.name, context.loginAccount.get.userName, id, form.content)
|
||||
}
|
||||
helper.html.commitcomment(comment, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository)
|
||||
helper.html.commitcomment(comment, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
|
||||
})
|
||||
|
||||
ajaxGet("/:owner/:repository/commit_comments/_data/:id")(readableUsersOnly { repository =>
|
||||
@@ -393,7 +393,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
enableRefsLink = true,
|
||||
enableAnchor = true,
|
||||
enableLineBreaks = true,
|
||||
hasWritePermission = isEditable(x.userName, x.repositoryName, x.commentedUserName)
|
||||
hasWritePermission = true
|
||||
)
|
||||
))
|
||||
}
|
||||
@@ -437,7 +437,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
.map(br => (br, getPullRequestByRequestCommit(repository.owner, repository.name, repository.repository.defaultBranch, br.name, br.commitId), protectedBranches.contains(br.name)))
|
||||
.reverse
|
||||
|
||||
html.branches(branches, hasWritePermission(repository.owner, repository.name, context.loginAccount), repository)
|
||||
html.branches(branches, hasDeveloperRole(repository.owner, repository.name, context.loginAccount), repository)
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -547,7 +547,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
*/
|
||||
private def fileList(repository: RepositoryService.RepositoryInfo, revstr: String = "", path: String = ".") = {
|
||||
if(repository.commitCount == 0){
|
||||
html.guide(repository, hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||
html.guide(repository, hasDeveloperRole(repository.owner, repository.name, context.loginAccount))
|
||||
} else {
|
||||
using(Git.open(getRepositoryDir(repository.owner, repository.name))){ git =>
|
||||
// get specified commit
|
||||
@@ -569,7 +569,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
html.files(revision, repository,
|
||||
if(path == ".") Nil else path.split("/").toList, // current path
|
||||
new JGitUtil.CommitInfo(lastModifiedCommit), // last modified commit
|
||||
files, readme, hasWritePermission(repository.owner, repository.name, context.loginAccount),
|
||||
files, readme, hasDeveloperRole(repository.owner, repository.name, context.loginAccount),
|
||||
getPullRequestFromBranch(repository.owner, repository.name, revstr, repository.repository.defaultBranch),
|
||||
flash.get("info"), flash.get("error"))
|
||||
}
|
||||
@@ -691,7 +691,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
}
|
||||
|
||||
private def isEditable(owner: String, repository: String, author: String)(implicit context: Context): Boolean =
|
||||
hasWritePermission(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
hasDeveloperRole(owner, repository, context.loginAccount) || author == context.loginAccount.get.userName
|
||||
|
||||
override protected def renderUncaughtException(e: Throwable)(implicit request: HttpServletRequest, response: HttpServletResponse): Unit = {
|
||||
e.printStackTrace()
|
||||
|
||||
@@ -242,9 +242,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
|
||||
private def isEditable(repository: RepositoryInfo)(implicit context: Context): Boolean = {
|
||||
repository.repository.options.wikiOption match {
|
||||
// case "ALL" => repository.repository.isPrivate == false || hasReadPermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "PUBLIC" => hasReadPermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasWritePermission(repository.owner, repository.name, context.loginAccount)
|
||||
case "ALL" => !repository.repository.isPrivate && context.loginAccount.isDefined
|
||||
case "PUBLIC" => hasGuestRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "PRIVATE" => hasDeveloperRole(repository.owner, repository.name, context.loginAccount)
|
||||
case "DISABLE" => false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ trait CollaboratorComponent extends TemplateComponent { self: Profile =>
|
||||
|
||||
class Collaborators(tag: Tag) extends Table[Collaborator](tag, "COLLABORATOR") with BasicTemplate {
|
||||
val collaboratorName = column[String]("COLLABORATOR_NAME")
|
||||
val permission = column[String]("PERMISSION")
|
||||
def * = (userName, repositoryName, collaboratorName, permission) <> (Collaborator.tupled, Collaborator.unapply)
|
||||
val role = column[String]("ROLE")
|
||||
def * = (userName, repositoryName, collaboratorName, role) <> (Collaborator.tupled, Collaborator.unapply)
|
||||
|
||||
def byPrimaryKey(owner: String, repository: String, collaborator: String) =
|
||||
byRepository(owner, repository) && (collaboratorName === collaborator.bind)
|
||||
@@ -19,15 +19,15 @@ case class Collaborator(
|
||||
userName: String,
|
||||
repositoryName: String,
|
||||
collaboratorName: String,
|
||||
permission: String
|
||||
role: String
|
||||
)
|
||||
|
||||
sealed abstract class Permission(val name: String)
|
||||
sealed abstract class Role(val name: String)
|
||||
|
||||
object Permission {
|
||||
object ADMIN extends Permission("ADMIN")
|
||||
object WRITE extends Permission("WRITE")
|
||||
object READ extends Permission("READ")
|
||||
object Role {
|
||||
object ADMIN extends Role("ADMIN")
|
||||
object DEVELOPER extends Role("DEVELOPER")
|
||||
object GUEST extends Role("GUEST")
|
||||
|
||||
// val values: Vector[Permission] = Vector(ADMIN, WRITE, READ)
|
||||
//
|
||||
|
||||
@@ -434,7 +434,7 @@ trait IssuesService {
|
||||
}
|
||||
|
||||
def getAssignableUserNames(owner: String, repository: String)(implicit s: Session): List[String] = {
|
||||
(getCollaboratorUserNames(owner, repository, Seq(Permission.ADMIN, Permission.WRITE)) :::
|
||||
(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER)) :::
|
||||
(if (getAccountByUserName(owner).get.isGroupAccount) getGroupMembers(owner).map(_.userName) else List(owner))).distinct.sorted
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package gitbucket.core.service
|
||||
|
||||
import gitbucket.core.controller.Context
|
||||
import gitbucket.core.model.{Collaborator, Repository, RepositoryOptions, Account, Permission}
|
||||
import gitbucket.core.model.{Collaborator, Repository, RepositoryOptions, Account, Role}
|
||||
import gitbucket.core.model.Profile._
|
||||
import gitbucket.core.util.JGitUtil
|
||||
import profile.simple._
|
||||
@@ -335,8 +335,8 @@ trait RepositoryService { self: AccountService =>
|
||||
/**
|
||||
* Add collaborator (user or group) to the repository.
|
||||
*/
|
||||
def addCollaborator(userName: String, repositoryName: String, collaboratorName: String, permission: String)(implicit s: Session): Unit =
|
||||
Collaborators insert Collaborator(userName, repositoryName, collaboratorName, permission)
|
||||
def addCollaborator(userName: String, repositoryName: String, collaboratorName: String, role: String)(implicit s: Session): Unit =
|
||||
Collaborators insert Collaborator(userName, repositoryName, collaboratorName, role)
|
||||
|
||||
/**
|
||||
* Remove all collaborators from the repository.
|
||||
@@ -359,38 +359,38 @@ trait RepositoryService { self: AccountService =>
|
||||
* Returns the list of all collaborator name and permission which is sorted with ascending order.
|
||||
* If a group is added as a collaborator, this method returns users who are belong to that group.
|
||||
*/
|
||||
def getCollaboratorUserNames(userName: String, repositoryName: String, filter: Seq[Permission] = Nil)(implicit s: Session): List[String] = {
|
||||
def getCollaboratorUserNames(userName: String, repositoryName: String, filter: Seq[Role] = Nil)(implicit s: Session): List[String] = {
|
||||
val q1 = Collaborators
|
||||
.innerJoin(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === false.bind) }
|
||||
.filter { case (t1, t2) => t1.byRepository(userName, repositoryName) }
|
||||
.map { case (t1, t2) => (t1.collaboratorName, t1.permission) }
|
||||
.map { case (t1, t2) => (t1.collaboratorName, t1.role) }
|
||||
|
||||
val q2 = Collaborators
|
||||
.innerJoin(Accounts).on { case (t1, t2) => (t1.collaboratorName === t2.userName) && (t2.groupAccount === true.bind) }
|
||||
.innerJoin(GroupMembers).on { case ((t1, t2), t3) => t2.userName === t3.groupName }
|
||||
.filter { case ((t1, t2), t3) => t1.byRepository(userName, repositoryName) }
|
||||
.map { case ((t1, t2), t3) => (t3.userName, t1.permission) }
|
||||
.map { case ((t1, t2), t3) => (t3.userName, t1.role) }
|
||||
|
||||
q1.union(q2).list.filter { x => filter.isEmpty || filter.exists(_.name == x._2) }.map(_._1)
|
||||
}
|
||||
|
||||
|
||||
def hasWritePermission(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
||||
def hasDeveloperRole(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
||||
loginAccount match {
|
||||
case Some(a) if(a.isAdmin) => true
|
||||
case Some(a) if(a.userName == owner) => true
|
||||
case Some(a) if(getGroupMembers(owner).exists(_.userName == a.userName)) => true
|
||||
case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Permission.ADMIN, Permission.WRITE)).contains(a.userName)) => true
|
||||
case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER)).contains(a.userName)) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
def hasReadPermission(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
||||
def hasGuestRole(owner: String, repository: String, loginAccount: Option[Account])(implicit s: Session): Boolean = {
|
||||
loginAccount match {
|
||||
case Some(a) if(a.isAdmin) => true
|
||||
case Some(a) if(a.userName == owner) => true
|
||||
case Some(a) if(getGroupMembers(owner).exists(_.userName == a.userName)) => true
|
||||
case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Permission.ADMIN, Permission.WRITE, Permission.READ)).contains(a.userName)) => true
|
||||
case Some(a) if(getCollaboratorUserNames(owner, repository, Seq(Role.ADMIN, Role.DEVELOPER, Role.GUEST)).contains(a.userName)) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class GitAuthenticationFilter extends Filter with RepositoryService with Account
|
||||
Array(username, password) = AuthUtil.decodeAuthHeader(auth).split(":", 2)
|
||||
account <- authenticate(settings, username, password)
|
||||
} yield if(isUpdating || repository.repository.isPrivate){
|
||||
if(hasWritePermission(repository.owner, repository.name, Some(account))){
|
||||
if(hasDeveloperRole(repository.owner, repository.name, Some(account))){
|
||||
request.setAttribute(Keys.Request.UserName, account.userName)
|
||||
true
|
||||
} else false
|
||||
|
||||
@@ -92,7 +92,7 @@ abstract class DefaultGitCommand(val owner: String, val repoName: String) extend
|
||||
protected def isWritableUser(username: String, repositoryInfo: RepositoryService.RepositoryInfo)
|
||||
(implicit session: Session): Boolean =
|
||||
getAccountByUserName(username) match {
|
||||
case Some(account) => hasWritePermission(repositoryInfo.owner, repositoryInfo.name, Some(account))
|
||||
case Some(account) => hasDeveloperRole(repositoryInfo.owner, repositoryInfo.name, Some(account))
|
||||
case None => false
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,11 @@ package gitbucket.core.util
|
||||
|
||||
import gitbucket.core.controller.ControllerBase
|
||||
import gitbucket.core.service.{AccountService, RepositoryService}
|
||||
import gitbucket.core.model.Permission
|
||||
import gitbucket.core.model.Role
|
||||
import RepositoryService.RepositoryInfo
|
||||
import Implicits._
|
||||
import ControlUtil._
|
||||
|
||||
import scala.collection.Searching.search
|
||||
|
||||
/**
|
||||
* Allows only oneself and administrators.
|
||||
*/
|
||||
@@ -45,7 +43,7 @@ trait OwnerAuthenticator { self: ControllerBase with RepositoryService with Acco
|
||||
case Some(x) if(repository.owner == x.userName) => action(repository)
|
||||
// TODO Repository management is allowed for only group managers?
|
||||
case Some(x) if(getGroupMembers(repository.owner).exists { m => m.userName == x.userName && m.isManager == true }) => action(repository)
|
||||
case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Permission.ADMIN)).contains(x.userName)) => action(repository)
|
||||
case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN)).contains(x.userName)) => action(repository)
|
||||
case _ => Unauthorized()
|
||||
}
|
||||
} getOrElse NotFound()
|
||||
@@ -156,7 +154,7 @@ trait WritableUsersAuthenticator { self: ControllerBase with RepositoryService w
|
||||
case Some(x) if(x.isAdmin) => action(repository)
|
||||
case Some(x) if(paths(0) == x.userName) => action(repository)
|
||||
case Some(x) if(getGroupMembers(repository.owner).exists(_.userName == x.userName)) => action(repository)
|
||||
case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Permission.ADMIN, Permission.WRITE)).contains(x.userName)) => action(repository)
|
||||
case Some(x) if(getCollaboratorUserNames(paths(0), paths(1), Seq(Role.ADMIN, Role.DEVELOPER)).contains(x.userName)) => action(repository)
|
||||
case _ => Unauthorized()
|
||||
}
|
||||
} getOrElse NotFound()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
isGroupRepository: Boolean,
|
||||
repository: gitbucket.core.service.RepositoryService.RepositoryInfo)(implicit context: gitbucket.core.controller.Context)
|
||||
@import gitbucket.core.view.helpers
|
||||
@import gitbucket.core.model.Permission
|
||||
@import gitbucket.core.model.Role
|
||||
@gitbucket.core.html.main("Settings", Some(repository)){
|
||||
@gitbucket.core.html.menu("settings", repository){
|
||||
@gitbucket.core.settings.html.menu("collaborators", repository){
|
||||
@@ -77,7 +77,8 @@ $(function(){
|
||||
$.post('@context.path/_user/existence', { 'userName': userName },
|
||||
function(data, status){
|
||||
if(data != ''){
|
||||
addListHTML(userName, '@Permission.ADMIN.name', '#' + id + '-list');
|
||||
addListHTML(userName, '@Role.ADMIN.name', '#' + id + '-list');
|
||||
$('#userName-' + id).val('');
|
||||
} else {
|
||||
$('#error-' + id).text('User does not exist.');
|
||||
}
|
||||
@@ -94,26 +95,26 @@ $(function(){
|
||||
});
|
||||
|
||||
@collaborators.map { case (collaborator, isGroup) =>
|
||||
addListHTML('@collaborator.collaboratorName', '@collaborator.permission', @if(isGroup){'#group-list'}else{'#collaborator-list'});
|
||||
addListHTML('@collaborator.collaboratorName', '@collaborator.role', @if(isGroup){'#group-list'}else{'#collaborator-list'});
|
||||
}
|
||||
|
||||
function addListHTML(userName, permission, id){
|
||||
var adminButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Permission.ADMIN.name" name="' + userName + '">Admin</label>');
|
||||
if(permission == '@Permission.ADMIN.name'){
|
||||
function addListHTML(userName, role, id){
|
||||
var adminButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Role.ADMIN.name" name="' + userName + '">Admin</label>');
|
||||
if(role == '@Role.ADMIN.name'){
|
||||
adminButton.addClass('active');
|
||||
}
|
||||
var writeButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Permission.WRITE.name" name="' + userName + '">Write</label>');
|
||||
if(permission == '@Permission.WRITE.name'){
|
||||
var writeButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Role.DEVELOPER.name" name="' + userName + '">Developer</label>');
|
||||
if(role == '@Role.DEVELOPER.name'){
|
||||
writeButton.addClass('active');
|
||||
}
|
||||
var readButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Permission.READ.name" name="' + userName + '">Read</label>');
|
||||
if(permission == '@Permission.READ.name'){
|
||||
var readButton = $('<label class="btn btn-default btn-mini"><input type="radio" value="@Role.GUEST.name" name="' + userName + '">Guest</label>');
|
||||
if(role == '@Role.GUEST.name'){
|
||||
readButton.addClass('active');
|
||||
}
|
||||
|
||||
$(id).append($('<li>')
|
||||
.data('name', userName)
|
||||
.append($('<div class="btn-group permission" data-toggle="buttons">')
|
||||
.append($('<div class="btn-group role" data-toggle="buttons">')
|
||||
.append(adminButton)
|
||||
.append(writeButton)
|
||||
.append(readButton))
|
||||
|
||||
@@ -61,12 +61,17 @@
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="issuesOption" value="PRIVATE" @if(repository.repository.options.issuesOption == "PRIVATE"){ checked}> Writable users can view, create and comment on issues
|
||||
<input type="radio" name="issuesOption" value="PRIVATE" @if(repository.repository.options.issuesOption == "PRIVATE"){ checked}> Developers can view, create and comment on issues
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="issuesOption" value="PUBLIC" @if(repository.repository.options.issuesOption == "PUBLIC"){ checked}> Readable users can view, create and comment on isues
|
||||
<input type="radio" name="issuesOption" value="PUBLIC" @if(repository.repository.options.issuesOption == "PUBLIC"){ checked}> Developers and guests can view, create and comment on isues
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio for-public-repo">
|
||||
<label>
|
||||
<input type="radio" name="issuesOption" value="ALL" @if(repository.repository.options.issuesOption == "ALL"){ checked}> All users can view, create and comment on isues
|
||||
</label>
|
||||
</div>
|
||||
<label for="externalIssuesUrl" class="strong">External URL:
|
||||
@@ -87,12 +92,17 @@
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="wikiOption" value="PRIVATE" @if(repository.repository.options.wikiOption == "PRIVATE"){ checked}> Writable users can view, create and edit wiki pages
|
||||
<input type="radio" name="wikiOption" value="PRIVATE" @if(repository.repository.options.wikiOption == "PRIVATE"){ checked}> Developers can view, create and edit wiki pages
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="wikiOption" value="PUBLIC" @if(repository.repository.options.wikiOption == "PUBLIC"){ checked}> Readable users can view, create and edit wiki pages
|
||||
<input type="radio" name="wikiOption" value="PUBLIC" @if(repository.repository.options.wikiOption == "PUBLIC"){ checked}> Developers ans guests can view, create and edit wiki pages
|
||||
</label>
|
||||
</div>
|
||||
<div class="radio for-public-repo">
|
||||
<label>
|
||||
<input type="radio" name="wikiOption" value="ALL" @if(repository.repository.options.issuesOption == "ALL"){ checked}> All users can view, create and comment on isues
|
||||
</label>
|
||||
</div>
|
||||
<label for="externalWikiUrl" class="strong">External URL:
|
||||
@@ -112,14 +122,25 @@
|
||||
<script>
|
||||
$(function(){
|
||||
updateFeatures();
|
||||
|
||||
$('input[name=issuesOption], input[name=wikiOption]').click(function(){
|
||||
$('input[name=isPrivate], input[name=issuesOption], input[name=wikiOption]').click(function(){
|
||||
updateFeatures();
|
||||
});
|
||||
});
|
||||
|
||||
function updateFeatures() {
|
||||
$('#externalIssuesUrl').prop('disabled', !$('input[name=issuesOption]').select('[value=DISABLE]').prop('checked'));
|
||||
$('#externalWikiUrl').prop('disabled', !$('input[name=wikiOption]').select('[value=DISABLE]').prop('checked'));
|
||||
if($('input[name=isPrivate]:checked').val() == 'false'){
|
||||
$('.for-public-repo').show();
|
||||
} else {
|
||||
if($('input[name=issuesOption]:checked').val() == 'ALL'){
|
||||
$('input[name=issuesOption][value=PUBLIC]').prop('checked', true);
|
||||
}
|
||||
if($('input[name=wikiOption]:checked').val() == 'ALL'){
|
||||
$('input[name=wikiOption][value=PUBLIC]').prop('checked', true);
|
||||
}
|
||||
$('.for-public-repo').hide();
|
||||
}
|
||||
|
||||
$('#externalIssuesUrl').prop('disabled', $('input[name=issuesOption]:checked').val() != 'DISABLE');
|
||||
$('#externalWikiUrl').prop('disabled', $('input[name=wikiOption]:checked').val() != 'DISABLE');
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user