Ejemplo n.º 1
0
def users_put_view(request):
    """
    Used for forgotten password requests
    """
    # TODO Make tests for this
    # TODO Make this a temporary reset link thing instead of actually resetting passwords to random
    if request.user is not None:
        request.response.status = 400
        return {
            'd': error_dict('api_errors',
                            'you are already logged in, ignoring')
        }
    username = request.json_body.get('username')
    email = request.json_body.get('email')
    if not isinstance(username, basestring) or not isinstance(
            email, basestring):
        request.response.status = 400
        return {
            'd':
            error_dict('api_errors',
                       'username and email are required string fields')
        }
    user = request.dbsession.query(User).filter(
        User.username == username.lower()).one_or_none()
    if user is None or user.email != email.lower():
        request.response.status = 400
        return {'d': error_dict('api_errors', 'invalid state found')}
    uid = uuid4()
    newpass = uid.hex
    user.salt = os.urandom(256)
    user.password = hash_password(newpass, user.salt)

    # This needs to be written to whatever queues/sends an email out.
    # send_email.apply_async((user.email, "pyrapostbin password recovery", recovery_template %(username, newpass)))
    return {'d': 'recovery email sent'}
Ejemplo n.º 2
0
 def test_missing_parameters(self):
     """
     If we don't pass in all the required parameters, get an error
     """
     self.assertEqual(0, self.session.query(User).count())
     for i in ['username', 'email', 'password']:
         self.request.json_body = deepcopy(self.new_account)
         del self.request.json_body[i]
         result = users_post_view(self.request)['d']
         self.assertEqual(
             result,
             error_dict(
                 'api_errors',
                 'username, email, and password are all required string fields'
             ))
     self.request.json_body = {}
     result = users_post_view(self.request)['d']
     self.assertEqual(
         result,
         error_dict(
             'api_errors',
             'username, email, and password are all required string fields')
     )
     self.request.json_body = {'username': '******'}
     result = users_post_view(self.request)['d']
     self.assertEqual(
         result,
         error_dict(
             'api_errors',
             'username, email, and password are all required string fields')
     )
Ejemplo n.º 3
0
    def test_bad_emails(self):
        """
        If we pass a bad email, get an error about it
        """
        bad_email = 'invalid@spaced domain.com'
        email_result = {}
        try:
            validate_email(bad_email)  # validate and get info
            self.fail('Validate email did not raise exception, fix the test')
        except EmailNotValidError as e:
            # email is not valid, exception message is human-readable
            email_result = error_dict('api_errors', 'email invalid: %s' % e)

        self.request.json_body = deepcopy(self.good_dict)
        self.request.json_body['email'] = bad_email
        result = user_id_put_view(self.request)['d']
        self.assertEqual(result, email_result)
        self.assertNotEqual(result, {})

        self.request.json_body = deepcopy(self.good_dict)
        self.request.json_body['email'] = 234234  # Not a string
        result = user_id_put_view(self.request)['d']
        self.assertEqual(
            result, error_dict('api_errors',
                               'email invalid: must be a string'))
Ejemplo n.º 4
0
def users_post_view(request):
    username = request.json_body.get('username')
    if not isinstance(username, basestring):
        request.response.status = 400
        return {
            'd':
            error_dict(
                'api_errors',
                'username, email, and password are all required string fields')
        }
    if username_in_use(request.json_body['username'], request.dbsession):
        request.response.status = 400
        return {
            'd':
            error_dict(
                'verification_error',
                'username already in use: %s' % request.json_body['username'])
        }

    requires = ['email', 'password']
    if not all(field in request.json_body for field in requires) \
       or not all(isinstance(request.json_body.get(field), basestring) for field in request.json_body):
        request.response.status = 400
        return {
            'd':
            error_dict(
                'api_errors',
                'username, email, and password are all required string fields')
        }

    user = User()
    user.salt = os.urandom(256)
    user.password = hash_password(request.json_body['password'], user.salt)
    user.username = request.json_body['username'].lower()
    user.email = request.json_body['email'].lower()
    user.origin = request.json_body.get('origin', None)
    user.authpin = '123456'

    request.dbsession.add(user)
    request.dbsession.flush()
    request.dbsession.refresh(user)

    s = Session()
    s.owner = user.id
    s.token = str(uuid4())
    request.dbsession.add(s)
    request.dbsession.flush()
    request.dbsession.refresh(s)
    result = dict_from_row(user, remove_fields=removals)
    result['session'] = dict_from_row(s, remove_fields=removals)

    return {'d': result}
Ejemplo n.º 5
0
def user_id_get_view(request):
    if request.user is None:
        request.response.status = 400
        return {
            'd': error_dict('api_errors', 'not authenticated for this request')
        }
    if not request.matchdict.get('user_id') or int(
            request.matchdict.get('user_id')) != request.user.id:
        request.response.status = 400
        return {
            'd': error_dict('api_errors', 'not authenticated for this request')
        }
    user = request.user
    result = dict_from_row(user, remove_fields=removals)
    return {'d': result}
Ejemplo n.º 6
0
 def test_not_logged_in(self):
     """
     If we aren't logged in, get an api error
     """
     self.request.user = None
     result = user_id_put_view(self.request)['d']
     self.assertEqual(result, error_dict('api_errors', 'not authenticated for this request'))
