Beispiel #1
0
    def setUp(self):
        '''called before each test'''
        # admin is already in the db
        user = UserRoles.get('user')
        manager_user = UserRoles.get('manager')

        db.session.add(
            UserDetails(
                first_name='user_first_name',
                last_name='user_last_name',
                username='******',
                email='*****@*****.**',
                password=UserDetails.generate_hash('user'),
                role_id=user['id'],
                enabled=True
            )
        )

        db.session.add(
            UserDetails(
                first_name='manager_first_name',
                last_name='manager_last_name',
                username='******',
                email='*****@*****.**',
                password=UserDetails.generate_hash('manager'),
                role_id=manager_user['id'],
                enabled=True
            )
        )
        db.session.commit()
Beispiel #2
0
    def test_update_user_manager(self):
        admin_user = th.get_user_details('manager')
        access_token = flask_jwt_extended.create_access_token(identity=admin_user)

        new_user_details = {
            'first_name': 'modified',
            'last_name': 'modififed',
            'email': '*****@*****.**'
        }
        username = '******'
        response = self.client.open(
            f'/api/v1/user/{username}',
            method='PUT',
            content_type='application/json',
            headers = {'Authorization': 'Bearer ' + access_token},
            data=json.dumps(new_user_details)
        )
        self.assertStatus(response, 403)

        username = '******'
        response = self.client.open(
            f'/api/v1/user/{username}',
            method='PUT',
            content_type='application/json',
            headers = {'Authorization': 'Bearer ' + access_token},
            data=json.dumps(new_user_details)
        )
        self.assertStatus(response, 200)

        data = UserDetails.get(username).to_dict()

        self.assertEqual(data['first_name'], 'modified')
        self.assertEqual(data['last_name'], 'modififed')
        self.assertEqual(data['username'], 'user')
        self.assertEqual(data['email'], '*****@*****.**')
        self.assertEqual(data['enabled'], True)

        new_user_details = {
            'first_name': 'modified',
            'last_name': 'modififed',
            'email': '*****@*****.**'
        }
        username = '******'
        response = self.client.open(
            f'/api/v1/user/{username}',
            method='PUT',
            content_type='application/json',
            headers = {'Authorization': 'Bearer ' + access_token},
            data=json.dumps(new_user_details)
        )
        self.assertStatus(response, 200)

        data = UserDetails.get(username).to_dict()

        self.assertEqual(data['first_name'], 'modified')
        self.assertEqual(data['last_name'], 'modififed')
        self.assertEqual(data['username'], 'manager')
        self.assertEqual(data['email'], '*****@*****.**')
        self.assertEqual(data['enabled'], True)
Beispiel #3
0
def delete_user(username, req_username, permission):
    '''delete a user'''
    try:
        user = get_user(username, req_username, permission)
        UserDetails.delete(username)
    except sqlalchemy.exc.SQLAlchemyError as ex:
        log.error(f'Error while deleting user {username} {ex}')
        raise error.StorageError(f'Error while deleting user {username}')

    log.info(f'User {username} deleted')
Beispiel #4
0
    def test_delete_user_admin_by_user(self):
        user = th.get_user_details('user')
        access_token = flask_jwt_extended.create_access_token(identity=user)

        self.assertEqual(len(UserDetails.get_all()), 3)
        username = '******'
        response = self.client.open(
            f'/api/v1/user/{username}',
            method='DELETE',
            content_type='application/json',
            headers = {'Authorization': 'Bearer ' + access_token}
        )
        self.assertStatus(response, 403)
        self.assertEqual(len(UserDetails.get_all()), 3)
Beispiel #5
0
def get_user_timezone_all(username):
    '''get all timezones for a user'''
    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    query = db.session.query(UserTimeZones, TimeZones, UserDetails.username)\
            .join(UserDetails, UserTimeZones.user_id == UserDetails.id)\
            .join(TimeZones, UserTimeZones.timezone_id == TimeZones.id)\
            .filter(UserDetails.username == username)

    try:
        req_list = query.all()
        ret_list = []

        for item in req_list:
            tz = item.TimeZones.to_dict()
            tz.update(item.UserTimeZones.to_dict())
            tz['username'] = item.username
            ret_list.append(tz)

        return {'data': ret_list}

    except sqlalchemy.exc.SQLAlchemyError as ex:
        log.error(f'Error while retrieving user timezones: {ex}')
        raise error.StorageError(
            f'Error while retrieving user {username} timezones')
