Beispiel #1
0
def update_user_fields(data, user):
    if user.id != 1:
        original_username = str(user.username)
        if 'username' in data and data['username']:
            user_db = User.query.filter_by(username=data['username']).first()
            if user_db is None or user_db.id == user.id:
                user.username = data['username']
            else:
                return Problem(HTTPStatus.BAD_REQUEST, 'Cannot update user.',
                               f"Username {data['username']} is already taken.")
        elif 'new_username' in data and data['new_username']:
            user_db = User.query.filter_by(username=data['old_username']).first()
            if user_db is None or user_db.id == user.id:
                user.username = data['new_username']
            else:
                return Problem(HTTPStatus.BAD_REQUEST, 'Cannot update user.',
                               f"Username {data['new_username']} is already taken.")
        if 'old_password' in data and 'password' in data and \
                data['old_password'] != "" and data['password'] != "":
            logger.info("go there")
            if user.verify_password(data['old_password']):
                user.password = data['password']
            else:
                user.username = original_username
                return Problem.from_crud_resource(
                    HTTPStatus.UNAUTHORIZED,
                    'user',
                    'update',
                    'Current password is incorrect.')
        db.session.commit()
        current_app.logger.info(f"Updated user {user.id}. Updated to: {user.as_json()}")
        return user.as_json(), HTTPStatus.OK
    else:
        return None, HTTPStatus.FORBIDDEN
Beispiel #2
0
def update_personal_user(username):
    data = request.get_json()
    current_user = get_jwt_identity()

    # check for internal user
    if username.id == 1:
        return Problem.from_crud_resource(
            HTTPStatus.FORBIDDEN,
            'user',
            'update',
            f"Current user does not have permission to update user {username.id}.")

    # check password
    if username.verify_password(data['old_password']):
        if username.id == current_user:
            # allow ability to update username/password but not roles/active
            if username.id == 2:
                username.set_roles([2])
                username.active = True
                return update_user_fields(data, username)
            else:
                return update_user_fields(data, username)
        else:
            return Problem.from_crud_resource(
                HTTPStatus.FORBIDDEN,
                'user',
                'update',
                f"Current user does not have permission to update user {username.id}.")
    else:
        return None, HTTPStatus.FORBIDDEN
Beispiel #3
0
    def __func():
        config_in = request.get_json()
        if not _reset_token_durations(access_token_duration=config_in.get(
                'access_token_duration', None),
                                      refresh_token_duration=config_in.get(
                                          'refresh_token_duration', None)):
            return Problem.from_crud_resource(
                HTTPStatus.BAD_REQUEST, 'configuration', 'update',
                'Access token duration must be less than refresh token duration.'
            )

        for config, config_value in config_in.items():
            if hasattr(api_gateway.config.Config, config.upper()):
                setattr(api_gateway.config.Config, config.upper(),
                        config_value)
            elif hasattr(current_app.config, config.upper()):
                setattr(current_app.config, config.upper(), config_value)

        current_app.logger.info('Changed configuration')
        try:
            api_gateway.config.Config.write_values_to_file()
            return __get_current_configuration(), HTTPStatus.OK
        except (IOError, OSError) as e:
            current_app.logger.error(
                'Could not write changes to configuration to file')
            return Problem(
                HTTPStatus.INTERNAL_SERVER_ERROR,
                'Could not write changes to file.',
                'Could not write configuration changes to file. Problem: {}'.
                format(format_exception_message(e)))
Beispiel #4
0
def stream_console_events():
    workflow_execution_id = request.args.get('workflow_execution_id')
    if workflow_execution_id is None:
        return Problem(HTTPStatus.BAD_REQUEST,
                       'Could not connect to log stream',
                       'workflow_execution_id is a required query param')
    try:
        UUID(workflow_execution_id)
        return console_stream.stream(subchannel=workflow_execution_id)
    except (ValueError, AttributeError):
        return Problem(HTTPStatus.BAD_REQUEST,
                       'Could not connect to log stream',
                       'workflow_execution_id must be a valid UUID')
