src/ldt/ldt/security/__init__.py
changeset 350 c6953232099f
parent 239 352be36c9fd7
child 384 0e410517b311
equal deleted inserted replaced
347:271235724f54 350:c6953232099f
       
     1 from django.conf import settings
       
     2 from django.contrib.contenttypes.models import ContentType
       
     3 from django.contrib.auth.models import User
       
     4 from django.core.signals import request_started 
       
     5 
       
     6 try:
       
     7     from threading import local
       
     8 except ImportError:
       
     9     from django.utils._threading_local import local
       
    10     
       
    11 _thread_locals = local()
       
    12 
       
    13 # The function that protect models is called on the first
       
    14 # HTTP request sent to the server (see function protect_models_request
       
    15 # in this file), and can not be called in this file directly 
       
    16 # because of circular import.
       
    17 #
       
    18 # To protect models from command line, use set_current_user(my_user)
       
    19 # and protect_models().
       
    20 
       
    21 _models_are_protected = False
       
    22 
       
    23 def get_current_user():
       
    24     return getattr(_thread_locals, 'user', None)
       
    25 
       
    26 def set_current_user(user):
       
    27     _thread_locals.user = user
       
    28     
       
    29 def del_current_user():
       
    30     del _thread_locals.user
       
    31     
       
    32 def get_anonymous_user():
       
    33     if hasattr(get_anonymous_user, 'anonymous_user'):
       
    34         return get_anonymous_user.anonymous_user
       
    35     
       
    36     get_anonymous_user.anonymous_user = User.objects.get(id=settings.ANONYMOUS_USER_ID)
       
    37     return get_anonymous_user.anonymous_user 
       
    38 
       
    39 def protect_models():
       
    40     cls_list = get_models_to_protect()
       
    41     if cls_list:
       
    42         for cls in get_models_to_protect():
       
    43                 protect_model(cls)
       
    44     
       
    45     _models_are_protected = True   
       
    46     
       
    47 def unprotect_models():
       
    48     for cls in get_models_to_protect():
       
    49             unprotect_model(cls)
       
    50             
       
    51     _models_are_protected = False
       
    52 
       
    53 def get_models_to_protect():
       
    54     if hasattr(get_models_to_protect, 'cls_list'):
       
    55         return get_models_to_protect.cls_list
       
    56         
       
    57     cls_list = []
       
    58     for cls_name in settings.USE_GROUP_PERMISSIONS:
       
    59         cls_type = ContentType.objects.get(model=cls_name.lower())
       
    60         cls_list.append(cls_type.model_class())
       
    61     get_models_to_protect.cls_list = cls_list
       
    62         
       
    63     return cls_list
       
    64 
       
    65 def protect_model(cls):  
       
    66     
       
    67     cls.old_save = cls.save
       
    68     cls.old_delete = cls.delete
       
    69     class_name = cls.__name__.lower()
       
    70     cls.save = change_security(class_name)(cls.save)
       
    71     cls.delete = change_security(class_name)(cls.delete)    
       
    72     
       
    73 def unprotect_model(cls): 
       
    74     if hasattr(cls, 'old_save'):
       
    75         cls.save = cls.old_save 
       
    76         cls.delete = cls.old_delete 
       
    77         del cls.old_save    
       
    78         del cls.old_delete
       
    79         cls.safe_objects.user = None 
       
    80         cls.safe_objects.check_perm = False
       
    81         
       
    82 def change_security(cls_name):
       
    83     def wrapper(func):
       
    84         def wrapped(self, *args, **kwargs):  
       
    85                         
       
    86             if self.pk and not get_current_user().has_perm('change_%s' % cls_name, self):
       
    87                 raise AttributeError('User %s is not allowed to change object %s' % (get_current_user(), self))
       
    88       
       
    89             return func(self, *args, **kwargs)
       
    90         return wrapped    
       
    91     return wrapper
       
    92 
       
    93 
       
    94 def protect_models_request(sender, **kwargs):
       
    95     if not _models_are_protected:
       
    96         protect_models()
       
    97 
       
    98 request_started.connect(protect_models_request)
       
    99