diff options
author | Rutger Broekhoff | 2024-01-22 22:52:01 +0100 |
---|---|---|
committer | Rutger Broekhoff | 2024-01-22 22:52:01 +0100 |
commit | f5ff2803af0e03f57ab3093a9384d91abb9de083 (patch) | |
tree | edb5a5c28c183c421bdf2b3e2c05c36ecb77bacd /rs/common | |
parent | efe9d55ea6c01c718d3c53dbcee6b48899b48267 (diff) | |
download | gitolfs3-f5ff2803af0e03f57ab3093a9384d91abb9de083.tar.gz gitolfs3-f5ff2803af0e03f57ab3093a9384d91abb9de083.zip |
Finish basic implementation of Rust LFS server
Diffstat (limited to 'rs/common')
-rw-r--r-- | rs/common/src/lib.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/rs/common/src/lib.rs b/rs/common/src/lib.rs index aafe7f1..27205bd 100644 --- a/rs/common/src/lib.rs +++ b/rs/common/src/lib.rs | |||
@@ -37,8 +37,9 @@ impl FromStr for Operation { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | #[repr(u8)] | 39 | #[repr(u8)] |
40 | pub enum AuthType { | 40 | enum AuthType { |
41 | GitLfsAuthenticate = 1, | 41 | BatchApi = 1, |
42 | Download = 2, | ||
42 | } | 43 | } |
43 | 44 | ||
44 | /// None means out of range. | 45 | /// None means out of range. |
@@ -156,6 +157,12 @@ impl<const N: usize> SafeByteArray<N> { | |||
156 | } | 157 | } |
157 | } | 158 | } |
158 | 159 | ||
160 | impl<const N: usize> Default for SafeByteArray<N> { | ||
161 | fn default() -> Self { | ||
162 | Self::new() | ||
163 | } | ||
164 | } | ||
165 | |||
159 | impl<const N: usize> AsRef<[u8]> for SafeByteArray<N> { | 166 | impl<const N: usize> AsRef<[u8]> for SafeByteArray<N> { |
160 | fn as_ref(&self) -> &[u8] { | 167 | fn as_ref(&self) -> &[u8] { |
161 | &self.inner | 168 | &self.inner |
@@ -184,10 +191,18 @@ impl<const N: usize> FromStr for SafeByteArray<N> { | |||
184 | } | 191 | } |
185 | } | 192 | } |
186 | 193 | ||
194 | pub type Oid = Digest<32>; | ||
195 | |||
196 | #[derive(Debug, Copy, Clone)] | ||
197 | pub enum SpecificClaims { | ||
198 | BatchApi(Operation), | ||
199 | Download(Oid), | ||
200 | } | ||
201 | |||
202 | #[derive(Debug, Copy, Clone)] | ||
187 | pub struct Claims<'a> { | 203 | pub struct Claims<'a> { |
188 | pub auth_type: AuthType, | 204 | pub specific_claims: SpecificClaims, |
189 | pub repo_path: &'a str, | 205 | pub repo_path: &'a str, |
190 | pub operation: Operation, | ||
191 | pub expires_at: DateTime<Utc>, | 206 | pub expires_at: DateTime<Utc>, |
192 | } | 207 | } |
193 | 208 | ||
@@ -198,10 +213,18 @@ pub fn generate_tag(claims: Claims, key: impl AsRef<[u8]>) -> Option<Digest<32>> | |||
198 | } | 213 | } |
199 | 214 | ||
200 | let mut hmac = hmac_sha256::HMAC::new(key); | 215 | let mut hmac = hmac_sha256::HMAC::new(key); |
201 | hmac.update([claims.auth_type as u8]); | 216 | match claims.specific_claims { |
217 | SpecificClaims::BatchApi(operation) => { | ||
218 | hmac.update([AuthType::BatchApi as u8]); | ||
219 | hmac.update([operation as u8]); | ||
220 | } | ||
221 | SpecificClaims::Download(oid) => { | ||
222 | hmac.update([AuthType::Download as u8]); | ||
223 | hmac.update(oid.as_bytes()); | ||
224 | } | ||
225 | } | ||
202 | hmac.update([claims.repo_path.len() as u8]); | 226 | hmac.update([claims.repo_path.len() as u8]); |
203 | hmac.update(claims.repo_path.as_bytes()); | 227 | hmac.update(claims.repo_path.as_bytes()); |
204 | hmac.update([claims.operation as u8]); | ||
205 | hmac.update(claims.expires_at.timestamp().to_be_bytes()); | 228 | hmac.update(claims.expires_at.timestamp().to_be_bytes()); |
206 | Some(hmac.finalize().into()) | 229 | Some(hmac.finalize().into()) |
207 | } | 230 | } |
@@ -280,9 +303,9 @@ impl<const N: usize> From<[u8; N]> for Digest<N> { | |||
280 | } | 303 | } |
281 | } | 304 | } |
282 | 305 | ||
283 | impl<const N: usize> Into<[u8; N]> for Digest<N> { | 306 | impl<const N: usize> From<Digest<N>> for [u8; N] { |
284 | fn into(self) -> [u8; N] { | 307 | fn from(val: Digest<N>) -> Self { |
285 | self.inner | 308 | val.inner |
286 | } | 309 | } |
287 | } | 310 | } |
288 | 311 | ||
@@ -304,7 +327,7 @@ impl<const N: usize> ConstantTimeEq for Digest<N> { | |||
304 | 327 | ||
305 | impl<const N: usize> PartialEq for Digest<N> { | 328 | impl<const N: usize> PartialEq for Digest<N> { |
306 | fn eq(&self, other: &Self) -> bool { | 329 | fn eq(&self, other: &Self) -> bool { |
307 | self.ct_eq(&other).into() | 330 | self.ct_eq(other).into() |
308 | } | 331 | } |
309 | } | 332 | } |
310 | 333 | ||