Beispiel #5
0
def update_user(user_id):
    data = request.get_json()
    current_user = get_jwt_identity()

    # check for internal user
    if user_id.id == 1:
        return None, HTTPStatus.FORBIDDEN

    if user_id.id == current_user:
        # check for super_admin, allows ability to update username/password but not roles/active
        if user_id.id == 2:
            user_id.set_roles([2])
            user_id.active = True
            return update_user_fields(data, user_id)
        return role_update_user_fields(data, user_id, update=True)
    else:
        # check for super_admin
        if user_id.id == 2:
            return None, HTTPStatus.FORBIDDEN
        else:
            response = role_update_user_fields(data, user_id, update=True)
            if isinstance(response, tuple) and response[1] == HTTPStatus.FORBIDDEN:
                current_app.logger.error(f"User {current_user} does not have permission to update user {user_id.id}")
                return Problem.from_crud_resource(
                    HTTPStatus.FORBIDDEN,
                    'user',
                    'update',
                    f"Current user does not have permission to update user {user_id.id}.")
            else:
                return response
Beispiel #6
0
def create_role():
    json_data = request.get_json()
    if not Role.query.filter_by(name=json_data['name']).first():
        resources = json_data['resources'] if 'resources' in json_data else []
        if '/roles' in resources:
            resources.remove('/roles')
        role_params = {
            'name':
            json_data['name'],
            'description':
            json_data['description'] if 'description' in json_data else '',
            'resources':
            resources
        }
        new_role = Role(**role_params)
        db.session.add(new_role)
        db.session.commit()
        current_app.logger.info(f"Role added: {role_params}")
        return new_role.as_json(), HTTPStatus.CREATED
    else:
        current_app.logger.warning(
            f"Role with name {json_data['name']} already exists")
        return Problem.from_crud_resource(
            HTTPStatus.BAD_REQUEST, 'role', 'create',
            f"Role with name {json_data['name']} already exists")
Beispiel #7
0
 def __func():
     data = request.get_json()
     refresh_token = data.get('refresh_token', None) if data else None
     if refresh_token is None:
         return Problem(HTTPStatus.BAD_REQUEST, 'Could not logout.', 'A refresh token is required to logout.')
     decoded_refresh_token = decode_token(refresh_token)
     refresh_token_identity = decoded_refresh_token[current_app.config['JWT_IDENTITY_CLAIM']]
     user_id = get_jwt_identity()
     if user_id == refresh_token_identity:
         user = User.query.filter(User.id == user_id).first()
         if user is not None:
             user.logout()
         revoke_token(decode_token(refresh_token))
         return None, HTTPStatus.NO_CONTENT
     else:
         return Problem(
             HTTPStatus.BAD_REQUEST,
             'Could not logout.',
             'The identity of the refresh token does not match the identity of the authentication token.')
Beispiel #8
0
def delete_user(user_id):
    if user_id.id != get_jwt_identity() and user_id.id != 1 and user_id.id != 2:
        db.session.delete(user_id)
        db.session.commit()
        current_app.logger.info(f"User {user_id.username} deleted")
        return None, HTTPStatus.NO_CONTENT
    else:
        if user_id.id == get_jwt_identity():
            current_app.logger.error(f"Could not delete user {user_id.id}. User is current user.")
            return Problem.from_crud_resource(HTTPStatus.FORBIDDEN, 'user', 'delete',
                                              'Current user cannot delete self.')
        if user_id.id == 2:
            current_app.logger.error(f"Could not delete user {user_id.username}. "
                                     f"You do not have permission to delete Super Admin.")
            return Problem.from_crud_resource(HTTPStatus.FORBIDDEN, 'user', 'delete',
                                              'A user cannot delete Super Admin.')
        if user_id.id == 1:
            current_app.logger.error(f"Could not delete user {user_id.username}. "
                                     f"You do not have permission to delete WALKOFF's internal user.")
            return Problem.from_crud_resource(HTTPStatus.FORBIDDEN, 'user', 'delete',
                                              "A user cannot delete WALKOFF's internal user.")
Beispiel #9
0
def refresh(body=None, token_info=None, user=None):
    current_user_id = get_jwt_identity()
    user = User.query.filter(User.id == current_user_id).first()
    if user is None:
        revoke_token(get_raw_jwt())
        return Problem(
            HTTPStatus.UNAUTHORIZED,
            'Could not grant access token.',
            'User {} from refresh JWT identity could not be found.'.format(current_user_id))
    if user.active:
        return {'access_token': create_access_token(identity=current_user_id, fresh=False)}, HTTPStatus.CREATED
    else:
        return user_deactivated_problem
