Skip to content

Commit

Permalink
Broke out LifeCycleUser trait
Browse files Browse the repository at this point in the history
  • Loading branch information
eltimn committed Jun 13, 2016
1 parent 446a878 commit 81d23fc
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 91 deletions.
2 changes: 1 addition & 1 deletion project/BuildSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down
110 changes: 55 additions & 55 deletions src/main/scala/net.liftmodules/mongoauth/AuthUser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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()
Expand All @@ -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 =>

Expand Down
69 changes: 39 additions & 30 deletions src/main/scala/net.liftmodules/mongoauth/Locs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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,
Expand All @@ -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",
Expand All @@ -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"))
}
2 changes: 1 addition & 1 deletion src/main/scala/net.liftmodules/mongoauth/MongoAuth.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/net.liftmodules/mongoauth/Permission.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 81d23fc

Please sign in to comment.