Exemple #1
0
def delete_region(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    q = model.RegionProduct.query.filter(
        model.RegionProduct.region_id == region.id, )
    if q.count() > 0:
        for relation in q.all():
            db.session.delete(relation)
        db.session.flush()

    db.session.delete(region)

    try:
        owner_group = keycloak.group_get(region.owner_group)
        keycloak.group_delete(owner_group['id'])
        logger.info(f'Deleted owners group {owner_group["id"]}')

    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error',
                       f'Failed to delete owner group in Keycloak, {e}')

    db.session.commit()
    logger.info(
        f'Region {region.name} (id {region.id}) deleted by user {user}')
Exemple #2
0
def add_region_product(keycloak: KeycloakClient, region_id, body, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    product = model.Product.query.get(body['id'])
    if not product:
        return problem(404, 'Not Found',
                       f'Product {body["id"]} does not exist')

    q = model.RegionProduct.query.filter(
        sqlalchemy.and_(
            model.RegionProduct.region_id == region.id,
            model.RegionProduct.product_id == product.id,
        ))
    if q.count() == 0:
        relation = model.RegionProduct(
            region_id=region.id,
            product_id=product.id,
            enabled=body.get('enabled', True),
        )
        db.session.add(relation)
        db.session.commit()
        logger.info(
            f'Added Product {product.name} (id {product.id}) to Region {region.name} '
            f'(id {region.id}) by user {user}')
    elif 'enabled' in body:
        for relation in q.all():
            relation.enabled = body['enabled']
        db.session.commit()
Exemple #3
0
def list_region_products(keycloak: KeycloakClient, region_id, user, filter_):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if region.users_group is not None:
        if not keycloak.user_check_role(user, ADMIN_ROLE):
            if not keycloak.user_check_group_any(
                    user, [region.users_group, region.owner_group]):
                raise Forbidden("You don't have access to this region.")

    products_relation = region.products_relation

    if 'name' in filter_:
        products_relation = products_relation.filter(
            model.Region.name.ilike(filter_['enabled']), )

    if 'enabled' in filter_:
        products_relation = products_relation.filter(
            model.Product.enabled == filter_['enabled'], )

    return [{
        'id': r.product_id,
        'region_id': r.region.id,
        'product_id': r.product.id,
        'product': r.product.to_dict(),
        'enabled': r.enabled,
    } | {
        '_href': _region_href(r.region) | _product_href(r.product)
    } for r in products_relation]
Exemple #4
0
def update_region(keycloak: KeycloakClient, vault: Vault, region_id, body,
                  user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    try:
        if body.get('users_group'):
            keycloak.group_get(body['users_group'])
    except KeycloakGetError as e:
        logger.exception(e)
        return problem(
            400, 'Users group does not exist',
            f'Users group {body["users_group"]} does not exist in Keycloak, '
            'you have to create group first or use existing group.')

    if 'quota' in body:
        if body['quota']:
            if region.quota is None:
                region.quota = model.Quota(**body['quota'])
            else:
                for k, v in body['quota'].items():
                    setattr(region.quota, k, v)
        else:
            region.quota = None
        del body['quota']

    openstack_credentials = dpath.get(body,
                                      'openstack/credentials',
                                      default=region.openstack_credentials)
    if not isinstance(openstack_credentials, str):
        vault.write(region.openstack_credentials, openstack_credentials)
        dpath.delete(body, 'openstack/credentials')

    satellite_credentials = dpath.get(body,
                                      'satellite/credentials',
                                      default=region.satellite_credentials)
    if not isinstance(satellite_credentials, str):
        vault.write(region.satellite_credentials, satellite_credentials)
        dpath.delete(body, 'satellite/credentials')

    dns_server_key = dpath.get(body,
                               'dns_server/key',
                               default=region.dns_server_key)
    if not isinstance(dns_server_key, str):
        vault.write(region.dns_server_key, dns_server_key)
        dpath.delete(body, 'dns_server/key')

    region.update_from_dict(body)

    db.session.commit()
    logger.info(
        f'Region {region.name} (id {region.id}) updated by user {user}')

    return region.to_dict() | {'_href': _region_href(region)}
Exemple #5
0
def add_user_group(keycloak: KeycloakClient, user_id, body, user):
    try:
        keycloak.group_user_add(user_id, body['id'])
        return {}, 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #6
0
def delete_user_group(keycloak: KeycloakClient, user_id, user):
    try:
        keycloak.group_user_remove(user_id, request.json['id'])
        return {}, 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #7
0
def delete_group(keycloak: KeycloakClient, group_id, user):
    try:
        keycloak.group_delete(group_id)
        logger.info(f'Deleted group {group_id}')
        return {}, 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #8
0
def delete_role(keycloak: KeycloakClient, role_id, user):
    try:
        keycloak.role_delete(role_id)
        logger.info(f'Deleted role {role_id}')
        return {}, 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #9
0
def get_region(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if region.users_group is not None:
        if not keycloak.user_check_role(user, ADMIN_ROLE):
            if not keycloak.user_check_group_any(
                    user, [region.users_group, region.owner_group]):
                raise Forbidden("You don't have access to this region.")

    return region.to_dict() | {'_href': _region_href(region)}
Exemple #10
0
def update_group(keycloak: KeycloakClient, group_id, body, user):
    try:
        keycloak.group_update(group_id, body)
        logger.info(f'Updated group {group_id}')
        group_data = keycloak.group_get(group_id)
        return group_data | {'_href': _group_href(group_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #11
0
def create_role(keycloak: KeycloakClient, body, user):
    try:
        role_id = keycloak.role_create(body)
        logger.info(f'Create role {role_id}')
        role_data = keycloak.role_get(role_id)
        return role_data | {'_href': _role_href(role_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #12
0
def update_user(keycloak: KeycloakClient, user_id, body, user):
    try:
        keycloak.user_update(user_id, body)
        logger.info(f'Updated user {user_id}')
        user_data = keycloak.user_get(user_id)
        return user_data | {'_href': _user_href(user_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #13
0
def update_role(keycloak: KeycloakClient, role_id, body, user):
    try:
        keycloak.role_update(role_id, body)
        role_name = body['name']
        logger.info(f'Updated role {role_id}')
        role_data = keycloak.role_get(role_name)
        return role_data | {'_href': _role_href(role_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #14
0
def list_product_regions(keycloak: KeycloakClient,
                         product_id,
                         user,
                         filter_,
                         page=0,
                         limit=DEFAULT_PAGE_LIMIT):
    product = model.Product.query.get(product_id)
    if not product:
        return problem(404, 'Not Found',
                       f'Product {product_id} does not exist')

    regions_relation = product.regions_relation

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        user_groups = [group['id'] for group in keycloak.user_group_list(user)]
        regions_relation = regions_relation.filter(
            sqlalchemy.or_(
                model.Region.users_group.is_(None),
                model.Region.users_group.in_(user_groups),
                model.Region.owner_group.in_(user_groups),
            ))

    if 'name' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.name.ilike(filter_['name']), )

    if 'location' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.location.ilike(filter_['location']), )

    if 'enabled' in filter_:
        regions_relation = regions_relation.filter(
            sqlalchemy.and_(
                model.RegionProduct.enabled == filter_['enabled'],
                model.Region.enabled == filter_['enabled'],
            ))

    if 'reservations_enabled' in filter_:
        regions_relation = regions_relation.filter(
            model.Region.reservations_enabled ==
            filter_['reservations_enabled'], )

    return [{
        'id': r.region_id,
        'region': r.region.to_dict(),
        'enabled': r.enabled
    } for r in regions_relation]
Exemple #15
0
def get_user(keycloak: KeycloakClient, user_id):
    try:
        user_data = keycloak.user_get(user_id)
        return user_data | {'_href': _user_href(user_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #16
0
def list_regions(keycloak: KeycloakClient,
                 user,
                 filter_,
                 sort=None,
                 page=0,
                 limit=DEFAULT_PAGE_LIMIT):
    if keycloak.user_check_role(user, ADMIN_ROLE):
        regions = model.Region.query
    else:
        user_groups = [group['id'] for group in keycloak.user_group_list(user)]
        regions = model.Region.query.filter(
            sqlalchemy.or_(
                model.Region.users_group.is_(None),
                model.Region.users_group.in_(user_groups),
                model.Region.owner_group.in_(user_groups),
            ))

    if 'name' in filter_:
        regions = regions.filter(model.Region.name.ilike(filter_['name']))

    if 'location' in filter_:
        regions = regions.filter(
            model.Region.location.ilike(filter_['location']))

    if 'enabled' in filter_:
        regions = regions.filter(model.Region.enabled == filter_['enabled'])

    if 'reservations_enabled' in filter_:
        regions = regions.filter(model.Region.reservations_enabled ==
                                 filter_['reservations_enabled'])

    if sort:
        regions = db_sort(regions, sort)

    return {
        'data': [
            region.to_dict() | {
                '_href': _region_href(region)
            } for region in regions.limit(limit).offset(page * limit)
        ],
        'total':
        regions.count(),
    }
Exemple #17
0
def get_role(keycloak: KeycloakClient, role_id):
    try:
        role_data = keycloak.role_get(role_id)
        return role_data | {'_href': _role_href(role_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #18
0
def get_group(keycloak: KeycloakClient, group_id):
    try:
        group_data = keycloak.group_get(group_id)
        return group_data | {'_href': _group_href(group_data)}
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #19
0
def get_token_info(keycloak: KeycloakClient):
    # Bearer auth is enforced by connexion (see openapi spec)
    _, access_token = request.headers['Authorization'].split()

    try:
        return keycloak.token_info(access_token), 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #20
0
def list_groups(keycloak: KeycloakClient):
    try:
        return [
            group | {'_href': _group_href(group)}
            for group in keycloak.group_list()
        ]
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #21
0
def get_keycloak() -> KeycloakClient:
    """Get KeycloakClient instance."""
    if 'keycloak' not in g:
        g.keycloak = KeycloakClient(
            server=current_app.config['KEYCLOAK_SERVER'],
            resource=current_app.config['KEYCLOAK_RESOURCE'],
            realm=current_app.config['KEYCLOAK_REALM'],
            secret=current_app.config['KEYCLOAK_SECRET'],
            admin_user=current_app.config['KEYCLOAK_ADMIN_USER'],
            admin_pass=current_app.config['KEYCLOAK_ADMIN_PASS'],
        )
    return g.keycloak
Exemple #22
0
def list_roles(keycloak: KeycloakClient):
    try:
        return [
            role | {
                '_href': _role_href(role)
            } for role in keycloak.role_list()
        ]
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #23
0
def list_group_users(keycloak: KeycloakClient, group_id):
    try:
        from rhub.api.auth.user import _user_href
        return [
            user | {'_href': _user_href(user)}
            for user in keycloak.group_user_list(group_id)
        ]
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #24
0
def list_user_groups(keycloak: KeycloakClient, user_id):
    try:
        from rhub.api.auth.group import _group_href
        return [
            group | {
                '_href': _group_href(group)
            } for group in keycloak.user_group_list(user_id)
        ]
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #25
0
def delete_policy(keycloak: KeycloakClient, user, policy_id):
    """
    API endpoint to delete policy given policy id
    """
    policy = model.Policy.query.get(policy_id)
    if not policy:
        return problem(404, 'Not Found', 'Record Does Not Exist')

    try:
        groups = {group['name']: group for group in keycloak.group_list()}
        group_name = f'policy-{policy_id}-owners'
        group_id = groups[group_name]['id']
        keycloak.group_delete(group_id)
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error',
                       f'Failed to delete owner group in Keycloak, {e}')

    db.session.delete(policy)
    db.session.commit()
Exemple #26
0
def create_policy(keycloak: KeycloakClient, user, body):
    """
    API endpoint to create a policy (JSON formatted)
    """
    policy = model.Policy.from_dict(body)

    try:
        db.session.add(policy)
        db.session.flush()
        group_id = keycloak.group_create(
            {'name': f'policy-{policy.id}-owners'})
        keycloak.group_user_add(user, group_id)
        keycloak.group_role_add('policy-owner', group_id)
        db.session.commit()
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error',
                       f'Failed to delete owner group in Keycloak, {e}')

    return policy.to_dict()
Exemple #27
0
def delete_region_product(keycloak: KeycloakClient, region_id, user):
    region = model.Region.query.get(region_id)
    if not region:
        return problem(404, 'Not Found', f'Region {region_id} does not exist')

    if not keycloak.user_check_role(user, ADMIN_ROLE):
        if not keycloak.user_check_group(user, region.owner_group):
            raise Forbidden("You don't have write access to this region.")

    product = model.Product.query.get(request.json['id'])
    if not product:
        return problem(404, 'Not Found',
                       f'Product {request.json["id"]} does not exist')

    q = model.RegionProduct.query.filter(
        sqlalchemy.and_(
            model.RegionProduct.region_id == region.id,
            model.RegionProduct.product_id == product.id,
        ))
    if q.count() > 0:
        for relation in q.all():
            db.session.delete(relation)
        db.session.commit()
Exemple #28
0
def create_token(keycloak: KeycloakClient):
    if not request.authorization:
        return problem(401, 'Unauthorized', 'Missing basic auth credentials')

    username = request.authorization['username']
    password = request.authorization['password']

    try:
        return keycloak.login(username, password), 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #29
0
def refresh_token(keycloak: KeycloakClient):
    if 'Authorization' not in request.headers:
        return problem(401, 'Unauthorized', 'Missing refresh token')

    try:
        _, refresh_token = request.headers['Authorization'].split()
    except Exception:
        return problem(401, 'Unauthorized', 'Invalid token')

    try:
        return keycloak.token_refresh(refresh_token), 200
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))
Exemple #30
0
def list_users(keycloak: KeycloakClient,
               filter_,
               page=0,
               limit=DEFAULT_PAGE_LIMIT):
    try:
        return [
            user | {
                '_href': _user_href(user)
            } for user in keycloak.user_list({
                'first': page * limit,
                'max': limit,
                **filter_,
            })
        ]
    except KeycloakGetError as e:
        logger.exception(e)
        return problem_from_keycloak_error(e)
    except Exception as e:
        logger.exception(e)
        return problem(500, 'Unknown Error', str(e))