user.rs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. use uuid::Uuid;
  2. use chrono::{DateTime, Utc};
  3. use sqlx::{PgPool, FromRow};
  4. use serde::Serialize;
  5. use crate::http_error::HttpError;
  6. #[derive(FromRow)]
  7. pub struct User {
  8. id: Uuid,
  9. session_token: Uuid,
  10. name: String,
  11. email: String,
  12. pass_hash: String,
  13. tokens: u64,
  14. created_at: DateTime<Utc>
  15. }
  16. #[derive(Serialize)]
  17. pub struct ResponseUser {
  18. id: String,
  19. name: String,
  20. email: String
  21. }
  22. impl User {
  23. pub fn new(name: String, email: String, pass_hash: String) -> Self {
  24. Self {
  25. id: Uuid::now_v7(),
  26. session_token: Uuid::new_v4(),
  27. name: name,
  28. email: email.to_lowercase(),
  29. pass_hash: pass_hash,
  30. tokens: 0,
  31. created_at: Utc::now()
  32. }
  33. }
  34. pub async fn insert_one(&self, db: &PgPool) -> Result<(), HttpError> {
  35. let result = sqlx::query(
  36. "INSERT into users(id, session_token, name, email, pass_hash, tokens, created_at)
  37. VALUES($1, $2, $3, $4, $5, $6, $7)"
  38. )
  39. .bind(&self.id)
  40. .bind(&self.session_token)
  41. .bind(&self.name)
  42. .bind(&self.email)
  43. .bind(&self.pass_hash)
  44. .bind(&self.tokens)
  45. .bind(&self.created_at)
  46. .execute(db)
  47. .await;
  48. match result {
  49. Ok(_) => Ok(()),
  50. Err(sqlx::Error::Database(db_err)) if db_err.code().as_deref() == Some("23505") => {
  51. Err(HttpError::InvalidInput("User with this email already exists".into()))
  52. },
  53. Err(e) => Err(HttpError::Database(e.into()))
  54. }
  55. }
  56. pub async fn find_one_by_session(
  57. db: &PgPool,
  58. user_id: Uuid,
  59. session_token: Uuid
  60. ) -> Result<User, HttpError> {
  61. let user = sqlx::query_as::<_, User>(
  62. "SELECT *
  63. FROM users
  64. WHERE id = $1
  65. and session_token = $2"
  66. )
  67. .bind(user_id)
  68. .bind(session_token)
  69. .fetch_one(db)
  70. .await?;
  71. Ok(user)
  72. }
  73. pub fn response(self) -> ResponseUser {
  74. ResponseUser {
  75. id: self.id.to_string(),
  76. name: self.name,
  77. email: self.email
  78. }
  79. }
  80. }