mirror of
https://git.proxmox.com/git/pve-access-control
synced 2025-10-04 06:58:44 +00:00
fix #4411: openid: add logic for openid groups support
Signed-off-by: Thomas Skinner <thomas@atskinner.net> Tested-by: Mira Limbeck <m.limbeck@proxmox.com> Reviewed-by: Mira Limbeck <m.limbeck@proxmox.com> FG: fixup whitespace Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
4546c8df48
commit
d9582bb9b8
@ -13,6 +13,7 @@ use PVE::Cluster qw(cfs_read_file cfs_write_file);
|
||||
use PVE::AccessControl;
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
use PVE::Auth::Plugin;
|
||||
use PVE::Auth::OpenId;
|
||||
|
||||
use PVE::RESTHandler;
|
||||
|
||||
@ -220,6 +221,88 @@ __PACKAGE__->register_method ({
|
||||
$rpcenv->check_user_enabled($username);
|
||||
}
|
||||
|
||||
if (defined(my $groups_claim = $config->{'groups-claim'})) {
|
||||
if (defined(my $groups_list = $info->{$groups_claim})) {
|
||||
if (ref($groups_list) eq 'ARRAY') {
|
||||
PVE::AccessControl::lock_user_config(sub {
|
||||
my $usercfg = cfs_read_file("user.cfg");
|
||||
|
||||
my $oidc_groups;
|
||||
for my $group (@$groups_list) {
|
||||
if (PVE::AccessControl::verify_groupname($group, 1)) {
|
||||
# add realm name as suffix to group
|
||||
$oidc_groups->{"$group-$realm"} = 1;
|
||||
} else {
|
||||
# ignore any groups in the list that have invalid characters
|
||||
syslog(
|
||||
'warn',
|
||||
"openid group '$group' contains invalid characters"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# get groups that exist in OIDC and PVE
|
||||
my $groups_intersect;
|
||||
for my $group (keys %$oidc_groups) {
|
||||
$groups_intersect->{$group} = 1 if $usercfg->{groups}->{$group};
|
||||
}
|
||||
|
||||
if ($config->{'groups-autocreate'}) {
|
||||
# populate all groups in claim
|
||||
$groups_intersect = $oidc_groups;
|
||||
my $groups_to_create;
|
||||
for my $group (keys %$oidc_groups) {
|
||||
$groups_to_create->{$group} = 1 if !$usercfg->{groups}->{$group};
|
||||
}
|
||||
if ($groups_to_create) {
|
||||
# log a messages about created groups here
|
||||
my $groups_to_create_string = join(', ', sort keys %$groups_to_create);
|
||||
syslog(
|
||||
'info',
|
||||
"groups created automatically from openid claim: $groups_to_create_string"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
# if groups should be overwritten, delete all the users groups first
|
||||
if ($config->{'groups-overwrite'} ) {
|
||||
PVE::AccessControl::delete_user_group(
|
||||
$username,
|
||||
$usercfg,
|
||||
);
|
||||
syslog(
|
||||
'info',
|
||||
"openid overwrite groups enabled; user '$username' removed from all groups"
|
||||
);
|
||||
}
|
||||
|
||||
if (keys %$groups_intersect) {
|
||||
# ensure user is a member of the groups
|
||||
for my $group (keys %$groups_intersect) {
|
||||
PVE::AccessControl::add_user_group(
|
||||
$username,
|
||||
$usercfg,
|
||||
$group
|
||||
);
|
||||
}
|
||||
|
||||
my $groups_intersect_string = join(', ', sort keys %$groups_intersect);
|
||||
syslog(
|
||||
'info',
|
||||
"openid user '$username' added to groups: $groups_intersect_string"
|
||||
);
|
||||
}
|
||||
|
||||
cfs_write_file("user.cfg", $usercfg);
|
||||
}, "openid group mapping failed");
|
||||
} else {
|
||||
syslog('err', "openid groups list is not an array; groups will not be updated");
|
||||
}
|
||||
} else {
|
||||
syslog('err', "openid groups claim '$groups_claim' is not found in claims");
|
||||
}
|
||||
}
|
||||
|
||||
my $ticket = PVE::AccessControl::assemble_ticket($username);
|
||||
my $csrftoken = PVE::AccessControl::assemble_csrf_prevention_token($username);
|
||||
my $cap = $rpcenv->compute_api_permission($username);
|
||||
|
@ -1293,7 +1293,7 @@ PVE::JSONSchema::register_format('pve-groupid', \&verify_groupname);
|
||||
sub verify_groupname {
|
||||
my ($groupname, $noerr) = @_;
|
||||
|
||||
if ($groupname !~ m/^[A-Za-z0-9\.\-_]+$/) {
|
||||
if ($groupname !~ m/^[$PVE::Auth::Plugin::groupname_regex_chars]+$/) {
|
||||
|
||||
die "group name '$groupname' contains invalid characters\n" if !$noerr;
|
||||
|
||||
|
@ -9,6 +9,9 @@ use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file
|
||||
|
||||
use base qw(PVE::Auth::Plugin);
|
||||
|
||||
# include all printable ascii characters
|
||||
my $openid_claim_regex = qr/[ -~]+/;
|
||||
|
||||
sub type {
|
||||
return 'openid';
|
||||
}
|
||||
@ -42,6 +45,25 @@ sub properties {
|
||||
type => 'string',
|
||||
optional => 1,
|
||||
},
|
||||
"groups-claim" => {
|
||||
description => "OpenID claim used to retrieve groups with.",
|
||||
type => 'string',
|
||||
pattern => $openid_claim_regex,
|
||||
maxLength => 256,
|
||||
optional => 1,
|
||||
},
|
||||
"groups-autocreate" => {
|
||||
description => "Automatically create groups if they do not exist.",
|
||||
optional => 1,
|
||||
type => 'boolean',
|
||||
default => 0,
|
||||
},
|
||||
"groups-overwrite" => {
|
||||
description => "All groups will be overwritten for the user on login.",
|
||||
type => 'boolean',
|
||||
default => 0,
|
||||
optional => 1,
|
||||
},
|
||||
prompt => {
|
||||
description => "Specifies whether the Authorization Server prompts the End-User for"
|
||||
." reauthentication and consent.",
|
||||
@ -73,6 +95,9 @@ sub options {
|
||||
"client-key" => { optional => 1 },
|
||||
autocreate => { optional => 1 },
|
||||
"username-claim" => { optional => 1, fixed => 1 },
|
||||
"groups-claim" => { optional => 1 },
|
||||
"groups-autocreate" => { optional => 1 },
|
||||
"groups-overwrite" => { optional => 1 },
|
||||
prompt => { optional => 1 },
|
||||
scopes => { optional => 1 },
|
||||
"acr-values" => { optional => 1 },
|
||||
|
@ -31,6 +31,7 @@ sub lock_domain_config {
|
||||
|
||||
our $realm_regex = qr/[A-Za-z][A-Za-z0-9\.\-_]+/;
|
||||
our $user_regex = qr![^\s:/]+!;
|
||||
our $groupname_regex_chars = qr/A-Za-z0-9\.\-_/;
|
||||
|
||||
PVE::JSONSchema::register_format('pve-realm', \&pve_verify_realm);
|
||||
sub pve_verify_realm {
|
||||
|
Loading…
Reference in New Issue
Block a user