Control de acceso.

Aqui se presentara como tener control de acceso con roles y usuarios, esto es con fines academicos.

Se quiere agregar un role a usuario, para saber que permisos tiene, que puede ver del menu, que puede modificar, etc.
Para lograr esto es necesario hacer una relacion de muchos a muchos.
Se necesitan un modelo User, un modelo Role y un modelo UserRole para tener la realacion de muchos a muchos.

Es necesario crear un catalogo de Role(ABC), y el snnipet Role; Puedes ver esto en Cómo hacer un catálogo básico (ABC) en Lift 2.6

Para iniciar hay que abrir el archivo User.scala, esta ubicado en /src/main/scala/code/model.
En la misma carpeta se crearan el archivo Role.scala y UserRole.scal.

Role.scala
package code
package model

import net.liftweb.mapper._
import net.liftweb.util._
import net.liftweb.common._
import net.liftweb.sitemap.Loc._
import net.liftweb.http._
import net.liftweb.http.SHtml._
import net.liftmodules.FoBoBs.mapper._

import net.liftweb.common.Logger
import net.liftweb.mapper.{MappedString, ValidateLength, LongKeyedMetaMapper, LongKeyedMapper, IdPK}


class Role extends LongKeyedMapper[Role] with ManyToMany with IdPK { 
def getSingleton = Role
 
object Role extends Role with LongKeyedMetaMapper[Role] {
override def dbTableName = "roles"

} 
UserRole.scala
package code
package model

import net.liftweb.mapper._
import net.liftweb.util._
import net.liftweb.common._
import net.liftweb.sitemap.Loc._
import net.liftweb.http._
import net.liftweb.http.SHtml._
import net.liftmodules.FoBoBs.mapper._

import net.liftweb.mapper._
import net.liftweb.mapper.{MappedString, ValidateLength, LongKeyedMetaMapper, LongKeyedMapper, IdPK}
 
class UserRole extends LongKeyedMapper[UserRole] with IdPK { 
def getSingleton = UserRole
 
}
 
object UserRole extends UserRole with LongKeyedMetaMapper[UserRole] {
override def dbTableName = "user_roles"

}
Ya estan los tres archivos que se usaran.
En el archivo Role.scala en la linea 16 se puede ver  with ManyToMany, lo cual hace referencia a una relacion de muchos a muchos, es necesario agregar la misma relacion a User.scala, en la linea 37.

User.scala
package code
package model

import net.liftweb.mapper._
import net.liftweb.util._
import net.liftweb.common._
import net.liftweb.sitemap.Loc._
import net.liftweb.http._
import net.liftweb.http.SHtml._
import net.liftmodules.FoBoBs.mapper._

/**
 * The singleton that has methods for accessing the database
 */
object User extends User with MetaMegaProtoUser[User] with BootstrapMegaMetaProtoUser[User]  {
  override def dbTableName = "users" // define the DB table name
  override def screenWrap = Full(
          )
  // define the order fields will appear in forms and output
  override def fieldOrder = List(id, firstName, lastName, email,
  locale, timezone, password, textArea) 
  
  //If you set this to false then comment out the validateUserMenuLoc override bellow
  override def skipEmailValidation = true

  //add a loc group to the user menu
  override def globalUserLocParams: List[LocParam[Unit]] = List(LocGroup("user"))
  
  override def resetPasswordMenuLoc: Box[net.liftweb.sitemap.Menu] = Box(Empty) 
  override def validateUserMenuLoc: Box[net.liftweb.sitemap.Menu] = Box(Empty) 
 
}

/**
 * An O-R mapped "User" class that includes first name, last name, password and we add a "Personal Essay" to it
 */
class User extends MegaProtoUser[User] with ManyToMany{
  def getSingleton = User // what's the "meta" server

  // define an additional field for a personal essay
  object textArea extends MappedTextarea(this, 2048) {
    override def textareaRows  = 10
    override def textareaCols = 50
    override def displayName = "Personal Essay"
  }
}
Ahora User.scala y Role.scala, tienen una relacion de muchos a muchos, pero no entre si. Para esto se usara UserRole.scala.

En UserRole.scala entre las lineas 16 y 18 de , se agregan las siguientes lineas.

object role extends MappedLongForeignKey(this, Role)
 
object user extends MappedLongForeignKey(this, User)

En User.scala abajo de la linea 45  se agrega la siguiente linea

object roles extends MappedManyToMany(UserRole, UserRole.user, UserRole.role, Role)

En Role.scala abajo de la linea 17 se agregan las siguientes lineas

object roleName extends MappedString(this, 50)

object users extends MappedManyToMany(UserRole, UserRole.role, UserRole.user, User)

Ya existe la relacion entre User y Role atraves de UserRol.

 Para saber que rol tiene un usuario se agregara el metodo hasRole() en User.scala y en Role.scala se agregara el metodo getRole().

Primero el metodo hasRole(), bajo la linea 47 en User.scala se agrega lo siguiente.

def hasRole(role : String) : Boolean = {
  val lista = UserRole.findAll(By(UserRole.user, this.id),By(UserRole.role, Role.getRole(role).id.is), PreCache(UserRole.user))
    if(lista.size > 0) true else false
  }

Ahora el metodo getRole(), bajo la linea 19 de Role.scala se agrega lo siguiente.

def getRole(rol: String) : Role = 
  Role.findAll(By(Role.roleName, rol))(0)  

Hasta aqui, ya se pueden obtener los roles de un usuario.

Comentarios

Entradas populares de este blog

Batch File como Servicio de Windows

Cómo crear archivos XML en Java con JAXB

Ejecutando Jetty como un Servicio en Windows Server 2012