openauth_plugins/api_key/routes/
get.rs1use http::{Method, StatusCode};
2use serde::{Deserialize, Serialize};
3
4use super::{
5 config_id_matches, current_identity, endpoint, error, json, query_param, SharedConfigurations,
6};
7use crate::api_key::errors;
8use crate::api_key::options::ApiKeyReference;
9use crate::api_key::organization::{ensure_organization_permission, owns_user_key, ApiKeyAction};
10use crate::api_key::storage::ApiKeyStore;
11
12#[derive(Debug, Clone, Deserialize, Serialize, Default)]
13#[serde(rename_all = "camelCase")]
14pub struct GetApiKeyQuery {
15 pub id: String,
16 pub config_id: Option<String>,
17}
18
19pub fn get_endpoint(configurations: SharedConfigurations) -> openauth_core::api::AsyncAuthEndpoint {
20 endpoint(
21 "/api-key/get",
22 Method::GET,
23 configurations,
24 |context, request, configurations| {
25 Box::pin(async move {
26 let id = match query_param(&request, "id") {
27 Some(id) => id,
28 None => return error(StatusCode::BAD_REQUEST, errors::KEY_NOT_FOUND),
29 };
30 let config_id = query_param(&request, "configId");
31 let options = configurations.resolve(config_id.as_deref())?;
32 let Some(identity) = current_identity(context, &request).await? else {
33 return error(StatusCode::UNAUTHORIZED, errors::UNAUTHORIZED_SESSION);
34 };
35 let Some(api_key) = ApiKeyStore::new(context, &options).get_by_id(&id).await?
36 else {
37 return error(StatusCode::NOT_FOUND, errors::KEY_NOT_FOUND);
38 };
39 let expected_config_id = options.config_id.as_deref().unwrap_or("default");
40 if !config_id_matches(&api_key.config_id, expected_config_id) {
41 return error(StatusCode::NOT_FOUND, errors::KEY_NOT_FOUND);
42 }
43 match options.reference {
44 ApiKeyReference::User
45 if owns_user_key(
46 options.reference,
47 &api_key.reference_id,
48 &identity.user.id,
49 ) => {}
50 ApiKeyReference::User => {
51 return error(StatusCode::NOT_FOUND, errors::KEY_NOT_FOUND);
52 }
53 ApiKeyReference::Organization => {
54 if let Err(error) = ensure_organization_permission(
55 context,
56 &identity.user.id,
57 &api_key.reference_id,
58 ApiKeyAction::Read,
59 )
60 .await
61 {
62 return error_response_from_openauth(error);
63 }
64 }
65 }
66 json(StatusCode::OK, &api_key.public())
67 })
68 },
69 )
70}
71
72fn error_response_from_openauth(
73 error: openauth_core::error::OpenAuthError,
74) -> Result<openauth_core::api::ApiResponse, openauth_core::error::OpenAuthError> {
75 let message = error.to_string();
76 if message.contains(errors::message(errors::USER_NOT_MEMBER_OF_ORGANIZATION)) {
77 return super::error(
78 StatusCode::FORBIDDEN,
79 errors::USER_NOT_MEMBER_OF_ORGANIZATION,
80 );
81 }
82 if message.contains(errors::message(errors::ORGANIZATION_PLUGIN_REQUIRED)) {
83 return super::error(
84 StatusCode::INTERNAL_SERVER_ERROR,
85 errors::ORGANIZATION_PLUGIN_REQUIRED,
86 );
87 }
88 super::error(
89 StatusCode::FORBIDDEN,
90 errors::INSUFFICIENT_API_KEY_PERMISSIONS,
91 )
92}