JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Begin new protocol refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨26651b1

⁨giterated-daemon/src/authentication.rs⁩ - ⁨4608⁩ bytes
Raw
1 use anyhow::Error;
2 use giterated_models::model::{
3 authenticated::{UserAuthenticationToken, UserTokenMetadata},
4 instance::Instance,
5 user::User,
6 };
7 use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, TokenData, Validation};
8 use std::{sync::Arc, time::SystemTime};
9 use tokio::{fs::File, io::AsyncReadExt, sync::Mutex};
10 use toml::Table;
11
12 use crate::keys::PublicKeyCache;
13
14 pub struct AuthenticationTokenGranter {
15 pub config: Table,
16 pub instance: Instance,
17 }
18
19 impl AuthenticationTokenGranter {
20 async fn private_key(&self) -> Vec<u8> {
21 let mut file = File::open(
22 self.config["giterated"]["keys"]["private"]
23 .as_str()
24 .unwrap(),
25 )
26 .await
27 .unwrap();
28
29 let mut key = vec![];
30 file.read_to_end(&mut key).await.unwrap();
31
32 key
33 }
34
35 pub(crate) async fn create_token_for(
36 &mut self,
37 user: &User,
38 generated_for: &Instance,
39 ) -> String {
40 let private_key = self.private_key().await;
41
42 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
43
44 let claims = UserTokenMetadata {
45 user: user.clone(),
46 generated_for: generated_for.clone(),
47 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
48 + std::time::Duration::from_secs(24 * 60 * 60))
49 .as_secs(),
50 };
51
52 encode(
53 &jsonwebtoken::Header::new(Algorithm::RS256),
54 &claims,
55 &encoding_key,
56 )
57 .unwrap()
58 }
59
60 pub async fn token_request(
61 &mut self,
62 issued_for: impl ToOwned<Owned = Instance>,
63 username: String,
64 _password: String,
65 ) -> Result<UserAuthenticationToken, Error> {
66 let private_key = {
67 let mut file = File::open(
68 self.config["giterated"]["keys"]["private"]
69 .as_str()
70 .unwrap(),
71 )
72 .await
73 .unwrap();
74
75 let mut key = vec![];
76 file.read_to_end(&mut key).await.unwrap();
77
78 key
79 };
80
81 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
82
83 let claims = UserTokenMetadata {
84 user: User {
85 username,
86 instance: self.instance.clone(),
87 },
88 generated_for: issued_for.to_owned(),
89 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
90 + std::time::Duration::from_secs(24 * 60 * 60))
91 .as_secs(),
92 };
93
94 let token = encode(
95 &jsonwebtoken::Header::new(Algorithm::RS256),
96 &claims,
97 &encoding_key,
98 )
99 .unwrap();
100
101 Ok(UserAuthenticationToken::from(token))
102 }
103
104 pub async fn extension_request(
105 &mut self,
106 issued_for: &Instance,
107 key_cache: &Arc<Mutex<PublicKeyCache>>,
108 token: UserAuthenticationToken,
109 ) -> Result<Option<UserAuthenticationToken>, Error> {
110 let mut key_cache = key_cache.lock().await;
111 let server_public_key = key_cache.get(issued_for).await?;
112 drop(key_cache);
113
114 let verification_key = DecodingKey::from_rsa_pem(server_public_key.as_bytes()).unwrap();
115
116 let data: TokenData<UserTokenMetadata> = decode(
117 token.as_ref(),
118 &verification_key,
119 &Validation::new(Algorithm::RS256),
120 )
121 .unwrap();
122
123 if data.claims.generated_for != *issued_for {
124 panic!()
125 }
126
127 info!("Token Extension Request Token validated");
128
129 let private_key = {
130 let mut file = File::open(
131 self.config["giterated"]["keys"]["private"]
132 .as_str()
133 .unwrap(),
134 )
135 .await
136 .unwrap();
137
138 let mut key = vec![];
139 file.read_to_end(&mut key).await.unwrap();
140
141 key
142 };
143
144 let encoding_key = EncodingKey::from_rsa_pem(&private_key).unwrap();
145
146 let claims = UserTokenMetadata {
147 // TODO: Probably exploitable
148 user: data.claims.user,
149 generated_for: issued_for.clone(),
150 exp: (SystemTime::UNIX_EPOCH.elapsed().unwrap()
151 + std::time::Duration::from_secs(24 * 60 * 60))
152 .as_secs(),
153 };
154
155 let token = encode(
156 &jsonwebtoken::Header::new(Algorithm::RS256),
157 &claims,
158 &encoding_key,
159 )
160 .unwrap();
161
162 Ok(Some(UserAuthenticationToken::from(token)))
163 }
164 }
165