mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-02 11:36:05 +01:00
Add authentication.
This commit is contained in:
@@ -2,7 +2,7 @@ package app
|
||||
|
||||
import util.Directory._
|
||||
import util.Implicits._
|
||||
import util.{JGitUtil, FileTypeUtil, CompressUtil}
|
||||
import _root_.util.{ReadableRepositoryAuthenticator, JGitUtil, FileTypeUtil, CompressUtil}
|
||||
import service._
|
||||
import org.scalatra._
|
||||
import java.io.File
|
||||
@@ -12,13 +12,13 @@ import org.apache.commons.io.FileUtils
|
||||
import org.eclipse.jgit.treewalk._
|
||||
|
||||
class RepositoryViewerController extends RepositoryViewerControllerBase
|
||||
with RepositoryService with AccountService
|
||||
with RepositoryService with AccountService with ReadableRepositoryAuthenticator
|
||||
|
||||
/**
|
||||
* The repository viewer.
|
||||
*/
|
||||
trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
self: RepositoryService with AccountService =>
|
||||
self: RepositoryService with AccountService with ReadableRepositoryAuthenticator =>
|
||||
|
||||
// TODO separate to AccountController?
|
||||
/**
|
||||
@@ -33,37 +33,37 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
/**
|
||||
* Displays the file list of the repository root and the default branch.
|
||||
*/
|
||||
get("/:owner/:repository") {
|
||||
get("/:owner/:repository")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
fileList(owner, repository)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays the file list of the repository root and the specified branch.
|
||||
*/
|
||||
get("/:owner/:repository/tree/:id") {
|
||||
get("/:owner/:repository/tree/:id")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
fileList(owner, repository, params("id"))
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays the file list of the specified path and branch.
|
||||
*/
|
||||
get("/:owner/:repository/tree/:id/*") {
|
||||
get("/:owner/:repository/tree/:id/*")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
fileList(owner, repository, params("id"), multiParams("splat").head)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays the commit list of the specified branch.
|
||||
*/
|
||||
get("/:owner/:repository/commits/:branch"){
|
||||
get("/:owner/:repository/commits/:branch")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val branchName = params("branch")
|
||||
@@ -77,12 +77,12 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
|
||||
}, page, hasNext)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays the commit list of the specified resource.
|
||||
*/
|
||||
get("/:owner/:repository/commits/:branch/*"){
|
||||
get("/:owner/:repository/commits/:branch/*")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val branchName = params("branch")
|
||||
@@ -97,13 +97,13 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
view.helpers.date(commit1.time) == view.helpers.date(commit2.time)
|
||||
}, page, hasNext)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
* Displays the file content of the specified branch or commit.
|
||||
*/
|
||||
get("/:owner/:repository/blob/:id/*"){
|
||||
get("/:owner/:repository/blob/:id/*")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val id = params("id") // branch name or commit id
|
||||
@@ -140,12 +140,12 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
repo.html.blob(id, repositoryInfo, path.split("/").toList, content, new JGitUtil.CommitInfo(revCommit))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays details of the specified commit.
|
||||
*/
|
||||
get("/:owner/:repository/commit/:id"){
|
||||
get("/:owner/:repository/commit/:id")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val id = params("id")
|
||||
@@ -155,22 +155,22 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
repo.html.commit(id, new JGitUtil.CommitInfo(revCommit),
|
||||
getRepository(owner, repository, servletContext).get, JGitUtil.getDiffs(git, id))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Displays tags.
|
||||
*/
|
||||
get("/:owner/:repository/tags"){
|
||||
get("/:owner/:repository/tags")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
repo.html.tags(getRepository(owner, repository, servletContext).get)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Download repository contents as an archive.
|
||||
*/
|
||||
get("/:owner/:repository/archive/:name"){
|
||||
get("/:owner/:repository/archive/:name")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val name = params("name")
|
||||
@@ -206,7 +206,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
} else {
|
||||
BadRequest
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Provides HTML of the file list.
|
||||
|
||||
@@ -46,7 +46,7 @@ trait SettingsControllerBase extends ControllerBase {
|
||||
/**
|
||||
* Save the repository options.
|
||||
*/
|
||||
post("/:owner/:repository/settings/options", optionsForm){ form =>
|
||||
post("/:owner/:repository/settings/options", optionsForm)(ownerOnly { form =>
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
@@ -54,7 +54,7 @@ trait SettingsControllerBase extends ControllerBase {
|
||||
saveRepositoryOptions(owner, repository, form.description, form.defaultBranch, form.repositoryType)
|
||||
|
||||
redirect("%s/%s/settings/options".format(owner, repository))
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Display the Collaborators page.
|
||||
|
||||
@@ -2,11 +2,12 @@ package app
|
||||
|
||||
import model._
|
||||
import service._
|
||||
import util.AdminOnlyAuthenticator
|
||||
import jp.sf.amateras.scalatra.forms._
|
||||
|
||||
class UsersController extends UsersControllerBase with AccountService
|
||||
class UsersController extends UsersControllerBase with AccountService with AdminOnlyAuthenticator
|
||||
|
||||
trait UsersControllerBase extends ControllerBase { self: AccountService =>
|
||||
trait UsersControllerBase extends ControllerBase { self: AccountService with AdminOnlyAuthenticator =>
|
||||
|
||||
// TODO ユーザ名の先頭に_は使えないようにする&利用可能文字チェック
|
||||
case class UserForm(userName: String, password: String, mailAddress: String, userType: Int, url: Option[String])
|
||||
@@ -27,15 +28,15 @@ trait UsersControllerBase extends ControllerBase { self: AccountService =>
|
||||
"url" -> trim(label("URL" , optional(text(maxlength(200)))))
|
||||
)(UserForm.apply)
|
||||
|
||||
get("/admin/users"){
|
||||
get("/admin/users")(adminOnly {
|
||||
admin.html.userlist(getAllUsers())
|
||||
}
|
||||
})
|
||||
|
||||
get("/admin/users/_new"){
|
||||
get("/admin/users/_new")(adminOnly {
|
||||
admin.html.useredit(None)
|
||||
}
|
||||
})
|
||||
|
||||
post("/admin/users/_new", newForm){ form =>
|
||||
post("/admin/users/_new", newForm)(adminOnly { form =>
|
||||
val currentDate = new java.sql.Date(System.currentTimeMillis)
|
||||
createAccount(Account(
|
||||
userName = form.userName,
|
||||
@@ -48,14 +49,14 @@ trait UsersControllerBase extends ControllerBase { self: AccountService =>
|
||||
lastLoginDate = None))
|
||||
|
||||
redirect("/admin/users")
|
||||
}
|
||||
})
|
||||
|
||||
get("/admin/users/:userName/_edit"){
|
||||
get("/admin/users/:userName/_edit")(adminOnly {
|
||||
val userName = params("userName")
|
||||
admin.html.useredit(getAccountByUserName(userName))
|
||||
}
|
||||
})
|
||||
|
||||
post("/admin/users/:name/_edit", editForm){ form =>
|
||||
post("/admin/users/:name/_edit", editForm)(adminOnly { form =>
|
||||
val userName = params("userName")
|
||||
val currentDate = new java.sql.Date(System.currentTimeMillis)
|
||||
updateAccount(getAccountByUserName(userName).get.copy(
|
||||
@@ -66,7 +67,7 @@ trait UsersControllerBase extends ControllerBase { self: AccountService =>
|
||||
updatedDate = currentDate))
|
||||
|
||||
redirect("/admin/users")
|
||||
}
|
||||
})
|
||||
|
||||
def unique: Constraint = new Constraint(){
|
||||
def validate(name: String, value: String): Option[String] =
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package app
|
||||
|
||||
import service._
|
||||
import util.{CollaboratorsOnlyAuthenticator, JGitUtil}
|
||||
import util.{WritableRepositoryAuthenticator, ReadableRepositoryAuthenticator, JGitUtil}
|
||||
import util.Directory._
|
||||
import jp.sf.amateras.scalatra.forms._
|
||||
|
||||
class WikiController extends WikiControllerBase
|
||||
with WikiService with RepositoryService with AccountService with CollaboratorsOnlyAuthenticator
|
||||
with WikiService with RepositoryService with AccountService with WritableRepositoryAuthenticator with ReadableRepositoryAuthenticator
|
||||
|
||||
trait WikiControllerBase extends ControllerBase {
|
||||
self: WikiService with RepositoryService with CollaboratorsOnlyAuthenticator =>
|
||||
self: WikiService with RepositoryService with WritableRepositoryAuthenticator with ReadableRepositoryAuthenticator =>
|
||||
|
||||
// TODO ユーザ名の先頭に_は使えないようにする
|
||||
case class WikiPageEditForm(pageName: String, content: String, message: Option[String], currentPageName: String)
|
||||
@@ -28,7 +28,7 @@ trait WikiControllerBase extends ControllerBase {
|
||||
"currentPageName" -> trim(label("Current page name" , text(required)))
|
||||
)(WikiPageEditForm.apply)
|
||||
|
||||
get("/:owner/:repository/wiki"){
|
||||
get("/:owner/:repository/wiki")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
@@ -36,9 +36,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
case Some(page) => wiki.html.wiki("Home", page, getRepository(owner, repository, servletContext).get, isWritable(owner, repository))
|
||||
case None => redirect("/%s/%s/wiki/Home/_edit".format(owner, repository))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/:page"){
|
||||
get("/:owner/:repository/wiki/:page")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val pageName = params("page")
|
||||
@@ -47,9 +47,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
case Some(page) => wiki.html.wiki(pageName, page, getRepository(owner, repository, servletContext).get, isWritable(owner, repository))
|
||||
case None => redirect("/%s/%s/wiki/%s/_edit".format(owner, repository, pageName)) // TODO URLEncode
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/:page/_history"){
|
||||
get("/:owner/:repository/wiki/:page/_history")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val page = params("page")
|
||||
@@ -58,9 +58,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
wiki.html.wikihistory(Some(page),
|
||||
JGitUtil.getCommitLog(git, "master", path = page + ".md")._1, getRepository(owner, repository, servletContext).get)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/:page/_compare/:commitId"){
|
||||
get("/:owner/:repository/wiki/:page/_compare/:commitId")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val page = params("page")
|
||||
@@ -70,9 +70,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
wiki.html.wikicompare(Some(page),
|
||||
getWikiDiffs(git, commitId(0), commitId(1)), getRepository(owner, repository, servletContext).get)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_compare/:commitId"){
|
||||
get("/:owner/:repository/wiki/_compare/:commitId")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val commitId = params("commitId").split("\\.\\.\\.")
|
||||
@@ -81,9 +81,9 @@ trait WikiControllerBase extends ControllerBase {
|
||||
wiki.html.wikicompare(None,
|
||||
getWikiDiffs(git, commitId(0), commitId(1)), getRepository(owner, repository, servletContext).get)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/:page/_edit")(collaboratorsOnly {
|
||||
get("/:owner/:repository/wiki/:page/_edit")(writableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val page = params("page")
|
||||
@@ -92,7 +92,7 @@ trait WikiControllerBase extends ControllerBase {
|
||||
getWikiPage(owner, repository, page), getRepository(owner, repository, servletContext).get)
|
||||
})
|
||||
|
||||
post("/:owner/:repository/wiki/_edit", editForm)(collaboratorsOnly { form =>
|
||||
post("/:owner/:repository/wiki/_edit", editForm)(writableRepository { form =>
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
@@ -102,14 +102,14 @@ trait WikiControllerBase extends ControllerBase {
|
||||
redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName))
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_new")(collaboratorsOnly {
|
||||
get("/:owner/:repository/wiki/_new")(writableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
wiki.html.wikiedit("", None, getRepository(owner, repository, servletContext).get)
|
||||
})
|
||||
|
||||
post("/:owner/:repository/wiki/_new", newForm)(collaboratorsOnly { form =>
|
||||
post("/:owner/:repository/wiki/_new", newForm)(writableRepository { form =>
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
@@ -119,7 +119,7 @@ trait WikiControllerBase extends ControllerBase {
|
||||
redirect("%s/%s/wiki/%s".format(owner, repository, form.pageName))
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/:page/_delete")(collaboratorsOnly {
|
||||
get("/:owner/:repository/wiki/:page/_delete")(writableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val page = params("page")
|
||||
@@ -129,14 +129,14 @@ trait WikiControllerBase extends ControllerBase {
|
||||
redirect("%s/%s/wiki".format(owner, repository))
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_pages"){
|
||||
get("/:owner/:repository/wiki/_pages")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
wiki.html.wikipages(getWikiPageList(owner, repository), getRepository(owner, repository, servletContext).get, isWritable(owner, repository))
|
||||
}
|
||||
})
|
||||
|
||||
get("/:owner/:repository/wiki/_history"){
|
||||
get("/:owner/:repository/wiki/_history")(readableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
|
||||
@@ -144,15 +144,15 @@ trait WikiControllerBase extends ControllerBase {
|
||||
wiki.html.wikihistory(None,
|
||||
JGitUtil.getCommitLog(git, "master")._1, getRepository(owner, repository, servletContext).get)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
post("/:owner/:repository/wiki/_preview"){
|
||||
post("/:owner/:repository/wiki/_preview")(writableRepository {
|
||||
val owner = params("owner")
|
||||
val repository = params("repository")
|
||||
val content = params("content")
|
||||
contentType = "text/html"
|
||||
view.helpers.markdown(content, getRepository(owner, repository, servletContext).get, true)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Constraint for the wiki page name.
|
||||
|
||||
@@ -8,7 +8,10 @@ import service._
|
||||
*/
|
||||
trait OwnerOnlyAuthenticator { self: ControllerBase =>
|
||||
|
||||
protected def ownerOnly(action: => Any) = {
|
||||
protected def ownerOnly(action: => Any) = { authenticate(action) }
|
||||
protected def ownerOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
{
|
||||
context.loginAccount match {
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action
|
||||
@@ -17,16 +20,6 @@ trait OwnerOnlyAuthenticator { self: ControllerBase =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def ownerOnly[T](action: T => Any) = {
|
||||
(form: T) => {
|
||||
context.loginAccount match {
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action(form)
|
||||
case Some(x) if(request.getRequestURI.split("/")(1) == x.userName) => action(form)
|
||||
case _ => redirect("/signin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +27,10 @@ trait OwnerOnlyAuthenticator { self: ControllerBase =>
|
||||
*/
|
||||
trait UsersOnlyAuthenticator { self: ControllerBase =>
|
||||
|
||||
protected def usersOnly(action: => Any) = {
|
||||
protected def usersOnly(action: => Any) = { authenticate(action) }
|
||||
protected def usersOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
{
|
||||
context.loginAccount match {
|
||||
case Some(x) => action
|
||||
@@ -42,12 +38,21 @@ trait UsersOnlyAuthenticator { self: ControllerBase =>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def usersOnly[T](action: T => Any) = {
|
||||
(form: T) => {
|
||||
/**
|
||||
* Allows only administrators.
|
||||
*/
|
||||
trait AdminOnlyAuthenticator { self: ControllerBase =>
|
||||
|
||||
protected def adminOnly(action: => Any) = { authenticate(action) }
|
||||
protected def adminOnly[T](action: T => Any) = (form: T) => authenticate({action(form)})
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
{
|
||||
context.loginAccount match {
|
||||
case Some(x) => action(form)
|
||||
case None => redirect("/signin")
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action
|
||||
case _ => redirect("/signin")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,40 +61,43 @@ trait UsersOnlyAuthenticator { self: ControllerBase =>
|
||||
/**
|
||||
* Allows only collaborators and administrators.
|
||||
*/
|
||||
trait CollaboratorsOnlyAuthenticator { self: ControllerBase with RepositoryService =>
|
||||
trait WritableRepositoryAuthenticator { self: ControllerBase with RepositoryService =>
|
||||
|
||||
protected def collaboratorsOnly(action: => Any) = {
|
||||
{
|
||||
protected def writableRepository(action: => Any) = { authenticate(action) }
|
||||
protected def writableRepository[T](action: T => Any) = (form: T) => authenticate({action(form)})
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
val paths = request.getRequestURI.split("/")
|
||||
context.loginAccount match {
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action
|
||||
case Some(x) if(request.getRequestURI.split("/")(1) == x.userName) => action
|
||||
case Some(x) => {
|
||||
val paths = request.getRequestURI.split("/")
|
||||
if(getCollaborators(paths(1), paths(2)).contains(x.userName)){
|
||||
action
|
||||
} else {
|
||||
redirect("/signin")
|
||||
}
|
||||
}
|
||||
case None => redirect("/signin")
|
||||
case Some(x) if(paths(1) == x.userName) => action
|
||||
case Some(x) if(getCollaborators(paths(1), paths(2)).contains(x.userName)) => action
|
||||
case _ => redirect("/signin")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def collaboratorsOnly[T](action: T => Any) = {
|
||||
(form: T) => {
|
||||
context.loginAccount match {
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action(form)
|
||||
case Some(x) if(request.getRequestURI.split("/")(1) == x.userName) => action(form)
|
||||
case Some(x) => {
|
||||
val paths = request.getRequestURI.split("/")
|
||||
if(getCollaborators(paths(1), paths(2)).contains(x.userName)){
|
||||
action(form)
|
||||
} else {
|
||||
redirect("/signin")
|
||||
}
|
||||
/**
|
||||
* Allows only the repository owner and administrators.
|
||||
*/
|
||||
trait ReadableRepositoryAuthenticator { self: ControllerBase with RepositoryService =>
|
||||
|
||||
protected def readableRepository(action: => Any) = { authenticate(action) }
|
||||
protected def readableRepository[T](action: T => Any) = (form: T) => authenticate({action(form)})
|
||||
|
||||
private def authenticate(action: => Any) = {
|
||||
{
|
||||
val paths = request.getRequestURI.split("/")
|
||||
val repository = getRepository(paths(1), paths(2), servletContext)
|
||||
if(repository.get.repository.repositoryType == RepositoryService.Public){
|
||||
action
|
||||
} else {
|
||||
context.loginAccount match {
|
||||
case Some(x) if(x.userType == AccountService.Administrator) => action
|
||||
case Some(x) if(paths(1) == x.userName) => action
|
||||
case Some(x) if(getCollaborators(paths(1), paths(2)).contains(x.userName)) => action
|
||||
case _ => redirect("/")
|
||||
}
|
||||
case None => redirect("/signin")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user