"""entity classes user and group entities:organization: Logilab:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"fromlogilab.common.decoratorsimportcachedfromcubicwebimportUnauthorizedfromcubicweb.entitiesimportAnyEntity,fetch_configclassCWGroup(AnyEntity):id='CWGroup'fetch_attrs,fetch_order=fetch_config(['name'])fetch_unrelated_order=fetch_orderdefdb_key_name(self):"""XXX goa specific"""returnself.get('name')classCWUser(AnyEntity):id='CWUser'fetch_attrs,fetch_order=fetch_config(['login','firstname','surname'])fetch_unrelated_order=fetch_order# used by repository to check if the user can log in or notAUTHENTICABLE_STATES=('activated',)# low level utilities #####################################################def__init__(self,*args,**kwargs):groups=kwargs.pop('groups',None)properties=kwargs.pop('properties',None)super(CWUser,self).__init__(*args,**kwargs)ifgroupsisnotNone:self._groups=groupsifpropertiesisnotNone:self._properties=properties@propertydefgroups(self):try:returnself._groupsexceptAttributeError:self._groups=set(g.nameforginself.in_group)returnself._groups@propertydefproperties(self):try:returnself._propertiesexceptAttributeError:self._properties=dict((p.pkey,p.value)forpinself.reverse_for_user)returnself._propertiesdefproperty_value(self,key):try:# properties stored on the user aren't correctly typed# (e.g. all values are unicode string)returnself.vreg.typed_value(key,self.properties[key])exceptKeyError:passexceptValueError:self.warning('incorrect value for eproperty %s of user %s',key,self.login)returnself.vreg.property_value(key)defmatching_groups(self,groups):"""return the number of the given group(s) in which the user is :type groups: str or iterable(str) :param groups: a group name or an iterable on group names """ifisinstance(groups,basestring):groups=frozenset((groups,))elifisinstance(groups,(tuple,list)):groups=frozenset(groups)returnlen(groups&self.groups)defis_in_group(self,group):"""convience / shortcut method to test if the user belongs to `group` """returnself.matching_groups(group)==1defis_anonymous(self):""" checks if user is an anonymous user"""#FIXME on the web-side anonymous user is detected according# to config['anonymous-user'], we don't have this info on# the server side.returnself.groups==frozenset(('guests',))defowns(self,eid):ifhasattr(self.req,'unsafe_execute'):# use unsafe_execute on the repository side, in case# session's user doesn't have access to CWUserexecute=self.req.unsafe_executeelse:execute=self.req.executetry:returnexecute('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',{'x':eid,'u':self.eid},'x')exceptUnauthorized:returnFalseowns=cached(owns,keyarg=1)defhas_permission(self,pname,contexteid=None):rql='Any P WHERE P is CWPermission, U eid %(u)s, U in_group G, '\'P name %(pname)s, P require_group G'kwargs={'pname':pname,'u':self.eid}cachekey=NoneifcontexteidisnotNone:rql+=', X require_permission P, X eid %(x)s'kwargs['x']=contexteidcachekey='x'try:returnself.req.execute(rql,kwargs,cachekey)exceptUnauthorized:returnFalse# presentation utilities ##################################################defname(self):"""construct a name using firstname / surname or login if not defined"""ifself.firstnameandself.surname:returnself.req._('%(firstname)s%(surname)s')%{'firstname':self.firstname,'surname':self.surname}ifself.firstname:returnself.firstnamereturnself.logindefdc_title(self):returnself.logindc_long_title=namedefdb_key_name(self):"""XXX goa specific"""returnself.get('login')fromlogilab.common.deprecationimportclass_renamedEUser=class_renamed('EUser',CWUser)EGroup=class_renamed('EGroup',CWGroup)