[repo] Use a connection instead of a session in Repository.properties()
# copyright 2003-2012 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,cw_fetch_order=fetch_config(['name'])cw_fetch_unrelated_order=cw_fetch_orderdefdc_long_title(self):name=self.nametrname=self._cw._(name)iftrname!=name:return'%s (%s)'%(name,trname)returnname@cacheddefnum_users(self):"""return the number of users in this group"""returnself._cw.execute('Any COUNT(U) WHERE U in_group G, G eid %(g)s',{'g':self.eid})[0][0]classCWUser(AnyEntity):__regid__='CWUser'fetch_attrs,cw_fetch_order=fetch_config(['login','firstname','surname'])cw_fetch_unrelated_order=cw_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._propertiesdefprefered_language(self,language=None):"""return language used by this user, if explicitly defined (eg not using http negociation) """language=languageorself.property_value('ui.language')vreg=self._cw.vregtry:vreg.config.translations[language]exceptKeyError:language=vreg.property_value('ui.language')assertlanguageinvreg.config.translations[language],languagereturnlanguagedefproperty_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)exceptException:kwargs=dict(pkey=unicode(pkey),value=value)ifself.is_in_group('managers'):kwargs['for_user']=selfself._cw.create_entity('CWProperty',**kwargs)else:prop.cw_set(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)# 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=namedef__call__(self,*args,**kwargs):"""ugly hack for compatibility betweeb dbapi and repo api In the dbapi, Connection and Session have a ``user`` method to generated a user for a request In the repo api, Connection and Session have a user attribute inherited from SessionRequestBase prototype. This ugly hack allows to not break user of the user method. XXX Deprecate me ASAP"""returnselffromlogilab.common.deprecationimportclass_renamedEUser=class_renamed('EUser',CWUser)EGroup=class_renamed('EGroup',CWGroup)