Skip to content

Commit 2abe79c

Browse files
authored
feat: OAuth session (#243)
* Move AtpAgent * Add Agent and SessionManager * Temporary fix for bsky-sdk * Add OAuthSession * Update * Update oauth_client::atproto * Add refresh token request * Update stores * Add SessionStore and SessionGetter * Use common for api * Fix bsky-sdk * Fix oauth-client * Extract WrapperClient and InnerStore to agent.rs * Add Configure and CloneWithProxy trait for agent * Update AtpAgent * Update * Add tests for oauth_session, implement oauth_session::store * WIP: Add tests for OAuthSession, update ServerAgent * Implement refresh token * Update atrium-api/agent * Fix error * Fix bsky_sdk * Fix oauth-client * Implement SessionGetter and SessionHandle * Remove unused code * Fix workflows * Use is_some_and/is_ok_and * Add tests for OAuthSession * Implement OAuthClient::restore * Implement OAuthClient::revoke() * Rename session_getter to session_registry * Fix for edition 2024 * WIP: Update SessionRegistry * Update SessionRegistry * WIP * Add session_registry::tests * Fix tests * Remove DidResolver * Remove HandleResolver
1 parent f162f81 commit 2abe79c

File tree

33 files changed

+1812
-306
lines changed

33 files changed

+1812
-306
lines changed

.github/workflows/wasm.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ jobs:
2020
- uses: actions/checkout@v4
2121
with:
2222
path: crates
23+
- name: Install Rust 1.75.0
24+
uses: actions-rust-lang/setup-rust-toolchain@v1
25+
with:
26+
toolchain: 1.75.0
2327
# We use a synthetic crate to ensure no dev-dependencies are enabled, which can
2428
# be incompatible with some of these targets.
2529
- name: Create synthetic crate for testing

Cargo.lock

Lines changed: 6 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

atrium-api/src/agent/atp_agent.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ mod tests {
324324
&self,
325325
request: Request<Vec<u8>>,
326326
) -> Result<Response<Vec<u8>>, Box<dyn std::error::Error + Send + Sync + 'static>> {
327+
// tick tokio time
327328
#[cfg(not(target_arch = "wasm32"))]
328329
tokio::time::sleep(std::time::Duration::from_micros(10)).await;
329330

atrium-api/src/agent/store.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

atrium-api/src/agent/store/memory.rs

Lines changed: 0 additions & 20 deletions
This file was deleted.

atrium-common/src/store/memory.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ use super::Store;
22
use std::collections::HashMap;
33
use std::fmt::Debug;
44
use std::hash::Hash;
5-
use std::sync::{Arc, Mutex};
5+
use std::sync::Arc;
66
use thiserror::Error;
7+
use tokio::sync::Mutex;
78

89
#[derive(Error, Debug)]
910
#[error("memory store error")]
1011
pub struct Error;
1112

12-
// TODO: LRU cache?
1313
#[derive(Clone)]
1414
pub struct MemoryStore<K, V> {
1515
store: Arc<Mutex<HashMap<K, V>>>,
@@ -29,18 +29,18 @@ where
2929
type Error = Error;
3030

3131
async fn get(&self, key: &K) -> Result<Option<V>, Self::Error> {
32-
Ok(self.store.lock().unwrap().get(key).cloned())
32+
Ok(self.store.lock().await.get(key).cloned())
3333
}
3434
async fn set(&self, key: K, value: V) -> Result<(), Self::Error> {
35-
self.store.lock().unwrap().insert(key, value);
35+
self.store.lock().await.insert(key, value);
3636
Ok(())
3737
}
3838
async fn del(&self, key: &K) -> Result<(), Self::Error> {
39-
self.store.lock().unwrap().remove(key);
39+
self.store.lock().await.remove(key);
4040
Ok(())
4141
}
4242
async fn clear(&self) -> Result<(), Self::Error> {
43-
self.store.lock().unwrap().clear();
43+
self.store.lock().await.clear();
4444
Ok(())
4545
}
4646
}

atrium-identity/src/did.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ mod common_resolver;
22
mod plc_resolver;
33
mod web_resolver;
44

5-
use crate::Error;
6-
75
pub use self::common_resolver::{CommonDidResolver, CommonDidResolverConfig};
86
pub use self::plc_resolver::DEFAULT_PLC_DIRECTORY_URL;
7+
use crate::Error;
98
use atrium_api::did_doc::DidDocument;
109
use atrium_api::types::string::Did;
1110
use atrium_common::resolver::Resolver;

atrium-identity/src/identity_resolver.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use crate::error::{Error, Result};
2-
use crate::{did::DidResolver, handle::HandleResolver};
3-
use atrium_api::types::string::AtIdentifier;
2+
use atrium_api::{
3+
did_doc::DidDocument,
4+
types::string::{AtIdentifier, Did, Handle},
5+
};
46
use atrium_common::resolver::Resolver;
57
use serde::{Deserialize, Serialize};
68

@@ -29,8 +31,8 @@ impl<D, H> IdentityResolver<D, H> {
2931

3032
impl<D, H> Resolver for IdentityResolver<D, H>
3133
where
32-
D: DidResolver + Send + Sync + 'static,
33-
H: HandleResolver + Send + Sync + 'static,
34+
D: Resolver<Input = Did, Output = DidDocument, Error = Error> + Send + Sync,
35+
H: Resolver<Input = Handle, Output = Did, Error = Error> + Send + Sync,
3436
{
3537
type Input = str;
3638
type Output = ResolvedIdentity;

atrium-oauth/oauth-client/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ keywords = ["atproto", "bluesky", "oauth"]
1414
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1515

1616
[dependencies]
17-
atrium-api = { workspace = true, default-features = false }
17+
atrium-api = { workspace = true, features = ["agent"] }
1818
atrium-common.workspace = true
1919
atrium-identity.workspace = true
2020
atrium-xrpc.workspace = true
2121
base64.workspace = true
2222
chrono.workspace = true
23+
dashmap.workspace = true
2324
ecdsa = { workspace = true, features = ["signing"] }
2425
elliptic-curve.workspace = true
2526
jose-jwa.workspace = true
@@ -32,11 +33,14 @@ serde_html_form.workspace = true
3233
serde_json.workspace = true
3334
sha2.workspace = true
3435
thiserror.workspace = true
36+
tokio = { workspace = true, features = ["sync"] }
3537
trait-variant.workspace = true
3638

3739
[dev-dependencies]
40+
atrium-api = { workspace = true, features = ["bluesky"] }
41+
futures.workspace = true
3842
hickory-resolver.workspace = true
39-
p256 = { workspace = true, features = ["pem"] }
43+
p256 = { workspace = true, features = ["pem", "std"] }
4044
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
4145

4246
[features]
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use elliptic_curve::pkcs8::EncodePrivateKey;
2+
use elliptic_curve::SecretKey;
3+
use jose_jwa::{Algorithm, Signing};
4+
use jose_jwk::{Class, Jwk, JwkSet, Key, Parameters};
5+
use p256::NistP256;
6+
use rand::rngs::ThreadRng;
7+
8+
fn main() -> Result<(), Box<dyn std::error::Error>> {
9+
let secret_key = SecretKey::<NistP256>::random(&mut ThreadRng::default());
10+
let key = Key::from(&secret_key.public_key().into());
11+
let jwks = JwkSet {
12+
keys: vec![Jwk {
13+
key,
14+
prm: Parameters {
15+
alg: Some(Algorithm::Signing(Signing::Es256)),
16+
kid: Some(String::from("kid01")),
17+
cls: Some(Class::Signing),
18+
..Default::default()
19+
},
20+
}],
21+
};
22+
println!("SECRET KEY:");
23+
println!("{}", secret_key.to_pkcs8_pem(Default::default())?.as_str());
24+
25+
println!("JWKS:");
26+
println!("{}", serde_json::to_string_pretty(&jwks)?);
27+
Ok(())
28+
}

0 commit comments

Comments
 (0)