Skip to content

Commit

Permalink
Merge pull request #15 from mdsol/convert-to-mauth-core
Browse files Browse the repository at this point in the history
Major upgrade and refactor
  • Loading branch information
jcarres-mdsol authored Jun 11, 2024
2 parents 20483dc + b00e86b commit 6c2abc7
Show file tree
Hide file tree
Showing 14 changed files with 758 additions and 922 deletions.
17 changes: 17 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2

updates:
- package-ecosystem: cargo
directory: /
schedule:
interval: weekly

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

on:
push:
branches:
- main
- master
pull_request:

env:
CARGO_TERM_COLOR: always

permissions:
contents: read

jobs:
rustfmt:
name: rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt
- name: Rustfmt Check
uses: actions-rust-lang/rustfmt@v1

clippy:
name: clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: clippy
- name: Clippy Check
run: cargo clippy --all-targets --all-features

test:
runs-on: ubuntu-latest
timeout-minutes: 10

concurrency:
# Cancel intermediate builds
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2

- name: Run tests
run: |
cargo test --all-features
28 changes: 28 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Publish

on:
workflow_dispatch:
push:
tags:
- "*.*.*"

env:
CARGO_TERM_COLOR: always

permissions:
contents: read

jobs:
build:
name: Build + Publish
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable

- run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

42 changes: 18 additions & 24 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mauth-client"
version = "0.3.0"
version = "0.4.0"
authors = ["Mason Gup <mgup@mdsol.com>"]
edition = "2021"
documentation = "https://docs.rs/mauth-client/"
Expand All @@ -13,31 +13,25 @@ keywords = ["security", "authentication", "web"]
categories = ["authentication", "web-programming"]

[dependencies]
ring = ">= 0.17.7"
reqwest = { version = ">= 0.11.23", features = ["json"] }
url = ">= 2.5.0"
serde = { version = ">= 1.0.85", features = ["derive"] }
serde_json = ">= 1.0.0"
serde_yaml = ">= 0.8.0"
uuid = { version = ">= 0.21.0", features = ["v4"] }
dirs = ">= 2.0.0"
base64 = ">= 0.10.0"
chrono = ">= 0.4.0"
percent-encoding = ">= 2.0.0"
tokio = { version = ">= 1.0.1", features = ["fs"] }
sha2 = ">= 0.9.0"
hex = ">= 0.4.0"
openssl = ">= 0.10.0"
regex = { version = "1", default_features = false, features = ["std"] }
bytes = ">= 1.0.0"
http = ">= 1.0.0"
tower = { version = ">= 0.4.13", optional = true }
reqwest = { version = "0.12", features = ["json"] }
url = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yml = "0.0.10"
uuid = { version = "1", features = ["v4"] }
dirs = "5"
chrono = "0.4"
tokio = { version = "1", features = ["fs"] }
tower = { version = "0.4", optional = true }
axum = { version = ">= 0.7.2", optional = true }
futures-core = { version = ">= 0.3.25", optional = true }
thiserror = ">= 1.0.37"
futures-core = { version = "0.3", optional = true }
http = { version = "1", optional = true }
bytes = { version = "1", optional = true }
thiserror = "1"
mauth-core = "0.5"

[dev-dependencies]
tokio = { version = ">= 1.0.1", features = ["rt-multi-thread", "macros"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

[features]
axum-service = ["tower", "futures-core", "axum"]
axum-service = ["tower", "futures-core", "axum", "http", "bytes"]
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,28 @@ release any code to Production or deploy in a Client-accessible environment with
approval for the full stack used through the Architecture and Security groups.

```rust
use mauth_client::MAuthInfo;
use reqwest::Client;
let mauth_info = MAuthInfo::from_default_file().unwrap();
let client = Client::new();
let uri: Url = "https://www.example.com/".parse().unwrap();
let (body, body_digest) = MAuthInfo::build_body_with_digest("".to_string());
let mut req = Request::new(Method::GET, uri);
*req.body_mut() = Some(body);
mauth_info.sign_request(&mut req, &body_digest);
let mut req = client.get("https://www.example.com/").build().unwrap();
mauth_info.sign_request(&mut req);
match client.execute(req).await {
Err(err) => println!("Got error {}", err),
Ok(response) => match mauth_info.validate_response(response).await {
Ok(resp_body) => println!(
"Got validated response with body {}",
&String::from_utf8(resp_body).unwrap()
),
Err(err) => println!("Error validating response: {:?}", err),
}
Ok(response) => println!("Got validated response with body {}", response.text().await.unwrap()),
}
```


The above code will read your mauth configuration from a file in `~/.mauth_config.yml` which format is:
```yaml
common: &common
mauth_baseurl: https://<URL of MAUTH SERVER>
mauth_api_version: v1
app_uuid: <YOUR APP UUID HERE>
private_key_file: <PATH TO MAUTH KEY>
```
The optional `axum-service` feature provides for a Tower Layer and Service that will
authenticate incoming requests via MAuth V2 or V1 and provide to the lower layers a
validated app_uuid from the request via the ValidatedRequestDetails struct.
Expand Down
10 changes: 0 additions & 10 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ fn main() {
let formatted_name = name.replace('-', "_");
code_str.push_str(&format!(
r#"
#[tokio::test]
async fn {formatted_name}_string_to_sign() {{
test_string_to_sign("{name}".to_string()).await;
}}
#[tokio::test]
async fn {formatted_name}_sign_string() {{
test_sign_string("{name}".to_string()).await;
}}
#[tokio::test]
async fn {formatted_name}_generate_headers() {{
test_generate_headers("{name}".to_string()).await;
Expand Down
9 changes: 6 additions & 3 deletions src/axum_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
use axum::extract::Request;
use futures_core::future::BoxFuture;
use openssl::{pkey::Public, rsa::Rsa};
use mauth_core::verifier::Verifier;
use std::collections::HashMap;
use std::error::Error;
use std::sync::{Arc, RwLock};
use std::task::{Context, Poll};
use tower::{Layer, Service};
use uuid::Uuid;

use crate::{ConfigFileSection, ConfigReadError, MAuthInfo};
use crate::{
config::{ConfigFileSection, ConfigReadError},
MAuthInfo,
};

/// This is a Tower Service which validates that incoming requests have a valid
/// MAuth signature. It only passes the request down to the next layer if the
Expand Down Expand Up @@ -69,7 +72,7 @@ impl<S: Clone> Clone for MAuthValidationService<S> {
#[derive(Clone)]
pub struct MAuthValidationLayer {
config_info: ConfigFileSection,
remote_key_store: Arc<RwLock<HashMap<Uuid, Rsa<Public>>>>,
remote_key_store: Arc<RwLock<HashMap<Uuid, Verifier>>>,
}

impl<S> Layer<S> for MAuthValidationLayer {
Expand Down
Loading

0 comments on commit 6c2abc7

Please sign in to comment.