|
|
|
|
174
|
return DBSession.query(cls).filter_by(email=username).first()
|
174
|
return DBSession.query(cls).filter_by(email=username).first()
|
175
|
|
175
|
|
176
|
@classmethod
|
176
|
@classmethod
|
177
|
- def _hash_password(cls, password):
|
|
|
|
|
177
|
+ def _hash_password(cls, cleartext_password):
|
178
|
salt = sha256()
|
178
|
salt = sha256()
|
179
|
salt.update(os.urandom(60))
|
179
|
salt.update(os.urandom(60))
|
180
|
salt = salt.hexdigest()
|
180
|
salt = salt.hexdigest()
|
181
|
|
181
|
|
182
|
hash = sha256()
|
182
|
hash = sha256()
|
183
|
# Make sure password is a str because we cannot hash unicode objects
|
183
|
# Make sure password is a str because we cannot hash unicode objects
|
184
|
- hash.update((password + salt).encode('utf-8'))
|
|
|
|
|
184
|
+ hash.update((cleartext_password + salt).encode('utf-8'))
|
185
|
hash = hash.hexdigest()
|
185
|
hash = hash.hexdigest()
|
186
|
|
186
|
|
187
|
- password = salt + hash
|
|
|
|
|
187
|
+ ciphertext_password = salt + hash
|
188
|
|
188
|
|
189
|
# Make sure the hashed password is a unicode object at the end of the
|
189
|
# Make sure the hashed password is a unicode object at the end of the
|
190
|
# process because SQLAlchemy _wants_ unicode objects for Unicode cols
|
190
|
# process because SQLAlchemy _wants_ unicode objects for Unicode cols
|
191
|
# FIXME - D.A. - 2013-11-20 - The following line has been removed since using python3. Is this normal ?!
|
191
|
# FIXME - D.A. - 2013-11-20 - The following line has been removed since using python3. Is this normal ?!
|
192
|
# password = password.decode('utf-8')
|
192
|
# password = password.decode('utf-8')
|
193
|
|
193
|
|
194
|
- return password
|
|
|
|
|
194
|
+ return ciphertext_password
|
195
|
|
195
|
|
196
|
- def _set_password(self, password):
|
|
|
197
|
- """Hash ``password`` on the fly and store its hashed version."""
|
|
|
198
|
- self._password = self._hash_password(password)
|
|
|
199
|
- self.update_webdav_digest_auth(password)
|
|
|
|
|
196
|
+ def _set_password(self, cleartext_password: str) -> None:
|
|
|
197
|
+ """
|
|
|
198
|
+ Set ciphertext password from cleartext password.
|
|
|
199
|
+
|
|
|
200
|
+ Hash cleartext password on the fly,
|
|
|
201
|
+ Store its ciphertext version,
|
|
|
202
|
+ Update the WebDAV hash as well.
|
|
|
203
|
+ """
|
|
|
204
|
+ self._password = self._hash_password(cleartext_password)
|
|
|
205
|
+ self.update_webdav_digest_auth(cleartext_password)
|
200
|
|
206
|
|
201
|
def _get_password(self):
|
207
|
def _get_password(self):
|
202
|
"""Return the hashed version of the password."""
|
208
|
"""Return the hashed version of the password."""
|
|
|
|
|
219
|
descriptor=property(_get_hash_digest,
|
225
|
descriptor=property(_get_hash_digest,
|
220
|
_set_hash_digest))
|
226
|
_set_hash_digest))
|
221
|
|
227
|
|
222
|
- def update_webdav_digest_auth(self, password) -> None:
|
|
|
|
|
228
|
+ def update_webdav_digest_auth(self, cleartext_password) -> None:
|
223
|
self.webdav_left_digest_response_hash \
|
229
|
self.webdav_left_digest_response_hash \
|
224
|
- = '{username}:/:{password}'.format(
|
|
|
|
|
230
|
+ = '{username}:/:{cleartext_password}'.format(
|
225
|
username=self.email,
|
231
|
username=self.email,
|
226
|
- password=password,
|
|
|
|
|
232
|
+ cleartext_password=cleartext_password,
|
227
|
)
|
233
|
)
|
228
|
|
234
|
|
229
|
|
235
|
|
230
|
- def validate_password(self, password):
|
|
|
|
|
236
|
+ def validate_password(self, cleartext_password):
|
231
|
"""
|
237
|
"""
|
232
|
Check the password against existing credentials.
|
238
|
Check the password against existing credentials.
|
233
|
|
239
|
|
234
|
- :param password: the password that was provided by the user to
|
|
|
235
|
- try and authenticate. This is the clear text version that we will
|
|
|
236
|
- need to match against the hashed one in the database.
|
|
|
237
|
- :type password: unicode object.
|
|
|
|
|
240
|
+ :param cleartext_password: the password that was provided by the user
|
|
|
241
|
+ to try and authenticate. This is the clear text version that we
|
|
|
242
|
+ will need to match against the hashed one in the database.
|
|
|
243
|
+ :type cleartext_password: unicode object.
|
238
|
:return: Whether the password is valid.
|
244
|
:return: Whether the password is valid.
|
239
|
:rtype: bool
|
245
|
:rtype: bool
|
240
|
|
246
|
|
|
|
|
|
242
|
result = False
|
248
|
result = False
|
243
|
if self.password:
|
249
|
if self.password:
|
244
|
hash = sha256()
|
250
|
hash = sha256()
|
245
|
- hash.update((password + self.password[:64]).encode('utf-8'))
|
|
|
|
|
251
|
+ hash.update((cleartext_password + self.password[:64]).encode('utf-8'))
|
246
|
result = self.password[64:] == hash.hexdigest()
|
252
|
result = self.password[64:] == hash.hexdigest()
|
247
|
if result and not self.webdav_left_digest_response_hash:
|
253
|
if result and not self.webdav_left_digest_response_hash:
|
248
|
- self.update_webdav_digest_auth(password)
|
|
|
|
|
254
|
+ self.update_webdav_digest_auth(cleartext_password)
|
249
|
return result
|
255
|
return result
|
250
|
|
256
|
|
251
|
def get_display_name(self, remove_email_part=False):
|
257
|
def get_display_name(self, remove_email_part=False):
|