Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar-ui

crates/gunnar-ui-server/src/anonymous/sso_switch.rs

//! **Company sign-in is its own default-off feature** (A34-15): the default
//! console serves none of the SSO doors (`/auth/sso/*`, `/login/sso/<account>`,
//! `/scim/v2/*`) and none of the account admin's `/api/account/sso*`, and its
//! status offers no company field without asking gunnar; an `sso` build serves
//! them.

use super::{anon, console, FakeGunnar};
#[cfg(not(feature = "sso"))]
use super::{send, signed_in};

/// The doors a browser or an IdP's SCIM client reaches with no session.
const DOORS: &[&str] = &["/auth/sso/discover?hint=a%40acme.example", "/auth/sso/start?account=acme", "/login/sso/acme", "/auth/sso/oidc/callback?state=s&code=c"];

/// ★ **The default build serves no company sign-in**: every door answers as a
/// path that was never routed, and the admin's Identity provider API is gone.
#[cfg(not(feature = "sso"))]
#[tokio::test]
async fn the_default_build_serves_no_company_sign_in() {
    let fake = FakeGunnar::new();
    fake.sso_providers.store(true, std::sync::atomic::Ordering::SeqCst);
    let (app, keys, _) = console(fake.clone(), false).await;
    let (never, never_body) = anon(&app, "/auth/no-such-door").await;
    for path in DOORS {
        let (status, body) = anon(&app, path).await;
        assert_eq!((status, body.contains("found")), (never, false), "{path} is served by the default build: {status} {body} (never routed: {never} {never_body})");
    }
    for (method, path) in [(http::Method::POST, "/auth/sso/saml/acs"), (http::Method::POST, "/auth/sso/second/finish"), (http::Method::GET, "/scim/v2/Users")] {
        let (status, body) = send(&app, method.clone(), path, None).await;
        let (never, _) = send(&app, method.clone(), "/auth/no-such-door", None).await;
        assert!(!body.contains("urn:ietf:params:scim") && status == never, "{method} {path} is served by the default build: {status} {body}");
    }
    let (status, body) = signed_in(&app, &keys, "acme", crate::role::Role::Admin, "/api/account/sso").await;
    let (never, _) = signed_in(&app, &keys, "acme", crate::role::Role::Admin, "/api/account/no-such-door").await;
    assert_eq!(status, never, "/api/account/sso is served by the default build: {body}");
    let (_, status_body) = anon(&app, "/auth/status").await;
    assert!(status_body.contains("\"sso_offered\":false"), "{status_body}");
    assert_eq!(fake.discovers.load(std::sync::atomic::Ordering::SeqCst), 0, "the default build asked gunnar about company sign-in");
}

/// An `sso` build answers the discovery door.
#[cfg(feature = "sso")]
#[tokio::test]
async fn the_sso_build_serves_the_doors() {
    let (app, _, _) = console(FakeGunnar::new(), false).await;
    let (status, body) = anon(&app, DOORS[0]).await;
    assert_eq!(status, http::StatusCode::OK, "{body}");
    assert!(body.contains("\"found\""), "{body}");
}