<s> import logging <EOL> from django . conf import settings <EOL> from django . contrib . auth . models import Group <EOL> from django . http import Http404 <EOL> from django_auth_ldap . backend import LDAPBackend <EOL> from guardian . shortcuts import get_groups_with_perms , get_users_with_perms , remove_perm <EOL> from rest_framework import viewsets <EOL> from rest_framework . serializers import ListField , SlugRelatedField , ValidationError <EOL> from stackdio . api . users . models import get_user_queryset <EOL> from . shortcuts import get_groups_with_model_perms , get_users_with_model_perms <EOL> from . import fields , serializers <EOL> logger = logging . getLogger ( __name__ ) <EOL> def _filter_perms ( available_perms , perms ) : <EOL> ret = [ ] <EOL> for perm in perms : <EOL> if perm in available_perms : <EOL> ret . append ( perm ) <EOL> return ret <EOL> class UserSlugRelatedField ( SlugRelatedField ) : <EOL> def to_internal_value ( self , data ) : <EOL> try : <EOL> return super ( UserSlugRelatedField , self ) . to_internal_value ( data ) <EOL> except ValidationError : <EOL> if settings . LDAP_ENABLED : <EOL> user = LDAPBackend ( ) . populate_user ( data ) <EOL> if user is not None : <EOL> return super ( UserSlugRelatedField , self ) . to_internal_value ( data ) <EOL> raise <EOL> class StackdioBasePermissionsViewSet ( viewsets . ModelViewSet ) : <EOL> """<STR_LIT>""" <EOL> user_or_group = None <EOL> model_or_object = None <EOL> lookup_value_regex = r'<STR_LIT>' <EOL> parent_lookup_field = '<STR_LIT>' <EOL> parent_lookup_url_kwarg = None <EOL> def get_model_name ( self ) : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> def get_app_label ( self ) : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> def get_serializer_class ( self ) : <EOL> user_or_group = self . get_user_or_group ( ) <EOL> model_or_object = self . get_model_or_object ( ) <EOL> model_name = self . get_model_name ( ) <EOL> app_label = self . get_app_label ( ) <EOL> super_cls = self . switch_model_object ( serializers . StackdioModelPermissionsSerializer , <EOL> serializers . StackdioObjectPermissionsSerializer ) <EOL> url_field_kwargs = { <EOL> '<STR_LIT>' : '<STR_LIT>' . format ( <EOL> app_label , <EOL> model_name , <EOL> model_or_object , <EOL> user_or_group <EOL> ) , <EOL> '<STR_LIT>' : self . lookup_field , <EOL> '<STR_LIT>' : self . lookup_url_kwarg or self . lookup_field , <EOL> '<STR_LIT>' : self . parent_lookup_field , <EOL> '<STR_LIT>' : self . parent_lookup_url_kwarg or self . parent_lookup_field , <EOL> } <EOL> url_field = self . switch_model_object ( <EOL> fields . HyperlinkedModelPermissionsField ( ** url_field_kwargs ) , <EOL> fields . HyperlinkedObjectPermissionsField ( ** url_field_kwargs ) , <EOL> ) <EOL> class StackdioUserPermissionsSerializer ( super_cls ) : <EOL> user = UserSlugRelatedField ( slug_field = '<STR_LIT:username>' , queryset = get_user_queryset ( ) ) <EOL> url = url_field <EOL> permissions = ListField ( ) <EOL> class StackdioGroupPermissionsSerializer ( super_cls ) : <EOL> group = SlugRelatedField ( slug_field = '<STR_LIT:name>' , queryset = Group . objects . all ( ) ) <EOL> url = url_field <EOL> permissions = ListField ( ) <EOL> return self . switch_user_group ( StackdioUserPermissionsSerializer , <EOL> StackdioGroupPermissionsSerializer ) <EOL> def get_user_or_group ( self ) : <EOL> assert self . user_or_group in ( '<STR_LIT:user>' , '<STR_LIT>' ) , ( <EOL> "<STR_LIT>" <EOL> % self . __class__ . __name__ <EOL> ) <EOL> return self . user_or_group <EOL> def switch_user_group ( self , if_user , if_group ) : <EOL> return { <EOL> '<STR_LIT:user>' : if_user , <EOL> '<STR_LIT>' : if_group , <EOL> } . get ( self . get_user_or_group ( ) ) <EOL> def get_model_or_object ( self ) : <EOL> assert self . model_or_object in ( '<STR_LIT>' , '<STR_LIT:object>' ) , ( <EOL> "<STR_LIT>" <EOL> % self . __class__ . __name__ <EOL> ) <EOL> return self . model_or_object <EOL> def switch_model_object ( self , if_model , if_object ) : <EOL> return { <EOL> '<STR_LIT>' : if_model , <EOL> '<STR_LIT:object>' : if_object , <EOL> } . get ( self . get_model_or_object ( ) ) <EOL> def _transform_perm ( self , model_name ) : <EOL> def do_tranform ( item ) : <EOL> perm , sep , empty = item . partition ( '<STR_LIT:_>' + model_name ) <EOL> return perm <EOL> return do_tranform <EOL> def get_object ( self ) : <EOL> queryset = self . get_queryset ( ) <EOL> url_kwarg = self . lookup_url_kwarg or self . lookup_field <EOL> name_attr = self . switch_user_group ( '<STR_LIT:username>' , '<STR_LIT:name>' ) <EOL> for obj in queryset : <EOL> auth_obj = obj [ self . get_user_or_group ( ) ] <EOL> if self . kwargs [ url_kwarg ] == getattr ( auth_obj , name_attr ) : <EOL> return obj <EOL> raise Http404 ( '<STR_LIT>' % self . kwargs [ url_kwarg ] ) <EOL> class StackdioModelPermissionsViewSet ( StackdioBasePermissionsViewSet ) : <EOL> model_cls = None <EOL> model_or_object = '<STR_LIT>' <EOL> def get_model_cls ( self ) : <EOL> assert self . model_cls , ( <EOL> "<STR_LIT>" <EOL> % self . __class__ . __name__ <EOL> ) <EOL> return self . model_cls <EOL> def get_model_name ( self ) : <EOL> return self . get_model_cls ( ) . _meta . model_name <EOL> def get_app_label ( self ) : <EOL> ret = self . get_model_cls ( ) . _meta . app_label <EOL> if ret == '<STR_LIT>' : <EOL> return '<STR_LIT>' <EOL> return ret <EOL> def get_model_permissions ( self ) : <EOL> return getattr ( self . get_model_cls ( ) , <EOL> '<STR_LIT>' , <EOL> getattr ( self , '<STR_LIT>' , ( ) ) ) <EOL> def get_queryset ( self ) : <EOL> model_cls = self . get_model_cls ( ) <EOL> model_name = model_cls . _meta . model_name <EOL> model_perms = self . get_model_permissions ( ) <EOL> perm_map = self . switch_user_group ( <EOL> get_users_with_model_perms ( model_cls , attach_perms = True , with_group_users = False ) , <EOL> get_groups_with_model_perms ( model_cls , attach_perms = True ) , <EOL> ) <EOL> ret = [ ] <EOL> sorted_perms = sorted ( perm_map . items ( ) , key = lambda x : getattr ( x [ <NUM_LIT:0> ] , self . lookup_field ) ) <EOL> for auth_obj , perms in sorted_perms : <EOL> new_perms = map ( self . _transform_perm ( model_name ) , perms ) <EOL> ret . append ( { <EOL> self . get_user_or_group ( ) : auth_obj , <EOL> '<STR_LIT>' : _filter_perms ( model_perms , new_perms ) , <EOL> } ) <EOL> return ret <EOL> def list ( self , request , * args , ** kwargs ) : <EOL> response = super ( StackdioModelPermissionsViewSet , self ) . list ( request , * args , ** kwargs ) <EOL> response . data [ '<STR_LIT>' ] = sorted ( self . get_model_permissions ( ) ) <EOL> return response <EOL> def perform_create ( self , serializer ) : <EOL> serializer . save ( model_cls = self . get_model_cls ( ) ) <EOL> def perform_update ( self , serializer ) : <EOL> serializer . save ( model_cls = self . get_model_cls ( ) ) <EOL> def perform_destroy ( self , instance ) : <EOL> model_cls = self . get_model_cls ( ) <EOL> app_label = model_cls . _meta . app_label <EOL> model_name = model_cls . _meta . model_name <EOL> for perm in instance [ '<STR_LIT>' ] : <EOL> remove_perm ( '<STR_LIT>' % ( app_label , perm , model_name ) , <EOL> instance [ self . get_user_or_group ( ) ] ) <EOL> class StackdioModelUserPermissionsViewSet ( StackdioModelPermissionsViewSet ) : <EOL> user_or_group = '<STR_LIT:user>' <EOL> lookup_field = '<STR_LIT:username>' <EOL> lookup_url_kwarg = '<STR_LIT:username>' <EOL> class StackdioModelGroupPermissionsViewSet ( StackdioModelPermissionsViewSet ) : <EOL> user_or_group = '<STR_LIT>' <EOL> lookup_field = '<STR_LIT:name>' <EOL> lookup_url_kwarg = '<STR_LIT>' <EOL> class StackdioObjectPermissionsViewSet ( StackdioBasePermissionsViewSet ) : <EOL> """<STR_LIT>""" <EOL> model_or_object = '<STR_LIT:object>' <EOL> def get_permissioned_object ( self ) : <EOL> raise NotImplementedError ( '<STR_LIT>' ) <EOL> def get_model_name ( self ) : <EOL> return self . get_permissioned_object ( ) . _meta . model_name <EOL> def get_app_label ( self ) : <EOL> ret = self . get_permissioned_object ( ) . _meta . app_label <EOL> if ret == '<STR_LIT>' : <EOL> return '<STR_LIT>' <EOL> return ret <EOL> def get_object_permissions ( self ) : <EOL> return getattr ( self . get_permissioned_object ( ) , <EOL> '<STR_LIT>' , <EOL> getattr ( self , '<STR_LIT>' , ( ) ) ) <EOL> def get_queryset ( self ) : <EOL> obj = self . get_permissioned_object ( ) <EOL> model_name = obj . _meta . model_name <EOL> object_perms = self . get_object_permissions ( ) <EOL> perm_map = self . switch_user_group ( <EOL> get_users_with_perms ( obj , attach_perms = True , <EOL> with_superusers = False , with_group_users = False ) , <EOL> get_groups_with_perms ( obj , attach_perms = True ) , <EOL> ) <EOL> ret = [ ] <EOL> sorted_perms = sorted ( perm_map . items ( ) , key = lambda x : getattr ( x [ <NUM_LIT:0> ] , self . lookup_field ) ) <EOL> for auth_obj , perms in sorted_perms : <EOL> new_perms = map ( self . _transform_perm ( model_name ) , perms ) <EOL> ret . append ( { <EOL> self . get_user_or_group ( ) : auth_obj , <EOL> '<STR_LIT>' : _filter_perms ( object_perms , new_perms ) , <EOL> } ) <EOL> return ret <EOL> def list ( self , request , * args , ** kwargs ) : <EOL> response = super ( StackdioObjectPermissionsViewSet , self ) . list ( request , * args , ** kwargs ) <EOL> response . data [ '<STR_LIT>' ] = sorted ( self . get_object_permissions ( ) ) <EOL> return response <EOL> def perform_create ( self , serializer ) : <EOL> serializer . save ( object = self . get_permissioned_object ( ) ) <EOL> def perform_update ( self , serializer ) : <EOL> serializer . save ( object = self . get_permissioned_object ( ) ) <EOL> def perform_destroy ( self , instance ) : <EOL> obj = self . get_permissioned_object ( ) <EOL> app_label = obj . _meta . app_label <EOL> model_name = obj . _meta . model_name <EOL> for perm in instance [ '<STR_LIT>' ] : <EOL> remove_perm ( '<STR_LIT>' % ( app_label , perm , model_name ) , <EOL> instance [ self . get_user_or_group ( ) ] , <EOL> obj ) <EOL> class StackdioObjectUserPermissionsViewSet ( StackdioObjectPermissionsViewSet ) : <EOL> user_or_group = '<STR_LIT:user>' <EOL> lookup_field = '<STR_LIT:username>' <EOL> lookup_url_kwarg = '<STR_LIT:username>' <EOL> class StackdioObjectGroupPermissionsViewSet ( StackdioObjectPermissionsViewSet ) : <EOL> user_or_group = '<STR_LIT>' <EOL> lookup_field = '<STR_LIT:name>' <EOL> lookup_url_kwarg = '<STR_LIT>' </s>
