entities/authobjs.py
changeset 0 b97547f5f1fa
child 583 d0c6f5efb837
child 590 bbf6d47a2e9b
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 from logilab.common.decorators import cached
       
     2 
       
     3 from cubicweb import Unauthorized
       
     4 from cubicweb.entities import AnyEntity, fetch_config
       
     5 
       
     6 class EGroup(AnyEntity):
       
     7     id = 'EGroup'
       
     8     fetch_attrs, fetch_order = fetch_config(['name'])
       
     9     __rtags__ = dict(in_group='create')
       
    10 
       
    11     def db_key_name(self):
       
    12         """XXX goa specific"""
       
    13         return self.get('name')
       
    14 
       
    15     
       
    16 class EUser(AnyEntity):
       
    17     id = 'EUser'
       
    18     fetch_attrs, fetch_order = fetch_config(['login', 'firstname', 'surname'])
       
    19     
       
    20     __rtags__ = { 'firstname'  : 'secondary',
       
    21                   'surname'    : 'secondary',
       
    22                   'last_login_time' : 'generated',
       
    23                   'todo_by'    : 'create',
       
    24                   'use_email'  : 'inlineview', # 'primary',
       
    25                   'in_state'   : 'primary', 
       
    26                   'in_group'   : 'primary', 
       
    27                   ('owned_by', '*', 'object') : ('generated', 'link'),
       
    28                   ('created_by','*','object') : ('generated', 'link'),
       
    29                   }
       
    30     
       
    31     # used by repository to check if  the user can log in or not
       
    32     AUTHENTICABLE_STATES = ('activated',)
       
    33 
       
    34     # low level utilities #####################################################
       
    35     def __init__(self, *args, **kwargs):
       
    36         groups = kwargs.pop('groups', None)
       
    37         properties = kwargs.pop('properties', None)
       
    38         super(EUser, self).__init__(*args, **kwargs)
       
    39         if groups is not None:
       
    40             self._groups = groups
       
    41         if properties is not None:
       
    42             self._properties = properties
       
    43             
       
    44     @property
       
    45     def groups(self):
       
    46         try:
       
    47             return self._groups
       
    48         except AttributeError:
       
    49             self._groups = set(g.name for g in self.in_group)
       
    50             return self._groups
       
    51         
       
    52     @property
       
    53     def properties(self):
       
    54         try:
       
    55             return self._properties
       
    56         except AttributeError:
       
    57             self._properties = dict((p.pkey, p.value) for p in self.reverse_for_user)
       
    58             return self._properties
       
    59 
       
    60     def property_value(self, key):
       
    61         try:
       
    62             # properties stored on the user aren't correctly typed
       
    63             # (e.g. all values are unicode string)
       
    64             return self.vreg.typed_value(key, self.properties[key])
       
    65         except KeyError:
       
    66             pass
       
    67         except ValueError:
       
    68             self.warning('incorrect value for eproperty %s of user %s', key, self.login)
       
    69         return self.vreg.property_value(key)
       
    70     
       
    71     def matching_groups(self, groups):
       
    72         """return the number of the given group(s) in which the user is
       
    73 
       
    74         :type groups: str or iterable(str)
       
    75         :param groups: a group name or an iterable on group names
       
    76         """
       
    77         if isinstance(groups, basestring):
       
    78             groups = frozenset((groups,))
       
    79         elif isinstance(groups, (tuple, list)):
       
    80             groups = frozenset(groups)
       
    81         return len(groups & self.groups)
       
    82 
       
    83     def is_in_group(self, group):
       
    84         """convience / shortcut method to test if the user belongs to `group`
       
    85         """
       
    86         return self.matching_groups(group) == 1
       
    87 
       
    88     def owns(self, eid):
       
    89         if hasattr(self.req, 'unsafe_execute'):
       
    90             # use unsafe_execute on the repository side, in case
       
    91             # session's user doesn't have access to EUser
       
    92             execute = self.req.unsafe_execute
       
    93         else:
       
    94             execute = self.req.execute
       
    95         try:
       
    96             return execute('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',
       
    97                            {'x': eid, 'u': self.eid}, 'x')
       
    98         except Unauthorized:
       
    99             return False
       
   100     owns = cached(owns, keyarg=1)
       
   101 
       
   102     def has_permission(self, pname, contexteid=None):
       
   103         rql = 'Any P WHERE P is EPermission, U eid %(u)s, U in_group G, '\
       
   104               'P name %(pname)s, P require_group G'
       
   105         kwargs = {'pname': pname, 'u': self.eid}
       
   106         cachekey = None
       
   107         if contexteid is not None:
       
   108             rql += ', X require_permission P, X eid %(x)s'
       
   109             kwargs['x'] = contexteid
       
   110             cachekey = 'x'
       
   111         try:
       
   112             return self.req.execute(rql, kwargs, cachekey)
       
   113         except Unauthorized:
       
   114             return False
       
   115     
       
   116     # presentation utilities ##################################################
       
   117     
       
   118     def name(self):
       
   119         """construct a name using firstname / surname or login if not defined"""
       
   120         
       
   121         if self.firstname and self.surname:
       
   122             return self.req._('%(firstname)s %(surname)s') % {
       
   123                 'firstname': self.firstname, 'surname' : self.surname}
       
   124         if self.firstname:
       
   125             return self.firstname
       
   126         return self.login
       
   127 
       
   128     def dc_title(self):
       
   129         return self.login
       
   130 
       
   131     dc_long_title = name
       
   132 
       
   133     def db_key_name(self):
       
   134         """XXX goa specific"""
       
   135         return self.get('login')
       
   136 
       
   137 from logilab.common.deprecation import class_renamed
       
   138 Euser = class_renamed('Euser', EUser)
       
   139 Euser.id = 'Euser'