From 8d7486ea147708574de6b93e6a36fb8b21a5449a Mon Sep 17 00:00:00 2001 From: bruk Date: Fri, 15 Nov 2024 17:03:02 -0500 Subject: [PATCH 01/36] add Schema for User/Token endpoint --- .../opportunities_v1/opportunity_schemas.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/api/src/api/opportunities_v1/opportunity_schemas.py b/api/src/api/opportunities_v1/opportunity_schemas.py index cd969ab35..e20e69090 100644 --- a/api/src/api/opportunities_v1/opportunity_schemas.py +++ b/api/src/api/opportunities_v1/opportunity_schemas.py @@ -535,3 +535,39 @@ class OpportunitySearchResponseV1Schema(AbstractResponseSchema, PaginationMixinS OpportunityFacetV1Schema(), metadata={"description": "Counts of filter/facet values in the full response"}, ) + + +class UserV1Schema(Schema): + user_id = fields.String( + metadata={ + "description": "The internal ID of a user", + "example": "861a0148-cf2c-432b-b0b3-690016299ab1", + } + ) + email = fields.String( + metadata={ + "description": "The email address returned from Oauth2 provider", + "example": "js@gmail.com", + } + ) + external_user_type = fields.String( + metadata={ + "description": "The Oauth2 provider through which a user was authenticated", + "example": "login_gov", + } + ) + + +class OpportunityUserTokenResponseV1Schema(AbstractResponseSchema): + token = fields.String( + metadata={ + "description": "Internal token generated for a user", + } + ) + user = fields.Nested(UserV1Schema()) + is_user_new = fields.Boolean( + allow_none=False, + metadata={ + "description": "Whether or not the user currently existed in our database", + }, + ) From 136dd019de9f4f65dd06ed40998df6603ab9bb90 Mon Sep 17 00:00:00 2001 From: bruk Date: Fri, 15 Nov 2024 17:04:55 -0500 Subject: [PATCH 02/36] add new user/token endpoint with static response --- .../opportunities_v1/opportunity_routes.py | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/api/src/api/opportunities_v1/opportunity_routes.py b/api/src/api/opportunities_v1/opportunity_routes.py index 678bf2a88..12be07ee9 100644 --- a/api/src/api/opportunities_v1/opportunity_routes.py +++ b/api/src/api/opportunities_v1/opportunity_routes.py @@ -1,7 +1,7 @@ import io import logging -from flask import Response +from flask import Response, request import src.adapters.db as db import src.adapters.db.flask_db as flask_db @@ -212,3 +212,28 @@ def opportunity_versions_get(db_session: db.Session, opportunity_id: int) -> res data = get_opportunity_versions(db_session, opportunity_id) return response.ApiResponse(message="Success", data=data) + + +@opportunity_blueprint.post("/user/token") +@opportunity_blueprint.output(opportunity_schemas.OpportunityUserTokenResponseV1Schema) +@opportunity_blueprint.auth_required(api_key_auth) +def user_token() -> response.ApiResponse | Response: + logger.info("POST /v1/user/token") + + header_token = request.headers.get("X-OAuth-login-gov") + if header_token: + data = { + "token": "the token goes here!", + "user": { + "user_id": "abc-...", + "email": "example@gmail.com", + "external_user_type": "login_gov", + }, + "is_user_new": True, + } + return response.ApiResponse(message="Success", data=data) + + message = "Missing X-OAuth-login-gov header" + logger.error(message) + + return response.ApiResponse(message=message, status_code=400) From 50b2b75006294a72f1ce51884ef6338b191f8c60 Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Fri, 15 Nov 2024 22:11:21 +0000 Subject: [PATCH 03/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 60 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index f11e5e235..0c007c06a 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -43,6 +43,27 @@ paths: tags: - Health summary: Health + /v1/user/token: + post: + parameters: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/OpportunityUserTokenResponseV1' + description: Successful response + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Authentication error + tags: + - Opportunity v1 + summary: User Token + security: + - ApiKeyAuth: [] /v1/opportunities/search: post: parameters: [] @@ -350,6 +371,45 @@ components: type: string description: An internal tracking ID example: 550e8400-e29b-41d4-a716-446655440000 + UserV1: + type: object + properties: + user_id: + type: string + description: The internal ID of a user + example: 861a0148-cf2c-432b-b0b3-690016299ab1 + email: + type: string + description: The email address returned from Oauth2 provider + example: js@gmail.com + external_user_type: + type: string + description: The Oauth2 provider through which a user was authenticated + example: login_gov + OpportunityUserTokenResponseV1: + type: object + properties: + message: + type: string + description: The message to return + example: Success + data: + description: The REST resource object + status_code: + type: integer + description: The HTTP status code + example: 200 + token: + type: string + description: Internal token generated for a user + user: + type: + - object + allOf: + - $ref: '#/components/schemas/UserV1' + is_user_new: + type: boolean + description: Whether or not the user currently existed in our database FundingInstrumentFilterV1: type: object properties: From ec38d8f95da3248520892f3ae340e9d307c75f07 Mon Sep 17 00:00:00 2001 From: bruk Date: Fri, 15 Nov 2024 17:14:14 -0500 Subject: [PATCH 04/36] fix description --- api/src/api/opportunities_v1/opportunity_schemas.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/api/opportunities_v1/opportunity_schemas.py b/api/src/api/opportunities_v1/opportunity_schemas.py index e20e69090..be1145a58 100644 --- a/api/src/api/opportunities_v1/opportunity_schemas.py +++ b/api/src/api/opportunities_v1/opportunity_schemas.py @@ -568,6 +568,6 @@ class OpportunityUserTokenResponseV1Schema(AbstractResponseSchema): is_user_new = fields.Boolean( allow_none=False, metadata={ - "description": "Whether or not the user currently existed in our database", + "description": "Whether or not the user existed in our database", }, ) From 6cc4c37aaefbe7221d79f7ed7e4b555cf3554fb6 Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Fri, 15 Nov 2024 22:19:07 +0000 Subject: [PATCH 05/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index 0c007c06a..301fe6cad 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -409,7 +409,7 @@ components: - $ref: '#/components/schemas/UserV1' is_user_new: type: boolean - description: Whether or not the user currently existed in our database + description: Whether or not the user existed in our database FundingInstrumentFilterV1: type: object properties: From f32b05a904b83dee4877631497d11a490a3793e4 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:55:42 -0500 Subject: [PATCH 06/36] user api blueprint --- api/src/api/users/user_blueprint.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 api/src/api/users/user_blueprint.py diff --git a/api/src/api/users/user_blueprint.py b/api/src/api/users/user_blueprint.py new file mode 100644 index 000000000..59400104a --- /dev/null +++ b/api/src/api/users/user_blueprint.py @@ -0,0 +1,9 @@ +from apiflask import APIBlueprint + +user_blueprint = APIBlueprint( + "user_v1", + __name__, + tag="User v1", + cli_group="user_v1", + url_prefix="/v1/users", +) From 352a79a91e086bb3253a63b685e6b0983da9f781 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:56:10 -0500 Subject: [PATCH 07/36] user routes with user/token endpoint --- api/src/api/users/user_routes.py | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 api/src/api/users/user_routes.py diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py new file mode 100644 index 000000000..7201f0885 --- /dev/null +++ b/api/src/api/users/user_routes.py @@ -0,0 +1,36 @@ +import logging + +from flask import Response, request + +from api.src.api import response +from api.src.api.route_utils import raise_flask_error +from api.src.api.users import user_schemas +from api.src.api.users.user_blueprint import user_blueprint +from api.src.auth import api_key_auth + +logger = logging.getLogger(__name__) + + +@user_blueprint.post("/user/token") +@user_blueprint.output(user_schemas.UserTokenResponseV1Schema) +@user_blueprint.auth_required(api_key_auth) +def user_token() -> response.ApiResponse | Response: + logger.info("POST /v1/users/user/token") + + header_token = request.headers.get("X-OAuth-login-gov") + if header_token: + data = { + "token": "the token goes here!", + "user": { + "user_id": "abc-...", + "email": "example@gmail.com", + "external_user_type": "login_gov", + }, + "is_user_new": True, + } + return response.ApiResponse(message="Success", data=data) + + message = "Missing X-OAuth-login-gov header" + logger.error(message) + + return raise_flask_error(400, message) From e90139d7c8b6fc4da59ee6b48cd1e052b5a920bb Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:56:43 -0500 Subject: [PATCH 08/36] moved user endpoint --- .../opportunities_v1/opportunity_routes.py | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/api/src/api/opportunities_v1/opportunity_routes.py b/api/src/api/opportunities_v1/opportunity_routes.py index 12be07ee9..678bf2a88 100644 --- a/api/src/api/opportunities_v1/opportunity_routes.py +++ b/api/src/api/opportunities_v1/opportunity_routes.py @@ -1,7 +1,7 @@ import io import logging -from flask import Response, request +from flask import Response import src.adapters.db as db import src.adapters.db.flask_db as flask_db @@ -212,28 +212,3 @@ def opportunity_versions_get(db_session: db.Session, opportunity_id: int) -> res data = get_opportunity_versions(db_session, opportunity_id) return response.ApiResponse(message="Success", data=data) - - -@opportunity_blueprint.post("/user/token") -@opportunity_blueprint.output(opportunity_schemas.OpportunityUserTokenResponseV1Schema) -@opportunity_blueprint.auth_required(api_key_auth) -def user_token() -> response.ApiResponse | Response: - logger.info("POST /v1/user/token") - - header_token = request.headers.get("X-OAuth-login-gov") - if header_token: - data = { - "token": "the token goes here!", - "user": { - "user_id": "abc-...", - "email": "example@gmail.com", - "external_user_type": "login_gov", - }, - "is_user_new": True, - } - return response.ApiResponse(message="Success", data=data) - - message = "Missing X-OAuth-login-gov header" - logger.error(message) - - return response.ApiResponse(message=message, status_code=400) From ef9861d35e0a3b515d8acb8efcb795ad1c63a07c Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:56:51 -0500 Subject: [PATCH 09/36] moved user schemas --- .../opportunities_v1/opportunity_schemas.py | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/api/src/api/opportunities_v1/opportunity_schemas.py b/api/src/api/opportunities_v1/opportunity_schemas.py index be1145a58..cd969ab35 100644 --- a/api/src/api/opportunities_v1/opportunity_schemas.py +++ b/api/src/api/opportunities_v1/opportunity_schemas.py @@ -535,39 +535,3 @@ class OpportunitySearchResponseV1Schema(AbstractResponseSchema, PaginationMixinS OpportunityFacetV1Schema(), metadata={"description": "Counts of filter/facet values in the full response"}, ) - - -class UserV1Schema(Schema): - user_id = fields.String( - metadata={ - "description": "The internal ID of a user", - "example": "861a0148-cf2c-432b-b0b3-690016299ab1", - } - ) - email = fields.String( - metadata={ - "description": "The email address returned from Oauth2 provider", - "example": "js@gmail.com", - } - ) - external_user_type = fields.String( - metadata={ - "description": "The Oauth2 provider through which a user was authenticated", - "example": "login_gov", - } - ) - - -class OpportunityUserTokenResponseV1Schema(AbstractResponseSchema): - token = fields.String( - metadata={ - "description": "Internal token generated for a user", - } - ) - user = fields.Nested(UserV1Schema()) - is_user_new = fields.Boolean( - allow_none=False, - metadata={ - "description": "Whether or not the user existed in our database", - }, - ) From c50111125ee7725ca8b9be7223c3519363c1493f Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:57:04 -0500 Subject: [PATCH 10/36] user schemas --- api/src/api/users/user_schemas.py | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 api/src/api/users/user_schemas.py diff --git a/api/src/api/users/user_schemas.py b/api/src/api/users/user_schemas.py new file mode 100644 index 000000000..7c886dec8 --- /dev/null +++ b/api/src/api/users/user_schemas.py @@ -0,0 +1,44 @@ +from api.src.api.schemas.response_schema import AbstractResponseSchema +from api.src.constants.lookup_constants import ExternalUserType +from src.api.schemas.extension import Schema, fields + + +class UserV1Schema(Schema): + user_id = fields.String( + metadata={ + "description": "The internal ID of a user", + "example": "861a0148-cf2c-432b-b0b3-690016299ab1", + } + ) + email = fields.String( + metadata={ + "description": "The email address returned from Oauth2 provider", + "example": "js@gmail.com", + } + ) + external_user_type = fields.Enum( + ExternalUserType, + metadata={ + "description": "The Oauth2 provider through which a user was authenticated", + "example": ExternalUserType.LOGIN_GOV, + }, + ) + + +class UserTokenSchema(Schema): + token = fields.String( + metadata={ + "description": "Internal token generated for a user", + } + ) + user = fields.Nested(UserV1Schema()) + is_user_new = fields.Boolean( + allow_none=False, + metadata={ + "description": "Whether or not the user existed in our database", + }, + ) + + +class UserTokenResponseV1Schema(AbstractResponseSchema): + data = fields.Nested(UserTokenSchema) From 6e8304208df1358cf2753f346a6631dd98dbee35 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 11:57:25 -0500 Subject: [PATCH 11/36] register user routes on blueprint --- api/src/api/users/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 api/src/api/users/__init__.py diff --git a/api/src/api/users/__init__.py b/api/src/api/users/__init__.py new file mode 100644 index 000000000..b6fba234e --- /dev/null +++ b/api/src/api/users/__init__.py @@ -0,0 +1,6 @@ +from src.api.users.user_blueprint import user_blueprint + +# import user_routes module to register the API routes on the blueprint +import src.api.users.user_routes # noqa: F401 E402 isort:skip + +__all__ = ["user_blueprint"] From 98aabd41fc020428092d2dfdd0270e65173b1491 Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Mon, 18 Nov 2024 17:00:25 +0000 Subject: [PATCH 12/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 60 --------------------------------------- 1 file changed, 60 deletions(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index 301fe6cad..f11e5e235 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -43,27 +43,6 @@ paths: tags: - Health summary: Health - /v1/user/token: - post: - parameters: [] - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/OpportunityUserTokenResponseV1' - description: Successful response - '401': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - description: Authentication error - tags: - - Opportunity v1 - summary: User Token - security: - - ApiKeyAuth: [] /v1/opportunities/search: post: parameters: [] @@ -371,45 +350,6 @@ components: type: string description: An internal tracking ID example: 550e8400-e29b-41d4-a716-446655440000 - UserV1: - type: object - properties: - user_id: - type: string - description: The internal ID of a user - example: 861a0148-cf2c-432b-b0b3-690016299ab1 - email: - type: string - description: The email address returned from Oauth2 provider - example: js@gmail.com - external_user_type: - type: string - description: The Oauth2 provider through which a user was authenticated - example: login_gov - OpportunityUserTokenResponseV1: - type: object - properties: - message: - type: string - description: The message to return - example: Success - data: - description: The REST resource object - status_code: - type: integer - description: The HTTP status code - example: 200 - token: - type: string - description: Internal token generated for a user - user: - type: - - object - allOf: - - $ref: '#/components/schemas/UserV1' - is_user_new: - type: boolean - description: Whether or not the user existed in our database FundingInstrumentFilterV1: type: object properties: From 9ef31c0ed58c2acb2d5016144786d04599747710 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 12:17:49 -0500 Subject: [PATCH 13/36] rm versioning --- api/src/api/users/user_schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/api/users/user_schemas.py b/api/src/api/users/user_schemas.py index 7c886dec8..144200156 100644 --- a/api/src/api/users/user_schemas.py +++ b/api/src/api/users/user_schemas.py @@ -3,7 +3,7 @@ from src.api.schemas.extension import Schema, fields -class UserV1Schema(Schema): +class UserSchema(Schema): user_id = fields.String( metadata={ "description": "The internal ID of a user", @@ -31,7 +31,7 @@ class UserTokenSchema(Schema): "description": "Internal token generated for a user", } ) - user = fields.Nested(UserV1Schema()) + user = fields.Nested(UserSchema()) is_user_new = fields.Boolean( allow_none=False, metadata={ From 625f3660b7bf70965cede5ebed4bdb5d44fd01b2 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 14:05:50 -0500 Subject: [PATCH 14/36] fix import --- api/src/api/users/user_schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/api/users/user_schemas.py b/api/src/api/users/user_schemas.py index 144200156..5fd17d478 100644 --- a/api/src/api/users/user_schemas.py +++ b/api/src/api/users/user_schemas.py @@ -1,6 +1,6 @@ -from api.src.api.schemas.response_schema import AbstractResponseSchema -from api.src.constants.lookup_constants import ExternalUserType from src.api.schemas.extension import Schema, fields +from src.api.schemas.response_schema import AbstractResponseSchema +from src.constants.lookup_constants import ExternalUserType class UserSchema(Schema): From a95f46b44e9793049ed0113535e05936f6da4f09 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 14:06:47 -0500 Subject: [PATCH 15/36] register user routes blueprint --- api/src/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/app.py b/api/src/app.py index ad79d1810..ded2d117c 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -18,6 +18,7 @@ from src.api.opportunities_v1 import opportunity_blueprint as opportunities_v1_blueprint from src.api.response import restructure_error_response from src.api.schemas import response_schema +from src.api.users.user_blueprint import user_blueprint from src.app_config import AppConfig from src.auth.api_key_auth import get_app_security_scheme from src.data_migration.data_migration_blueprint import data_migration_blueprint @@ -118,6 +119,7 @@ def register_blueprints(app: APIFlask) -> None: app.register_blueprint(opportunities_v0_blueprint) app.register_blueprint(opportunities_v0_1_blueprint) app.register_blueprint(opportunities_v1_blueprint) + app.register_blueprint(user_blueprint) # Non-api blueprints app.register_blueprint(data_migration_blueprint) From 1f033774f095dc6efeac8afdab8b0e423d470103 Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 17:12:00 -0500 Subject: [PATCH 16/36] fix naming --- api/src/api/users/user_routes.py | 19 ++++++++++++------- api/src/api/users/user_schemas.py | 2 +- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 7201f0885..34919d9e8 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -1,19 +1,24 @@ import logging +from http.client import responses from flask import Response, request -from api.src.api import response -from api.src.api.route_utils import raise_flask_error -from api.src.api.users import user_schemas -from api.src.api.users.user_blueprint import user_blueprint -from api.src.auth import api_key_auth +from src.api import response +from src.api.route_utils import raise_flask_error +from src.api.users import user_schemas +from src.api.users.user_blueprint import user_blueprint +from src.auth.api_key_auth import api_key_auth logger = logging.getLogger(__name__) @user_blueprint.post("/user/token") -@user_blueprint.output(user_schemas.UserTokenResponseV1Schema) +@user_blueprint.output(user_schemas.UserTokenResponseSchema) @user_blueprint.auth_required(api_key_auth) +@user_blueprint.doc( + description="Test", + responses=[200, 400] +) def user_token() -> response.ApiResponse | Response: logger.info("POST /v1/users/user/token") @@ -33,4 +38,4 @@ def user_token() -> response.ApiResponse | Response: message = "Missing X-OAuth-login-gov header" logger.error(message) - return raise_flask_error(400, message) + raise_flask_error(400, message) diff --git a/api/src/api/users/user_schemas.py b/api/src/api/users/user_schemas.py index 5fd17d478..432f4b406 100644 --- a/api/src/api/users/user_schemas.py +++ b/api/src/api/users/user_schemas.py @@ -40,5 +40,5 @@ class UserTokenSchema(Schema): ) -class UserTokenResponseV1Schema(AbstractResponseSchema): +class UserTokenResponseSchema(AbstractResponseSchema): data = fields.Nested(UserTokenSchema) From 528dfd1e46faf2195aed666b7ef818497a3f288f Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Mon, 18 Nov 2024 22:14:08 +0000 Subject: [PATCH 17/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index f11e5e235..89d93aec1 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -22,6 +22,7 @@ info: tags: - name: Health - name: Opportunity v1 +- name: User v1 servers: . paths: /health: @@ -43,6 +44,34 @@ paths: tags: - Health summary: Health + /v1/users/user/token: + post: + parameters: [] + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/UserTokenResponse' + description: Successful response + '401': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Authentication error + '400': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Bad Request + tags: + - User v1 + summary: User Token + description: Test + security: + - ApiKeyAuth: [] /v1/opportunities/search: post: parameters: [] @@ -350,6 +379,55 @@ components: type: string description: An internal tracking ID example: 550e8400-e29b-41d4-a716-446655440000 + User: + type: object + properties: + user_id: + type: string + description: The internal ID of a user + example: 861a0148-cf2c-432b-b0b3-690016299ab1 + email: + type: string + description: The email address returned from Oauth2 provider + example: js@gmail.com + external_user_type: + description: The Oauth2 provider through which a user was authenticated + example: !!python/object/apply:src.constants.lookup_constants.ExternalUserType + - login_gov + enum: + - login_gov + type: + - string + UserToken: + type: object + properties: + token: + type: string + description: Internal token generated for a user + user: + type: + - object + allOf: + - $ref: '#/components/schemas/User' + is_user_new: + type: boolean + description: Whether or not the user existed in our database + UserTokenResponse: + type: object + properties: + message: + type: string + description: The message to return + example: Success + data: + type: + - object + allOf: + - $ref: '#/components/schemas/UserToken' + status_code: + type: integer + description: The HTTP status code + example: 200 FundingInstrumentFilterV1: type: object properties: From 4594b267f2da4b603025aada0ce4b91496840a9e Mon Sep 17 00:00:00 2001 From: bruk Date: Mon, 18 Nov 2024 22:24:58 -0500 Subject: [PATCH 18/36] define param for swagger --- api/src/api/users/user_routes.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 34919d9e8..0431da264 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -1,5 +1,4 @@ import logging -from http.client import responses from flask import Response, request @@ -17,9 +16,24 @@ @user_blueprint.auth_required(api_key_auth) @user_blueprint.doc( description="Test", - responses=[200, 400] + responses=[200, 400], + # parameters={ + # "name": "X-OAuth-login-gov", + # "in": "header", + # "schema": {"type": "string"}, + # "description": "JWT token", + # }, ) def user_token() -> response.ApiResponse | Response: + """ + parameters: + - name: X-OAuth-login-gov + in: header + type: string + required: true + description: The Oauth2 JWT token + """ + logger.info("POST /v1/users/user/token") header_token = request.headers.get("X-OAuth-login-gov") From 15d14b809c61c74b6b95932c127a5356984e70e7 Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Tue, 19 Nov 2024 03:28:26 +0000 Subject: [PATCH 19/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index 89d93aec1..9dd5e601a 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -68,7 +68,7 @@ paths: description: Bad Request tags: - User v1 - summary: User Token + summary: 'parameters:' description: Test security: - ApiKeyAuth: [] From 34624a2d63c810d797fdcfb70dd49c136dc86a3b Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 11:12:31 -0500 Subject: [PATCH 20/36] unit test user/route --- api/tests/src/api/users/__init__.py | 0 api/tests/src/api/users/test_user_route_token.py | 16 ++++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 api/tests/src/api/users/__init__.py create mode 100644 api/tests/src/api/users/test_user_route_token.py diff --git a/api/tests/src/api/users/__init__.py b/api/tests/src/api/users/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/tests/src/api/users/test_user_route_token.py b/api/tests/src/api/users/test_user_route_token.py new file mode 100644 index 000000000..2d6a8e6fe --- /dev/null +++ b/api/tests/src/api/users/test_user_route_token.py @@ -0,0 +1,16 @@ + + +##################################### +# POST user token tests +##################################### + +def test_post_user_route_token_200(client, api_auth_token): + resp= client.post(f"/v1/users/user/token", headers={"X-Auth": api_auth_token, "X-OAuth-login-gov": "test_token" }) + assert resp.status_code == 200 + response_data = resp.get_json()["data"] + + +def test_post_user_route_token_400(client, api_auth_token): + resp= client.post(f"v1/users/user/token", headers={"X-Auth": api_auth_token}) + assert resp.status_code == 400 + assert resp.get_json()["message"] == "Missing X-OAuth-login-gov header" \ No newline at end of file From 4c90bfbbe2fe96670a7f6d02d2d0fb71db6b7e78 Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 11:17:37 -0500 Subject: [PATCH 21/36] use SHARED_ALPHA_DESCRIPTION --- api/src/api/users/user_routes.py | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 0431da264..a277d25a3 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -10,30 +10,25 @@ logger = logging.getLogger(__name__) +# Descriptions in OpenAPI support markdown https://swagger.io/specification/ +SHARED_ALPHA_DESCRIPTION = """ +__ALPHA VERSION__ + +This endpoint in its current form is primarily for testing and feedback. + +Features in this endpoint are still under heavy development, and subject to change. Not for production use. + +See [Release Phases](https://github.com/github/roadmap?tab=readme-ov-file#release-phases) for further details. +""" @user_blueprint.post("/user/token") @user_blueprint.output(user_schemas.UserTokenResponseSchema) @user_blueprint.auth_required(api_key_auth) -@user_blueprint.doc( - description="Test", - responses=[200, 400], - # parameters={ - # "name": "X-OAuth-login-gov", - # "in": "header", - # "schema": {"type": "string"}, - # "description": "JWT token", - # }, +@user_blueprint.doc( #should we include this? + description=SHARED_ALPHA_DESCRIPTION, + responses=[200, 400] ) def user_token() -> response.ApiResponse | Response: - """ - parameters: - - name: X-OAuth-login-gov - in: header - type: string - required: true - description: The Oauth2 JWT token - """ - logger.info("POST /v1/users/user/token") header_token = request.headers.get("X-OAuth-login-gov") From 240614b3bfbde53be9119a6abe2ab2e28906f963 Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Tue, 19 Nov 2024 16:20:20 +0000 Subject: [PATCH 22/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index 9dd5e601a..e052e33d3 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -68,8 +68,23 @@ paths: description: Bad Request tags: - User v1 - summary: 'parameters:' - description: Test + summary: User Token + description: ' + + __ALPHA VERSION__ + + + This endpoint in its current form is primarily for testing and feedback. + + + Features in this endpoint are still under heavy development, and subject to + change. Not for production use. + + + See [Release Phases](https://github.com/github/roadmap?tab=readme-ov-file#release-phases) + for further details. + + ' security: - ApiKeyAuth: [] /v1/opportunities/search: From db3099289d9f972d15d0e0cd01207d34f68f1dad Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 22:07:31 -0500 Subject: [PATCH 23/36] set auth_endpoint env variable --- api/src/app.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/api/src/app.py b/api/src/app.py index ded2d117c..231f57dc0 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -24,6 +24,7 @@ from src.data_migration.data_migration_blueprint import data_migration_blueprint from src.search.backend.load_search_data_blueprint import load_search_data_blueprint from src.task import task_blueprint +from src.util.env_config import PydanticBaseEnvConfig logger = logging.getLogger(__name__) @@ -38,6 +39,11 @@ """ +class authEndpointConfig(PydanticBaseEnvConfig): + auth_endpoint: bool = False if os.getenv("ENVIRONMENT", "local") == "local" else True + +auth_endpoint = authEndpointConfig() + def create_app() -> APIFlask: app = APIFlask(__name__, title=TITLE, version=API_OVERALL_VERSION) @@ -119,7 +125,8 @@ def register_blueprints(app: APIFlask) -> None: app.register_blueprint(opportunities_v0_blueprint) app.register_blueprint(opportunities_v0_1_blueprint) app.register_blueprint(opportunities_v1_blueprint) - app.register_blueprint(user_blueprint) + if auth_endpoint: + app.register_blueprint(user_blueprint) # Non-api blueprints app.register_blueprint(data_migration_blueprint) From 4e45c18c91bc1896687c6910887910dcdff66389 Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 22:08:00 -0500 Subject: [PATCH 24/36] validate response data --- .../src/api/users/test_user_route_token.py | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/api/tests/src/api/users/test_user_route_token.py b/api/tests/src/api/users/test_user_route_token.py index 2d6a8e6fe..ed2616029 100644 --- a/api/tests/src/api/users/test_user_route_token.py +++ b/api/tests/src/api/users/test_user_route_token.py @@ -1,16 +1,27 @@ +################## +# POST /user/token +################## -##################################### -# POST user token tests -##################################### - def test_post_user_route_token_200(client, api_auth_token): - resp= client.post(f"/v1/users/user/token", headers={"X-Auth": api_auth_token, "X-OAuth-login-gov": "test_token" }) - assert resp.status_code == 200 + resp = client.post( + "/v1/users/user/token", headers={"X-Auth": api_auth_token, "X-OAuth-login-gov": "test"} + ) response_data = resp.get_json()["data"] + expected_response_data = { + "token": "the token goes here!", + "user": { + "user_id": "abc-...", + "email": "example@gmail.com", + "external_user_type": "login_gov", + }, + "is_user_new": True, + } + assert resp.status_code == 200 + assert response_data == expected_response_data def test_post_user_route_token_400(client, api_auth_token): - resp= client.post(f"v1/users/user/token", headers={"X-Auth": api_auth_token}) + resp = client.post("v1/users/user/token", headers={"X-Auth": api_auth_token}) assert resp.status_code == 400 - assert resp.get_json()["message"] == "Missing X-OAuth-login-gov header" \ No newline at end of file + assert resp.get_json()["message"] == "Missing X-OAuth-login-gov header" From 45b249dd97a1eadb50dccdd38e2ca616bc33b4e4 Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 22:08:21 -0500 Subject: [PATCH 25/36] add header schema --- api/src/api/users/user_schemas.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/src/api/users/user_schemas.py b/api/src/api/users/user_schemas.py index 432f4b406..3ea05421f 100644 --- a/api/src/api/users/user_schemas.py +++ b/api/src/api/users/user_schemas.py @@ -3,6 +3,15 @@ from src.constants.lookup_constants import ExternalUserType +class UserTokenHeaderSchema(Schema): + x_oauth_login_gov = fields.String( + data_key="X-OAuth-login-gov", + metadata={ + "description": "The login_gov header token", + }, + ) + + class UserSchema(Schema): user_id = fields.String( metadata={ From e3292ade387086140c634aabe871dd8cb482130d Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 22:09:08 -0500 Subject: [PATCH 26/36] add blueprint header --- api/src/api/users/user_routes.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index a277d25a3..0c57dfcae 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -1,6 +1,6 @@ import logging -from flask import Response, request +from flask import Response from src.api import response from src.api.route_utils import raise_flask_error @@ -21,18 +21,20 @@ See [Release Phases](https://github.com/github/roadmap?tab=readme-ov-file#release-phases) for further details. """ + @user_blueprint.post("/user/token") +@user_blueprint.input( + user_schemas.UserTokenHeaderSchema, location="headers", arg_name="x_oauth_login_gov" +) @user_blueprint.output(user_schemas.UserTokenResponseSchema) @user_blueprint.auth_required(api_key_auth) -@user_blueprint.doc( #should we include this? - description=SHARED_ALPHA_DESCRIPTION, - responses=[200, 400] +@user_blueprint.doc( # should we include this? + description=SHARED_ALPHA_DESCRIPTION, responses=[200, 400] ) -def user_token() -> response.ApiResponse | Response: +def user_token(x_oauth_login_gov: str) -> response.ApiResponse | Response: logger.info("POST /v1/users/user/token") - header_token = request.headers.get("X-OAuth-login-gov") - if header_token: + if x_oauth_login_gov: data = { "token": "the token goes here!", "user": { From c0c643df0f583e93e51a190bb0f7ae11cd883fbd Mon Sep 17 00:00:00 2001 From: bruk Date: Tue, 19 Nov 2024 22:09:38 -0500 Subject: [PATCH 27/36] lint/format --- api/src/app.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/src/app.py b/api/src/app.py index 231f57dc0..993d5a3b1 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -42,8 +42,10 @@ class authEndpointConfig(PydanticBaseEnvConfig): auth_endpoint: bool = False if os.getenv("ENVIRONMENT", "local") == "local" else True + auth_endpoint = authEndpointConfig() + def create_app() -> APIFlask: app = APIFlask(__name__, title=TITLE, version=API_OVERALL_VERSION) From dee8882d9fdf4b412d9a4d2b93d0257605fbc2ab Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Wed, 20 Nov 2024 03:12:11 +0000 Subject: [PATCH 28/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index e052e33d3..df5517c08 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -46,7 +46,13 @@ paths: summary: Health /v1/users/user/token: post: - parameters: [] + parameters: + - in: header + name: X-OAuth-login-gov + description: The login_gov header token + schema: + type: string + required: false responses: '200': content: @@ -54,6 +60,12 @@ paths: schema: $ref: '#/components/schemas/UserTokenResponse' description: Successful response + '422': + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + description: Validation error '401': content: application/json: From fda2bfbfe6a8146a9076f7ef4e1acb75fb96e455 Mon Sep 17 00:00:00 2001 From: bruk Date: Wed, 20 Nov 2024 11:03:53 -0500 Subject: [PATCH 29/36] Set auth_endpoint env var --- api/src/app.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/app.py b/api/src/app.py index 993d5a3b1..b9bed4893 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -39,11 +39,11 @@ """ -class authEndpointConfig(PydanticBaseEnvConfig): - auth_endpoint: bool = False if os.getenv("ENVIRONMENT", "local") == "local" else True +class AuthEndpointConfig(PydanticBaseEnvConfig): + auth_endpoint: bool = True if os.getenv("ENVIRONMENT", "local") == "local" else False -auth_endpoint = authEndpointConfig() +auth_endpoint_config = AuthEndpointConfig() def create_app() -> APIFlask: @@ -127,7 +127,7 @@ def register_blueprints(app: APIFlask) -> None: app.register_blueprint(opportunities_v0_blueprint) app.register_blueprint(opportunities_v0_1_blueprint) app.register_blueprint(opportunities_v1_blueprint) - if auth_endpoint: + if auth_endpoint_config.auth_endpoint: app.register_blueprint(user_blueprint) # Non-api blueprints From 5c8320f90957c7cc80750e80671eb176be2d873e Mon Sep 17 00:00:00 2001 From: bruk Date: Wed, 20 Nov 2024 15:22:44 -0500 Subject: [PATCH 30/36] update AuthEndpointConfig --- api/src/app.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/app.py b/api/src/app.py index b9bed4893..fb20bda89 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -4,6 +4,7 @@ from apiflask import APIFlask, exceptions from flask_cors import CORS +from pydantic import Field import src.adapters.db as db import src.adapters.db.flask_db as flask_db @@ -40,10 +41,7 @@ class AuthEndpointConfig(PydanticBaseEnvConfig): - auth_endpoint: bool = True if os.getenv("ENVIRONMENT", "local") == "local" else False - - -auth_endpoint_config = AuthEndpointConfig() + auth_endpoint: bool = Field(False, alias="ENABLE_AUTH_ENDPOINT") def create_app() -> APIFlask: @@ -127,6 +125,8 @@ def register_blueprints(app: APIFlask) -> None: app.register_blueprint(opportunities_v0_blueprint) app.register_blueprint(opportunities_v0_1_blueprint) app.register_blueprint(opportunities_v1_blueprint) + + auth_endpoint_config = AuthEndpointConfig() if auth_endpoint_config.auth_endpoint: app.register_blueprint(user_blueprint) From 6a1dd4daf9d821a2d2ff4c8a1cbecfb02e087a34 Mon Sep 17 00:00:00 2001 From: bruk Date: Wed, 20 Nov 2024 15:23:11 -0500 Subject: [PATCH 31/36] add ENABLE_AUTH_ENDPOINT env var --- api/local.env | 1 + 1 file changed, 1 insertion(+) diff --git a/api/local.env b/api/local.env index f4f805609..9f56b5f7e 100644 --- a/api/local.env +++ b/api/local.env @@ -45,6 +45,7 @@ LOGIN_GOV_JWK_ENDPOINT=http://localhost:5001/issuer1/jwks LOGIN_GOV_ENDPOINT=http://localhost:5001 LOGIN_GOV_CLIENT_ID=TODO +ENABLE_AUTH_ENDPOINT=TRUE ############################ # DB Environment Variables ############################ From aceb260195438d40c2909be3dc05b23366ab9235 Mon Sep 17 00:00:00 2001 From: bruk Date: Wed, 20 Nov 2024 20:42:44 -0500 Subject: [PATCH 32/36] update endpoint route --- api/src/api/users/user_routes.py | 11 ++++------- api/tests/src/api/users/test_user_route_token.py | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 0c57dfcae..16e651ff9 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -22,17 +22,14 @@ """ -@user_blueprint.post("/user/token") +@user_blueprint.post("/token") @user_blueprint.input( user_schemas.UserTokenHeaderSchema, location="headers", arg_name="x_oauth_login_gov" ) @user_blueprint.output(user_schemas.UserTokenResponseSchema) @user_blueprint.auth_required(api_key_auth) -@user_blueprint.doc( # should we include this? - description=SHARED_ALPHA_DESCRIPTION, responses=[200, 400] -) -def user_token(x_oauth_login_gov: str) -> response.ApiResponse | Response: - logger.info("POST /v1/users/user/token") +def user_token(x_oauth_login_gov: dict) -> response.ApiResponse | Response: + logger.info("POST /v1/users/token") if x_oauth_login_gov: data = { @@ -47,6 +44,6 @@ def user_token(x_oauth_login_gov: str) -> response.ApiResponse | Response: return response.ApiResponse(message="Success", data=data) message = "Missing X-OAuth-login-gov header" - logger.error(message) + logger.info(message) raise_flask_error(400, message) diff --git a/api/tests/src/api/users/test_user_route_token.py b/api/tests/src/api/users/test_user_route_token.py index ed2616029..13f3d5aa6 100644 --- a/api/tests/src/api/users/test_user_route_token.py +++ b/api/tests/src/api/users/test_user_route_token.py @@ -5,7 +5,7 @@ def test_post_user_route_token_200(client, api_auth_token): resp = client.post( - "/v1/users/user/token", headers={"X-Auth": api_auth_token, "X-OAuth-login-gov": "test"} + "/v1/users/token", headers={"X-Auth": api_auth_token, "X-OAuth-login-gov": "test"} ) response_data = resp.get_json()["data"] expected_response_data = { @@ -22,6 +22,6 @@ def test_post_user_route_token_200(client, api_auth_token): def test_post_user_route_token_400(client, api_auth_token): - resp = client.post("v1/users/user/token", headers={"X-Auth": api_auth_token}) + resp = client.post("v1/users/token", headers={"X-Auth": api_auth_token}) assert resp.status_code == 400 assert resp.get_json()["message"] == "Missing X-OAuth-login-gov header" From d3bf43bbbfbad2ee0aacd3df9568a347e8893f6b Mon Sep 17 00:00:00 2001 From: nava-platform-bot Date: Thu, 21 Nov 2024 01:45:10 +0000 Subject: [PATCH 33/36] Create ERD diagram and Update OpenAPI spec --- api/openapi.generated.yml | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/api/openapi.generated.yml b/api/openapi.generated.yml index df5517c08..c28cccc6c 100644 --- a/api/openapi.generated.yml +++ b/api/openapi.generated.yml @@ -44,7 +44,7 @@ paths: tags: - Health summary: Health - /v1/users/user/token: + /v1/users/token: post: parameters: - in: header @@ -72,31 +72,9 @@ paths: schema: $ref: '#/components/schemas/ErrorResponse' description: Authentication error - '400': - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - description: Bad Request tags: - User v1 summary: User Token - description: ' - - __ALPHA VERSION__ - - - This endpoint in its current form is primarily for testing and feedback. - - - Features in this endpoint are still under heavy development, and subject to - change. Not for production use. - - - See [Release Phases](https://github.com/github/roadmap?tab=readme-ov-file#release-phases) - for further details. - - ' security: - ApiKeyAuth: [] /v1/opportunities/search: From e623330d13a640a3e3d7ffc94a7bbf92dd6788dd Mon Sep 17 00:00:00 2001 From: bruk Date: Thu, 21 Nov 2024 10:07:26 -0500 Subject: [PATCH 34/36] fix comment --- api/tests/src/api/users/test_user_route_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/tests/src/api/users/test_user_route_token.py b/api/tests/src/api/users/test_user_route_token.py index 13f3d5aa6..d0811de94 100644 --- a/api/tests/src/api/users/test_user_route_token.py +++ b/api/tests/src/api/users/test_user_route_token.py @@ -1,5 +1,5 @@ ################## -# POST /user/token +# POST /token ################## From 2b25ab7f40937475c68aedc6d9ab2f8614d441ab Mon Sep 17 00:00:00 2001 From: bruk Date: Thu, 21 Nov 2024 10:43:22 -0500 Subject: [PATCH 35/36] rm docstring and response type --- api/src/api/users/user_routes.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 16e651ff9..216cdf849 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -10,17 +10,6 @@ logger = logging.getLogger(__name__) -# Descriptions in OpenAPI support markdown https://swagger.io/specification/ -SHARED_ALPHA_DESCRIPTION = """ -__ALPHA VERSION__ - -This endpoint in its current form is primarily for testing and feedback. - -Features in this endpoint are still under heavy development, and subject to change. Not for production use. - -See [Release Phases](https://github.com/github/roadmap?tab=readme-ov-file#release-phases) for further details. -""" - @user_blueprint.post("/token") @user_blueprint.input( @@ -28,7 +17,7 @@ ) @user_blueprint.output(user_schemas.UserTokenResponseSchema) @user_blueprint.auth_required(api_key_auth) -def user_token(x_oauth_login_gov: dict) -> response.ApiResponse | Response: +def user_token(x_oauth_login_gov: dict) -> response.ApiResponse: logger.info("POST /v1/users/token") if x_oauth_login_gov: From 0433f6e23ee61b9a3eb83b564354184380387ed3 Mon Sep 17 00:00:00 2001 From: bruk Date: Thu, 21 Nov 2024 10:44:29 -0500 Subject: [PATCH 36/36] cleanup --- api/src/api/users/user_routes.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/src/api/users/user_routes.py b/api/src/api/users/user_routes.py index 216cdf849..1c34f0b5a 100644 --- a/api/src/api/users/user_routes.py +++ b/api/src/api/users/user_routes.py @@ -1,7 +1,5 @@ import logging -from flask import Response - from src.api import response from src.api.route_utils import raise_flask_error from src.api.users import user_schemas