diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..552b80e --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,94 @@ +# Based on https://github.com/actions-rs/meta/blob/master/recipes/quickstart.md +# +# While our "example" application has the platform-specific code, +# for simplicity we are compiling and testing everything on the Ubuntu environment only. +# For multi-OS testing see the `cross.yml` workflow. + +on: [push, pull_request] + +name: Tests + +jobs: + check: + name: Check ${{ matrix.db_feature }} (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + rust: [stable] + db_feature: [db-sled, db-redis, db-mongo] + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - name: Run cargo check + uses: actions-rs/cargo@v1 + with: + command: check + args: --no-default-features --features=secure-auth,${{ matrix.db_feature }},crates-io-mirroring + + test: + name: Test ${{ matrix.db_feature }} (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + rust: [stable] + db_feature: [db-sled, db-redis, db-mongo] + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + + - name: Run cargo test + uses: actions-rs/cargo@v1 + with: + command: test + args: --no-default-features --features=secure-auth,${{ matrix.db_feature }},crates-io-mirroring + + lints: + name: Lints (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + steps: + - name: Checkout sources + uses: actions/checkout@v2 + + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + components: rustfmt, clippy + + - name: Run cargo fmt + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + - name: Run cargo clippy + uses: actions-rs/cargo@v1 + continue-on-error: true # Set until the lints are fixed separately + with: + command: clippy + args: -- -D warnings diff --git a/src/config.rs b/src/config.rs index 721cf8c..defad63 100644 --- a/src/config.rs +++ b/src/config.rs @@ -76,6 +76,9 @@ impl CrateFilesConfig { #[derive(Debug, Clone, Deserialize)] pub struct DbConfig { + #[serde(default = "DbConfig::login_prefix_default")] + pub login_prefix: String, + #[cfg(feature = "db-sled")] #[serde(default = "DbConfig::db_dir_path_default")] pub db_dir_path: PathBuf, @@ -92,6 +95,7 @@ pub struct DbConfig { impl Default for DbConfig { fn default() -> DbConfig { DbConfig { + login_prefix: DbConfig::login_prefix_default(), #[cfg(feature = "db-sled")] db_dir_path: DbConfig::db_dir_path_default(), #[cfg(feature = "db-redis")] @@ -103,6 +107,10 @@ impl Default for DbConfig { } impl DbConfig { + fn login_prefix_default() -> String { + "ktra-secure-auth:".to_owned() + } + #[cfg(feature = "db-sled")] fn db_dir_path_default() -> PathBuf { PathBuf::from("db") diff --git a/src/db_manager/mongo_db_manager.rs b/src/db_manager/mongo_db_manager.rs index a9ea003..c7f52cb 100644 --- a/src/db_manager/mongo_db_manager.rs +++ b/src/db_manager/mongo_db_manager.rs @@ -49,6 +49,7 @@ struct EntryMap { pub struct MongoDbManager { client: Client, database_name: String, + login_prefix: String, } #[async_trait] @@ -79,6 +80,7 @@ impl DbManager for MongoDbManager { let db_manager = MongoDbManager { client, database_name, + login_prefix: config.login_prefix.clone(), }; Ok(db_manager) }; @@ -86,6 +88,10 @@ impl DbManager for MongoDbManager { initialization.map_err(Error::Db).await } + async fn get_login_prefix(&self) -> Result<&str, Error> { + Ok(&self.login_prefix) + } + #[tracing::instrument(skip(self, user_id, name))] async fn can_edit_owners(&self, user_id: u32, name: &str) -> Result { check_crate_name(&name)?; @@ -233,7 +239,7 @@ impl DbManager for MongoDbManager { #[tracing::instrument(skip(self, name))] async fn user_by_username(&self, name: &str) -> Result { let name = name.to_owned(); - let login = format!("ktra-secure-auth:{}", name); + let login = format!("{}{}", self.login_prefix, name); let collection = self .client .database(&self.database_name) diff --git a/src/db_manager/redis_db_manager.rs b/src/db_manager/redis_db_manager.rs index ae2ee36..3955d9e 100644 --- a/src/db_manager/redis_db_manager.rs +++ b/src/db_manager/redis_db_manager.rs @@ -26,6 +26,7 @@ const TOKENS_KEY: &str = "ktra:__TOKENS__"; pub struct RedisDbManager { client: Client, + login_prefix: String, } #[async_trait] @@ -42,13 +43,20 @@ impl DbManager for RedisDbManager { connection.set(SCHEMA_VERSION_KEY, &SCHEMA_VERSION).await?; } - let db_manager = RedisDbManager { client }; + let db_manager = RedisDbManager { + client, + login_prefix: config.login_prefix.clone(), + }; Ok(db_manager) }; initialization.map_err(Error::Db).await } + async fn get_login_prefix(&self) -> Result<&str, Error> { + Ok(&self.login_prefix) + } + #[tracing::instrument(skip(self, user_id, name))] async fn can_edit_owners(&self, user_id: u32, name: &str) -> Result { check_crate_name(&name)?; @@ -134,7 +142,7 @@ impl DbManager for RedisDbManager { #[tracing::instrument(skip(self, name))] async fn user_by_username(&self, name: &str) -> Result { let name = name.into(); - let login = format!("ktra-secure-auth:{}", name); + let login = format!("{}{}", self.login_prefix, name); let mut users: Vec = self.deserialize(USERS_KEY).await?.unwrap_or_default(); users.sort_by_key(|u| u.login.clone()); diff --git a/src/db_manager/sled_db_manager.rs b/src/db_manager/sled_db_manager.rs index 153f340..8bb5b23 100644 --- a/src/db_manager/sled_db_manager.rs +++ b/src/db_manager/sled_db_manager.rs @@ -27,6 +27,7 @@ const OLD_TOKENS_KEY: &str = "tokens"; pub struct SledDbManager { tree: Db, + login_prefix: String, } #[async_trait] @@ -48,11 +49,18 @@ impl DbManager for SledDbManager { tree.flush_async().map_err(Error::Db).await?; } - let db_manager = SledDbManager { tree }; + let db_manager = SledDbManager { + tree, + login_prefix: config.login_prefix.clone(), + }; Ok(db_manager) } + async fn get_login_prefix(&self) -> Result<&str, Error> { + Ok(&self.login_prefix) + } + #[tracing::instrument(skip(self, user_id, name))] async fn can_edit_owners(&self, user_id: u32, name: &str) -> Result { check_crate_name(&name)?; @@ -136,7 +144,7 @@ impl DbManager for SledDbManager { #[tracing::instrument(skip(self, name))] async fn user_by_username(&self, name: &str) -> Result { let name = name.into(); - let login = format!("ktra-secure-auth:{}", name); + let login = format!("{}{}", self.login_prefix, name); let mut users: Vec = self.deserialize(USERS_KEY)?.unwrap_or_default(); users.sort_by_key(|u| u.login.clone()); diff --git a/src/db_manager/traits.rs b/src/db_manager/traits.rs index 6133689..7034ddc 100644 --- a/src/db_manager/traits.rs +++ b/src/db_manager/traits.rs @@ -7,6 +7,7 @@ use semver::Version; #[async_trait] pub trait DbManager: Send + Sync + Sized { async fn new(confg: &DbConfig) -> Result; + async fn get_login_prefix(&self) -> Result<&str, Error>; async fn can_edit_owners(&self, user_id: u32, name: &str) -> Result; async fn owners(&self, name: &str) -> Result, Error>; diff --git a/src/main.rs b/src/main.rs index 213a707..232587f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -175,6 +175,7 @@ fn matches() -> ArgMatches<'static> { (@arg DL_DIR_PATH: --("dl-dir-path") +takes_value "Sets the crate files directory") (@arg CACHE_DIR_PATH: --("cache-dir-path") +takes_value "Sets the crates.io cache files directory (needs `crates-io-mirroring` feature)") (@arg DL_PATH: --("dl-path") +takes_value ... "Sets a crate files download path") + (@arg LOGIN_PREFIX: --("login-prefix") +takes_value "Sets the prefix to registered users on the registry.") (@arg DB_DIR_PATH: --("db-dir-path") +takes_value "Sets a database directory (needs `db-sled` feature)") (@arg REDIS_URL: --("redis-url") + takes_value "Sets a Redis URL (needs `db-redis` feature)") (@arg MONGODB_URL: --("mongodb-url") + takes_value "Sets a MongoDB URL (needs `db-mongo` feature)") @@ -220,6 +221,10 @@ async fn main() -> anyhow::Result<()> { config.crate_files_config.dl_path = dl_path; } + if let Some(login_prefix) = matches.value_of("LOGIN_PREFIX") { + config.db_config.login_prefix = login_prefix.into(); + } + #[cfg(feature = "db-sled")] if let Some(db_dir_path) = matches.value_of("DB_DIR_PATH").map(PathBuf::from) { config.db_config.db_dir_path = db_dir_path; diff --git a/src/post.rs b/src/post.rs index 6594de2..e9c9531 100644 --- a/src/post.rs +++ b/src/post.rs @@ -41,7 +41,7 @@ async fn handle_new_user( .map_ok(|user_id| user_id.map(|u| u + 1).unwrap_or(0)) .map_err(warp::reject::custom) .await?; - let login_id = format!("ktra-secure-auth:{}", name); + let login_id = format!("{}{}", db_manager.get_login_prefix().await?, name); let user = User::new(user_id, login_id, Some(name)); db_manager