/
RegistrationTool.py
136 lines (110 loc) · 4.63 KB
/
RegistrationTool.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import random
import md5
import re
from Products.CMFCore.utils import getToolByName
from Products.CMFDefault.RegistrationTool import RegistrationTool as BaseTool
from Products.CMFPlone import ToolNames
from Globals import InitializeClass
from AccessControl import ClassSecurityInfo
from Products.CMFPlone.PloneBaseTool import PloneBaseTool
from Products.CMFPlone.PloneTool import EMAIL_RE
# - remove '1', 'l', and 'I' to avoid confusion
# - remove '0', 'O', and 'Q' to avoid confusion
# - remove vowels to avoid spelling words
invalid_password_chars = ['a','e','i','o','u','y','l','q']
def getValidPasswordChars():
password_chars = []
for i in range(0, 26):
if chr(ord('a')+i) not in invalid_password_chars:
password_chars.append(chr(ord('a')+i))
password_chars.append(chr(ord('A')+i))
for i in range(2, 10):
password_chars.append(chr(ord('0')+i))
return password_chars
password_chars = getValidPasswordChars()
# seed the random number generator
random.seed()
class RegistrationTool(PloneBaseTool, BaseTool):
meta_type = ToolNames.RegistrationTool
security = ClassSecurityInfo()
toolicon = 'skins/plone_images/pencil_icon.gif'
plone_tool = 1
__implements__ = (PloneBaseTool.__implements__, BaseTool.__implements__, )
md5key = None
_v_md5base = None
def __init__(self):
if hasattr(BaseTool, '__init__'):
BaseTool.__init__(self)
# build and persist an MD5 key
self.md5key = ''
for i in range(0, 20):
self.md5key += chr(ord('a')+random.randint(0,26))
def _md5base(self):
if self._v_md5base is None:
self._v_md5base = md5.new(self.md5key)
return self._v_md5base
# Get a password of the prescribed length
#
# For s=None, generates a random password
# For s!=None, generates a deterministic password using a hash of s
# (length must be <= 16 for s != None)
#
# XXX: Could this be made private?
def getPassword(self, length=5, s=None):
global password_chars, md5base
if s is None:
password = ''
nchars = len(password_chars)
for i in range(0, length):
password += password_chars[random.randint(0,nchars-1)]
return password
else:
m = self._md5base().copy()
m.update(s)
d = m.digest() # compute md5(md5key + s)
assert(len(d) >= length)
password = ''
nchars = len(password_chars)
for i in range(0, length):
password += password_chars[ord(d[i]) % nchars]
return password
security.declarePublic('isValidEmail')
def isValidEmail(self, email):
""" checks for valid email """
if EMAIL_RE.search(email) == None:
return 0
return 1
security.declarePublic('generatePassword')
def generatePassword(self):
"""Generates a password which is guaranteed to comply
with the password policy."""
return self.getPassword(6)
security.declarePublic('generateResetCode')
def generateResetCode(self, salt, length=14):
"""Generates a reset code which is guaranteed to return the
same value for a given length and salt, every time."""
return self.getPassword(length, salt)
security.declarePublic('mailPassword')
def mailPassword(self, forgotten_userid, REQUEST):
""" Wrapper around mailPassword """
membership = getToolByName(self, 'portal_membership')
utils = getToolByName(self, 'plone_utils')
member = membership.getMemberById(forgotten_userid)
if member and member.getProperty('email'):
# add the single email address
if not utils.validateSingleEmailAddress(member.getProperty('email')):
raise ValueError, 'The email address did not validate'
return BaseTool.mailPassword(self, forgotten_userid, REQUEST)
security.declarePublic('registeredNotify')
def registeredNotify(self, new_member_id):
""" Wrapper around registeredNotify """
membership = getToolByName( self, 'portal_membership' )
utils = getToolByName(self, 'plone_utils')
member = membership.getMemberById( new_member_id )
if member and member.getProperty('email'):
# add the single email address
if not utils.validateSingleEmailAddress(member.getProperty('email')):
raise ValueError, 'The email address did not validate'
return BaseTool.registeredNotify(self, new_member_id)
RegistrationTool.__doc__ = BaseTool.__doc__
InitializeClass(RegistrationTool)