Beispiel #10
0
def delete_user(user_id):
    if user_id.id != get_jwt_identity(
    ) and user_id.username != "internal_user":
        db.session.delete(user_id)
        db.session.commit()
        current_app.logger.info(f"User {user_id.username} deleted")
        return None, HTTPStatus.NO_CONTENT
    else:
        current_app.logger.error(
            f"Could not delete user {user_id.id}. User is current user.")
        return Problem.from_crud_resource(HTTPStatus.FORBIDDEN, 'user',
                                          'delete',
                                          'Current user cannot delete self.')
Beispiel #11
0
    def __func():
        # TODO: Remove this once connexion can validate enums with openapi3.
        if field_name not in [
                'info', 'action_apis', 'condition_apis', 'transform_apis',
                'device_apis', 'tags', 'externalDocs'
        ]:
            return Problem(HTTPStatus.BAD_REQUEST, 'Could not read app api.',
                           '{} is not a valid field name.'.format(field_name))

        api = json.loads(redis_cache.hget("app-apis", app_name))
        if api is not None:
            return format_full_app_api(api,
                                       app_name)[field_name], HTTPStatus.OK
        else:
            return app_api_dne_problem(app_name)
Beispiel #12
0
def update_settings():
    config_in = request.get_json()
    if not _reset_token_durations(access_token_duration=config_in.get('access_token_duration', None),
                                  refresh_token_duration=config_in.get('refresh_token_duration', None)):
        return Problem.from_crud_resource(
            HTTPStatus.BAD_REQUEST,
            'settings',
            'update',
            'Access token duration must be less than refresh token duration.')

    for config, config_value in config_in.items():
        if hasattr(api_gateway.flask_config.FlaskConfig, config.upper()):
            setattr(api_gateway.flask_config.FlaskConfig, config.upper(), config_value)
        elif hasattr(current_app.config, config.upper()):
            setattr(current_app.config, config.upper(), config_value)

    current_app.logger.info('Changed settings')
Beispiel #13
0
def create_user():
    data = request.get_json()
    username = data['username']
    if not User.query.filter_by(username=username).first():
        user = add_user(username=username, password=data['password'])

        if 'roles' in data or 'active' in data:
            role_update_user_fields(data, user)

        db.session.commit()
        current_app.logger.info(f'User added: {user.as_json()}')
        return user.as_json(), HTTPStatus.CREATED
    else:
        current_app.logger.warning(
            f'Cannot create user {username}. User already exists.')
        return Problem.from_crud_resource(
            HTTPStatus.BAD_REQUEST, 'user', 'create',
            f'User with username {username} already exists')
Beispiel #14
0
    def __func():
        # TODO: Remove this once connexion can validate enums with openapi3.
        if field_name and field_name not in [
                'info', 'action_apis', 'condition_apis', 'transform_apis',
                'device_apis', 'tags', 'external_docs'
        ]:
            return Problem(HTTPStatus.BAD_REQUEST, 'Could not read app api.',
                           '{} is not a valid field name.'.format(field_name))

        ret = []
        for app_name, app_api in redis_cache.hgetall("app-apis").items():
            ret.append(
                format_full_app_api(json.loads(app_api),
                                    app_name.decode("utf-8")))
        if field_name is not None:
            default = [] if field_name not in ('info', 'external_docs') else {}
            ret = [{
                'name': api['name'],
                field_name: api.get(field_name, default)
            } for api in ret]
        return ret, HTTPStatus.OK
Beispiel #15
0
def update_user(user_id):
    data = request.get_json()
    current_user = get_jwt_identity()

    if user_id.username == "internal_user":
        return None, HTTPStatus.FORBIDDEN

    if user_id.id == current_user:
        return update_user_fields(data, user_id)
    else:
        response = role_update_user_fields(data, user_id, update=True)
        if isinstance(response, tuple) and response[1] == HTTPStatus.FORBIDDEN:
            current_app.logger.error(
                f"User {current_user} does not have permission to update user {user_id.id}"
            )
            return Problem.from_crud_resource(
                HTTPStatus.FORBIDDEN, 'user', 'update',
                f"Current user does not have permission to update user {user_id.id}."
            )
        else:
            return response
