Composición de Autorizaciones en Ruby usando Walruz
-
Upload
romanandreg -
Category
Technology
-
view
633 -
download
1
Transcript of Composición de Autorizaciones en Ruby usando Walruz
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