Beispiel #6
0
def create_user_timezone(username, name, timezone_id):
    '''create a new user timezone'''
    if not name or not timezone_id:
        log.error(f'invalid input: {name}, {timezone_id}')
        raise ValueError('Invalid input values!')

    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    timezone = TimeZones.get(timezone_id)
    if not timezone:
        log.error(f'timezone {timezone_id} not found')
        raise error.RecordNotFoundError(f'requested timezone not found')

    res = _get_timezone_by_username_and_name(username, name)
    if res:
        raise error.StorageErrorConflict(f'timezone {name} already exists')

    new_user_timezone = UserTimeZones(user_id=user.id,
                                      name=name,
                                      timezone_id=timezone_id)

    try:
        db.session.add(new_user_timezone)
        db.session.commit()
    except sqlalchemy.exc.SQLAlchemyError as ex:
        db.session.rollback()
        log.error(f'Could not create timezone {name} for {username}: {ex}')
        raise error.StorageError(
            f'Could not add timezone {name} for user {username}!')

    log.info(f'User {username} created')
    return new_user_timezone
Beispiel #7
0
    def test_create_user(self):
        user_data = {
            'first_name': 'first_name',
            'last_name': 'last_name',
            'username': '******',
            'email': '*****@*****.**',
            'password': '******'
        }
        response = self.client.open(
            '/api/v1/user',
            method='POST',
            content_type='application/json',
            data=json.dumps(user_data)
        )
        self.assertStatus(response, 200)

        data = response.json

        self.assertEqual(data['first_name'], 'first_name')
        self.assertEqual(data['last_name'], 'last_name')
        self.assertEqual(data['username'], 'username')
        self.assertEqual(data['email'], '*****@*****.**')
        self.assertEqual(data['enabled'], False)
        self.assertNotIn('password', data)
        self.assertNotIn('role', data)

        db_data = UserDetails.get('username')
        self.assertEqual(db_data.role_id, None)
Beispiel #8
0
def enable_user(username, enable_value):
    '''enable/disble an existing user'''
    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    changed = False
    try:
        if user.enabled != enable_value:
            user.enabled = enable_value
            changed = True

        if changed:
            db.session.add(user)
            db.session.commit()
    except sqlalchemy.exc.SQLAlchemyError as ex:
        db.session.rollback()
        log.error(f'Could not update user {username}: {ex}')
        raise error.StorageError(f'Could not update user {username}!')
    except Exception as ex:
        db.session.rollback()
        log.error(f'Could not update user {username}: {ex}')
        raise

    enabled_str = 'enabled' if enable_value else 'disabled'
    log.info(f'User {username} {enabled_str}')
Beispiel #9
0
def authenticate_user(username, passwd):
    """
    generates jwt token for user
    """
    query = db.session.query(UserDetails, UserRoles).outerjoin(
        UserRoles, UserRoles.id == UserDetails.role_id)

    user = None
    if username is not None:
        query = query.filter(UserDetails.username == username)
        res = query.one_or_none()

        if res and (not res.UserDetails.enabled
                    or not res.UserDetails.role_id):
            raise error.AuthError(
                'User Account is not yet active, please contact support')

        if not (res
                and UserDetails.verify_hash(passwd, res.UserDetails.password)):
            raise error.AuthError('invalid user credentials')

        user = res.UserRoles.to_dict()
        user.update(res.UserDetails.to_dict())
    else:
        raise error.AuthError("invalid username format")

    access_token = flask_jwt_extended.create_access_token(identity=user)
    log.info(f'created JWT access tokens for user {username}: {access_token}')

    return {'access_token': access_token}
Beispiel #10
0
def check_user_enabled():
    user_identity = flask_jwt_extended.get_jwt_identity()
    user = UserDetails.get(user_identity)
    if not user:
        raise Exception('Could not identify user!')
    if not user.enabled:
        raise err.PermissionsError(
            'Account is diabled; please contact support for further details')
