Advertisement
SpiderLordCoder1st

Untitled

May 17th, 2025
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.75 KB | None | 0 0
  1.  
  2. const SECRET: &str = "randomString";
  3.  
  4. #[derive(Deserialize, Serialize)]
  5. pub struct Claims {
  6. pub exp: usize,
  7. pub iat: usize,
  8. pub user: String,
  9. }
  10.  
  11. #[derive(Clone, Debug)]
  12. pub struct User {
  13. pub username: String,
  14. pub password_hash: String,
  15. }
  16.  
  17. impl AuthUser for User {
  18. type Id = String;
  19. fn id(&self) -> Self::Id {
  20. self.username.clone()
  21. }
  22. fn session_auth_hash(&self) -> &[u8] {
  23. self.password_hash.as_bytes()
  24. }
  25. }
  26.  
  27. fn resolve_jwt(token: &str) -> Result<TokenData<Claims>, StatusCode> {
  28. decode::<Claims>(
  29. token,
  30. &DecodingKey::from_secret(SECRET.as_bytes()),
  31. &Validation::default(),
  32. )
  33. .map_err(|_| StatusCode::UNAUTHORIZED)
  34. }
  35.  
  36. fn retrive_user(username: String) -> Option<User> {
  37. Some(User {
  38. username,
  39. password_hash: "".into(),
  40. })
  41. }
  42.  
  43. pub fn verify_password(password: String, hash: String) -> Result<bool, BcryptError> {
  44. verify(password, &hash)
  45. }
  46.  
  47. fn encode_token(user: String) -> Result<String, StatusCode> {
  48. let now = Utc::now();
  49. let exp = (now + OtherDuration::hours(24)).timestamp() as usize;
  50. let iat = now.timestamp() as usize;
  51. let claims = Claims { exp, iat, user };
  52. encode(
  53. &Header::default(),
  54. &claims,
  55. &EncodingKey::from_secret(SECRET.as_bytes()),
  56. )
  57. .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)
  58. }
  59.  
  60. pub struct JwtToken(pub String);
  61.  
  62. pub async fn sign_in(
  63. State(_state): State<Backend>,
  64. Json(request): Json<LoginData>,
  65. ) -> Result<Json<ResponseMessage>, StatusCode> {
  66. let user = retrive_user(request.user.clone()).ok_or(StatusCode::UNAUTHORIZED)?;
  67. if !verify_password(request.password, user.password_hash.clone())
  68. .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
  69. {
  70. return Err(StatusCode::UNAUTHORIZED);
  71. }
  72. let token = encode_token(user.username)?;
  73. Ok(Json(ResponseMessage { response: token }))
  74. }
  75.  
  76. #[derive(Debug, Deserialize, Clone)]
  77. pub struct LoginData {
  78. pub user: String,
  79. pub password: String,
  80. }
  81.  
  82.  
  83.  
  84. #[derive(Clone, Default)]
  85. pub struct Backend {
  86. pub users: HashMap<String, User>,
  87. }
  88.  
  89. #[async_trait]
  90. impl AuthnBackend for Backend {
  91. type User = User;
  92. type Credentials = String;
  93. type Error = Infallible;
  94.  
  95. async fn authenticate(
  96. &self,
  97. token: Self::Credentials,
  98. ) -> Result<Option<Self::User>, Self::Error> {
  99. let user = resolve_jwt(&token)
  100. .ok()
  101. .and_then(|data| retrive_user(data.claims.user));
  102. Ok(user)
  103. }
  104.  
  105. async fn get_user(
  106. &self,
  107. user_id: &<Self::User as AuthUser>::Id,
  108. ) -> Result<Option<Self::User>, Self::Error> {
  109. Ok(self.users.get(user_id).cloned())
  110. }
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement