composición de autorizaciones en ruby usando walruz

24
Composici ´ on de Autorizaciones en Ruby usando Walruz Rom´ an Gonz ´ alez LATAM on Rails November 7, 2010

Upload: romanandreg

Post on 18-Jul-2015

633 views

Category:

Technology


1 download

TRANSCRIPT

Composicion de Autorizaciones en Rubyusando Walruz

Roman Gonzalez

LATAM on Rails

November 7, 2010

Definiciones

→ Autenticacion != Autorizacion

→ Autenticacion: Es el proceso de verificar algo o alguiencomo autentico

→ Autorizacion: Es el proceso de verificar los privilegios deuna entidad

Plugins existentes en Rails

→ Autenticaciondevisewardenacts as authenticated

→ Autorizaciondeclarative authorizationwalruz

Definamos un escenario

c l a s s User < ActiveRecord : : Base# a t t r i b u t e : admin , : b o o l e a nhas many : f r i e n d s h i p shas many : albums

end

c l a s s Friendship < ActiveRecord : : Basebe longs to : f r i e n d , : c lass name => ’ User ’be longs to : befr iend , : c lass name => ’ User ’

end

c l a s s Album < ActiveRecord : : Basebe longs to : owner , : c lass name => ’ User ’

end

AlbumsController

c l a s s AlbumsController < A p p l i c a t i o n C o n t r o l l e rb e f o r e f i l t e r : f i n d u s e r

def show@album = user . albums . f ind ( params [ : id ] )render : a c t i o n => ’ show ’

end

protec ted : f i n d u s e rdef f i n d u s e r

@user = User . f ind ( params [ : u s e r i d ] )end

end

Solo el creador del Album

1 def show2 i f c u r r e n t u s e r == user3 @album = user . albums . f ind ( params [ : id ] )4 render : a c t i o n => ’ show ’5 e l s e6 unauthorized7 end8 end

+ Admin

1 def show2 i f c u r r e n t u s e r . admin? | | c u r r e n t u s e r == user3 @album = user . albums . f ind ( params [ : id ] )4 render : a c t i o n => ’ show ’5 e l s e6 unauthorized7 end8 end

+ Amigos

1 def show2 allowed = c u r r e n t u s e r . admin? | |3 c u r r e n t u s e r == user | |4 user . f r i e n d ? ( c u r r e n t u s e r )5 i f allowed6 @album = user . albums . f ind ( params [ : id ] )7 render : a c t i o n => ’ show ’8 e l s e9 unauthorized

10 end11 end

- Amigos que esten autorizados

1 def show2 @album = user . albums . f ind ( params [ : id ] )3 allowed = c u r r e n t u s e r . admin? | |4 c u r r e n t u s e r == user | |5 ( ( f = user . f r i e n d s h i p w i t h ( c u r r e n t u s e r ) ) &&6 f . a l low to see album ? ( @album ) )7 i f allowed8 render : a c t i o n => ’ show ’9 e l s e

10 unauthorized11 end12 end

+ Verifica que el Album sea publico

1 allowed = album . i s p u b l i c ? | |2 c u r r e n t u s e r . admin? | |3 c u r r e n t u s e r == user | |4 ( ( f = user . f r i e n d s h i p w i t h ( c u r r e n t u s e r ) ) &&5 f . a l low to see album ? ( @album ) )

Observaciones

→ Estamos implementando una logica que puede nopertenecer a un solo controlador (Copy-Paste)

→ Los controladores dejan de ser skinny por tener codigo quese encarga de las autorizaciones

Posibles Soluciones

→ ¿Mover la logica de validacion de autorizaciones alModelo?

→ NO. El codigo estarıa esparcido en distintos modelos,haciendo casi imposible mantener rastro de las distintasautorizaciones que existen en proyectos de mediano a grantamano.

Usando Walruz

1 def show2 @album = user . albums . f ind ( params [ : id ] )3 # a c t o r . can ?( a c t i o n , s u b j e c t )4 i f c u r r e n t u s e r . can ? ( : read , @album )5 render : a c t i o n => ’ show ’6 e l s e7 unauthorized8 end9 end

