Skip to content

Commit 8f177bf

Browse files
committedMay 2, 2022
Adding JWT Mock and Keycloak docker mock
1 parent b8fae87 commit 8f177bf

18 files changed

+2780
-238
lines changed
 

‎.github/workflows/forms-flow-api-ci.yml

+12-13
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,24 @@ jobs:
5858
FLASK_ENV: "testing"
5959
DATABASE_URL_TEST: "postgresql://postgres:postgres@localhost:5432/postgres"
6060
FORMSFLOW_API_URL: "http://localhost:5000"
61-
KEYCLOAK_URL: ${{ secrets.KEYCLOAK_URL }}
62-
KEYCLOAK_URL_REALM: ${{ secrets.KEYCLOAK_URL_REALM }}
63-
KEYCLOAK_BPM_CLIENT_SECRET: ${{ secrets.KEYCLOAK_BPM_CLIENT_SECRET }}
64-
CAMUNDA_API_URL: ${{ secrets.CAMUNDA_API_URL }}
65-
JWT_OIDC_WELL_KNOWN_CONFIG: ${{ secrets.JWT_OIDC_WELL_KNOWN_CONFIG }}
61+
KEYCLOAK_URL: "http://localhost:8081"
62+
KEYCLOAK_URL_REALM: "forms-flow-ai"
63+
KEYCLOAK_BPM_CLIENT_SECRET: "demo"
64+
JWT_OIDC_WELL_KNOWN_CONFIG: "http://localhost:8081/auth/realms/forms-flow-ai/.well-known/openid-configuration"
6665
JWT_OIDC_ALGORITHMS: "RS256"
67-
JWT_OIDC_JWKS_URI: ${{ secrets.JWT_OIDC_JWKS_URI }}
68-
JWT_OIDC_ISSUER: ${{ secrets.JWT_OIDC_ISSUER }}
69-
JWT_OIDC_AUDIENCE: ${{ secrets.JWT_OIDC_AUDIENCE }}
66+
JWT_OIDC_JWKS_URI: "http://localhost:8081/auth/realms/forms-flow-ai/protocol/openid-connect/certs"
67+
JWT_OIDC_ISSUER: "http://localhost:8081/auth/realms/forms-flow-ai"
68+
JWT_OIDC_AUDIENCE: "forms-flow-web"
7069
JWT_OIDC_CACHING_ENABLED: "True"
7170
BPM_API_BASE: ${{ secrets.BPM_API_BASE }}
72-
BPM_CLIENT_SECRET: ${{ secrets.BPM_CLIENT_SECRET }}
73-
BPM_CLIENT_ID: ${{ secrets.BPM_CLIENT_ID }}
74-
BPM_TOKEN_API: ${{ secrets.BPM_TOKEN_API }}
75-
TEST_REVIEWER_USERID: ${{ secrets.TEST_REVIEWER_USERID }}
76-
TEST_REVIEWER_PASSWORD: ${{ secrets.TEST_REVIEWER_PASSWORD }}
71+
BPM_CLIENT_SECRET: "demo"
72+
BPM_CLIENT_ID: "forms-flow-bpm"
73+
BPM_TOKEN_API: "http://localhost:8081/auth/realms/forms-flow-ai/protocol/openid-connect/token"
74+
CAMUNDA_API_URL: ${{ secrets.CAMUNDA_API_URL }}
7775
INSIGHT_API_URL: ${{ secrets.INSIGHT_API_URL }}
7876
INSIGHT_API_KEY: ${{ secrets.INSIGHT_API_KEY }}
7977
SKIP_IN_CI: "True"
78+
USE_DOCKER_MOCK: "True"
8079

8180
runs-on: ubuntu-20.04
8281

‎forms-flow-api/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ build: ## Build the project with basic python dependencies
5252
. venv/bin/activate ;\
5353
pip install --upgrade pip ;\
5454
pip install -Ur requirements.txt ;\
55-
pip install -Ur requirements_dev.txt ;\
55+
pip install -Ur requirements/dev.txt ;\
5656
pip install -e .
5757

5858
#################################################################################

‎forms-flow-api/requirements/dev.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ pytest-cov
1414
pytest-it
1515
pyflakes
1616
pylint
17+
lovely-pytest-docker

‎forms-flow-api/requirements_dev.txt

-38
This file was deleted.

‎forms-flow-api/setup.cfg

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = formsflow_api
3-
version = 4.0.5
3+
version = 4.0.6
44
author = aot-technologies
55
classifiers =
66
Development Status :: Beta
@@ -36,7 +36,7 @@ exclude = .git,*migrations*,*venv*, .eggs*
3636
docstring-min-length=10
3737
per-file-ignores =
3838
*/__init__.py:F401,I001
39-
max-line-length = 88
39+
max-line-length = 120
4040
ignore = E203,E501, Q000, D401, B902, I001, I003, I004, E126, W503, W504
4141

4242
[pycodestyle]

