Compare commits

...

5 Commits

23 changed files with 293 additions and 247 deletions

View File

@ -5,13 +5,19 @@ use super::migrate::RunMigrations;
#[derive(Clone)]
pub struct Postgres {
pool: PgPool,
pub pool: PgPool,
}
impl Postgres {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
pub async fn init(database_url: &str) -> Self {
let pool = PgPool::connect(database_url).await.unwrap();
Self::new(pool)
}
}
#[async_trait::async_trait]

View File

@ -1,60 +0,0 @@
use std::str::FromStr;
use actix_web::{get, http::header, post, web, HttpResponse};
use crate::forge::auth::adapter::out::forge::SupportedForges;
use crate::forge::auth::application::port::input::ui::{
errors::*, login::RequestAuthorizationInterface,
};
use crate::forge::auth::application::services::request_authorization::command::RequestAuthorizationCommand;
use super::{templates::login::LoginCtxFactory, ServiceFactory, WebCtx};
use crate::ActixCtx;
#[async_trait::async_trait]
impl RequestAuthorizationInterface for WebCtx {
#[tracing::instrument(name = "web adapter request_oauth_authorization", skip(self))]
async fn request_oauth_authorization(&self, forge_name: String) -> InUIResult<HttpResponse> {
let service = ServiceFactory::request_authorization(
SupportedForges::from_str(&forge_name).map_err(|_| InUIError::BadRequest)?,
self,
)?;
log::info!("service found");
let cmd = RequestAuthorizationCommand::new_command(forge_name)?;
let auth_page = service.request_authorization(cmd).await?;
Ok(HttpResponse::Found()
.insert_header((header::LOCATION, auth_page.as_str()))
.finish())
}
}
#[get("/login")]
async fn login_page(ctx: ActixCtx) -> InUIResult<HttpResponse> {
let template_ctx =
LoginCtxFactory::get_ctx(ctx.adapters.forges.get_supported_forges(), &ctx.routes);
let page = ctx
.templates
.login_page
.get_login_page(template_ctx)
.unwrap();
Ok(HttpResponse::Ok()
.append_header((header::CONTENT_TYPE, "text/html; charset=UTF-8"))
.body(page))
}
#[post("/oauth/{forge}/login")]
#[tracing::instrument(name = "web handler request_oauth_authorization", skip(ctx))]
async fn request_oauth_authorization(
ctx: ActixCtx,
forge_name: web::Path<String>,
) -> InUIResult<HttpResponse> {
ctx.request_oauth_authorization(forge_name.into_inner())
.await
}
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(login_page);
cfg.service(request_oauth_authorization);
}

View File

@ -0,0 +1,55 @@
use std::sync::Arc;
use actix_web::{http::header, HttpResponse};
use url::Url;
use crate::forge::auth::application::port::input::ui::{
errors::*, login::RequestAuthorizationInterface,
};
use crate::forge::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
use crate::forge::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
use crate::forge::auth::application::services::request_authorization::{
command::RequestAuthorizationCommand, service::RequestAuthorizationService,
RequestAuthorizationUserCase,
};
//use crate::forge::auth::application::services::request_authorization::command::RequestAuthorizationCommand;
pub struct RequestAuthorizationHandler {
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
process_authorization_response_redirect_uri: Url,
}
impl RequestAuthorizationHandler {
pub fn new(
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
process_authorization_response_redirect_uri: Url,
) -> Self {
Self {
save_oauth_state_adapter,
oauth_auth_req_uri_adapter,
process_authorization_response_redirect_uri,
}
}
}
#[async_trait::async_trait]
impl RequestAuthorizationInterface for RequestAuthorizationHandler {
#[tracing::instrument(name = "web adapter request_oauth_authorization", skip(self))]
async fn request_oauth_authorization(&self, forge_name: String) -> InUIResult<HttpResponse> {
let service = RequestAuthorizationService::new(
self.save_oauth_state_adapter.clone(),
self.oauth_auth_req_uri_adapter.clone(),
self.process_authorization_response_redirect_uri.clone(),
);
log::info!("service found");
let cmd = RequestAuthorizationCommand::new_command(forge_name)?;
let auth_page = service.request_authorization(cmd).await?;
Ok(HttpResponse::Found()
.insert_header((header::LOCATION, auth_page.as_str()))
.finish())
}
}

