def setUp(self): self.anyuser = User.query.first() # @UndefinedVariable self.user = self.createUserWithCredentials().user Assurance.new(self.user, 'emailverification', self.user) self.oldEmailAddress = self.userCreationEmail self.newEmailAddress = "email{0}@example.com".format(self.mkRandomString(5)) PDUnitTest.setUp(self)
def do_verify_email(self, token): cred = self.getCredentialForEmailverifyToken(token) self.checkEmailverifyCredential(cred) user = cred.user Assurance.new(user,emailVerification,user) cred.rm() return self.simple_response("email verified OK")
def _loginAndDeregister(self): self.createLoggedInUser() user = self.cred.user Assurance.new(user, "test", user) self._assureHaveCredentialsAndAssurances(user) resp = self._doDeregister() return resp
def doverifyEmail(self, token): cred = self.getCredentialForEmailverifyToken(token) self.checkEmailverifyCredential(cred) user = cred.user Assurance.new(user,emailVerification,user) cred.rm() return self.simple_response(emailVerifiedOK)
def updateHashAndAssurances(self, user, digest): user.hash = digest assurances = Assurance.listByUser(user) self.deleteHandAssuredAssurances(assurances) if digest is not None: Assurance.new(user, "hashgiven", user) user.save()
def test_assurance_counts_are_increasing_with_new_assurance(self): assurercount = Assurance.query.filter( Assurance.name == 'assurer').count() # @UndefinedVariable user = User.query.first() # @UndefinedVariable Assurance.new(user, 'assurer', user).save() self.stats = self.controller.getStats() self.assertEqual(self.stats['assurances']['assurer'], assurercount + 1)
def prepareHashCollision(self, assuredTarget, email=None): form = self.prepareLoginForm(email=email) self.anotherUser = self.createUserWithCredentials().user self.anotherUser.hash = self.targetUser.hash if assuredTarget: Assurance.new(self.anotherUser, 'test', self.cred.user) return form
def users_with_assurer_assurance_can_get_user_by_email(self): current_user = self.controller.getCurrentUser() Assurance.new(current_user, 'assurer', current_user) self.setupRandom() self.createUserWithCredentials() target = User.getByEmail(self.usercreation_email) resp = self.controller.do_get_by_email(target.email) self.assertUserResponse(resp)
def users_without_assurer_assurance_cannot_get_email_and_digest_for_anyone(self): current_user = self.controller.getCurrentUser() targetuser=self.createUserWithCredentials() Assurance.new(targetuser,'test',current_user) target = User.getByEmail(self.usercreation_email) with self.assertRaises(ReportedError) as e: self.showUserByCurrentUser(target.userid) self.assertTrue(e.exception.status,403)
def test_the_applications_receive_intersection_of_users_assurances_and_applications_assurances(self): AppAssurance.add(self.app, 'test') AppAssurance.add(self.app, 'test2') user = self.cred.user Assurance.new(user, "test", user) Assurance.new(user, "test3", user) userinfo = self.getUserInfo() self.assertEqual(userinfo['assurances'], ['test'])
def no_by_email_with_wrong_email(self): current_user = self.controller.getCurrentUser() Assurance.new(current_user, 'assurer', current_user) self.setupRandom() self.createUserWithCredentials() target = User.getByEmail(self.usercreation_email) with self.assertRaises(ReportedError) as e: self.controller.do_get_by_email('u'+target.email) self.assertTrue(e.exception.status,404)
def test_users_with_assurer_assurance_can_get_email_and_digest_for_anyone(self): current_user = self._createAssurer() targetuser=self.createUserWithCredentials().user Assurance.new(targetuser,'test',current_user) target = User.getByEmail(self.userCreationEmail) resp = self.showUserByCurrentUser(target.userid) data = self.fromJson(resp) assurances = data['assurances'] self.assertEqual(assurances['test'][0]['assurer'], current_user.email)
def test_the_applications_receive_intersection_of_users_assurances_and_applications_assurances( self): AppAssurance.add(self.app, 'test') AppAssurance.add(self.app, 'test2') user = self.cred.user Assurance.new(user, "test", user) Assurance.new(user, "test3", user) userinfo = self.getUserInfo() self.assertEqual(userinfo['assurances'], ['test'])
def test_users_without_assurer_assurance_cannot_get_email_and_digest_for_anyone( self): current_user = self.controller.getCurrentUser() targetuser = self.createUserWithCredentials().user Assurance.new(targetuser, 'test', current_user) target = User.getByEmail(self.userCreationEmail) with self.assertRaises(ReportedError) as context: self.showUserByCurrentUser(target.userid) self.assertEqual(context.exception.status, 403)
def test_the_emailverification_assurance_does_not_count_in_hash_collision(self): anotherUser = self.createUserWithCredentials().user Assurance.new(anotherUser, "emailverification", anotherUser) theHash = self.createHash() anotherUser.hash = theHash form = self.prepareLoginForm(digest=theHash) resp = self.controller.doRegistration(form) self.assertEqual(200, resp.status_code) data = self.fromJson(resp) self.assertEqual(data['message'],anotherUserUsingYourHash)
def test_users_with_assurer_assurance_can_get_email_and_digest_for_anyone( self): current_user = self._createAssurer() targetuser = self.createUserWithCredentials().user Assurance.new(targetuser, 'test', current_user) target = User.getByEmail(self.userCreationEmail) resp = self.showUserByCurrentUser(target.userid) data = self.fromJson(resp) assurances = data['assurances'] self.assertEqual(assurances['test'][0]['assurer'], current_user.email)
def doAddAssurance(self, form): neededAssurance = form.assurance.data self.assureUserHaveTheGivingAssurancesFor(neededAssurance) user = self.getUserForEmailAndOrHash( form.digest.data, form.email.data) numOfOthers = self.deleteDigestFromOtherUsers(user) Assurance.new(user, neededAssurance, self.getCurrentUser()) msg = [[addedAssurance, neededAssurance, user.email]] if numOfOthers: msg.append([otherUsersWithYourHash, str(numOfOthers)]) return self.simple_response(msg)
def test_error_message_on_hash_collision(self): anotheruser = self.createUserWithCredentials().user digest = self.createHash() anotheruser.hash = digest Assurance.new(anotheruser, "test", anotheruser) anotheruser.save() with app.test_client() as client: resp = self.doUpdateHashForUser(client, digest=digest) self.assertEqual(400, resp.status_code) self.assertEqual('{"errors": ["another user is using your hash"]}', resp.data.decode('utf-8'))
def updateEmailByCredential(self, cred, verify): oldemail=cred.user.email cred.user.email = cred.getAdditionalInfo() cred.user.save() for assurance in Assurance.listByUser(cred.user, 'emailverification'): assurance.rm() if verify: Assurance.new(cred.user, 'emailverification', cred.user) else: self.sendPasswordVerificationEmail(cred.user) self.sendEmail(cred.user, None, None, "CHANGE_EMAIL_DONE",oldemail=oldemail, newemail=cred.user.email)
def assurers_need_assurer_assurance(self): with app.test_client() as c: target = self._setupTestWithoutAssurance(c) Assurance.new(current_user, 'assurer.test', current_user) data = dict( digest = target.hash, assurance = "test", email = target.email, csrf_token = self.getCSRF(c)) resp = c.post(config.base_url + '/v1/add_assurance', data = data) self.assertEquals(403, resp.status_code) self.assertEquals('{"errors": ["no authorization"]}', self.getResponseText(resp))
def test_when_a_hash_is_registered_which_is_already_used_by_another_assured_user___the_user_is_notified_about_the_fact_and_registration_fails(self): anotherUser = self.createUserWithCredentials().user Assurance.new(anotherUser, "test", anotherUser) theHash = self.createHash() anotherUser.hash = theHash form = self.prepareLoginForm(digest=theHash) email = self.userCreationEmail self.assertReportedError(self.controller.doRegistration, [form], 400, [anotherUserUsingYourHash]) self.assertEqual(email, User.getByEmail(email).email)
def test_if_hash_is_same_no_assurances_deleted(self): digest = self.createHash() user = self.createUserWithCredentials().user data = dict( digest=digest ) self.controller.checkAndUpdateHash(FakeForm(data), user) Assurance.new(user, "test", user) self.controller.checkAndUpdateHash(FakeForm(data), user) assurances = Assurance.getByUser(user) self.assertTrue("test" in assurances.keys()) self.assertTrue("hashgiven" in assurances.keys())
def getAssurerUser(): userName = "******" password = "******" assurerEmail = "*****@*****.**" user = User.getByEmail(assurerEmail) if not user: user = CredentialManager.create_user_with_creds('password', userName, password, assurerEmail).user user.activate() Assurance.new(user, "assurer", user).save() Assurance.new(user, "assurer.test", user).save() user.password=password user.userName=userName return user
def the_emailverification_assurance_does_not_count_in_hash_collision(self): anotherUser = self.createUserWithCredentials() Assurance.new(anotherUser, emailVerification, anotherUser, time.time()) self.setupRandom() theHash = self.createHash() anotherUser.hash = theHash data = self.prepareData() data['digest'] = theHash with app.test_client() as c: resp = c.post(config.base_url + '/v1/register', data=data) self.assertEqual(200, resp.status_code) text = self.getResponseText(resp) self.assertTrue("another user is using your hash" in text)
def When_a_hash_is_registered_which_is_already_used_by_another_assured_user___the_user_is_notified_about_the_fact_and_registration_fails(self): anotherUser = self.createUserWithCredentials() Assurance.new(anotherUser, "test", anotherUser, time.time()) self.setupRandom() theHash = self.createHash() anotherUser.hash = theHash data = self.prepareData() data['digest'] = theHash with app.test_client() as c: resp = c.post(config.base_url + '/v1/register', data=data) self.assertEqual(400, resp.status_code) text = self.getResponseText(resp) self.assertTrue("another user is using your hash" in text)
def getAssurerUser(): userName = "******" password = "******" assurerEmail = "*****@*****.**" user = User.getByEmail(assurerEmail) if not user: user = CredentialManager.create_user_with_creds( 'password', userName, password, assurerEmail).user user.activate() Assurance.new(user, "assurer", user).save() Assurance.new(user, "assurer.test", user).save() user.password = password user.userName = userName return user
def test_in_hash_collision_if_the_other_user_is_hand_assured_the_user_is_not_deleted(self): anotheruser = self.createUserWithCredentials().user digest = self.createHash() anotheruser.hash = digest Assurance.new(anotheruser, "test", anotheruser) anotheruser.save() user = self.createUserWithCredentials().user app = Application.query.first() # @UndefinedVariable AppMap.new(app, user) email = self.userCreationEmail additionalInfo = dict() with self.assertRaises(ReportedError): self.controller.checkHashInOtherUsers(user,additionalInfo,digest) self.assertEqual(email, User.getByEmail(email).email)
def shownDataForUser(self, user): return dict( email=user.email, userid=user.userid, assurances=Assurance.getByUser(user), hash=user.hash, credentials=Credential.getByUser_as_dictlist(user))
def test_in_assured_collision_the_hash_of_the_user_is_deleted(self): self.doHashCollision() assurances = Assurance.getByUser(self.anotherUser) assurer = assurances['test'][0]['assurer'] self.assertEqual(assurer, self.controller.getCurrentUser().email) self.assertEqual(self.targetUser.hash, self.digest) self.assertEqual(self.anotherUser.hash, None)
def test_adding_assurance_with_invalid_hash_and_email_fails(self): badhash = self.createHash() form = self.prepareLoginForm(digest=badhash) self.assertReportedError( self.controller.doAddAssurance,[form], 400, ['This user does not have that digest']) self.assertFalse('test' in Assurance.getByUser(self.targetUser))
def updateEmailByCredential(self, cred, verify): oldemail = cred.user.email cred.user.email = cred.getAdditionalInfo() cred.user.save() for assurance in Assurance.listByUser(cred.user, 'emailverification'): assurance.rm() if verify: Assurance.new(cred.user, 'emailverification', cred.user) else: self.sendPasswordVerificationEmail(cred.user) self.sendEmail(cred.user, None, None, "CHANGE_EMAIL_DONE", oldemail=oldemail, newemail=cred.user.email)
def test_adding_assurance_with_invalid_hash_and_no_email_fails(self): badhash = self.createHash() form = self.prepareLoginForm(digest=badhash,email=False) self.assertReportedError( self.controller.doAddAssurance,[form], 400, ['No user with this hash']) self.assertFalse('test' in Assurance.getByUser(self.targetUser))
def your_assurances_are_deleted_in_deregistration(self): with app.test_client() as c: self.login(c) user = User.getByEmail(self.usercreation_email) Assurance.new(user, "test", user) assurances = Assurance.getByUser(user) self.assertTrue(len(assurances) > 0) data = dict( csrf_token = self.getCSRF(c), credentialType= "password", identifier= self.usercreation_userid, secret = self.usercreation_password ) c.post(config.base_url+'/deregister', data=data) user = User.getByEmail(self.usercreation_email) assurances = Assurance.getByUser(user) self.assertTrue(len(assurances) == 0)
def _do_get_by_email(self, email): assurances = Assurance.getByUser(self.getCurrentUser()) if assurances.has_key('assurer'): user = User.getByEmail(email) if user is None: raise ReportedError(["no such user"], status=404) return self.as_dict(user) raise ReportedError(["no authorization"], status=403)
def computeAssurancesForApp(self, user, app): appAssurances = AppAssurance.get(app) userAssurances = Assurance.listByUser(user) shownAssurances = list() for userAssurance in userAssurances: if userAssurance.name in appAssurances: shownAssurances.append(userAssurance.name) return shownAssurances
def test_adding_assurance_with_email_and_hash_of_someone_other_fails(self): otherHash = self.createHash() form = self.prepareLoginForm(digest=otherHash) self.anotherUser = self.createUserWithCredentials().user self.anotherUser.hash = otherHash self.assertReportedError(self.controller.doAddAssurance, [form], 400, ['This user does not have that digest']) self.assertFalse('test' in Assurance.getByUser(self.targetUser))
def test_email_validation_gives_emailverification_assurance(self): self.setupRandom() with app.test_client(): email = self.registerAndObtainValidationUri() self.assertTrue(self.validateUri.startswith(config.BASE_URL + "/v1/verify_email")) with app.test_client() as client: user = User.getByEmail(email) creds = Credential.getByUser(user) assurances = Assurance.getByUser(user) self.assertTrue(emailVerification not in assurances) resp = client.get(self.validateUri) self.assertEqual(resp.status_code, 200) self.assertEqual(user.email, email) newcreds = Credential.getByUser(user) self.assertEqual(len(creds) - 1 , len(newcreds)) assurances = Assurance.getByUser(user) self.assertTrue(assurances[emailVerification] is not None) user.rm()
def doGetByEmail(self, email): current_user = self.getCurrentUser() assurances = Assurance.getByUser(current_user) if 'assurer' in assurances: user = User.getByEmail(email) if user is None: raise ReportedError([noSuchUser], status=404) return self.as_dict(user) raise ReportedError([noAuthorization], status=403)
def as_dict(self, user, **kwargs): kwargs.update({'email':user.email, 'userid':user.userid, 'assurances':Assurance.getByUser(user), 'hash': user.hash, 'credentials': Credential.getByUser_as_dictlist(user) }) ret = json.dumps(kwargs) return self.make_response(ret,200)
def test_email_validation_gives_emailverification_assurance(self): self.setupRandom() with app.test_client(): email = self.registerAndObtainValidationUri() self.assertTrue( self.validateUri.startswith(config.BASE_URL + "/v1/verify_email")) with app.test_client() as client: user = User.getByEmail(email) creds = Credential.getByUser(user) assurances = Assurance.getByUser(user) self.assertTrue(emailVerification not in assurances) resp = client.get(self.validateUri) self.assertEqual(resp.status_code, 200) self.assertEqual(user.email, email) newcreds = Credential.getByUser(user) self.assertEqual(len(creds) - 1, len(newcreds)) assurances = Assurance.getByUser(user) self.assertTrue(assurances[emailVerification] is not None) user.rm()
def prepareLoginForm(self, noTestAdderAssurance=False, email=None, noAssurerAssurance=False, digest=None): self.createLoggedInUser() user = self.cred.user if not noAssurerAssurance: Assurance.new(user, 'assurer', user) if not noTestAdderAssurance: Assurance.new(user, 'assurer.test', user) self.targetUser = self.createUserWithCredentials().user self.targetUser.hash = self.createHash() self.digest = self.targetUser.hash self.data = dict(assurance='test', email=None) self.addDataBasedOnOptionValue('email', email, self.targetUser.email) self.addDataBasedOnOptionValue('digest', digest, self.targetUser.hash) form = FakeForm(self.data) return form
def doUpdateHashForUser(self, client, assurance="test", addDigest=True, digest=None): resp = self.login(client) self.assertUserResponse(resp) user = User.getByEmail(self.userCreationEmail) Assurance.new(user, assurance, user, time.time()) oldHash = self.createHash() user.hash = oldHash user.save() userToCheck = User.getByEmail(self.userCreationEmail) assurancesBefore = Assurance.getByUser(userToCheck) self.assertEqual(len(assurancesBefore), 1) self.setupRandom() csrf = self.getCSRF(client) data = dict(csrf_token=csrf) if addDigest: if digest is None: data['digest'] = self.createHash() else: data['digest'] = digest resp = client.post(config.BASE_URL + '/v1/users/me/update_hash', data=data) return resp
def do_main(verbose, email, assurer_email, assurances): if verbose > 0: print("Setting assurances {0} for user {1} by {2}".format( assurances, email, assurer_email)) user = User.getByEmail(email) if user is None: print("no such user: {0}".format(email)) return 2 if assurer_email == 'self': assurer = user else: assurer = User.getByEmail(assurer_email) if user is None: print("no such assurer: {0}".format(assurer_email)) return 2 for ass in assurances: if verbose > 1: print("Setting assurance {0} for user {1} by {2}".format( ass, email, assurer_email)) Assurance.new(user, ass, assurer, time.time()) return 0
def getDataOfUserForAuthenticator(self, userid, authuser, authenticator): user = User.get(userid) if not user: raise ReportedError([noSuchUser], status=404) if self.doesUserAskOwnData(userid, authenticator): return self.shownDataForUser(user) if self.doesUserAskForOthersData(authuser, authenticator): assurances = Assurance.getByUser(authuser) if 'assurer' in assurances: return self.shownDataForAssurer(user) else: raise ReportedError([noShowAuthorization], status=403) return self.shownDataForApp(user, authenticator)
def addUserDataToDict(self, user, kwargs): return kwargs.update({ 'email': user.email, 'userid': user.userid, 'assurances': Assurance.getByUser(user), 'hash': user.hash, 'credentials': Credential.getByUser_as_dictlist(user) })
def test_assurers_with_appropriate_credential_can_add_assurance_to_user_using_hash( self): """ the appropriate credential is an assurance in the form "assurer.<assurance_name>" where assurance_name is the assurance to be added """ with app.test_client() as client: target = self._setupTest(client) data = dict(digest=target.hash, assurance="test", email=target.email, csrf_token=self.getCSRF(client)) resp = client.post(config.BASE_URL + '/v1/add_assurance', data=data) self.assertEqual(200, resp.status_code) self.assertEqual( Assurance.getByUser(target)['test'][0]['assurer'], current_user.email)
def test_user_info_contains_assurance(self): current_user = self.controller.getCurrentUser() myEmail = current_user.email now = round(time.time()) Assurance.new(current_user, 'test', current_user, now) Assurance.new(current_user, 'test2', current_user, now) Assurance.new(current_user, 'test2', current_user, now) resp = self.showUserByCurrentUser('me') self.assertEqual(resp.status_code, 200) data = self.fromJson(resp) self.assertTrue('assurances' in data) assurances = data['assurances'] assurance = assurances['test'][0] self.assertEqual(assurance['assurer'], myEmail) self.assertEqual(assurance['user'], myEmail) self.assertEqual(round(assurance['timestamp']), now) self.assertEqual(assurance['readable_time'], time.asctime(time.gmtime(now))) self.assertEqual(len(assurances['test2']), 2)