Mercurial > libervia-backend
comparison sat/memory/memory.py @ 3128:73b5228715e8
core (memory): avoid session locking if profileAuthenticate is called twice quickly
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 27 Jan 2020 19:52:49 +0100 |
parents | 130f9cb6e0ab |
children | 9d0df638c8b4 |
comparison
equal
deleted
inserted
replaced
3127:2798c86412e1 | 3128:73b5228715e8 |
---|---|
387 @param password (unicode): the SàT profile password | 387 @param password (unicode): the SàT profile password |
388 @param profile: %(doc_profile)s | 388 @param profile: %(doc_profile)s |
389 @return (D): a deferred None in case of success, a failure otherwise. | 389 @return (D): a deferred None in case of success, a failure otherwise. |
390 @raise exceptions.PasswordError: the password does not match | 390 @raise exceptions.PasswordError: the password does not match |
391 """ | 391 """ |
392 session_data = self.auth_sessions.profileGetUnique(profile) | 392 if not password and self.auth_sessions.profileGetUnique(profile): |
393 if not password and session_data: | |
394 # XXX: this allows any frontend to connect with the empty password as soon as | 393 # XXX: this allows any frontend to connect with the empty password as soon as |
395 # the profile has been authenticated at least once before. It is OK as long as | 394 # the profile has been authenticated at least once before. It is OK as long as |
396 # submitting a form with empty passwords is restricted to local frontends. | 395 # submitting a form with empty passwords is restricted to local frontends. |
397 return defer.succeed(None) | 396 return defer.succeed(None) |
398 | 397 |
402 raise failure.Failure( | 401 raise failure.Failure( |
403 exceptions.PasswordError( | 402 exceptions.PasswordError( |
404 "The provided profile password doesn't match." | 403 "The provided profile password doesn't match." |
405 ) | 404 ) |
406 ) | 405 ) |
407 if ( | 406 return self.newAuthSession(password, profile) |
408 not session_data | |
409 ): # avoid to create two profile sessions when password if specified | |
410 return self.newAuthSession(password, profile) | |
411 | 407 |
412 d = self.asyncGetParamA( | 408 d = self.asyncGetParamA( |
413 C.PROFILE_PASS_PATH[1], C.PROFILE_PASS_PATH[0], profile_key=profile | 409 C.PROFILE_PASS_PATH[1], C.PROFILE_PASS_PATH[0], profile_key=profile |
414 ) | 410 ) |
415 d.addCallback(lambda sat_cipher: PasswordHasher.verify(password, sat_cipher)) | 411 d.addCallback(lambda sat_cipher: PasswordHasher.verify(password, sat_cipher)) |
416 return d.addCallback(check_result) | 412 return d.addCallback(check_result) |
417 | 413 |
418 def newAuthSession(self, key, profile): | 414 def newAuthSession(self, key, profile): |
419 """Start a new session for the authenticated profile. | 415 """Start a new session for the authenticated profile. |
420 | 416 |
417 If there is already an existing session, no new one is created | |
421 The personal key is loaded encrypted from a PersistentDict before being decrypted. | 418 The personal key is loaded encrypted from a PersistentDict before being decrypted. |
422 | 419 |
423 @param key: the key to decrypt the personal key | 420 @param key: the key to decrypt the personal key |
424 @param profile: %(doc_profile)s | 421 @param profile: %(doc_profile)s |
425 @return: a deferred None value | 422 @return: a deferred None value |
426 """ | 423 """ |
427 | 424 |
428 def gotPersonalKey(personal_key): | 425 def gotPersonalKey(personal_key): |
429 """Create the session for this profile and store the personal key""" | 426 """Create the session for this profile and store the personal key""" |
430 self.auth_sessions.newSession( | 427 session_data = self.auth_sessions.profileGetUnique(profile) |
431 {C.MEMORY_CRYPTO_KEY: personal_key}, profile=profile | 428 if not session_data: |
432 ) | 429 self.auth_sessions.newSession( |
433 log.debug("auth session created for profile %s" % profile) | 430 {C.MEMORY_CRYPTO_KEY: personal_key}, profile=profile |
431 ) | |
432 log.debug("auth session created for profile %s" % profile) | |
434 | 433 |
435 d = PersistentDict(C.MEMORY_CRYPTO_NAMESPACE, profile).load() | 434 d = PersistentDict(C.MEMORY_CRYPTO_NAMESPACE, profile).load() |
436 d.addCallback(lambda data: BlockCipher.decrypt(key, data[C.MEMORY_CRYPTO_KEY])) | 435 d.addCallback(lambda data: BlockCipher.decrypt(key, data[C.MEMORY_CRYPTO_KEY])) |
437 return d.addCallback(gotPersonalKey) | 436 return d.addCallback(gotPersonalKey) |
438 | 437 |