View File

@ -0,0 +1,65 @@
use std::sync::Arc;
use actix_web::{get, http::header, post, web, HttpResponse};
use url::Url;
use crate::forge::auth::adapter::input::web::routes::RoutesRepository;
use crate::forge::auth::adapter::out::forge::SupportedForges;
use crate::forge::auth::application::port::input::ui::{
errors::*, login::RequestAuthorizationInterface,
};
use crate::forge::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
use super::template::{LoginCtxFactory, LoginPageInterface};
use crate::ForgeRepository;
#[get("/login")]
#[tracing::instrument(name = "login page handler", skip(forges, routes, template))]
async fn login_page(
forges: web::Data<Arc<ForgeRepository>>,
routes: web::Data<Arc<RoutesRepository>>,
template: web::Data<Arc<dyn LoginPageInterface>>,
) -> InUIResult<HttpResponse> {
let template_ctx = LoginCtxFactory::get_ctx(forges.get_supported_forges(), &routes);
let page = template.get_login_page(template_ctx).unwrap();
Ok(HttpResponse::Ok()
.append_header((header::CONTENT_TYPE, "text/html; charset=UTF-8"))
.body(page))
}
#[post("/oauth/forgejo/login")]
async fn request_oauth_authorization_forgejo(
forge_name: web::Path<String>,
forges: web::Data<Arc<ForgeRepository>>,
save_oauth_state_adapter: web::Data<Arc<dyn SaveOAuthState>>,
routes: web::Data<Arc<RoutesRepository>>,
settings: web::Data<crate::settings::Settings>,
) -> InUIResult<HttpResponse> {
let oauth_auth_req_uri_adapter = &forges
.get_forge(&SupportedForges::Forgejo)
.unwrap()
.oauth_auth_req_uri_adapter;
let process_authorization_response_redirect_uri = Url::parse(&format!(
"{}://{}{}",
"http",
&settings.server.domain,
&routes.process_oauth_authorization_response(&SupportedForges::Forgejo)
))
.map_err(|_| InUIError::InternalServerError)?;
let web_adapter = super::adapter::RequestAuthorizationHandler::new(
save_oauth_state_adapter.as_ref().to_owned(),
oauth_auth_req_uri_adapter.clone(),
process_authorization_response_redirect_uri,
);
web_adapter
.request_oauth_authorization(forge_name.into_inner())
.await
}
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(login_page);
cfg.service(request_oauth_authorization_forgejo);
}

View File

@ -0,0 +1,12 @@
use actix_web::web;
mod adapter;
mod handler;
mod template;
pub use template::register_templates;
pub fn services(cfg: &mut web::ServiceConfig) {
template::load_templates(cfg);
handler::services(cfg);
}

View File

