tangled
alpha
login
or
join now
smokesignal.events
/
smokesignal
51
fork
atom
The smokesignal.events web application
51
fork
atom
overview
issues
7
pulls
pipelines
chore: upgrading to atproto-* release candidates
Nick Gerakines
4 months ago
7da344fc
2fffe5fc
+37
-42
12 changed files
expand all
collapse all
unified
split
Cargo.toml
src
bin
smokesignal.rs
http
context.rs
handle_oauth_callback.rs
identity_cache.rs
key_provider.rs
processor.rs
storage
atproto.rs
content.rs
task_identity_refresh.rs
task_search_indexer.rs
task_webhooks.rs
+9
-8
Cargo.toml
···
24
24
minijinja-embed = {version = "2.7"}
25
25
26
26
[dependencies]
27
27
-
atproto-client = { version = "0.12.0" }
28
28
-
atproto-identity = { version = "0.12.0", features = ["lru", "zeroize"] }
29
29
-
atproto-oauth = { version = "0.12.0", features = ["lru", "zeroize"] }
30
30
-
atproto-oauth-aip = { version = "0.12.0" }
31
31
-
atproto-oauth-axum = { version = "0.12.0", features = ["zeroize"] }
32
32
-
atproto-record = { version = "0.12.0" }
33
33
-
atproto-jetstream = { version = "0.12.0" }
34
34
-
atproto-xrpcs = { version = "0.12.0" }
27
27
+
atproto-client = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" }
28
28
+
atproto-attestation = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" }
29
29
+
atproto-identity = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["lru", "zeroize", "hickory-dns"] }
30
30
+
atproto-jetstream = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" }
31
31
+
atproto-oauth = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["lru", "zeroize"] }
32
32
+
atproto-oauth-aip = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" }
33
33
+
atproto-oauth-axum = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs", features = ["zeroize"] }
34
34
+
atproto-record = { git = "https://tangled.org/@smokesignal.events/atproto-identity-rs" }
35
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
192
-
return Err(blahg::errors::BlahgError::ConfigFeatureNotEnabled {
193
193
-
feature: "S3 storage requested but s3 feature is not enabled".to_string(),
194
194
-
});
192
192
+
return Err(anyhow::anyhow!(
193
193
+
"S3 storage requested but s3 feature is not enabled. Rebuild with --features s3"
194
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
1
-
use atproto_identity::key::KeyProvider;
2
1
use atproto_identity::resolve::IdentityResolver;
3
3
-
use atproto_identity::storage::DidDocumentStorage;
2
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
59
-
pub(crate) key_provider: Arc<dyn KeyProvider>,
58
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
90
-
key_provider: Arc<dyn KeyProvider>,
89
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
131
-
impl FromRef<WebContext> for Arc<dyn KeyProvider> {
130
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
4
-
use atproto_identity::key::{KeyProvider, identify_key};
4
4
+
use atproto_identity::key::identify_key;
5
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
38
-
key_provider: State<Arc<dyn KeyProvider>>,
39
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
109
-
.get_private_key_by_id(&oauth_request.signing_public_key)
110
110
+
.resolve(&oauth_request.signing_public_key)
110
111
.await;
111
112
112
113
let secret_key_data = match secret_signing_key {
113
113
-
Ok(Some(value)) => value,
114
114
-
Ok(None) => {
115
115
-
return contextual_error!(
116
116
-
web_context,
117
117
-
language,
118
118
-
error_template,
119
119
-
default_context,
120
120
-
LoginError::OAuthCallbackIncomplete
121
121
-
);
122
122
-
}
114
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
10
-
use atproto_identity::{model::Document, resolve::IdentityResolver, storage::DidDocumentStorage};
10
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
2
-
use atproto_identity::key::{KeyData, KeyProvider};
2
2
+
use atproto_identity::key::KeyData;
3
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
17
-
impl KeyProvider for SimpleKeyProvider {
18
18
-
async fn get_private_key_by_id(&self, key_id: &str) -> anyhow::Result<Option<KeyData>> {
19
19
-
Ok(self.keys.get(key_id).cloned())
18
18
+
impl KeyResolver for SimpleKeyProvider {
19
19
+
async fn resolve(&self, key: &str) -> anyhow::Result<KeyData> {
20
20
+
self.keys
21
21
+
.get(key)
22
22
+
.cloned()
23
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
5
-
use atproto_identity::storage::DidDocumentStorage;
5
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
2
-
use atproto_identity::{model::Document, storage::DidDocumentStorage};
2
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
13
+
use crate::storage::errors::ContentError;
14
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
25
-
26
26
-
#[cfg(feature = "s3")]
27
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
4
-
use atproto_identity::{resolve::IdentityResolver, storage::DidDocumentStorage};
4
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
2
-
use atproto_identity::{model::Document, resolve::IdentityResolver, storage::DidDocumentStorage};
2
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
2
-
use atproto_identity::storage::DidDocumentStorage;
2
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};