2019-12-17 09:56:59 +01:00
|
|
|
package Lemonldap::NG::Manager::Api::Providers::OidcRp;
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2021-06-28 15:36:29 +02:00
|
|
|
our $VERSION = '2.0.12';
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
package Lemonldap::NG::Manager::Api;
|
|
|
|
|
2020-11-21 18:19:10 +01:00
|
|
|
use strict;
|
2019-12-17 09:56:59 +01:00
|
|
|
use utf8;
|
|
|
|
use Mouse;
|
2020-04-07 17:33:12 +02:00
|
|
|
use Lemonldap::NG::Manager::Conf::Parser;
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
extends 'Lemonldap::NG::Manager::Api::Common';
|
|
|
|
|
|
|
|
sub getOidcRpByConfKey {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
|
|
|
|
my $confKey = $req->params('confKey')
|
|
|
|
or return $self->sendError( $req, 'confKey is missing', 400 );
|
|
|
|
|
|
|
|
$self->logger->debug("[API] OIDC RP $confKey configuration requested");
|
|
|
|
|
|
|
|
# Get latest configuration
|
|
|
|
my $conf = $self->_confAcc->getConf;
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
my $oidcRp = $self->_getOidcRpByConfKey( $conf, $confKey );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Return 404 if not found
|
2020-01-10 21:29:11 +01:00
|
|
|
return $self->sendError( $req,
|
|
|
|
"OIDC relying party '$confKey' not found", 404 )
|
|
|
|
unless ( defined $oidcRp );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
return $self->sendJSONresponse( $req, $oidcRp );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub findOidcRpByConfKey {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
|
|
|
|
my $pattern = (
|
2019-12-17 20:58:55 +01:00
|
|
|
defined $req->params('uPattern')
|
|
|
|
? $req->params('uPattern')
|
|
|
|
: ( defined $req->params('pattern') ? $req->params('pattern') : undef )
|
2019-12-17 09:56:59 +01:00
|
|
|
);
|
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: pattern is missing', 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( defined $pattern );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-08 15:00:22 +02:00
|
|
|
unless ( $pattern = $self->_getRegexpFromPattern($pattern) ) {
|
|
|
|
return $self->sendError( $req, 'Invalid input: pattern is invalid',
|
|
|
|
400 );
|
|
|
|
}
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"[API] Find OIDC RPs by confKey regexp $pattern requested");
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Get latest configuration
|
|
|
|
my $conf = $self->_confAcc->getConf;
|
|
|
|
|
2020-01-10 21:29:11 +01:00
|
|
|
my @oidcRps =
|
|
|
|
map { $_ =~ $pattern ? $self->_getOidcRpByConfKey( $conf, $_ ) : () }
|
|
|
|
keys %{ $conf->{oidcRPMetaDataOptions} };
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
return $self->sendJSONresponse( $req, [@oidcRps] );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub findOidcRpByClientId {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
|
|
|
|
my $clientId = (
|
2019-12-17 20:58:55 +01:00
|
|
|
defined $req->params('uClientId') ? $req->params('uClientId')
|
|
|
|
: (
|
|
|
|
defined $req->params('clientId') ? $req->params('clientId')
|
2019-12-20 11:13:15 +01:00
|
|
|
: undef
|
|
|
|
)
|
2019-12-17 09:56:59 +01:00
|
|
|
);
|
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: clientId is missing', 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( defined $clientId );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
$self->logger->debug("[API] Find OIDC RPs by clientId $clientId requested");
|
|
|
|
|
|
|
|
# Get latest configuration
|
|
|
|
my $conf = $self->_confAcc->getConf;
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
my $oidcRp = $self->_getOidcRpByClientId( $conf, $clientId );
|
2020-01-10 21:29:11 +01:00
|
|
|
return $self->sendError( $req,
|
|
|
|
"OIDC relying party with clientId '$clientId' not found", 404 )
|
|
|
|
unless ( defined $oidcRp );
|
2019-12-18 17:18:17 +01:00
|
|
|
|
|
|
|
return $self->sendJSONresponse( $req, $oidcRp );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub addOidcRp {
|
2019-12-17 20:58:55 +01:00
|
|
|
my ( $self, $req ) = @_;
|
2020-12-28 15:18:47 +01:00
|
|
|
my $add = $req->jsonBodyToObj;
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ($add);
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: confKey is missing', 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( defined $add->{confKey} );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-07 14:53:18 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: confKey is not a string',
|
|
|
|
400 )
|
|
|
|
if ( ref $add->{confKey} );
|
|
|
|
|
2020-10-14 11:36:37 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: confKey is empty', 400 )
|
|
|
|
unless ( $add->{confKey} );
|
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: clientId is missing', 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( defined $add->{clientId} );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-07 14:53:18 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: clientId is not a string',
|
|
|
|
400 )
|
|
|
|
if ( ref $add->{clientId} );
|
|
|
|
|
|
|
|
return $self->sendError( $req, 'Invalid input: redirectUris is missing',
|
|
|
|
400 )
|
|
|
|
unless ( defined $add->{redirectUris} );
|
|
|
|
|
|
|
|
return $self->sendError( $req,
|
|
|
|
'Invalid input: redirectUris must be an array', 400 )
|
|
|
|
unless ( ref( $add->{redirectUris} ) eq "ARRAY" );
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"[API] Add OIDC RP with confKey $add->{confKey} and clientId $add->{clientId} requested"
|
|
|
|
);
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Get latest configuration
|
2020-01-10 21:29:11 +01:00
|
|
|
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-01-10 21:29:11 +01:00
|
|
|
return $self->sendError(
|
|
|
|
$req,
|
|
|
|
"Invalid input: An OIDC RP with confKey $add->{confKey} already exists",
|
2020-04-07 18:59:39 +02:00
|
|
|
409
|
2020-01-10 21:29:11 +01:00
|
|
|
) if ( defined $self->_getOidcRpByConfKey( $conf, $add->{confKey} ) );
|
|
|
|
|
|
|
|
return $self->sendError(
|
|
|
|
$req,
|
2019-12-17 20:58:55 +01:00
|
|
|
"Invalid input: An OIDC RP with clientId $add->{clientId} already exists",
|
2020-04-07 18:59:39 +02:00
|
|
|
409
|
2020-01-10 21:29:11 +01:00
|
|
|
) if ( defined $self->_getOidcRpByClientId( $conf, $add->{clientId} ) );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-01-10 21:29:11 +01:00
|
|
|
$add->{options} = {} unless ( defined $add->{options} );
|
2020-04-07 18:37:30 +02:00
|
|
|
$add->{options}->{clientId} = $add->{clientId};
|
2020-04-07 14:53:18 +02:00
|
|
|
$add->{options}->{redirectUris} = $add->{redirectUris};
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
my $res = $self->_pushOidcRp( $conf, $add->{confKey}, $add, 1 );
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, $res->{msg}, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( $res->{res} eq 'ok' );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-09 19:26:12 +02:00
|
|
|
return $self->sendJSONresponse(
|
|
|
|
$req,
|
|
|
|
{ message => "Successful operation" },
|
|
|
|
code => 201
|
|
|
|
);
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub updateOidcRp {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
my $confKey = $req->params('confKey')
|
|
|
|
or return $self->sendError( $req, 'confKey is missing', 400 );
|
|
|
|
|
2020-12-28 15:18:47 +01:00
|
|
|
my $update = $req->jsonBodyToObj;
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ($update);
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2021-01-14 18:58:59 +01:00
|
|
|
if ( $update->{redirectUris} ) {
|
|
|
|
if ( ref( $update->{redirectUris} ) eq "ARRAY" ) {
|
|
|
|
$update->{options}->{redirectUris} = $update->{redirectUris};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return $self->sendError( $req,
|
|
|
|
'Invalid input: redirectUris must be an array', 400 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"[API] OIDC RP $confKey configuration update requested");
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Get latest configuration
|
2020-01-10 21:29:11 +01:00
|
|
|
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
my $current = $self->_getOidcRpByConfKey( $conf, $confKey );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Return 404 if not found
|
2020-01-10 21:29:11 +01:00
|
|
|
|
|
|
|
return $self->sendError( $req,
|
|
|
|
"OIDC relying party '$confKey' not found", 404 )
|
|
|
|
unless ( defined $current );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# check if new clientID exists already
|
2019-12-17 20:58:55 +01:00
|
|
|
my $res = $self->_isNewOidcRpClientIdUnique( $conf, $confKey, $update );
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2020-04-07 18:59:39 +02:00
|
|
|
return $self->sendError( $req, $res->{msg}, 409 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( $res->{res} eq 'ok' );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$res = $self->_pushOidcRp( $conf, $confKey, $update, 0 );
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, $res->{msg}, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( $res->{res} eq 'ok' );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-09 19:26:12 +02:00
|
|
|
return $self->sendJSONresponse( $req, undef, code => 204 );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub replaceOidcRp {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
my $confKey = $req->params('confKey')
|
|
|
|
or return $self->sendError( $req, 'confKey is missing', 400 );
|
|
|
|
|
2020-12-28 15:18:47 +01:00
|
|
|
my $replace = $req->jsonBodyToObj;
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, "Invalid input: " . $req->error, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ($replace);
|
2020-04-07 14:53:18 +02:00
|
|
|
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: clientId is missing', 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( defined $replace->{clientId} );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-07 14:53:18 +02:00
|
|
|
return $self->sendError( $req, 'Invalid input: clientId is not a string',
|
|
|
|
400 )
|
|
|
|
if ( ref $replace->{clientId} );
|
|
|
|
|
|
|
|
return $self->sendError( $req, 'Invalid input: redirectUris is missing',
|
|
|
|
400 )
|
|
|
|
unless ( defined $replace->{redirectUris} );
|
|
|
|
|
|
|
|
return $self->sendError( $req,
|
|
|
|
'Invalid input: redirectUris must be an array', 400 )
|
|
|
|
unless ( ref( $replace->{redirectUris} ) eq "ARRAY" );
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
"[API] OIDC RP $confKey configuration replace requested");
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Get latest configuration
|
2020-01-10 21:29:11 +01:00
|
|
|
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Return 404 if not found
|
2020-01-10 21:29:11 +01:00
|
|
|
|
|
|
|
return $self->sendError( $req,
|
|
|
|
"OIDC relying party '$confKey' not found", 404 )
|
|
|
|
unless ( defined $self->_getOidcRpByConfKey( $conf, $confKey ) );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# check if new clientID exists already
|
2019-12-17 20:58:55 +01:00
|
|
|
my $res = $self->_isNewOidcRpClientIdUnique( $conf, $confKey, $replace );
|
2020-04-07 18:59:39 +02:00
|
|
|
return $self->sendError( $req, $res->{msg}, 409 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( $res->{res} eq 'ok' );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-07 14:53:18 +02:00
|
|
|
$replace->{options} = {} unless ( defined $replace->{options} );
|
2020-04-07 18:37:30 +02:00
|
|
|
$replace->{options}->{clientId} = $replace->{clientId};
|
2020-04-07 14:53:18 +02:00
|
|
|
$replace->{options}->{redirectUris} = $replace->{redirectUris};
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
$res = $self->_pushOidcRp( $conf, $confKey, $replace, 1 );
|
2020-04-01 20:46:30 +02:00
|
|
|
return $self->sendError( $req, $res->{msg}, 400 )
|
2020-01-10 21:29:11 +01:00
|
|
|
unless ( $res->{res} eq 'ok' );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-09 19:26:12 +02:00
|
|
|
return $self->sendJSONresponse( $req, undef, code => 204 );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub deleteOidcRp {
|
|
|
|
my ( $self, $req ) = @_;
|
|
|
|
my $confKey = $req->params('confKey')
|
|
|
|
or return $self->sendError( $req, 'confKey is missing', 400 );
|
|
|
|
|
|
|
|
# Get latest configuration
|
2020-01-10 21:29:11 +01:00
|
|
|
my $conf = $self->_confAcc->getConf( { noCache => 1 } );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
my $delete = $self->_getOidcRpByConfKey( $conf, $confKey );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Return 404 if not found
|
2020-01-10 21:29:11 +01:00
|
|
|
|
|
|
|
return $self->sendError( $req,
|
|
|
|
"OIDC relying party '$confKey' not found", 404 )
|
|
|
|
unless ( defined $delete );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
delete $conf->{oidcRPMetaDataOptions}->{$confKey};
|
|
|
|
delete $conf->{oidcRPMetaDataExportedVars}->{$confKey};
|
|
|
|
delete $conf->{oidcRPMetaDataOptionsExtraClaims}->{$confKey};
|
2020-04-06 21:02:55 +02:00
|
|
|
delete $conf->{oidcRPMetaDataMacros}->{$confKey};
|
2021-01-14 17:59:36 +01:00
|
|
|
delete $conf->{oidcRPMetaDataScopeRules}->{$confKey};
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Save configuration
|
2020-12-28 17:48:09 +01:00
|
|
|
$self->_saveApplyConf($conf);
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-09 19:26:12 +02:00
|
|
|
return $self->sendJSONresponse( $req, undef, code => 204 );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
sub _getOidcRpByConfKey {
|
|
|
|
my ( $self, $conf, $confKey ) = @_;
|
|
|
|
|
|
|
|
# Check if confKey is defined
|
2020-01-10 21:29:11 +01:00
|
|
|
return undef unless ( defined $conf->{oidcRPMetaDataOptions}->{$confKey} );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
# Get Client ID
|
|
|
|
my $clientId = $conf->{oidcRPMetaDataOptions}->{$confKey}
|
|
|
|
->{oidcRPMetaDataOptionsClientID};
|
|
|
|
|
|
|
|
# Get exported vars
|
|
|
|
my $exportedVars = $conf->{oidcRPMetaDataExportedVars}->{$confKey};
|
|
|
|
|
|
|
|
# Get extra claim
|
2020-04-06 20:35:13 +02:00
|
|
|
my $extraClaims = $conf->{oidcRPMetaDataOptionsExtraClaims}->{$confKey};
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-06 21:02:55 +02:00
|
|
|
# Get macros
|
|
|
|
my $macros = $conf->{oidcRPMetaDataMacros}->{$confKey} || {};
|
|
|
|
|
2021-01-14 17:59:36 +01:00
|
|
|
# Get scope rules
|
|
|
|
my $scopeRules = $conf->{oidcRPMetaDataScopeRules}->{$confKey} || {};
|
|
|
|
|
2020-10-14 11:37:13 +02:00
|
|
|
# Redirect URIs, filled later
|
2021-01-14 18:58:59 +01:00
|
|
|
my $redirectUris = $self->_translateValueConfToApi(
|
|
|
|
'oidcRPMetaDataOptionsRedirectUris',
|
|
|
|
$conf->{oidcRPMetaDataOptions}->{$confKey}
|
|
|
|
->{oidcRPMetaDataOptionsRedirectUris}
|
|
|
|
);
|
2020-10-14 11:37:13 +02:00
|
|
|
|
2019-12-17 09:56:59 +01:00
|
|
|
# Get options
|
2020-04-06 22:52:44 +02:00
|
|
|
my $options = {};
|
|
|
|
for
|
|
|
|
my $configOption ( keys %{ $conf->{oidcRPMetaDataOptions}->{$confKey} } )
|
|
|
|
{
|
2020-12-28 14:50:45 +01:00
|
|
|
my $apiName = $self->_translateOptionConfToApi($configOption);
|
|
|
|
my $apiValue = $self->_translateValueConfToApi( $configOption,
|
|
|
|
$conf->{oidcRPMetaDataOptions}->{$confKey}->{$configOption} );
|
|
|
|
$options->{$apiName} = $apiValue;
|
2020-04-06 22:52:44 +02:00
|
|
|
}
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
confKey => $confKey,
|
|
|
|
clientId => $clientId,
|
2020-10-14 11:37:13 +02:00
|
|
|
redirectUris => $redirectUris,
|
2019-12-17 09:56:59 +01:00
|
|
|
exportedVars => $exportedVars,
|
2020-04-06 20:35:13 +02:00
|
|
|
extraClaims => $extraClaims,
|
2020-04-06 21:02:55 +02:00
|
|
|
macros => $macros,
|
2021-01-14 17:59:36 +01:00
|
|
|
scopeRules => $scopeRules,
|
2019-12-17 20:58:55 +01:00
|
|
|
options => $options
|
2019-12-17 09:56:59 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub _getOidcRpByClientId {
|
|
|
|
my ( $self, $conf, $clientId ) = @_;
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
foreach ( keys %{ $conf->{oidcRPMetaDataOptions} } ) {
|
2020-01-10 21:29:11 +01:00
|
|
|
return $self->_getOidcRpByConfKey( $conf, $_ )
|
|
|
|
if ( $conf->{oidcRPMetaDataOptions}->{$_}
|
|
|
|
->{oidcRPMetaDataOptionsClientID} eq $clientId );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2019-12-17 09:56:59 +01:00
|
|
|
return undef;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub _isNewOidcRpClientIdUnique {
|
2019-12-17 20:58:55 +01:00
|
|
|
my ( $self, $conf, $confKey, $oidcRp ) = @_;
|
|
|
|
my $curClientId = $self->_getOidcRpByConfKey( $conf, $confKey )->{clientId};
|
|
|
|
my $newClientId =
|
|
|
|
$oidcRp->{clientId}
|
2020-04-07 18:37:30 +02:00
|
|
|
|| $oidcRp->{options}->{clientId}
|
2019-12-17 20:58:55 +01:00
|
|
|
|| "";
|
|
|
|
if ( $newClientId ne '' && $newClientId ne $curClientId ) {
|
2020-01-10 21:29:11 +01:00
|
|
|
return {
|
|
|
|
res => 'ko',
|
|
|
|
msg =>
|
2019-12-17 20:58:55 +01:00
|
|
|
"An OIDC relying party with clientId '$newClientId' already exists"
|
2020-01-10 21:29:11 +01:00
|
|
|
}
|
|
|
|
if ( defined $self->_getOidcRpByClientId( $conf, $newClientId ) );
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
2020-01-10 21:29:11 +01:00
|
|
|
|
2019-12-17 09:56:59 +01:00
|
|
|
return { res => 'ok' };
|
|
|
|
}
|
|
|
|
|
|
|
|
sub _pushOidcRp {
|
2019-12-17 20:58:55 +01:00
|
|
|
my ( $self, $conf, $confKey, $push, $replace ) = @_;
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2020-04-06 22:52:44 +02:00
|
|
|
my $translatedOptions = {};
|
2019-12-17 09:56:59 +01:00
|
|
|
if ($replace) {
|
2019-12-17 20:58:55 +01:00
|
|
|
$conf->{oidcRPMetaDataOptions}->{$confKey} = {};
|
|
|
|
$conf->{oidcRPMetaDataExportedVars}->{$confKey} = {};
|
2019-12-17 09:56:59 +01:00
|
|
|
$conf->{oidcRPMetaDataOptionsExtraClaims}->{$confKey} = {};
|
2020-04-06 21:02:55 +02:00
|
|
|
$conf->{oidcRPMetaDataMacros}->{$confKey} = {};
|
2020-04-06 22:52:44 +02:00
|
|
|
$translatedOptions = $self->_getDefaultValues('oidcRPMetaDataNode');
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
if ( defined $push->{options} ) {
|
2020-04-06 22:52:44 +02:00
|
|
|
|
|
|
|
foreach ( keys %{ $push->{options} } ) {
|
2020-04-07 14:53:18 +02:00
|
|
|
|
2020-12-28 14:50:45 +01:00
|
|
|
my $optionName = $self->_translateOptionApiToConf( $_, 'oidcRP' );
|
|
|
|
eval {
|
|
|
|
my $optionValue =
|
|
|
|
$self->_translateValueApiToConf( $_, $push->{options}->{$_} );
|
|
|
|
$translatedOptions->{$optionName} = $optionValue;
|
|
|
|
};
|
|
|
|
if ($@) {
|
2020-04-07 14:53:18 +02:00
|
|
|
return {
|
|
|
|
res => 'ko',
|
2020-12-28 14:50:45 +01:00
|
|
|
msg => "Invalid input: $@",
|
|
|
|
};
|
2020-04-07 14:53:18 +02:00
|
|
|
}
|
2020-04-06 22:52:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
my $res = $self->_hasAllowedAttributes( $translatedOptions,
|
2019-12-17 20:58:55 +01:00
|
|
|
'oidcRPMetaDataNode' );
|
2020-01-10 21:29:11 +01:00
|
|
|
return $res unless ( $res->{res} eq 'ok' );
|
|
|
|
|
2020-04-06 22:52:44 +02:00
|
|
|
foreach ( keys %{$translatedOptions} ) {
|
2019-12-17 20:58:55 +01:00
|
|
|
$conf->{oidcRPMetaDataOptions}->{$confKey}->{$_} =
|
2020-04-06 22:52:44 +02:00
|
|
|
$translatedOptions->{$_};
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
2020-04-06 22:52:44 +02:00
|
|
|
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
|
2020-01-10 21:29:11 +01:00
|
|
|
$conf->{oidcRPMetaDataOptions}->{$confKey}->{oidcRPMetaDataOptionsClientID}
|
|
|
|
= $push->{clientId}
|
|
|
|
if ( defined $push->{clientId} );
|
2019-12-17 09:56:59 +01:00
|
|
|
|
2019-12-17 20:58:55 +01:00
|
|
|
if ( defined $push->{exportedVars} ) {
|
|
|
|
if ( $self->_isSimpleKeyValueHash( $push->{exportedVars} ) ) {
|
|
|
|
foreach ( keys %{ $push->{exportedVars} } ) {
|
|
|
|
$conf->{oidcRPMetaDataExportedVars}->{$confKey}->{$_} =
|
|
|
|
$push->{exportedVars}->{$_};
|
2019-12-17 18:43:29 +01:00
|
|
|
}
|
2019-12-17 20:58:55 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return {
|
|
|
|
res => 'ko',
|
|
|
|
msg =>
|
|
|
|
"Invalid input: exportedVars is not a hash object with \"key\":\"value\" attributes"
|
|
|
|
};
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-06 21:02:55 +02:00
|
|
|
if ( defined $push->{macros} ) {
|
|
|
|
if ( $self->_isSimpleKeyValueHash( $push->{macros} ) ) {
|
|
|
|
foreach ( keys %{ $push->{macros} } ) {
|
|
|
|
$conf->{oidcRPMetaDataMacros}->{$confKey}->{$_} =
|
|
|
|
$push->{macros}->{$_};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return {
|
|
|
|
res => 'ko',
|
2021-01-14 17:59:36 +01:00
|
|
|
msg => "Invalid input: macros is not a hash object"
|
|
|
|
. " with \"key\":\"value\" attributes"
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( defined $push->{scopeRules} ) {
|
|
|
|
if ( $self->_isSimpleKeyValueHash( $push->{scopeRules} ) ) {
|
|
|
|
foreach ( keys %{ $push->{scopeRules} } ) {
|
|
|
|
$conf->{oidcRPMetaDataScopeRules}->{$confKey}->{$_} =
|
|
|
|
$push->{scopeRules}->{$_};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return {
|
|
|
|
res => 'ko',
|
|
|
|
msg => "Invalid input: scopeRules is not a hash object"
|
|
|
|
. " with \"key\":\"value\" attributes"
|
2020-04-06 21:02:55 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-06 20:35:13 +02:00
|
|
|
if ( defined $push->{extraClaims} ) {
|
|
|
|
if ( $self->_isSimpleKeyValueHash( $push->{extraClaims} ) ) {
|
|
|
|
foreach ( keys %{ $push->{extraClaims} } ) {
|
2019-12-17 20:58:55 +01:00
|
|
|
$conf->{oidcRPMetaDataOptionsExtraClaims}->{$confKey}->{$_} =
|
2020-04-06 20:35:13 +02:00
|
|
|
$push->{extraClaims}->{$_};
|
2019-12-17 18:43:29 +01:00
|
|
|
}
|
2019-12-17 20:58:55 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return {
|
|
|
|
res => 'ko',
|
2021-01-14 17:59:36 +01:00
|
|
|
msg => "Invalid input: extraClaims is not a hash object"
|
|
|
|
. " with \"key\":\"value\" attributes"
|
2019-12-17 20:58:55 +01:00
|
|
|
};
|
2019-12-17 09:56:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-07 17:33:12 +02:00
|
|
|
# Test new configuration
|
|
|
|
my $parser = Lemonldap::NG::Manager::Conf::Parser->new( {
|
|
|
|
refConf => $self->_confAcc->getConf,
|
|
|
|
newConf => $conf,
|
|
|
|
req => {},
|
|
|
|
}
|
|
|
|
);
|
|
|
|
unless ( $parser->testNewConf( $self->p ) ) {
|
|
|
|
return {
|
|
|
|
res => 'ko',
|
|
|
|
code => 400,
|
|
|
|
msg => "Configuration error: "
|
|
|
|
. join( ". ", map { $_->{message} } @{ $parser->errors } ),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-12-17 09:56:59 +01:00
|
|
|
# Save configuration
|
2020-12-28 17:48:09 +01:00
|
|
|
$self->_saveApplyConf($conf);
|
2019-12-17 09:56:59 +01:00
|
|
|
|
|
|
|
return { res => 'ok' };
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|