mod api; mod client; mod service; mod util; use std::error::Error; use client::sqldb::PostgresClient; use env_logger::Env; use service::authn::Authn; use sqlx::postgres::PgPoolOptions; #[async_std::main] async fn main() -> Result<(), Box> { env_logger::Builder::from_env(Env::default().default_filter_or("debug")).init(); // Load configuration // which DB do you want to use? // what is the connection string (e.g. location, pass, etc...)? let pool = PgPoolOptions::new() .max_connections(5) .connect("postgres://secduser:p4ssw0rd@localhost:5419/secd") .await?; sqlx::migrate!("store/sql/migrations").run(&pool).await?; // there are a few routes // the service itself just provides some local functions which may be wrapped in a server. // if you want to use the server, then you start the java/python/rust/ruby/go/etc... server // otherwise, you just bring in the java/python/rust/ruby/go/etc... client // also...maybe a terraform template to launch a _minimal_ auth server // with your choice of RDS, dynamo, bigquery, or even local sqlite... // obviously need to configure terraform things... // if using the server, then you need to configure a few things: // oauth endpoint with response_type, client_id // scratch let pg_client = Box::new(PostgresClient::new(pool)); let authn = Authn { store: pg_client }; ////////////////////////////////////////////////// // CREATE NEW IDENTITY // which would be saved by the client let identity = authn.register_identity().await?; ////////////////////////////////////////////////// // Register a new oauth provider with some secrets, redirect, ids, etc... authn .register_oauth_provider( api::OauthProvider::Google, format!("client_id_{}", "CLIENT_SECRET_123"), format!("client_secret_{}", util::generate_random_url_safe(4)), "https://iam.SOMESITE.com/goauth...provided by default or customized".to_string(), ) .await?; ////////////////////////////////////////////////// // Start oauth challenge and return the appropriate location. let loc = authn .initiate_oauth_challenge(identity, api::OauthProvider::Google) .await?; ////////////////////////////////////////////////// // Complete oauth challenge and return a session token // let session = authn // .complete_oauth_challenge(identity, api::OauthProvider::Google, state, access_token, expires_at, raw); ////////////////////////////////////////////////// // Start email challenge // authn.initiate_email_challenge(identity, email_address); ////////////////////////////////////////////////// // Complete email challenge // let session = authn.complete_email_challenge(email_address, code); ////////////////////////////////////////////////// // Start SMS challenge // authn.initiate_sms_challenge(identity, phone_number); ////////////////////////////////////////////////// // Complete SMS challenge // let session = authn.complete_sms_challenge(phone_number, code); ////////////////////////////////////////////////// // Validate credentials // let session = authn.validate(username, passphrase); ////////////////////////////////////////////////// // Revoke session // authn.revoke_session(token); ////////////////////////////////////////////////// // Create API key // let pub, priv = authn.generate_api_key(identity, Some(expires_at)); ////////////////////////////////////////////////// // Revoke API key // authn.revoke_api_key(pub, priv); ////////////////////////////////////////////////// // Revoke identity // authn.revoke_identity(identity); println!("Oauth2.0 URL: {}", loc); Ok(()) } // TODO: oauth flow // TODO: email flow