Beispiel #11
0
def create_user(first_name, last_name, username, email, password):
    '''create a new user'''
    if not first_name or not last_name or not username or not email or not password:
        log.error(
            f'invalid input: {first_name}, {last_name}, {username}, {email}, {password}'
        )
        raise ValueError('Invalid input values!')

    _check_name_field(first_name, 3)
    _check_name_field(last_name, 3)
    _check_name_field(username)
    _check_email_address_format(email)
    _check_passwd_field(password)

    user = UserDetails.get(username)
    if user:
        raise error.StorageErrorConflict('username already exists')

    user_email = db.session.query(UserDetails).filter_by(
        email=email).one_or_none()
    if user_email:
        raise error.StorageErrorConflict('email already registered')

    #user_role = get_user_role(role)

    new_user = UserDetails(first_name=first_name,
                           last_name=last_name,
                           username=username,
                           email=email,
                           password=UserDetails.generate_hash(password))

    try:
        db.session.add(new_user)
        db.session.commit()
    except sqlalchemy.exc.SQLAlchemyError as ex:
        db.session.rollback()
        log.error(f'Could not reate user {username}: {ex}')
        raise error.StorageError(f'Could not add user {username}!')

    log.info(f'User {username} created')

    user_info = new_user.to_dict()
    return user_info
Beispiel #12
0
    def test_get_all_users_inactive_account(self):
        from app.storage.user_details import UserDetails
        db.session.add(
            UserDetails(first_name='test',
                        last_name='test',
                        username='******',
                        email='*****@*****.**',
                        password=UserDetails.generate_hash('test'),
                        role_id=1,
                        enabled=False))
        db.session.commit()

        username = '******'
        passw = 'test'

        response = self.client.open('/api/v1/auth/login',
                                    method='POST',
                                    content_type='application/json',
                                    data=json.dumps({
                                        "username": username,
                                        "password": passw
                                    }))

        self.assertStatus(response, 401)
Beispiel #13
0
def delete_user_timezone(username, name):
    '''delete a user timezone'''
    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    timezone = _get_timezone_by_username_and_name(username, name)
    if not timezone:
        raise error.RecordNotFoundError(f'timezone {tz_name} not found')
    log.error(f'deleteing {timezone}')
    try:
        db.session.delete(timezone)
        db.session.commit()
    except sqlalchemy.exc.SQLAlchemyError as ex:
        db.session.rollback()
        log.error(f'Error while deleting timezone {name}: {ex}')
        raise error.StorageError(f'Error while deleting timezone {name}')

    log.info(f'timezone {name} deleted for user {username}')
Beispiel #14
0
def _validate_user_request(username, req_username, permission):
    '''checks if the requesting user has the right permissions for the requested action'''
    if not username == req_username:
        if permission == UserRolesEnum.user.value:
            raise error.PermissionsError()
        user_details = UserDetails.get(username)
        if not user_details:
            raise error.RecordNotFoundError(f'username {username} not found')
        if user_details.role_id:
            perm_query = db.session.query(UserRoles.permissions).join(
                UserDetails, UserRoles.id == UserDetails.role_id)
            perm_query = perm_query.filter(UserDetails.username == username)
            user_perm = perm_query.one_or_none()
            if not user_perm:
                raise error.RecordNotFoundError(
                    f'username {username} not found')
            if ((UserRolesEnum.user_privileged.value in user_perm.permissions
                 or UserRolesEnum.user_all.value in user_perm.permissions)
                    and not permission == UserRolesEnum.user_all.value):
                raise error.PermissionsError()
Beispiel #15
0
def get_user_timezone(username, name):
    '''get a user timezone'''
    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    query = db.session.query(UserTimeZones, TimeZones)\
            .join(UserDetails, UserTimeZones.user_id == UserDetails.id)\
            .join(TimeZones, UserTimeZones.timezone_id == TimeZones.id)\
            .filter(UserDetails.username == username)\
            .filter(UserTimeZones.name == name)

    res = query.one_or_none()
    if not res:
        raise error.RecordNotFoundError(
            f'user {username} timezone {name} not found')

    timezone = res.TimeZones.to_dict()
    timezone.update(res.UserTimeZones.to_dict())

    return timezone