Beispiel #16
0
    def __func(workflow):
        if not workflow.is_valid:
            return Problem(HTTPStatus.BAD_REQUEST, 'Cannot execute workflow',
                           'Workflow is invalid')

        # Short circuits the multiprocessed executor
        workflow = current_app.running_context.execution_db.session.query(
            Workflow).filter_by(id=workflow_id).first()
        workflow_schema = WorkflowSchema()
        workflow = workflow_schema.dump(workflow)
        execution_id = str(uuid.uuid4())

        workflow_data = {
            'execution_id': execution_id,
            'id': workflow["id"],
            'name': workflow["name"]
        }
        current_app.running_context.results_sender.handle_event(
            workflow=workflow,
            sender=workflow_data,
            event=WalkoffEvent.WorkflowExecutionPending,
            data=data)

        message = {
            "workflow": workflow,
            "workflow_id": str(workflow_id),
            "execution_id": execution_id
        }
        current_app.running_context.cache.lpush(
            "workflow-queue",
            json.dumps(message))  # self.__box.encrypt(message))

        current_app.running_context.results_sender.handle_event(
            workflow=workflow,
            sender=workflow_data,
            event=WalkoffEvent.SchedulerJobExecuted,
            data=data)

        current_app.logger.info('Executed workflow {0}'.format(workflow_id))
        return {'id': execution_id}, HTTPStatus.ACCEPTED
Beispiel #17
0
from flask import request, current_app
from flask_jwt_extended import (jwt_refresh_token_required, create_access_token, create_refresh_token, get_jwt_identity,
                                get_raw_jwt, jwt_required, decode_token)

from api_gateway.server.problem import Problem
from http import HTTPStatus
from api_gateway.serverdb import User, db
from api_gateway.serverdb.tokens import revoke_token

token_problem_title = 'Could not grant access token.'
invalid_username_password_problem = Problem(
    HTTPStatus.UNAUTHORIZED, token_problem_title, 'Invalid username or password.')
user_deactivated_problem = Problem(HTTPStatus.UNAUTHORIZED, token_problem_title, 'User is deactivated.')


def _authenticate_and_grant_tokens(json_in, with_refresh=False):
    username = json_in.get('username', None)
    password = json_in.get('password', None)
    if not (username and password):
        return invalid_username_password_problem

    user = User.query.filter_by(username=username).first()
    if user is None:
        return invalid_username_password_problem
    try:
        password = password.encode('utf-8')
    except UnicodeEncodeError:
        return invalid_username_password_problem
    if not user.active:
        return user_deactivated_problem
    if user.verify_password(password):
Beispiel #18
0
def scheduled_task_name_already_exists_problem(name, operation):
    return Problem.from_crud_resource(
        HTTPStatus.BAD_REQUEST, 'scheduled task', operation,
        'Could not {} scheduled task. Scheduled task with name {} already exists.'
        .format(operation, name))
Beispiel #19
0
def invalid_uuid_problem(invalid_uuids):
    return Problem(HTTPStatus.BAD_REQUEST, 'Invalid scheduled task.',
                   'Specified UUIDs {} are not valid.'.format(invalid_uuids))
Beispiel #20
0

def invalid_uuid_problem(invalid_uuids):
    return Problem(HTTPStatus.BAD_REQUEST, 'Invalid scheduled task.',
                   'Specified UUIDs {} are not valid.'.format(invalid_uuids))


def scheduled_task_name_already_exists_problem(name, operation):
    return Problem.from_crud_resource(
        HTTPStatus.BAD_REQUEST, 'scheduled task', operation,
        'Could not {} scheduled task. Scheduled task with name {} already exists.'
        .format(operation, name))


invalid_scheduler_args_problem = Problem(HTTPStatus.BAD_REQUEST,
                                         'Invalid scheduled task.',
                                         'Invalid scheduler arguments.')


def create_scheduled_task():
    @jwt_required
    @permissions_accepted_for_resources(
        ResourcePermissions('scheduler', ['create', 'execute']))
    def __func():
        data = request.get_json()
        invalid_uuids = validate_uuids(data['workflows'])
        if invalid_uuids:
            return invalid_uuid_problem(invalid_uuids)
        task = ScheduledTask.query.filter_by(name=data['name']).first()
        if task is None:
            try:
Beispiel #21
0
def handle_generic_server_error(e):
    current_app.logger.exception('Caught an unhandled error.')
    return Problem(HTTPStatus.INTERNAL_SERVER_ERROR,
                   'An error occurred in the server.', e.__class__.__name__)
Beispiel #22
0
def handle_database_errors(e):
    current_app.logger.exception('Caught an unhandled SqlAlchemy exception.')
    return Problem(HTTPStatus.INTERNAL_SERVER_ERROR,
                   'A database error occurred.', e.__class__.__name__)
Beispiel #23
0
def app_api_dne_problem(app_name):
    return Problem(HTTPStatus.NOT_FOUND, 'Could not read app api.',
                   'App {} does not exist.'.format(app_name))