Example #1
0
    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))
Example #3
0
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)
Example #4
0
    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'))
Example #5
0
    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())
Example #6
0
    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)
Example #7
0
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)
Example #8
0
    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)
Example #9
0
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)
Example #10
0
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)