[gen] Changed the way to customize the Config in an app.
This commit is contained in:
parent
88bd5e5bce
commit
8833f7b0ae
|
@ -8,7 +8,7 @@ from appy.px import Px
|
||||||
class OgoneConfig:
|
class OgoneConfig:
|
||||||
'''If you plan, in your app, to perform on-line payments via the Ogone (r)
|
'''If you plan, in your app, to perform on-line payments via the Ogone (r)
|
||||||
system, create an instance of this class in your app and place it in the
|
system, create an instance of this class in your app and place it in the
|
||||||
'ogone' attr of your appy.gen.Config instance.'''
|
'ogone' attr of your appy.gen.Config class.'''
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# self.env refers to the Ogone environment and can be "test" or "prod".
|
# self.env refers to the Ogone environment and can be "test" or "prod".
|
||||||
self.env = 'test'
|
self.env = 'test'
|
||||||
|
@ -103,7 +103,7 @@ class Ogone(Field):
|
||||||
necessary info for making the payment.'''
|
necessary info for making the payment.'''
|
||||||
tool = obj.getTool()
|
tool = obj.getTool()
|
||||||
# Basic Ogone parameters were generated in the app config module.
|
# Basic Ogone parameters were generated in the app config module.
|
||||||
res = obj.getProductConfig().ogone.copy()
|
res = obj.getProductConfig(True).ogone.copy()
|
||||||
shaKey = res['shaInKey']
|
shaKey = res['shaInKey']
|
||||||
# Remove elements from the Ogone config that we must not send in the
|
# Remove elements from the Ogone config that we must not send in the
|
||||||
# payment request.
|
# payment request.
|
||||||
|
@ -139,7 +139,7 @@ class Ogone(Field):
|
||||||
'''Returns True if the SHA-1 signature from Ogone matches retrieved
|
'''Returns True if the SHA-1 signature from Ogone matches retrieved
|
||||||
params.'''
|
params.'''
|
||||||
response = obj.REQUEST.form
|
response = obj.REQUEST.form
|
||||||
shaKey = obj.getProductConfig().ogone['shaOutKey']
|
shaKey = obj.getProductConfig(True).ogone['shaOutKey']
|
||||||
digest = self.createShaDigest(response, shaKey,
|
digest = self.createShaDigest(response, shaKey,
|
||||||
keysToIgnore=self.noShaOutKeys)
|
keysToIgnore=self.noShaOutKeys)
|
||||||
return digest.lower() == response['SHASIGN'].lower()
|
return digest.lower() == response['SHASIGN'].lower()
|
||||||
|
|
|
@ -554,51 +554,63 @@ class Tool(Model):
|
||||||
class User(Model):
|
class User(Model):
|
||||||
'''If you want to extend or modify the User class, subclass me.'''
|
'''If you want to extend or modify the User class, subclass me.'''
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
class LdapConfig:
|
||||||
|
'''Parameters for authenticating users to an external LDAP.'''
|
||||||
|
server = '' # Name of the LDAP server
|
||||||
|
port = None # Port for this server.
|
||||||
|
# Login and password of the technical power user that the Appy application
|
||||||
|
# will use to connect to the LDAP.
|
||||||
|
adminLogin = ''
|
||||||
|
adminPassword = ''
|
||||||
|
# LDAP attribute to use as login for authenticating users.
|
||||||
|
loginAttribute = 'dn' # Can also be "mail", "sAMAccountName", "cn"
|
||||||
|
baseDn = '' # Base distinguished name where to find users in the LDAP.
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
class Config:
|
class Config:
|
||||||
'''If you want to specify some configuration parameters for appy.gen and
|
'''If you want to specify some configuration parameters for appy.gen and
|
||||||
your application, please create an instance of this class and modify its
|
your application, please create a class named "Config" in the __init__.py
|
||||||
attributes. You may put your instance anywhere in your application
|
file of your application and override some of the attributes defined
|
||||||
(main package, sub-package, etc).'''
|
here, ie:
|
||||||
|
|
||||||
# The default Config instance, used if the application does not give one.
|
import appy.gen
|
||||||
defaultConfig = None
|
class Config(appy.gen.Config):
|
||||||
def getDefault():
|
langages = ('en', 'fr')
|
||||||
if not Config.defaultConfig:
|
'''
|
||||||
Config.defaultConfig = Config()
|
|
||||||
return Config.defaultConfig
|
|
||||||
getDefault = staticmethod(getDefault)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
# For every language code that you specify in this list, appy.gen will
|
# For every language code that you specify in this list, appy.gen will
|
||||||
# produce and maintain translation files.
|
# produce and maintain translation files.
|
||||||
self.languages = ['en']
|
languages = ['en']
|
||||||
# If languageSelector is True, on every page, a language selector will
|
# If languageSelector is True, on every page, a language selector will
|
||||||
# allow to switch between languages defined in self.languages. Else,
|
# allow to switch between languages defined in self.languages. Else,
|
||||||
# the browser-defined language will be used for choosing the language
|
# the browser-defined language will be used for choosing the language
|
||||||
# of returned pages.
|
# of returned pages.
|
||||||
self.languageSelector = False
|
languageSelector = False
|
||||||
# People having one of these roles will be able to create instances
|
# People having one of these roles will be able to create instances
|
||||||
# of classes defined in your application.
|
# of classes defined in your application.
|
||||||
self.defaultCreators = ['Manager', 'Owner']
|
defaultCreators = ['Manager', 'Owner']
|
||||||
# Number of translations for every page on a Translation object
|
# Number of translations for every page on a Translation object
|
||||||
self.translationsPerPage = 30
|
translationsPerPage = 30
|
||||||
# Language that will be used as a basis for translating to other
|
# Language that will be used as a basis for translating to other
|
||||||
# languages.
|
# languages.
|
||||||
self.sourceLanguage = 'en'
|
sourceLanguage = 'en'
|
||||||
# Activate or not the button on home page for asking a new password
|
# Activate or not the button on home page for asking a new password
|
||||||
self.activateForgotPassword = True
|
activateForgotPassword = True
|
||||||
# Enable session timeout?
|
# Enable session timeout?
|
||||||
self.enableSessionTimeout = False
|
enableSessionTimeout = False
|
||||||
# If the following field is True, the login/password widget will be
|
# If the following field is True, the login/password widget will be
|
||||||
# discreet. This is for sites where authentication is not foreseen for
|
# discreet. This is for sites where authentication is not foreseen for
|
||||||
# the majority of visitors (just for some administrators).
|
# the majority of visitors (just for some administrators).
|
||||||
self.discreetLogin = False
|
discreetLogin = False
|
||||||
# When using Ogone, place an instance of appy.gen.ogone.OgoneConfig in
|
# When using Ogone, place an instance of appy.gen.ogone.OgoneConfig in
|
||||||
# the field below.
|
# the field below.
|
||||||
self.ogone = None
|
ogone = None
|
||||||
# When using Google analytics, specify here the Analytics ID
|
# When using Google analytics, specify here the Analytics ID
|
||||||
self.googleAnalyticsId = None
|
googleAnalyticsId = None
|
||||||
# Create a group for every global role?
|
# Create a group for every global role?
|
||||||
self.groupsForGlobalRoles = False
|
groupsForGlobalRoles = False
|
||||||
|
# When using a LDAP for authenticating users, place an instance of class
|
||||||
|
# LdapConfig above in the field below.
|
||||||
|
ldap = None
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -146,29 +146,23 @@ class Generator:
|
||||||
self.user = None
|
self.user = None
|
||||||
self.workflows = []
|
self.workflows = []
|
||||||
self.initialize()
|
self.initialize()
|
||||||
self.config = gen.Config.getDefault()
|
self.config = gen.Config
|
||||||
self.modulesWithTests = set()
|
self.modulesWithTests = set()
|
||||||
self.totalNumberOfTests = 0
|
self.totalNumberOfTests = 0
|
||||||
|
|
||||||
def determineAppyType(self, klass):
|
def determineGenType(self, klass):
|
||||||
'''Is p_klass an Appy class ? An Appy workflow? None of this ?
|
'''If p_klass is:
|
||||||
If it (or a parent) declares at least one appy type definition,
|
* a gen-class, this method returns "class";
|
||||||
it will be considered an Appy class. If it (or a parent) declares at
|
* a gen-workflow, this method it "workflow";
|
||||||
least one state definition, it will be considered an Appy
|
* none of it, this method returns None.
|
||||||
workflow.'''
|
|
||||||
res = 'none'
|
If p_klass declares at least one static attribute that is a
|
||||||
for attrValue in klass.__dict__.itervalues():
|
appy.fields.Field, it will be considered a gen-class. If p_klass
|
||||||
if isinstance(attrValue, gen.Field):
|
declares at least one static attribute that is a appy.gen.State,
|
||||||
res = 'class'
|
it will be considered a gen-workflow.'''
|
||||||
elif isinstance(attrValue, gen.State):
|
for attr in klass.__dict__.itervalues():
|
||||||
res = 'workflow'
|
if isinstance(attr, gen.Field): return 'class'
|
||||||
if not res:
|
elif isinstance(attr, gen.State): return 'workflow'
|
||||||
for baseClass in klass.__bases__:
|
|
||||||
baseClassType = self.determineAppyType(baseClass)
|
|
||||||
if baseClassType != 'none':
|
|
||||||
res = baseClassType
|
|
||||||
break
|
|
||||||
return res
|
|
||||||
|
|
||||||
def containsTests(self, moduleOrClass):
|
def containsTests(self, moduleOrClass):
|
||||||
'''Returns True if p_moduleOrClass contains doctests. This method also
|
'''Returns True if p_moduleOrClass contains doctests. This method also
|
||||||
|
@ -206,11 +200,13 @@ class Generator:
|
||||||
# Find all classes in this module
|
# Find all classes in this module
|
||||||
for name in module.__dict__.keys():
|
for name in module.__dict__.keys():
|
||||||
exec 'moduleElem = module.%s' % name
|
exec 'moduleElem = module.%s' % name
|
||||||
if (type(moduleElem) == classType) and \
|
# Ignore non-classes module elements or classes that were imported
|
||||||
(moduleElem.__module__ == module.__name__):
|
# from other modules.
|
||||||
# We have found a Python class definition in this module.
|
if (type(moduleElem) != classType) or \
|
||||||
appyType = self.determineAppyType(moduleElem)
|
(moduleElem.__module__ != module.__name__): continue
|
||||||
if appyType == 'none': continue
|
# Ignore classes that are not gen-classes or gen-workflows.
|
||||||
|
genType = self.determineGenType(moduleElem)
|
||||||
|
if not genType: continue
|
||||||
# Produce a list of static class attributes (in the order
|
# Produce a list of static class attributes (in the order
|
||||||
# of their definition).
|
# of their definition).
|
||||||
attrs = astClasses[moduleElem.__name__].attributes
|
attrs = astClasses[moduleElem.__name__].attributes
|
||||||
|
@ -224,7 +220,7 @@ class Generator:
|
||||||
moreAttrs.sort()
|
moreAttrs.sort()
|
||||||
if moreAttrs: attrs += moreAttrs
|
if moreAttrs: attrs += moreAttrs
|
||||||
# Add attributes added as back references
|
# Add attributes added as back references
|
||||||
if appyType == 'class':
|
if genType == 'class':
|
||||||
# Determine the class type (standard, tool, user...)
|
# Determine the class type (standard, tool, user...)
|
||||||
if issubclass(moduleElem, gen.Tool):
|
if issubclass(moduleElem, gen.Tool):
|
||||||
if not self.tool:
|
if not self.tool:
|
||||||
|
@ -245,14 +241,12 @@ class Generator:
|
||||||
# Manage classes containing tests
|
# Manage classes containing tests
|
||||||
if self.containsTests(moduleElem):
|
if self.containsTests(moduleElem):
|
||||||
self.modulesWithTests.add(module.__name__)
|
self.modulesWithTests.add(module.__name__)
|
||||||
elif appyType == 'workflow':
|
elif genType == 'workflow':
|
||||||
descriptorClass = self.descriptorClasses['workflow']
|
descriptorClass = self.descriptorClasses['workflow']
|
||||||
descriptor = descriptorClass(moduleElem, attrs, self)
|
descriptor = descriptorClass(moduleElem, attrs, self)
|
||||||
self.workflows.append(descriptor)
|
self.workflows.append(descriptor)
|
||||||
if self.containsTests(moduleElem):
|
if self.containsTests(moduleElem):
|
||||||
self.modulesWithTests.add(module.__name__)
|
self.modulesWithTests.add(module.__name__)
|
||||||
elif isinstance(moduleElem, gen.Config):
|
|
||||||
self.config = moduleElem
|
|
||||||
|
|
||||||
def walkApplication(self):
|
def walkApplication(self):
|
||||||
'''This method walks into the application and creates the corresponding
|
'''This method walks into the application and creates the corresponding
|
||||||
|
@ -262,6 +256,13 @@ class Generator:
|
||||||
sys.path.append(containingFolder)
|
sys.path.append(containingFolder)
|
||||||
# What is the name of the application ?
|
# What is the name of the application ?
|
||||||
appName = os.path.basename(self.application)
|
appName = os.path.basename(self.application)
|
||||||
|
# Get the app-specific config if any
|
||||||
|
exec 'import %s as appModule' % appName
|
||||||
|
if hasattr (appModule, 'Config'):
|
||||||
|
self.config = appModule.Config
|
||||||
|
if not issubclass(self.config, gen.Config):
|
||||||
|
raise Exception('Your Config class must subclass ' \
|
||||||
|
'appy.gen.Config.')
|
||||||
# Collect modules (only a the first level) in this application. Import
|
# Collect modules (only a the first level) in this application. Import
|
||||||
# them all, to be sure class definitions are complete (ie, back
|
# them all, to be sure class definitions are complete (ie, back
|
||||||
# references are set from one class to the other). Moreover, potential
|
# references are set from one class to the other). Moreover, potential
|
||||||
|
@ -556,9 +557,6 @@ class ZopeGenerator(Generator):
|
||||||
if theImport not in imports:
|
if theImport not in imports:
|
||||||
imports.append(theImport)
|
imports.append(theImport)
|
||||||
repls['imports'] = '\n'.join(imports)
|
repls['imports'] = '\n'.join(imports)
|
||||||
# Compute default add roles
|
|
||||||
repls['defaultAddRoles'] = ','.join(
|
|
||||||
['"%s"' % r for r in self.config.defaultCreators])
|
|
||||||
# Compute list of add permissions
|
# Compute list of add permissions
|
||||||
addPermissions = ''
|
addPermissions = ''
|
||||||
for classDescr in classesAll:
|
for classDescr in classesAll:
|
||||||
|
@ -599,16 +597,6 @@ class ZopeGenerator(Generator):
|
||||||
repls['gRoles'] = ','.join(['"%s"' % r.name for r in globalRoles])
|
repls['gRoles'] = ','.join(['"%s"' % r.name for r in globalRoles])
|
||||||
grantableRoles = self.getAllUsedRoles(local=False, grantable=True)
|
grantableRoles = self.getAllUsedRoles(local=False, grantable=True)
|
||||||
repls['grRoles'] = ','.join(['"%s"' % r.name for r in grantableRoles])
|
repls['grRoles'] = ','.join(['"%s"' % r.name for r in grantableRoles])
|
||||||
# Generate configuration options
|
|
||||||
repls['languages'] = ','.join('"%s"' % l for l in self.config.languages)
|
|
||||||
repls['languageSelector'] = self.config.languageSelector
|
|
||||||
repls['sourceLanguage'] = self.config.sourceLanguage
|
|
||||||
repls['enableSessionTimeout'] = self.config.enableSessionTimeout
|
|
||||||
repls['discreetLogin'] = self.config.discreetLogin
|
|
||||||
repls['ogone'] = repr(self.config.ogone)
|
|
||||||
repls['googleAnalyticsId'] = repr(self.config.googleAnalyticsId)
|
|
||||||
repls['activateForgotPassword'] = self.config.activateForgotPassword
|
|
||||||
repls['groupsForGlobalRoles'] = self.config.groupsForGlobalRoles
|
|
||||||
self.copyFile('config.pyt', repls, destName='config.py')
|
self.copyFile('config.pyt', repls, destName='config.py')
|
||||||
|
|
||||||
def generateInit(self):
|
def generateInit(self):
|
||||||
|
|
|
@ -75,7 +75,7 @@ class ZopeInstaller:
|
||||||
self.classes = classes
|
self.classes = classes
|
||||||
# Unwrap some useful config variables
|
# Unwrap some useful config variables
|
||||||
self.productName = config.PROJECTNAME
|
self.productName = config.PROJECTNAME
|
||||||
self.languages = config.languages
|
self.languages = config.appConfig.languages
|
||||||
self.logger = config.logger
|
self.logger = config.logger
|
||||||
self.addContentPermissions = config.ADD_CONTENT_PERMISSIONS
|
self.addContentPermissions = config.ADD_CONTENT_PERMISSIONS
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ class ZopeInstaller:
|
||||||
|
|
||||||
# Create a group for every global role defined in the application
|
# Create a group for every global role defined in the application
|
||||||
# (if required).
|
# (if required).
|
||||||
if self.app.config.getProductConfig().groupsForGlobalRoles:
|
if self.config.appConfig.groupsForGlobalRoles:
|
||||||
for role in self.config.applicationGlobalRoles:
|
for role in self.config.applicationGlobalRoles:
|
||||||
groupId = role.lower()
|
groupId = role.lower()
|
||||||
if appyTool.count('Group', noSecurity=True, login=groupId):
|
if appyTool.count('Group', noSecurity=True, login=groupId):
|
||||||
|
@ -333,7 +333,7 @@ class ZopeInstaller:
|
||||||
# launching Zope in test mode, the temp folder does not exist.
|
# launching Zope in test mode, the temp folder does not exist.
|
||||||
if not hasattr(self.app, 'temp_folder'): return
|
if not hasattr(self.app, 'temp_folder'): return
|
||||||
sessionData = self.app.temp_folder.session_data
|
sessionData = self.app.temp_folder.session_data
|
||||||
if self.config.enableSessionTimeout:
|
if self.config.appConfig.enableSessionTimeout:
|
||||||
sessionData.setDelNotificationTarget(onDelSession)
|
sessionData.setDelNotificationTarget(onDelSession)
|
||||||
else:
|
else:
|
||||||
sessionData.setDelNotificationTarget(None)
|
sessionData.setDelNotificationTarget(None)
|
||||||
|
|
5
gen/ldap.py
Normal file
5
gen/ldap.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
def authenticate(login, password, ldapConfig, tool):
|
||||||
|
'''Tries to authenticate user p_login in the LDAP.'''
|
||||||
|
return
|
||||||
|
# ------------------------------------------------------------------------------
|
|
@ -2,7 +2,7 @@
|
||||||
import os, os.path, sys, re, time, random, types, base64, urllib
|
import os, os.path, sys, re, time, random, types, base64, urllib
|
||||||
from appy import Object
|
from appy import Object
|
||||||
import appy.gen
|
import appy.gen
|
||||||
from appy.gen import Search, String, Page
|
from appy.gen import Search, String, Page, ldap
|
||||||
from appy.gen.utils import SomeObjects, getClassName, GroupDescr, SearchDescr
|
from appy.gen.utils import SomeObjects, getClassName, GroupDescr, SearchDescr
|
||||||
from appy.gen.mixins import BaseMixin
|
from appy.gen.mixins import BaseMixin
|
||||||
from appy.gen.wrappers import AbstractWrapper
|
from appy.gen.wrappers import AbstractWrapper
|
||||||
|
@ -139,6 +139,8 @@ class ToolMixin(BaseMixin):
|
||||||
'''Gets attribute named p_name.'''
|
'''Gets attribute named p_name.'''
|
||||||
if source == 'config':
|
if source == 'config':
|
||||||
obj = self.getProductConfig()
|
obj = self.getProductConfig()
|
||||||
|
elif source == 'app':
|
||||||
|
obj = self.getProductConfig(True)
|
||||||
else:
|
else:
|
||||||
obj = self.appy()
|
obj = self.appy()
|
||||||
return getattr(obj, name, None)
|
return getattr(obj, name, None)
|
||||||
|
@ -160,7 +162,7 @@ class ToolMixin(BaseMixin):
|
||||||
'''We must show the language selector if the app config requires it and
|
'''We must show the language selector if the app config requires it and
|
||||||
it there is more than 2 supported languages. Moreover, on some pages,
|
it there is more than 2 supported languages. Moreover, on some pages,
|
||||||
switching the language is not allowed.'''
|
switching the language is not allowed.'''
|
||||||
cfg = self.getProductConfig()
|
cfg = self.getProductConfig(True)
|
||||||
if not cfg.languageSelector: return
|
if not cfg.languageSelector: return
|
||||||
if len(cfg.languages) < 2: return
|
if len(cfg.languages) < 2: return
|
||||||
page = self.REQUEST.get('ACTUAL_URL').split('/')[-1]
|
page = self.REQUEST.get('ACTUAL_URL').split('/')[-1]
|
||||||
|
@ -168,11 +170,11 @@ class ToolMixin(BaseMixin):
|
||||||
|
|
||||||
def showForgotPassword(self):
|
def showForgotPassword(self):
|
||||||
'''We must show link "forgot password?" when the app requires it.'''
|
'''We must show link "forgot password?" when the app requires it.'''
|
||||||
return self.getProductConfig().activateForgotPassword
|
return self.getProductConfig(True).activateForgotPassword
|
||||||
|
|
||||||
def getLanguages(self):
|
def getLanguages(self):
|
||||||
'''Returns the supported languages. First one is the default.'''
|
'''Returns the supported languages. First one is the default.'''
|
||||||
return self.getProductConfig().languages
|
return self.getProductConfig(True).languages
|
||||||
|
|
||||||
def getLanguageName(self, code):
|
def getLanguageName(self, code):
|
||||||
'''Gets the language name (in this language) from a 2-chars language
|
'''Gets the language name (in this language) from a 2-chars language
|
||||||
|
@ -1005,27 +1007,43 @@ class ToolMixin(BaseMixin):
|
||||||
'''Returns the encrypted version of clear p_password.'''
|
'''Returns the encrypted version of clear p_password.'''
|
||||||
return self.acl_users._encryptPassword(password)
|
return self.acl_users._encryptPassword(password)
|
||||||
|
|
||||||
|
def _zopeAuthenticate(self, request):
|
||||||
|
'''Performs the Zope-level authentication. Returns True if
|
||||||
|
authentication succeeds.'''
|
||||||
|
user = self.acl_users.validate(rq)
|
||||||
|
return not self.userIsAnon()
|
||||||
|
|
||||||
|
def _ldapAuthenticate(self, login, password):
|
||||||
|
'''Performs a LDAP-based authentication. Returns True if authentication
|
||||||
|
succeeds.'''
|
||||||
|
# Check if LDAP is configured.
|
||||||
|
ldapConfig = self.getProductConfig(True).ldap
|
||||||
|
if not ldapConfig: return
|
||||||
|
user = ldap.authenticate(login, password, ldapConfig, self)
|
||||||
|
if not user: return
|
||||||
|
return True
|
||||||
|
|
||||||
def performLogin(self):
|
def performLogin(self):
|
||||||
'''Logs the user in.'''
|
'''Logs the user in.'''
|
||||||
rq = self.REQUEST
|
rq = self.REQUEST
|
||||||
jsEnabled = rq.get('js_enabled', False) in ('1', 1)
|
jsEnabled = rq.get('js_enabled', False) in ('1', 1)
|
||||||
cookiesEnabled = rq.get('cookies_enabled', False) in ('1', 1)
|
cookiesEnabled = rq.get('cookies_enabled', False) in ('1', 1)
|
||||||
urlBack = rq['HTTP_REFERER']
|
urlBack = rq['HTTP_REFERER']
|
||||||
|
|
||||||
if jsEnabled and not cookiesEnabled:
|
if jsEnabled and not cookiesEnabled:
|
||||||
msg = self.translate('enable_cookies')
|
msg = self.translate('enable_cookies')
|
||||||
return self.goto(urlBack, msg)
|
return self.goto(urlBack, msg)
|
||||||
# Perform the Zope-level authentication
|
# Extract the login and password
|
||||||
login = rq.get('__ac_name', '')
|
login = rq.get('__ac_name', '')
|
||||||
self._updateCookie(login, rq.get('__ac_password', ''))
|
password = rq.get('__ac_password', '')
|
||||||
user = self.acl_users.validate(rq)
|
# Perform the Zope-level authentication
|
||||||
if self.userIsAnon():
|
self._updateCookie(login, password)
|
||||||
rq.RESPONSE.expireCookie('__ac', path='/')
|
if self._zopeAuthenticate(rq) or self._ldapAuthenticate(login,password):
|
||||||
msg = self.translate('login_ko')
|
|
||||||
logMsg = 'Authentication failed (tried with login "%s").' % login
|
|
||||||
else:
|
|
||||||
msg = self.translate('login_ok')
|
msg = self.translate('login_ok')
|
||||||
logMsg = 'User "%s" logged in.' % login
|
logMsg = 'User "%s" logged in.' % login
|
||||||
|
else:
|
||||||
|
rq.RESPONSE.expireCookie('__ac', path='/')
|
||||||
|
msg = self.translate('login_ko')
|
||||||
|
logMsg = 'Authentication failed with login "%s".' % login
|
||||||
self.log(logMsg)
|
self.log(logMsg)
|
||||||
return self.goto(self.getApp().absolute_url(), msg)
|
return self.goto(self.getApp().absolute_url(), msg)
|
||||||
|
|
||||||
|
@ -1303,7 +1321,7 @@ class ToolMixin(BaseMixin):
|
||||||
# Disable Google Analytics when we are in debug mode.
|
# Disable Google Analytics when we are in debug mode.
|
||||||
if self.isDebug(): return
|
if self.isDebug(): return
|
||||||
# Disable Google Analytics if no ID is found in the config.
|
# Disable Google Analytics if no ID is found in the config.
|
||||||
gaId = self.getProductConfig().googleAnalyticsId
|
gaId = self.getProductConfig(True).googleAnalyticsId
|
||||||
if not gaId: return
|
if not gaId: return
|
||||||
# Google Analytics must be enabled: return the chunk of Javascript
|
# Google Analytics must be enabled: return the chunk of Javascript
|
||||||
# code specified by Google.
|
# code specified by Google.
|
||||||
|
|
|
@ -1646,9 +1646,12 @@ class BaseMixin:
|
||||||
'''Returns the application tool.'''
|
'''Returns the application tool.'''
|
||||||
return self.getPhysicalRoot().config
|
return self.getPhysicalRoot().config
|
||||||
|
|
||||||
def getProductConfig(self):
|
def getProductConfig(self, app=False):
|
||||||
'''Returns a reference to the config module.'''
|
'''Returns a reference to the config module. If p_app is True, it
|
||||||
return self.__class__.config
|
returns the application config.'''
|
||||||
|
res = self.__class__.config
|
||||||
|
if app: res = res.appConfig
|
||||||
|
return res
|
||||||
|
|
||||||
def getParent(self):
|
def getParent(self):
|
||||||
'''If this object is stored within another one, this method returns it.
|
'''If this object is stored within another one, this method returns it.
|
||||||
|
|
|
@ -164,6 +164,9 @@ class User(ModelClass):
|
||||||
def showRoles(self): pass
|
def showRoles(self): pass
|
||||||
roles = gen.String(show=showRoles, indexed=True,
|
roles = gen.String(show=showRoles, indexed=True,
|
||||||
validator=gen.Selection('getGrantableRoles'), **gm)
|
validator=gen.Selection('getGrantableRoles'), **gm)
|
||||||
|
# Where is this user stored? By default, in the ZODB. But the user can be
|
||||||
|
# stored in an external LDAP.
|
||||||
|
source = gen.String(show=False, default='zodb', layouts='f', **gm)
|
||||||
|
|
||||||
# The Group class --------------------------------------------------------------
|
# The Group class --------------------------------------------------------------
|
||||||
class Group(ModelClass):
|
class Group(ModelClass):
|
||||||
|
|
|
@ -24,7 +24,6 @@ logger = logging.getLogger('<!applicationName!>')
|
||||||
# Some global variables --------------------------------------------------------
|
# Some global variables --------------------------------------------------------
|
||||||
PROJECTNAME = '<!applicationName!>'
|
PROJECTNAME = '<!applicationName!>'
|
||||||
diskFolder = os.path.dirname(<!applicationName!>.__file__)
|
diskFolder = os.path.dirname(<!applicationName!>.__file__)
|
||||||
defaultAddRoles = [<!defaultAddRoles!>]
|
|
||||||
ADD_CONTENT_PERMISSIONS = {
|
ADD_CONTENT_PERMISSIONS = {
|
||||||
<!addPermissions!>}
|
<!addPermissions!>}
|
||||||
|
|
||||||
|
@ -43,16 +42,10 @@ applicationRoles = [<!roles!>]
|
||||||
applicationGlobalRoles = [<!gRoles!>]
|
applicationGlobalRoles = [<!gRoles!>]
|
||||||
grantableRoles = [<!grRoles!>]
|
grantableRoles = [<!grRoles!>]
|
||||||
|
|
||||||
# Configuration options
|
try:
|
||||||
languages = [<!languages!>]
|
appConfig = <!applicationName!>.Config
|
||||||
languageSelector = <!languageSelector!>
|
except AttributeError:
|
||||||
sourceLanguage = '<!sourceLanguage!>'
|
appConfig = appy.gen.Config
|
||||||
activateForgotPassword = <!activateForgotPassword!>
|
|
||||||
enableSessionTimeout = <!enableSessionTimeout!>
|
|
||||||
discreetLogin = <!discreetLogin!>
|
|
||||||
ogone = <!ogone!>
|
|
||||||
googleAnalyticsId = <!googleAnalyticsId!>
|
|
||||||
groupsForGlobalRoles = <!groupsForGlobalRoles!>
|
|
||||||
|
|
||||||
# When Zope is starting or runs in test mode, there is no request object. We
|
# When Zope is starting or runs in test mode, there is no request object. We
|
||||||
# create here a fake one for storing Appy wrappers.
|
# create here a fake one for storing Appy wrappers.
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
contextObj python: tool.getPublishedObject(layoutType) or tool.getHomeObject();
|
contextObj python: tool.getPublishedObject(layoutType) or tool.getHomeObject();
|
||||||
showPortlet python: tool.showPortlet(context, layoutType);
|
showPortlet python: tool.showPortlet(context, layoutType);
|
||||||
dir python: tool.getLanguageDirection(lang);
|
dir python: tool.getLanguageDirection(lang);
|
||||||
discreetLogin python: tool.getAttr('discreetLogin', source='config');
|
discreetLogin python: tool.getAttr('discreetLogin', source='app');
|
||||||
dleft python: (dir == 'ltr') and 'left' or 'right';
|
dleft python: (dir == 'ltr') and 'left' or 'right';
|
||||||
dright python: (dir == 'ltr') and 'right' or 'left';
|
dright python: (dir == 'ltr') and 'right' or 'left';
|
||||||
x python: resp.setHeader('Content-type', 'text/html;;charset=UTF-8');
|
x python: resp.setHeader('Content-type', 'text/html;;charset=UTF-8');
|
||||||
|
|
|
@ -14,7 +14,7 @@ class TranslationWrapper(AbstractWrapper):
|
||||||
# either from the config object.
|
# either from the config object.
|
||||||
sourceLanguage = self.sourceLanguage
|
sourceLanguage = self.sourceLanguage
|
||||||
if not sourceLanguage:
|
if not sourceLanguage:
|
||||||
sourceLanguage = self.o.getProductConfig().sourceLanguage
|
sourceLanguage = self.o.getProductConfig(True).sourceLanguage
|
||||||
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
||||||
# p_field is the Computed field. We need to get the name of the
|
# p_field is the Computed field. We need to get the name of the
|
||||||
# corresponding field holding the translation message.
|
# corresponding field holding the translation message.
|
||||||
|
@ -43,7 +43,7 @@ class TranslationWrapper(AbstractWrapper):
|
||||||
if field.type == 'Computed': name = field.name[:-6]
|
if field.type == 'Computed': name = field.name[:-6]
|
||||||
else: name = field.name
|
else: name = field.name
|
||||||
# Get the source message
|
# Get the source message
|
||||||
sourceLanguage = self.o.getProductConfig().sourceLanguage
|
sourceLanguage = self.o.getProductConfig(True).sourceLanguage
|
||||||
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
sourceTranslation = getattr(tool.o, sourceLanguage).appy()
|
||||||
sourceMsg = getattr(sourceTranslation, name)
|
sourceMsg = getattr(sourceTranslation, name)
|
||||||
if field.isEmptyValue(sourceMsg): return False
|
if field.isEmptyValue(sourceMsg): return False
|
||||||
|
|
|
@ -360,7 +360,7 @@ class AbstractWrapper(object):
|
||||||
obj = zobj and zobj.appy() or None;
|
obj = zobj and zobj.appy() or None;
|
||||||
showPortlet=ztool.showPortlet(zobj, layoutType);
|
showPortlet=ztool.showPortlet(zobj, layoutType);
|
||||||
dir=ztool.getLanguageDirection(lang);
|
dir=ztool.getLanguageDirection(lang);
|
||||||
discreetLogin=ztool.getAttr('discreetLogin', source='config');
|
discreetLogin=ztool.getProductConfig(True).discreetLogin;
|
||||||
dleft=(dir == 'ltr') and 'left' or 'right';
|
dleft=(dir == 'ltr') and 'left' or 'right';
|
||||||
dright=(dir == 'ltr') and 'right' or 'left';
|
dright=(dir == 'ltr') and 'right' or 'left';
|
||||||
x=resp.setHeader('Content-type', ztool.xhtmlEncoding);
|
x=resp.setHeader('Content-type', ztool.xhtmlEncoding);
|
||||||
|
@ -879,7 +879,7 @@ class AbstractWrapper(object):
|
||||||
p_cfg is the product config that holds the default value.'''
|
p_cfg is the product config that holds the default value.'''
|
||||||
res = klass._getParentAttr('creators')
|
res = klass._getParentAttr('creators')
|
||||||
# Return default creators if no creators was found.
|
# Return default creators if no creators was found.
|
||||||
if not res: res = cfg.defaultAddRoles
|
if not res: res = cfg.appConfig.defaultCreators
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
Loading…
Reference in a new issue