Skip to content

Commit 7ab071c

Browse files
committed
Add AuthException
It will be used when an unauthorized request is made or authentication from headers fails.
1 parent 0718590 commit 7ab071c

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() {
1414
#[cfg(genproto)]
1515
fn generate_protos() {
1616
download_file(
17-
"https://raw.githubusercontent.com/lightningdevkit/vss-server/cb1159c3b1835c66a857b25b114f15d18d2a4297/app/src/main/proto/vss.proto",
17+
"https://raw.githubusercontent.com/lightningdevkit/vss-server/7f492fcac0c561b212f49ca40f7d16075822440f/app/src/main/proto/vss.proto",
1818
"src/proto/vss.proto",
1919
).unwrap();
2020

src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ pub enum VssError {
1919
/// Please refer to [`ErrorCode::ConflictException`].
2020
ConflictError(String),
2121

22+
/// Please refer to [`ErrorCode::AuthException`].
23+
AuthError(String),
24+
2225
/// Please refer to [`ErrorCode::InternalServerException`].
2326
InternalServerError(String),
2427

@@ -53,6 +56,9 @@ impl Display for VssError {
5356
VssError::ConflictError(message) => {
5457
write!(f, "Potential version conflict in write operation: {}", message)
5558
}
59+
VssError::AuthError(message) => {
60+
write!(f, "Authentication or Authorization failure: {}", message)
61+
}
5662
VssError::InternalServerError(message) => {
5763
write!(f, "InternalServerError: {}", message)
5864
}
@@ -71,6 +77,7 @@ impl From<ErrorResponse> for VssError {
7177
ErrorCode::NoSuchKeyException => VssError::NoSuchKeyError(error_response.message),
7278
ErrorCode::InvalidRequestException => VssError::InvalidRequestError(error_response.message),
7379
ErrorCode::ConflictException => VssError::ConflictError(error_response.message),
80+
ErrorCode::AuthException => VssError::AuthError(error_response.message),
7481
ErrorCode::InternalServerException => VssError::InternalServerError(error_response.message),
7582
_ => VssError::InternalError(format!(
7683
"VSS responded with an unknown error code: {}, message: {}",

src/types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,8 @@ pub enum ErrorCode {
348348
InternalServerException = 3,
349349
/// Used when the specified `key` in a `GetObjectRequest` does not exist.
350350
NoSuchKeyException = 4,
351+
/// Used when authentication fails or in case of an unauthorized request.
352+
AuthException = 5,
351353
}
352354
impl ErrorCode {
353355
/// String value of the enum field names used in the ProtoBuf definition.
@@ -361,6 +363,7 @@ impl ErrorCode {
361363
ErrorCode::InvalidRequestException => "INVALID_REQUEST_EXCEPTION",
362364
ErrorCode::InternalServerException => "INTERNAL_SERVER_EXCEPTION",
363365
ErrorCode::NoSuchKeyException => "NO_SUCH_KEY_EXCEPTION",
366+
ErrorCode::AuthException => "AUTH_EXCEPTION",
364367
}
365368
}
366369
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -371,6 +374,7 @@ impl ErrorCode {
371374
"INVALID_REQUEST_EXCEPTION" => Some(Self::InvalidRequestException),
372375
"INTERNAL_SERVER_EXCEPTION" => Some(Self::InternalServerException),
373376
"NO_SUCH_KEY_EXCEPTION" => Some(Self::NoSuchKeyException),
377+
"AUTH_EXCEPTION" => Some(Self::AuthException),
374378
_ => None,
375379
}
376380
}

tests/tests.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,56 @@ mod tests {
255255
mock_server.expect(4).assert();
256256
}
257257

258+
#[tokio::test]
259+
async fn test_auth_err_handling() {
260+
let base_url = mockito::server_url();
261+
let vss_client = VssClient::new(&base_url, retry_policy());
262+
263+
// Invalid Request Error
264+
let error_response =
265+
ErrorResponse { error_code: ErrorCode::AuthException.into(), message: "AuthException".to_string() };
266+
let mock_server = mockito::mock("POST", Matcher::Any)
267+
.with_status(400)
268+
.with_body(&error_response.encode_to_vec())
269+
.create();
270+
271+
let get_result = vss_client
272+
.get_object(&GetObjectRequest { store_id: "store".to_string(), key: "k1".to_string() })
273+
.await;
274+
assert!(matches!(get_result.unwrap_err(), VssError::AuthError { .. }));
275+
276+
let put_result = vss_client
277+
.put_object(&PutObjectRequest {
278+
store_id: "store".to_string(),
279+
global_version: Some(4),
280+
transaction_items: vec![KeyValue { key: "k1".to_string(), version: 2, value: b"k1v3".to_vec() }],
281+
delete_items: vec![],
282+
})
283+
.await;
284+
assert!(matches!(put_result.unwrap_err(), VssError::AuthError { .. }));
285+
286+
let delete_result = vss_client
287+
.delete_object(&DeleteObjectRequest {
288+
store_id: "store".to_string(),
289+
key_value: Some(KeyValue { key: "k1".to_string(), version: 2, value: b"k1v3".to_vec() }),
290+
})
291+
.await;
292+
assert!(matches!(delete_result.unwrap_err(), VssError::AuthError { .. }));
293+
294+
let list_result = vss_client
295+
.list_key_versions(&ListKeyVersionsRequest {
296+
store_id: "store".to_string(),
297+
page_size: Some(5),
298+
page_token: None,
299+
key_prefix: Some("k".into()),
300+
})
301+
.await;
302+
assert!(matches!(list_result.unwrap_err(), VssError::AuthError { .. }));
303+
304+
// Verify 4 requests hit the server
305+
mock_server.expect(4).assert();
306+
}
307+
258308
#[tokio::test]
259309
async fn test_conflict_err_handling() {
260310
let base_url = mockito::server_url();
@@ -401,7 +451,10 @@ mod tests {
401451
.skip_retry_on_error(|e| {
402452
matches!(
403453
e,
404-
VssError::NoSuchKeyError(..) | VssError::InvalidRequestError(..) | VssError::ConflictError(..)
454+
VssError::NoSuchKeyError(..)
455+
| VssError::InvalidRequestError(..)
456+
| VssError::ConflictError(..)
457+
| VssError::AuthError(..)
405458
)
406459
})
407460
}

0 commit comments

Comments
 (0)