Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentik #2

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
21f3c62
test token
Sep 18, 2024
cba8b88
test only token set
Sep 18, 2024
f96eb23
test token access
Sep 18, 2024
d9f5ee5
test form x www urlencoded
Sep 20, 2024
19a6934
test token emty
Sep 20, 2024
cc1c128
test admin
Sep 24, 2024
871b39f
test app and provider create
Sep 27, 2024
d7c03d9
app return type missing
Oct 17, 2024
1c1a35c
min functions are provideded for authentik
Oct 20, 2024
6364ee1
flow and property set
Oct 22, 2024
4dec8ea
Merge branch 'main' into authentik
Oct 23, 2024
acb1694
test for flow uuid
Oct 23, 2024
7eee90a
test ignored for build
Oct 23, 2024
8e1abea
feat: add property caching
Threated Oct 24, 2024
c59c495
refactor: clean up oidc init logic
Threated Oct 24, 2024
8e98fb3
provider compare authentik and keyclaok bail macro instat of unteachable
Oct 31, 2024
b4d2bc4
failt test
Nov 12, 2024
f4a8e30
bug CLIENT static as fn
Nov 13, 2024
3d40bc8
test no creation
Nov 13, 2024
9186f18
test tokio multi thread
Nov 15, 2024
0951cbb
authentik docker compose
Nov 15, 2024
dfbb787
fix: docker setup
Threated Nov 20, 2024
3fdc507
fix: authentik group generation url
Threated Nov 20, 2024
b47a778
group, app, provider success created, matches failed
Nov 26, 2024
2595825
docker file for tests
Nov 26, 2024
d95436b
provider, app created, matched, conflict faild
Nov 26, 2024
04eaaa0
matches completed, validation todo and secret todo
Nov 27, 2024
2046bf7
successful test bug redirect_is
Dec 2, 2024
08b660c
provider and app match fn
Dec 4, 2024
e59513c
test validate and update provider
Dec 10, 2024
beed17d
private uris fix and debug output
Dec 10, 2024
10e0cd0
docker version authentik
Martin1088 Dec 10, 2024
88cf539
removed test clipborard token copy
Jan 8, 2025
1ae98d4
test fast shutdown not successfull
Jan 8, 2025
f1c9fb1
gitlab token merge into auth (authentik and keycloak)
Jan 8, 2025
1253d9d
config is now in mod auth
Jan 8, 2025
ad521ad
new version 2024.12
Jan 8, 2025
dd9b420
code review fix
Jan 9, 2025
3b64520
param deleted
Jan 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[env]
RUST_LOG = "debug"
24 changes: 16 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,28 @@ members = ["local", "central", "shared"]
resolver = "2"

[workspace.dependencies]
beam-lib = { git = "https://github.com/samply/beam", features = ["http-util"], branch = "develop" }
clap = { version = "4.4", features = ["derive", "env"]}
beam-lib = { git = "https://github.com/samply/beam", features = [
"http-util",
], branch = "develop" }
clap = { version = "4.4", features = ["derive", "env"] }
once_cell = "1"
tokio = { version = "1", default-features = false, features = ["macros", "rt-multi-thread"] }
serde = { version = "1", features = ["derive"]}
tokio = { version = "1", default-features = false, features = [
"macros",
"rt-multi-thread",
] }
serde = { version = "1", features = ["derive"] }
futures = "0.3"
shared = { path = "./shared" }
tracing = "0.1"
tracing-subscriber = "0.3.0"
anyhow = "1"

[profile.release]
#opt-level = "z" # Optimize for size.
lto = true # Enable Link Time Optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = "abort" # Abort on panic
strip = true # Automatically strip symbols from the binary.
lto = true # Enable Link Time Optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = "abort" # Abort on panic
strip = true # Automatically strip symbols from the binary.

[profile.bloat]
inherits = "release"
Expand Down
11 changes: 8 additions & 3 deletions central/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ license = "Apache-2.0"
[dependencies]
beam-lib = { workspace = true }
clap = { workspace = true }
tokio = { workspace = true, features= ["signal"] }
tokio = { workspace = true, features = ["signal"] }
once_cell = { workspace = true }
shared = { workspace = true }
serde = { workspace = true }
futures = { workspace = true }
serde_json = "1"
rand = "0.8"
reqwest = { version = "0.12", default_features = false, features = ["default-tls"] }
anyhow = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
reqwest = { version = "0.12", default_features = false, features = [
"default-tls",
] }
urlencoding = "2.1.3"
chrono = "0.4.39"
chrono = "0.4"
141 changes: 141 additions & 0 deletions central/src/auth/authentik/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use beam_lib::reqwest::{self, Response, StatusCode};
use reqwest::{Client, Url};
use serde_json::{json, Value};
use shared::OIDCConfig;
use std::i64;
use tracing::{debug, info};

use crate::CLIENT;

use super::{
get_uuid,
provider::{compare_provider, get_provider, get_provider_id, RedirectURIS},
AuthentikConfig,
};

pub fn generate_app_values(provider: i64, client_id: &str) -> Value {
json!({
"name": client_id,
"slug": client_id,
"provider": provider,
"group": client_id.split('-').next().expect("group name does not contain - ")
})
}

pub async fn generate_application(
provider: i64,
client_id: &str,
conf: &AuthentikConfig,
token: &str,
) -> reqwest::Result<Response> {
let app_value = generate_app_values(provider, client_id);
debug!("{:#?}", app_value);
CLIENT
.post(
conf.authentik_url
.join("api/v3/core/applications/")
.expect("Error parsing app url"),
)
.bearer_auth(token)
.json(&app_value)
.send()
.await
}

pub async fn check_app_result(
token: &str,
client_id: &str,
provider_pk: i64,
conf: &AuthentikConfig,
) -> anyhow::Result<bool> {
let res = generate_application(provider_pk, client_id, conf, token).await?;
match res.status() {
StatusCode::CREATED => {
info!("Application for {client_id} created.");
Ok(true)
}
StatusCode::BAD_REQUEST => {
let conflicting_client = get_application(client_id, token, conf).await?;
if app_configs_match(
&conflicting_client,
&generate_app_values(provider_pk, client_id),
) {
info!("Application {client_id} exists.");
Ok(true)
} else {
info!("Application for {client_id} is updated.");
Ok(CLIENT
.put(
conf.authentik_url.join("api/v3/core/applicaions/")?.join(
conflicting_client
.get("slug")
.and_then(Value::as_str)
.expect("No valid client"),
)?,
)
.bearer_auth(token)
.json(&generate_app_values(provider_pk, client_id))
.send()
.await?
.status()
.is_success())
}
}
s => anyhow::bail!("Unexpected statuscode {s} while creating authentik client. {res:?}"),
}
}

pub async fn get_application(
client_id: &str,
token: &str,
conf: &AuthentikConfig,
) -> reqwest::Result<serde_json::Value> {
CLIENT
.get(
conf.authentik_url
.join(&format!("api/v3/core/applications/{client_id}/"))
.expect("Error parsing app url"),
)
.bearer_auth(token)
.send()
.await?
.json()
.await
}

// used only from validate in config
pub async fn compare_app_provider(
token: &str,
name: &str,
oidc_client_config: &OIDCConfig,
secret: &str,
conf: &AuthentikConfig,
) -> anyhow::Result<bool> {
let client_id = format!(
"{name}-{}",
if oidc_client_config.is_public {
"public"
} else {
"private"
}
);

let provider_pk = get_provider_id(&client_id, token, conf).await;
match provider_pk {
Some(pr_id) => {
let app_res = get_application(&client_id, token, conf).await?;
if app_configs_match(&app_res, &generate_app_values(pr_id, &client_id)) {
compare_provider(token, &client_id, oidc_client_config, conf, secret).await
} else {
Ok(false)
}
}
None => Ok(false),
}
}

pub fn app_configs_match(a: &Value, b: &Value) -> bool {
a.get("name") == b.get("name")
&& a.get("group") == b.get("group")
&& a.get("provider") == b.get("provider")
}
44 changes: 44 additions & 0 deletions central/src/auth/authentik/group.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use beam_lib::reqwest::StatusCode;
use serde_json::json;
use tracing::info;

use crate::CLIENT;

use super::AuthentikConfig;

pub async fn create_groups(name: &str, token: &str, conf: &AuthentikConfig) -> anyhow::Result<()> {
let capitalize = |s: &str| {
let mut chrs = s.chars();
chrs.next()
.map(char::to_uppercase)
.map(Iterator::collect)
.unwrap_or(String::new())
+ chrs.as_str()
};
let name = capitalize(name);
for group in &conf.authentik_groups_per_bh {
post_group(&group.replace('#', &name), token, conf).await?;
}
Ok(())
}

pub async fn post_group(name: &str, token: &str, conf: &AuthentikConfig) -> anyhow::Result<()> {
let res = CLIENT
.post(conf.authentik_url.join("api/v3/core/groups/")?)
.bearer_auth(token)
.json(&json!({
"name": name
}))
.send()
.await?;
match res.status() {
StatusCode::CREATED => info!("Created group {name}"),
StatusCode::OK => info!("Created group {name}"),
StatusCode::BAD_REQUEST => info!("Group {name} already existed"),
s => anyhow::bail!(
"Unexpected statuscode {s} while creating group {name}: {:#?}",
res.json::<serde_json::Value>().await.unwrap_or_default()
),
}
Ok(())
}
Loading
Loading