‎forms-flow-api/src/formsflow_api/config.py

+61-2
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,76 @@ class TestConfig(_Config): # pylint: disable=too-few-public-methods
104104
# POSTGRESQL
105105
SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL_TEST")
106106

107-
# JWT_OIDC_TEST_MODE = True
107+
JWT_OIDC_TEST_MODE = True
108108
# USE_TEST_KEYCLOAK_DOCKER = os.getenv("USE_TEST_KEYCLOAK_DOCKER")
109109

110110
# JWT_OIDC Settings
111111
JWT_OIDC_TEST_AUDIENCE = os.getenv("JWT_OIDC_AUDIENCE")
112112
JWT_OIDC_TEST_ISSUER = os.getenv("JWT_OIDC_ISSUER")
113113
JWT_OIDC_TEST_WELL_KNOWN_CONFIG = os.getenv("JWT_OIDC_WELL_KNOWN_CONFIG")
114-
JWT_OIDC_TEST_ALGORITHMS = os.getenv("JWT_OIDC_ALGORITHMS")
114+
JWT_OIDC_TEST_ALGORITHMS = "RS256"
115115
JWT_OIDC_TEST_JWKS_URI = os.getenv("JWT_OIDC_JWKS_URI")
116116
JWT_OIDC_TEST_JWKS_CACHE_TIMEOUT = 6000
117117

118+
# Keycloak Service for BPM Camunda
119+
KEYCLOAK_URL_REALM = os.getenv("KEYCLOAK_URL_REALM", default="forms-flow-ai")
120+
KEYCLOAK_URL = os.getenv("KEYCLOAK_URL", default="http://localhost:8081")
121+
122+
# Use docker to spin up mocks
123+
USE_DOCKER_MOCK = os.getenv('USE_DOCKER_MOCK', 'False').lower() == 'true'
124+
125+
JWT_OIDC_TEST_KEYS = {
126+
"keys": [
127+
{
128+
"kid": JWT_OIDC_TEST_AUDIENCE,
129+
"kty": "RSA",
130+
"alg": "RS256",
131+
"use": "sig",
132+
"n": "AN-fWcpCyE5KPzHDjigLaSUVZI0uYrcGcc40InVtl-rQRDmAh-C2W8H4_Hxhr5VLc6crsJ2LiJTV_E72S03pzpOOaaYV6-"
133+
"TzAjCou2GYJIXev7f6Hh512PuG5wyxda_TlBSsI-gvphRTPsKCnPutrbiukCYrnPuWxX5_cES9eStR",
134+
"e": "AQAB",
135+
}
136+
]
137+
}
138+
139+
JWT_OIDC_TEST_PRIVATE_KEY_JWKS = {
140+
"keys": [
141+
{
142+
"kid": JWT_OIDC_TEST_AUDIENCE,
143+
"kty": "RSA",
144+
"alg": "RS256",
145+
"use": "sig",
146+
"n": "AN-fWcpCyE5KPzHDjigLaSUVZI0uYrcGcc40InVtl-rQRDmAh-C2W8H4_Hxhr5VLc6crsJ2LiJTV_E72S03pzpOOaaYV6-"
147+
"TzAjCou2GYJIXev7f6Hh512PuG5wyxda_TlBSsI-gvphRTPsKCnPutrbiukCYrnPuWxX5_cES9eStR",
148+
"e": "AQAB",
149+
"d": "C0G3QGI6OQ6tvbCNYGCqq043YI_8MiBl7C5dqbGZmx1ewdJBhMNJPStuckhskURaDwk4-"
150+
"8VBW9SlvcfSJJrnZhgFMjOYSSsBtPGBIMIdM5eSKbenCCjO8Tg0BUh_"
151+
"xa3CHST1W4RQ5rFXadZ9AeNtaGcWj2acmXNO3DVETXAX3x0",
152+
"p": "APXcusFMQNHjh6KVD_hOUIw87lvK13WkDEeeuqAydai9Ig9JKEAAfV94W6Aftka7tGgE7ulg1vo3eJoLWJ1zvKM",
153+
"q": "AOjX3OnPJnk0ZFUQBwhduCweRi37I6DAdLTnhDvcPTrrNWuKPg9uGwHjzFCJgKd8KBaDQ0X1rZTZLTqi3peT43s",
154+
"dp": "AN9kBoA5o6_Rl9zeqdsIdWFmv4DB5lEqlEnC7HlAP-3oo3jWFO9KQqArQL1V8w2D4aCd0uJULiC9pCP7aTHvBhc",
155+
"dq": "ANtbSY6njfpPploQsF9sU26U0s7MsuLljM1E8uml8bVJE1mNsiu9MgpUvg39jEu9BtM2tDD7Y51AAIEmIQex1nM",
156+
"qi": "XLE5O360x-MhsdFXx8Vwz4304-MJg-oGSJXCK_ZWYOB_FGXFRTfebxCsSYi0YwJo-oNu96bvZCuMplzRI1liZw",
157+
}
158+
]
159+
}
160+
161+
JWT_OIDC_TEST_PRIVATE_KEY_PEM = """-----BEGIN RSA PRIVATE KEY-----
162+
MIICXQIBAAKBgQDfn1nKQshOSj8xw44oC2klFWSNLmK3BnHONCJ1bZfq0EQ5gIfg
163+
tlvB+Px8Ya+VS3OnK7Cdi4iU1fxO9ktN6c6TjmmmFevk8wIwqLthmCSF3r+3+h4e
164+
ddj7hucMsXWv05QUrCPoL6YUUz7Cgpz7ra24rpAmK5z7lsV+f3BEvXkrUQIDAQAB
165+
AoGAC0G3QGI6OQ6tvbCNYGCqq043YI/8MiBl7C5dqbGZmx1ewdJBhMNJPStuckhs
166+
kURaDwk4+8VBW9SlvcfSJJrnZhgFMjOYSSsBtPGBIMIdM5eSKbenCCjO8Tg0BUh/
167+
xa3CHST1W4RQ5rFXadZ9AeNtaGcWj2acmXNO3DVETXAX3x0CQQD13LrBTEDR44ei
168+
lQ/4TlCMPO5bytd1pAxHnrqgMnWovSIPSShAAH1feFugH7ZGu7RoBO7pYNb6N3ia
169+
C1idc7yjAkEA6Nfc6c8meTRkVRAHCF24LB5GLfsjoMB0tOeEO9w9Ous1a4o+D24b
170+
AePMUImAp3woFoNDRfWtlNktOqLel5PjewJBAN9kBoA5o6/Rl9zeqdsIdWFmv4DB
171+
5lEqlEnC7HlAP+3oo3jWFO9KQqArQL1V8w2D4aCd0uJULiC9pCP7aTHvBhcCQQDb
172+
W0mOp436T6ZaELBfbFNulNLOzLLi5YzNRPLppfG1SRNZjbIrvTIKVL4N/YxLvQbT
173+
NrQw+2OdQACBJiEHsdZzAkBcsTk7frTH4yGx0VfHxXDPjfTj4wmD6gZIlcIr9lZg
174+
4H8UZcVFN95vEKxJiLRjAmj6g273pu9kK4ymXNEjWWJn
175+
-----END RSA PRIVATE KEY-----"""
176+
118177

