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
3.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #[macro_use]
  2. extern crate diesel;
  3. #[macro_use]
  4. extern crate derive_new;
  5. extern crate bcrypt;
  6. extern crate custom_error;
  7. extern crate regex;
  8. extern crate validator;
  9. use actix_web::{middleware, web, App, HttpServer, cookie::SameSite};
  10. use actix_web_httpauth::middleware::HttpAuthentication;
  11. use actix_identity::{CookieIdentityPolicy, IdentityService};
  12. use rand::Rng;
  13. use actix_files as fs;
  14. use diesel::prelude::*;
  15. use diesel::r2d2::{self, ConnectionManager};
  16. use listenfd::ListenFd;
  17. use types::DbPool;
  18. mod actions;
  19. mod errors;
  20. mod middlewares;
  21. mod models;
  22. mod routes;
  23. mod schema;
  24. mod types;
  25. mod utils;
  26. #[macro_use]
  27. extern crate log;
  28. #[derive(Clone)]
  29. pub struct AppConfig {
  30. hash_cost: u32,
  31. pool: DbPool,
  32. }
  33. #[actix_rt::main]
  34. async fn main() -> std::io::Result<()> {
  35. std::env::set_var("RUST_LOG", "debug");
  36. env_logger::init();
  37. dotenv::dotenv().ok();
  38. let basic_auth_middleware =
  39. HttpAuthentication::basic(utils::auth::validator);
  40. // set up database connection pool
  41. let connspec =
  42. std::env::var("DATABASE_URL").expect("DATABASE_URL NOT FOUND");
  43. let manager = ConnectionManager::<SqliteConnection>::new(connspec);
  44. let pool = r2d2::Pool::builder()
  45. .build(manager)
  46. .expect("Failed to create pool.");
  47. diesel_migrations::run_pending_migrations(&pool.get().unwrap())
  48. .expect("Error running migrations");
  49. let hash_cost = std::env::var("HASH_COST")
  50. .map_err(|e| e.to_string())
  51. .and_then(|x| x.parse::<u32>().map_err(|e| e.to_string()))
  52. .unwrap_or_else(|_| {
  53. info!("Error parsing hash cost env variable, or it is not set. Using default cost of 8");
  54. 8
  55. });
  56. let config: AppConfig = AppConfig { pool, hash_cost };
  57. let addr = std::env::var("BIND_ADDRESS").expect("BIND ADDRESS NOT FOUND");
  58. info!("Starting server {}", addr);
  59. let private_key = rand::thread_rng().gen::<[u8; 32]>();
  60. let app = move || {
  61. App::new()
  62. .data(config.clone())
  63. .wrap(IdentityService::new(
  64. CookieIdentityPolicy::new(&private_key)
  65. .name("my-app-auth")
  66. .secure(false)
  67. .same_site(SameSite::Lax)
  68. ))
  69. .wrap(middleware::Logger::default())
  70. .service(
  71. web::scope("/api/authzd") // endpoint requiring authentication
  72. .wrap(basic_auth_middleware.clone())
  73. .service(routes::users::get_user)
  74. .service(routes::users::get_all_users),
  75. )
  76. .service(web::scope("/api/public")) // public endpoint - not implemented yet
  77. .service(routes::auth::login)
  78. .service(routes::auth::logout)
  79. .service(routes::auth::index)
  80. .service(routes::users::add_user)
  81. .service(fs::Files::new("/", "./static"))
  82. };
  83. // HttpServer::new(app).bind(addr)?.run().await
  84. let mut listenfd = ListenFd::from_env();
  85. let mut server = HttpServer::new(app);
  86. server = if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
  87. server.listen(l)?
  88. } else {
  89. server.bind(addr)?
  90. };
  91. server.run().await
  92. }