+2
-2
pegasus/lib/auth.ml
+2
-2
pegasus/lib/auth.ml
···
258
258
~url:(Dream.target req) ~dpop_header ()
259
259
with
260
260
| Error "use_dpop_nonce" ->
261
-
Lwt.return_error @@ Errors.use_dpop_nonce ()
261
+
Lwt.return_error @@ Errors.use_dpop_nonce_auth ()
262
262
| Error e ->
263
263
Log.debug (fun log -> log "dpop error: %s" e) ;
264
264
Lwt.return_error @@ Errors.invalid_request ("dpop error: " ^ e)
···
279
279
~access_token:token ()
280
280
with
281
281
| Error "use_dpop_nonce" ->
282
-
Lwt.return_error @@ Errors.use_dpop_nonce ()
282
+
Lwt.return_error @@ Errors.use_dpop_nonce_resource ()
283
283
| Error e ->
284
284
Log.debug (fun log -> log "dpop error: %s" e) ;
285
285
Lwt.return_error @@ Errors.invalid_request ("dpop error: " ^ e)
+18
-5
pegasus/lib/errors.ml
+18
-5
pegasus/lib/errors.ml
···
8
8
9
9
exception Redirect of string
10
10
11
-
exception UseDpopNonceError
11
+
(* HTTP 400, { error: "use_dpop_nonce" } — https://datatracker.ietf.org/doc/html/rfc9449#section-8 *)
12
+
exception UseDpopNonceAuthError
13
+
14
+
(* HTTP 401, WWW-Authenticate — https://datatracker.ietf.org/doc/html/rfc9449#section-9 *)
15
+
exception UseDpopNonceResourceError
12
16
13
17
let is_xrpc_error = function
14
18
| InvalidRequestError _
···
30
34
31
35
let not_found ?(name = "NotFound") msg = raise (NotFoundError (name, msg))
32
36
33
-
let use_dpop_nonce () = raise UseDpopNonceError
37
+
let use_dpop_nonce_auth () = raise UseDpopNonceAuthError
38
+
39
+
let use_dpop_nonce_resource () = raise UseDpopNonceResourceError
34
40
35
41
let printer = function
36
42
| InvalidRequestError (error, message) ->
···
41
47
Some (Printf.sprintf "Auth error (%s): %s" error message)
42
48
| NotFoundError (error, message) ->
43
49
Some (Printf.sprintf "Not found (%s): %s" error message)
44
-
| UseDpopNonceError ->
50
+
| UseDpopNonceAuthError ->
51
+
Some "Use DPoP nonce"
52
+
| UseDpopNonceResourceError ->
45
53
Some "Use DPoP nonce"
46
54
| _ ->
47
55
None
···
64
72
| NotFoundError (error, message) ->
65
73
Log.debug (fun log -> log "not found error: %s - %s" error message) ;
66
74
format_response error message `Not_Found
67
-
| UseDpopNonceError ->
68
-
Log.debug (fun log -> log "use_dpop_nonce error") ;
75
+
| UseDpopNonceAuthError ->
76
+
Log.debug (fun log -> log "use_dpop_nonce auth error") ;
69
77
Dream.json ~status:`Bad_Request
78
+
~headers:[("Access-Control-Expose-Headers", "DPoP-Nonce")]
79
+
{|{ "error": "use_dpop_nonce" }|}
80
+
| UseDpopNonceResourceError ->
81
+
Log.debug (fun log -> log "use_dpop_nonce resource error") ;
82
+
Dream.json ~status:`Unauthorized
70
83
~headers:
71
84
[ ("WWW-Authenticate", {|DPoP error="use_dpop_nonce"|})
72
85
; ("Access-Control-Expose-Headers", "DPoP-Nonce, WWW-Authenticate") ]
+10
-4
pegasus/lib/xrpc.ml
+10
-4
pegasus/lib/xrpc.ml
···
107
107
Dream.set_header res "DPoP-Nonce" (Oauth.Dpop.next_nonce ())
108
108
in
109
109
let () =
110
+
let to_expose =
111
+
(* see comments on UseDpopNonce____Error in errors.ml *)
112
+
if Dream.status res = `Unauthorized then "DPoP-Nonce, WWW-Authenticate"
113
+
else if Dream.status res = `Bad_Request then "DPoP-Nonce"
114
+
else ""
115
+
in
110
116
match Dream.header res "Access-Control-Expose-Headers" with
111
117
| Some header when Util.str_contains ~affix:"DPoP-Nonce" header ->
112
118
()
113
119
| Some header ->
114
120
Dream.set_header res "Access-Control-Expose-Headers"
115
-
(header ^ ", DPoP-Nonce")
121
+
(header ^ ", " ^ to_expose)
116
122
| _ ->
117
-
Dream.set_header res "Access-Control-Expose-Headers" "DPoP-Nonce"
123
+
Dream.set_header res "Access-Control-Expose-Headers" to_expose
118
124
in
119
125
res
120
126
···
140
146
let%lwt res = exn_to_response e in
141
147
Lwt.return
142
148
( match e with
143
-
| UseDpopNonceError ->
149
+
| UseDpopNonceAuthError | UseDpopNonceResourceError ->
144
150
add_dpop_nonce_if_needed res
145
151
| _ ->
146
152
res )
···
149
155
Dream.redirect init.req r
150
156
| Rate_limiter.Rate_limit_exceeded status ->
151
157
rate_limit_response status
152
-
| UseDpopNonceError as e ->
158
+
| (UseDpopNonceAuthError | UseDpopNonceResourceError) as e ->
153
159
let%lwt res = exn_to_response e in
154
160
Lwt.return (add_dpop_nonce_if_needed res)
155
161
| e ->