This commit is contained in:
Daniel Flanagan 2024-08-07 16:21:51 -05:00
parent f2deb35e69
commit ac4dfca0ac
6 changed files with 143 additions and 9 deletions

1
Cargo.lock generated
View file

@ -3781,6 +3781,7 @@ dependencies = [
"serde",
"serde_json",
"serde_with",
"thiserror",
"tokio",
"tracing",
"tracing-subscriber",

View file

@ -21,4 +21,5 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
urlencoding = "2.1.3"
http_client = { workspace = true }
discord_bot = { workspace = true }
thiserror = { workspace = true }
openidconnect = "3.5.0"

View file

@ -1,4 +1,6 @@
use reqwest::redirect::Policy;
use std::io::{self, BufRead};
use thiserror::Error;
use color_eyre::{eyre::eyre, Result};
use openidconnect::core::{
@ -6,17 +8,58 @@ use openidconnect::core::{
};
use openidconnect::AuthorizationCode;
use openidconnect::{
AccessTokenHash, ClientId, CsrfToken, IssuerUrl, Nonce, PkceCodeChallenge, RedirectUrl, Scope,
AccessTokenHash, ClientId, CsrfToken, HttpResponse, IssuerUrl, Nonce, PkceCodeChallenge,
RedirectUrl, Scope,
};
use openidconnect::reqwest::http_client;
const ISSUER_URL: &str = "https://idm.h.lyte.dev/oauth2/openid/yourcloud-dev";
const CLIENT_ID: &str = "yourcloud-dev";
// const CLIENT_SECRET: &str = "client_secret";
const ISSUER_URL: &str = "https://localhost:8443/oauth2/openid/yourcloud";
const CLIENT_ID: &str = "yourcloud";
const REDIRECT_URL: &str = "http://localhost:3000/oauth2/handler";
const SCOPES: [&str; 3] = ["read", "write", "email"];
#[derive(Debug, Error)]
pub enum Error {
/// Error returned by reqwest crate.
#[error("request failed")]
Reqwest(#[source] reqwest::Error),
/// I/O error.
#[error("I/O error")]
Io(#[source] std::io::Error),
/// Other error.
#[error("Other error: {}", _0)]
Other(String),
}
fn http_client(request: openidconnect::HttpRequest) -> Result<HttpResponse, Error> {
let client = reqwest::Client::builder()
// Following redirects opens the client up to SSRF vulnerabilities.
.redirect(Policy::none())
.build()
.map_err(Error::Reqwest)?;
let mut request_builder = client
.request(request.method, request.url.as_str())
.body(request.body);
for (name, value) in &request.headers {
request_builder = request_builder.header(name.as_str(), value.as_bytes());
}
let mut response = client
.execute(request_builder.build().map_err(Error::Reqwest)?)
.map_err(Error::Reqwest)?;
let mut body = Vec::new();
response.read_to_end(&mut body).map_err(Error::Io)?;
{
Ok(HttpResponse {
status_code: response.status(),
headers: response.headers().to_owned(),
body,
})
}
}
fn main() -> Result<()> {
// Use OpenID Connect Discovery to fetch the provider metadata.
use openidconnect::{OAuth2TokenResponse, TokenResponse};

87
config/kanidm/basic-setup.sh Normal file → Executable file
View file

@ -1 +1,88 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p ripgrep oath-toolkit
FAKE_PASSWORD="f0rTkN0x1s_cool"
function kdrun {
podman exec -it kanidm "$@"
}
echo "Resetting kanidm admin credentials"
admin_password="$(kdrun kanidmd recover-account admin | rg '.*new_password: "([^"]+)"' -r '$1')"
idm_password="$(kdrun kanidmd recover-account idm_admin | rg '.*new_password: "([^"]+)"' -r '$1')"
echo "admin password: $admin_password"
echo "idm_admin password: $idm_password"
# start a kanidm client in the background for an hour
podman kill kanidm-client || true
sleep 0.2
podman run -itd --rm \
--network host \
--name kanidm-client \
-v "$PWD/client.toml:/root/.config/kanidm:ro" \
docker.io/kanidm/tools \
bash -c 'sleep 3600' \
>/dev/null 2>&1
sleep 0.2
function krun {
podman exec -it kanidm-client "$@"
}
# setup sessions for both admin accounts
echo "$admin_password" | krun kanidm login -D admin
echo "$idm_password" | krun kanidm login -D idm_admin
function create_user {
username="$1"; shift
echo "Creating person (user) '${username}'..."
# krun kanidm person delete "$username" --name idm_admin
krun kanidm person create "$username" "$username user" --name idm_admin
krun kanidm person update "$username" --legalname "$username Lastname" --mail "${username}@example.com" --name idm_admin
# TODO: this doesn't seem to work? can't seem to commit changes
(
sleep 0.1
echo "pass"
sleep 0.1
echo "$FAKE_PASSWORD"
sleep 0.1
echo "$FAKE_PASSWORD"
sleep 0.1
echo "totp"
sleep 0.1
echo "totpname"
sleep 0.25
totp_uri="$(rg 'TOTP URI: (.+)' /tmp/create-user-log.txt -r '$1')"
totp_secret="$(echo "$totp_uri" | rg '.*?secret=([^&]+).*' -r '$1')"
totp_code="$(oathtool --totp=SHA256 -b "$totp_secret")"
echo "$totp_code"
sleep 0.1
echo "commit"
sleep 0.1
echo "y"
sleep 0.1
echo "end"
) | krun kanidm person credential update "$username" --name idm_admin | tee /tmp/create-user-log.txt
}
# some groups
app="yourcloud"
adm_group="${app}--admins"
krun kanidm group create "$adm_group" --name idm_admin
# create our OAuth 2 application
krun kanidm system oauth2 create "$app" "Yourcloud" "http://localhost:3000" --name idm_admin
krun kanidm system oauth2 update-scope-map "$app" "$adm_group" admin openid email read --name idm_admin
# TODO: expired/disabled users?
# for u in alice bob user1 user2 user3; do
# create_user "$u"
# done
for u in gilfoyle dinesh; do
create_user "$u"
done
# add users to groups
krun kanidm group add-members "$adm_group" gilfoyle --name idm_admin
krun kanidm group add-members "$adm_group" dinesh --name idm_admin

View file

@ -0,0 +1,2 @@
uri = "https://localhost:8443"
verify_ca = false

View file

@ -1,8 +1,8 @@
#!/usr/bin/env bash
podman run -itd --rm \
-p 8443:8443 \
-v "$PWD/server.toml:/data/server.toml" \
-v "$PWD/chain.pem:/data/chain.pem" \
-v "$PWD/key.pem:/data/key.pem" \
-v "$PWD/server.toml:/data/server.toml:ro" \
-v "$PWD/chain.pem:/data/chain.pem:ro" \
-v "$PWD/key.pem:/data/key.pem:ro" \
--name kanidm \
docker.io/kanidm/server:latest