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.

108 lines
2.9 KiB

  1. #![forbid(unsafe_code)]
  2. #[macro_use]
  3. extern crate diesel;
  4. #[macro_use]
  5. extern crate derive_new;
  6. #[macro_use]
  7. extern crate log;
  8. mod actions;
  9. mod errors;
  10. mod middlewares;
  11. pub mod models;
  12. mod routes;
  13. mod schema;
  14. mod services;
  15. mod types;
  16. mod utils;
  17. use actix_files as fs;
  18. use actix_identity::{CookieIdentityPolicy, IdentityService};
  19. use actix_web::{cookie::SameSite, middleware, web, App, HttpServer};
  20. use actix_web::{middleware::Logger, web::ServiceConfig};
  21. use rand::Rng;
  22. use serde::Deserialize;
  23. use types::DbPool;
  24. build_info::build_info!(pub fn get_build_info);
  25. #[derive(Deserialize, Debug, Clone)]
  26. pub struct EnvConfig {
  27. pub database_url: String,
  28. pub http_host: String,
  29. #[serde(default = "default_hash_cost")]
  30. pub hash_cost: u8,
  31. }
  32. #[derive(Deserialize, Debug, Clone)]
  33. pub struct AppConfig {
  34. pub hash_cost: u8,
  35. }
  36. #[derive(Clone)]
  37. pub struct AppData {
  38. pub config: AppConfig,
  39. pub pool: DbPool,
  40. }
  41. pub fn default_hash_cost() -> u8 {
  42. 8
  43. }
  44. pub fn configure_app(app_data: AppData) -> Box<dyn Fn(&mut ServiceConfig)> {
  45. Box::new(move |cfg: &mut ServiceConfig| {
  46. cfg.data(app_data.clone())
  47. .service(
  48. web::scope("/api")
  49. .service(
  50. web::scope("/users")
  51. .route(
  52. "",
  53. web::get().to(routes::users::get_all_users),
  54. )
  55. .route(
  56. "/{user_id}",
  57. web::get().to(routes::users::get_user),
  58. ),
  59. )
  60. .route(
  61. "/build-info",
  62. web::get().to(routes::misc::build_info_req),
  63. ),
  64. )
  65. // .route("/api/users/get", web::get().to(user_controller.get_user.into()))
  66. .service(web::scope("/api/public")) // public endpoint - not implemented yet
  67. .service(routes::auth::login)
  68. .service(routes::auth::logout)
  69. .service(routes::auth::index)
  70. .service(routes::users::add_user)
  71. .service(fs::Files::new("/", "./static"));
  72. })
  73. }
  74. pub fn id_service(
  75. private_key: &[u8],
  76. ) -> actix_identity::IdentityService<CookieIdentityPolicy> {
  77. IdentityService::new(
  78. CookieIdentityPolicy::new(&private_key)
  79. .name("my-app-auth")
  80. .secure(false)
  81. .same_site(SameSite::Lax),
  82. )
  83. }
  84. pub fn app_logger() -> Logger {
  85. middleware::Logger::default()
  86. }
  87. pub async fn run(addr: String, app_data: AppData) -> std::io::Result<()> {
  88. info!("Starting server at {}", addr);
  89. let private_key = rand::thread_rng().gen::<[u8; 32]>();
  90. let app = move || {
  91. App::new()
  92. .configure(configure_app(app_data.clone()))
  93. .wrap(id_service(&private_key))
  94. .wrap(app_logger())
  95. };
  96. HttpServer::new(app).bind(addr)?.run().await
  97. }