1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-10-01 08:44:09 +02:00

feat(service): Add SCIM sync for Teams

Signed-off-by: Louis Chmn <louis@chmn.me>
This commit is contained in:
Louis Chmn 2026-09-07 11:35:18 +02:00 • committed by Robin Appelman
commit 188a26ab2d
5 changed files with 139 additions and 1 deletions

View file

@ -84,6 +84,7 @@ Additionally, you can use the following options when starting an instance:
- `ldap`: set up an LDAP server. - `ldap`: set up an LDAP server.
- `saml`: set up authentik as a SAML IDP. - `saml`: set up authentik as a SAML IDP.
- `oidc`: set up authentik as an OIDC IDP. - `oidc`: set up authentik as an OIDC IDP.
- `scim`: set up authentik as a SCIM server.
- `office`: set up a Nextcloud Office server. - `office`: set up a Nextcloud Office server.
- `onlyoffice` setup an onlyoffice document server. - `onlyoffice` setup an onlyoffice document server.
- `push` set up [client push](https://github.com/nextcloud/notify_push). - `push` set up [client push](https://github.com/nextcloud/notify_push).

View file

@ -0,0 +1,55 @@
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
version: 1
metadata:
name: haze-nextcloud-scim
entries:
- model: authentik_sources_scim.scimsource
id: scim-source
identifiers:
slug: nextcloud-scim
attrs:
name: Nextcloud SCIM
enabled: true
- model: authentik_core.token
identifiers:
identifier: !Format ["ak-source-scim-%s", !KeyOf scim-source]
attrs:
key: haze-scim-token
intent: api
expiring: false
user:
!Find [
authentik_core.user,
[username, !Format ["ak-source-scim-%s", !KeyOf scim-source]],
]
# Pushes Authentik's users and groups into Authentik's SCIM source
- model: authentik_providers_scim.scimprovider
id: scim-provider
identifiers:
name: Nextcloud SCIM
attrs:
url: http://authentik:9000/source/scim/nextcloud-scim/v2
token: haze-scim-token
exclude_users_service_account: true
property_mappings:
- !Find [
authentik_providers_scim.scimmapping,
[managed, goauthentik.io/providers/scim/user],
]
property_mappings_group:
- !Find [
authentik_providers_scim.scimmapping,
[managed, goauthentik.io/providers/scim/group],
]
- model: authentik_core.application
identifiers:
slug: nextcloud-scim
attrs:
name: Nextcloud SCIM
backchannel_providers:
- !KeyOf scim-provider
meta_launch_url: !File /haze/authentik/nextcloud-url
meta_description: Nextcloud instance provisioned by haze

View file

@ -19,7 +19,7 @@ mod webhook;
use crate::cloud::CloudOptions; use crate::cloud::CloudOptions;
use crate::config::{HazeConfig, Preset, ProxyConfig}; use crate::config::{HazeConfig, Preset, ProxyConfig};
pub use crate::service::authentik::{Authentik, AuthentikOidc, AuthentikSaml}; pub use crate::service::authentik::{Authentik, AuthentikOidc, AuthentikSaml, AuthentikScim};
pub use crate::service::clam::{Clam, ClamIcap, ClamIcapTls, ClamSocket}; pub use crate::service::clam::{Clam, ClamIcap, ClamIcapTls, ClamSocket};
use crate::service::dav::Dav; use crate::service::dav::Dav;
use crate::service::imaginary::Imaginary; use crate::service::imaginary::Imaginary;
@ -322,6 +322,8 @@ pub enum ServiceType {
Saml, Saml,
/// Configure Authentik as an OIDC IDP for Nextcloud /// Configure Authentik as an OIDC IDP for Nextcloud
Oidc, Oidc,
/// Configure Authentik as a SCIM server for Nextcloud
Scim,
} }
#[enum_dispatch] #[enum_dispatch]
@ -358,6 +360,7 @@ pub enum Service {
Authentik(Authentik), Authentik(Authentik),
AuthentikSaml(AuthentikSaml), AuthentikSaml(AuthentikSaml),
AuthentikOidc(AuthentikOidc), AuthentikOidc(AuthentikOidc),
AuthentikScim(AuthentikScim),
Preset(PresetService), Preset(PresetService),
} }
@ -413,6 +416,10 @@ impl Service {
Service::Authentik(Authentik), Service::Authentik(Authentik),
Service::AuthentikOidc(AuthentikOidc), Service::AuthentikOidc(AuthentikOidc),
]), ]),
ServiceType::Scim => Some(vec![
Service::Authentik(Authentik),
Service::AuthentikScim(AuthentikScim),
]),
} }
} else { } else {
presets presets

View file

@ -1,8 +1,10 @@
mod oidc; mod oidc;
mod saml; mod saml;
mod scim;
pub use oidc::AuthentikOidc; pub use oidc::AuthentikOidc;
pub use saml::AuthentikSaml; pub use saml::AuthentikSaml;
pub use scim::AuthentikScim;
use crate::Result; use crate::Result;
use crate::cloud::CloudOptions; use crate::cloud::CloudOptions;

View file

@ -0,0 +1,73 @@
use super::{AUTHENTIK_PORT, container_ip, container_name, write_file};
use crate::Result;
use crate::cloud::CloudOptions;
use crate::config::{HazeConfig, ProxyConfig};
use crate::service::{ServiceTrait, split_cmnd};
use bollard::Docker;
const BLUEPRINT: &str = include_str!("../../../blueprints/authentik-scim.yaml");
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AuthentikScim;
#[async_trait::async_trait]
impl ServiceTrait for AuthentikScim {
fn name(&self) -> &str {
"scim"
}
async fn spawn(
&self,
_docker: &Docker,
cloud_id: &str,
_network: &str,
config: &HazeConfig,
_options: &CloudOptions,
) -> Result<Vec<String>> {
let blueprints_directory = config
.work_dir
.join(cloud_id)
.join("authentik")
.join("blueprints");
write_file(&blueprints_directory, "scim.yaml", BLUEPRINT)?;
Ok(Vec::new())
}
fn apps(&self) -> &'static [&'static str] {
&["circles"]
}
async fn post_setup(
&self,
docker: &Docker,
cloud_id: &str,
config: &HazeConfig,
) -> Result<Vec<Vec<String>>> {
let authentik_container = container_name(cloud_id, "server");
let authentik_url = config.proxy.addr_with_port(
&authentik_container,
container_ip(docker, &authentik_container, None).await?,
AUTHENTIK_PORT,
);
Ok(vec![
split_cmnd("occ config:app:set --silent circles scim_enabled --type boolean --value 1"),
split_cmnd(&format!(
"occ config:app:set --silent circles scim_endpoint --value {authentik_url}/source/scim/nextcloud-scim/v2"
)),
split_cmnd("occ config:app:set --silent circles scim_token --value haze-scim-token"),
])
}
async fn start_message(
&self,
_docker: &Docker,
cloud_id: &str,
_proxy: &ProxyConfig,
) -> Result<Option<String>> {
Ok(Some(format!(
"Once Authentik as started, you can sync teams with 'haze {cloud_id} occ circles:scim:sync-circles'\n",
)))
}
}