diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2018-12-31 13:20:02 -0800 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2018-12-31 13:20:02 -0800 | 
| commit | f9c15a4fc22cb87179e459a283146769e612a92b (patch) | |
| tree | 0f82f216fa17a2178b766d0af76cb8be7657ddee /rust/src | |
| parent | 8a6ab2ed76d725e6e8d47e51572f009407ed5ca2 (diff) | |
| download | fatcat-f9c15a4fc22cb87179e459a283146769e612a92b.tar.gz fatcat-f9c15a4fc22cb87179e459a283146769e612a92b.zip | |
wire-up auth config via ENV
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/auth.rs | 20 | ||||
| -rw-r--r-- | rust/src/bin/fatcat-auth.rs | 39 | ||||
| -rw-r--r-- | rust/src/bin/fatcat-export.rs | 18 | ||||
| -rw-r--r-- | rust/src/lib.rs | 26 | 
4 files changed, 54 insertions, 49 deletions
| diff --git a/rust/src/auth.rs b/rust/src/auth.rs index 0fe21ebe..450a19d6 100644 --- a/rust/src/auth.rs +++ b/rust/src/auth.rs @@ -40,22 +40,24 @@ pub struct AuthConfectionary {  }  impl AuthConfectionary { -    pub fn new(location: String, identifier: String, key: Vec<u8>) -> AuthConfectionary { +    pub fn new(location: String, identifier: String, key_base64: String) -> Result<AuthConfectionary> { +        let key = BASE64.decode(key_base64.as_bytes())?;          let mut root_keys = HashMap::new();          root_keys.insert(identifier.clone(), key.clone()); -        AuthConfectionary { +        Ok(AuthConfectionary {              location: location,              identifier: identifier,              key: key,              root_keys: root_keys, -        } +        })      }      pub fn new_dummy() -> AuthConfectionary {          AuthConfectionary::new(              "test.fatcat.wiki".to_string(),              "dummy".to_string(), -            DUMMY_KEY.to_vec()) +            BASE64.encode(DUMMY_KEY), +        ).unwrap()      }      pub fn create_token(&self, editor_id: FatCatId, expires: Option<DateTime<Utc>>) -> Result<String> { @@ -180,7 +182,15 @@ impl AuthConfectionary {      }  } -pub fn revoke_tokens(conn: &DbConn, editor_id: FatCatId) -> Result<()>{ +pub fn create_key() -> String { +    let mut key: Vec<u8> = vec![0; 32]; +    for v in key.iter_mut() { +        *v = rand::random() +    } +    BASE64.encode(&key) +} + +pub fn revoke_tokens(conn: &DbConn, editor_id: FatCatId) -> Result<()> {      diesel::update(editor::table.filter(editor::id.eq(&editor_id.to_uuid())))          .set(editor::auth_epoch.eq(Utc::now()))          .execute(conn)?; diff --git a/rust/src/bin/fatcat-auth.rs b/rust/src/bin/fatcat-auth.rs index 5a8f0f98..3240964f 100644 --- a/rust/src/bin/fatcat-auth.rs +++ b/rust/src/bin/fatcat-auth.rs @@ -14,12 +14,8 @@ extern crate serde_json;  extern crate uuid;  use clap::{App, SubCommand}; -use dotenv::dotenv; -use std::env;  use diesel::prelude::*; -use diesel::r2d2::ConnectionManager; -use fatcat::ConnectionPool;  use fatcat::errors::*;  use fatcat::api_helpers::FatCatId;  use std::str::FromStr; @@ -31,18 +27,6 @@ use std::str::FromStr;  //use std::io::{BufReader, BufWriter}; -/// Instantiate a new API server with a pooled database connection -// TODO: copypasta from fatcat-export -pub fn database_worker_pool() -> Result<ConnectionPool> { -    dotenv().ok(); -    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); -    let manager = ConnectionManager::<PgConnection>::new(database_url); -    let pool = diesel::r2d2::Pool::builder() -        .build(manager) -        .expect("Failed to create database pool."); -    Ok(pool) -} -  fn run() -> Result<()> {      let m = App::new("fatcat-auth")          .version(env!("CARGO_PKG_VERSION")) @@ -66,7 +50,7 @@ fn run() -> Result<()> {                  .about("Creates a new auth token (macaroon) for the given editor")                  .args_from_usage(                      "<editor-id> 'id of the editor (fatcatid, not username)' -                     --env-format 'outputs in a format that shells can source'" +                     --env-format 'outputs in a format that shells can source'" // TODO                  )          )          .subcommand( @@ -77,6 +61,13 @@ fn run() -> Result<()> {                  )          )          .subcommand( +            SubCommand::with_name("create-key") +                .about("Creates a new auth secret key (aka, root/signing key for tokens)") +                .args_from_usage( +                    "--env-format 'outputs in a format that shells can source'" // TODO +                ) +        ) +        .subcommand(              SubCommand::with_name("revoke-tokens")                  .about("Resets auth_epoch for a single editor (invalidating all existing tokens)")                  .args_from_usage( @@ -89,8 +80,18 @@ fn run() -> Result<()> {          )          .get_matches(); -    let db_conn = database_worker_pool()?.get().expect("database pool"); -    let confectionary = fatcat::auth::AuthConfectionary::new_dummy(); +    // First, the commands with no db or confectionary needed +    match m.subcommand() { +        ("create-key", Some(_subm)) => { +            println!("{}", fatcat::auth::create_key()); +            return Ok(()) +        }, +        _ => (), +    } + +    // Then the ones that do +    let db_conn = fatcat::database_worker_pool()?.get().expect("database pool"); +    let confectionary = fatcat::env_confectionary()?;      match m.subcommand() {          ("list-editors", Some(_subm)) => {              fatcat::auth::print_editors(&db_conn)?; diff --git a/rust/src/bin/fatcat-export.rs b/rust/src/bin/fatcat-export.rs index ec66ed4c..e1b930fc 100644 --- a/rust/src/bin/fatcat-export.rs +++ b/rust/src/bin/fatcat-export.rs @@ -17,15 +17,10 @@ extern crate serde_json;  extern crate uuid;  use clap::{App, Arg}; -use dotenv::dotenv; -use std::env; -use diesel::prelude::*; -use diesel::r2d2::ConnectionManager;  use fatcat::api_entity_crud::*;  use fatcat::api_helpers::*;  use fatcat::errors::*; -use fatcat::ConnectionPool;  use fatcat_api_spec::models::*;  use std::str::FromStr;  use uuid::Uuid; @@ -59,17 +54,6 @@ struct IdentRow {      redirect_id: Option<FatCatId>,  } -/// Instantiate a new API server with a pooled database connection -pub fn database_worker_pool() -> Result<ConnectionPool> { -    dotenv().ok(); -    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); -    let manager = ConnectionManager::<PgConnection>::new(database_url); -    let pool = diesel::r2d2::Pool::builder() -        .build(manager) -        .expect("Failed to create database pool."); -    Ok(pool) -} -  macro_rules! generic_loop_work {      ($fn_name:ident, $entity_model:ident) => {          fn $fn_name( @@ -183,7 +167,7 @@ pub fn do_export(      entity_type: ExportEntityType,      redirects: bool,  ) -> Result<()> { -    let db_pool = database_worker_pool()?; +    let db_pool = fatcat::database_worker_pool()?;      let buf_input = BufReader::new(std::io::stdin());      let (row_sender, row_receiver) = channel::bounded(CHANNEL_BUFFER_LEN);      let (output_sender, output_receiver) = channel::bounded(CHANNEL_BUFFER_LEN); diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 983645d8..233f8642 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -93,20 +93,29 @@ use dotenv::dotenv;  use iron::middleware::AfterMiddleware;  use iron::{Request, Response};  use std::env; +use auth::AuthConfectionary;  #[cfg(feature = "postgres")]  embed_migrations!("../migrations/");  pub type ConnectionPool = diesel::r2d2::Pool<ConnectionManager<diesel::pg::PgConnection>>; -/// Establish a direct database connection. Not currently used, but could be helpful for -/// single-threaded tests or utilities. -pub fn establish_connection() -> PgConnection { +/// Instantiate a new API server with a pooled database connection +pub fn database_worker_pool() -> Result<ConnectionPool> {      dotenv().ok(); -      let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); -    PgConnection::establish(&database_url) -        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url)) +    let manager = ConnectionManager::<PgConnection>::new(database_url); +    let pool = diesel::r2d2::Pool::builder() +        .build(manager) +        .expect("Failed to create database pool."); +    Ok(pool) +} + +pub fn env_confectionary() -> Result<AuthConfectionary> { +    let auth_location = env::var("AUTH_LOCATION").expect("AUTH_LOCATION must be set"); +    let auth_key = env::var("AUTH_SECRET_KEY").expect("AUTH_SECRET_KEY must be set"); +    let auth_key_ident = env::var("AUTH_KEY_IDENT").expect("AUTH_KEY_IDENT must be set"); +    AuthConfectionary::new(auth_location, auth_key_ident, auth_key)  }  /// Instantiate a new API server with a pooled database connection @@ -117,7 +126,7 @@ pub fn server() -> Result<api_server::Server> {      let pool = diesel::r2d2::Pool::builder()          .build(manager)          .expect("Failed to create database pool."); -    let confectionary = auth::AuthConfectionary::new_dummy(); +    let confectionary = env_confectionary()?;      Ok(api_server::Server { db_pool: pool, auth_confectionary: confectionary })  } @@ -126,7 +135,8 @@ pub fn test_server() -> Result<api_server::Server> {      let database_url = env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set");      env::set_var("DATABASE_URL", database_url); -    let server = server()?; +    let mut server = server()?; +    server.auth_confectionary = AuthConfectionary::new_dummy();      let conn = server.db_pool.get().expect("db_pool error");      // run migrations; revert latest (dummy data); re-run latest | 
