golf-mcp 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of golf-mcp might be problematic. Click here for more details.
- golf/__init__.py +1 -1
- golf/_endpoints.py.in +6 -0
- {golf_mcp-0.2.2.dist-info → golf_mcp-0.2.4.dist-info}/METADATA +1 -1
- golf_mcp-0.2.4.dist-info/RECORD +56 -0
- golf/examples/__pycache__/__init__.cpython-311.pyc +0 -0
- golf/examples/basic/.coverage +0 -0
- golf/examples/basic/__pycache__/auth.cpython-311.pyc +0 -0
- golf/examples/basic/htmlcov/.gitignore +0 -2
- golf/examples/basic/htmlcov/class_index.html +0 -547
- golf/examples/basic/htmlcov/coverage_html_cb_6fb7b396.js +0 -733
- golf/examples/basic/htmlcov/favicon_32_cb_58284776.png +0 -0
- golf/examples/basic/htmlcov/function_index.html +0 -2091
- golf/examples/basic/htmlcov/index.html +0 -349
- golf/examples/basic/htmlcov/keybd_closed_cb_ce680311.png +0 -0
- golf/examples/basic/htmlcov/status.json +0 -1
- golf/examples/basic/htmlcov/style_cb_8e611ae1.css +0 -337
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496___init___py.html +0 -323
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_api_key_py.html +0 -170
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_factory_py.html +0 -430
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_helpers_py.html +0 -288
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_providers_py.html +0 -493
- golf/examples/basic/htmlcov/z_1c9a91c0e91c8496_registry_py.html +0 -353
- golf/examples/basic/htmlcov/z_3ec3b3f490dc0950___init___py.html +0 -120
- golf/examples/basic/htmlcov/z_3ec3b3f490dc0950_instrumentation_py.html +0 -1535
- golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db___init___py.html +0 -98
- golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_branding_py.html +0 -289
- golf/examples/basic/htmlcov/z_4b8b9dd4ccccc5db_main_py.html +0 -476
- golf/examples/basic/htmlcov/z_5a6c4e6bcc86fb2f___init___py.html +0 -97
- golf/examples/basic/htmlcov/z_6cadab9ec0df475d___init___py.html +0 -102
- golf/examples/basic/htmlcov/z_6cadab9ec0df475d_build_py.html +0 -178
- golf/examples/basic/htmlcov/z_6cadab9ec0df475d_init_py.html +0 -387
- golf/examples/basic/htmlcov/z_6cadab9ec0df475d_run_py.html +0 -222
- golf/examples/basic/htmlcov/z_6fcdee0582ba84e4___init___py.html +0 -106
- golf/examples/basic/htmlcov/z_6fcdee0582ba84e4__endpoints_fallback_py.html +0 -107
- golf/examples/basic/htmlcov/z_7ba499ed22986217___init___py.html +0 -98
- golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_auth_py.html +0 -306
- golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_metrics_py.html +0 -329
- golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_py.html +0 -1471
- golf/examples/basic/htmlcov/z_7ba499ed22986217_builder_telemetry_py.html +0 -186
- golf/examples/basic/htmlcov/z_7ba499ed22986217_config_py.html +0 -315
- golf/examples/basic/htmlcov/z_7ba499ed22986217_parser_py.html +0 -1149
- golf/examples/basic/htmlcov/z_7ba499ed22986217_platform_py.html +0 -279
- golf/examples/basic/htmlcov/z_7ba499ed22986217_telemetry_py.html +0 -589
- golf/examples/basic/htmlcov/z_7ba499ed22986217_transformer_py.html +0 -286
- golf/examples/basic/htmlcov/z_7d7da37693a43688___init___py.html +0 -107
- golf/examples/basic/htmlcov/z_7d7da37693a43688_collector_py.html +0 -417
- golf/examples/basic/htmlcov/z_7d7da37693a43688_registry_py.html +0 -109
- golf/examples/basic/htmlcov/z_abe733142b40ad4e___init___py.html +0 -109
- golf/examples/basic/htmlcov/z_abe733142b40ad4e_context_py.html +0 -150
- golf/examples/basic/htmlcov/z_abe733142b40ad4e_elicitation_py.html +0 -267
- golf/examples/basic/htmlcov/z_abe733142b40ad4e_sampling_py.html +0 -318
- golf/examples/basic/prompts/__pycache__/welcome.cpython-311.pyc +0 -0
- golf/examples/basic/resources/__pycache__/current_time.cpython-311.pyc +0 -0
- golf/examples/basic/resources/__pycache__/info.cpython-311.pyc +0 -0
- golf/examples/basic/resources/weather/__pycache__/common.cpython-311.pyc +0 -0
- golf/examples/basic/resources/weather/__pycache__/current.cpython-311.pyc +0 -0
- golf/examples/basic/resources/weather/__pycache__/forecast.cpython-311.pyc +0 -0
- golf/examples/basic/tools/__pycache__/calculator.cpython-311.pyc +0 -0
- golf/examples/basic/tools/say/__pycache__/hello.cpython-311.pyc +0 -0
- golf_mcp-0.2.2.dist-info/RECORD +0 -110
- {golf_mcp-0.2.2.dist-info → golf_mcp-0.2.4.dist-info}/WHEEL +0 -0
- {golf_mcp-0.2.2.dist-info → golf_mcp-0.2.4.dist-info}/entry_points.txt +0 -0
- {golf_mcp-0.2.2.dist-info → golf_mcp-0.2.4.dist-info}/licenses/LICENSE +0 -0
- {golf_mcp-0.2.2.dist-info → golf_mcp-0.2.4.dist-info}/top_level.txt +0 -0
|
@@ -1,493 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
5
|
-
<title>Coverage for /Users/antonigmitruk/golf/src/golf/auth/providers.py: 0%</title>
|
|
6
|
-
<link rel="icon" sizes="32x32" href="favicon_32_cb_58284776.png">
|
|
7
|
-
<link rel="stylesheet" href="style_cb_8e611ae1.css" type="text/css">
|
|
8
|
-
<script src="coverage_html_cb_6fb7b396.js" defer></script>
|
|
9
|
-
</head>
|
|
10
|
-
<body class="pyfile">
|
|
11
|
-
<header>
|
|
12
|
-
<div class="content">
|
|
13
|
-
<h1>
|
|
14
|
-
<span class="text">Coverage for </span><b>/Users/antonigmitruk/golf/src/golf/auth/providers.py</b>:
|
|
15
|
-
<span class="pc_cov">0%</span>
|
|
16
|
-
</h1>
|
|
17
|
-
<aside id="help_panel_wrapper">
|
|
18
|
-
<input id="help_panel_state" type="checkbox">
|
|
19
|
-
<label for="help_panel_state">
|
|
20
|
-
<img id="keyboard_icon" src="keybd_closed_cb_ce680311.png" alt="Show/hide keyboard shortcuts">
|
|
21
|
-
</label>
|
|
22
|
-
<div id="help_panel">
|
|
23
|
-
<p class="legend">Shortcuts on this page</p>
|
|
24
|
-
<div class="keyhelp">
|
|
25
|
-
<p>
|
|
26
|
-
<kbd>r</kbd>
|
|
27
|
-
<kbd>m</kbd>
|
|
28
|
-
<kbd>x</kbd>
|
|
29
|
-
toggle line displays
|
|
30
|
-
</p>
|
|
31
|
-
<p>
|
|
32
|
-
<kbd>j</kbd>
|
|
33
|
-
<kbd>k</kbd>
|
|
34
|
-
next/prev highlighted chunk
|
|
35
|
-
</p>
|
|
36
|
-
<p>
|
|
37
|
-
<kbd>0</kbd> (zero) top of page
|
|
38
|
-
</p>
|
|
39
|
-
<p>
|
|
40
|
-
<kbd>1</kbd> (one) first highlighted chunk
|
|
41
|
-
</p>
|
|
42
|
-
<p>
|
|
43
|
-
<kbd>[</kbd>
|
|
44
|
-
<kbd>]</kbd>
|
|
45
|
-
prev/next file
|
|
46
|
-
</p>
|
|
47
|
-
<p>
|
|
48
|
-
<kbd>u</kbd> up to the index
|
|
49
|
-
</p>
|
|
50
|
-
<p>
|
|
51
|
-
<kbd>?</kbd> show/hide this help
|
|
52
|
-
</p>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
</aside>
|
|
56
|
-
<h2>
|
|
57
|
-
<span class="text">179 statements </span>
|
|
58
|
-
<button type="button" class="run button_toggle_run" value="run" data-shortcut="r" title="Toggle lines run">0<span class="text"> run</span></button>
|
|
59
|
-
<button type="button" class="mis show_mis button_toggle_mis" value="mis" data-shortcut="m" title="Toggle lines missing">179<span class="text"> missing</span></button>
|
|
60
|
-
<button type="button" class="exc show_exc button_toggle_exc" value="exc" data-shortcut="x" title="Toggle lines excluded">0<span class="text"> excluded</span></button>
|
|
61
|
-
</h2>
|
|
62
|
-
<p class="text">
|
|
63
|
-
<a id="prevFileLink" class="nav" href="z_1c9a91c0e91c8496_helpers_py.html">« prev</a>
|
|
64
|
-
<a id="indexLink" class="nav" href="index.html">^ index</a>
|
|
65
|
-
<a id="nextFileLink" class="nav" href="z_1c9a91c0e91c8496_registry_py.html">» next</a>
|
|
66
|
-
|
|
67
|
-
<a class="nav" href="https://coverage.readthedocs.io/en/7.6.12">coverage.py v7.6.12</a>,
|
|
68
|
-
created at 2025-08-16 18:46 +0200
|
|
69
|
-
</p>
|
|
70
|
-
<aside class="hidden">
|
|
71
|
-
<button type="button" class="button_next_chunk" data-shortcut="j"></button>
|
|
72
|
-
<button type="button" class="button_prev_chunk" data-shortcut="k"></button>
|
|
73
|
-
<button type="button" class="button_top_of_page" data-shortcut="0"></button>
|
|
74
|
-
<button type="button" class="button_first_chunk" data-shortcut="1"></button>
|
|
75
|
-
<button type="button" class="button_prev_file" data-shortcut="["></button>
|
|
76
|
-
<button type="button" class="button_next_file" data-shortcut="]"></button>
|
|
77
|
-
<button type="button" class="button_to_index" data-shortcut="u"></button>
|
|
78
|
-
<button type="button" class="button_show_hide_help" data-shortcut="?"></button>
|
|
79
|
-
</aside>
|
|
80
|
-
</div>
|
|
81
|
-
</header>
|
|
82
|
-
<main id="source">
|
|
83
|
-
<p class="pln"><span class="n"><a id="t1" href="#t1">1</a></span><span class="t"><span class="str">"""Modern authentication provider configurations for Golf MCP servers.</span> </span><span class="r"></span></p>
|
|
84
|
-
<p class="pln"><span class="n"><a id="t2" href="#t2">2</a></span><span class="t"> </span><span class="r"></span></p>
|
|
85
|
-
<p class="pln"><span class="n"><a id="t3" href="#t3">3</a></span><span class="t"><span class="str">This module provides configuration classes for FastMCP 2.11+ authentication providers,</span> </span><span class="r"></span></p>
|
|
86
|
-
<p class="pln"><span class="n"><a id="t4" href="#t4">4</a></span><span class="t"><span class="str">replacing the legacy custom OAuth implementation with the new built-in auth system.</span> </span><span class="r"></span></p>
|
|
87
|
-
<p class="pln"><span class="n"><a id="t5" href="#t5">5</a></span><span class="t"><span class="str">"""</span> </span><span class="r"></span></p>
|
|
88
|
-
<p class="pln"><span class="n"><a id="t6" href="#t6">6</a></span><span class="t"> </span><span class="r"></span></p>
|
|
89
|
-
<p class="mis show_mis"><span class="n"><a id="t7" href="#t7">7</a></span><span class="t"><span class="key">import</span> <span class="nam">os</span> </span><span class="r"></span></p>
|
|
90
|
-
<p class="mis show_mis"><span class="n"><a id="t8" href="#t8">8</a></span><span class="t"><span class="key">from</span> <span class="nam">typing</span> <span class="key">import</span> <span class="nam">Any</span><span class="op">,</span> <span class="nam">Literal</span> </span><span class="r"></span></p>
|
|
91
|
-
<p class="mis show_mis"><span class="n"><a id="t9" href="#t9">9</a></span><span class="t"><span class="key">from</span> <span class="nam">urllib</span><span class="op">.</span><span class="nam">parse</span> <span class="key">import</span> <span class="nam">urlparse</span> </span><span class="r"></span></p>
|
|
92
|
-
<p class="pln"><span class="n"><a id="t10" href="#t10">10</a></span><span class="t"> </span><span class="r"></span></p>
|
|
93
|
-
<p class="mis show_mis"><span class="n"><a id="t11" href="#t11">11</a></span><span class="t"><span class="key">from</span> <span class="nam">pydantic</span> <span class="key">import</span> <span class="nam">BaseModel</span><span class="op">,</span> <span class="nam">Field</span><span class="op">,</span> <span class="nam">field_validator</span><span class="op">,</span> <span class="nam">model_validator</span> </span><span class="r"></span></p>
|
|
94
|
-
<p class="pln"><span class="n"><a id="t12" href="#t12">12</a></span><span class="t"> </span><span class="r"></span></p>
|
|
95
|
-
<p class="pln"><span class="n"><a id="t13" href="#t13">13</a></span><span class="t"> </span><span class="r"></span></p>
|
|
96
|
-
<p class="mis show_mis"><span class="n"><a id="t14" href="#t14">14</a></span><span class="t"><span class="key">class</span> <span class="nam">JWTAuthConfig</span><span class="op">(</span><span class="nam">BaseModel</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
97
|
-
<p class="pln"><span class="n"><a id="t15" href="#t15">15</a></span><span class="t"> <span class="str">"""Configuration for JWT token verification using FastMCP's JWTVerifier.</span> </span><span class="r"></span></p>
|
|
98
|
-
<p class="pln"><span class="n"><a id="t16" href="#t16">16</a></span><span class="t"> </span><span class="r"></span></p>
|
|
99
|
-
<p class="pln"><span class="n"><a id="t17" href="#t17">17</a></span><span class="t"><span class="str"> Use this when you have JWT tokens issued by an external OAuth server</span> </span><span class="r"></span></p>
|
|
100
|
-
<p class="pln"><span class="n"><a id="t18" href="#t18">18</a></span><span class="t"><span class="str"> (like Auth0, Okta, etc.) and want to verify them in your Golf server.</span> </span><span class="r"></span></p>
|
|
101
|
-
<p class="pln"><span class="n"><a id="t19" href="#t19">19</a></span><span class="t"> </span><span class="r"></span></p>
|
|
102
|
-
<p class="pln"><span class="n"><a id="t20" href="#t20">20</a></span><span class="t"><span class="str"> Security Note:</span> </span><span class="r"></span></p>
|
|
103
|
-
<p class="pln"><span class="n"><a id="t21" href="#t21">21</a></span><span class="t"><span class="str"> For production use, it's strongly recommended to specify both `issuer` and `audience`</span> </span><span class="r"></span></p>
|
|
104
|
-
<p class="pln"><span class="n"><a id="t22" href="#t22">22</a></span><span class="t"><span class="str"> to ensure tokens are validated against the expected issuer and intended audience.</span> </span><span class="r"></span></p>
|
|
105
|
-
<p class="pln"><span class="n"><a id="t23" href="#t23">23</a></span><span class="t"><span class="str"> This prevents token misuse across different services or environments.</span> </span><span class="r"></span></p>
|
|
106
|
-
<p class="pln"><span class="n"><a id="t24" href="#t24">24</a></span><span class="t"><span class="str"> """</span> </span><span class="r"></span></p>
|
|
107
|
-
<p class="pln"><span class="n"><a id="t25" href="#t25">25</a></span><span class="t"> </span><span class="r"></span></p>
|
|
108
|
-
<p class="mis show_mis"><span class="n"><a id="t26" href="#t26">26</a></span><span class="t"> <span class="nam">provider_type</span><span class="op">:</span> <span class="nam">Literal</span><span class="op">[</span><span class="str">"jwt"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"jwt"</span> </span><span class="r"></span></p>
|
|
109
|
-
<p class="pln"><span class="n"><a id="t27" href="#t27">27</a></span><span class="t"> </span><span class="r"></span></p>
|
|
110
|
-
<p class="pln"><span class="n"><a id="t28" href="#t28">28</a></span><span class="t"> <span class="com"># JWT verification settings</span> </span><span class="r"></span></p>
|
|
111
|
-
<p class="mis show_mis"><span class="n"><a id="t29" href="#t29">29</a></span><span class="t"> <span class="nam">public_key</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"PEM-encoded public key for JWT verification"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
112
|
-
<p class="mis show_mis"><span class="n"><a id="t30" href="#t30">30</a></span><span class="t"> <span class="nam">jwks_uri</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"URI to fetch JSON Web Key Set for verification"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
113
|
-
<p class="mis show_mis"><span class="n"><a id="t31" href="#t31">31</a></span><span class="t"> <span class="nam">issuer</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Expected JWT issuer claim (strongly recommended for production)"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
114
|
-
<p class="mis show_mis"><span class="n"><a id="t32" href="#t32">32</a></span><span class="t"> <span class="nam">audience</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
115
|
-
<p class="pln"><span class="n"><a id="t33" href="#t33">33</a></span><span class="t"> <span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Expected JWT audience claim(s) (strongly recommended for production)"</span> </span><span class="r"></span></p>
|
|
116
|
-
<p class="pln"><span class="n"><a id="t34" href="#t34">34</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
117
|
-
<p class="mis show_mis"><span class="n"><a id="t35" href="#t35">35</a></span><span class="t"> <span class="nam">algorithm</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="str">"RS256"</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"JWT signing algorithm"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
118
|
-
<p class="pln"><span class="n"><a id="t36" href="#t36">36</a></span><span class="t"> </span><span class="r"></span></p>
|
|
119
|
-
<p class="pln"><span class="n"><a id="t37" href="#t37">37</a></span><span class="t"> <span class="com"># Scope and access control</span> </span><span class="r"></span></p>
|
|
120
|
-
<p class="mis show_mis"><span class="n"><a id="t38" href="#t38">38</a></span><span class="t"> <span class="nam">required_scopes</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="nam">default_factory</span><span class="op">=</span><span class="nam">list</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Scopes required for all requests"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
121
|
-
<p class="pln"><span class="n"><a id="t39" href="#t39">39</a></span><span class="t"> </span><span class="r"></span></p>
|
|
122
|
-
<p class="pln"><span class="n"><a id="t40" href="#t40">40</a></span><span class="t"> <span class="com"># Environment variable names for runtime configuration</span> </span><span class="r"></span></p>
|
|
123
|
-
<p class="mis show_mis"><span class="n"><a id="t41" href="#t41">41</a></span><span class="t"> <span class="nam">public_key_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for public key"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
124
|
-
<p class="mis show_mis"><span class="n"><a id="t42" href="#t42">42</a></span><span class="t"> <span class="nam">jwks_uri_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for JWKS URI"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
125
|
-
<p class="mis show_mis"><span class="n"><a id="t43" href="#t43">43</a></span><span class="t"> <span class="nam">issuer_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for issuer"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
126
|
-
<p class="mis show_mis"><span class="n"><a id="t44" href="#t44">44</a></span><span class="t"> <span class="nam">audience_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for audience"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
127
|
-
<p class="pln"><span class="n"><a id="t45" href="#t45">45</a></span><span class="t"> </span><span class="r"></span></p>
|
|
128
|
-
<p class="mis show_mis"><span class="n"><a id="t46" href="#t46">46</a></span><span class="t"> <span class="op">@</span><span class="nam">model_validator</span><span class="op">(</span><span class="nam">mode</span><span class="op">=</span><span class="str">"after"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
129
|
-
<p class="mis show_mis"><span class="n"><a id="t47" href="#t47">47</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_jwt_config</span><span class="op">(</span><span class="nam">self</span><span class="op">)</span> <span class="op">-></span> <span class="str">"JWTAuthConfig"</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
130
|
-
<p class="pln"><span class="n"><a id="t48" href="#t48">48</a></span><span class="t"> <span class="str">"""Validate JWT configuration requirements."""</span> </span><span class="r"></span></p>
|
|
131
|
-
<p class="pln"><span class="n"><a id="t49" href="#t49">49</a></span><span class="t"> <span class="com"># Ensure exactly one of public_key or jwks_uri is provided</span> </span><span class="r"></span></p>
|
|
132
|
-
<p class="mis show_mis"><span class="n"><a id="t50" href="#t50">50</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">public_key</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">jwks_uri</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">public_key_env_var</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">jwks_uri_env_var</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
133
|
-
<p class="mis show_mis"><span class="n"><a id="t51" href="#t51">51</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"Either public_key, jwks_uri, or their environment variable equivalents must be provided"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
134
|
-
<p class="pln"><span class="n"><a id="t52" href="#t52">52</a></span><span class="t"> </span><span class="r"></span></p>
|
|
135
|
-
<p class="mis show_mis"><span class="n"><a id="t53" href="#t53">53</a></span><span class="t"> <span class="key">if</span> <span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">public_key</span> <span class="key">or</span> <span class="nam">self</span><span class="op">.</span><span class="nam">public_key_env_var</span><span class="op">)</span> <span class="key">and</span> <span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">jwks_uri</span> <span class="key">or</span> <span class="nam">self</span><span class="op">.</span><span class="nam">jwks_uri_env_var</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
136
|
-
<p class="mis show_mis"><span class="n"><a id="t54" href="#t54">54</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"Provide either public_key or jwks_uri (or their env vars), not both"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
137
|
-
<p class="pln"><span class="n"><a id="t55" href="#t55">55</a></span><span class="t"> </span><span class="r"></span></p>
|
|
138
|
-
<p class="pln"><span class="n"><a id="t56" href="#t56">56</a></span><span class="t"> <span class="com"># Warn about missing issuer/audience in production-like environments</span> </span><span class="r"></span></p>
|
|
139
|
-
<p class="mis show_mis"><span class="n"><a id="t57" href="#t57">57</a></span><span class="t"> <span class="nam">is_production</span> <span class="op">=</span> <span class="op">(</span> </span><span class="r"></span></p>
|
|
140
|
-
<p class="pln"><span class="n"><a id="t58" href="#t58">58</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"GOLF_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
141
|
-
<p class="pln"><span class="n"><a id="t59" href="#t59">59</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"NODE_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="op">==</span> <span class="str">"production"</span> </span><span class="r"></span></p>
|
|
142
|
-
<p class="pln"><span class="n"><a id="t60" href="#t60">60</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ENVIRONMENT"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
143
|
-
<p class="pln"><span class="n"><a id="t61" href="#t61">61</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
144
|
-
<p class="pln"><span class="n"><a id="t62" href="#t62">62</a></span><span class="t"> </span><span class="r"></span></p>
|
|
145
|
-
<p class="mis show_mis"><span class="n"><a id="t63" href="#t63">63</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_production</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
146
|
-
<p class="mis show_mis"><span class="n"><a id="t64" href="#t64">64</a></span><span class="t"> <span class="nam">missing_fields</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span> </span><span class="r"></span></p>
|
|
147
|
-
<p class="mis show_mis"><span class="n"><a id="t65" href="#t65">65</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">issuer</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">issuer_env_var</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
148
|
-
<p class="mis show_mis"><span class="n"><a id="t66" href="#t66">66</a></span><span class="t"> <span class="nam">missing_fields</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="str">"issuer"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
149
|
-
<p class="mis show_mis"><span class="n"><a id="t67" href="#t67">67</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">audience</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">self</span><span class="op">.</span><span class="nam">audience_env_var</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
150
|
-
<p class="mis show_mis"><span class="n"><a id="t68" href="#t68">68</a></span><span class="t"> <span class="nam">missing_fields</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="str">"audience"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
151
|
-
<p class="pln"><span class="n"><a id="t69" href="#t69">69</a></span><span class="t"> </span><span class="r"></span></p>
|
|
152
|
-
<p class="mis show_mis"><span class="n"><a id="t70" href="#t70">70</a></span><span class="t"> <span class="key">if</span> <span class="nam">missing_fields</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
153
|
-
<p class="mis show_mis"><span class="n"><a id="t71" href="#t71">71</a></span><span class="t"> <span class="key">import</span> <span class="nam">warnings</span> </span><span class="r"></span></p>
|
|
154
|
-
<p class="pln"><span class="n"><a id="t72" href="#t72">72</a></span><span class="t"> </span><span class="r"></span></p>
|
|
155
|
-
<p class="mis show_mis"><span class="n"><a id="t73" href="#t73">73</a></span><span class="t"> <span class="nam">warnings</span><span class="op">.</span><span class="nam">warn</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
156
|
-
<p class="pln"><span class="n"><a id="t74" href="#t74">74</a></span><span class="t"> <span class="str">f"JWT configuration is missing recommended fields for production: {', '.join(missing_fields)}. "</span> </span><span class="r"></span></p>
|
|
157
|
-
<p class="pln"><span class="n"><a id="t75" href="#t75">75</a></span><span class="t"> <span class="str">"This may allow tokens from unintended issuers or audiences to be accepted."</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
158
|
-
<p class="pln"><span class="n"><a id="t76" href="#t76">76</a></span><span class="t"> <span class="nam">UserWarning</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
159
|
-
<p class="pln"><span class="n"><a id="t77" href="#t77">77</a></span><span class="t"> <span class="nam">stacklevel</span><span class="op">=</span><span class="num">2</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
160
|
-
<p class="pln"><span class="n"><a id="t78" href="#t78">78</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
161
|
-
<p class="pln"><span class="n"><a id="t79" href="#t79">79</a></span><span class="t"> </span><span class="r"></span></p>
|
|
162
|
-
<p class="mis show_mis"><span class="n"><a id="t80" href="#t80">80</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span> </span><span class="r"></span></p>
|
|
163
|
-
<p class="pln"><span class="n"><a id="t81" href="#t81">81</a></span><span class="t"> </span><span class="r"></span></p>
|
|
164
|
-
<p class="pln"><span class="n"><a id="t82" href="#t82">82</a></span><span class="t"> </span><span class="r"></span></p>
|
|
165
|
-
<p class="mis show_mis"><span class="n"><a id="t83" href="#t83">83</a></span><span class="t"><span class="key">class</span> <span class="nam">StaticTokenConfig</span><span class="op">(</span><span class="nam">BaseModel</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
166
|
-
<p class="pln"><span class="n"><a id="t84" href="#t84">84</a></span><span class="t"> <span class="str">"""Configuration for static token verification for development/testing.</span> </span><span class="r"></span></p>
|
|
167
|
-
<p class="pln"><span class="n"><a id="t85" href="#t85">85</a></span><span class="t"> </span><span class="r"></span></p>
|
|
168
|
-
<p class="pln"><span class="n"><a id="t86" href="#t86">86</a></span><span class="t"><span class="str"> Use this for local development and testing when you need predictable</span> </span><span class="r"></span></p>
|
|
169
|
-
<p class="pln"><span class="n"><a id="t87" href="#t87">87</a></span><span class="t"><span class="str"> API keys without setting up a full OAuth server.</span> </span><span class="r"></span></p>
|
|
170
|
-
<p class="pln"><span class="n"><a id="t88" href="#t88">88</a></span><span class="t"> </span><span class="r"></span></p>
|
|
171
|
-
<p class="pln"><span class="n"><a id="t89" href="#t89">89</a></span><span class="t"><span class="str"> WARNING: Never use in production!</span> </span><span class="r"></span></p>
|
|
172
|
-
<p class="pln"><span class="n"><a id="t90" href="#t90">90</a></span><span class="t"><span class="str"> """</span> </span><span class="r"></span></p>
|
|
173
|
-
<p class="pln"><span class="n"><a id="t91" href="#t91">91</a></span><span class="t"> </span><span class="r"></span></p>
|
|
174
|
-
<p class="mis show_mis"><span class="n"><a id="t92" href="#t92">92</a></span><span class="t"> <span class="nam">provider_type</span><span class="op">:</span> <span class="nam">Literal</span><span class="op">[</span><span class="str">"static"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"static"</span> </span><span class="r"></span></p>
|
|
175
|
-
<p class="pln"><span class="n"><a id="t93" href="#t93">93</a></span><span class="t"> </span><span class="r"></span></p>
|
|
176
|
-
<p class="pln"><span class="n"><a id="t94" href="#t94">94</a></span><span class="t"> <span class="com"># Static tokens mapping: token_string -> metadata</span> </span><span class="r"></span></p>
|
|
177
|
-
<p class="mis show_mis"><span class="n"><a id="t95" href="#t95">95</a></span><span class="t"> <span class="nam">tokens</span><span class="op">:</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">dict</span><span class="op">[</span><span class="nam">str</span><span class="op">,</span> <span class="nam">Any</span><span class="op">]</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
178
|
-
<p class="pln"><span class="n"><a id="t96" href="#t96">96</a></span><span class="t"> <span class="nam">default_factory</span><span class="op">=</span><span class="nam">dict</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
179
|
-
<p class="pln"><span class="n"><a id="t97" href="#t97">97</a></span><span class="t"> <span class="nam">description</span><span class="op">=</span><span class="str">"Static tokens with their metadata (client_id, scopes, expires_at)"</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
180
|
-
<p class="pln"><span class="n"><a id="t98" href="#t98">98</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
181
|
-
<p class="pln"><span class="n"><a id="t99" href="#t99">99</a></span><span class="t"> </span><span class="r"></span></p>
|
|
182
|
-
<p class="pln"><span class="n"><a id="t100" href="#t100">100</a></span><span class="t"> <span class="com"># Scope and access control</span> </span><span class="r"></span></p>
|
|
183
|
-
<p class="mis show_mis"><span class="n"><a id="t101" href="#t101">101</a></span><span class="t"> <span class="nam">required_scopes</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="nam">default_factory</span><span class="op">=</span><span class="nam">list</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Scopes required for all requests"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
184
|
-
<p class="pln"><span class="n"><a id="t102" href="#t102">102</a></span><span class="t"> </span><span class="r"></span></p>
|
|
185
|
-
<p class="pln"><span class="n"><a id="t103" href="#t103">103</a></span><span class="t"> </span><span class="r"></span></p>
|
|
186
|
-
<p class="mis show_mis"><span class="n"><a id="t104" href="#t104">104</a></span><span class="t"><span class="key">class</span> <span class="nam">OAuthServerConfig</span><span class="op">(</span><span class="nam">BaseModel</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
187
|
-
<p class="pln"><span class="n"><a id="t105" href="#t105">105</a></span><span class="t"> <span class="str">"""Configuration for full OAuth authorization server using FastMCP's OAuthProvider.</span> </span><span class="r"></span></p>
|
|
188
|
-
<p class="pln"><span class="n"><a id="t106" href="#t106">106</a></span><span class="t"> </span><span class="r"></span></p>
|
|
189
|
-
<p class="pln"><span class="n"><a id="t107" href="#t107">107</a></span><span class="t"><span class="str"> Use this when you want your Golf server to act as a complete OAuth server,</span> </span><span class="r"></span></p>
|
|
190
|
-
<p class="pln"><span class="n"><a id="t108" href="#t108">108</a></span><span class="t"><span class="str"> handling authorization flows and token issuance.</span> </span><span class="r"></span></p>
|
|
191
|
-
<p class="pln"><span class="n"><a id="t109" href="#t109">109</a></span><span class="t"> </span><span class="r"></span></p>
|
|
192
|
-
<p class="pln"><span class="n"><a id="t110" href="#t110">110</a></span><span class="t"><span class="str"> Security Considerations:</span> </span><span class="r"></span></p>
|
|
193
|
-
<p class="pln"><span class="n"><a id="t111" href="#t111">111</a></span><span class="t"><span class="str"> - URLs are validated to prevent SSRF attacks</span> </span><span class="r"></span></p>
|
|
194
|
-
<p class="pln"><span class="n"><a id="t112" href="#t112">112</a></span><span class="t"><span class="str"> - Scopes are validated against OAuth 2.0 standards</span> </span><span class="r"></span></p>
|
|
195
|
-
<p class="pln"><span class="n"><a id="t113" href="#t113">113</a></span><span class="t"><span class="str"> - Base URL must use HTTPS in production environments</span> </span><span class="r"></span></p>
|
|
196
|
-
<p class="pln"><span class="n"><a id="t114" href="#t114">114</a></span><span class="t"><span class="str"> - Client registration is disabled for security</span> </span><span class="r"></span></p>
|
|
197
|
-
<p class="pln"><span class="n"><a id="t115" href="#t115">115</a></span><span class="t"><span class="str"> """</span> </span><span class="r"></span></p>
|
|
198
|
-
<p class="pln"><span class="n"><a id="t116" href="#t116">116</a></span><span class="t"> </span><span class="r"></span></p>
|
|
199
|
-
<p class="mis show_mis"><span class="n"><a id="t117" href="#t117">117</a></span><span class="t"> <span class="nam">provider_type</span><span class="op">:</span> <span class="nam">Literal</span><span class="op">[</span><span class="str">"oauth_server"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"oauth_server"</span> </span><span class="r"></span></p>
|
|
200
|
-
<p class="pln"><span class="n"><a id="t118" href="#t118">118</a></span><span class="t"> </span><span class="r"></span></p>
|
|
201
|
-
<p class="pln"><span class="n"><a id="t119" href="#t119">119</a></span><span class="t"> <span class="com"># OAuth server URLs</span> </span><span class="r"></span></p>
|
|
202
|
-
<p class="mis show_mis"><span class="n"><a id="t120" href="#t120">120</a></span><span class="t"> <span class="nam">base_url</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="op">...</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Public URL of this Golf server (must use HTTPS in production)"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
203
|
-
<p class="mis show_mis"><span class="n"><a id="t121" href="#t121">121</a></span><span class="t"> <span class="nam">issuer_url</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"OAuth issuer URL (defaults to base_url, must be HTTPS)"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
204
|
-
<p class="mis show_mis"><span class="n"><a id="t122" href="#t122">122</a></span><span class="t"> <span class="nam">service_documentation_url</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"URL of service documentation"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
205
|
-
<p class="pln"><span class="n"><a id="t123" href="#t123">123</a></span><span class="t"> </span><span class="r"></span></p>
|
|
206
|
-
<p class="pln"><span class="n"><a id="t124" href="#t124">124</a></span><span class="t"> <span class="com"># Client registration settings</span> </span><span class="r"></span></p>
|
|
207
|
-
<p class="mis show_mis"><span class="n"><a id="t125" href="#t125">125</a></span><span class="t"> <span class="nam">valid_scopes</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
208
|
-
<p class="pln"><span class="n"><a id="t126" href="#t126">126</a></span><span class="t"> <span class="nam">default_factory</span><span class="op">=</span><span class="nam">list</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Valid scopes for client registration (OAuth 2.0 format)"</span> </span><span class="r"></span></p>
|
|
209
|
-
<p class="pln"><span class="n"><a id="t127" href="#t127">127</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
210
|
-
<p class="mis show_mis"><span class="n"><a id="t128" href="#t128">128</a></span><span class="t"> <span class="nam">default_scopes</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="nam">default_factory</span><span class="op">=</span><span class="nam">list</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Default scopes for new clients"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
211
|
-
<p class="pln"><span class="n"><a id="t129" href="#t129">129</a></span><span class="t"> </span><span class="r"></span></p>
|
|
212
|
-
<p class="pln"><span class="n"><a id="t130" href="#t130">130</a></span><span class="t"> <span class="com"># Token revocation settings</span> </span><span class="r"></span></p>
|
|
213
|
-
<p class="mis show_mis"><span class="n"><a id="t131" href="#t131">131</a></span><span class="t"> <span class="nam">allow_token_revocation</span><span class="op">:</span> <span class="nam">bool</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">True</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Allow token revocation"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
214
|
-
<p class="pln"><span class="n"><a id="t132" href="#t132">132</a></span><span class="t"> </span><span class="r"></span></p>
|
|
215
|
-
<p class="pln"><span class="n"><a id="t133" href="#t133">133</a></span><span class="t"> <span class="com"># Access control</span> </span><span class="r"></span></p>
|
|
216
|
-
<p class="mis show_mis"><span class="n"><a id="t134" href="#t134">134</a></span><span class="t"> <span class="nam">required_scopes</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="nam">default_factory</span><span class="op">=</span><span class="nam">list</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Scopes required for all requests"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
217
|
-
<p class="pln"><span class="n"><a id="t135" href="#t135">135</a></span><span class="t"> </span><span class="r"></span></p>
|
|
218
|
-
<p class="pln"><span class="n"><a id="t136" href="#t136">136</a></span><span class="t"> <span class="com"># Environment variable names for runtime configuration</span> </span><span class="r"></span></p>
|
|
219
|
-
<p class="mis show_mis"><span class="n"><a id="t137" href="#t137">137</a></span><span class="t"> <span class="nam">base_url_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for base URL"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
220
|
-
<p class="pln"><span class="n"><a id="t138" href="#t138">138</a></span><span class="t"> </span><span class="r"></span></p>
|
|
221
|
-
<p class="mis show_mis"><span class="n"><a id="t139" href="#t139">139</a></span><span class="t"> <span class="op">@</span><span class="nam">field_validator</span><span class="op">(</span><span class="str">"base_url"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
222
|
-
<p class="mis show_mis"><span class="n"><a id="t140" href="#t140">140</a></span><span class="t"> <span class="op">@</span><span class="nam">classmethod</span> </span><span class="r"></span></p>
|
|
223
|
-
<p class="mis show_mis"><span class="n"><a id="t141" href="#t141">141</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_base_url</span><span class="op">(</span><span class="nam">cls</span><span class="op">,</span> <span class="nam">v</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
224
|
-
<p class="pln"><span class="n"><a id="t142" href="#t142">142</a></span><span class="t"> <span class="str">"""Validate base URL for security and format compliance."""</span> </span><span class="r"></span></p>
|
|
225
|
-
<p class="mis show_mis"><span class="n"><a id="t143" href="#t143">143</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">v</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">v</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
226
|
-
<p class="mis show_mis"><span class="n"><a id="t144" href="#t144">144</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"base_url cannot be empty"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
227
|
-
<p class="pln"><span class="n"><a id="t145" href="#t145">145</a></span><span class="t"> </span><span class="r"></span></p>
|
|
228
|
-
<p class="mis show_mis"><span class="n"><a id="t146" href="#t146">146</a></span><span class="t"> <span class="nam">url</span> <span class="op">=</span> <span class="nam">v</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
229
|
-
<p class="mis show_mis"><span class="n"><a id="t147" href="#t147">147</a></span><span class="t"> <span class="key">try</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
230
|
-
<p class="mis show_mis"><span class="n"><a id="t148" href="#t148">148</a></span><span class="t"> <span class="nam">parsed</span> <span class="op">=</span> <span class="nam">urlparse</span><span class="op">(</span><span class="nam">url</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
231
|
-
<p class="mis show_mis"><span class="n"><a id="t149" href="#t149">149</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">netloc</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
232
|
-
<p class="mis show_mis"><span class="n"><a id="t150" href="#t150">150</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid base URL format: '{url}' - must include scheme and netloc"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
233
|
-
<p class="pln"><span class="n"><a id="t151" href="#t151">151</a></span><span class="t"> </span><span class="r"></span></p>
|
|
234
|
-
<p class="mis show_mis"><span class="n"><a id="t152" href="#t152">152</a></span><span class="t"> <span class="key">if</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">not</span> <span class="key">in</span> <span class="op">(</span><span class="str">"http"</span><span class="op">,</span> <span class="str">"https"</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
235
|
-
<p class="mis show_mis"><span class="n"><a id="t153" href="#t153">153</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Base URL must use http or https scheme: '{url}'"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
236
|
-
<p class="pln"><span class="n"><a id="t154" href="#t154">154</a></span><span class="t"> </span><span class="r"></span></p>
|
|
237
|
-
<p class="pln"><span class="n"><a id="t155" href="#t155">155</a></span><span class="t"> <span class="com"># Warn about HTTP in production-like environments</span> </span><span class="r"></span></p>
|
|
238
|
-
<p class="mis show_mis"><span class="n"><a id="t156" href="#t156">156</a></span><span class="t"> <span class="nam">is_production</span> <span class="op">=</span> <span class="op">(</span> </span><span class="r"></span></p>
|
|
239
|
-
<p class="pln"><span class="n"><a id="t157" href="#t157">157</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"GOLF_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
240
|
-
<p class="pln"><span class="n"><a id="t158" href="#t158">158</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"NODE_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="op">==</span> <span class="str">"production"</span> </span><span class="r"></span></p>
|
|
241
|
-
<p class="pln"><span class="n"><a id="t159" href="#t159">159</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ENVIRONMENT"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
242
|
-
<p class="pln"><span class="n"><a id="t160" href="#t160">160</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
243
|
-
<p class="pln"><span class="n"><a id="t161" href="#t161">161</a></span><span class="t"> </span><span class="r"></span></p>
|
|
244
|
-
<p class="mis show_mis"><span class="n"><a id="t162" href="#t162">162</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_production</span> <span class="key">and</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="op">==</span> <span class="str">"http"</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
245
|
-
<p class="mis show_mis"><span class="n"><a id="t163" href="#t163">163</a></span><span class="t"> <span class="key">import</span> <span class="nam">warnings</span> </span><span class="r"></span></p>
|
|
246
|
-
<p class="pln"><span class="n"><a id="t164" href="#t164">164</a></span><span class="t"> </span><span class="r"></span></p>
|
|
247
|
-
<p class="mis show_mis"><span class="n"><a id="t165" href="#t165">165</a></span><span class="t"> <span class="nam">warnings</span><span class="op">.</span><span class="nam">warn</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
248
|
-
<p class="pln"><span class="n"><a id="t166" href="#t166">166</a></span><span class="t"> <span class="str">f"Base URL '{url}' uses HTTP in production environment. "</span> </span><span class="r"></span></p>
|
|
249
|
-
<p class="pln"><span class="n"><a id="t167" href="#t167">167</a></span><span class="t"> <span class="str">"HTTPS is strongly recommended for OAuth servers to prevent token interception."</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
250
|
-
<p class="pln"><span class="n"><a id="t168" href="#t168">168</a></span><span class="t"> <span class="nam">UserWarning</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
251
|
-
<p class="pln"><span class="n"><a id="t169" href="#t169">169</a></span><span class="t"> <span class="nam">stacklevel</span><span class="op">=</span><span class="num">2</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
252
|
-
<p class="pln"><span class="n"><a id="t170" href="#t170">170</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
253
|
-
<p class="pln"><span class="n"><a id="t171" href="#t171">171</a></span><span class="t"> </span><span class="r"></span></p>
|
|
254
|
-
<p class="pln"><span class="n"><a id="t172" href="#t172">172</a></span><span class="t"> <span class="com"># Prevent common SSRF targets</span> </span><span class="r"></span></p>
|
|
255
|
-
<p class="mis show_mis"><span class="n"><a id="t173" href="#t173">173</a></span><span class="t"> <span class="key">if</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">hostname</span> <span class="key">in</span> <span class="op">(</span><span class="str">"localhost"</span><span class="op">,</span> <span class="str">"127.0.0.1"</span><span class="op">,</span> <span class="str">"0.0.0.0"</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
256
|
-
<p class="mis show_mis"><span class="n"><a id="t174" href="#t174">174</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_production</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
257
|
-
<p class="mis show_mis"><span class="n"><a id="t175" href="#t175">175</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Base URL cannot use localhost/loopback addresses in production: '{url}'"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
258
|
-
<p class="pln"><span class="n"><a id="t176" href="#t176">176</a></span><span class="t"> </span><span class="r"></span></p>
|
|
259
|
-
<p class="mis show_mis"><span class="n"><a id="t177" href="#t177">177</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
260
|
-
<p class="mis show_mis"><span class="n"><a id="t178" href="#t178">178</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">e</span><span class="op">,</span> <span class="nam">ValueError</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
261
|
-
<p class="mis show_mis"><span class="n"><a id="t179" href="#t179">179</a></span><span class="t"> <span class="key">raise</span> </span><span class="r"></span></p>
|
|
262
|
-
<p class="mis show_mis"><span class="n"><a id="t180" href="#t180">180</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid base URL '{url}': {e}"</span><span class="op">)</span> <span class="key">from</span> <span class="nam">e</span> </span><span class="r"></span></p>
|
|
263
|
-
<p class="pln"><span class="n"><a id="t181" href="#t181">181</a></span><span class="t"> </span><span class="r"></span></p>
|
|
264
|
-
<p class="mis show_mis"><span class="n"><a id="t182" href="#t182">182</a></span><span class="t"> <span class="key">return</span> <span class="nam">url</span> </span><span class="r"></span></p>
|
|
265
|
-
<p class="pln"><span class="n"><a id="t183" href="#t183">183</a></span><span class="t"> </span><span class="r"></span></p>
|
|
266
|
-
<p class="mis show_mis"><span class="n"><a id="t184" href="#t184">184</a></span><span class="t"> <span class="op">@</span><span class="nam">field_validator</span><span class="op">(</span><span class="str">"issuer_url"</span><span class="op">,</span> <span class="str">"service_documentation_url"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
267
|
-
<p class="mis show_mis"><span class="n"><a id="t185" href="#t185">185</a></span><span class="t"> <span class="op">@</span><span class="nam">classmethod</span> </span><span class="r"></span></p>
|
|
268
|
-
<p class="mis show_mis"><span class="n"><a id="t186" href="#t186">186</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_optional_urls</span><span class="op">(</span><span class="nam">cls</span><span class="op">,</span> <span class="nam">v</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
269
|
-
<p class="pln"><span class="n"><a id="t187" href="#t187">187</a></span><span class="t"> <span class="str">"""Validate optional URLs for security and format compliance."""</span> </span><span class="r"></span></p>
|
|
270
|
-
<p class="mis show_mis"><span class="n"><a id="t188" href="#t188">188</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">v</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
271
|
-
<p class="mis show_mis"><span class="n"><a id="t189" href="#t189">189</a></span><span class="t"> <span class="key">return</span> <span class="nam">v</span> </span><span class="r"></span></p>
|
|
272
|
-
<p class="pln"><span class="n"><a id="t190" href="#t190">190</a></span><span class="t"> </span><span class="r"></span></p>
|
|
273
|
-
<p class="mis show_mis"><span class="n"><a id="t191" href="#t191">191</a></span><span class="t"> <span class="nam">url</span> <span class="op">=</span> <span class="nam">v</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
274
|
-
<p class="mis show_mis"><span class="n"><a id="t192" href="#t192">192</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">url</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
275
|
-
<p class="mis show_mis"><span class="n"><a id="t193" href="#t193">193</a></span><span class="t"> <span class="key">return</span> <span class="key">None</span> </span><span class="r"></span></p>
|
|
276
|
-
<p class="pln"><span class="n"><a id="t194" href="#t194">194</a></span><span class="t"> </span><span class="r"></span></p>
|
|
277
|
-
<p class="mis show_mis"><span class="n"><a id="t195" href="#t195">195</a></span><span class="t"> <span class="key">try</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
278
|
-
<p class="mis show_mis"><span class="n"><a id="t196" href="#t196">196</a></span><span class="t"> <span class="nam">parsed</span> <span class="op">=</span> <span class="nam">urlparse</span><span class="op">(</span><span class="nam">url</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
279
|
-
<p class="mis show_mis"><span class="n"><a id="t197" href="#t197">197</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">netloc</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
280
|
-
<p class="mis show_mis"><span class="n"><a id="t198" href="#t198">198</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid URL format: '{url}' - must include scheme and netloc"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
281
|
-
<p class="pln"><span class="n"><a id="t199" href="#t199">199</a></span><span class="t"> </span><span class="r"></span></p>
|
|
282
|
-
<p class="mis show_mis"><span class="n"><a id="t200" href="#t200">200</a></span><span class="t"> <span class="key">if</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">not</span> <span class="key">in</span> <span class="op">(</span><span class="str">"http"</span><span class="op">,</span> <span class="str">"https"</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
283
|
-
<p class="mis show_mis"><span class="n"><a id="t201" href="#t201">201</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"URL must use http or https scheme: '{url}'"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
284
|
-
<p class="pln"><span class="n"><a id="t202" href="#t202">202</a></span><span class="t"> </span><span class="r"></span></p>
|
|
285
|
-
<p class="pln"><span class="n"><a id="t203" href="#t203">203</a></span><span class="t"> <span class="com"># Check for HTTPS requirement in production for issuer URL</span> </span><span class="r"></span></p>
|
|
286
|
-
<p class="mis show_mis"><span class="n"><a id="t204" href="#t204">204</a></span><span class="t"> <span class="key">if</span> <span class="nam">v</span> <span class="op">==</span> <span class="nam">cls</span><span class="op">.</span><span class="nam">__dict__</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"issuer_url"</span><span class="op">)</span><span class="op">:</span> <span class="com"># This is the issuer_url field</span> </span><span class="r"></span></p>
|
|
287
|
-
<p class="mis show_mis"><span class="n"><a id="t205" href="#t205">205</a></span><span class="t"> <span class="nam">is_production</span> <span class="op">=</span> <span class="op">(</span> </span><span class="r"></span></p>
|
|
288
|
-
<p class="pln"><span class="n"><a id="t206" href="#t206">206</a></span><span class="t"> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"GOLF_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
289
|
-
<p class="pln"><span class="n"><a id="t207" href="#t207">207</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"NODE_ENV"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="op">==</span> <span class="str">"production"</span> </span><span class="r"></span></p>
|
|
290
|
-
<p class="pln"><span class="n"><a id="t208" href="#t208">208</a></span><span class="t"> <span class="key">or</span> <span class="nam">os</span><span class="op">.</span><span class="nam">environ</span><span class="op">.</span><span class="nam">get</span><span class="op">(</span><span class="str">"ENVIRONMENT"</span><span class="op">,</span> <span class="str">""</span><span class="op">)</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="op">(</span><span class="str">"prod"</span><span class="op">,</span> <span class="str">"production"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
291
|
-
<p class="pln"><span class="n"><a id="t209" href="#t209">209</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
292
|
-
<p class="pln"><span class="n"><a id="t210" href="#t210">210</a></span><span class="t"> </span><span class="r"></span></p>
|
|
293
|
-
<p class="mis show_mis"><span class="n"><a id="t211" href="#t211">211</a></span><span class="t"> <span class="key">if</span> <span class="nam">is_production</span> <span class="key">and</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="op">==</span> <span class="str">"http"</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
294
|
-
<p class="mis show_mis"><span class="n"><a id="t212" href="#t212">212</a></span><span class="t"> <span class="key">import</span> <span class="nam">warnings</span> </span><span class="r"></span></p>
|
|
295
|
-
<p class="pln"><span class="n"><a id="t213" href="#t213">213</a></span><span class="t"> </span><span class="r"></span></p>
|
|
296
|
-
<p class="mis show_mis"><span class="n"><a id="t214" href="#t214">214</a></span><span class="t"> <span class="nam">warnings</span><span class="op">.</span><span class="nam">warn</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
297
|
-
<p class="pln"><span class="n"><a id="t215" href="#t215">215</a></span><span class="t"> <span class="str">f"Issuer URL '{url}' uses HTTP in production. HTTPS is required for OAuth issuer URLs."</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
298
|
-
<p class="pln"><span class="n"><a id="t216" href="#t216">216</a></span><span class="t"> <span class="nam">UserWarning</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
299
|
-
<p class="pln"><span class="n"><a id="t217" href="#t217">217</a></span><span class="t"> <span class="nam">stacklevel</span><span class="op">=</span><span class="num">2</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
300
|
-
<p class="pln"><span class="n"><a id="t218" href="#t218">218</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
301
|
-
<p class="pln"><span class="n"><a id="t219" href="#t219">219</a></span><span class="t"> </span><span class="r"></span></p>
|
|
302
|
-
<p class="mis show_mis"><span class="n"><a id="t220" href="#t220">220</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
303
|
-
<p class="mis show_mis"><span class="n"><a id="t221" href="#t221">221</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">e</span><span class="op">,</span> <span class="nam">ValueError</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
304
|
-
<p class="mis show_mis"><span class="n"><a id="t222" href="#t222">222</a></span><span class="t"> <span class="key">raise</span> </span><span class="r"></span></p>
|
|
305
|
-
<p class="mis show_mis"><span class="n"><a id="t223" href="#t223">223</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid URL '{url}': {e}"</span><span class="op">)</span> <span class="key">from</span> <span class="nam">e</span> </span><span class="r"></span></p>
|
|
306
|
-
<p class="pln"><span class="n"><a id="t224" href="#t224">224</a></span><span class="t"> </span><span class="r"></span></p>
|
|
307
|
-
<p class="mis show_mis"><span class="n"><a id="t225" href="#t225">225</a></span><span class="t"> <span class="key">return</span> <span class="nam">url</span> </span><span class="r"></span></p>
|
|
308
|
-
<p class="pln"><span class="n"><a id="t226" href="#t226">226</a></span><span class="t"> </span><span class="r"></span></p>
|
|
309
|
-
<p class="mis show_mis"><span class="n"><a id="t227" href="#t227">227</a></span><span class="t"> <span class="op">@</span><span class="nam">field_validator</span><span class="op">(</span><span class="str">"valid_scopes"</span><span class="op">,</span> <span class="str">"default_scopes"</span><span class="op">,</span> <span class="str">"required_scopes"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
310
|
-
<p class="mis show_mis"><span class="n"><a id="t228" href="#t228">228</a></span><span class="t"> <span class="op">@</span><span class="nam">classmethod</span> </span><span class="r"></span></p>
|
|
311
|
-
<p class="mis show_mis"><span class="n"><a id="t229" href="#t229">229</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_scopes</span><span class="op">(</span><span class="nam">cls</span><span class="op">,</span> <span class="nam">v</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span><span class="op">)</span> <span class="op">-></span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
312
|
-
<p class="pln"><span class="n"><a id="t230" href="#t230">230</a></span><span class="t"> <span class="str">"""Validate OAuth 2.0 scopes format and security."""</span> </span><span class="r"></span></p>
|
|
313
|
-
<p class="mis show_mis"><span class="n"><a id="t231" href="#t231">231</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">v</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
314
|
-
<p class="mis show_mis"><span class="n"><a id="t232" href="#t232">232</a></span><span class="t"> <span class="key">return</span> <span class="nam">v</span> </span><span class="r"></span></p>
|
|
315
|
-
<p class="pln"><span class="n"><a id="t233" href="#t233">233</a></span><span class="t"> </span><span class="r"></span></p>
|
|
316
|
-
<p class="mis show_mis"><span class="n"><a id="t234" href="#t234">234</a></span><span class="t"> <span class="nam">valid_scopes</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span> </span><span class="r"></span></p>
|
|
317
|
-
<p class="mis show_mis"><span class="n"><a id="t235" href="#t235">235</a></span><span class="t"> <span class="key">for</span> <span class="nam">scope</span> <span class="key">in</span> <span class="nam">v</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
318
|
-
<p class="mis show_mis"><span class="n"><a id="t236" href="#t236">236</a></span><span class="t"> <span class="nam">scope</span> <span class="op">=</span> <span class="nam">scope</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
319
|
-
<p class="mis show_mis"><span class="n"><a id="t237" href="#t237">237</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">scope</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
320
|
-
<p class="mis show_mis"><span class="n"><a id="t238" href="#t238">238</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"Scopes cannot be empty or whitespace-only"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
321
|
-
<p class="pln"><span class="n"><a id="t239" href="#t239">239</a></span><span class="t"> </span><span class="r"></span></p>
|
|
322
|
-
<p class="pln"><span class="n"><a id="t240" href="#t240">240</a></span><span class="t"> <span class="com"># OAuth 2.0 scope format validation (RFC 6749)</span> </span><span class="r"></span></p>
|
|
323
|
-
<p class="pln"><span class="n"><a id="t241" href="#t241">241</a></span><span class="t"> <span class="com"># Scopes should be ASCII printable characters except space, and no control characters</span> </span><span class="r"></span></p>
|
|
324
|
-
<p class="mis show_mis"><span class="n"><a id="t242" href="#t242">242</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">all</span><span class="op">(</span><span class="num">32</span> <span class="op"><</span> <span class="nam">ord</span><span class="op">(</span><span class="nam">c</span><span class="op">)</span> <span class="op"><</span> <span class="num">127</span> <span class="key">and</span> <span class="nam">c</span> <span class="key">not</span> <span class="key">in</span> <span class="str">' "\\'</span> <span class="key">for</span> <span class="nam">c</span> <span class="key">in</span> <span class="nam">scope</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
325
|
-
<p class="mis show_mis"><span class="n"><a id="t243" href="#t243">243</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
326
|
-
<p class="pln"><span class="n"><a id="t244" href="#t244">244</a></span><span class="t"> <span class="str">f"Invalid scope format: '{scope}' - must be ASCII printable without spaces, quotes, or backslashes"</span> </span><span class="r"></span></p>
|
|
327
|
-
<p class="pln"><span class="n"><a id="t245" href="#t245">245</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
328
|
-
<p class="pln"><span class="n"><a id="t246" href="#t246">246</a></span><span class="t"> </span><span class="r"></span></p>
|
|
329
|
-
<p class="pln"><span class="n"><a id="t247" href="#t247">247</a></span><span class="t"> <span class="com"># Reasonable length limit to prevent abuse</span> </span><span class="r"></span></p>
|
|
330
|
-
<p class="mis show_mis"><span class="n"><a id="t248" href="#t248">248</a></span><span class="t"> <span class="key">if</span> <span class="nam">len</span><span class="op">(</span><span class="nam">scope</span><span class="op">)</span> <span class="op">></span> <span class="num">128</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
331
|
-
<p class="mis show_mis"><span class="n"><a id="t249" href="#t249">249</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Scope too long: '{scope}' - maximum 128 characters"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
332
|
-
<p class="pln"><span class="n"><a id="t250" href="#t250">250</a></span><span class="t"> </span><span class="r"></span></p>
|
|
333
|
-
<p class="pln"><span class="n"><a id="t251" href="#t251">251</a></span><span class="t"> <span class="com"># Prevent potentially dangerous scope names</span> </span><span class="r"></span></p>
|
|
334
|
-
<p class="mis show_mis"><span class="n"><a id="t252" href="#t252">252</a></span><span class="t"> <span class="nam">dangerous_scopes</span> <span class="op">=</span> <span class="op">{</span><span class="str">"admin"</span><span class="op">,</span> <span class="str">"root"</span><span class="op">,</span> <span class="str">"superuser"</span><span class="op">,</span> <span class="str">"system"</span><span class="op">,</span> <span class="str">"*"</span><span class="op">,</span> <span class="str">"all"</span><span class="op">}</span> </span><span class="r"></span></p>
|
|
335
|
-
<p class="mis show_mis"><span class="n"><a id="t253" href="#t253">253</a></span><span class="t"> <span class="key">if</span> <span class="nam">scope</span><span class="op">.</span><span class="nam">lower</span><span class="op">(</span><span class="op">)</span> <span class="key">in</span> <span class="nam">dangerous_scopes</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
336
|
-
<p class="mis show_mis"><span class="n"><a id="t254" href="#t254">254</a></span><span class="t"> <span class="key">import</span> <span class="nam">warnings</span> </span><span class="r"></span></p>
|
|
337
|
-
<p class="pln"><span class="n"><a id="t255" href="#t255">255</a></span><span class="t"> </span><span class="r"></span></p>
|
|
338
|
-
<p class="mis show_mis"><span class="n"><a id="t256" href="#t256">256</a></span><span class="t"> <span class="nam">warnings</span><span class="op">.</span><span class="nam">warn</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
339
|
-
<p class="pln"><span class="n"><a id="t257" href="#t257">257</a></span><span class="t"> <span class="str">f"Potentially dangerous scope detected: '{scope}'. "</span> </span><span class="r"></span></p>
|
|
340
|
-
<p class="pln"><span class="n"><a id="t258" href="#t258">258</a></span><span class="t"> <span class="str">"Consider using more specific, principle-of-least-privilege scopes."</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
341
|
-
<p class="pln"><span class="n"><a id="t259" href="#t259">259</a></span><span class="t"> <span class="nam">UserWarning</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
342
|
-
<p class="pln"><span class="n"><a id="t260" href="#t260">260</a></span><span class="t"> <span class="nam">stacklevel</span><span class="op">=</span><span class="num">2</span><span class="op">,</span> </span><span class="r"></span></p>
|
|
343
|
-
<p class="pln"><span class="n"><a id="t261" href="#t261">261</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
344
|
-
<p class="pln"><span class="n"><a id="t262" href="#t262">262</a></span><span class="t"> </span><span class="r"></span></p>
|
|
345
|
-
<p class="mis show_mis"><span class="n"><a id="t263" href="#t263">263</a></span><span class="t"> <span class="nam">valid_scopes</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">scope</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
346
|
-
<p class="pln"><span class="n"><a id="t264" href="#t264">264</a></span><span class="t"> </span><span class="r"></span></p>
|
|
347
|
-
<p class="mis show_mis"><span class="n"><a id="t265" href="#t265">265</a></span><span class="t"> <span class="key">return</span> <span class="nam">valid_scopes</span> </span><span class="r"></span></p>
|
|
348
|
-
<p class="pln"><span class="n"><a id="t266" href="#t266">266</a></span><span class="t"> </span><span class="r"></span></p>
|
|
349
|
-
<p class="mis show_mis"><span class="n"><a id="t267" href="#t267">267</a></span><span class="t"> <span class="op">@</span><span class="nam">model_validator</span><span class="op">(</span><span class="nam">mode</span><span class="op">=</span><span class="str">"after"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
350
|
-
<p class="mis show_mis"><span class="n"><a id="t268" href="#t268">268</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_oauth_server_config</span><span class="op">(</span><span class="nam">self</span><span class="op">)</span> <span class="op">-></span> <span class="str">"OAuthServerConfig"</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
351
|
-
<p class="pln"><span class="n"><a id="t269" href="#t269">269</a></span><span class="t"> <span class="str">"""Validate OAuth server configuration for security and consistency."""</span> </span><span class="r"></span></p>
|
|
352
|
-
<p class="pln"><span class="n"><a id="t270" href="#t270">270</a></span><span class="t"> <span class="com"># Validate default_scopes are subset of valid_scopes</span> </span><span class="r"></span></p>
|
|
353
|
-
<p class="mis show_mis"><span class="n"><a id="t271" href="#t271">271</a></span><span class="t"> <span class="key">if</span> <span class="nam">self</span><span class="op">.</span><span class="nam">default_scopes</span> <span class="key">and</span> <span class="nam">self</span><span class="op">.</span><span class="nam">valid_scopes</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
354
|
-
<p class="mis show_mis"><span class="n"><a id="t272" href="#t272">272</a></span><span class="t"> <span class="nam">invalid_defaults</span> <span class="op">=</span> <span class="nam">set</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">default_scopes</span><span class="op">)</span> <span class="op">-</span> <span class="nam">set</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">valid_scopes</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
355
|
-
<p class="mis show_mis"><span class="n"><a id="t273" href="#t273">273</a></span><span class="t"> <span class="key">if</span> <span class="nam">invalid_defaults</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
356
|
-
<p class="mis show_mis"><span class="n"><a id="t274" href="#t274">274</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"default_scopes contains invalid scopes not in valid_scopes: {invalid_defaults}"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
357
|
-
<p class="pln"><span class="n"><a id="t275" href="#t275">275</a></span><span class="t"> </span><span class="r"></span></p>
|
|
358
|
-
<p class="pln"><span class="n"><a id="t276" href="#t276">276</a></span><span class="t"> <span class="com"># Validate required_scopes are subset of valid_scopes</span> </span><span class="r"></span></p>
|
|
359
|
-
<p class="mis show_mis"><span class="n"><a id="t277" href="#t277">277</a></span><span class="t"> <span class="key">if</span> <span class="nam">self</span><span class="op">.</span><span class="nam">required_scopes</span> <span class="key">and</span> <span class="nam">self</span><span class="op">.</span><span class="nam">valid_scopes</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
360
|
-
<p class="mis show_mis"><span class="n"><a id="t278" href="#t278">278</a></span><span class="t"> <span class="nam">invalid_required</span> <span class="op">=</span> <span class="nam">set</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">required_scopes</span><span class="op">)</span> <span class="op">-</span> <span class="nam">set</span><span class="op">(</span><span class="nam">self</span><span class="op">.</span><span class="nam">valid_scopes</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
361
|
-
<p class="mis show_mis"><span class="n"><a id="t279" href="#t279">279</a></span><span class="t"> <span class="key">if</span> <span class="nam">invalid_required</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
362
|
-
<p class="mis show_mis"><span class="n"><a id="t280" href="#t280">280</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"required_scopes contains invalid scopes not in valid_scopes: {invalid_required}"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
363
|
-
<p class="pln"><span class="n"><a id="t281" href="#t281">281</a></span><span class="t"> </span><span class="r"></span></p>
|
|
364
|
-
<p class="mis show_mis"><span class="n"><a id="t282" href="#t282">282</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span> </span><span class="r"></span></p>
|
|
365
|
-
<p class="pln"><span class="n"><a id="t283" href="#t283">283</a></span><span class="t"> </span><span class="r"></span></p>
|
|
366
|
-
<p class="pln"><span class="n"><a id="t284" href="#t284">284</a></span><span class="t"> </span><span class="r"></span></p>
|
|
367
|
-
<p class="mis show_mis"><span class="n"><a id="t285" href="#t285">285</a></span><span class="t"><span class="key">class</span> <span class="nam">RemoteAuthConfig</span><span class="op">(</span><span class="nam">BaseModel</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
368
|
-
<p class="pln"><span class="n"><a id="t286" href="#t286">286</a></span><span class="t"> <span class="str">"""Configuration for remote authorization server integration.</span> </span><span class="r"></span></p>
|
|
369
|
-
<p class="pln"><span class="n"><a id="t287" href="#t287">287</a></span><span class="t"> </span><span class="r"></span></p>
|
|
370
|
-
<p class="pln"><span class="n"><a id="t288" href="#t288">288</a></span><span class="t"><span class="str"> Use this when you have token verification logic and want to advertise</span> </span><span class="r"></span></p>
|
|
371
|
-
<p class="pln"><span class="n"><a id="t289" href="#t289">289</a></span><span class="t"><span class="str"> the authorization servers that issue valid tokens (RFC 9728 compliance).</span> </span><span class="r"></span></p>
|
|
372
|
-
<p class="pln"><span class="n"><a id="t290" href="#t290">290</a></span><span class="t"><span class="str"> """</span> </span><span class="r"></span></p>
|
|
373
|
-
<p class="pln"><span class="n"><a id="t291" href="#t291">291</a></span><span class="t"> </span><span class="r"></span></p>
|
|
374
|
-
<p class="mis show_mis"><span class="n"><a id="t292" href="#t292">292</a></span><span class="t"> <span class="nam">provider_type</span><span class="op">:</span> <span class="nam">Literal</span><span class="op">[</span><span class="str">"remote"</span><span class="op">]</span> <span class="op">=</span> <span class="str">"remote"</span> </span><span class="r"></span></p>
|
|
375
|
-
<p class="pln"><span class="n"><a id="t293" href="#t293">293</a></span><span class="t"> </span><span class="r"></span></p>
|
|
376
|
-
<p class="pln"><span class="n"><a id="t294" href="#t294">294</a></span><span class="t"> <span class="com"># Authorization servers that issue tokens</span> </span><span class="r"></span></p>
|
|
377
|
-
<p class="mis show_mis"><span class="n"><a id="t295" href="#t295">295</a></span><span class="t"> <span class="nam">authorization_servers</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
378
|
-
<p class="pln"><span class="n"><a id="t296" href="#t296">296</a></span><span class="t"> <span class="op">...</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"List of authorization server URLs that issue valid tokens"</span> </span><span class="r"></span></p>
|
|
379
|
-
<p class="pln"><span class="n"><a id="t297" href="#t297">297</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
380
|
-
<p class="pln"><span class="n"><a id="t298" href="#t298">298</a></span><span class="t"> </span><span class="r"></span></p>
|
|
381
|
-
<p class="pln"><span class="n"><a id="t299" href="#t299">299</a></span><span class="t"> <span class="com"># This server's URL</span> </span><span class="r"></span></p>
|
|
382
|
-
<p class="mis show_mis"><span class="n"><a id="t300" href="#t300">300</a></span><span class="t"> <span class="nam">resource_server_url</span><span class="op">:</span> <span class="nam">str</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span><span class="op">...</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"URL of this resource server"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
383
|
-
<p class="pln"><span class="n"><a id="t301" href="#t301">301</a></span><span class="t"> </span><span class="r"></span></p>
|
|
384
|
-
<p class="pln"><span class="n"><a id="t302" href="#t302">302</a></span><span class="t"> <span class="com"># Token verification (delegate to another config)</span> </span><span class="r"></span></p>
|
|
385
|
-
<p class="mis show_mis"><span class="n"><a id="t303" href="#t303">303</a></span><span class="t"> <span class="nam">token_verifier_config</span><span class="op">:</span> <span class="nam">JWTAuthConfig</span> <span class="op">|</span> <span class="nam">StaticTokenConfig</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
386
|
-
<p class="pln"><span class="n"><a id="t304" href="#t304">304</a></span><span class="t"> <span class="op">...</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Configuration for the underlying token verifier"</span> </span><span class="r"></span></p>
|
|
387
|
-
<p class="pln"><span class="n"><a id="t305" href="#t305">305</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
388
|
-
<p class="pln"><span class="n"><a id="t306" href="#t306">306</a></span><span class="t"> </span><span class="r"></span></p>
|
|
389
|
-
<p class="pln"><span class="n"><a id="t307" href="#t307">307</a></span><span class="t"> <span class="com"># Environment variable names for runtime configuration</span> </span><span class="r"></span></p>
|
|
390
|
-
<p class="mis show_mis"><span class="n"><a id="t308" href="#t308">308</a></span><span class="t"> <span class="nam">authorization_servers_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
391
|
-
<p class="pln"><span class="n"><a id="t309" href="#t309">309</a></span><span class="t"> <span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for comma-separated authorization server URLs"</span> </span><span class="r"></span></p>
|
|
392
|
-
<p class="pln"><span class="n"><a id="t310" href="#t310">310</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
393
|
-
<p class="mis show_mis"><span class="n"><a id="t311" href="#t311">311</a></span><span class="t"> <span class="nam">resource_server_url_env_var</span><span class="op">:</span> <span class="nam">str</span> <span class="op">|</span> <span class="key">None</span> <span class="op">=</span> <span class="nam">Field</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
394
|
-
<p class="pln"><span class="n"><a id="t312" href="#t312">312</a></span><span class="t"> <span class="key">None</span><span class="op">,</span> <span class="nam">description</span><span class="op">=</span><span class="str">"Environment variable name for resource server URL"</span> </span><span class="r"></span></p>
|
|
395
|
-
<p class="pln"><span class="n"><a id="t313" href="#t313">313</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
396
|
-
<p class="pln"><span class="n"><a id="t314" href="#t314">314</a></span><span class="t"> </span><span class="r"></span></p>
|
|
397
|
-
<p class="mis show_mis"><span class="n"><a id="t315" href="#t315">315</a></span><span class="t"> <span class="op">@</span><span class="nam">field_validator</span><span class="op">(</span><span class="str">"authorization_servers"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
398
|
-
<p class="mis show_mis"><span class="n"><a id="t316" href="#t316">316</a></span><span class="t"> <span class="op">@</span><span class="nam">classmethod</span> </span><span class="r"></span></p>
|
|
399
|
-
<p class="mis show_mis"><span class="n"><a id="t317" href="#t317">317</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_authorization_servers</span><span class="op">(</span><span class="nam">cls</span><span class="op">,</span> <span class="nam">v</span><span class="op">:</span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span><span class="op">)</span> <span class="op">-></span> <span class="nam">list</span><span class="op">[</span><span class="nam">str</span><span class="op">]</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
400
|
-
<p class="pln"><span class="n"><a id="t318" href="#t318">318</a></span><span class="t"> <span class="str">"""Validate authorization servers are non-empty and valid URLs."""</span> </span><span class="r"></span></p>
|
|
401
|
-
<p class="mis show_mis"><span class="n"><a id="t319" href="#t319">319</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">v</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
402
|
-
<p class="mis show_mis"><span class="n"><a id="t320" href="#t320">320</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
403
|
-
<p class="pln"><span class="n"><a id="t321" href="#t321">321</a></span><span class="t"> <span class="str">"authorization_servers cannot be empty - at least one authorization server URL is required"</span> </span><span class="r"></span></p>
|
|
404
|
-
<p class="pln"><span class="n"><a id="t322" href="#t322">322</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
405
|
-
<p class="pln"><span class="n"><a id="t323" href="#t323">323</a></span><span class="t"> </span><span class="r"></span></p>
|
|
406
|
-
<p class="mis show_mis"><span class="n"><a id="t324" href="#t324">324</a></span><span class="t"> <span class="nam">valid_urls</span> <span class="op">=</span> <span class="op">[</span><span class="op">]</span> </span><span class="r"></span></p>
|
|
407
|
-
<p class="mis show_mis"><span class="n"><a id="t325" href="#t325">325</a></span><span class="t"> <span class="key">for</span> <span class="nam">url</span> <span class="key">in</span> <span class="nam">v</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
408
|
-
<p class="mis show_mis"><span class="n"><a id="t326" href="#t326">326</a></span><span class="t"> <span class="nam">url</span> <span class="op">=</span> <span class="nam">url</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
409
|
-
<p class="mis show_mis"><span class="n"><a id="t327" href="#t327">327</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">url</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
410
|
-
<p class="mis show_mis"><span class="n"><a id="t328" href="#t328">328</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"authorization_servers cannot contain empty URLs"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
411
|
-
<p class="pln"><span class="n"><a id="t329" href="#t329">329</a></span><span class="t"> </span><span class="r"></span></p>
|
|
412
|
-
<p class="pln"><span class="n"><a id="t330" href="#t330">330</a></span><span class="t"> <span class="com"># Validate URL format</span> </span><span class="r"></span></p>
|
|
413
|
-
<p class="mis show_mis"><span class="n"><a id="t331" href="#t331">331</a></span><span class="t"> <span class="key">try</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
414
|
-
<p class="mis show_mis"><span class="n"><a id="t332" href="#t332">332</a></span><span class="t"> <span class="nam">parsed</span> <span class="op">=</span> <span class="nam">urlparse</span><span class="op">(</span><span class="nam">url</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
415
|
-
<p class="mis show_mis"><span class="n"><a id="t333" href="#t333">333</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">netloc</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
416
|
-
<p class="mis show_mis"><span class="n"><a id="t334" href="#t334">334</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
417
|
-
<p class="pln"><span class="n"><a id="t335" href="#t335">335</a></span><span class="t"> <span class="str">f"Invalid URL format for authorization server: '{url}' - must include scheme and netloc"</span> </span><span class="r"></span></p>
|
|
418
|
-
<p class="pln"><span class="n"><a id="t336" href="#t336">336</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
419
|
-
<p class="mis show_mis"><span class="n"><a id="t337" href="#t337">337</a></span><span class="t"> <span class="key">if</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">not</span> <span class="key">in</span> <span class="op">(</span><span class="str">"http"</span><span class="op">,</span> <span class="str">"https"</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
420
|
-
<p class="mis show_mis"><span class="n"><a id="t338" href="#t338">338</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Authorization server URL must use http or https scheme: '{url}'"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
421
|
-
<p class="mis show_mis"><span class="n"><a id="t339" href="#t339">339</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
422
|
-
<p class="mis show_mis"><span class="n"><a id="t340" href="#t340">340</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid authorization server URL '{url}': {e}"</span><span class="op">)</span> <span class="key">from</span> <span class="nam">e</span> </span><span class="r"></span></p>
|
|
423
|
-
<p class="pln"><span class="n"><a id="t341" href="#t341">341</a></span><span class="t"> </span><span class="r"></span></p>
|
|
424
|
-
<p class="mis show_mis"><span class="n"><a id="t342" href="#t342">342</a></span><span class="t"> <span class="nam">valid_urls</span><span class="op">.</span><span class="nam">append</span><span class="op">(</span><span class="nam">url</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
425
|
-
<p class="pln"><span class="n"><a id="t343" href="#t343">343</a></span><span class="t"> </span><span class="r"></span></p>
|
|
426
|
-
<p class="mis show_mis"><span class="n"><a id="t344" href="#t344">344</a></span><span class="t"> <span class="key">return</span> <span class="nam">valid_urls</span> </span><span class="r"></span></p>
|
|
427
|
-
<p class="pln"><span class="n"><a id="t345" href="#t345">345</a></span><span class="t"> </span><span class="r"></span></p>
|
|
428
|
-
<p class="mis show_mis"><span class="n"><a id="t346" href="#t346">346</a></span><span class="t"> <span class="op">@</span><span class="nam">field_validator</span><span class="op">(</span><span class="str">"resource_server_url"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
429
|
-
<p class="mis show_mis"><span class="n"><a id="t347" href="#t347">347</a></span><span class="t"> <span class="op">@</span><span class="nam">classmethod</span> </span><span class="r"></span></p>
|
|
430
|
-
<p class="mis show_mis"><span class="n"><a id="t348" href="#t348">348</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_resource_server_url</span><span class="op">(</span><span class="nam">cls</span><span class="op">,</span> <span class="nam">v</span><span class="op">:</span> <span class="nam">str</span><span class="op">)</span> <span class="op">-></span> <span class="nam">str</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
431
|
-
<p class="pln"><span class="n"><a id="t349" href="#t349">349</a></span><span class="t"> <span class="str">"""Validate resource server URL is a valid URL."""</span> </span><span class="r"></span></p>
|
|
432
|
-
<p class="mis show_mis"><span class="n"><a id="t350" href="#t350">350</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">v</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">v</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
433
|
-
<p class="mis show_mis"><span class="n"><a id="t351" href="#t351">351</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"resource_server_url cannot be empty"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
434
|
-
<p class="pln"><span class="n"><a id="t352" href="#t352">352</a></span><span class="t"> </span><span class="r"></span></p>
|
|
435
|
-
<p class="mis show_mis"><span class="n"><a id="t353" href="#t353">353</a></span><span class="t"> <span class="nam">url</span> <span class="op">=</span> <span class="nam">v</span><span class="op">.</span><span class="nam">strip</span><span class="op">(</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
436
|
-
<p class="mis show_mis"><span class="n"><a id="t354" href="#t354">354</a></span><span class="t"> <span class="key">try</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
437
|
-
<p class="mis show_mis"><span class="n"><a id="t355" href="#t355">355</a></span><span class="t"> <span class="nam">parsed</span> <span class="op">=</span> <span class="nam">urlparse</span><span class="op">(</span><span class="nam">url</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
438
|
-
<p class="mis show_mis"><span class="n"><a id="t356" href="#t356">356</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">or</span> <span class="key">not</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">netloc</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
439
|
-
<p class="mis show_mis"><span class="n"><a id="t357" href="#t357">357</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid URL format for resource server: '{url}' - must include scheme and netloc"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
440
|
-
<p class="mis show_mis"><span class="n"><a id="t358" href="#t358">358</a></span><span class="t"> <span class="key">if</span> <span class="nam">parsed</span><span class="op">.</span><span class="nam">scheme</span> <span class="key">not</span> <span class="key">in</span> <span class="op">(</span><span class="str">"http"</span><span class="op">,</span> <span class="str">"https"</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
441
|
-
<p class="mis show_mis"><span class="n"><a id="t359" href="#t359">359</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Resource server URL must use http or https scheme: '{url}'"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
442
|
-
<p class="mis show_mis"><span class="n"><a id="t360" href="#t360">360</a></span><span class="t"> <span class="key">except</span> <span class="nam">Exception</span> <span class="key">as</span> <span class="nam">e</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
443
|
-
<p class="mis show_mis"><span class="n"><a id="t361" href="#t361">361</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">f"Invalid resource server URL '{url}': {e}"</span><span class="op">)</span> <span class="key">from</span> <span class="nam">e</span> </span><span class="r"></span></p>
|
|
444
|
-
<p class="pln"><span class="n"><a id="t362" href="#t362">362</a></span><span class="t"> </span><span class="r"></span></p>
|
|
445
|
-
<p class="mis show_mis"><span class="n"><a id="t363" href="#t363">363</a></span><span class="t"> <span class="key">return</span> <span class="nam">url</span> </span><span class="r"></span></p>
|
|
446
|
-
<p class="pln"><span class="n"><a id="t364" href="#t364">364</a></span><span class="t"> </span><span class="r"></span></p>
|
|
447
|
-
<p class="mis show_mis"><span class="n"><a id="t365" href="#t365">365</a></span><span class="t"> <span class="op">@</span><span class="nam">model_validator</span><span class="op">(</span><span class="nam">mode</span><span class="op">=</span><span class="str">"after"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
448
|
-
<p class="mis show_mis"><span class="n"><a id="t366" href="#t366">366</a></span><span class="t"> <span class="key">def</span> <span class="nam">validate_token_verifier_compatibility</span><span class="op">(</span><span class="nam">self</span><span class="op">)</span> <span class="op">-></span> <span class="str">"RemoteAuthConfig"</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
449
|
-
<p class="pln"><span class="n"><a id="t367" href="#t367">367</a></span><span class="t"> <span class="str">"""Validate that the token verifier config is compatible with token verification."""</span> </span><span class="r"></span></p>
|
|
450
|
-
<p class="pln"><span class="n"><a id="t368" href="#t368">368</a></span><span class="t"> <span class="com"># The duck-typing check is already handled by the factory function, but we can</span> </span><span class="r"></span></p>
|
|
451
|
-
<p class="pln"><span class="n"><a id="t369" href="#t369">369</a></span><span class="t"> <span class="com"># add a basic sanity check here that the config types are ones we know work</span> </span><span class="r"></span></p>
|
|
452
|
-
<p class="mis show_mis"><span class="n"><a id="t370" href="#t370">370</a></span><span class="t"> <span class="nam">config</span> <span class="op">=</span> <span class="nam">self</span><span class="op">.</span><span class="nam">token_verifier_config</span> </span><span class="r"></span></p>
|
|
453
|
-
<p class="pln"><span class="n"><a id="t371" href="#t371">371</a></span><span class="t"> </span><span class="r"></span></p>
|
|
454
|
-
<p class="mis show_mis"><span class="n"><a id="t372" href="#t372">372</a></span><span class="t"> <span class="key">if</span> <span class="key">not</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">config</span><span class="op">,</span> <span class="nam">JWTAuthConfig</span> <span class="op">|</span> <span class="nam">StaticTokenConfig</span><span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
455
|
-
<p class="mis show_mis"><span class="n"><a id="t373" href="#t373">373</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
456
|
-
<p class="pln"><span class="n"><a id="t374" href="#t374">374</a></span><span class="t"> <span class="str">f"token_verifier_config must be JWTAuthConfig or StaticTokenConfig, got {type(config).__name__}"</span> </span><span class="r"></span></p>
|
|
457
|
-
<p class="pln"><span class="n"><a id="t375" href="#t375">375</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
458
|
-
<p class="pln"><span class="n"><a id="t376" href="#t376">376</a></span><span class="t"> </span><span class="r"></span></p>
|
|
459
|
-
<p class="pln"><span class="n"><a id="t377" href="#t377">377</a></span><span class="t"> <span class="com"># For JWT configs, ensure they have the minimum required fields</span> </span><span class="r"></span></p>
|
|
460
|
-
<p class="mis show_mis"><span class="n"><a id="t378" href="#t378">378</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">config</span><span class="op">,</span> <span class="nam">JWTAuthConfig</span><span class="op">)</span> <span class="key">and</span> <span class="op">(</span> </span><span class="r"></span></p>
|
|
461
|
-
<p class="pln"><span class="n"><a id="t379" href="#t379">379</a></span><span class="t"> <span class="key">not</span> <span class="nam">config</span><span class="op">.</span><span class="nam">public_key</span> </span><span class="r"></span></p>
|
|
462
|
-
<p class="pln"><span class="n"><a id="t380" href="#t380">380</a></span><span class="t"> <span class="key">and</span> <span class="key">not</span> <span class="nam">config</span><span class="op">.</span><span class="nam">jwks_uri</span> </span><span class="r"></span></p>
|
|
463
|
-
<p class="pln"><span class="n"><a id="t381" href="#t381">381</a></span><span class="t"> <span class="key">and</span> <span class="key">not</span> <span class="nam">config</span><span class="op">.</span><span class="nam">public_key_env_var</span> </span><span class="r"></span></p>
|
|
464
|
-
<p class="pln"><span class="n"><a id="t382" href="#t382">382</a></span><span class="t"> <span class="key">and</span> <span class="key">not</span> <span class="nam">config</span><span class="op">.</span><span class="nam">jwks_uri_env_var</span> </span><span class="r"></span></p>
|
|
465
|
-
<p class="pln"><span class="n"><a id="t383" href="#t383">383</a></span><span class="t"> <span class="op">)</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
466
|
-
<p class="mis show_mis"><span class="n"><a id="t384" href="#t384">384</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span> </span><span class="r"></span></p>
|
|
467
|
-
<p class="pln"><span class="n"><a id="t385" href="#t385">385</a></span><span class="t"> <span class="str">"JWT token verifier config must provide public_key, jwks_uri, or their environment variable equivalents"</span> </span><span class="r"></span></p>
|
|
468
|
-
<p class="pln"><span class="n"><a id="t386" href="#t386">386</a></span><span class="t"> <span class="op">)</span> </span><span class="r"></span></p>
|
|
469
|
-
<p class="pln"><span class="n"><a id="t387" href="#t387">387</a></span><span class="t"> </span><span class="r"></span></p>
|
|
470
|
-
<p class="pln"><span class="n"><a id="t388" href="#t388">388</a></span><span class="t"> <span class="com"># For static token configs, ensure they have tokens</span> </span><span class="r"></span></p>
|
|
471
|
-
<p class="mis show_mis"><span class="n"><a id="t389" href="#t389">389</a></span><span class="t"> <span class="key">if</span> <span class="nam">isinstance</span><span class="op">(</span><span class="nam">config</span><span class="op">,</span> <span class="nam">StaticTokenConfig</span><span class="op">)</span> <span class="key">and</span> <span class="key">not</span> <span class="nam">config</span><span class="op">.</span><span class="nam">tokens</span><span class="op">:</span> </span><span class="r"></span></p>
|
|
472
|
-
<p class="mis show_mis"><span class="n"><a id="t390" href="#t390">390</a></span><span class="t"> <span class="key">raise</span> <span class="nam">ValueError</span><span class="op">(</span><span class="str">"Static token verifier config must provide at least one token"</span><span class="op">)</span> </span><span class="r"></span></p>
|
|
473
|
-
<p class="pln"><span class="n"><a id="t391" href="#t391">391</a></span><span class="t"> </span><span class="r"></span></p>
|
|
474
|
-
<p class="mis show_mis"><span class="n"><a id="t392" href="#t392">392</a></span><span class="t"> <span class="key">return</span> <span class="nam">self</span> </span><span class="r"></span></p>
|
|
475
|
-
<p class="pln"><span class="n"><a id="t393" href="#t393">393</a></span><span class="t"> </span><span class="r"></span></p>
|
|
476
|
-
<p class="pln"><span class="n"><a id="t394" href="#t394">394</a></span><span class="t"> </span><span class="r"></span></p>
|
|
477
|
-
<p class="pln"><span class="n"><a id="t395" href="#t395">395</a></span><span class="t"><span class="com"># Union type for all auth configurations</span> </span><span class="r"></span></p>
|
|
478
|
-
<p class="mis show_mis"><span class="n"><a id="t396" href="#t396">396</a></span><span class="t"><span class="nam">AuthConfig</span> <span class="op">=</span> <span class="nam">JWTAuthConfig</span> <span class="op">|</span> <span class="nam">StaticTokenConfig</span> <span class="op">|</span> <span class="nam">OAuthServerConfig</span> <span class="op">|</span> <span class="nam">RemoteAuthConfig</span> </span><span class="r"></span></p>
|
|
479
|
-
</main>
|
|
480
|
-
<footer>
|
|
481
|
-
<div class="content">
|
|
482
|
-
<p>
|
|
483
|
-
<a class="nav" href="z_1c9a91c0e91c8496_helpers_py.html">« prev</a>
|
|
484
|
-
<a class="nav" href="index.html">^ index</a>
|
|
485
|
-
<a class="nav" href="z_1c9a91c0e91c8496_registry_py.html">» next</a>
|
|
486
|
-
|
|
487
|
-
<a class="nav" href="https://coverage.readthedocs.io/en/7.6.12">coverage.py v7.6.12</a>,
|
|
488
|
-
created at 2025-08-16 18:46 +0200
|
|
489
|
-
</p>
|
|
490
|
-
</div>
|
|
491
|
-
</footer>
|
|
492
|
-
</body>
|
|
493
|
-
</html>
|