aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Rutger Broekhoff2024-01-24 18:07:09 +0100
committerLibravatar Rutger Broekhoff2024-01-24 18:07:09 +0100
commitdbe5de070b8b4c86abe27bb3378e1685632dfdab (patch)
treeb578aeb36af41cef567bec5b3edabf3ddd460839
parent955ca49ef8a1db0e8791fc21daf1b3d302361593 (diff)
downloadgitolfs3-dbe5de070b8b4c86abe27bb3378e1685632dfdab.tar.gz
gitolfs3-dbe5de070b8b4c86abe27bb3378e1685632dfdab.zip
Write claim validation test
-rw-r--r--rs/common/src/lib.rs16
-rw-r--r--rs/server/src/main.rs45
2 files changed, 42 insertions, 19 deletions
diff --git a/rs/common/src/lib.rs b/rs/common/src/lib.rs
index 27205bd..89c3286 100644
--- a/rs/common/src/lib.rs
+++ b/rs/common/src/lib.rs
@@ -136,9 +136,9 @@ fn parse_hex_exact(value: &str, buf: &mut [u8]) -> Result<(), ParseHexError> {
136 for (i, c) in value.bytes().enumerate() { 136 for (i, c) in value.bytes().enumerate() {
137 if let Some(b) = decode_nibble(c) { 137 if let Some(b) = decode_nibble(c) {
138 if i % 2 == 0 { 138 if i % 2 == 0 {
139 buf[i / 2] |= b; 139 buf[i / 2] |= b << 4;
140 } else { 140 } else {
141 buf[i / 2] = b << 4; 141 buf[i / 2] |= b;
142 } 142 }
143 } else { 143 } else {
144 return Err(ParseHexError::InvalidCharacter); 144 return Err(ParseHexError::InvalidCharacter);
@@ -236,8 +236,16 @@ impl<B: AsRef<[u8]>> fmt::Display for HexFmt<B> {
236 let HexFmt(buf) = self; 236 let HexFmt(buf) = self;
237 for b in buf.as_ref() { 237 for b in buf.as_ref() {
238 let (high, low) = (b >> 4, b & 0xF); 238 let (high, low) = (b >> 4, b & 0xF);
239 let highc = if high < 10 { b'0' + high } else { b'a' + high }; 239 let highc = if high < 10 {
240 let lowc = if low < 10 { b'0' + low } else { b'a' + low }; 240 high + b'0'
241 } else {
242 high - 10 + b'a'
243 };
244 let lowc = if low < 10 {
245 low + b'0'
246 } else {
247 low - 10 + b'a'
248 };
241 f.write_char(highc as char)?; 249 f.write_char(highc as char)?;
242 f.write_char(lowc as char)?; 250 f.write_char(lowc as char)?;
243 } 251 }
diff --git a/rs/server/src/main.rs b/rs/server/src/main.rs
index a8c6aa5..bdf38ef 100644
--- a/rs/server/src/main.rs
+++ b/rs/server/src/main.rs
@@ -279,7 +279,7 @@ struct BatchRequest {
279 hash_algo: HashAlgo, 279 hash_algo: HashAlgo,
280} 280}
281 281
282#[derive(Clone)] 282#[derive(Debug, Clone)]
283struct GitLfsJson<T>(Json<T>); 283struct GitLfsJson<T>(Json<T>);
284 284
285const LFS_MIME: &str = "application/vnd.git-lfs+json"; 285const LFS_MIME: &str = "application/vnd.git-lfs+json";
@@ -306,18 +306,6 @@ fn is_git_lfs_json_mimetype(mimetype: &str) -> bool {
306 let Ok(mime) = mimetype.parse::<mime::Mime>() else { 306 let Ok(mime) = mimetype.parse::<mime::Mime>() else {
307 return false; 307 return false;
308 }; 308 };
309 println!(
310 "MIME type: {:?}; type: {}, subtype: {}, suffix: {}, charset: {}",
311 mime,
312 mime.type_(),
313 mime.subtype(),
314 mime.suffix()
315 .map(|name| name.to_string())
316 .unwrap_or("<no suffix>".to_string()),
317 mime.get_param(mime::CHARSET)
318 .map(|name| name.to_string())
319 .unwrap_or("<no charset>".to_string())
320 );
321 if mime.type_() != mime::APPLICATION 309 if mime.type_() != mime::APPLICATION
322 || mime.subtype() != "vnd.git-lfs" 310 || mime.subtype() != "vnd.git-lfs"
323 || mime.suffix() != Some(mime::JSON) 311 || mime.suffix() != Some(mime::JSON)
@@ -371,7 +359,7 @@ impl<T: Serialize> IntoResponse for GitLfsJson<T> {
371 } 359 }
372} 360}
373 361
374#[derive(Serialize)] 362#[derive(Debug, Serialize)]
375struct GitLfsErrorData<'a> { 363struct GitLfsErrorData<'a> {
376 message: &'a str, 364 message: &'a str,
377} 365}
@@ -841,7 +829,6 @@ pub struct VerifyClaimsInput<'a> {
841 pub repo_path: &'a str, 829 pub repo_path: &'a str,
842} 830}
843 831
844// Note: expires_at is ignored.
845fn verify_claims( 832fn verify_claims(
846 conf: &AuthorizationConfig, 833 conf: &AuthorizationConfig,
847 claims: &VerifyClaimsInput, 834 claims: &VerifyClaimsInput,
@@ -992,3 +979,31 @@ fn test_deserialize() {
992 expected 979 expected
993 ); 980 );
994} 981}
982
983#[test]
984fn test_validate_claims() {
985 let key = "00232f7a019bd34e3921ee6c5f04caf48a4489d1be5d1999038950a7054e0bfea369ce2becc0f13fd3c69f8af2384a25b7ac2d52eb52c33722f3c00c50d4c9c2";
986 let key: common::Key = key.parse().unwrap();
987
988 let expires_at = Utc::now() + std::time::Duration::from_secs(5 * 60);
989 let claims = common::Claims {
990 expires_at,
991 repo_path: "lfs-test.git",
992 specific_claims: common::SpecificClaims::BatchApi(common::Operation::Download),
993 };
994 let tag = common::generate_tag(claims, &key).unwrap();
995 let header_value = format!("Gitolfs3-Hmac-Sha256 {tag} {}", expires_at.timestamp());
996
997 let conf = AuthorizationConfig {
998 key,
999 trusted_forwarded_hosts: HashSet::new(),
1000 };
1001 let claims = VerifyClaimsInput {
1002 repo_path: "lfs-test.git",
1003 specific_claims: common::SpecificClaims::BatchApi(common::Operation::Download),
1004 };
1005 let mut headers = HeaderMap::new();
1006 headers.insert(header::AUTHORIZATION, header_value.try_into().unwrap());
1007
1008 assert!(verify_claims(&conf, &claims, &headers).unwrap());
1009}