From d29d2d4a115b27e743048cef7e17afa125b39c51 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Sat, 21 Mar 2020 16:01:56 +0100 Subject: [PATCH] realm: add default-sync-options to config This allows us to have a convenient way to set the desired default sync options, and thus not forcing users to pass always all options when they want to trigger a sync. We still die when an option is neither specified in the domains (realm) config nor as API/CLI parameter. Signed-off-by: Thomas Lamprecht --- PVE/API2/Domains.pm | 59 +++++++++++++++++++++++++-------------------- PVE/Auth/LDAP.pm | 11 ++++++++- PVE/Auth/Plugin.pm | 31 ++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/PVE/API2/Domains.pm b/PVE/API2/Domains.pm index fa6ab78..23db19b 100644 --- a/PVE/API2/Domains.pm +++ b/PVE/API2/Domains.pm @@ -276,7 +276,7 @@ my $update_users = sub { my $olduser = $oldusers->{$userid} // {}; if (defined(my $enabled = $olduser->{enable})) { $user->{enable} = $enabled; - } elsif ($opts->{enable}) { + } elsif ($opts->{'enable-new'}) { $user->{enable} = 1; } @@ -340,6 +340,31 @@ my $update_groups = sub { } }; +my $parse_sync_opts = sub { + my ($param, $realmconfig) = @_; + + my $sync_opts_fmt = PVE::JSONSchema::get_format('realm-sync-options'); + + my $res = {}; + if (defined(my $cfg_opts = $realmconfig->{'sync-defaults-options'})) { + $res = PVE::JSONSchema::parse_property_string($sync_opts_fmt, $cfg_opts); + } + + for my $opt (sort keys %$sync_opts_fmt) { + my $fmt = $sync_opts_fmt->{$opt}; + + if (exists $param->{$opt}) { + $res->{$opt} = $param->{$opt}; + } elsif (!exists $res->{$opt}) { + raise_param_exc({ + "$opt" => 'Not passed as parameter and not defined in realm default sync options.' + }) if !$fmt->{optional}; + $res->{$opt} = $fmt->{default} if exists $fmt->{default}; + } + } + return $res; +}; + __PACKAGE__->register_method ({ name => 'sync', path => '{realm}/sync', @@ -358,28 +383,9 @@ __PACKAGE__->register_method ({ protected => 1, parameters => { additionalProperties => 0, - properties => { - realm => get_standard_option('realm'), - scope => { - description => "Select what to sync.", - type => 'string', - enum => [qw(users groups both)], - }, - full => { - description => "If set, uses the LDAP Directory as source of truth, ". - "deleting all information not contained there. ". - "Otherwise only syncs information set explicitly.", - type => 'boolean', - }, - enable => { - description => "Enable newly synced users.", - type => 'boolean', - }, - purge => { - description => "Remove ACLs for users/groups that were removed from the config.", - type => 'boolean', - }, - } + properties => get_standard_option('realm-sync-options', { + realm => get_standard_option('realm'), + }) }, returns => { description => 'Worker Task-UPID', @@ -402,8 +408,9 @@ __PACKAGE__->register_method ({ die "Cannot sync realm type '$type'! Only LDAP/AD realms can be synced.\n"; } + my $opts = $parse_sync_opts->($param, $realmconfig); # can throw up - my $scope = $param->{scope}; + my $scope = $opts->{scope}; my $whatstring = $scope eq 'both' ? "users and groups" : $scope; my $plugin = PVE::Auth::Plugin->lookup($type); @@ -422,11 +429,11 @@ __PACKAGE__->register_method ({ print "got data from server, updating $whatstring\n"; if ($scope eq 'users' || $scope eq 'both') { - $update_users->($usercfg, $realm, $synced_users, $param); + $update_users->($usercfg, $realm, $synced_users, $opts); } if ($scope eq 'groups' || $scope eq 'both') { - $update_groups->($usercfg, $realm, $synced_groups, $param); + $update_groups->($usercfg, $realm, $synced_groups, $opts); } cfs_write_file("user.cfg", $usercfg); diff --git a/PVE/Auth/LDAP.pm b/PVE/Auth/LDAP.pm index 3dd4ae6..905cc47 100755 --- a/PVE/Auth/LDAP.pm +++ b/PVE/Auth/LDAP.pm @@ -3,9 +3,11 @@ package PVE::Auth::LDAP; use strict; use warnings; -use PVE::Tools; use PVE::Auth::Plugin; +use PVE::JSONSchema; use PVE::LDAP; +use PVE::Tools; + use base qw(PVE::Auth::Plugin); sub type { @@ -109,6 +111,12 @@ sub properties { format => 'ldap-simple-attr-list', optional => 1, }, + 'sync-defaults-options' => { + description => "The default options for behavior of synchronizations.", + type => 'string', + format => 'realm-sync-options', + optional => 1, + }, }; } @@ -136,6 +144,7 @@ sub options { group_name_attr => { optional => 1 }, group_filter => { optional => 1 }, group_classes => { optional => 1 }, + 'sync-defaults-options' => { optional => 1 }, }; } diff --git a/PVE/Auth/Plugin.pm b/PVE/Auth/Plugin.pm index 6d59b72..5272ef5 100755 --- a/PVE/Auth/Plugin.pm +++ b/PVE/Auth/Plugin.pm @@ -47,6 +47,37 @@ PVE::JSONSchema::register_standard_option('realm', { maxLength => 32, }); +my $realm_sync_options_desc = { + scope => { + description => "Select what to sync.", + type => 'string', + enum => [qw(users groups both)], + optional => '1', + }, + full => { + description => "If set, uses the LDAP Directory as source of truth," + ." deleting users or groups not returned from the sync. Otherwise" + ." only syncs information which is not already present, and does not" + ." deletes or modifies anything else.", + type => 'boolean', + optional => '1', + }, + 'enable-new' => { + description => "Enable newly synced users immediately.", + type => 'boolean', + default => '1', + optional => '1', + }, + purge => { + description => "Remove ACLs for users or groups which were removed from" + ." the config during a sync.", + type => 'boolean', + optional => '1', + }, +}; +PVE::JSONSchema::register_standard_option('realm-sync-options', $realm_sync_options_desc); +PVE::JSONSchema::register_format('realm-sync-options', $realm_sync_options_desc); + PVE::JSONSchema::register_format('pve-userid', \&verify_username); sub verify_username { my ($username, $noerr) = @_; -- 2.39.2