You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.6 KiB

  1. use diesel::prelude::*;
  2. use crate::errors;
  3. use crate::models;
  4. use bcrypt::{hash, verify, DEFAULT_COST};
  5. use std::rc::Rc;
  6. pub fn find_user_by_uid(
  7. uid: i32,
  8. conn: &SqliteConnection,
  9. ) -> Result<Option<models::UserDTO>, errors::DomainError> {
  10. use crate::schema::users::dsl::*;
  11. let maybe_user = users
  12. .select((name, created_at))
  13. .find(uid)
  14. .first::<models::UserDTO>(conn)
  15. .optional();
  16. Ok(maybe_user?)
  17. }
  18. pub fn _find_user_by_name(
  19. user_name: String,
  20. conn: &SqliteConnection,
  21. ) -> Result<Option<models::UserDTO>, errors::DomainError> {
  22. let maybe_user = query::_get_user_by_name(&user_name)
  23. .first::<models::UserDTO>(conn)
  24. .optional();
  25. Ok(maybe_user?)
  26. }
  27. pub fn get_all(
  28. conn: &SqliteConnection,
  29. ) -> Result<Option<Vec<models::UserDTO>>, errors::DomainError> {
  30. use crate::schema::users::dsl::*;
  31. Ok(users
  32. .select((name, created_at))
  33. .load::<models::UserDTO>(conn)
  34. .optional()?)
  35. }
  36. /// Run query using Diesel to insert a new database row and return the result.
  37. pub fn insert_new_user(
  38. mut nu: Rc<models::NewUser>,
  39. conn: &SqliteConnection,
  40. ) -> Result<models::UserDTO, errors::DomainError> {
  41. // It is common when using Diesel with Actix web to import schema-related
  42. // modules inside a function's scope (rather than the normal module's scope)
  43. // to prevent import collisions and namespace pollution.
  44. use crate::schema::users::dsl::*;
  45. let mut nu2 = Rc::make_mut(&mut nu);
  46. nu2.password = hash(&nu2.password, DEFAULT_COST)?;
  47. diesel::insert_into(users)
  48. .values(nu.as_ref())
  49. .execute(conn)?;
  50. let user =
  51. query::_get_user_by_name(&nu.name).first::<models::UserDTO>(conn)?;
  52. Ok(user)
  53. }
  54. pub fn verify_password<'a>(
  55. user_name: &'a String,
  56. given_password: &'a String,
  57. conn: &SqliteConnection,
  58. ) -> Result<bool, errors::DomainError> {
  59. use crate::schema::users::dsl::*;
  60. let password_hash = users
  61. .select(password)
  62. .filter(name.eq(user_name))
  63. .first::<String>(conn)?;
  64. Ok(verify(given_password, password_hash.as_str())?)
  65. }
  66. mod query {
  67. use diesel::prelude::*;
  68. use diesel::sql_types::Text;
  69. use diesel::sql_types::Timestamp;
  70. use diesel::sqlite::Sqlite;
  71. /// <'a, B, T> where a = lifetime, B = Backend, T = SQL data types
  72. type Query<'a, B, T> = crate::schema::users::BoxedQuery<'a, B, T>;
  73. pub fn _get_user_by_name(
  74. user_name: &String,
  75. ) -> Query<Sqlite, (Text, Timestamp)> {
  76. use crate::schema::users::dsl::*;
  77. users
  78. .select((name, created_at))
  79. .filter(name.eq(user_name))
  80. .into_boxed()
  81. }
  82. }