Skip to content

Commit 360ccfa

Browse files
Bring IDToken fields into agreement with OIDC Spec (HarryMWinters#10) 😊
- Updates IDToken type. - Adds OktaIDToken child type. - Fixes CI.
1 parent bce67e6 commit 360ccfa

File tree

11 files changed

+980
-527
lines changed

11 files changed

+980
-527
lines changed

.bandit.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
### This config may optionally select a subset of tests to run or skip by
2+
### filling out the 'tests' and 'skips' lists given below. If no tests are
3+
### specified for inclusion then it is assumed all tests are desired. The skips
4+
### set will remove specific tests from the include set. This can be controlled
5+
### using the -t/-s CLI options. Note that the same test ID should not appear
6+
### in both 'tests' and 'skips', this would be nonsensical and is detected by
7+
### Bandit at runtime.
8+
9+
# Available tests:
10+
# B101 : assert_used
11+
# B102 : exec_used
12+
# B103 : set_bad_file_permissions
13+
# B104 : hardcoded_bind_all_interfaces
14+
# B105 : hardcoded_password_string
15+
# B106 : hardcoded_password_funcarg
16+
# B107 : hardcoded_password_default
17+
# B108 : hardcoded_tmp_directory
18+
# B110 : try_except_pass
19+
# B112 : try_except_continue
20+
# B201 : flask_debug_true
21+
# B301 : pickle
22+
# B302 : marshal
23+
# B303 : md5
24+
# B304 : ciphers
25+
# B305 : cipher_modes
26+
# B306 : mktemp_q
27+
# B307 : eval
28+
# B308 : mark_safe
29+
# B309 : httpsconnection
30+
# B310 : urllib_urlopen
31+
# B311 : random
32+
# B312 : telnetlib
33+
# B313 : xml_bad_cElementTree
34+
# B314 : xml_bad_ElementTree
35+
# B315 : xml_bad_expatreader
36+
# B316 : xml_bad_expatbuilder
37+
# B317 : xml_bad_sax
38+
# B318 : xml_bad_minidom
39+
# B319 : xml_bad_pulldom
40+
# B320 : xml_bad_etree
41+
# B321 : ftplib
42+
# B322 : input
43+
# B323 : unverified_context
44+
# B324 : hashlib_new_insecure_functions
45+
# B325 : tempnam
46+
# B401 : import_telnetlib
47+
# B402 : import_ftplib
48+
# B403 : import_pickle
49+
# B404 : import_subprocess
50+
# B405 : import_xml_etree
51+
# B406 : import_xml_sax
52+
# B407 : import_xml_expat
53+
# B408 : import_xml_minidom
54+
# B409 : import_xml_pulldom
55+
# B410 : import_lxml
56+
# B411 : import_xmlrpclib
57+
# B412 : import_httpoxy
58+
# B413 : import_pycrypto
59+
# B501 : request_with_no_cert_validation
60+
# B502 : ssl_with_bad_version
61+
# B503 : ssl_with_bad_defaults
62+
# B504 : ssl_with_no_version
63+
# B505 : weak_cryptographic_key
64+
# B506 : yaml_load
65+
# B507 : ssh_no_host_key_verification
66+
# B601 : paramiko_calls
67+
# B602 : subprocess_popen_with_shell_equals_true
68+
# B603 : subprocess_without_shell_equals_true
69+
# B604 : any_other_function_with_shell_equals_true
70+
# B605 : start_process_with_a_shell
71+
# B606 : start_process_with_no_shell
72+
# B607 : start_process_with_partial_path
73+
# B608 : hardcoded_sql_expressions
74+
# B609 : linux_commands_wildcard_injection
75+
# B610 : django_extra_used
76+
# B611 : django_rawsql_used
77+
# B701 : jinja2_autoescape_false
78+
# B702 : use_of_mako_templates
79+
# B703 : django_mark_safe
80+
81+
# (optional) list included test IDs here, eg '[B101, B406]':
82+
tests:
83+
84+
# (optional) list skipped test IDs here, eg '[B101, B406]':
85+
skips: [B101]

.github/workflows/tests.yaml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ jobs:
2121
uses: actions/setup-python@v1
2222
with:
2323
python-version: ${{ matrix.python-version }}
24+
2425
- name: Install Task
25-
uses: Arduino/actions/setup-taskfile@master
26-
with:
27-
version: 3.x
28-
- name: Run pre-commit
29-
run: task pre-commit-ci
30-
- name: Run test
31-
run: task unit-test
26+
uses: arduino/setup-task@v1
27+
28+
- name: Run CI
29+
run: task ci

.isort.cfg

Lines changed: 0 additions & 4 deletions
This file was deleted.

.pre-commit-config.yaml

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,42 @@ default_language_version:
33

44
repos:
55
- repo: git://github.com/pre-commit/pre-commit-hooks
6-
rev: v2.3.0
6+
rev: v4.0.1
77
hooks:
88
- id: check-merge-conflict
9+
910
- repo: https://github.com/asottile/seed-isort-config
10-
rev: v1.9.4
11+
rev: v2.2.0
1112
hooks:
1213
- id: seed-isort-config
1314
language_version: python3.8
15+
1416
- repo: https://github.com/timothycrosley/isort
15-
rev: cd9c2f6
17+
rev: 5.9.2
1618
hooks:
1719
- id: isort
20+
1821
- repo: https://github.com/psf/black
19-
rev: stable
22+
rev: 21.7b0
2023
hooks:
2124
- id: black
25+
2226
- repo: https://github.com/pre-commit/mirrors-mypy
23-
rev: v0.770
27+
rev: v0.910
2428
hooks:
2529
- id: mypy
2630
additional_dependencies:
2731
- "pydantic"
32+
- "types-requests"
33+
- "types-cachetools"
34+
2835
- repo: https://gitlab.com/pycqa/flake8
29-
rev: 3.7.9
36+
rev: 3.9.2
3037
hooks:
3138
- id: flake8
39+
3240
- repo: https://github.com/PyCQA/bandit
33-
rev: "1.6.2"
41+
rev: "1.7.0"
3442
hooks:
3543
- id: bandit
44+
entry: bandit -c .bandit.yml

Taskfile.yml

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,42 @@ version: "3"
33
dotenv: [".env"]
44

55
tasks:
6+
7+
ci:
8+
desc: "Run code analyzers from pre-commit and unit tests"
9+
deps: [install-poetry, create-virtual-env]
10+
cmds:
11+
- task: unit
12+
- task: lint
13+
14+
lint:
15+
desc: "Install and init pre-commits."
16+
deps: [install-poetry, create-virtual-env]
17+
cmds:
18+
- poetry run pre-commit run --all-files
19+
20+
unit:
21+
desc: "Run unit tests"
22+
deps: [install-poetry, create-virtual-env]
23+
cmds:
24+
- poetry run pytest
25+
silent: true
26+
627
install-poetry:
728
desc: "Install poetry package manager."
829
cmds:
9-
- curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3 -
30+
- pip install poetry
1031
status:
1132
- poetry --version
1233
generates:
1334
- $HOME/.poetry/env
1435

15-
unit-test:
16-
desc: "Run unit tests"
17-
deps: [install-poetry, create-virtual-env]
18-
cmds:
19-
- source $HOME/.poetry/env && poetry run pytest
20-
# --cov=fastapi_oidc \
21-
# --cov-report=term-missing
22-
# --cov-report=xml tests ${@}
23-
silent: true
2436
create-virtual-env:
2537
desc: "Create poetry virtual env."
2638
deps: [install-poetry]
2739
cmds:
28-
- source $HOME/.poetry/env && poetry install
40+
- poetry install
41+
2942
build:
3043
desc: "Build python package for publication."
3144
deps: [install-poetry]
@@ -37,6 +50,7 @@ tasks:
3750
- pyproject.toml
3851
generates:
3952
- dist/**
53+
4054
publish:
4155
desc: "Push package to PIPy"
4256
deps: [build]
@@ -51,22 +65,11 @@ tasks:
5165
# - pyproject.toml
5266
# status:
5367
# - echo "Return nonzero code if we shouldn't publish"
68+
5469
clean:
5570
desc: "Remove artifacts and caches."
5671
cmds:
5772
- rm -rf ./build ./dist ./*.egg-info __pycache__
58-
pre-commit-ci:
59-
desc: "Install and init pre-commits."
60-
deps: [install-pre-commit-ci, init-pre-commit-ci]
61-
cmds:
62-
- python3 pre-commit-2.8.2.pyz run --all-files
63-
install-pre-commit-ci:
64-
desc: "Install pre-commit without dependencies."
65-
cmds:
66-
- curl -OL https://github.com/pre-commit/pre-commit/releases/download/v2.8.2/pre-commit-2.8.2.pyz
67-
- python3 pre-commit-2.8.2.pyz
68-
status:
69-
- which pre-commit
7073

7174
init-pre-commit-ci:
7275
desc: "Init pre-commit."
@@ -77,7 +80,7 @@ tasks:
7780
- .git/hooks/pre-commit
7881

7982
build_docs:
80-
desc: "Build sphinc docs in /docs"
83+
desc: "Build sphinx docs in /docs"
8184
deps: [create-virtual-env]
8285
cmds:
8386
- |

fastapi_oidc/auth.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def get_auth(
3939
) -> Callable[[str], IDToken]:
4040
"""Take configurations and return the authenticate_user function.
4141
42-
This function should only be invoked once at the begging of your
42+
This function should only be invoked once at the beggining of your
4343
server code. The function it returns should be used to check user credentials.
4444
4545
Args:
@@ -110,7 +110,7 @@ def authenticate_user(auth_header: str = Depends(oauth2_scheme)) -> IDToken:
110110

111111
# This is a dummy method for sphinx docs. DO NOT User.
112112
# TODO Find a way to doc higher order functions w/ sphinx.
113-
def authenticate_user(auth_header: str) -> IDToken:
113+
def authenticate_user(auth_header: str) -> IDToken: # type: ignore
114114
"""
115115
Validate and parse OIDC ID token against issuer in config.
116116
Note this function caches the signatures and algorithms of the issuing server

fastapi_oidc/types.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from pydantic import BaseModel
44
from pydantic import BaseSettings
5+
from pydantic import Extra
56

67

78
class OIDCConfig(BaseSettings):
@@ -12,21 +13,43 @@ class OIDCConfig(BaseSettings):
1213

1314

1415
class IDToken(BaseModel):
15-
""""""
16+
"""Pydantic model representing an OIDC ID Token.
17+
18+
ID Tokens are polymorphic and may have many attributes not defined in the spec thus this model accepts
19+
all addition fields. Only required fields are listed in the attributes section of this docstring or
20+
enforced by pydantic.
21+
22+
See the specifications here. https://openid.net/specs/openid-connect-core-1_0.html#IDToken
23+
24+
Attributes:
25+
iss (str): Issuer Identifier for the Issuer of the response.
26+
sub (str): Subject Identifier.
27+
aud (str): Audience(s) that this ID Token is intended for.
28+
exp (str): Expiration time on or after which the ID Token MUST NOT be accepted for processing.
29+
iat (iat): Time at which the JWT was issued.
30+
31+
"""
1632

17-
# TODO Verify the minimum and maximum claim set for ID Tokens.
18-
name: str
19-
email: str
20-
preferred_username: str
21-
exp: int
22-
auth_time: int
23-
sub: str
24-
ver: int
2533
iss: str
34+
sub: str
2635
aud: str
36+
exp: int
2737
iat: int
38+
39+
class Config:
40+
extra = Extra.allow
41+
42+
43+
class OktaIDToken(IDToken):
44+
"""Pydantic Model for the IDToken returned by Okta's OIDC implementation."""
45+
46+
auth_time: int
47+
ver: int
2848
jti: str
2949
amr: List[str]
3050
idp: str
3151
nonce: str
3252
at_hash: str
53+
name: str
54+
email: str
55+
preferred_username: str

0 commit comments

Comments
 (0)