polyester/services/
api_keys.rs1use super::ServiceContext;
4use super::scope;
5use super::unary;
6use crate::auth;
7use crate::codecs::decode::{api_key_from_get_proto, api_keys_list_from_proto};
8use crate::connect::auth::v1::ApiKeyServiceClient;
9use crate::errors::Result;
10use crate::models::{ApiKeySummary, ApiKeysList, Ed25519Keypair};
11use crate::proto::auth::v1::{GetApiKeyRequest, ListApiKeysRequest};
12
13#[derive(Clone)]
14pub struct ApiKeysService {
15 ctx: ServiceContext,
16}
17
18impl ApiKeysService {
19 pub fn new(ctx: ServiceContext) -> Self {
20 Self { ctx }
21 }
22
23 pub(crate) fn connect_client(&self) -> ApiKeyServiceClient<crate::transport::SharedTransport> {
24 ApiKeyServiceClient::new(
25 self.ctx.factory.transport(),
26 self.ctx.factory.connect_config(),
27 )
28 }
29
30 pub async fn list(&self, subaccount_id: Option<u64>) -> Result<ApiKeysList> {
31 let req = ListApiKeysRequest {
32 subaccount_id: scope::optional_subaccount(&self.ctx, subaccount_id)?,
33 ..Default::default()
34 };
35 let client = self.connect_client();
36 let resp = unary::await_auth(
37 &self.ctx.factory,
38 "/auth.v1.ApiKeyService/ListApiKeys",
39 req,
40 |req, opts| client.list_api_keys_with_options(req, opts),
41 )
42 .await?
43 .into_owned();
44 Ok(api_keys_list_from_proto(&resp))
45 }
46
47 pub async fn get(&self, key_id: &str) -> Result<Option<ApiKeySummary>> {
48 let client = self.connect_client();
49 let resp = unary::await_auth(
50 &self.ctx.factory,
51 "/auth.v1.ApiKeyService/GetApiKey",
52 GetApiKeyRequest {
53 key_id: key_id.to_owned(),
54 ..Default::default()
55 },
56 |req, opts| client.get_api_key_with_options(req, opts),
57 )
58 .await?
59 .into_owned();
60 Ok(api_key_from_get_proto(&resp))
61 }
62
63 pub fn generate_keypair(&self) -> Ed25519Keypair {
65 let (secret_key_hex, public_key_hex) = auth::generate_ed25519_keypair();
66 let public_key = hex::decode(&public_key_hex).unwrap_or_default();
67 let secret_key = hex::decode(&secret_key_hex).unwrap_or_default();
68 Ed25519Keypair {
69 public_key_hex,
70 secret_key_hex,
71 public_key,
72 secret_key,
73 }
74 }
75
76 pub async fn subscribe(
78 &self,
79 account_id: Option<&str>,
80 ) -> Result<crate::realtime::TypedSubscription<ApiKeySummary>> {
81 let account = scope::resolve_account_id(&self.ctx, account_id)?;
82 let channel = format!("private:auth:api-keys:{account}:proto");
83 self.ctx
84 .realtime
85 .subscribe_proto(&channel, crate::codecs::decode::api_key_from_bytes)
86 .await
87 }
88}