diff --git a/src/main/scala/app/AccountController.scala b/src/main/scala/app/AccountController.scala index 0574dc0..16a75c2 100644 --- a/src/main/scala/app/AccountController.scala +++ b/src/main/scala/app/AccountController.scala @@ -1,15 +1,15 @@ package app import service._ -import util.OwnerOnlyAuthenticator +import util.OneselfAuthenticator import util.StringUtil._ import jp.sf.amateras.scalatra.forms._ class AccountController extends AccountControllerBase - with SystemSettingsService with AccountService with RepositoryService with OwnerOnlyAuthenticator + with SystemSettingsService with AccountService with RepositoryService with OneselfAuthenticator trait AccountControllerBase extends ControllerBase { - self: SystemSettingsService with AccountService with RepositoryService with OwnerOnlyAuthenticator => + self: SystemSettingsService with AccountService with RepositoryService with OneselfAuthenticator => case class AccountNewForm(userName: String, password: String,mailAddress: String, url: Option[String]) @@ -38,12 +38,12 @@ } getOrElse NotFound } - get("/:userName/_edit")(ownerOnly { + get("/:userName/_edit")(oneselfOnly { val userName = params("userName") getAccountByUserName(userName).map(x => account.html.edit(Some(x))) getOrElse NotFound }) - post("/:userName/_edit", editForm)(ownerOnly { form => + post("/:userName/_edit", editForm)(oneselfOnly { form => val userName = params("userName") getAccountByUserName(userName).map { account => updateAccount(account.copy( diff --git a/src/main/scala/util/Authenticator.scala b/src/main/scala/util/Authenticator.scala index ebcdf2b..3eed8e6 100644 --- a/src/main/scala/util/Authenticator.scala +++ b/src/main/scala/util/Authenticator.scala @@ -5,8 +5,28 @@ import RepositoryService.RepositoryInfo /** + * Allows only oneself and administrators. + */ +trait OneselfAuthenticator { self: ControllerBase => + protected def oneselfOnly(action: (RepositoryInfo) => Any) = { authenticate(action) } + protected def oneselfOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => { authenticate(action(form, _)) } + + private def authenticate(action: (RepositoryInfo) => Any) = { + { + val paths = request.getRequestURI.substring(request.getContextPath.length).split("/") + context.loginAccount match { + case Some(x) if(x.isAdmin) => action + case Some(x) if(paths(1) == x.userName) => action + case _ => Unauthorized() + } + } + } +} + +/** * Allows only the repository owner and administrators. */ +// TODO rename to OwnerAuthenticator trait OwnerOnlyAuthenticator { self: ControllerBase with RepositoryService => protected def ownerOnly(action: (RepositoryInfo) => Any) = { authenticate(action) } protected def ownerOnly[T](action: (T, RepositoryInfo) => Any) = (form: T) => { authenticate(action(form, _)) } @@ -28,6 +48,7 @@ /** * Allows only signed in users. */ +// TODO rename to UsersAuthenticator trait UsersOnlyAuthenticator { self: ControllerBase => protected def usersOnly(action: => Any) = { authenticate(action) } protected def usersOnly[T](action: T => Any) = (form: T) => { authenticate(action(form)) } @@ -45,6 +66,7 @@ /** * Allows only administrators. */ +// TODO rename to AdminAuthenticator trait AdminOnlyAuthenticator { self: ControllerBase => protected def adminOnly(action: => Any) = { authenticate(action) } protected def adminOnly[T](action: T => Any) = (form: T) => { authenticate(action(form)) }