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

ambee/giterated

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

Fixed imports!

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨ef0e853

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