@ -1,36 +1,44 @@
use std::sync::Arc;
use actix_web::web;
use serde::{Deserialize, Serialize};
use crate::forge::auth::adapter::input::web::routes::RoutesRepository;
use crate::forge::auth::adapter::out::forge::SupportedForges;
use super::{tera_context, TEMPLATES};
use crate::forge::auth::adapter::input::web::template::{tera_context, TemplateFile, TEMPLATES};
pub trait LoginPageInterface: Send + Sync {
fn get_login_page(&self, ctx: LoginCtx) -> Result<String, Box<dyn std::error::Error>>;
}
use super::TemplateFile;
const LOGIN_TEMPLATE: TemplateFile = TemplateFile::new("login", "login/page.html");
pub const LOGIN_TEMPLATE: TemplateFile = TemplateFile::new("login", "login.html");
pub fn register_templates(t: &mut tera::Tera) {
println!("registering login template");
LOGIN_TEMPLATE.register(t).expect(LOGIN_TEMPLATE.name);
}
pub fn load_templates(cfg: &mut web::ServiceConfig) {
let t: Arc<dyn LoginPageInterface> = Arc::new(LoginPageTemplate);
cfg.app_data(web::Data::new(t));
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Forge {
struct Forge {
name: String,
path: String,
}
impl Forge {
pub fn new(name: String, path: String) -> Self {
fn new(name: String, path: String) -> Self {
Self { name, path }
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct LoginCtx {
pub forges: Vec<Forge>,
forges: Vec<Forge>,
}
pub struct LoginCtxFactory;
@ -47,7 +55,7 @@ impl LoginCtxFactory {
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct LoginPageTemplate;
struct LoginPageTemplate;
impl LoginPageInterface for LoginPageTemplate {
fn get_login_page(&self, ctx: LoginCtx) -> Result<String, Box<dyn std::error::Error>> {

View File

@ -1,81 +1,20 @@
use std::sync::Arc;
use actix_web::web::{self, Data};
use url::Url;
use crate::forge::auth::adapter::out::db::DBAdapter;
use crate::forge::auth::adapter::out::forge::{ForgeRepository, SupportedForges};
use crate::forge::auth::application::port::input::ui::errors::{InUIError, InUIResult};
use crate::forge::auth::application::services::request_authorization::service::RequestAuthorizationService;
use crate::forge::auth::application::services::request_authorization::RequestAuthorizationUserCase;
use crate::settings::Settings;
use actix_web::web;
pub mod login;
mod routes;
mod templates;
mod template;
use routes::RoutesRepository;
pub type ArcCtx = Arc<WebCtx>;
pub type ActixCtx = Data<ArcCtx>;
pub fn load_ctx() -> impl FnOnce(&mut web::ServiceConfig) {
let routes = web::Data::new(Arc::new(RoutesRepository::default()));
#[derive(Clone)]
pub struct WebCtx {
pub routes: Arc<RoutesRepository>,
pub adapters: Adapters,
pub templates: templates::Templates,
pub settings: Settings,
}
impl WebCtx {
pub fn new_actix_ctx(forges: ForgeRepository, db: DBAdapter, settings: Settings) -> ActixCtx {
let routes = Arc::new(RoutesRepository::default());
Data::new(Arc::new(Self {
routes: routes.clone(),
adapters: Adapters::new(forges, db),
templates: templates::Templates::default(),
settings,
}))
}
}
#[derive(Clone)]
pub struct Adapters {
pub forges: ForgeRepository,
pub db: DBAdapter,
}
impl Adapters {
pub fn new(forges: ForgeRepository, db: DBAdapter) -> Self {
Self { forges, db }
}
}
pub struct ServiceFactory;
impl ServiceFactory {
pub fn request_authorization(
forge_name: SupportedForges,
ctx: &WebCtx,
) -> InUIResult<Arc<dyn RequestAuthorizationUserCase>> {
if let Some(forge) = ctx.adapters.forges.get_forge(&forge_name) {
Ok(Arc::new(RequestAuthorizationService::new(
ctx.adapters.db.save_oauth_state_adapter.clone(),
forge.get_redirect_uri_adapter.clone(),
Url::parse(&format!(
"{}://{}{}",
"http",
&ctx.settings.server.domain,
&ctx.routes.process_oauth_authorization_response(&forge_name)
))
.map_err(|_| InUIError::InternalServerError)?,
)))
} else {
Err(InUIError::BadRequest)
}
}
}
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.configure(login::services);
let f = move |cfg: &mut web::ServiceConfig| {
cfg.app_data(routes);
cfg.configure(login::services);
};
Box::new(f)
}

View File

@ -1,7 +1,10 @@
use lazy_static::lazy_static;
use rust_embed::RustEmbed;
use std::cell::RefCell;
use tera::*;
use serde::Serialize;
pub struct TemplateFile {
pub name: &'static str,
pub path: &'static str,
@ -16,12 +19,12 @@ impl TemplateFile {
t.add_raw_template(self.name, &Templates::get_template(self).expect(self.name))
}
#[cfg(test)]
#[allow(dead_code)]
pub fn register_from_file(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> {
use std::path::Path;
t.add_template_file(Path::new("templates/").join(self.path), Some(self.name))
}
// #[cfg(test)]
// #[allow(dead_code)]
// pub fn register_from_file(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> {
// use std::path::Path;
// t.add_template_file(Path::new("./").join(self.path), Some(self.name))
// }
}
pub const PAYLOAD_KEY: &str = "payload";
@ -40,14 +43,12 @@ lazy_static! {
// errors::register_templates(&mut tera);
tera.autoescape_on(vec![".html", ".sql"]);
super::login::register_templates(&mut tera);
// auth::register_templates(&mut tera);
// gists::register_templates(&mut tera);
tera
};
}
#[derive(RustEmbed)]
#[folder = "src/forge/auth/adapter/input/web/templates/"]
#[folder = "src/forge/auth/adapter/input/web/"]
#[include = "*.html"]
#[exclude = "*.rs"]
struct Templates;
@ -60,3 +61,9 @@ impl Templates {
}
}
}
pub fn tera_context<T: Serialize>(s: &T) -> RefCell<Context> {
let c = RefCell::new(Context::new());
c.borrow_mut().insert(PAYLOAD_KEY, s);
c
}

View File

@ -1,23 +0,0 @@
use std::sync::Arc;
pub mod login;
pub mod setup;
mod utils;
use login::{LoginPageInterface, LoginPageTemplate};
pub use setup::{TemplateFile, PAYLOAD_KEY, TEMPLATES};
pub use utils::tera_context;
#[derive(Clone)]
pub struct Templates {
pub login_page: Arc<dyn LoginPageInterface>,
}
impl Default for Templates {
fn default() -> Self {
Self {
login_page: Arc::new(LoginPageTemplate),
}
}
}

View File

@ -1,11 +0,0 @@
use std::cell::RefCell;
use super::PAYLOAD_KEY;
use serde::Serialize;
use tera::Context;
pub fn tera_context<T: Serialize>(s: &T) -> RefCell<Context> {
let c = RefCell::new(Context::new());
c.borrow_mut().insert(PAYLOAD_KEY, s);
c
}

View File

@ -1,2 +1,31 @@
use std::sync::Arc;
use actix_web::web;
use sqlx::postgres::PgPool;
pub mod input;
pub mod out;
use crate::settings;
use out::db::DBAdapter;
use out::forge::{forgejo::Forgejo, ForgeRepository};
pub fn load_adapters(
pool: PgPool,
settings: &settings::Settings,
) -> impl FnOnce(&mut web::ServiceConfig) {
let forgejo = Forgejo::new(
settings.forges.forgejo.url.clone(),
settings.forges.forgejo.client_id.clone(),
settings.forges.forgejo.client_secret.clone(),
);
let forges = ForgeRepository::new(forgejo);
let f = move |cfg: &mut web::ServiceConfig| {
cfg.app_data(web::Data::new(Arc::new(DBAdapter::new(pool))));
cfg.app_data(web::Data::new(Arc::new(forges.clone())));
cfg.configure(input::web::load_ctx());
};
Box::new(f)
}

View File

@ -1,7 +1,6 @@
use std::sync::Arc;
use sqlx::PgPool;
use url::Url;
use crate::db::migrate::RunMigrations;
use crate::forge::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
@ -15,12 +14,7 @@ pub struct DBAdapter {
}
impl DBAdapter {
pub async fn init(database_url: &str) -> Self {
let pool = PgPool::connect(database_url).await.unwrap();
Self::new(pool)
}
fn new(pool: PgPool) -> Self {
pub fn new(pool: PgPool) -> Self {
let pg_adapter = postgres::DBOutPostgresAdapter::new(pool);
Self {
save_oauth_state_adapter: Arc::new(pg_adapter.clone()),

View File

@ -1,24 +0,0 @@
use url::Url;
use super::Forgejo;
use crate::forge::auth::application::port::out::forge::{
errors::OutForgePortResult, get_redirect_uri::GetRedirectUri,
};
impl GetRedirectUri for Forgejo {
fn get_redirect_uri(
&self,
state: &str,
process_authorization_response_uri: &Url,
) -> OutForgePortResult<Url> {
let mut u = self.url().to_owned();
u.set_path("/login/oauth/authorize");
u.set_query(Some(&format!(
"client_id={}&redirect_uri={}&response_type=code&state={state}",
self.client_id(),
process_authorization_response_uri.as_str()
)));
Ok(u)
}
}

View File

@ -1,6 +1,6 @@
use url::Url;
mod get_redirect_uri;
pub mod oauth_auth_req_uri;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Forgejo {

View File

@ -0,0 +1,54 @@
use url::Url;
use super::Forgejo;
use crate::forge::auth::application::port::out::forge::{
errors::OutForgePortResult, oauth_auth_req_uri::OAuthAuthReqUri,
};
impl OAuthAuthReqUri for Forgejo {
fn oauth_auth_req_uri(
&self,
state: &str,
process_authorization_response_uri: &Url,
) -> OutForgePortResult<Url> {
let mut u = self.url().to_owned();
u.set_path("/login/oauth/authorize/");
u.set_query(Some(&format!(
"client_id={}&redirect_uri={}&response_type=code&state={state}",
self.client_id(),
process_authorization_response_uri.as_str()
)));
Ok(u)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_forgejo_oauth_auth_req_uri() {
let u = Url::parse("https://forgejo").unwrap();
let client_id = "id";
let client_secret = "sec";
let state = "st";
let process_authorization_response_uri = Url::parse("https://forgeflux").unwrap();
let f = Forgejo::new(u.clone(), client_id.into(), client_secret.into());
let oauth_auth_req_uri = f
.oauth_auth_req_uri(state, &process_authorization_response_uri)
.unwrap();
let path = "/login/oauth/authorize";
let q = format!(
"client_id={}&redirect_uri={}&response_type=code&state={state}",
client_id,
process_authorization_response_uri.as_str()
);
assert_eq!(
oauth_auth_req_uri.to_string(),
format!("https://forgejo{path}/?{q}")
);
}
}

View File

@ -5,7 +5,7 @@ use std::sync::Arc;
use derive_more::Display;
use serde::{Deserialize, Serialize};
use crate::forge::auth::application::port::out::forge::get_redirect_uri::GetRedirectUri;
use crate::forge::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
use self::forgejo::Forgejo;
@ -13,7 +13,7 @@ pub mod forgejo;
#[derive(Clone)]
pub struct ForgeAdapter {
pub get_redirect_uri_adapter: Arc<dyn GetRedirectUri>,
pub oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
}
#[derive(Clone, Default)]
@ -44,7 +44,7 @@ impl ForgeRepository {
pub fn new(forgejo: Forgejo) -> Self {
let forgejo_adapter = ForgeAdapter {
get_redirect_uri_adapter: Arc::new(forgejo),
oauth_auth_req_uri_adapter: Arc::new(forgejo),
};
let mut s = Self::default();
s.add_forge(SupportedForges::Forgejo, forgejo_adapter);

View File

@ -1,5 +1,5 @@
pub mod errors;
pub mod get_redirect_uri;
pub mod oauth_auth_req_uri;
pub mod refresh_access_token;
pub mod request_access_token;
@ -10,14 +10,14 @@ pub mod tests {
use super::*;
use errors::*;
use get_redirect_uri::GetRedirectUri;
use oauth_auth_req_uri::OAuthAuthReqUri;
#[derive(Clone, Default)]
pub struct MockForge; // {
#[async_trait::async_trait]
impl GetRedirectUri for MockForge {
fn get_redirect_uri(
impl OAuthAuthReqUri for MockForge {
fn oauth_auth_req_uri(
&self,
state: &str,
process_authorization_response_uri: &Url,

View File

@ -1,8 +1,8 @@
use super::errors::*;
use url::Url;
pub trait GetRedirectUri: Send + Sync {
fn get_redirect_uri(
pub trait OAuthAuthReqUri: Send + Sync {
fn oauth_auth_req_uri(
&self,
state: &str,
process_authorization_response_uri: &Url,

View File

@ -4,7 +4,7 @@ use url::Url;
use crate::forge::auth::application::port::out::db::errors::OutDBPortError;
use crate::forge::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
use crate::forge::auth::application::port::out::forge::get_redirect_uri::GetRedirectUri;
use crate::forge::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
use crate::utils;
use super::{errors::*, RequestAuthorizationUserCase};
@ -14,19 +14,19 @@ const STATE_LEN: usize = 8;
#[derive(Clone)]
pub struct RequestAuthorizationService {
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
get_redirect_uri_adapter: Arc<dyn GetRedirectUri>,
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
process_authorization_response_redirect_uri: Url,
}
impl RequestAuthorizationService {
pub fn new(
save_oauth_state_adapter: Arc<dyn SaveOAuthState>,
get_redirect_uri_adapter: Arc<dyn GetRedirectUri>,
oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
process_authorization_response_redirect_uri: Url,
) -> Self {
Self {
save_oauth_state_adapter,
get_redirect_uri_adapter,
oauth_auth_req_uri_adapter,
process_authorization_response_redirect_uri,
}
}
@ -58,8 +58,8 @@ impl RequestAuthorizationUserCase for RequestAuthorizationService {
}
}
let redirect = self
.get_redirect_uri_adapter
.get_redirect_uri(&state, &self.process_authorization_response_redirect_uri)?;
.oauth_auth_req_uri_adapter
.oauth_auth_req_uri(&state, &self.process_authorization_response_redirect_uri)?;
Ok(redirect)
}
}
@ -78,13 +78,13 @@ mod tests {
#[actix_rt::test]
async fn test_service() {
let save_oauth_state = MockDB::default();
let get_redirect_uri = MockForge::default();
let oauth_auth_req_uri = MockForge;
let url = Url::parse("http://test_service_request_auth").unwrap();
let oauth_provider = "test_service_request_auth_oauth_provider";
let s = RequestAuthorizationService::new(
Arc::new(save_oauth_state.clone()),
Arc::new(get_redirect_uri),
Arc::new(oauth_auth_req_uri),
url.clone(),
);
let cmd = RequestAuthorizationCommand::new_command(oauth_provider.to_owned()).unwrap();
@ -92,7 +92,7 @@ mod tests {
let res = s.request_authorization(cmd).await.unwrap().to_string();
{
let save_oauth_state_ctx = save_oauth_state.calls.read().unwrap();
let call = save_oauth_state_ctx.get(0).unwrap();
let call = save_oauth_state_ctx.first().unwrap();
assert_eq!(
res,
format!("http://test_service_request_auth/?state={}", &call.state)

View File

@ -1,13 +1,13 @@
use std::env;
use actix_web::{middleware, App, HttpServer};
use db::migrate::RunMigrations;
mod db;
mod forge;
mod settings;
mod utils;
pub use crate::forge::auth::adapter::input::web::{services, ActixCtx, WebCtx};
pub use crate::forge::auth::adapter::out::{
db::DBAdapter,
forge::{forgejo::Forgejo, ForgeRepository},
@ -27,26 +27,22 @@ async fn main() {
pretty_env_logger::init();
let forgejo = Forgejo::new(
settings.forges.forgejo.url.clone(),
settings.forges.forgejo.client_id.clone(),
settings.forges.forgejo.client_secret.clone(),
);
let forges = ForgeRepository::new(forgejo);
let db = DBAdapter::init(&settings.database.url).await;
db.migratable().migrate().await;
let ctx = WebCtx::new_actix_ctx(forges, db, settings.clone());
let db = db::sqlx_postgres::Postgres::init(&settings.database.url).await;
db.migrate().await;
let socket_addr = settings.server.get_ip();
HttpServer::new(move || {
App::new()
.wrap(tracing_actix_web::TracingLogger::default())
.wrap(middleware::Compress::default())
.app_data(ctx.clone())
.app_data(actix_web::web::Data::new(settings.clone()))
.wrap(
middleware::DefaultHeaders::new().add(("Permissions-Policy", "interest-cohort=()")),
)
.configure(services)
.configure(forge::auth::adapter::load_adapters(
db.pool.clone(),
&settings,
))
})
.bind(&socket_addr)
.unwrap()

View File

@ -1,6 +1,5 @@
use config::{builder::DefaultState, ConfigBuilder};
use serde::Deserialize;
use std::env;
pub mod forgejo;
@ -12,7 +11,7 @@ pub struct Forges {
}
impl Forges {
pub fn env_override(mut s: ConfigBuilder<DefaultState>) -> ConfigBuilder<DefaultState> {
pub fn env_override(s: ConfigBuilder<DefaultState>) -> ConfigBuilder<DefaultState> {
Forgejo::env_override(s)
}
}

View File

@ -120,7 +120,7 @@ pub mod tests {
println!("Setting env var {} to {} for test", $env, $val);
env::set_var($env, $val);
{
let new_settings = crate::settings::Settings::new().unwrap();
let new_settings = $crate::settings::Settings::new().unwrap();
assert_eq!(new_settings.$($param).+, $val_typed, "should match");
assert_ne!(new_settings.$($param).+, $init_settings.$($param).+);
}