[bin] backup.py: remove Data.fs.old before packing the ZODB to avoid disk space problems; [checkldap] added a param to define the scope of the LDAP query (base, onelevel or subtree); [shared] xml_parser: convert nbsp entity to the equivalent utf-8 char.
This commit is contained in:
parent
528cca9aa0
commit
1be7d9f0ab
|
@ -61,6 +61,21 @@ class ZodbBackuper:
|
|||
fileName = self.storageLocation + fileSuffix
|
||||
os.system('chown %s %s' % (self.zopeUser, fileName))
|
||||
|
||||
def removeDataFsOld(self):
|
||||
'''Removes the file Data.fs.old if it exists.
|
||||
|
||||
In the process of packing the ZODB, an additional file Data.fs.pack
|
||||
is created, and renamed to Data.fs once finished. It means that, when
|
||||
we pack the ZODB, 3 copies of the DB can be present at the same time:
|
||||
Data.fs, Data.fs.old and Data.fs.pack. We prefer to remove the
|
||||
Data.fs.old copy to avoid missing disk space if the DB is big.
|
||||
'''
|
||||
old = self.storageLocation + '.old'
|
||||
if os.path.exists(old):
|
||||
self.log('Removing %s...' % old)
|
||||
os.remove(old)
|
||||
self.log('Done.')
|
||||
|
||||
folderCreateError = 'Could not create backup folder. Backup of log ' \
|
||||
'files will not take place. %s'
|
||||
def backupLogs(self):
|
||||
|
@ -190,6 +205,8 @@ class ZodbBackuper:
|
|||
self.executeCommand('%s stop' % self.zopectl)
|
||||
# If we are on the "full backup day", let's pack the ZODB first
|
||||
if time.asctime().startswith(self.options.dayFullBackup):
|
||||
# As a preamble to packing the ZODB, remove Data.fs.old if present.
|
||||
self.removeDataFsOld()
|
||||
w('> Day is "%s", packing the ZODB...' % self.options.dayFullBackup)
|
||||
self.packZodb()
|
||||
w('> Make a backup of log files...')
|
||||
|
|
|
@ -12,18 +12,22 @@ class LdapTester:
|
|||
attrs is a comma-separated list of attrs we will retrieve in the LDAP,
|
||||
ie "uid,login"
|
||||
filter is the query filter, ie "(&(attr1=Geez*)(status=OK))"
|
||||
scope is the scope of the search, and can be:
|
||||
BASE To search the object itself on base
|
||||
ONELEVEL To search base's immediate children
|
||||
SUBTREE To search base and all its descendants
|
||||
'''
|
||||
def __init__(self):
|
||||
# Get params from shell args.
|
||||
if len(sys.argv) != 7:
|
||||
if len(sys.argv) != 8:
|
||||
print(LdapTester.__doc__)
|
||||
sys.exit(0)
|
||||
s = self
|
||||
s.uri, s.login, s.password, s.base, s.attrs, s.filter = sys.argv[1:]
|
||||
s.uri,s.login,s.password,s.base,s.attrs,s.filter,s.scope = sys.argv[1:]
|
||||
self.attrs = self.attrs.split(',')
|
||||
self.tentatives = 5
|
||||
self.timeout = 5
|
||||
self.attrList = ['cfwbV2cn', 'logindisabled']
|
||||
self.attrList = ['cn']
|
||||
self.ssl = False
|
||||
|
||||
def test(self):
|
||||
|
@ -38,8 +42,9 @@ class LdapTester:
|
|||
for i in range(self.tentatives):
|
||||
try:
|
||||
print('Done. Performing a simple query on %s...'% self.base)
|
||||
res = server.search_st(
|
||||
self.base, ldap.SCOPE_ONELEVEL, filterstr=self.filter,
|
||||
res = server.search_st(self.base,
|
||||
getattr(ldap, 'SCOPE_%s' % self.scope),
|
||||
filterstr=self.filter,
|
||||
attrlist=self.attrs, timeout=5)
|
||||
print('Got %d entries' % len(res))
|
||||
break
|
||||
|
|
|
@ -369,15 +369,22 @@ class User(Model):
|
|||
# ------------------------------------------------------------------------------
|
||||
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 = ''
|
||||
def __init__(self):
|
||||
self.server = '' # Name of the LDAP server
|
||||
self.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.
|
||||
self.adminLogin = ''
|
||||
self.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.
|
||||
self.loginAttribute = 'dn' # Can also be "mail", "sAMAccountName", "cn"
|
||||
self.baseDn = '' # Base distinguished name where to find users.
|
||||
|
||||
def getServerUri(self):
|
||||
'''Returns the complete URI for accessing the LDAP, ie
|
||||
"ldap://some.ldap.server:389".'''
|
||||
port = self.port or 389
|
||||
return 'ldap://%s:%d' % (self.server, port)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class Config:
|
||||
|
|
|
@ -25,12 +25,11 @@ def traverseWrapper(self, path, response=None, validated_hook=None):
|
|||
'''This function is called every time a users gets a URL, this is used for
|
||||
tracking user activity. self is a BaseRequest'''
|
||||
res = originalTraverse(self, path, response, validated_hook)
|
||||
t = time.time()
|
||||
if os.path.splitext(path)[-1].lower() not in doNotTrack:
|
||||
# Do nothing when the user gets non-pages
|
||||
# Do nothing when the user gets non-pages.
|
||||
userId, dummy = gutils.readCookie(self)
|
||||
if userId:
|
||||
loggedUsers[userId] = t
|
||||
loggedUsers[userId] = time.time()
|
||||
# "Touch" the SESSION object. Else, expiration won't occur.
|
||||
session = self.SESSION
|
||||
return res
|
||||
|
|
29
gen/ldap.py
29
gen/ldap.py
|
@ -1,5 +1,34 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
try:
|
||||
import ldap
|
||||
except ImportError:
|
||||
# For people that do not care about ldap.
|
||||
ldap = None
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def connect(serverUri, login, password):
|
||||
'''Tries to connect to some LDAP server whose UIR is p_serverUri, using
|
||||
p_login and p_password as credentials.'''
|
||||
try:
|
||||
server = ldap.initialize(serverUri)
|
||||
server.simple_bind(login, password)
|
||||
return True, server, None
|
||||
except ldap.LDAPError, le:
|
||||
return False, None, str(le)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def authenticate(login, password, ldapConfig, tool):
|
||||
'''Tries to authenticate user p_login in the LDAP.'''
|
||||
# Connect to the ldap server.
|
||||
serverUri = cfg.getServerUri()
|
||||
success, server, msg = connect(serverUri, cfg.adminLogin, cfg.adminPassword)
|
||||
# Manage a connection error.
|
||||
if not success:
|
||||
tool.log('%s: connect error (%s).' % (serverUri, msg))
|
||||
return
|
||||
# Do p_login and p_password correspond to a user in the LDAP?
|
||||
try:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -1051,6 +1051,7 @@ class ToolMixin(BaseMixin):
|
|||
# a is the object the object was accessed through
|
||||
# c is the physical container of the object
|
||||
a, c, n, v = self._getobcontext(v, request)
|
||||
print c
|
||||
# Try to get user name and password from basic authentication
|
||||
login, password = self.identify(auth)
|
||||
if not login:
|
||||
|
|
|
@ -330,7 +330,7 @@ class XhtmlEnvironment(XmlEnvironment):
|
|||
'''Dumps content that was temporarily stored in self.currentContent
|
||||
into the result.'''
|
||||
contentSize = 0
|
||||
if self.currentContent.strip():
|
||||
if self.currentContent.strip(' \n\r\t'): # NBSP must not be in this list
|
||||
# Manage missing elements
|
||||
currentElem = self.getCurrentElement()
|
||||
if self.anElementIsMissing(currentElem, None):
|
||||
|
|
|
@ -61,7 +61,7 @@ HTML_ENTITIES = {
|
|||
'ntilde':'ñ', 'ograve':'ò', 'oacute':'ó', 'ocirc':'ô', 'otilde':'õ',
|
||||
'ouml':'ö', 'divide':'÷', 'oslash':'ø', 'ugrave':'ù', 'uacute':'ú',
|
||||
'ucirc':'û', 'uuml':'ü', 'yacute':'ý', 'thorn':'þ', 'yuml':'ÿ',
|
||||
'euro':'€', 'nbsp':' ', "rsquo":"'", "lsquo":"'", "ldquo":"'",
|
||||
'euro':'€', 'nbsp':' ', "rsquo":"'", "lsquo":"'", "ldquo":"'",
|
||||
"rdquo":"'", 'ndash': '—', 'mdash': '—', 'oelig':'oe', 'quot': "'",
|
||||
'mu': 'µ'}
|
||||
import htmlentitydefs
|
||||
|
@ -1135,7 +1135,10 @@ class XhtmlCleaner(XmlParser):
|
|||
# between tags.
|
||||
if not self.env.currentContent or \
|
||||
self.env.currentContent[-1] in ('\n', ' '):
|
||||
toAdd = content.lstrip()
|
||||
# I give here to lstrip an explicit list of what is to be considered
|
||||
# as blank chars, because I do not want unicode NBSP chars to be in
|
||||
# this list.
|
||||
toAdd = content.lstrip(u' \n\r\t')
|
||||
else:
|
||||
toAdd = content
|
||||
# Re-transform XML special chars to entities.
|
||||
|
|
Loading…
Reference in a new issue