importdatetimeimportloggingimportwarningsfromzope.interfaceimportimplementerfrompyramid.settingsimportasboolfrompyramid.authorizationimportACLAuthorizationPolicyfrompyramid_cubicweb.coreimportget_principalsfrompyramid_multiauthimportMultiAuthenticationPolicyfrompyramid.authenticationimportAuthTktAuthenticationPolicyfrompyramid.interfacesimportIAuthenticationPolicylog=logging.getLogger(__name__)@implementer(IAuthenticationPolicy)classUpdateLoginTimeAuthenticationPolicy(object):"""An authentication policy that update the user last_login_time. The update is done in the 'remember' method, which is called by the login views login, Usually used via :func:`includeme`. """defauthenticated_userid(self,request):passdefeffective_principals(self,request):return()defremember(self,request,principal,**kw):try:repo=request.registry['cubicweb.repository']withrepo.internal_cnx()ascnx:cnx.execute("SET U last_login_time %(now)s WHERE U eid %(user)s",{'now':datetime.datetime.now(),'user':principal})cnx.commit()except:log.exception("Failed to update last_login_time")return()defforget(self,request):return()classCWAuthTktAuthenticationPolicy(AuthTktAuthenticationPolicy):""" An authentication policy that inhibate the call the 'remember' if a 'persistent' argument is passed to it, and is equal to the value that was passed to the constructor. This allow to combine two policies with different settings and select them by just setting this argument. """def__init__(self,secret,persistent,defaults={},prefix='',**settings):self.persistent=persistentunset=object()kw={}# load string settingsfornamein('cookie_name','path','domain','hashalg'):value=settings.get(prefix+name,defaults.get(name,unset))ifvalueisnotunset:kw[name]=value# load boolean settingsfornamein('secure','include_ip','http_only','wild_domain','parent_domain','debug'):value=settings.get(prefix+name,defaults.get(name,unset))ifvalueisnotunset:kw[name]=asbool(value)# load int settingsfornamein('timeout','reissue_time','max_age'):value=settings.get(prefix+name,defaults.get(name,unset))ifvalueisnotunset:kw[name]=int(value)super(CWAuthTktAuthenticationPolicy,self).__init__(secret,**kw)defremember(self,request,principals,**kw):if'persistent'notinkworkw.pop('persistent')==self.persistent:returnsuper(CWAuthTktAuthenticationPolicy,self).remember(request,principals,**kw)else:return()defincludeme(config):""" Activate the CubicWeb AuthTkt authentication policy. Usually called via ``config.include('pyramid_cubicweb.auth')``. See also :ref:`defaults_module` """settings=config.registry.settingspolicies=[]ifasbool(settings.get('cubicweb.auth.update_login_time',True)):policies.append(UpdateLoginTimeAuthenticationPolicy())ifasbool(settings.get('cubicweb.auth.authtkt',True)):session_prefix='cubicweb.auth.authtkt.session.'persistent_prefix='cubicweb.auth.authtkt.persistent.'try:secret=config.registry['cubicweb.config']['pyramid-auth-secret']warnings.warn("pyramid-auth-secret from all-in-one is now ""cubicweb.auth.authtkt.[session|persistent].secret",DeprecationWarning)except:secret='notsosecret'session_secret=settings.get(session_prefix+'secret',secret)persistent_secret=settings.get(persistent_prefix+'secret',secret)if'notsosecret'in(session_secret,persistent_secret):warnings.warn(''' !! SECURITY WARNING !! The authentication cookies are signed with a static secret key. Configure the following options in your pyramid.ini file: - cubicweb.auth.authtkt.session.secret - cubicweb.auth.authtkt.persistent.secret YOU SHOULD STOP THIS INSTANCE unless your really know what you are doing !! ''')policies.append(CWAuthTktAuthenticationPolicy(session_secret,False,defaults={'hashalg':'sha512','cookie_name':'auth_tkt','timeout':1200,'reissue_time':120,'http_only':True,'secure':True},prefix=session_prefix,**settings))policies.append(CWAuthTktAuthenticationPolicy(persistent_secret,True,defaults={'hashalg':'sha512','cookie_name':'pauth_tkt','max_age':3600*24*30,'reissue_time':3600*24,'http_only':True,'secure':True},prefix=persistent_prefix,**settings))kw={}ifasbool(settings.get('cubicweb.auth.groups_principals',True)):kw['callback']=get_principalsauthpolicy=MultiAuthenticationPolicy(policies,**kw)config.registry['cubicweb.authpolicy']=authpolicyconfig.set_authentication_policy(authpolicy)config.set_authorization_policy(ACLAuthorizationPolicy())