from flask.blueprints import Blueprint from flask_apispec import marshal_with from atlas_um.api.decorators import doc_list_view, doc_details_view from atlas_um.api.facades import APIQueryFacade from atlas_um.auth.claims import Audience, Role from atlas_um.auth.decorators import claims_required from atlas_um.caching import strategies as cache_strategies from atlas_um.extensions import cache from atlas_um.pgdb import ( DNAAccount, ClaimValue, ClaimName, ResourceGroup, ) from . import schemas api_v1 = Blueprint("api_v1", __name__) @api_v1.route("resource_groups", methods=["GET"]) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.ResourceGroupsCache) @marshal_with(schemas.ResourceGroupsResponseSchema) @doc_list_view( summary="Resource groups list", description="Returns all available resource groups", tags=["Resource groups"], responses={ 200: { "description": "A list of resource groups", "schema": schemas.ResourceGroupsResponseSchema, } }, ) def resource_groups(): query = ResourceGroup.query.active() return APIQueryFacade( query=query, allowed_fields=[ResourceGroup.name, ResourceGroup.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "resource_groups//claim_names", methods=["GET"] ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.ClaimNamesCache) @marshal_with(schemas.ClaimNamesResponseSchema) @doc_list_view( summary="Claim names list", description=( "Returns all available claim names for specified resource group" ), tags=["Claim names"], path_params={"resource_group_id": "Resource group ID"}, responses={ 200: { "description": "A list of claim names", "schema": schemas.ClaimNamesResponseSchema, } }, ) def claim_names(resource_group_id): query = ClaimName.query.active().by_group_external_id(resource_group_id) return APIQueryFacade( query=query, allowed_fields=[ClaimName.friendly, ClaimName.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route("claim_names", methods=["GET"]) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.ClaimNamesCache) @marshal_with(schemas.ClaimNamesResponseSchema) @doc_list_view( summary="Global claim names list", description="Returns all available global claim names", tags=["Claim names"], responses={ 200: { "description": "A list of claim names", "schema": schemas.ClaimNamesResponseSchema, } }, ) def global_claim_names(): query = ClaimName.query.active(True).filter_global() return APIQueryFacade( query=query, allowed_fields=[ClaimName.friendly, ClaimName.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "resource_groups//claim_names/", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.ClaimValuesCache) @marshal_with(schemas.ClaimValuesResponseSchema) @doc_list_view( summary="Claim values list", description=( "Returns all available claim values for specified claim name" ), tags=["Claim values"], path_params={ "resource_group_id": "Resource group ID", "claim_name_id": "Claim name ID", }, responses={ 200: { "description": "A list of claim values", "schema": schemas.ClaimValuesResponseSchema, } }, ) def claim_values(resource_group_id, claim_name_id): query = ClaimValue.query.active().by_name_external_ids( resource_group_id, claim_name_id ) return APIQueryFacade( query=query, allowed_fields=[ClaimValue.friendly, ClaimValue.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "claim_names/", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.ClaimValuesCache) @marshal_with(schemas.ClaimValuesResponseSchema) @doc_list_view( summary="Global claim values list", description=( "Returns all available claim values for specified global claim name" ), tags=["Claim values"], path_params={ "claim_name_id": "Claim name ID", }, responses={ 200: { "description": "A list of claim values", "schema": schemas.ClaimValuesResponseSchema, } }, ) def global_claim_values(claim_name_id): query = ClaimValue.query.active(True).global_by_name_external_ids( claim_name_id ) return APIQueryFacade( query=query, allowed_fields=[ClaimValue.friendly, ClaimValue.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "resource_groups//" "claim_names///users", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.UsersResponseSchema) @doc_list_view( summary="Claim value users list", description="Returns all users for specified clim value", tags=["Users"], path_params={ "resource_group_id": "Resource group ID", "claim_name_id": "Claim name ID", "claim_value_id": "Claim value ID", }, responses={ 200: { "description": "A list of claim values", "schema": schemas.UsersResponseSchema, } }, ) def claim_value_users(resource_group_id, claim_name_id, claim_value_id): query = DNAAccount.query.activated().by_claim_external_ids( resource_group_id, claim_name_id, claim_value_id ) return APIQueryFacade( query=query, allowed_fields=[ DNAAccount.sub, DNAAccount.email, DNAAccount.given_name, DNAAccount.family_name, ], fields_mapping={"id": "sub"}, ) @api_v1.route("users", methods=["GET"]) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.UsersResponseSchema) @doc_list_view( summary="Users list", description="Returns all users", tags=["Users"], responses={ 200: { "description": "A list of users", "schema": schemas.UsersResponseSchema, } }, ) def users(): query = DNAAccount.query.with_relations().activated() return APIQueryFacade( query=query, allowed_fields=[ DNAAccount.sub, DNAAccount.email, DNAAccount.given_name, DNAAccount.family_name, ], fields_mapping={"id": "sub"}, ) @api_v1.route("users/", methods=["GET"]) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.UserDetailsResponseSchema) @doc_details_view( summary="Details for specified user", description="Returns detail information on specified user", tags=["Users"], responses={ 200: { "description": "User details", "schema": schemas.UserDetailsResponseSchema, } }, path_params={"user_id": "User ID"}, ) def user_details(user_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() return account @api_v1.route("users//resource_groups", methods=["GET"]) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.ResourceGroupsResponseSchema) @doc_list_view( summary="Resource groups list for specified user", description="Returns all resource groups activated for user", tags=["Resource groups"], responses={ 200: { "description": "A list of resource groups", "schema": schemas.ResourceGroupsResponseSchema, } }, path_params={"user_id": "User ID"}, ) def user_resource_groups(user_id): query = ResourceGroup.query.active().by_dna_account_sub(user_id) return APIQueryFacade( query=query, allowed_fields=[ResourceGroup.name, ClaimName.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "users//claims", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @doc_details_view( summary="Claims for specified user", description="Returns all user claims", tags=["Claims"], path_params={"user_id": "User ID"}, responses={ 200: { "description": "Claims mapping", "schema": schemas.ClaimResponseSchema, } }, ) def user_claims(user_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() return account.serialize_claims() @api_v1.route( "users//resource_groups//claim_names", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.ClaimNamesResponseSchema) @doc_list_view( summary="Claim names list for specified user", description=( "Returns claim names for specified " "resource group activated for specified user" ), tags=["Claim names"], path_params={ "user_id": "User ID", "resource_group_id": "Resource group ID", }, responses={ 200: { "description": "A list of claim names", "schema": schemas.ClaimNamesResponseSchema, } }, ) def user_claim_names(user_id, resource_group_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() query = ClaimName.query.active().by_dna_account_sub_group_external_id( account.sub, resource_group_id ) return APIQueryFacade( query=query, allowed_fields=[ClaimName.friendly, ClaimName.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "users//resource_groups//claims", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @doc_details_view( summary="Claims for specified user and resource group", description="Returns user claims filtered by specified resource group", tags=["Claims"], path_params={ "user_id": "User ID", "resource_group_id": "Resource group ID", }, responses={ 200: { "description": "Claims mapping", "schema": schemas.ClaimResponseSchema, } }, ) def user_resource_group_claims(user_id, resource_group_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() resource_group = ( ResourceGroup.query.active() .by_external_id(resource_group_id) .first_or_404() ) return account.serialize_claims(resource_group=resource_group) @api_v1.route( "users//resource_groups/" "/claim_names/", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @marshal_with(schemas.ClaimValuesResponseSchema) @doc_list_view( summary="Claim values list for specified user", description=( "Returns claim values for specified " "claim name activated for specified user" ), tags=["Claim values"], path_params={ "user_id": "User ID", "resource_group_id": "Resource group ID", "claim_name_id": "Claim name ID", }, responses={ 200: { "description": "A list of claim values", "schema": schemas.ClaimValuesResponseSchema, } }, ) def user_claim_values(user_id, resource_group_id, claim_name_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() query = ClaimValue.query.by_dna_account_sub_name_external_ids( account.sub, resource_group_id, claim_name_id ) return APIQueryFacade( query=query, allowed_fields=[ClaimValue.friendly, ClaimValue.external_id], fields_mapping={"id": "external_id"}, ) @api_v1.route( "users//resource_groups/" "/claim_names//claims", methods=["GET"], ) @claims_required( [Role(Role.Values.admin), Audience(Audience.Values.api_read)], login_redirect=False, ) @cache.cached_with(cache_strategies.DNAAccountsCache) @doc_details_view( summary="Claims for specified user, resource group and claim name", description=( "Returns user claims filtered by " "specified resource group and claim name" ), tags=["Claims"], path_params={ "user_id": "User ID", "resource_group_id": "Resource group ID", "claim_name_id": "Claim name ID", }, responses={ 200: { "description": "Claims mapping", "schema": schemas.ClaimResponseSchema, } }, ) def user_claim_name_claims(user_id, resource_group_id, claim_name_id): account = DNAAccount.query.activated().by_sub(user_id).first_or_404() claim_name = ( ClaimName.query.active() .by_name_external_ids(resource_group_id, claim_name_id) .first_or_404() ) return account.serialize_claims(claim_name=claim_name)