Unverified Commit 16cdde80 authored by Jappie3's avatar Jappie3
Browse files

nixos/kanidm: add extraJsonFile option to allow provisioning from a json file

parent 6cfaf75d
Loading
Loading
Loading
Loading
+46 −19
Original line number Diff line number Diff line
@@ -182,6 +182,12 @@ let
        fi
      '';

  finalJson =
    if cfg.provision.extraJsonFile != null then
      "<(${lib.getExe pkgs.jq} -s '.[0] * .[1]' ${provisionStateJson} ${cfg.provision.extraJsonFile})"
    else
      provisionStateJson;

  postStartScript = pkgs.writeShellScript "post-start" ''
    set -euo pipefail

@@ -207,7 +213,7 @@ let
        ${optionalString (!cfg.provision.autoRemove) "--no-auto-remove"} \
        ${optionalString cfg.provision.acceptInvalidCerts "--accept-invalid-certs"} \
        --url "${cfg.provision.instanceUrl}" \
        --state ${provisionStateJson}
        --state ${finalJson}
  '';

  serverPort =
@@ -431,6 +437,19 @@ in
        default = true;
      };

      extraJsonFile = mkOption {
        description = ''
          A JSON file for provisioning persons, groups & systems.
          Options set in this file take precedence over values set using the other options.
          In the case of duplicates, `jq` will remove all but the last one
          when merging this file with the options.
          The accepted JSON schema can be found at <https://github.com/oddlama/kanidm-provision#json-schema>.
          Note: theoretically `jq` cannot merge nested types, but this does not pose an issue as kanidm-provision's JSON scheme does not use nested types.
        '';
        type = types.nullOr types.path;
        default = null;
      };

      groups = mkOption {
        description = "Provisioning of kanidm groups";
        default = { };
@@ -756,38 +775,46 @@ in
          }
        )
      ]
      ++ flip mapAttrsToList (filterPresent cfg.provision.persons) (
      ++ (optionals (cfg.provision.extraJsonFile == null) (
        flip mapAttrsToList (filterPresent cfg.provision.persons) (
          person: personCfg:
          assertGroupsKnown "services.kanidm.provision.persons.${person}.groups" personCfg.groups
        )
      ++ flip mapAttrsToList (filterPresent cfg.provision.groups) (
      ))
      ++ (optionals (cfg.provision.extraJsonFile == null) (
        flip mapAttrsToList (filterPresent cfg.provision.groups) (
          group: groupCfg:
          assertEntitiesKnown "services.kanidm.provision.groups.${group}.members" groupCfg.members
        )
      ))
      ++ concatLists (
        flip mapAttrsToList (filterPresent cfg.provision.systems.oauth2) (
          oauth2: oauth2Cfg:
          [
            (assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.scopeMaps" (
          (optionals (cfg.provision.extraJsonFile == null) (
            assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.scopeMaps" (
              attrNames oauth2Cfg.scopeMaps
            )
          ))
            (assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.supplementaryScopeMaps" (
          ++ (optionals (cfg.provision.extraJsonFile == null) (
            assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.supplementaryScopeMaps" (
              attrNames oauth2Cfg.supplementaryScopeMaps
            )
          ))
          ]
          ++ concatLists (
            flip mapAttrsToList oauth2Cfg.claimMaps (
              claim: claimCfg: [
                (assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim}.valuesByGroup" (
                (mkIf (cfg.provision.extraJsonFile == null) (
                  assertGroupsKnown "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim}.valuesByGroup" (
                    attrNames claimCfg.valuesByGroup
                  )
                ))
                # At least one group must map to a value in each claim map
                {
                (mkIf (cfg.provision.extraJsonFile == null) {
                  assertion =
                    (cfg.provision.enable && cfg.enableServer)
                    -> any (xs: xs != [ ]) (attrValues claimCfg.valuesByGroup);
                  message = "services.kanidm.provision.systems.oauth2.${oauth2}.claimMaps.${claim} does not specify any values for any group";
                }
                })
                # Public clients cannot define a basic secret
                {
                  assertion =