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.

94 lines
2.8 KiB

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