Ejemplo n.º 7
0
 def test_no_user(self):
     """
     If we try to get info without a login, get an error back
     """
     self.request.user = None
     result = user_id_get_view(self.request)['d']
     self.assertEqual(result, error_dict('api_errors', 'not authenticated for this request'))
Ejemplo n.º 8
0
 def test_wrong_id(self):
     """
     If we don't use the right id in the url, get an api error
     """
     self.request.matchdict = {'user_id': int(self.request.user.id)+4}
     self.request.json_body = {}
     result = user_id_put_view(self.request)['d']
     self.assertEqual(result, error_dict('api_errors', 'not authenticated for this request'))
Ejemplo n.º 9
0
 def test_bad_password_type(self):
     """
     If we pass in anything but a string, get an error indicating so
     """
     for val in [x for x in bad_data_typevals_list if not isinstance(x, basestring) and x is not None]:
         self.request.json_body = deepcopy(self.good_dict)
         self.request.json_body['password'] = val
         result = user_id_put_view(self.request)['d']
         self.assertEqual(result, error_dict('api_errors', 'password must be a string'))
Ejemplo n.º 10
0
 def test_no_user_matchdict(self):
     """
     If we try to get info a login but not the same ID in the url, get an error back
     """
     user = self.datautils.create_user()
     self.request.matchdict = {'user_id': user.id + 4}
     self.request.user = user
     result = user_id_get_view(self.request)['d']
     self.assertEqual(result, error_dict('api_errors', 'not authenticated for this request'))
Ejemplo n.º 11
0
 def test_username_not_in_use(self):
     """
     If we provide a username that is not in use, get False
     """
     self.request.json_body = {'username': '******'}
     self.datautils.create_user({'username': '******', 'password': '******'})
     result = users_post_view(self.request)['d']
     self.assertIsInstance(result, dict)
     self.assertEqual(result, error_dict('api_errors', 'username, email, and password are all required string fields'))
Ejemplo n.º 12
0
 def test_username_in_use(self):
     """
     If we provide a username that is in use, get True
     """
     self.request.json_body = {'username': '******'}
     self.datautils.create_user({'username': '******', 'password': '******'})
     result = users_post_view(self.request)['d']
     self.assertIsInstance(result, dict)
     self.assertEqual(result, error_dict('verification_error', 'username already in use: testuser'))
Ejemplo n.º 13
0
 def test_username_taken(self):
     """
     If we try to create an account that is in use, get an api error
     """
     self.datautils.create_user({'username': '******'})
     self.assertEqual(1, self.session.query(User).count())
     self.request.json_body = deepcopy(self.new_account)
     result = users_post_view(self.request)['d']
     self.assertEqual(result, error_dict('verification_error',
                                         'username already in use: %s' % self.new_account['username']))
Ejemplo n.º 14
0
 def test_invalid_password(self):
     """
     If we give a string of insufficient complexity, error
     """
     self.request.json_body = deepcopy(self.good_dict)
     invalids = ['5horT']
     for val in invalids:
         self.request.json_body['password'] = val
         result = user_id_put_view(self.request)['d']
         self.assertEqual(result, error_dict('api_errors', 'password must be at least 8 characters'))
Ejemplo n.º 15
0
 def test_bad_parameters(self):
     """
     If we don't pass in all the right types, get an error
     """
     self.assertEqual(0, self.session.query(User).count())
     for i in ['username', 'email', 'password']:
         self.request.json_body = deepcopy(self.new_account)
         for val in [x for x in bad_data_typevals_list if not isinstance(x, basestring)]:
             self.request.json_body[i] = val
             result = users_post_view(self.request)['d']
             self.assertEqual(result, error_dict('api_errors',
                                                 'username, email, and password are all required string fields'))
Ejemplo n.º 16
0
def user_id_put_view(request):
    if request.user is None:
        request.response.status = 400
        return {
            'd': error_dict('api_errors', 'not authenticated for this request')
        }
    if not request.matchdict.get('user_id') or int(
            request.matchdict.get('user_id')) != request.user.id:
        request.response.status = 400
        return {
            'd': error_dict('api_errors', 'not authenticated for this request')
        }
    valid_types = {
        'email': basestring,
        'pin': basestring,
        'timezone': datetime,
        'infoemails': bool,
    }
    email = request.json_body.get('email')
    authpin = request.json_body.get('authpin')
    timezone = request.json_body.get('timezone')
    infoemails = request.json_body.get('infoemails')
    if not isinstance(email, basestring):
        request.response.status = 400
        return {
            'd': error_dict('api_errors', 'email invalid: must be a string')
        }
    try:
        v = validate_email(email)  # validate and get info
        email = v["email"]  # replace with normalized form
    except EmailNotValidError as e:
        # email is not valid, exception message is human-readable
        request.response.status = 400
        return {'d': error_dict('api_errors', 'email invalid: %s' % e)}
    password = request.json_body.get('password')
    # Password must be optional, since they don't know the old value
    if password is not None:
        if not isinstance(password, basestring):
            request.response.status = 400
            return {'d': error_dict('api_errors', 'password must be a string')}
        if len(password) < 8:
            request.response.status = 400
            return {
                'd':
                error_dict('api_errors',
                           'password must be at least 8 characters')
            }
        request.user.password = hash_password(password, request.user.salt)

    request.user.email = email

    request.dbsession.flush()
    request.dbsession.refresh(request.user)
    return {'d': dict_from_row(request.user, remove_fields=removals)}