added script to add test keycloak users and moved all keycloak stuff to keycloak directory w/ burnettk
This commit is contained in:
parent
dd8427bd32
commit
306676aa11
|
@ -86,7 +86,7 @@ jobs:
|
||||||
run: ./bin/wait_for_frontend_to_be_up 5
|
run: ./bin/wait_for_frontend_to_be_up 5
|
||||||
- name: wait_for_keycloak
|
- name: wait_for_keycloak
|
||||||
working-directory: ./spiffworkflow-backend
|
working-directory: ./spiffworkflow-backend
|
||||||
run: ./bin/wait_for_keycloak 5
|
run: ./keycloak/bin/wait_for_keycloak 5
|
||||||
- name: Cypress run
|
- name: Cypress run
|
||||||
uses: cypress-io/github-action@v4
|
uses: cypress-io/github-action@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -22,8 +22,8 @@ set -o errtrace -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
# 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}
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"web": {
|
|
||||||
"issuer": "http://localhost:8080/realms/finance",
|
|
||||||
"auth_uri": "http://localhost:8080/realms/finance/protocol/openid-connect/auth",
|
|
||||||
"client_id": "myclient",
|
|
||||||
"client_secret": "OAh6rkjXIiPJDtPOz4459i3VtdlxGcce",
|
|
||||||
"redirect_uris": ["http://localhost:5005/*"],
|
|
||||||
"userinfo_uri": "http://localhost:8080/realms/finance/protocol/openid-connect/userinfo",
|
|
||||||
"token_uri": "http://localhost:8080/realms/finance/protocol/openid-connect/token",
|
|
||||||
"token_introspection_uri": "http://localhost:8080/realms/finance/protocol/openid-connect/token/introspect"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
# type: ignore
|
|
||||||
"""keycloak_test_server."""
|
|
||||||
# ./bin/start_keycloak # starts keycloak on 8080
|
|
||||||
# pip install flask_oidc
|
|
||||||
# pip install itsdangerous==2.0.1
|
|
||||||
# python ./bin/keycloak_test_server.py # starts flask on 5005
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from flask import Flask
|
|
||||||
from flask import g
|
|
||||||
from flask_oidc import OpenIDConnect
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
app.config.update(
|
|
||||||
{
|
|
||||||
"SECRET_KEY": "SomethingNotEntirelySecret",
|
|
||||||
"TESTING": True,
|
|
||||||
"DEBUG": True,
|
|
||||||
"OIDC_CLIENT_SECRETS": "bin/keycloak_test_secrets.json",
|
|
||||||
"OIDC_ID_TOKEN_COOKIE_SECURE": False,
|
|
||||||
"OIDC_REQUIRE_VERIFIED_EMAIL": False,
|
|
||||||
"OIDC_USER_INFO_ENABLED": True,
|
|
||||||
"OIDC_OPENID_REALM": "flask-demo",
|
|
||||||
"OIDC_SCOPES": ["openid", "email", "profile"],
|
|
||||||
"OIDC_INTROSPECTION_AUTH_METHOD": "client_secret_post",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
oidc = OpenIDConnect(app)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
|
||||||
def hello_world():
|
|
||||||
"""Hello_world."""
|
|
||||||
if oidc.user_loggedin:
|
|
||||||
return (
|
|
||||||
'Hello, %s, <a href="/private">See private</a> '
|
|
||||||
'<a href="/logout">Log out</a>'
|
|
||||||
% oidc.user_getfield("preferred_username")
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return 'Welcome anonymous, <a href="/private">Log in</a>'
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/private")
|
|
||||||
@oidc.require_login
|
|
||||||
def hello_me():
|
|
||||||
"""Example for protected endpoint that extracts private information from the OpenID Connect id_token.
|
|
||||||
|
|
||||||
Uses the accompanied access_token to access a backend service.
|
|
||||||
"""
|
|
||||||
info = oidc.user_getinfo(["preferred_username", "email", "sub"])
|
|
||||||
|
|
||||||
username = info.get("preferred_username")
|
|
||||||
email = info.get("email")
|
|
||||||
user_id = info.get("sub")
|
|
||||||
|
|
||||||
if user_id in oidc.credentials_store:
|
|
||||||
try:
|
|
||||||
from oauth2client.client import OAuth2Credentials
|
|
||||||
|
|
||||||
access_token = OAuth2Credentials.from_json(
|
|
||||||
oidc.credentials_store[user_id]
|
|
||||||
).access_token
|
|
||||||
print("access_token=<%s>" % access_token)
|
|
||||||
headers = {"Authorization": "Bearer %s" % (access_token)}
|
|
||||||
# YOLO
|
|
||||||
greeting = requests.get(
|
|
||||||
"http://localhost:8080/greeting", headers=headers
|
|
||||||
).text
|
|
||||||
except BaseException:
|
|
||||||
print("Could not access greeting-service")
|
|
||||||
greeting = "Hello %s" % username
|
|
||||||
|
|
||||||
return """{} your email is {} and your user_id is {}!
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Home</a></li>
|
|
||||||
<li><a href="//localhost:8080/auth/realms/finance/account?referrer=flask-app&referrer_uri=http://localhost:5005/private&">Account</a></li>
|
|
||||||
</ul>""".format(
|
|
||||||
greeting,
|
|
||||||
email,
|
|
||||||
user_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api", methods=["POST"])
|
|
||||||
@oidc.accept_token(require_token=True, scopes_required=["openid"])
|
|
||||||
def hello_api():
|
|
||||||
"""OAuth 2.0 protected API endpoint accessible via AccessToken."""
|
|
||||||
return json.dumps({"hello": "Welcome %s" % g.oidc_token_info["sub"]})
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/logout")
|
|
||||||
def logout():
|
|
||||||
"""Performs local logout by removing the session cookie."""
|
|
||||||
oidc.logout()
|
|
||||||
return 'Hi, you have been logged out! <a href="/">Return</a>'
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run(port=5005)
|
|
|
@ -1,10 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
function error_handler() {
|
|
||||||
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
|
||||||
exit "$2"
|
|
||||||
}
|
|
||||||
trap 'error_handler ${LINENO} $?' ERR
|
|
||||||
set -o errtrace -o errexit -o nounset -o pipefail
|
|
||||||
|
|
||||||
curl -v -F key1=value1 -F upload=@localfilename URL
|
|
|
@ -1,26 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
function error_handler() {
|
|
||||||
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
|
||||||
exit "$2"
|
|
||||||
}
|
|
||||||
trap 'error_handler ${LINENO} $?' ERR
|
|
||||||
set -o errtrace -o errexit -o nounset -o pipefail
|
|
||||||
|
|
||||||
if [[ "${1:-}" == "c" ]]; then
|
|
||||||
curl --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{}'
|
|
||||||
elif grep -qE '^[0-9]$' <<<"${1:-}" ; then
|
|
||||||
curl --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d "{ \"task_identifier\": \"${1}\"}"
|
|
||||||
else
|
|
||||||
./bin/recreate_db clean
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Product Name": "G", "Quantity": "2"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Sleeve Type": "Short"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Continue shopping?": "N"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Shipping Method": "Overnight"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Shipping Address": "Somewhere"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Place Order": "Y"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Card Number": "MY_CARD"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "2", "answer": {"Was the customer charged?": "Y"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Was the product available?": "Y"}}' | jq .
|
|
||||||
curl --silent --fail localhost:5000/run_process -H "Content-type: application/json" -X POST -d '{ "task_identifier": "1", "answer": {"Was the order shipped?": "Y"}}' | jq .
|
|
||||||
fi
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
function error_handler() {
|
||||||
|
>&2 echo "Exited with BAD EXIT CODE '${2}' in ${0} script at line: ${1}."
|
||||||
|
exit "$2"
|
||||||
|
}
|
||||||
|
trap 'error_handler ${LINENO} $?' ERR
|
||||||
|
set -o errtrace -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
user_file_with_one_email_per_line="${1:-}"
|
||||||
|
if [[ -z "${1:-}" ]]; then
|
||||||
|
>&2 echo "usage: $(basename "$0") [user_file_with_one_email_per_line]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
KEYCLOAK_BASE_URL=http://localhost:7002
|
||||||
|
REALM_NAME=master
|
||||||
|
ADMIN_USERNAME="admin"
|
||||||
|
ADMIN_PASSWORD="admin"
|
||||||
|
SECURE=false
|
||||||
|
|
||||||
|
KEYCLOAK_URL=$KEYCLOAK_BASE_URL/realms/$REALM_NAME/protocol/openid-connect/token
|
||||||
|
|
||||||
|
if [[ $SECURE = 'y' ]]; then
|
||||||
|
INSECURE=
|
||||||
|
else
|
||||||
|
INSECURE=--insecure
|
||||||
|
fi
|
||||||
|
|
||||||
|
# https://www.appsdeveloperblog.com/keycloak-rest-api-create-a-new-user/
|
||||||
|
result=$(curl --fail -s -X POST "$KEYCLOAK_URL" "$INSECURE" \
|
||||||
|
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
|
--data-urlencode "username=${ADMIN_USERNAME}" \
|
||||||
|
--data-urlencode "password=${ADMIN_PASSWORD}" \
|
||||||
|
--data-urlencode 'grant_type=password' \
|
||||||
|
--data-urlencode 'client_id=admin-cli'
|
||||||
|
)
|
||||||
|
backend_token=$(jq -r '.access_token' <<< "$result")
|
||||||
|
|
||||||
|
while read -r user_email; do
|
||||||
|
if [[ -n "$user_email" ]]; then
|
||||||
|
username=$(awk -F '@' '{print $1}' <<<"$user_email")
|
||||||
|
credentials='{"type":"password","value":"'"${username}"'","temporary":false}'
|
||||||
|
|
||||||
|
curl --fail --location --request POST 'http://localhost:7002/admin/realms/spiffworkflow/users' \
|
||||||
|
-H 'Content-Type: application/json' \
|
||||||
|
-H "Authorization: Bearer $backend_token" \
|
||||||
|
--data-raw '{"email":"'"${user_email}"'", "enabled":"true", "username":"'"${username}"'", "credentials":['"${credentials}"']}'
|
||||||
|
fi
|
||||||
|
done <"$user_file_with_one_email_per_line"
|
|
@ -7,6 +7,8 @@ function error_handler() {
|
||||||
trap 'error_handler ${LINENO} $?' ERR
|
trap 'error_handler ${LINENO} $?' ERR
|
||||||
set -o errtrace -o errexit -o nounset -o pipefail
|
set -o errtrace -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
|
|
||||||
realms="$*"
|
realms="$*"
|
||||||
if [[ -z "$realms" ]]; then
|
if [[ -z "$realms" ]]; then
|
||||||
realms="spiffworkflow-realm"
|
realms="spiffworkflow-realm"
|
||||||
|
@ -19,7 +21,7 @@ docker exec keycloak /opt/keycloak/bin/kc.sh export --dir "${docker_container_pa
|
||||||
docker cp "keycloak:${docker_container_path}" "$local_tmp_dir"
|
docker cp "keycloak:${docker_container_path}" "$local_tmp_dir"
|
||||||
|
|
||||||
for realm in $realms ; do
|
for realm in $realms ; do
|
||||||
cp "${local_tmp_dir}/hey/${realm}.json" bin/
|
cp "${local_tmp_dir}/hey/${realm}.json" "${script_dir}/realm_exports"
|
||||||
done
|
done
|
||||||
|
|
||||||
rm -rf "$local_tmp_dir"
|
rm -rf "$local_tmp_dir"
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,7 @@ docker run \
|
||||||
-Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
|
-Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
|
||||||
|
|
||||||
script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
script_dir="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||||
cp "${script_dir}/spiffworkflow-realm.json" /tmp/spiffworkflow-realm.json
|
cp "${script_dir}/../realm_exports/spiffworkflow-realm.json" /tmp/spiffworkflow-realm.json
|
||||||
spiff_subdomain="unused-for-local-dev"
|
spiff_subdomain="unused-for-local-dev"
|
||||||
perl -pi -e "s/{{SPIFF_SUBDOMAIN}}/${spiff_subdomain}/g" /tmp/spiffworkflow-realm.json
|
perl -pi -e "s/{{SPIFF_SUBDOMAIN}}/${spiff_subdomain}/g" /tmp/spiffworkflow-realm.json
|
||||||
docker cp /tmp/spiffworkflow-realm.json keycloak:/tmp
|
docker cp /tmp/spiffworkflow-realm.json keycloak:/tmp
|
|
@ -0,0 +1,9 @@
|
||||||
|
finance.lead@status.im
|
||||||
|
legal.lead@status.im
|
||||||
|
program.lead@status.im
|
||||||
|
services.lead@status.im
|
||||||
|
finance.sme@status.im
|
||||||
|
infra.sme@status.im
|
||||||
|
legal.sme@status.im
|
||||||
|
security.sme@status.im
|
||||||
|
|
|
@ -87,7 +87,7 @@ jobs:
|
||||||
run: ./bin/wait_for_frontend_to_be_up 5
|
run: ./bin/wait_for_frontend_to_be_up 5
|
||||||
- name: wait_for_keycloak
|
- name: wait_for_keycloak
|
||||||
working-directory: ./spiffworkflow-backend
|
working-directory: ./spiffworkflow-backend
|
||||||
run: ./bin/wait_for_keycloak 5
|
run: ./keycloak/bin/wait_for_keycloak 5
|
||||||
- name: Cypress run
|
- name: Cypress run
|
||||||
uses: cypress-io/github-action@v4
|
uses: cypress-io/github-action@v4
|
||||||
with:
|
with:
|
||||||
|
|
Loading…
Reference in New Issue