119178
class ProdConfig(_Config): # pylint: disable=too-few-public-methods
120179
"""Production environment configuration."""

‎forms-flow-api/tests/conftest.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from sqlalchemy import event, text
66
from sqlalchemy.schema import DropConstraint, MetaData
77

8-
from formsflow_api import create_app
8+
from formsflow_api import create_app, setup_jwt_manager
99
from formsflow_api.models import db as _db
1010
from formsflow_api.utils import jwt as _jwt
1111

@@ -126,3 +126,22 @@ def restart_savepoint(sess2, trans): # pylint: disable=unused-variable
126126
# This instruction rollsback any commit that were executed in the tests.
127127
txn.rollback()
128128
conn.close()
129+
130+
131+
@pytest.fixture(scope="session", autouse=True)
132+
def auto(docker_services, app):
133+
"""Spin up a keycloak instance and initialize jwt."""
134+
if app.config.get('USE_DOCKER_MOCK'):
135+
docker_services.start('keycloak')
136+
docker_services.wait_for_service('keycloak', 8081)
137+
setup_jwt_manager(app, _jwt)
138+
139+
140+
@pytest.fixture(scope="session")
141+
def docker_compose_files(pytestconfig):
142+
"""Get the docker-compose.yml absolute path."""
143+
import os
144+
145+
return [
146+
os.path.join(str(pytestconfig.rootdir), "tests/docker", "docker-compose.yml")
147+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
version: "3"
2+
3+
services:
4+
keycloak:
5+
image: quay.io/keycloak/keycloak:14.0.0
6+
ports:
7+
- "8081:8081"
8+
environment:
9+
- KEYCLOAK_USER=admin
10+
- KEYCLOAK_PASSWORD=admin
11+
command: -b 0.0.0.0 -Djboss.http.port=8081 -Dkeycloak.migration.action=import -Dkeycloak.migration.provider=dir -Dkeycloak.migration.dir=/tmp/keycloak/test -Dkeycloak.migration.strategy=OVERWRITE_EXISTING
12+
healthcheck:
13+
test:
14+
[
15+
"CMD",
16+
"curl",
17+
"--fail",
18+
"http://localhost:8081/auth/realms/forms-flow-ai || exit 1",
19+
]
20+
interval: 30s
21+
timeout: 10s
22+
retries: 10
23+
volumes:
24+
- ./realms:/tmp/keycloak/test/
25+
networks:
26+
- test-network
27+
28+
networks:
29+
test-network:
30+
driver: 'bridge'

0 commit comments

Comments
 (0)