# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more# details.## You should have received a copy of the GNU Lesser General Public License along# with CubicWeb. If not, see <http://www.gnu.org/licenses/>."""entity classes user and group entities"""__docformat__="restructuredtext en"fromlogilab.common.decoratorsimportcachedfromcubicwebimportUnauthorizedfromcubicweb.entitiesimportAnyEntity,fetch_configclassCWGroup(AnyEntity):__regid__='CWGroup'fetch_attrs,fetch_order=fetch_config(['name'])fetch_unrelated_order=fetch_orderdefgrant_permission(self,entity,pname,plabel=None):"""grant local `pname` permission on `entity` to this group using :class:`CWPermission`. If a similar permission already exists, add the group to it, else create a new one. """ifnotself._cw.execute('SET X require_group G WHERE E eid %(e)s, G eid %(g)s, ''E require_permission X, X name %(name)s, X label %(label)s',{'e':entity.eid,'g':self.eid,'name':pname,'label':plabel}):self._cw.create_entity('CWPermission',name=pname,label=plabel,require_group=self,reverse_require_permission=entity)classCWUser(AnyEntity):__regid__='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._cw.vreg.typed_value(key,self.properties[key])exceptKeyError:passexceptValueError:self.warning('incorrect value for eproperty %s of user %s',key,self.login)returnself._cw.vreg.property_value(key)defset_property(self,pkey,value):value=unicode(value)try:prop=self._cw.execute('CWProperty X WHERE X pkey %(k)s, X for_user U, U eid %(u)s',{'k':pkey,'u':self.eid}).get_entity(0,0)except:kwargs=dict(pkey=unicode(pkey),value=value)ifself.is_in_group('managers'):kwargs['for_user']=selfself._cw.create_entity('CWProperty',**kwargs)else:prop.set_attributes(value=value)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)# XXX return the resulting set instead of its sizedefis_in_group(self,group):"""convience / shortcut method to test if the user belongs to `group` """returngroupinself.groupsdefis_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):try:returnself._cw.execute('Any X WHERE X eid %(x)s, X owned_by U, U eid %(u)s',{'x':eid,'u':self.eid})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}ifcontexteidisnotNone:rql+=', X require_permission P, X eid %(x)s'kwargs['x']=contexteidtry:returnself._cw.execute(rql,kwargs)exceptUnauthorized:returnFalse# presentation utilities ##################################################defname(self):"""construct a name using firstname / surname or login if not defined"""ifself.firstnameandself.surname:returnself._cw._('%(firstname)s%(surname)s')%{'firstname':self.firstname,'surname':self.surname}ifself.firstname:returnself.firstnamereturnself.logindefdc_title(self):returnself.logindc_long_title=namefromlogilab.common.deprecationimportclass_renamedEUser=class_renamed('EUser',CWUser)EGroup=class_renamed('EGroup',CWGroup)