public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH access-control] Add OpenID group sync in pve-access-control
@ 2024-02-15 21:27 Alexis | Dawnalex
  2024-02-15 21:27 ` [pve-devel] [PATCH manager] Update UI and backend integration for OpenID group creation Alexis | Dawnalex
  0 siblings, 1 reply; 2+ messages in thread
From: Alexis | Dawnalex @ 2024-02-15 21:27 UTC (permalink / raw)
  To: pve-devel

This commit adds the group synchronization feature to OpenID authentication, allowing automatic user group mapping and updates based on the OpenID provider information. Enhances integration and access control within Proxmox VE.

Signed-off-by: Alexis | Dawnalex <alexis@danwalex.com>
---
 src/PVE/API2/OpenId.pm | 83 +++++++++++++++++++++++++++++++++++++++---
 src/PVE/Auth/OpenId.pm | 18 ++++++++-
 2 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/src/PVE/API2/OpenId.pm b/src/PVE/API2/OpenId.pm
index 77410e6..52511ce 100644
--- a/src/PVE/API2/OpenId.pm
+++ b/src/PVE/API2/OpenId.pm
@@ -35,6 +35,7 @@ my $lookup_openid_auth = sub {
 	issuer_url => $config->{'issuer-url'},
 	client_id => $config->{'client-id'},
 	client_key => $config->{'client-key'},
+
     };
     $openid_config->{prompt} = $config->{'prompt'} if defined($config->{'prompt'});

@@ -150,6 +151,7 @@ __PACKAGE__->register_method ({
 	    CSRFPreventionToken => { type => 'string' },
 	    cap => { type => 'object' },  # computed api permissions
 	    clustername => { type => 'string', optional => 1 },
+		groups => get_standard_option('group-list'),
 	},
     },
     permissions => { user => 'world' },
@@ -190,6 +192,8 @@ __PACKAGE__->register_method ({
 	    }

 	    my $username = "${unique_name}\@${realm}";
+
+

 	    # first, check if $username respects our naming conventions
 	    PVE::Auth::Plugin::verify_username($username);
@@ -210,16 +214,23 @@ __PACKAGE__->register_method ({
 		    if (defined(my $family_name = $info->{'family_name'})) {
 			$entry->{lastname} = $family_name;
 		    }
-
+			if (defined(my $groups = $info->{'groups'})) {
+				sync_group($username, $info, $config, $groups);
+			}
 		    $usercfg->{users}->{$username} = $entry;
-
 		    cfs_write_file("user.cfg", $usercfg);
 		}, "autocreate openid user failed");
 	    } else {
+
+		if (defined(my $groups = $info->{'groups'})) {
+			my $usercfg = cfs_read_file("user.cfg");
+			sync_group($username, $info, $config, $groups);
+		}
 		# test if user exists and is enabled
 		$rpcenv->check_user_enabled($username);
 	    }
-
+		#check
+
 	    my $ticket = PVE::AccessControl::assemble_ticket($username);
 	    my $csrftoken = PVE::AccessControl::assemble_csrf_prevention_token($username);
 	    my $cap = $rpcenv->compute_api_permission($username);
@@ -243,7 +254,69 @@ __PACKAGE__->register_method ({
 	    die PVE::Exception->new("authentication failure\n", code => 401);
 	}

-	PVE::Cluster::log_msg('info', 'root@pam', "successful openid auth for user '$res->{username}'");
-
+	PVE::Cluster::log_msg('info', 'root@pam', "successful authentication (OpenID) for user '$res->{username}'");
 	return $res;
     }});
+
+#function to create groups with lock user config and create group
+sub create_group {
+	my ($group, $comment) = @_;
+	my $param = {
+		groupid => $group,
+		comment => $comment,
+		};
+	eval {
+	PVE::AccessControl::lock_user_config(
+	    sub {
+
+		my $usercfg = cfs_read_file("user.cfg");
+
+		my $group = $param->{groupid};
+
+		die "group '$group' already exists\n"
+		    if $usercfg->{groups}->{$group};
+
+		$usercfg->{groups}->{$group} = { users => {} };
+
+		$usercfg->{groups}->{$group}->{comment} = $param->{comment} if $param->{comment};
+
+
+		cfs_write_file("user.cfg", $usercfg);
+	    }, "create group failed");
+	};
+}
+## function to sync groups waiting update to move without API2
+sub sync_group {
+ 	my ($username, $info, $config, $groups) = @_;
+	my $usercfg = cfs_read_file("user.cfg");
+	# First Check if the group name respects our naming conventions
+	my @filtered_groups = grep { /^[a-zA-Z0-9_\-]+$/ } @{$groups};
+	# Then add Add filter regex to check and check the regex is valid
+	my $filter_regex = $config->{'groups-filter'};
+
+	if (defined($filter_regex)) {
+		eval { qr/$filter_regex/ };
+		if ($@) {
+			die "Invalid groups-filter regex: $@\n";
+		}
+		@filtered_groups = grep { /$filter_regex/ } @filtered_groups;
+	}
+	if (defined($config->{'autocreate-groups'})){
+
+		foreach my $group (@filtered_groups) {
+
+			unless ($usercfg->{groups}->{$group}) {
+
+				create_group($group, "Autocreated by OpenID Connect");
+			}
+			PVE::AccessControl::add_user_group($username, $usercfg, $group);
+		};
+	}
+	else{
+		foreach my $group (@filtered_groups) {
+			PVE::AccessControl::add_user_group($username, $usercfg, $group);
+		};
+	}
+
+
+}
\ No newline at end of file
diff --git a/src/PVE/Auth/OpenId.pm b/src/PVE/Auth/OpenId.pm
index c8e4db9..6404b49 100755
--- a/src/PVE/Auth/OpenId.pm
+++ b/src/PVE/Auth/OpenId.pm
@@ -37,6 +37,18 @@ sub properties {
 	    type => 'boolean',
 	    default => 0,
 	},
+	"autocreate-groups" => {
+	    description => "Automatically create users if they do not exist.",
+	    optional => 1,
+	    type => 'boolean',
+	    default => 0,
+	},
+	"groups-filter" => {
+	    description => "Only allow users in these groups.",
+	    optional => 1,
+	    type => 'string',
+	    maxLength => 256,
+	},
 	"username-claim" => {
 	    description => "OpenID claim used to generate the unique username.",
 	    type => 'string',
@@ -62,7 +74,8 @@ sub properties {
 	    type => 'string',
 	    pattern => '^[^\x00-\x1F\x7F <>#"]*$', # Prohibit characters not allowed in URI RFC 2396.
 	    optional => 1,
-	},
+	},
+
    };
 }

@@ -72,12 +85,15 @@ sub options {
 	"client-id" => {},
 	"client-key" => { optional => 1 },
 	autocreate => { optional => 1 },
+	"autocreate-groups" => { optional => 1},
+	"groups-filter" => { optional => 1 },
 	"username-claim" => { optional => 1, fixed => 1 },
 	prompt => { optional => 1 },
 	scopes => { optional => 1 },
 	"acr-values" => { optional => 1 },
 	default => { optional => 1 },
 	comment => { optional => 1 },
+
     };
 }

--
2.43.0.windows.1




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2024-02-15 21:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-15 21:27 [pve-devel] [PATCH access-control] Add OpenID group sync in pve-access-control Alexis | Dawnalex
2024-02-15 21:27 ` [pve-devel] [PATCH manager] Update UI and backend integration for OpenID group creation Alexis | Dawnalex

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal