From 81d23fc8bc5c608acf8c897aed92c3c4ebf6bf8f Mon Sep 17 00:00:00 2001 From: Tim Nelson Date: Mon, 13 Jun 2016 15:53:01 -0500 Subject: [PATCH] Broke out LifeCycleUser trait --- project/BuildSettings.scala | 2 +- .../net.liftmodules/mongoauth/AuthUser.scala | 110 +++++++++--------- .../net.liftmodules/mongoauth/Locs.scala | 69 ++++++----- .../net.liftmodules/mongoauth/MongoAuth.scala | 2 +- .../mongoauth/Permission.scala | 8 +- 5 files changed, 100 insertions(+), 91 deletions(-) diff --git a/project/BuildSettings.scala b/project/BuildSettings.scala index e56d19c..ddbef37 100644 --- a/project/BuildSettings.scala +++ b/project/BuildSettings.scala @@ -19,7 +19,7 @@ trait BuildSettings { case _ => Seq("2.10.6", "2.11.8") }}, scalacOptions := Seq("-deprecation", "-unchecked", "-feature", "-language:postfixOps", "-language:implicitConversions"), - SbtGit.git.baseVersion in ThisBuild := "0.8", + SbtGit.git.baseVersion in ThisBuild := "1.0", organization in ThisBuild := "net.liftmodules" ) diff --git a/src/main/scala/net.liftmodules/mongoauth/AuthUser.scala b/src/main/scala/net.liftmodules/mongoauth/AuthUser.scala index 42040da..6a04f10 100644 --- a/src/main/scala/net.liftmodules/mongoauth/AuthUser.scala +++ b/src/main/scala/net.liftmodules/mongoauth/AuthUser.scala @@ -17,14 +17,17 @@ import record.field.{PasswordField => _, _} import util.FieldError import util.Helpers -/** - * AuthUser is a base class that gives you a "User" that has roles and permissions. - */ -trait AuthUser { +trait LifeCycleUser { /* * String representing the User ID */ def userIdAsString: String +} + +/** + * AuthUser is a base class that gives you a "User" that has roles and permissions. + */ +trait AuthUser extends LifeCycleUser { /* * A list of this user's permissions @@ -37,47 +40,14 @@ trait AuthUser { def authRoles: Set[String] } -trait AuthUserMeta[UserType <: AuthUser] { - /* - * True when the user request var is defined. - */ - def isLoggedIn: Boolean - /* - * User logged in by supplying password. False if auto logged in by ExtSession or LoginToken. - */ - def isAuthenticated: Boolean - /* - * Current user has the given role - */ - def hasRole(role: String): Boolean - def lacksRole(role: String): Boolean = !hasRole(role) - def hasAnyRoles(roles: Seq[String]) = roles exists (r => hasRole(r.trim)) - - /* - * Current user has the given permission - */ - def hasPermission(permission: Permission): Boolean - def lacksPermission(permission: Permission): Boolean = !hasPermission(permission) - - /* - * Log the current user out - */ - def logUserOut(): Unit - - /* - * Handle a LoginToken. Called from Locs.loginTokenLocParams - */ - def handleLoginToken(): Box[LiftResponse] = Empty -} - /* * Trait that has login related code */ -trait UserLifeCycle[UserType <: AuthUser] { +trait UserLifeCycle[UserType <: LifeCycleUser] { - /* - * Given a String representing the User ID, find the user - */ + /** + * Given a String representing the User ID, find the user + */ def findByStringId(id: String): Box[UserType] // log in/out lifecycle callbacks @@ -97,18 +67,16 @@ trait UserLifeCycle[UserType <: AuthUser] { } def currentUser: Box[UserType] = curUser.get + /** + * True when the user request var is defined. + */ def isLoggedIn: Boolean = currentUserId.isDefined - def isAuthenticated: Boolean = curUserIsAuthenticated.is - def hasRole(role: String): Boolean = currentUser - .map(_.authRoles.exists(_ == role)) - .openOr(false) - - def hasPermission(permission: Permission): Boolean = { - currentUser - .map(u => permission.implies(u.authPermissions)) - .openOr(false) - } + /** + * true if user logged in by supplying password. False if + * auto logged in by ExtSession or LoginToken. + */ + def isAuthenticated: Boolean = curUserIsAuthenticated.is def logUserIn(who: UserType, isAuthed: Boolean = false, isRemember: Boolean = false): Unit = { curUserId.remove() @@ -122,18 +90,50 @@ trait UserLifeCycle[UserType <: AuthUser] { ExtSession.createExtSessionBox(who.userIdAsString) } - def logUserOut() { + /** + * Log the current user out + */ + def logUserOut(): Unit = { onLogOut.foreach(_(currentUser)) curUserId.remove() curUserIsAuthenticated.remove() curUser.remove() S.session.foreach(_.destroySession()) } + + /** + * Handle a LoginToken. Called from Locs.loginTokenLocParams + */ + def handleLoginToken(): Box[LiftResponse] = Empty } -/* - * Mongo version of AuthUser - */ +trait AuthUserMeta[UserType <: AuthUser] extends UserLifeCycle[UserType] { + + /** + * Current user has the given role + */ + def hasRole(role: String): Boolean = currentUser + .map(_.authRoles.exists(_ == role)) + .openOr(false) + + def lacksRole(role: String): Boolean = !hasRole(role) + def hasAnyRoles(roles: Seq[String]) = roles.exists(r => hasRole(r.trim)) + + /* + * Current user has the given permission + */ + def hasPermission(permission: Permission): Boolean = { + currentUser + .map(u => permission.implies(u.authPermissions)) + .openOr(false) + } + + def lacksPermission(permission: Permission): Boolean = !hasPermission(permission) +} + +/** + * Mongo version of AuthUser + */ trait MongoAuthUser[T <: MongoAuthUser[T]] extends MongoRecord[T] with AuthUser { self: T => diff --git a/src/main/scala/net.liftmodules/mongoauth/Locs.scala b/src/main/scala/net.liftmodules/mongoauth/Locs.scala index 1d84fba..a12b54f 100644 --- a/src/main/scala/net.liftmodules/mongoauth/Locs.scala +++ b/src/main/scala/net.liftmodules/mongoauth/Locs.scala @@ -6,14 +6,18 @@ import http.{RedirectResponse, RedirectWithState, S, RedirectState} import sitemap.{Loc, Menu} import sitemap.Loc.{DispatchLocSnippets, EarlyResponse, If} -object Locs extends Locs -trait Locs { - private lazy val userMeta = MongoAuth.authUserMeta.vend +object Locs extends Locs { + protected def userMeta = MongoAuth.authUserMeta.vend +} +trait Locs extends LifeCycleLocs with AuthLocs + +trait LifeCycleLocs { + protected def userMeta: UserLifeCycle[_] - private lazy val indexUrl = MongoAuth.indexUrl.vend - private lazy val loginUrl = MongoAuth.loginUrl.vend - private lazy val logoutUrl = MongoAuth.logoutUrl.vend - private lazy val loginTokenUrl = MongoAuth.loginTokenUrl.vend + protected lazy val indexUrl = MongoAuth.indexUrl.vend + protected lazy val loginUrl = MongoAuth.loginUrl.vend + protected lazy val logoutUrl = MongoAuth.logoutUrl.vend + protected lazy val loginTokenUrl = MongoAuth.loginTokenUrl.vend // redirects def RedirectToLoginWithReferrer = { @@ -24,9 +28,6 @@ trait Locs { def RedirectToIndex = RedirectResponse(indexUrl) def RedirectToIndexWithCookies = RedirectResponse(indexUrl, S.responseCookies:_*) - protected def DisplayError(message: String) = () => - RedirectWithState(indexUrl, RedirectState(() => S.error(S ? message))) - // Loc guards val RequireAuthentication = If( () => userMeta.isAuthenticated, @@ -44,26 +45,6 @@ trait Locs { () => !userMeta.isLoggedIn, () => RedirectToIndex) - def HasRole(role: String) = - If(() => userMeta.hasRole(role), - DisplayError("liftmodule-monogoauth.locs.hasRole")) - - def LacksRole(role: String) = - If(() => userMeta.lacksRole(role), - DisplayError("liftmodule-monogoauth.locs.lacksRole")) - - def HasPermission(permission: Permission) = - If(() => userMeta.hasPermission(permission), - DisplayError("liftmodule-monogoauth.locs.hasPermission")) - - def LacksPermission(permission: Permission) = - If(() => userMeta.lacksPermission(permission), - DisplayError("liftmodule-monogoauth.locs.overQualified")) - - def HasAnyRoles(roles: Seq[String]) = - If(() => userMeta.hasAnyRoles(roles), - DisplayError("liftmodule-monogoauth.locs.wrongRole")) - // Menus def buildLogoutMenu = Menu(Loc( "Logout", @@ -87,3 +68,31 @@ trait Locs { EarlyResponse(() => userMeta.handleLoginToken) :: Nil } + +trait AuthLocs { + protected def userMeta: AuthUserMeta[_] + + protected def DisplayError(message: String) = () => + RedirectWithState(MongoAuth.indexUrl.vend, RedirectState(() => S.error(S ? message))) + + // Loc guards + def HasRole(role: String) = + If(() => userMeta.hasRole(role), + DisplayError("liftmodule-monogoauth.locs.hasRole")) + + def LacksRole(role: String) = + If(() => userMeta.lacksRole(role), + DisplayError("liftmodule-monogoauth.locs.lacksRole")) + + def HasPermission(permission: Permission) = + If(() => userMeta.hasPermission(permission), + DisplayError("liftmodule-monogoauth.locs.hasPermission")) + + def LacksPermission(permission: Permission) = + If(() => userMeta.lacksPermission(permission), + DisplayError("liftmodule-monogoauth.locs.overQualified")) + + def HasAnyRoles(roles: Seq[String]) = + If(() => userMeta.hasAnyRoles(roles), + DisplayError("liftmodule-monogoauth.locs.wrongRole")) +} diff --git a/src/main/scala/net.liftmodules/mongoauth/MongoAuth.scala b/src/main/scala/net.liftmodules/mongoauth/MongoAuth.scala index dd2a49f..d457b20 100644 --- a/src/main/scala/net.liftmodules/mongoauth/MongoAuth.scala +++ b/src/main/scala/net.liftmodules/mongoauth/MongoAuth.scala @@ -40,7 +40,7 @@ object MongoAuth extends Factory { .openOrThrowException("isDefined is called in the guard") }) - // AuthUserMeta object + // AuthUserMeta object, used in Locs val authUserMeta = new FactoryMaker[AuthUserMeta[_]](model.SimpleUser) {} // urls diff --git a/src/main/scala/net.liftmodules/mongoauth/Permission.scala b/src/main/scala/net.liftmodules/mongoauth/Permission.scala index 6c67479..f12614b 100644 --- a/src/main/scala/net.liftmodules/mongoauth/Permission.scala +++ b/src/main/scala/net.liftmodules/mongoauth/Permission.scala @@ -4,10 +4,10 @@ package net.liftmodules.mongoauth * A permission that has three parts; domain, actions, and entities */ case class Permission( - val domain: String, - val actions: Set[String] = Set(Permission.wildcardToken), - val entities: Set[String] = Set(Permission.wildcardToken)) -{ + domain: String, + actions: Set[String] = Set(Permission.wildcardToken), + entities: Set[String] = Set(Permission.wildcardToken) +) { def implies(p: Permission) = p match { case Permission(d, a, e) => if (d == Permission.wildcardToken)