The smokesignal.events web application

chore: upgrading to atproto-* release candidates

+37 -42
+9 -8
Cargo.toml
··· 24 24 minijinja-embed = {version = "2.7"} 25 25 26 26 [dependencies] 27 - atproto-client = { version = "0.12.0" } 28 - atproto-identity = { version = "0.12.0", features = ["lru", "zeroize"] } 29 - atproto-oauth = { version = "0.12.0", features = ["lru", "zeroize"] } 30 - atproto-oauth-aip = { version = "0.12.0" } 31 - atproto-oauth-axum = { version = "0.12.0", features = ["zeroize"] } 32 - atproto-record = { version = "0.12.0" } 33 - atproto-jetstream = { version = "0.12.0" } 34 - atproto-xrpcs = { version = "0.12.0" } 27 + atproto-client = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 28 + atproto-attestation = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 29 + atproto-identity = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["lru", "zeroize", "hickory-dns"] } 30 + atproto-jetstream = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 31 + atproto-oauth = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["lru", "zeroize"] } 32 + atproto-oauth-aip = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 33 + atproto-oauth-axum = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["zeroize"] } 34 + atproto-record = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 35 + atproto-xrpcs = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" } 35 36 36 37 anyhow = "1.0" 37 38 async-trait = "0.1"
+3 -3
src/bin/smokesignal.rs
··· 189 189 } 190 190 #[cfg(not(feature = "s3"))] 191 191 { 192 - return Err(blahg::errors::BlahgError::ConfigFeatureNotEnabled { 193 - feature: "S3 storage requested but s3 feature is not enabled".to_string(), 194 - }); 192 + return Err(anyhow::anyhow!( 193 + "S3 storage requested but s3 feature is not enabled. Rebuild with --features s3" 194 + )); 195 195 } 196 196 } else { 197 197 let filesystem_storage = Arc::new(FilesystemStorage::new(&config.content_storage).await?);
+4 -5
src/http/context.rs
··· 1 - use atproto_identity::key::KeyProvider; 2 1 use atproto_identity::resolve::IdentityResolver; 3 - use atproto_identity::storage::DidDocumentStorage; 2 + use atproto_identity::traits::{DidDocumentStorage, KeyResolver}; 4 3 use atproto_oauth::storage::OAuthRequestStorage; 5 4 use atproto_oauth_axum::state::OAuthClientConfig; 6 5 use axum::extract::FromRef; ··· 56 55 pub(crate) i18n_context: I18nContext, 57 56 pub(crate) oauth_client_config: atproto_oauth_axum::state::OAuthClientConfig, 58 57 pub(crate) identity_resolver: Arc<dyn IdentityResolver>, 59 - pub(crate) key_provider: Arc<dyn KeyProvider>, 58 + pub(crate) key_provider: Arc<dyn KeyResolver>, 60 59 pub(crate) oauth_storage: Arc<dyn OAuthRequestStorage>, 61 60 pub(crate) document_storage: Arc<dyn DidDocumentStorage>, 62 61 pub(crate) content_storage: Arc<dyn ContentStorage>, ··· 87 86 config: Config, 88 87 oauth_client_config: OAuthClientConfig, 89 88 identity_resolver: Arc<dyn IdentityResolver>, 90 - key_provider: Arc<dyn KeyProvider>, 89 + key_provider: Arc<dyn KeyResolver>, 91 90 oauth_storage: Arc<dyn OAuthRequestStorage>, 92 91 document_storage: Arc<dyn DidDocumentStorage>, 93 92 supported_languages: Vec<LanguageIdentifier>, ··· 128 127 } 129 128 } 130 129 131 - impl FromRef<WebContext> for Arc<dyn KeyProvider> { 130 + impl FromRef<WebContext> for Arc<dyn KeyResolver> { 132 131 fn from_ref(context: &WebContext) -> Self { 133 132 context.0.key_provider.clone() 134 133 }
+5 -13
src/http/handle_oauth_callback.rs
··· 1 1 use std::sync::Arc; 2 2 3 3 use anyhow::Result; 4 - use atproto_identity::key::{KeyProvider, identify_key}; 4 + use atproto_identity::key::identify_key; 5 + use atproto_identity::traits::KeyResolver; 5 6 use atproto_oauth::{ 6 7 resources::oauth_authorization_server, 7 8 workflow::{OAuthClient, oauth_complete}, ··· 35 36 36 37 pub(crate) async fn handle_oauth_callback( 37 38 State(web_context): State<WebContext>, 38 - key_provider: State<Arc<dyn KeyProvider>>, 39 + key_provider: State<Arc<dyn KeyResolver>>, 39 40 Language(language): Language, 40 41 jar: PrivateCookieJar, 41 42 Form(callback_form): Form<OAuthCallbackForm>, ··· 106 107 107 108 let secret_signing_key = key_provider 108 109 .0 109 - .get_private_key_by_id(&oauth_request.signing_public_key) 110 + .resolve(&oauth_request.signing_public_key) 110 111 .await; 111 112 112 113 let secret_key_data = match secret_signing_key { 113 - Ok(Some(value)) => value, 114 - Ok(None) => { 115 - return contextual_error!( 116 - web_context, 117 - language, 118 - error_template, 119 - default_context, 120 - LoginError::OAuthCallbackIncomplete 121 - ); 122 - } 114 + Ok(value) => value, 123 115 Err(err) => { 124 116 return contextual_error!(web_context, language, error_template, default_context, err); 125 117 }
+1 -1
src/identity_cache.rs
··· 7 7 8 8 use anyhow::Result; 9 9 use async_trait::async_trait; 10 - use atproto_identity::{model::Document, resolve::IdentityResolver, storage::DidDocumentStorage}; 10 + use atproto_identity::{model::Document, resolve::IdentityResolver, traits::DidDocumentStorage}; 11 11 use chrono::{Duration, Utc}; 12 12 13 13 // TODO: Use a different library because lru uses unsafe.
+8 -4
src/key_provider.rs
··· 1 1 use async_trait::async_trait; 2 - use atproto_identity::key::{KeyData, KeyProvider}; 2 + use atproto_identity::key::KeyData; 3 + use atproto_identity::traits::KeyResolver; 3 4 use std::collections::HashMap; 4 5 5 6 #[derive(Clone)] ··· 14 15 } 15 16 16 17 #[async_trait] 17 - impl KeyProvider for SimpleKeyProvider { 18 - async fn get_private_key_by_id(&self, key_id: &str) -> anyhow::Result<Option<KeyData>> { 19 - Ok(self.keys.get(key_id).cloned()) 18 + impl KeyResolver for SimpleKeyProvider { 19 + async fn resolve(&self, key: &str) -> anyhow::Result<KeyData> { 20 + self.keys 21 + .get(key) 22 + .cloned() 23 + .ok_or_else(|| anyhow::anyhow!("Key not found: {}", key)) 20 24 } 21 25 }
+1 -1
src/processor.rs
··· 2 2 use atproto_client::com::atproto::repo::get_blob; 3 3 use atproto_identity::model::Document; 4 4 use atproto_identity::resolve::IdentityResolver; 5 - use atproto_identity::storage::DidDocumentStorage; 5 + use atproto_identity::traits::DidDocumentStorage; 6 6 use image::GenericImageView; 7 7 use image::ImageFormat; 8 8 use serde_json::Value;
+1 -1
src/storage/atproto.rs
··· 1 1 use async_trait::async_trait; 2 - use atproto_identity::{model::Document, storage::DidDocumentStorage}; 2 + use atproto_identity::{model::Document, traits::DidDocumentStorage}; 3 3 use atproto_oauth::{storage::OAuthRequestStorage, workflow::OAuthRequest}; 4 4 use chrono::{DateTime, Utc}; 5 5 use serde_json::Value as JsonValue;
+2 -3
src/storage/content.rs
··· 10 10 #[cfg(feature = "s3")] 11 11 use minio::s3::{Client as MinioClient, creds::StaticProvider, http::BaseUrl, types::S3Api}; 12 12 13 + use crate::storage::errors::ContentError; 14 + 13 15 /// Trait for storing and retrieving content by CID. 14 16 #[async_trait] 15 17 pub trait ContentStorage: Send + Sync { ··· 22 24 /// Read content data for a given CID. 23 25 async fn read_content(&self, cid: &str) -> Result<Vec<u8>>; 24 26 } 25 - 26 - #[cfg(feature = "s3")] 27 - use crate::storage::errors::ContentError; 28 27 29 28 pub use self::FilesystemContentStorage as FilesystemStorage; 30 29
+1 -1
src/task_identity_refresh.rs
··· 1 1 use std::sync::Arc; 2 2 3 3 use anyhow::Result; 4 - use atproto_identity::{resolve::IdentityResolver, storage::DidDocumentStorage}; 4 + use atproto_identity::{resolve::IdentityResolver, traits::DidDocumentStorage}; 5 5 use chrono::Duration; 6 6 use sqlx::FromRow; 7 7 use tokio::time::{Instant, sleep};
+1 -1
src/task_search_indexer.rs
··· 1 1 use anyhow::Result; 2 - use atproto_identity::{model::Document, resolve::IdentityResolver, storage::DidDocumentStorage}; 2 + use atproto_identity::{model::Document, resolve::IdentityResolver, traits::DidDocumentStorage}; 3 3 use opensearch::{ 4 4 DeleteParts, IndexParts, OpenSearch, 5 5 http::transport::Transport,
+1 -1
src/task_webhooks.rs
··· 1 1 use anyhow::Result; 2 - use atproto_identity::storage::DidDocumentStorage; 2 + use atproto_identity::traits::DidDocumentStorage; 3 3 use atproto_oauth::jwt::{Claims, Header, mint}; 4 4 use chrono::Utc; 5 5 use rand::distributions::{Alphanumeric, DistString};