tangled
alpha
login
or
join now
ligo.at
/
core
6
fork
atom
decentralized and customizable links page on top of atproto
ligo.at
atproto
link-in-bio
python
uv
6
fork
atom
overview
issues
2
pulls
pipelines
close connection after reading json
nauta.one
4 weeks ago
25f4e2c0
7bbcc337
+15
-12
2 changed files
expand all
collapse all
unified
split
src
atproto
oauth.py
oauth.py
+10
-10
src/atproto/oauth.py
···
26
26
# Prepares and sends a pushed auth request (PAR) via HTTP POST to the Authorization Server.
27
27
# Returns "state" id HTTP response on success, without checking HTTP response status
28
28
async def send_par_auth_request(
29
29
+
hardened_client: ClientSession,
29
30
authserver_url: str,
30
31
authserver_meta: dict[str, str],
31
32
login_hint: str | None,
···
70
71
71
72
# IMPORTANT: Pushed Authorization Request URL is untrusted input, SSRF mitigations are needed
72
73
assert is_safe_url(par_url)
73
73
-
async with hardened_http.get_session() as session:
74
74
-
resp = await session.post(
75
75
-
par_url,
76
76
-
headers={
77
77
-
"Content-Type": "application/x-www-form-urlencoded",
78
78
-
"DPoP": dpop_proof,
79
79
-
},
80
80
-
data=par_body,
81
81
-
)
82
82
-
respjson = await resp.json()
74
74
+
resp = await hardened_client.post(
75
75
+
par_url,
76
76
+
headers={
77
77
+
"Content-Type": "application/x-www-form-urlencoded",
78
78
+
"DPoP": dpop_proof,
79
79
+
},
80
80
+
data=par_body,
81
81
+
)
82
82
+
respjson = await resp.json()
83
83
84
84
# Handle DPoP missing/invalid nonce error by retrying with server-provided nonce
85
85
if resp.status == 400 and respjson["error"] == "use_dpop_nonce":
+5
-2
src/oauth.py
···
29
29
save_auth_session,
30
30
)
31
31
from src.db import KV, get_db
32
32
-
from src.security import is_safe_url
32
32
+
from src.security import hardened_http, is_safe_url
33
33
34
34
oauth = Blueprint("oauth", __name__, url_prefix="/oauth")
35
35
···
100
100
101
101
CLIENT_SECRET_JWK = JsonWebKey.import_key(current_app.config["CLIENT_SECRET_JWK"])
102
102
103
103
+
client = hardened_http.get_session()
103
104
pkce_verifier, state, dpop_authserver_nonce, resp = await send_par_auth_request(
105
105
+
client,
104
106
authserver_url,
105
107
authserver_meta,
106
108
login_hint,
···
119
121
120
122
respjson: dict[str, str] = await resp.json()
121
123
par_request_uri: str = respjson["request_uri"]
122
122
-
current_app.logger.debug(f"saving oauth_auth_request to DB state={state}")
124
124
+
await client.close()
123
125
126
126
+
current_app.logger.debug(f"saving oauth_auth_request to DB state={state}")
124
127
oauth_request = OAuthAuthRequest(
125
128
state,
126
129
authserver_meta["issuer"],