···
247
247
use atrium_identity::Error as IdError;
248
248
use atrium_oauth::Error as OAuthError;
249
249
250
250
+
let err = |code, reason| {
251
251
+
let info = json!({
252
252
+
"result": "fail",
253
253
+
"reason": reason,
254
254
+
});
255
255
+
(code, RenderHtml("auth-fail", engine.clone(), info)).into_response()
256
256
+
};
257
257
+
250
258
match oauth.begin(¶ms.handle).await {
251
259
Ok(auth_url) => (jar, Redirect::to(&auth_url)).into_response(),
252
252
-
Err(OAuthError::Identity(IdError::NotFound)) => {
253
253
-
let info = json!({ "reason": "handle not found" });
254
254
-
(StatusCode::NOT_FOUND, RenderHtml("auth-fail", engine, info)).into_response()
255
255
-
}
256
256
-
Err(OAuthError::Identity(IdError::AtIdentifier(r))) => {
257
257
-
let info = json!({ "reason": r });
258
258
-
(StatusCode::NOT_FOUND, RenderHtml("auth-fail", engine, info)).into_response()
259
259
-
}
260
260
-
Err(OAuthError::Identity(IdError::HttpStatus(StatusCode::NOT_FOUND))) => {
261
261
-
let info = json!({ "reason": "handle not found" });
262
262
-
(StatusCode::NOT_FOUND, RenderHtml("auth-fail", engine, info)).into_response()
263
263
-
}
260
260
+
Err(OAuthError::Identity(
261
261
+
IdError::NotFound | IdError::HttpStatus(StatusCode::NOT_FOUND),
262
262
+
)) => err(StatusCode::NOT_FOUND, "handle not found"),
263
263
+
Err(OAuthError::Identity(IdError::AtIdentifier(r))) => err(StatusCode::BAD_REQUEST, &r),
264
264
Err(e) => {
265
265
eprintln!("begin auth failed: {e:?}");
266
266
-
let info = json!({ "reason": "unknown" });
267
267
-
(
268
268
-
StatusCode::INTERNAL_SERVER_ERROR,
269
269
-
RenderHtml("auth-fail", engine, info),
270
270
-
)
271
271
-
.into_response()
266
266
+
err(StatusCode::INTERNAL_SERVER_ERROR, "unknown")
272
267
}
273
268
}
274
269
}
275
270
276
276
-
impl OAuthCompleteError {
277
277
-
fn to_error_response(&self, engine: AppEngine) -> Response {
278
278
-
let (level, desc) = match self {
279
279
-
OAuthCompleteError::Denied { description, .. } => {
280
280
-
("warn", format!("asdf: {description:?}"))
281
281
-
}
282
282
-
OAuthCompleteError::Failed { .. } => (
283
283
-
"error",
284
284
-
"Something went wrong while requesting permission, sorry!".to_string(),
285
285
-
),
286
286
-
OAuthCompleteError::CallbackFailed(_) => (
287
287
-
"error",
288
288
-
"Something went wrong after permission was granted, sorry!".to_string(),
289
289
-
),
290
290
-
OAuthCompleteError::NoDid => (
291
291
-
"error",
292
292
-
"Something went wrong when trying to confirm your identity, sorry!".to_string(),
293
293
-
),
294
294
-
};
295
295
-
(
296
296
-
if level == "warn" {
297
297
-
StatusCode::FORBIDDEN
298
298
-
} else {
299
299
-
StatusCode::INTERNAL_SERVER_ERROR
300
300
-
},
301
301
-
RenderHtml(
302
302
-
"auth-fail",
303
303
-
engine,
304
304
-
json!({
305
305
-
"reason": desc,
306
306
-
}),
307
307
-
),
308
308
-
)
309
309
-
.into_response()
310
310
-
}
311
311
-
}
312
312
-
313
271
async fn complete_oauth(
314
272
State(AppState {
315
273
engine,
···
320
278
}): State<AppState>,
321
279
Query(params): Query<OAuthCallbackParams>,
322
280
jar: SignedCookieJar,
323
323
-
) -> Result<(SignedCookieJar, impl IntoResponse), Response> {
281
281
+
) -> Response {
282
282
+
let err = |code, result, reason| {
283
283
+
let info = json!({
284
284
+
"result": result,
285
285
+
"reason": reason,
286
286
+
});
287
287
+
(code, RenderHtml("auth-fail", engine.clone(), info)).into_response()
288
288
+
};
289
289
+
324
290
let did = match oauth.complete(params).await {
325
291
Ok(did) => did,
326
326
-
Err(e) => return Err(e.to_error_response(engine)),
292
292
+
Err(e) => {
293
293
+
return match e {
294
294
+
OAuthCompleteError::Denied { description, .. } => {
295
295
+
let desc = description.unwrap_or("permission to share was denied".to_string());
296
296
+
err(StatusCode::FORBIDDEN, "deny", desc.as_str())
297
297
+
}
298
298
+
OAuthCompleteError::Failed { .. } => {
299
299
+
eprintln!("auth completion failed: {e:?}");
300
300
+
err(
301
301
+
StatusCode::INTERNAL_SERVER_ERROR,
302
302
+
"fail",
303
303
+
"failed to complete",
304
304
+
)
305
305
+
}
306
306
+
OAuthCompleteError::CallbackFailed(e) => {
307
307
+
eprintln!("auth callback failed: {e:?}");
308
308
+
err(
309
309
+
StatusCode::INTERNAL_SERVER_ERROR,
310
310
+
"fail",
311
311
+
"failed to complete callback",
312
312
+
)
313
313
+
}
314
314
+
OAuthCompleteError::NoDid => err(StatusCode::BAD_REQUEST, "fail", "no DID found"),
315
315
+
};
316
316
+
}
327
317
};
328
318
329
319
let cookie = Cookie::build((DID_COOKIE_KEY, did.to_string()))
···
342
332
},
343
333
shutdown.child_token(),
344
334
);
345
345
-
346
346
-
Ok((
347
347
-
jar,
348
348
-
RenderHtml(
349
349
-
"authorized",
350
350
-
engine,
351
351
-
json!({
352
352
-
"did": did,
353
353
-
"fetch_key": fetch_key,
354
354
-
}),
355
355
-
),
356
356
-
))
335
335
+
let info = json!({
336
336
+
"did": did,
337
337
+
"fetch_key": fetch_key,
338
338
+
});
339
339
+
(jar, RenderHtml("authorized", engine, info)).into_response()
357
340
}
···
9
9
10
10
<script>
11
11
localStorage.setItem("who-am-i", JSON.stringify({
12
12
-
result: "fail",
12
12
+
result: {{{json result}}},
13
13
reason: {{{json reason}}},
14
14
}));
15
15
···
87
87
fail(`uh oh: ${parsed.reason}`);
88
88
}
89
89
90
90
+
if (parsed.result === "deny") {
91
91
+
fail(parsed.reason);
92
92
+
}
93
93
+
90
94
infoEl.classList.add('hidden');
91
95
92
96
const handle = await lookUp(parsed.fetch_key);
···
111
115
const shareAllow = handle => {
112
116
top.postMessage(
113
117
{ action: "allow", handle },
114
114
-
{{{json parent_host}}},
118
118
+
{{{json parent_origin}}},
115
119
);
116
120
}
117
121