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 7fab1f4f6b
commit ff8912f505
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 ciadmin1 ciadmin1 '%2Fprocess-models'
# KEYCLOAK_BASE_URL=http://localhost:7002
KEYCLOAK_BASE_URL=https://keycloak.dev.spiffworkflow.org
# BACKEND_BASE_URL=http://localhost:7000
BACKEND_BASE_URL=https://api.dev.spiffworkflow.org
KEYCLOAK_BASE_URL=http://localhost:7002
# KEYCLOAK_BASE_URL=https://keycloak.dev.spiffworkflow.org
BACKEND_BASE_URL=http://localhost:7000
# BACKEND_BASE_URL=https://api.dev.spiffworkflow.org
REALM_NAME=spiffworkflow
USERNAME=${1-fin}
PASSWORD=${2-fin}
@ -36,12 +36,12 @@ SECURE=false
BACKEND_BASIC_AUTH=$(echo -n "${BACKEND_CLIENT_ID}:${BACKEND_CLIENT_SECRET}" | base64)
KEYCLOAK_URL=$KEYCLOAK_BASE_URL/realms/$REALM_NAME/protocol/openid-connect/token
echo "Using Keycloak: $KEYCLOAK_URL"
echo "realm: $REALM_NAME"
echo "client-id: $FRONTEND_CLIENT_ID"
echo "username: $USERNAME"
echo "password: $PASSWORD"
echo "secure: $SECURE"
>&2 echo "Using Keycloak: $KEYCLOAK_URL"
>&2 echo "realm: $REALM_NAME"
>&2 echo "client-id: $FRONTEND_CLIENT_ID"
>&2 echo "username: $USERNAME"
>&2 echo "password: $PASSWORD"
>&2 echo "secure: $SECURE"
if [[ $SECURE = 'y' ]]; then
@ -61,8 +61,9 @@ result=$(curl -s -X POST "$KEYCLOAK_URL" "$INSECURE" \
-d "client_id=$BACKEND_CLIENT_ID" \
)
backend_token=$(jq -r '.access_token' <<< "$result")
echo "testing hitting backend with token: $backend_token"
curl --fail -v "${BACKEND_BASE_URL}/v1.0/process-groups?per_page=1" -H "Authorization: Bearer $backend_token"
echo "$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

View File

@ -79,6 +79,26 @@ paths:
"200":
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:
get:
operationId: spiffworkflow_backend.routes.user.login_api

View File

@ -1,5 +1,7 @@
"""User."""
import ast
from flask import make_response
from flask import jsonify
import base64
import json
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]:
"""Login_return."""
state_dict = ast.literal_eval(base64.b64decode(state).decode("utf-8"))
state_redirect_url = state_dict["redirect_url"]
auth_token_object = AuthenticationService().get_auth_token_object(code)
if "id_token" in auth_token_object:
id_token = auth_token_object["id_token"]
user_info = parse_id_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:
"""Login_api."""
redirect_url = "/v1.0/login_api_return"