1 import logging
, re
, datetime
, uuid
, hashlib
4 from fma
import SuperDoc
5 from fma
.orm
import relation
8 def _hash_passkey(passkey
, salt
):
9 #CHECK: use static salt?
10 #return hashlib.sha1(salt + hashlib.md5(passkey).hexdigest()).hexdigest()
11 return hashlib
.sha1(salt
+ passkey
).hexdigest()
13 def _generate_activation_key():
14 #CHECK: more sophisticated generator?
15 #return str(uuid.uuid4())
16 return '%x' % (crc32(str(uuid
.uuid4())) & 0xffffffffL
)
19 class Error(Exception):
22 class NameInvalid(Error
): pass
23 class NameExists(Error
): pass
24 class EmailInvalid(Error
): pass
25 class EmailExists(Error
): pass
28 class Account(SuperDoc
):
29 _collection_name
= 'accounts'
34 'req' : ['idname','email','passkey']
43 #TODO: check for existing name or email
44 if self
.idname
is None:
47 self
.idname
= self
.name
.lower()
49 self
.idname
= self
.idname
.lower()
50 #TODO: name validity check here
51 if len(self
.idname
) < 4 or len(self
.idname
) > 32:
53 # Check if the id already existed
54 #TODO: expiration (when the account activation is expired, the name could be used)
55 if self
._monga
.col(Account
).find_one(idname
=self
.idname
):
57 self
.email
= self
.email
.lower()
58 #TODO: check email address validity here
59 # Check if the email address already existed
60 if self
._monga
.col(Account
).find_one(email
=self
.email
):
62 if hasattr(self
, 'creation_timestamp') is not True or len(self
.creation_timestamp
) is 0:
63 self
.creation_timestamp
= datetime
.datetime
.utcnow()
64 self
.salt
= '%x' % (crc32(str(uuid
.uuid4())) & 0xffffffffL
)
65 self
.passkey
= _hash_passkey(self
.passkey
, self
.salt
)
66 #TODO: check config for activation method
67 if hasattr(self
, 'active') is False or self
.active
is not True:
69 self
.activation_key
= _generate_activation_key()
71 #if self.admin is None:
74 #TODO: check for changed properties
76 super(Account
, self
).save()
78 def activate(self
, actkey
):
80 if self
.activation_key
== actkey
:
82 #TODO: clear completely
83 self
.activation_key
= None
87 def regenerate_activation_key(self
, active_check
=True):
88 if (active_check
and self
.activate
is not True) or active_check
== False:
89 self
.activation_key
= _generate_activation_key()
91 def authenticate(self
, passkey
):
96 return self
.passkey
== _hash_passkey(passkey
, self
.salt
)
98 def change_passkey(self
, newpasskey
):
99 """ WARNING: no old passkey checking (use authenticate first)
101 self
.passkey
= _hash_passkey(newpasskey
, self
.salt
)
105 #def register(name, email, password):
108 # acc.idname = name.lower()
110 # acc.passkey = password
112 # #TODO: catch exception here!
114 # g.db.col(Account).insert(acc)