Removemos toda la logica de autorizacion

→ Los controladores pasan a ser Open For Extension/ClosedFor Modification

→ El codigo sigue siendo legible y claro en sus intenciones

¿Como funciona?

c l a s s User < ActiveRecord : : Baseinclude Walruz : : Actor

end

c l a s s Album < ActiveRecord : : Baseinclude Walruz : : S u b j e c tc h e c k a u t h o r i z a t i o n s

# a c t i o n => p o l i c y: read => P o l i c i e s : : AlbumReadAuthorization

end

¿Que es Policies::AlbumReadAuthorization?

Policies File

# l i b / walruz / p o l i c i e s . rbmodule P o l i c i e s

requi re ” p o l i c i e s /a c t or i s a d mi n ”requi re ” p o l i c i e s /a c t o r i s o w n e r ”requi re ” p o l i c i e s / a c t o r i s f r i e n d ”requi re ” p o l i c i e s /fr iendship al low read albums ”

AlbumReadAuthorization =orP ( ActorIsAdmin ,

ActorIsOwner ,andP ( Actor IsFr iend . f o r s u b j e c t ( : owner ) ,

FriendshipAllowReadAlbums ))

end

ActorIsAdmin

c l a s s ActorIsAdmin < Walruz : : Po l i cy

# c u r r e n t u s e r . can ? ( : r ead , @album )# a c t o r −> c u r r e n t u s e r# s u b j e c t −> @album

def authorized ? ( actor , s u b j e c t )a c t o r . admin?

end

end

ActorIsOwner

c l a s s ActorIsOwner < Walruz : : Po l i cy

# c u r r e n t u s e r . can ? ( : r ead , @album )# a c t o r −> c u r r e n t u s e r# s u b j e c t −> @album

def authorized ? ( actor , s u b j e c t )a c t o r == s u b j e c t . owner

end

end

ActorIsFriend

# A c t o r I s F r i e n d . f o r s u b j e c t ( : owner )

c l a s s ActorIsFr iend < Walruz : : Po l i cy

# c u r r e n t u s e r . can ? ( : r ead , @album )# a c t o r −> c u r r e n t u s e r# s u b j e c t −> @album . owner

def authorized ? ( user , o t h e r u s e r )f r i e n d s h i p = o t h e r u s e r . f r i e n d s h i p w i t h ( user )i f f r i e n d s h i p

[ true , : f r i e n d s h i p => f r i e n d s h i p ]e l s e

f a l s eend

end

end

FriendshipAllowReadAlbum

# andP ( A c t o r I s F r i e n d . f o r s u b j e c t ( : owner ) ,# Fr i endsh ipAl lowReadAlbum )

c l a s s FriendshipAllowReadAlbum < Walruz : : Po l i cy

def authorized ? ( actor , album )params [ : f r i e n d s h i p ] . a l low to see album ? ( album )

end

end

Observaciones

→ Las diferentes polıticas que se implementan se mantienenbien aisladas y simples

→ Mediante la composicion de estas polıticas podemosdefinir facilmente polıticas con mayor complejidad

→ Todo el sistema de seguridad se mantiene en un solo sitioen el proyecto

→ El problema deja de ser, invocar las autorizaciones en elproyecto, y pasa a ser manejar el archivo de polıticasautorizaciones

Desventajas

→ Esto es Ruby, no SQL

→ A medida que las polıticas son mas complejas, mas tiempose va a tomar en ejecutar la verificaciones

→ Las colecciones de objetos no son el mejor caso de uso, peroen el caso de que sea requerido, memcache es tu amigo

→ Por ahora, walruz-rails solo soporta rails 2

¿Preguntas?

¡Gracias!+ Informacion:

Comunidad:http://ruby.org.ve

Twitter:@romanandreg

Proyecto:http://github.com/noomii/walruzhttp://github.com/noomii/walruz-rails