This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-atproto / src / auth.rs
1.8 kB 72 lines
1use http::HeaderValue; 2use knot_runtime::{Entropy, HttpRequest, Signer}; 3use knot_types::{KnotId, Nsid, ServiceDid, UnixSeconds}; 4 5use crate::AtprotoError; 6use crate::jwt; 7use crate::jwt::JwtNonce; 8 9const POINTER_NONCE_BYTES: usize = 16; 10 11pub struct PointerAuth<'a> { 12 pub issuer: &'a KnotId, 13 pub audience: &'a ServiceDid, 14 pub lxm: &'a Nsid, 15 pub now_unix: UnixSeconds, 16} 17 18pub trait PointerAuthorizer { 19 fn authorize( 20 &self, 21 request: &mut HttpRequest, 22 ctx: &PointerAuth<'_>, 23 ) -> Result<(), AtprotoError>; 24} 25 26pub struct ServiceAuth<'a> { 27 signer: &'a dyn Signer, 28 entropy: &'a dyn Entropy, 29} 30 31impl<'a> ServiceAuth<'a> { 32 pub fn new(signer: &'a dyn Signer, entropy: &'a dyn Entropy) -> Self { 33 Self { signer, entropy } 34 } 35} 36 37impl PointerAuthorizer for ServiceAuth<'_> { 38 fn authorize( 39 &self, 40 request: &mut HttpRequest, 41 ctx: &PointerAuth<'_>, 42 ) -> Result<(), AtprotoError> { 43 let mut bytes = [0u8; POINTER_NONCE_BYTES]; 44 self.entropy.fill(&mut bytes); 45 let nonce = JwtNonce::new(knot_types::lowercase_hex(&bytes))?; 46 let token = jwt::mint( 47 self.signer, 48 ctx.issuer, 49 ctx.audience, 50 ctx.lxm, 51 nonce, 52 ctx.now_unix, 53 ); 54 let header = HeaderValue::from_str(&format!("Bearer {token}")) 55 .expect("base64url jwt is valid header value"); 56 request.headers.insert(http::header::AUTHORIZATION, header); 57 Ok(()) 58 } 59} 60 61pub struct OauthAuthorizer; 62 63impl PointerAuthorizer for OauthAuthorizer { 64 fn authorize( 65 &self, 66 _request: &mut HttpRequest, 67 _ctx: &PointerAuth<'_>, 68 ) -> Result<(), AtprotoError> { 69 todo!("OAuth+DPoP authorizer is waiting on an OAuth client") 70 // one day... 71 } 72}