Beispiel #16
0
    def test_get_all_users_admin(self):
        admin_user = th.get_user_details('admin')
        access_token = flask_jwt_extended.create_access_token(identity=admin_user)

        response = self.client.open(
            '/api/v1/user',
            method='GET',
            content_type='application/json',
            headers = {'Authorization': 'Bearer ' + access_token}
        )
        self.assertStatus(response, 200)

        data = response.json['data']

        self.assertEqual(len(UserDetails.get_all()), 3)
        self.assertEqual(len(data), 3)

        self.assertEqual(data[0]['first_name'], 'Administrator')
        self.assertEqual(data[0]['last_name'], 'SuperUser')
        self.assertEqual(data[0]['username'], 'admin')
        self.assertEqual(data[0]['email'], '*****@*****.**')
        self.assertEqual(data[0]['role'], 'admin')
        self.assertEqual(data[0]['enabled'], True)
        self.assertNotIn('password', data[0])

        self.assertEqual(data[1]['first_name'], 'user_first_name')
        self.assertEqual(data[1]['last_name'], 'user_last_name')
        self.assertEqual(data[1]['username'], 'user')
        self.assertEqual(data[1]['email'], '*****@*****.**')
        self.assertEqual(data[1]['role'], 'user')
        self.assertEqual(data[1]['enabled'], True)
        self.assertNotIn('password', data[1])

        self.assertEqual(data[2]['first_name'], 'manager_first_name')
        self.assertEqual(data[2]['last_name'], 'manager_last_name')
        self.assertEqual(data[2]['username'], 'manager')
        self.assertEqual(data[2]['email'], '*****@*****.**')
        self.assertEqual(data[2]['role'], 'manager')
        self.assertEqual(data[2]['enabled'], True)
        self.assertNotIn('password', data[2])
Beispiel #17
0
def update_user_timezone(username, tz_name, **kwargs):
    '''update a user timezone'''
    new_name = kwargs.get('name')
    timezone_id = kwargs.get('timezone_id')

    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    timezone = _get_timezone_by_username_and_name(username, tz_name)
    if not timezone:
        raise error.RecordNotFoundError(f'timezone {tz_name} not found')

    changed = False

    if new_name and timezone.name != new_name:
        tz = _get_timezone_by_username_and_name(username, new_name)
        if tz:
            raise error.StorageErrorConflict(
                f'timezone {new_name} already exists')

        timezone.name = new_name
        changed = True

    if timezone_id and timezone.timezone_id != timezone_id:
        timezone.timezone_id = timezone_id
        changed = True

    if changed:
        try:
            db.session.add(timezone)
            db.session.commit()
        except sqlalchemy.exc.SQLAlchemyError as ex:
            db.session.rollback()
            log.error(f'Could not update timezone {tz_name}: {ex}')
            raise error.StorageError(f'Could not update timezone {tz_name}!')

    log.info(f'timezone {tz_name} updated user {username}')
Beispiel #18
0
def update_user(username, req_username, permission, **kwargs):
    '''update an existing user'''
    _validate_user_request(username, req_username, permission)

    first_name = kwargs.get('first_name')
    last_name = kwargs.get('last_name')
    email = kwargs.get('email')
    password = kwargs.get('password')
    role = kwargs.get('role')

    role_id = None
    if role:
        if not permission == UserRolesEnum.user_all.value:
            raise error.PermissionsError(
                'insufficient permissions to update role')
        role_details = UserRoles.get(role)
        if not role_details:
            raise error.RecordNotFoundError(f'role {role} not found')
        role_id = role_details['id']

    if email:
        _check_email_address_format(email)

    user = UserDetails.get(username)
    if not user:
        raise error.RecordNotFoundError(f'username {username} not found')

    changed = False
    try:
        if role_id and user.role_id != role_id:
            user.role_id = role_id
            changed = True

        if first_name and user.first_name != first_name:
            _check_name_field(first_name, 3)
            user.first_name = first_name
            changed = True

        if last_name and user.last_name != last_name:
            _check_name_field(last_name, 3)
            user.last_name = last_name
            changed = True

        if email and user.email != email:
            _check_email_address_format(email)
            user.email = email
            changed = True

        if password and not UserDetails.verify_hash(password, user.password):
            _check_passwd_field(password)
            user.password = UserDetails.generate_hash(password)
            changed = True

        if changed:

            db.session.add(user)
            db.session.commit()
    except sqlalchemy.exc.SQLAlchemyError as ex:
        db.session.rollback()
        log.error(f'Could not update user {username}: {ex}')
        raise error.StorageError(f'Could not update user {username}!')
    except Exception as ex:
        db.session.rollback()
        log.error(f'Could not update user {username}: {ex}')
        raise

    log.info(f'User {username} updated')