def test_facebook_login_post_duplicate_login(self): user1 = models.User.objects.create(email='*****@*****.**') models.FacebookLogin.objects.create(profile_id='facebookid1', user=user1) user2 = models.User.objects.create(email='*****@*****.**') models.MyLogin.objects.create( pw_hash=password_hasher().hash('password1'), user=user2) with self.settings(FACEBOOK_TEST_ID='facebookid1'): response = self.client.post( '/api/login/facebook', ujson.dumps({ 'email': '*****@*****.**', 'password': '******', 'token': 'goodtoken', }), 'application/json') self.assertEqual(response.status_code, 409, response.content) with self.settings(FACEBOOK_TEST_ID='facebookid'): response = self.client.post( '/api/login/facebook', ujson.dumps({ 'email': '*****@*****.**', 'password': '******', 'token': 'goodtoken', }), 'application/json') self.assertEqual(response.status_code, 409, response.content)
def setUpTestData(cls): super().setUpTestData() cls.user = models.User.objects.create(email=UserTestCase.USER_EMAIL) models.MyLogin.objects.create( user=cls.user, pw_hash=password_hasher().hash(UserTestCase.USER_PASSWORD))
def _my_login_session_post(request): if not request.body: return HttpResponseBadRequest('no HTTP body') # pragma: no cover json_ = None try: json_ = ujson.loads(request.body) except ValueError: # pragma: no cover return HttpResponseBadRequest('HTTP body cannot be parsed') if type(json_) is not dict: return HttpResponseBadRequest('JSON body must be object') # pragma: no cover if 'email' not in json_: return HttpResponseBadRequest('\'email\' missing') if type(json_['email']) is not str: return HttpResponseBadRequest('\'email\' must be string') if 'password' not in json_: return HttpResponseBadRequest('\'password\' missing') if type(json_['password']) is not str: return HttpResponseBadRequest('\'password\' must be string') my_login = None try: my_login = models.MyLogin.objects.get( user__email__iexact=json_['email']) except models.MyLogin.DoesNotExist: return HttpResponseForbidden() try: password_hasher().verify(my_login.pw_hash, json_['password']) except argon2.exceptions.VerifyMismatchError: return HttpResponseForbidden() session = models.Session.objects.create( user=my_login.user, expires_at=datetime.datetime.utcnow() + _SESSION_EXPIRY_INTERVAL, ) content, content_type = query_utils.serialize_content(str(session.uuid)) return HttpResponse(content, content_type)
def setUpTestData(cls): super().setUpTestData() cls.user = models.User.objects.create(email=UserTestCase.USER_EMAIL) models.MyLogin.objects.create(user=cls.user, pw_hash=password_hasher().hash( UserTestCase.USER_PASSWORD)) cls.session = models.Session.objects.create( user=cls.user, expires_at=(datetime.datetime.utcnow() + datetime.timedelta(days=2))) cls.session_token = cls.session.uuid cls.session_token_str = str(cls.session.uuid) user2 = models.User.objects.create(email=UserTestCase.NON_UNIQUE_EMAIL) models.MyLogin.objects.create( user=user2, pw_hash=password_hasher().hash('password2'))
def test_my_login(self): user = models.User.objects.create( email='*****@*****.**') self.assertIsNone(user.my_login()) del user._my_login models.MyLogin.objects.create( user=user, pw_hash=password_hasher().hash('mypassword')) self.assertIsNotNone(user.my_login())
def test_my_login_post_already_exists(self): user = models.User.objects.create(email='*****@*****.**') models.MyLogin.objects.create( user=user, pw_hash=password_hasher().hash('mypassword')) response = self.client.post( '/api/login/my', ujson.dumps({ 'email': '*****@*****.**', 'password': '******', }), 'application/json') self.assertEqual(response.status_code, 409, response.content)
def _my_login_post(request): if not request.body: return HttpResponseBadRequest('no HTTP body') # pragma: no cover json_ = None try: json_ = ujson.loads(request.body) except ValueError: # pragma: no cover return HttpResponseBadRequest('HTTP body cannot be parsed') if type(json_) is not dict: return HttpResponseBadRequest('JSON body must be object') # pragma: no cover if 'email' not in json_: return HttpResponseBadRequest('\'email\' missing') if type(json_['email']) is not str: return HttpResponseBadRequest('\'email\' must be string') if not validators.email(json_['email']): return HttpResponseBadRequest('\'email\' malformed') if 'password' not in json_: return HttpResponseBadRequest('\'password\' missing') if type(json_['password']) is not str: return HttpResponseBadRequest('\'password\' must be string') if models.MyLogin.objects.filter(user__email__iexact=json_['email']).exists(): return HttpResponse('login already exists', status=409) with transaction.atomic(): user = None verification_token = None try: user = models.User.objects.get(email__iexact=json_['email']) except models.User.DoesNotExist: user = models.User.objects.create(email=json_['email']) verification_token = models.VerificationToken.objects.create(user=user, expires_at=( datetime.datetime.utcnow() + _USER_VERIFICATION_EXPIRY_INTERVAL)) models.MyLogin.objects.create( pw_hash=password_hasher().hash(json_['password']), user=user) if verification_token is not None: _prepare_verify_notification( verification_token.token_str(), json_['email']) return HttpResponse(status=204)
def test_my_login_session_post(self): user = models.User.objects.create(email='*****@*****.**') models.MyLogin.objects.create( user=user, pw_hash=password_hasher().hash('mypassword')) response = self.client.post( '/api/login/my/session', ujson.dumps({ 'email': '*****@*****.**', 'password': '******', }), 'application/json') self.assertEqual(response.status_code, 200, response.content) json_ = ujson.loads(response.content) self.assertIsInstance(json_, str)
def _passwordresettoken_reset_post(request): token = request.POST.get('token') if token is None: return HttpResponseBadRequest('\'token\' missing') password = request.POST.get('password') if password is None: return HttpResponseBadRequest('\'password\' missing') password_reset_token = models.PasswordResetToken.find_by_token(token) if password_reset_token is None: return HttpResponseNotFound('token not valid') my_login = models.MyLogin.objects.get(user_id=password_reset_token.user_id) my_login.pw_hash = password_hasher().hash(password) with transaction.atomic(): my_login.save(update_fields=['pw_hash']) password_reset_token.delete() return HttpResponse(status=204)
def _user_put(request): if not request.body: return HttpResponseBadRequest('no HTTP body') # pragma: no cover json_ = None try: json_ = ujson.loads(request.body) except ValueError: # pragma: no cover return HttpResponseBadRequest('HTTP body cannot be parsed') if type(json_) is not dict: return HttpResponseBadRequest( 'JSON body must be object') # pragma: no cover user = request.user has_changed = False verification_token = None if 'email' in json_: if type(json_['email']) is not str: return HttpResponseBadRequest('\'email\' must be string') if not validators.email(json_['email']): return HttpResponseBadRequest( '\'email\' malformed') # pragma: no cover if user.email != json_['email']: if models.User.objects.filter(email=json_['email']).exists(): return HttpResponse('email already in use', status=409) user.email = json_['email'] verification_token = models.VerificationToken( user=user, expires_at=(datetime.datetime.utcnow() + _USER_VERIFICATION_EXPIRY_INTERVAL)) has_changed = True my_login = None if 'my' in json_: my_json = json_['my'] if type(my_json) is not dict: return HttpResponseBadRequest('\'my\' must be object') my_login = user.my_login() if 'password' in my_json: password_json = my_json['password'] if type(password_json) is not dict: return HttpResponseBadRequest('\'password\' must be object') if 'old' not in password_json: return HttpResponseBadRequest('\'old\' missing') if type(password_json['old']) is not str: return HttpResponseBadRequest('\'old\' must be string') if 'new' not in password_json: return HttpResponseBadRequest('\'new\' missing') if type(password_json['new']) is not str: return HttpResponseBadRequest('\'new\' must be string') try: password_hasher().verify(my_login.pw_hash, password_json['old']) except argon2.exceptions.VerifyMismatchError: return HttpResponseForbidden() my_login.pw_hash = password_hasher().hash(password_json['new']) has_changed = True google_login_db_fn = None if 'google' in json_: google_json = json_['google'] if google_json is None: def google_login_db_fn(): return _google_login_delete(user) has_changed = True elif type(google_json) is dict: google_login = None try: google_login = models.GoogleLogin.objects.get(user=user) except models.GoogleLogin.DoesNotExist: google_login = models.GoogleLogin(user=user) def google_login_db_fn(): return _google_login_save(google_login) if 'token' in google_json: if type(google_json['token']) is not str: return HttpResponseBadRequest('\'token\' must be string') try: google_login.g_user_id = google.get_id( google_json['token']) except ValueError: # pragma: no cover return HttpResponseBadRequest('bad Google token') has_changed = True else: return HttpResponseBadRequest('\'google\' must be object or null') facebook_login_db_fn = None if 'facebook' in json_: facebook_json = json_['facebook'] if facebook_json is None: def facebook_login_db_fn(): return _facebook_login_delete(user) has_changed = True elif type(facebook_json) is dict: facebook_login = None try: facebook_login = models.FacebookLogin.objects.get(user=user) except models.FacebookLogin.DoesNotExist: facebook_login = models.FacebookLogin(user=user) def facebook_login_db_fn(): return _facebook_login_save(facebook_login) if 'token' in facebook_json: if type(facebook_json['token']) is not str: return HttpResponseBadRequest('\'token\' must be string') try: facebook_login.profile_id = facebook.get_id( facebook_json['token']) except ValueError: # pragma: no cover return HttpResponseBadRequest('bad Facebook token') has_changed = True else: return HttpResponseBadRequest( '\'facebook\' must be object or null') if has_changed: with transaction.atomic(): user.save() if my_login is not None: my_login.save() if google_login_db_fn is not None: google_login_db_fn() if facebook_login_db_fn is not None: facebook_login_db_fn() if verification_token is not None: models.VerificationToken.objects.filter(user=user).delete() verification_token.save() token_str = verification_token.token_str() subject = verifyrender.subject() plain_text = verifyrender.plain_text(token_str) html_text = verifyrender.html_text(token_str) email_queue_entry = models.NotifyEmailQueueEntry.objects.create( subject=subject, plain_text=plain_text, html_text=html_text) models.NotifyEmailQueueEntryRecipient.objects.create( type=models.NotifyEmailQueueEntryRecipient.TYPE_TO, email=json_['email'], entry=email_queue_entry) return HttpResponse(status=204)