[pve-devel] applied: [PATCH access-control 4/4] realm: add default-sync-options to config

Thomas Lamprecht t.lamprecht at proxmox.com
Sat Mar 21 16:31:18 CET 2020


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 <t.lamprecht at proxmox.com>
---

the double registration as format and option seems a bit weird, I could had
used get_default_option for the format in LDAP too, but didn't felt to nice.

If somebody has/sees issues with that feel free to holler me (or better sent a
patch) :)

 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.20.1





More information about the pve-devel mailing list