Skip to content

Commit

Permalink
Add local authz backend, remove unused dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
auguwu committed Feb 13, 2025
1 parent 62f0a37 commit 8b78b0c
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 81 deletions.
52 changes: 3 additions & 49 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/authz/local/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ charted-authz.workspace = true
charted-core.workspace = true
eyre.workspace = true
tracing.workspace = true

[dev-dependencies]
charted-database.workspace = true
charted-types.workspace = true
tokio = { workspace = true, features = ["rt", "macros"] }
102 changes: 74 additions & 28 deletions crates/authz/local/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use argon2::{PasswordHash, PasswordVerifier};
use charted_authz::{Authenticator, Request};
use charted_core::BoxedFuture;
use charted_core::{BoxedFuture, ARGON2};
use eyre::{bail, eyre};
use tracing::{error, instrument};

/// Main implementation of the **local** session management
#[derive(Debug, Clone, Copy, Default)]
Expand All @@ -23,42 +26,85 @@ pub struct Backend {
}

impl Authenticator for Backend {
fn authenticate<'a>(
&'a self,
Request {
user: _,
password: _,
model: _,
}: Request<'a>,
) -> BoxedFuture<'a, eyre::Result<()>> {
Box::pin(async move { Ok(()) })
}
}

/*
pub struct Backend;
impl charted_authz::Authenticator for Backend {
fn authenticate<'u>(&'u self, user: &'u User, password: String) -> charted_core::BoxedFuture<'u, eyre::Result<()>> {
#[instrument(name = "charted.authz.local.authenticate", skip_all, fields(%user.username, %user.id))]
fn authenticate<'a>(&'a self, Request { user, password, model }: Request<'a>) -> BoxedFuture<'a, eyre::Result<()>> {
Box::pin(async move {
let Some(ref pass) = user.password else {
return Err(eyre!(
"missing `password` field, did you migrate all users from previous backends?"
));
let Some(ref pass) = model.password else {
bail!("missing `password` field for user, did you migrate all users from previous backends?")
};

let hash = PasswordHash::new(pass)
.inspect_err(|e| {
error!(error = %e, "failed to compute argon2 hash for password");
error!(error = %e, "failed to compute argon2 hash");
})
.map_err(|e|
/* since `password_hash::Error` doesn't implement `std::error::Error`,
we forward it to what `eyre!` uses instead */
eyre!(e))?;
.map_err(|e| eyre!(e))?;

ARGON2
.verify_password(password.as_ref(), &hash)
.verify_password(password.as_bytes(), &hash)
.map_err(|_| charted_authz::InvalidPassword.into())
})
}
}
*/

#[cfg(test)]
mod tests {
use super::*;
use charted_authz::InvalidPassword;
use charted_database::entities::user::Model;
use charted_types::User;
use std::borrow::Cow;

fn build_request<'s>(username: &'s str, password: &'s str) -> Request<'s> {
charted_authz::Request {
password: Cow::Borrowed(password),
model: Model {
// echo "noeliscutieuwu" | cargo cli admin authz hash-password --stdin
password: Some(String::from(
"$argon2id$v=19$m=19456,t=2,p=1$gIcVA4mVHgr8ZWkmDrtJlw$sb5ypFAvphFCGrJXy9fRI1Gb/2vGIH1FTzDax458+xY",
)),

email: "noel@noelware.org".to_owned(),
username: username.parse().unwrap(),
verified_publisher: Default::default(),
prefers_gravatar: Default::default(),
gravatar_email: Default::default(),
description: Default::default(),
avatar_hash: Default::default(),
created_at: Default::default(),
updated_at: Default::default(),
admin: Default::default(),
name: Default::default(),
id: Default::default(),
},
user: User {
username: username.parse().unwrap(),
verified_publisher: Default::default(),
prefers_gravatar: Default::default(),
gravatar_email: Default::default(),
description: Default::default(),
avatar_hash: Default::default(),
created_at: Default::default(),
updated_at: Default::default(),
admin: Default::default(),
name: Default::default(),
id: Default::default(),
},
}
}

#[tokio::test]
async fn authenticate() {
let backend = Backend::default();
assert!(backend
.authenticate(build_request("noel", "noeliscutieuwu"))
.await
.is_ok());

let err = backend
.authenticate(build_request("noel", "thetwinofboel"))
.await
.unwrap_err();

assert!(err.is::<InvalidPassword>());
}
}
2 changes: 1 addition & 1 deletion crates/database/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ sea-orm-migration.workspace = true
sqlx.workspace = true
tracing = { workspace = true, features = ["log"] }

[package.metadata.docs.rs]
[package.metadata.cargo-machete]
ignored = ["sqlx"]
5 changes: 2 additions & 3 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,15 @@ authors.workspace = true

[dependencies]
axum = { workspace = true, features = ["matched-path"] }
axum-extra = { version = "0.10.0", features = ["typed-header"] }
axum-server = { version = "0.7.1", features = ["tls-rustls", "tokio-rustls"] }
azalia = { workspace = true, features = ["remi"] }
base64 = "0.22.1"
charted-authz.workspace = true
charted-authz-local.workspace = true
#charted-authz-local.workspace = true
charted-config.workspace = true
charted-core = { workspace = true, features = ["openapi", "axum"] }
charted-database.workspace = true
charted-helm-charts.workspace = true
#charted-helm-charts.workspace = true
charted-helm-types = { workspace = true, features = ["openapi"] }
charted-types = { workspace = true, features = ["openapi"] }
derive_more = { workspace = true, features = ["display", "from", "error"] }
Expand Down

0 comments on commit 8b78b0c

Please # to comment.