added api endpoint to allow logging in for the first time with an openid access_token w/ burnettk

This commit is contained in:
jasquat 2023-02-13 11:57:31 -05:00
parent 69f85aad6b
commit a39ae63bde
3 changed files with 52 additions and 14 deletions

View File

@ -20,10 +20,10 @@ set -o errtrace -o errexit -o nounset -o pipefail
# ./bin/get_token repeat_form_user_1 repeat_form_user_1 # actually has permissions to the resource in this script # ./bin/get_token repeat_form_user_1 repeat_form_user_1 # actually has permissions to the resource in this script
# ./bin/get_token ciadmin1 ciadmin1 '%2Fprocess-models' # ./bin/get_token ciadmin1 ciadmin1 '%2Fprocess-models'
# KEYCLOAK_BASE_URL=http://localhost:7002 KEYCLOAK_BASE_URL=http://localhost:7002
KEYCLOAK_BASE_URL=https://keycloak.dev.spiffworkflow.org # KEYCLOAK_BASE_URL=https://keycloak.dev.spiffworkflow.org
# BACKEND_BASE_URL=http://localhost:7000 BACKEND_BASE_URL=http://localhost:7000
BACKEND_BASE_URL=https://api.dev.spiffworkflow.org # BACKEND_BASE_URL=https://api.dev.spiffworkflow.org
REALM_NAME=spiffworkflow REALM_NAME=spiffworkflow
USERNAME=${1-fin} USERNAME=${1-fin}
PASSWORD=${2-fin} PASSWORD=${2-fin}
@ -36,12 +36,12 @@ SECURE=false
BACKEND_BASIC_AUTH=$(echo -n "${BACKEND_CLIENT_ID}:${BACKEND_CLIENT_SECRET}" | base64) BACKEND_BASIC_AUTH=$(echo -n "${BACKEND_CLIENT_ID}:${BACKEND_CLIENT_SECRET}" | base64)
KEYCLOAK_URL=$KEYCLOAK_BASE_URL/realms/$REALM_NAME/protocol/openid-connect/token KEYCLOAK_URL=$KEYCLOAK_BASE_URL/realms/$REALM_NAME/protocol/openid-connect/token
echo "Using Keycloak: $KEYCLOAK_URL" >&2 echo "Using Keycloak: $KEYCLOAK_URL"
echo "realm: $REALM_NAME" >&2 echo "realm: $REALM_NAME"
echo "client-id: $FRONTEND_CLIENT_ID" >&2 echo "client-id: $FRONTEND_CLIENT_ID"
echo "username: $USERNAME" >&2 echo "username: $USERNAME"
echo "password: $PASSWORD" >&2 echo "password: $PASSWORD"
echo "secure: $SECURE" >&2 echo "secure: $SECURE"
if [[ $SECURE = 'y' ]]; then if [[ $SECURE = 'y' ]]; then
@ -61,8 +61,9 @@ result=$(curl -s -X POST "$KEYCLOAK_URL" "$INSECURE" \
-d "client_id=$BACKEND_CLIENT_ID" \ -d "client_id=$BACKEND_CLIENT_ID" \
) )
backend_token=$(jq -r '.access_token' <<< "$result") backend_token=$(jq -r '.access_token' <<< "$result")
echo "testing hitting backend with token: $backend_token" echo "$backend_token"
curl --fail -v "${BACKEND_BASE_URL}/v1.0/process-groups?per_page=1" -H "Authorization: Bearer $backend_token" # curl --fail -v "${BACKEND_BASE_URL}/v1.0/process-groups?per_page=1" -H "Authorization: Bearer $backend_token"
# curl -v -X POST "${BACKEND_BASE_URL}/v1.0/login_with_access_token?access_token=${backend_token}" -H "Authorization: Bearer $backend_token"
### Get with frontend and exchange with backend - not configured to work in keycloak atm ### Get with frontend and exchange with backend - not configured to work in keycloak atm

View File

@ -79,6 +79,26 @@ paths:
"200": "200":
description: Logout Authenticated User description: Logout Authenticated User
/login_with_access_token:
parameters:
- name: access_token
in: query
required: true
schema:
type: string
post:
operationId: spiffworkflow_backend.routes.user.login_with_access_token
summary: Authenticate user for API access with an openid token already posessed.
tags:
- Authentication
responses:
"200":
description: "Returns ok: true if user successfully logged in."
content:
application/json:
schema:
$ref: "#/components/schemas/OkTrue"
/login_api: /login_api:
get: get:
operationId: spiffworkflow_backend.routes.user.login_api operationId: spiffworkflow_backend.routes.user.login_api

View File

@ -1,5 +1,7 @@
"""User.""" """User."""
import ast import ast
from flask import make_response
from flask import jsonify
import base64 import base64
import json import json
import re import re
@ -261,13 +263,11 @@ def parse_id_token(token: str) -> Any:
def login_return(code: str, state: str, session_state: str = "") -> Optional[Response]: def login_return(code: str, state: str, session_state: str = "") -> Optional[Response]:
"""Login_return."""
state_dict = ast.literal_eval(base64.b64decode(state).decode("utf-8")) state_dict = ast.literal_eval(base64.b64decode(state).decode("utf-8"))
state_redirect_url = state_dict["redirect_url"] state_redirect_url = state_dict["redirect_url"]
auth_token_object = AuthenticationService().get_auth_token_object(code) auth_token_object = AuthenticationService().get_auth_token_object(code)
if "id_token" in auth_token_object: if "id_token" in auth_token_object:
id_token = auth_token_object["id_token"] id_token = auth_token_object["id_token"]
user_info = parse_id_token(id_token) user_info = parse_id_token(id_token)
if AuthenticationService.validate_id_or_access_token(id_token): if AuthenticationService.validate_id_or_access_token(id_token):
@ -299,6 +299,23 @@ def login_return(code: str, state: str, session_state: str = "") -> Optional[Res
) )
# FIXME: share more code with login_return and maybe attempt to get a refresh token
def login_with_access_token(access_token: str) -> Response:
user_info = parse_id_token(access_token)
if AuthenticationService.validate_id_or_access_token(access_token):
if user_info and "error" not in user_info:
AuthorizationService.create_user_from_sign_in(user_info)
else:
raise ApiError(
error_code="invalid_login",
message="Login failed. Please try again",
status_code=401,
)
return make_response(jsonify({"ok": True}))
def login_api() -> Response: def login_api() -> Response:
"""Login_api.""" """Login_api."""
redirect_url = "/v1.0/login_api_return" redirect_url = "/v1.0/login_api_return"