Oauth admin (#434)
* Adding dependencies * Disconnect from /v1/auths for auth list. hardcoded for now. * Revert changes * WIP * Getting hardcoded v2 auths into the frontend * Better url for v2 oauth * Pass the auth token from the frontend, don't verify token to start the auth process * Manually verify the token from the querystring * WIP * WIP * WIP, refactor SPIFF_SECRET handling, move dependencies * Construct remote_app * WIP * WIP * WIP * WIP * Ugly but getting the grant screen * WIP * WIP * Github oauth ok * Verify token, save access token * Let secret name work with regex * Getting bin_pyl to pass * New component * Load up the current config in an editor * Getting bin_pyl to pass * End point to update auth config * Linting * Adding configuration model * Adding configuration model * Prep to read config from db * Read config from the db * Save/reload poor man's styling * Getting bin_pyl to pass * Getting bin_pyl to pass * Getting bin_pyl to pass * Better handling of invalid json * Getting bin_pyl to pass
This commit is contained in:
parent
ca4984599a
commit
e24c9a17a9
|
@ -0,0 +1,41 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 5c50ecf2c1cd
|
||||
Revises: 64adf34a98db
|
||||
Create Date: 2023-08-08 11:21:15.278625
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5c50ecf2c1cd'
|
||||
down_revision = '64adf34a98db'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('configuration',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('category', sa.String(length=255), nullable=True),
|
||||
sa.Column('value', sa.JSON(), nullable=True),
|
||||
sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True),
|
||||
sa.Column('created_at_in_seconds', sa.Integer(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
with op.batch_alter_table('configuration', schema=None) as batch_op:
|
||||
batch_op.create_index(batch_op.f('ix_configuration_category'), ['category'], unique=False)
|
||||
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
with op.batch_alter_table('configuration', schema=None) as batch_op:
|
||||
batch_op.drop_index(batch_op.f('ix_configuration_category'))
|
||||
|
||||
op.drop_table('configuration')
|
||||
# ### end Alembic commands ###
|
|
@ -1,9 +1,10 @@
|
|||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "alembic"
|
||||
version = "1.10.3"
|
||||
description = "A database migration tool for SQLAlchemy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -23,6 +24,7 @@ tz = ["python-dateutil"]
|
|||
name = "aniso8601"
|
||||
version = "9.0.1"
|
||||
description = "A library for parsing ISO 8601 strings."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -37,6 +39,7 @@ dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"]
|
|||
name = "apscheduler"
|
||||
version = "3.10.1"
|
||||
description = "In-process task scheduler with Cron-like capabilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -48,7 +51,7 @@ files = [
|
|||
pytz = "*"
|
||||
setuptools = ">=0.7"
|
||||
six = ">=1.4.0"
|
||||
tzlocal = ">=2.0,<3.dev0 || >=4.dev0"
|
||||
tzlocal = ">=2.0,<3.0.0 || >=4.0.0"
|
||||
|
||||
[package.extras]
|
||||
doc = ["sphinx", "sphinx-rtd-theme"]
|
||||
|
@ -66,6 +69,7 @@ zookeeper = ["kazoo"]
|
|||
name = "attrs"
|
||||
version = "22.2.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -84,6 +88,7 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy
|
|||
name = "bandit"
|
||||
version = "1.7.2"
|
||||
description = "Security oriented static analyser for python code."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -106,6 +111,7 @@ yaml = ["PyYAML"]
|
|||
name = "bcrypt"
|
||||
version = "4.0.1"
|
||||
description = "Modern password hashing for your software and your servers"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -140,6 +146,7 @@ typecheck = ["mypy"]
|
|||
name = "black"
|
||||
version = "22.12.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -174,6 +181,7 @@ uvloop = ["uvloop (>=0.15.2)"]
|
|||
name = "blinker"
|
||||
version = "1.6.2"
|
||||
description = "Fast, simple object-to-object and broadcast signaling"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -181,10 +189,23 @@ files = [
|
|||
{file = "blinker-1.6.2.tar.gz", hash = "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cachelib"
|
||||
version = "0.10.2"
|
||||
description = "A collection of cache libraries in the same API interface."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "cachelib-0.10.2-py3-none-any.whl", hash = "sha256:42d49f2fad9310dd946d7be73d46776bcd4d5fde4f49ad210cfdd447fbdfc346"},
|
||||
{file = "cachelib-0.10.2.tar.gz", hash = "sha256:593faeee62a7c037d50fc835617a01b887503f972fb52b188ae7e50e9cb69740"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2023.7.22"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -196,6 +217,7 @@ files = [
|
|||
name = "cffi"
|
||||
version = "1.15.1"
|
||||
description = "Foreign Function Interface for Python calling C code."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -272,6 +294,7 @@ pycparser = "*"
|
|||
name = "cfgv"
|
||||
version = "3.3.1"
|
||||
description = "Validate configuration and produce human readable error messages."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1"
|
||||
files = [
|
||||
|
@ -283,6 +306,7 @@ files = [
|
|||
name = "charset-normalizer"
|
||||
version = "3.1.0"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
|
@ -367,6 +391,7 @@ files = [
|
|||
name = "click"
|
||||
version = "8.1.3"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -381,6 +406,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
|||
name = "clickclick"
|
||||
version = "20.10.2"
|
||||
description = "Click utility functions"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -396,6 +422,7 @@ PyYAML = ">=3.11"
|
|||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
|
@ -407,6 +434,7 @@ files = [
|
|||
name = "configparser"
|
||||
version = "5.3.0"
|
||||
description = "Updated configparser from stdlib for earlier Pythons."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -422,6 +450,7 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec
|
|||
name = "connexion"
|
||||
version = "2.14.1"
|
||||
description = "Connexion - API first applications with OpenAPI/Swagger and Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -452,6 +481,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14
|
|||
name = "coverage"
|
||||
version = "6.5.0"
|
||||
description = "Code coverage measurement for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -517,6 +547,7 @@ toml = ["tomli"]
|
|||
name = "cryptography"
|
||||
version = "41.0.3"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -562,6 +593,7 @@ test-randomorder = ["pytest-randomly"]
|
|||
name = "dateparser"
|
||||
version = "1.1.8"
|
||||
description = "Date parsing library designed to parse dates from HTML pages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -584,6 +616,7 @@ langdetect = ["langdetect"]
|
|||
name = "distlib"
|
||||
version = "0.3.6"
|
||||
description = "Distribution utilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -595,6 +628,7 @@ files = [
|
|||
name = "dparse"
|
||||
version = "0.6.2"
|
||||
description = "A parser for Python dependency files"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -614,6 +648,7 @@ pipenv = ["pipenv"]
|
|||
name = "exceptiongroup"
|
||||
version = "1.1.1"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -628,6 +663,7 @@ test = ["pytest (>=6)"]
|
|||
name = "execnet"
|
||||
version = "1.9.0"
|
||||
description = "execnet: rapid multi-Python deployment"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
|
@ -642,6 +678,7 @@ testing = ["pre-commit"]
|
|||
name = "filelock"
|
||||
version = "3.11.0"
|
||||
description = "A platform independent file lock."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -657,6 +694,7 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "p
|
|||
name = "flask"
|
||||
version = "2.2.5"
|
||||
description = "A simple framework for building complex web applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -678,6 +716,7 @@ dotenv = ["python-dotenv"]
|
|||
name = "flask-admin"
|
||||
version = "1.6.1"
|
||||
description = "Simple and extensible admin interface framework for Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -697,6 +736,7 @@ azure = ["azure-storage-blob"]
|
|||
name = "flask-bcrypt"
|
||||
version = "1.0.1"
|
||||
description = "Brcrypt hashing for Flask."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -712,6 +752,7 @@ Flask = "*"
|
|||
name = "flask-cors"
|
||||
version = "3.0.10"
|
||||
description = "A Flask extension adding a decorator for CORS support"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -727,6 +768,7 @@ Six = "*"
|
|||
name = "flask-jwt-extended"
|
||||
version = "4.4.4"
|
||||
description = "Extended JWT integration with Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4"
|
||||
files = [
|
||||
|
@ -746,6 +788,7 @@ asymmetric-crypto = ["cryptography (>=3.3.1)"]
|
|||
name = "flask-mail"
|
||||
version = "0.9.1"
|
||||
description = "Flask extension for sending email"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -760,6 +803,7 @@ Flask = "*"
|
|||
name = "flask-marshmallow"
|
||||
version = "0.15.0"
|
||||
description = "Flask + marshmallow for beautiful APIs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -782,6 +826,7 @@ tests = ["flask-sqlalchemy (>=3.0.0)", "marshmallow-sqlalchemy (>=0.28.2)", "moc
|
|||
name = "flask-migrate"
|
||||
version = "4.0.4"
|
||||
description = "SQLAlchemy database migrations for Flask applications using Alembic."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -794,10 +839,29 @@ alembic = ">=1.9.0"
|
|||
Flask = ">=0.9"
|
||||
Flask-SQLAlchemy = ">=1.0"
|
||||
|
||||
[[package]]
|
||||
name = "flask-oauthlib"
|
||||
version = "0.9.6"
|
||||
description = "OAuthlib for Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "Flask-OAuthlib-0.9.6.tar.gz", hash = "sha256:5bb79c8a8e670c2eb4cb553dfc3283b6c8d1202f674934676dc173cee94fe39c"},
|
||||
{file = "Flask_OAuthlib-0.9.6-py3-none-any.whl", hash = "sha256:a5c3b62959aa1922470a62b6ebf4273b75f1c29561a7eb4a69cde85d45a1d669"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cachelib = "*"
|
||||
Flask = "*"
|
||||
oauthlib = ">=1.1.2,<2.0.3 || >2.0.3,<2.0.4 || >2.0.4,<2.0.5 || >2.0.5,<3.0.0"
|
||||
requests-oauthlib = ">=0.6.2,<1.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "flask-restful"
|
||||
version = "0.3.9"
|
||||
description = "Simple framework for creating REST APIs"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -814,10 +878,27 @@ six = ">=1.3.0"
|
|||
[package.extras]
|
||||
docs = ["sphinx"]
|
||||
|
||||
[[package]]
|
||||
name = "flask-session"
|
||||
version = "0.5.0"
|
||||
description = "Server-side session support for Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "Flask-Session-0.5.0.tar.gz", hash = "sha256:190875e6aebf2953c6803d42379ef3b934bc209ef8ef006f97aecb08f5aaeb86"},
|
||||
{file = "flask_session-0.5.0-py3-none-any.whl", hash = "sha256:1619bcbc16f04f64e90f8e0b17145ba5c9700090bb1294e889956c1282d58631"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cachelib = "*"
|
||||
flask = ">=2.2"
|
||||
|
||||
[[package]]
|
||||
name = "flask-simple-crypt"
|
||||
version = "0.3.3"
|
||||
description = "Flask extension based on simple-crypt that allows simple, secure encryption and decryption for Python."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -833,6 +914,7 @@ pycryptodome = "*"
|
|||
name = "flask-sqlalchemy"
|
||||
version = "3.0.3"
|
||||
description = "Add SQLAlchemy support to your Flask application."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -848,6 +930,7 @@ SQLAlchemy = ">=1.4.18"
|
|||
name = "gitdb"
|
||||
version = "4.0.10"
|
||||
description = "Git Object Database"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -862,6 +945,7 @@ smmap = ">=3.0.1,<6"
|
|||
name = "gitpython"
|
||||
version = "3.1.31"
|
||||
description = "GitPython is a Python library used to interact with Git repositories"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -876,6 +960,7 @@ gitdb = ">=4.0.1,<5"
|
|||
name = "greenlet"
|
||||
version = "2.0.2"
|
||||
description = "Lightweight in-process concurrent programming"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*"
|
||||
files = [
|
||||
|
@ -949,6 +1034,7 @@ test = ["objgraph", "psutil"]
|
|||
name = "gunicorn"
|
||||
version = "20.1.0"
|
||||
description = "WSGI HTTP Server for UNIX"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -969,6 +1055,7 @@ tornado = ["tornado (>=0.2)"]
|
|||
name = "identify"
|
||||
version = "2.5.22"
|
||||
description = "File identification library for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -983,6 +1070,7 @@ license = ["ukkonen"]
|
|||
name = "idna"
|
||||
version = "3.4"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -994,6 +1082,7 @@ files = [
|
|||
name = "inflection"
|
||||
version = "0.5.1"
|
||||
description = "A port of Ruby on Rails inflector to Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -1005,6 +1094,7 @@ files = [
|
|||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1016,6 +1106,7 @@ files = [
|
|||
name = "itsdangerous"
|
||||
version = "2.1.2"
|
||||
description = "Safely pass data to untrusted environments and back."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1027,6 +1118,7 @@ files = [
|
|||
name = "jinja2"
|
||||
version = "3.1.2"
|
||||
description = "A very fast and expressive template engine."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1044,6 +1136,7 @@ i18n = ["Babel (>=2.7)"]
|
|||
name = "jsonschema"
|
||||
version = "4.17.3"
|
||||
description = "An implementation of JSON Schema validation for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1063,6 +1156,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-
|
|||
name = "lxml"
|
||||
version = "4.9.2"
|
||||
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
|
||||
files = [
|
||||
|
@ -1155,6 +1249,7 @@ source = ["Cython (>=0.29.7)"]
|
|||
name = "mako"
|
||||
version = "1.2.4"
|
||||
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1174,6 +1269,7 @@ testing = ["pytest"]
|
|||
name = "markupsafe"
|
||||
version = "2.1.2"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1233,6 +1329,7 @@ files = [
|
|||
name = "marshmallow"
|
||||
version = "3.19.0"
|
||||
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1253,6 +1350,7 @@ tests = ["pytest", "pytz", "simplejson"]
|
|||
name = "marshmallow-enum"
|
||||
version = "1.5.1"
|
||||
description = "Enum field for Marshmallow"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -1267,6 +1365,7 @@ marshmallow = ">=2.0.0"
|
|||
name = "marshmallow-sqlalchemy"
|
||||
version = "0.29.0"
|
||||
description = "SQLAlchemy integration with the marshmallow (de)serialization library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1289,6 +1388,7 @@ tests = ["pytest", "pytest-lazy-fixture (>=0.6.2)"]
|
|||
name = "mypy"
|
||||
version = "1.2.0"
|
||||
description = "Optional static typing for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1335,6 +1435,7 @@ reports = ["lxml"]
|
|||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -1346,6 +1447,7 @@ files = [
|
|||
name = "mysqlclient"
|
||||
version = "2.2.0"
|
||||
description = "Python interface to MySQL"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -1362,6 +1464,7 @@ files = [
|
|||
name = "nodeenv"
|
||||
version = "1.7.0"
|
||||
description = "Node.js virtual environment builder"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
|
||||
files = [
|
||||
|
@ -1372,10 +1475,29 @@ files = [
|
|||
[package.dependencies]
|
||||
setuptools = "*"
|
||||
|
||||
[[package]]
|
||||
name = "oauthlib"
|
||||
version = "2.1.0"
|
||||
description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "oauthlib-2.1.0-py2.py3-none-any.whl", hash = "sha256:d883b36b21a6ad813953803edfa563b1b579d79ca758fe950d1bc9e8b326025b"},
|
||||
{file = "oauthlib-2.1.0.tar.gz", hash = "sha256:ac35665a61c1685c56336bda97d5eefa246f1202618a1d6f34fccb1bdd404162"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
rsa = ["cryptography"]
|
||||
signals = ["blinker"]
|
||||
signedtoken = ["cryptography", "pyjwt (>=1.0.0)"]
|
||||
test = ["blinker", "cryptography", "mock", "nose", "pyjwt (>=1.0.0)", "unittest2"]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -1390,6 +1512,7 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
|||
name = "pathspec"
|
||||
version = "0.11.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1401,6 +1524,7 @@ files = [
|
|||
name = "pbr"
|
||||
version = "5.11.1"
|
||||
description = "Python Build Reasonableness"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6"
|
||||
files = [
|
||||
|
@ -1412,6 +1536,7 @@ files = [
|
|||
name = "platformdirs"
|
||||
version = "3.2.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1427,6 +1552,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-
|
|||
name = "pluggy"
|
||||
version = "1.0.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -1442,6 +1568,7 @@ testing = ["pytest", "pytest-benchmark"]
|
|||
name = "pre-commit"
|
||||
version = "2.21.0"
|
||||
description = "A framework for managing and maintaining multi-language pre-commit hooks."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1460,6 +1587,7 @@ virtualenv = ">=20.10.0"
|
|||
name = "pre-commit-hooks"
|
||||
version = "4.4.0"
|
||||
description = "Some out-of-the-box hooks for pre-commit."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1475,6 +1603,7 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
|||
name = "prometheus-client"
|
||||
version = "0.16.0"
|
||||
description = "Python client for the Prometheus monitoring system."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -1489,6 +1618,7 @@ twisted = ["twisted"]
|
|||
name = "prometheus-flask-exporter"
|
||||
version = "0.22.3"
|
||||
description = "Prometheus metrics exporter for Flask"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -1504,6 +1634,7 @@ prometheus-client = "*"
|
|||
name = "psycopg2"
|
||||
version = "2.9.6"
|
||||
description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -1526,6 +1657,7 @@ files = [
|
|||
name = "pycparser"
|
||||
version = "2.21"
|
||||
description = "C parser in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
|
@ -1537,6 +1669,7 @@ files = [
|
|||
name = "pycryptodome"
|
||||
version = "3.17"
|
||||
description = "Cryptographic library for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
files = [
|
||||
|
@ -1579,6 +1712,7 @@ files = [
|
|||
name = "pygments"
|
||||
version = "2.15.1"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1593,6 +1727,7 @@ plugins = ["importlib-metadata"]
|
|||
name = "pyjwt"
|
||||
version = "2.6.0"
|
||||
description = "JSON Web Token implementation in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1610,6 +1745,7 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
|
|||
name = "pyparsing"
|
||||
version = "3.0.9"
|
||||
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.8"
|
||||
files = [
|
||||
|
@ -1624,6 +1760,7 @@ diagrams = ["jinja2", "railroad-diagrams"]
|
|||
name = "pyrsistent"
|
||||
version = "0.19.3"
|
||||
description = "Persistent/Functional/Immutable data structures"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1660,6 +1797,7 @@ files = [
|
|||
name = "pytest"
|
||||
version = "7.4.0"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1682,6 +1820,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
|
|||
name = "pytest-flask"
|
||||
version = "1.2.0"
|
||||
description = "A set of py.test fixtures to test Flask applications."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -1701,6 +1840,7 @@ docs = ["Sphinx", "sphinx-rtd-theme"]
|
|||
name = "pytest-flask-sqlalchemy"
|
||||
version = "1.1.0"
|
||||
description = "A pytest plugin for preserving test isolation in Flask-SQlAlchemy using database transactions."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -1722,6 +1862,7 @@ tests = ["psycopg2-binary", "pytest (>=6.0.1)", "pytest-postgresql (>=2.4.0,<4.0
|
|||
name = "pytest-mock"
|
||||
version = "3.10.0"
|
||||
description = "Thin-wrapper around the mock package for easier use with pytest"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1739,6 +1880,7 @@ dev = ["pre-commit", "pytest-asyncio", "tox"]
|
|||
name = "pytest-random-order"
|
||||
version = "1.1.0"
|
||||
description = "Randomise the order in which pytest tests are run with some control over the randomness"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5.0"
|
||||
files = [
|
||||
|
@ -1753,6 +1895,7 @@ pytest = ">=3.0.0"
|
|||
name = "pytest-xdist"
|
||||
version = "3.3.1"
|
||||
description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1773,6 +1916,7 @@ testing = ["filelock"]
|
|||
name = "python-dateutil"
|
||||
version = "2.8.2"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
|
@ -1787,6 +1931,7 @@ six = ">=1.5"
|
|||
name = "pytz"
|
||||
version = "2022.7.1"
|
||||
description = "World timezone definitions, modern and historical"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -1798,6 +1943,7 @@ files = [
|
|||
name = "pytz-deprecation-shim"
|
||||
version = "0.1.0.post0"
|
||||
description = "Shims to make deprecation of pytz easier"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
||||
files = [
|
||||
|
@ -1812,6 +1958,7 @@ tzdata = {version = "*", markers = "python_version >= \"3.6\""}
|
|||
name = "pyyaml"
|
||||
version = "6.0"
|
||||
description = "YAML parser and emitter for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -1861,6 +2008,7 @@ files = [
|
|||
name = "regex"
|
||||
version = "2023.3.23"
|
||||
description = "Alternative regular expression module, to replace re."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -1930,6 +2078,7 @@ files = [
|
|||
name = "requests"
|
||||
version = "2.31.0"
|
||||
description = "Python HTTP for Humans."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -1947,10 +2096,30 @@ urllib3 = ">=1.21.1,<3"
|
|||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "requests-oauthlib"
|
||||
version = "1.1.0"
|
||||
description = "OAuthlib authentication support for Requests."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
{file = "requests-oauthlib-1.1.0.tar.gz", hash = "sha256:eabd8eb700ebed81ba080c6ead96d39d6bdc39996094bd23000204f6965786b0"},
|
||||
{file = "requests_oauthlib-1.1.0-py2.py3-none-any.whl", hash = "sha256:be76f2bb72ca5525998e81d47913e09b1ca8b7957ae89b46f787a79e68ad5e61"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
oauthlib = ">=2.1.0,<3.0.0"
|
||||
requests = ">=2.0.0"
|
||||
|
||||
[package.extras]
|
||||
rsa = ["oauthlib[signedtoken] (>=2.1.0,<3.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "restrictedpython"
|
||||
version = "6.1"
|
||||
description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6, <3.12"
|
||||
files = [
|
||||
|
@ -1966,6 +2135,7 @@ test = ["pytest", "pytest-mock"]
|
|||
name = "ruamel-yaml"
|
||||
version = "0.17.21"
|
||||
description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3"
|
||||
files = [
|
||||
|
@ -1984,6 +2154,7 @@ jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"]
|
|||
name = "ruamel-yaml-clib"
|
||||
version = "0.2.7"
|
||||
description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
|
@ -1994,8 +2165,7 @@ files = [
|
|||
{file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"},
|
||||
{file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"},
|
||||
|
@ -2030,6 +2200,7 @@ files = [
|
|||
name = "ruff"
|
||||
version = "0.0.270"
|
||||
description = "An extremely fast Python linter, written in Rust."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2056,6 +2227,7 @@ files = [
|
|||
name = "safety"
|
||||
version = "2.3.5"
|
||||
description = "Checks installed dependencies for known vulnerabilities and licenses."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2079,6 +2251,7 @@ gitlab = ["python-gitlab (>=1.3.0)"]
|
|||
name = "sentry-sdk"
|
||||
version = "1.19.1"
|
||||
description = "Python client for Sentry (https://sentry.io)"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2120,6 +2293,7 @@ tornado = ["tornado (>=5)"]
|
|||
name = "setuptools"
|
||||
version = "65.7.0"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2136,6 +2310,7 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (
|
|||
name = "simplejson"
|
||||
version = "3.19.1"
|
||||
description = "Simple, fast, extensible JSON encoder/decoder for Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
|
@ -2230,6 +2405,7 @@ files = [
|
|||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
|
@ -2241,6 +2417,7 @@ files = [
|
|||
name = "smmap"
|
||||
version = "5.0.0"
|
||||
description = "A pure Python implementation of a sliding window memory map manager"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -2252,6 +2429,7 @@ files = [
|
|||
name = "spiff-element-units"
|
||||
version = "0.3.0"
|
||||
description = ""
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
|
@ -2272,6 +2450,7 @@ files = [
|
|||
name = "SpiffWorkflow"
|
||||
version = "2.0.0rc0"
|
||||
description = "A workflow framework and BPMN/DMN Processor"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = []
|
||||
|
@ -2291,6 +2470,7 @@ resolved_reference = "0adfc8cbaec80d36f98a4136434e960f666fcfe2"
|
|||
name = "sqlalchemy"
|
||||
version = "2.0.9"
|
||||
description = "Database Abstraction Library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2338,7 +2518,7 @@ files = [
|
|||
]
|
||||
|
||||
[package.dependencies]
|
||||
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""}
|
||||
greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
|
||||
typing-extensions = ">=4.2.0"
|
||||
|
||||
[package.extras]
|
||||
|
@ -2368,6 +2548,7 @@ sqlcipher = ["sqlcipher3-binary"]
|
|||
name = "sqlalchemy-stubs"
|
||||
version = "0.4"
|
||||
description = "SQLAlchemy stubs and mypy plugin"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = []
|
||||
|
@ -2387,6 +2568,7 @@ resolved_reference = "d1176931684ce5b327539cc9567d4a1cd8ef1efd"
|
|||
name = "stevedore"
|
||||
version = "5.0.0"
|
||||
description = "Manage dynamic plugins for Python applications"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -2401,6 +2583,7 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
|||
name = "swagger-ui-bundle"
|
||||
version = "0.0.9"
|
||||
description = "swagger_ui_bundle - swagger-ui files in a pip package"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2415,6 +2598,7 @@ Jinja2 = ">=2.0"
|
|||
name = "toml"
|
||||
version = "0.10.2"
|
||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
|
@ -2426,6 +2610,7 @@ files = [
|
|||
name = "tomli"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2437,6 +2622,7 @@ files = [
|
|||
name = "typeguard"
|
||||
version = "3.0.2"
|
||||
description = "Run-time type checker for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7.4"
|
||||
files = [
|
||||
|
@ -2455,6 +2641,7 @@ test = ["mypy (>=0.991)", "pytest (>=7)"]
|
|||
name = "types-click"
|
||||
version = "7.1.8"
|
||||
description = "Typing stubs for click"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2466,6 +2653,7 @@ files = [
|
|||
name = "types-dateparser"
|
||||
version = "1.1.4.9"
|
||||
description = "Typing stubs for dateparser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2477,6 +2665,7 @@ files = [
|
|||
name = "types-flask"
|
||||
version = "1.1.6"
|
||||
description = "Typing stubs for Flask"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2493,6 +2682,7 @@ types-Werkzeug = "*"
|
|||
name = "types-jinja2"
|
||||
version = "2.11.9"
|
||||
description = "Typing stubs for Jinja2"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2507,6 +2697,7 @@ types-MarkupSafe = "*"
|
|||
name = "types-markupsafe"
|
||||
version = "1.1.10"
|
||||
description = "Typing stubs for MarkupSafe"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2518,6 +2709,7 @@ files = [
|
|||
name = "types-pytz"
|
||||
version = "2022.7.1.2"
|
||||
description = "Typing stubs for pytz"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2529,6 +2721,7 @@ files = [
|
|||
name = "types-pyyaml"
|
||||
version = "6.0.12.9"
|
||||
description = "Typing stubs for PyYAML"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2540,6 +2733,7 @@ files = [
|
|||
name = "types-requests"
|
||||
version = "2.28.11.17"
|
||||
description = "Typing stubs for requests"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2554,6 +2748,7 @@ types-urllib3 = "<1.27"
|
|||
name = "types-urllib3"
|
||||
version = "1.26.25.10"
|
||||
description = "Typing stubs for urllib3"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2565,6 +2760,7 @@ files = [
|
|||
name = "types-werkzeug"
|
||||
version = "1.0.9"
|
||||
description = "Typing stubs for Werkzeug"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
|
@ -2576,6 +2772,7 @@ files = [
|
|||
name = "typing-extensions"
|
||||
version = "4.5.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2587,6 +2784,7 @@ files = [
|
|||
name = "tzdata"
|
||||
version = "2023.3"
|
||||
description = "Provider of IANA time zone data"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
files = [
|
||||
|
@ -2598,6 +2796,7 @@ files = [
|
|||
name = "tzlocal"
|
||||
version = "4.3"
|
||||
description = "tzinfo object for the local timezone"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2616,6 +2815,7 @@ devenv = ["black", "check-manifest", "flake8", "pyroma", "pytest (>=4.3)", "pyte
|
|||
name = "urllib3"
|
||||
version = "1.26.15"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
|
||||
files = [
|
||||
|
@ -2632,6 +2832,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
|||
name = "virtualenv"
|
||||
version = "20.21.0"
|
||||
description = "Virtual Python Environment builder"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2652,6 +2853,7 @@ test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess
|
|||
name = "werkzeug"
|
||||
version = "2.3.4"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
|
@ -2669,6 +2871,7 @@ watchdog = ["watchdog (>=2.3)"]
|
|||
name = "wtforms"
|
||||
version = "3.0.1"
|
||||
description = "Form validation and rendering for Python web development."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
|
@ -2686,6 +2889,7 @@ email = ["email-validator"]
|
|||
name = "xdoctest"
|
||||
version = "1.1.1"
|
||||
description = "A rewrite of the builtin doctest module"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
|
@ -2714,4 +2918,4 @@ tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "p
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.10,<3.12"
|
||||
content-hash = "43d6e84c8ef9e0ea48876bb490f8486b6e25bff2ada6981c739e03b35ea3da6c"
|
||||
content-hash = "6cbc9666f9045835a75dc38cdd9e02c0ea53c061b57162e7744572661527aa61"
|
||||
|
|
|
@ -73,6 +73,8 @@ spiff-element-units = "^0.3.0"
|
|||
# mysqlclient lib is deemed better than the mysql-connector-python lib by sqlalchemy
|
||||
# https://docs.sqlalchemy.org/en/20/dialects/mysql.html#module-sqlalchemy.dialects.mysql.mysqlconnector
|
||||
mysqlclient = "^2.2.0"
|
||||
flask-session = "^0.5.0"
|
||||
flask-oauthlib = "^0.9.6"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^7.1.2"
|
||||
|
|
|
@ -1876,6 +1876,64 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ServiceTask"
|
||||
|
||||
/authentication/configuration:
|
||||
get:
|
||||
tags:
|
||||
- Authentications
|
||||
operationId: spiffworkflow_backend.routes.service_tasks_controller.authentication_configuration
|
||||
summary: Gets authentication configurations
|
||||
responses:
|
||||
"200":
|
||||
description: Authentication configuration
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ServiceTask"
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.service_tasks_controller.authentication_configuration_update
|
||||
summary: Save the authentication configuration
|
||||
tags:
|
||||
- Authentication
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ServiceTask"
|
||||
responses:
|
||||
"200":
|
||||
description: Authentication configuration updated successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/OkTrue"
|
||||
|
||||
/authentication_begin/{service}/{auth_method}:
|
||||
parameters:
|
||||
- name: service
|
||||
in: path
|
||||
required: true
|
||||
description: The name of the service
|
||||
schema:
|
||||
type: string
|
||||
- name: auth_method
|
||||
in: path
|
||||
required: true
|
||||
description: The method
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
tags:
|
||||
- Authentications
|
||||
operationId: spiffworkflow_backend.routes.service_tasks_controller.authentication_begin
|
||||
summary: Begin an external authentication
|
||||
responses:
|
||||
"200":
|
||||
description: All authentications
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ServiceTask"
|
||||
|
||||
/authentication_callback/{service}/{auth_method}:
|
||||
parameters:
|
||||
- name: service
|
||||
|
@ -1892,13 +1950,37 @@ paths:
|
|||
type: string
|
||||
- name: response
|
||||
in: query
|
||||
required: true
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
- name: token
|
||||
in: query
|
||||
required: true
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
- name: code
|
||||
in: query
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
- name: code_challenge
|
||||
in: query
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
- name: code_challenge_method
|
||||
in: query
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
- name: state
|
||||
in: query
|
||||
required: false
|
||||
description: The response
|
||||
schema:
|
||||
type: string
|
||||
|
|
|
@ -85,5 +85,8 @@ from spiffworkflow_backend.models.typeahead import (
|
|||
from spiffworkflow_backend.models.task_draft_data import (
|
||||
TaskDraftDataModel,
|
||||
) # noqa: F401
|
||||
from spiffworkflow_backend.models.configuration import (
|
||||
ConfigurationModel,
|
||||
) # noqa: F401
|
||||
|
||||
add_listeners()
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConfigurationModel(SpiffworkflowBaseDBModel):
|
||||
__tablename__ = "configuration"
|
||||
|
||||
id: int = db.Column(db.Integer, primary_key=True)
|
||||
category: str = db.Column(db.String(255), index=True)
|
||||
value: dict = db.Column(db.JSON)
|
||||
updated_at_in_seconds: int = db.Column(db.Integer)
|
||||
created_at_in_seconds: int = db.Column(db.Integer)
|
|
@ -9,7 +9,9 @@ from flask import redirect
|
|||
from flask import request
|
||||
from flask.wrappers import Response
|
||||
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.routes.user import verify_token
|
||||
from spiffworkflow_backend.services.oauth_service import OAuthService
|
||||
from spiffworkflow_backend.services.secret_service import SecretService
|
||||
from spiffworkflow_backend.services.service_task_service import ServiceTaskService
|
||||
|
||||
|
@ -21,8 +23,11 @@ def service_task_list() -> flask.wrappers.Response:
|
|||
|
||||
def authentication_list() -> flask.wrappers.Response:
|
||||
available_authentications = ServiceTaskService.authentication_list()
|
||||
available_v2_authentications = OAuthService.authentication_list()
|
||||
|
||||
response_json = {
|
||||
"results": available_authentications,
|
||||
"resultsV2": available_v2_authentications,
|
||||
"connector_proxy_base_url": current_app.config["SPIFFWORKFLOW_BACKEND_CONNECTOR_PROXY_URL"],
|
||||
"redirect_url": f"{current_app.config['SPIFFWORKFLOW_BACKEND_URL']}/v1.0/authentication_callback",
|
||||
}
|
||||
|
@ -30,11 +35,44 @@ def authentication_list() -> flask.wrappers.Response:
|
|||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def authentication_configuration() -> flask.wrappers.Response:
|
||||
config = OAuthService.authentication_configuration()
|
||||
|
||||
return Response(json.dumps(config), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def authentication_configuration_update(body: dict) -> flask.wrappers.Response:
|
||||
OAuthService.update_authentication_configuration(body)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def authentication_begin(
|
||||
service: str,
|
||||
auth_method: str,
|
||||
) -> werkzeug.wrappers.Response:
|
||||
token = request.args.get("token")
|
||||
verify_token(token, force_run=True)
|
||||
if not OAuthService.supported_service(service):
|
||||
raise ApiError("unknown_authentication_service", f"Unknown authentication service: {service}", status_code=400)
|
||||
remote_app = OAuthService.remote_app(service, token)
|
||||
callback = f"{current_app.config['SPIFFWORKFLOW_BACKEND_URL']}/v1.0/authentication_callback/{service}/oauth"
|
||||
return remote_app.authorize(callback=callback, _external=True) # type: ignore
|
||||
|
||||
|
||||
def authentication_callback(
|
||||
service: str,
|
||||
auth_method: str,
|
||||
) -> werkzeug.wrappers.Response:
|
||||
verify_token(request.args.get("token"), force_run=True)
|
||||
response = request.args["response"]
|
||||
SecretService.update_secret(f"{service}/{auth_method}", response, g.user.id, create_if_not_exists=True)
|
||||
if OAuthService.supported_service(service):
|
||||
token = OAuthService.token_from_state(request.args.get("state"))
|
||||
verify_token(token, force_run=True)
|
||||
remote_app = OAuthService.remote_app(service, token)
|
||||
response = remote_app.authorized_response()
|
||||
SecretService.update_secret(
|
||||
f"{service}_{auth_method}", response["access_token"], g.user.id, create_if_not_exists=True
|
||||
)
|
||||
else:
|
||||
verify_token(request.args.get("token"), force_run=True)
|
||||
response = request.args["response"]
|
||||
SecretService.update_secret(f"{service}/{auth_method}", response, g.user.id, create_if_not_exists=True)
|
||||
return redirect(f"{current_app.config['SPIFFWORKFLOW_BACKEND_URL_FOR_FRONTEND']}/admin/configuration")
|
||||
|
|
|
@ -242,6 +242,7 @@ class AuthorizationService:
|
|||
authentication_exclusion_list = [
|
||||
"status",
|
||||
"test_raise_error",
|
||||
"authentication_begin",
|
||||
"authentication_callback",
|
||||
"github_webhook_receive",
|
||||
]
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import json
|
||||
from typing import Any
|
||||
|
||||
from spiffworkflow_backend.models.configuration import ConfigurationModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
|
||||
class ConfigurationService:
|
||||
@staticmethod
|
||||
def configuration_for_category(category: str) -> Any:
|
||||
config = db.session.query(ConfigurationModel).filter(ConfigurationModel.category == category).first()
|
||||
try:
|
||||
value = config.value if config is not None else ""
|
||||
return json.loads(value) # type: ignore
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def update_configuration_for_category(category: str, new_config: dict[str, Any]) -> None:
|
||||
config = db.session.query(ConfigurationModel).filter(ConfigurationModel.category == category).first()
|
||||
if config is None:
|
||||
config = ConfigurationModel(category=category)
|
||||
if "value" in new_config:
|
||||
config.value = new_config["value"]
|
||||
else:
|
||||
config.value = {}
|
||||
|
||||
db.session.add(config)
|
||||
db.session.commit()
|
|
@ -0,0 +1,66 @@
|
|||
import base64
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from flask import Flask
|
||||
from flask import session
|
||||
from flask_oauthlib.client import OAuth # type: ignore
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.services.configuration_service import ConfigurationService
|
||||
from spiffworkflow_backend.services.secret_service import SecretService
|
||||
|
||||
|
||||
class OAuthService:
|
||||
@classmethod
|
||||
def authentication_list(
|
||||
cls,
|
||||
) -> list[dict[str, Any]]:
|
||||
return [{"id": f"{k}/OAuth", "parameters": []} for k in cls.authentication_configuration().keys()]
|
||||
|
||||
@staticmethod
|
||||
def authentication_configuration() -> Any:
|
||||
return ConfigurationService.configuration_for_category("oauth")
|
||||
|
||||
@staticmethod
|
||||
def update_authentication_configuration(config: dict[str, Any]) -> None:
|
||||
try:
|
||||
_ = json.loads(config["value"])
|
||||
except Exception as e:
|
||||
raise ApiError(
|
||||
error_code="invalid_authentication_configuration",
|
||||
message=f"The authentication configuration is not valid JSON. {e}",
|
||||
) from e
|
||||
|
||||
return ConfigurationService.update_configuration_for_category("oauth", config)
|
||||
|
||||
@classmethod
|
||||
def supported_service(cls, service: str) -> bool:
|
||||
return service in cls.authentication_configuration()
|
||||
|
||||
@classmethod
|
||||
def remote_app(cls, service: str, token: str | None) -> Any:
|
||||
config = cls.authentication_configuration()[service]
|
||||
|
||||
for k in ["consumer_key", "consumer_secret"]:
|
||||
if k in config:
|
||||
config[k] = SecretService.resolve_possibly_secret_value(config[k])
|
||||
|
||||
if token is not None:
|
||||
state = base64.urlsafe_b64encode(bytes(token, "utf-8"))
|
||||
config["request_token_params"]["state"] = state
|
||||
|
||||
app = Flask(__name__)
|
||||
oauth = OAuth(app)
|
||||
remote_app = oauth.remote_app(service, **config)
|
||||
|
||||
@remote_app.tokengetter
|
||||
def get_token(token=None): # type: ignore
|
||||
return session[f"{service}_token"]
|
||||
|
||||
return remote_app
|
||||
|
||||
@staticmethod
|
||||
def token_from_state(state: str | None) -> str | None:
|
||||
if state is not None:
|
||||
return base64.urlsafe_b64decode(state).decode("utf-8")
|
||||
return None
|
|
@ -1,3 +1,6 @@
|
|||
import re
|
||||
|
||||
import sentry_sdk
|
||||
from flask import current_app
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
@ -110,3 +113,15 @@ class SecretService:
|
|||
message=f"Cannot delete secret with key: {key}. Resource does not exist.",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def resolve_possibly_secret_value(cls, value: str) -> str:
|
||||
if "SPIFF_SECRET:" in value:
|
||||
spiff_secret_match = re.match(r".*SPIFF_SECRET:(?P<variable_name>\w+).*", value)
|
||||
if spiff_secret_match is not None:
|
||||
spiff_variable_name = spiff_secret_match.group("variable_name")
|
||||
secret = cls.get_secret(spiff_variable_name)
|
||||
with sentry_sdk.start_span(op="task", description="decrypt_secret"):
|
||||
decrypted_value = cls._decrypt(secret.value)
|
||||
return re.sub(r"\bSPIFF_SECRET:\w+", decrypted_value, value)
|
||||
return value
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import json
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
|
@ -40,14 +39,7 @@ class ServiceTaskDelegate:
|
|||
with open(full_path) as f:
|
||||
return f.read()
|
||||
|
||||
if "SPIFF_SECRET:" in value:
|
||||
spiff_secret_match = re.match(r".*SPIFF_SECRET:(?P<variable_name>\w+).*", value)
|
||||
if spiff_secret_match is not None:
|
||||
spiff_variable_name = spiff_secret_match.group("variable_name")
|
||||
secret = SecretService.get_secret(spiff_variable_name)
|
||||
with sentry_sdk.start_span(op="task", description="decrypt_secret"):
|
||||
decrypted_value = SecretService._decrypt(secret.value)
|
||||
return re.sub(r"\bSPIFF_SECRET:\w+", decrypted_value, value)
|
||||
return SecretService.resolve_possibly_secret_value(value)
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import Editor from '@monaco-editor/react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Button } from '@carbon/react';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
||||
export default function AuthenticationConfiguration() {
|
||||
const [authConfig, setAuthConfig] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
HttpService.makeCallToBackend({
|
||||
path: '/authentication/configuration',
|
||||
successCallback: (newAuthConfig: string) => {
|
||||
setAuthConfig(JSON.stringify(newAuthConfig, null, 4));
|
||||
},
|
||||
});
|
||||
}, []);
|
||||
|
||||
const saveAuthConfig = () => {
|
||||
HttpService.makeCallToBackend({
|
||||
path: '/authentication/configuration',
|
||||
successCallback: () => { window.location.reload() },
|
||||
httpMethod: 'PUT',
|
||||
postBody: { value: authConfig },
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => saveAuthConfig()}>Save</Button>
|
||||
<br />
|
||||
<br />
|
||||
<h2>Local Configuration</h2>
|
||||
<br />
|
||||
<Editor
|
||||
height={600}
|
||||
width="auto"
|
||||
defaultLanguage="json"
|
||||
defaultValue={authConfig || ''}
|
||||
onChange={(value) => setAuthConfig(value || '')}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -4,11 +4,16 @@ import { Table } from '@carbon/react';
|
|||
import { AuthenticationItem } from '../interfaces';
|
||||
import HttpService from '../services/HttpService';
|
||||
import UserService from '../services/UserService';
|
||||
import { BACKEND_BASE_URL } from '../config';
|
||||
import AuthenticationConfiguration from '../components/AuthenticationConfiguration';
|
||||
|
||||
export default function AuthenticationList() {
|
||||
const [authenticationList, setAuthenticationList] = useState<
|
||||
AuthenticationItem[] | null
|
||||
>(null);
|
||||
const [authenticationV2List, setAuthenticationV2List] = useState<
|
||||
AuthenticationItem[] | null
|
||||
>(null);
|
||||
const [connectProxyBaseUrl, setConnectProxyBaseUrl] = useState<string | null>(
|
||||
null
|
||||
);
|
||||
|
@ -17,6 +22,7 @@ export default function AuthenticationList() {
|
|||
useEffect(() => {
|
||||
const processResult = (result: any) => {
|
||||
setAuthenticationList(result.results);
|
||||
setAuthenticationV2List(result.resultsV2);
|
||||
setConnectProxyBaseUrl(result.connector_proxy_base_url);
|
||||
setRedirectUrl(result.redirect_url);
|
||||
};
|
||||
|
@ -27,7 +33,7 @@ export default function AuthenticationList() {
|
|||
}, []);
|
||||
|
||||
const buildTable = () => {
|
||||
if (authenticationList) {
|
||||
if (authenticationList && authenticationV2List) {
|
||||
const rows = authenticationList.map((row) => {
|
||||
return (
|
||||
<tr key={row.id}>
|
||||
|
@ -43,6 +49,24 @@ export default function AuthenticationList() {
|
|||
{row.id}
|
||||
</a>
|
||||
</td>
|
||||
<td>Connector Proxy</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
const rowsV2 = authenticationV2List.map((row) => {
|
||||
return (
|
||||
<tr key={row.id}>
|
||||
<td>
|
||||
<a
|
||||
data-qa="authentication-create-link"
|
||||
href={`${BACKEND_BASE_URL}/authentication_begin/${
|
||||
row.id
|
||||
}?token=${UserService.getAccessToken()}`}
|
||||
>
|
||||
{row.id}
|
||||
</a>
|
||||
</td>
|
||||
<td>Local Configuration</td>
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
|
@ -51,9 +75,13 @@ export default function AuthenticationList() {
|
|||
<thead>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>{rows}</tbody>
|
||||
<tbody>
|
||||
{rows}
|
||||
{rowsV2}
|
||||
</tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
@ -61,7 +89,12 @@ export default function AuthenticationList() {
|
|||
};
|
||||
|
||||
if (authenticationList) {
|
||||
return <>{buildTable()}</>;
|
||||
return (
|
||||
<>
|
||||
{buildTable()}
|
||||
{AuthenticationConfiguration()}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return <main />;
|
||||
|
|
Loading…
Reference in New Issue