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