mirror of
				https://github.com/dani-garcia/vaultwarden.git
				synced 2025-10-31 02:08:20 +02:00 
			
		
		
		
	Implemented better errors for JWT
This commit is contained in:
		
							
								
								
									
										43
									
								
								src/auth.rs
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								src/auth.rs
									
									
									
									
									
								
							| @@ -7,6 +7,7 @@ use chrono::Duration; | ||||
| use jsonwebtoken::{self, Algorithm, Header}; | ||||
| use serde::ser::Serialize; | ||||
|  | ||||
| use crate::error::{Error, MapResult}; | ||||
| use crate::CONFIG; | ||||
|  | ||||
| const JWT_ALGORITHM: Algorithm = Algorithm::RS256; | ||||
| @@ -31,11 +32,11 @@ lazy_static! { | ||||
| pub fn encode_jwt<T: Serialize>(claims: &T) -> String { | ||||
|     match jsonwebtoken::encode(&JWT_HEADER, claims, &PRIVATE_RSA_KEY) { | ||||
|         Ok(token) => token, | ||||
|         Err(e) => panic!("Error encoding jwt {}", e) | ||||
|         Err(e) => panic!("Error encoding jwt {}", e), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub fn decode_jwt(token: &str) -> Result<JWTClaims, String> { | ||||
| pub fn decode_jwt(token: &str) -> Result<JWTClaims, Error> { | ||||
|     let validation = jsonwebtoken::Validation { | ||||
|         leeway: 30, // 30 seconds | ||||
|         validate_exp: true, | ||||
| @@ -47,16 +48,12 @@ pub fn decode_jwt(token: &str) -> Result<JWTClaims, String> { | ||||
|         algorithms: vec![JWT_ALGORITHM], | ||||
|     }; | ||||
|  | ||||
|     match jsonwebtoken::decode(token, &PUBLIC_RSA_KEY, &validation) { | ||||
|         Ok(decoded) => Ok(decoded.claims), | ||||
|         Err(msg) => { | ||||
|             error!("Error validating jwt - {:#?}", msg); | ||||
|             Err(msg.to_string()) | ||||
|         } | ||||
|     } | ||||
|     jsonwebtoken::decode(token, &PUBLIC_RSA_KEY, &validation) | ||||
|         .map(|d| d.claims) | ||||
|         .map_res("Error decoding login JWT") | ||||
| } | ||||
|  | ||||
| pub fn decode_invite_jwt(token: &str) -> Result<InviteJWTClaims, String> { | ||||
| pub fn decode_invite_jwt(token: &str) -> Result<InviteJWTClaims, Error> { | ||||
|     let validation = jsonwebtoken::Validation { | ||||
|         leeway: 30, // 30 seconds | ||||
|         validate_exp: true, | ||||
| @@ -68,13 +65,9 @@ pub fn decode_invite_jwt(token: &str) -> Result<InviteJWTClaims, String> { | ||||
|         algorithms: vec![JWT_ALGORITHM], | ||||
|     }; | ||||
|  | ||||
|     match jsonwebtoken::decode(token, &PUBLIC_RSA_KEY, &validation) { | ||||
|         Ok(decoded) => Ok(decoded.claims), | ||||
|         Err(msg) => { | ||||
|             error!("Error validating jwt - {:#?}", msg); | ||||
|             Err(msg.to_string()) | ||||
|         } | ||||
|     } | ||||
|     jsonwebtoken::decode(token, &PUBLIC_RSA_KEY, &validation)  | ||||
|         .map(|d| d.claims) | ||||
|         .map_res("Error decoding invite JWT") | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize, Deserialize)] | ||||
| @@ -150,7 +143,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers { | ||||
|             CONFIG.domain.clone() | ||||
|         } else if let Some(referer) = headers.get_one("Referer") { | ||||
|             referer.to_string() | ||||
|         } else {    | ||||
|         } else { | ||||
|             // Try to guess from the headers | ||||
|             use std::env; | ||||
|  | ||||
| @@ -185,7 +178,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers { | ||||
|         // Check JWT token is valid and get device and user from it | ||||
|         let claims: JWTClaims = match decode_jwt(access_token) { | ||||
|             Ok(claims) => claims, | ||||
|             Err(_) => err_handler!("Invalid claim") | ||||
|             Err(_) => err_handler!("Invalid claim"), | ||||
|         }; | ||||
|  | ||||
|         let device_uuid = claims.device; | ||||
| @@ -193,17 +186,17 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers { | ||||
|  | ||||
|         let conn = match request.guard::<DbConn>() { | ||||
|             Outcome::Success(conn) => conn, | ||||
|             _ => err_handler!("Error getting DB") | ||||
|             _ => err_handler!("Error getting DB"), | ||||
|         }; | ||||
|  | ||||
|         let device = match Device::find_by_uuid(&device_uuid, &conn) { | ||||
|             Some(device) => device, | ||||
|             None => err_handler!("Invalid device id") | ||||
|             None => err_handler!("Invalid device id"), | ||||
|         }; | ||||
|  | ||||
|         let user = match User::find_by_uuid(&user_uuid, &conn) { | ||||
|             Some(user) => user, | ||||
|             None => err_handler!("Device has no user associated") | ||||
|             None => err_handler!("Device has no user associated"), | ||||
|         }; | ||||
|  | ||||
|         if user.security_stamp != claims.sstamp { | ||||
| @@ -248,11 +241,11 @@ impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders { | ||||
|                             None => err_handler!("The current user isn't member of the organization") | ||||
|                         }; | ||||
|  | ||||
|                         Outcome::Success(Self{ | ||||
|                         Outcome::Success(Self { | ||||
|                             host: headers.host, | ||||
|                             device: headers.device, | ||||
|                             user: headers.user, | ||||
|                             org_user_type: {  | ||||
|                             org_user_type: { | ||||
|                                 if let Some(org_usr_type) = UserOrgType::from_i32(org_user.type_) { | ||||
|                                     org_usr_type | ||||
|                                 } else { // This should only happen if the DB is corrupted | ||||
| @@ -260,7 +253,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for OrgHeaders { | ||||
|                                 } | ||||
|                             }, | ||||
|                         }) | ||||
|                     }, | ||||
|                     } | ||||
|                     _ => err_handler!("Error getting the organization id"), | ||||
|                 } | ||||
|             } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user