2010-09-26 10:16:56 +02:00
|
|
|
## @file
|
2017-01-05 09:59:05 +01:00
|
|
|
# OpenID SREG extension for Lemonldap::NG::Portal::Issuer::OpenID class
|
2010-09-26 10:16:56 +02:00
|
|
|
|
|
|
|
## @class
|
2017-01-05 09:59:05 +01:00
|
|
|
# OpenID SREG extension for Lemonldap::NG::Portal::Issuer::OpenID class
|
2010-09-26 10:16:56 +02:00
|
|
|
|
2017-01-05 09:59:05 +01:00
|
|
|
package Lemonldap::NG::Portal::Lib::OpenID::SREG;
|
2010-09-26 10:16:56 +02:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Lemonldap::NG::Common::Regexp;
|
|
|
|
|
2017-02-28 21:53:19 +01:00
|
|
|
our $VERSION = '2.0.0';
|
|
|
|
|
2010-09-26 10:16:56 +02:00
|
|
|
## @method protected hash sregHook(hash prm)
|
|
|
|
# Hook called to add SREG parameters to the OpenID response
|
|
|
|
# @return Hash containing wanted parameters
|
|
|
|
sub sregHook {
|
2017-01-05 12:55:46 +01:00
|
|
|
my ( $self, $req, $u, $trust_root, $is_id, $is_trusted, $prm ) = @_;
|
2010-09-28 18:26:35 +02:00
|
|
|
my ( @req, @opt );
|
2010-09-26 10:16:56 +02:00
|
|
|
|
2010-09-29 08:42:48 +02:00
|
|
|
# Refuse federation if rejected by user
|
2017-01-06 07:02:52 +01:00
|
|
|
if ( $req->param('confirm') and $req->param('confirm') == -1 ) {
|
2010-10-14 11:50:23 +02:00
|
|
|
my %h;
|
|
|
|
$h{$_} = undef foreach (
|
|
|
|
qw(fullname nickname language postcode timezone country gender email dob)
|
|
|
|
);
|
2017-10-31 13:04:05 +01:00
|
|
|
$self->p->updatePersistentSession( $req, \%h );
|
2010-10-14 11:50:23 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2010-09-29 12:09:04 +02:00
|
|
|
|
|
|
|
# If identity is not trusted, does nothing
|
2010-10-14 11:50:23 +02:00
|
|
|
return ( 0, $prm ) unless ( $is_id and $is_trusted );
|
2010-09-26 10:16:56 +02:00
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("SREG start");
|
2010-09-26 10:16:56 +02:00
|
|
|
|
|
|
|
my $accepted = 1;
|
2010-09-29 12:09:04 +02:00
|
|
|
|
|
|
|
# Check all parameters
|
2017-10-11 14:21:40 +02:00
|
|
|
my @pol;
|
2010-09-26 10:16:56 +02:00
|
|
|
while ( my ( $k, $v ) = each %$prm ) {
|
2010-09-29 12:09:04 +02:00
|
|
|
|
|
|
|
# Store policy if provided
|
2010-09-26 10:16:56 +02:00
|
|
|
if ( $k eq 'policy_url' ) {
|
|
|
|
if ( $v =~ Lemonldap::NG::Common::Regexp::HTTP_URI ) {
|
2017-10-11 14:21:40 +02:00
|
|
|
push @pol, { url => $v };
|
2010-09-28 18:26:35 +02:00
|
|
|
|
2010-09-29 12:09:04 +02:00
|
|
|
# Question: is it important to notify policy changes ?
|
|
|
|
# if yes, uncomment this
|
2010-09-28 18:26:35 +02:00
|
|
|
#my $p =
|
2017-01-05 12:55:46 +01:00
|
|
|
# $req->{sessionInfo}->{"_openidTrust$trust_root\_Policy"};
|
2010-09-28 18:26:35 +02:00
|
|
|
#$accepted = 0 unless ( $p and $p eq $v );
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error("Bad policy url");
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
}
|
2010-09-29 12:09:04 +02:00
|
|
|
|
|
|
|
# Parse required attributes
|
2010-09-26 10:16:56 +02:00
|
|
|
elsif ( $k eq 'required' ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Required attr $v");
|
2010-09-26 10:16:56 +02:00
|
|
|
push @req, split( /,/, $v );
|
|
|
|
}
|
2010-09-29 12:09:04 +02:00
|
|
|
|
|
|
|
# Parse optional attributes
|
2010-09-26 10:16:56 +02:00
|
|
|
elsif ( $k eq 'optional' ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug("Optional attr $v");
|
|
|
|
push @opt,
|
|
|
|
grep { defined $self->conf->{"openIdSreg_$trust_root$_"} }
|
2010-10-14 11:50:23 +02:00
|
|
|
split( /,/, $v );
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error("Unknown OpenID SREG request $k");
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
}
|
2018-07-05 22:56:16 +02:00
|
|
|
$req->data->{_openIdTrustExtMsg} .= $self->loadTemplate(
|
2017-10-11 14:21:40 +02:00
|
|
|
'openIdPol',
|
|
|
|
params => {
|
|
|
|
policies => \@pol,
|
|
|
|
}
|
|
|
|
) if (@pol);
|
2010-09-26 10:16:56 +02:00
|
|
|
|
|
|
|
# Check if required keys are valid SREG requests
|
2010-09-29 12:09:04 +02:00
|
|
|
# Question: reject bad SREG request ? Not done yet
|
2010-09-28 18:26:35 +02:00
|
|
|
@req = sregfilter( $self, @req );
|
|
|
|
@opt = sregfilter( $self, @opt );
|
|
|
|
|
2010-10-01 17:05:06 +02:00
|
|
|
# Return if nothing is asked
|
|
|
|
return ( 1, {} ) unless ( @req or @opt );
|
2010-09-26 10:16:56 +02:00
|
|
|
|
|
|
|
# If a required data is not available, returns nothing
|
|
|
|
foreach my $k (@req) {
|
2017-01-05 12:55:46 +01:00
|
|
|
unless ( $self->conf->{"openIdSreg_$k"} ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->notice(
|
|
|
|
"Parameter $k is required by $trust_root but not defined in configuration"
|
2010-09-26 10:16:56 +02:00
|
|
|
);
|
|
|
|
|
2017-10-11 14:21:40 +02:00
|
|
|
$req->info(
|
|
|
|
$self->loadTemplate(
|
|
|
|
'simpleInfo', params => { trspan => "openidRpns,$k" }
|
|
|
|
)
|
|
|
|
);
|
2010-09-26 10:16:56 +02:00
|
|
|
return ( 0, {} );
|
|
|
|
}
|
|
|
|
}
|
2010-09-26 15:09:46 +02:00
|
|
|
|
2018-07-05 22:56:16 +02:00
|
|
|
# Now set data
|
2010-10-08 18:14:06 +02:00
|
|
|
my ( %r, %msg, %ag, %toStore );
|
2010-09-28 18:26:35 +02:00
|
|
|
|
|
|
|
# Requested parameters: check if already agreed or confirm is set
|
|
|
|
foreach my $k (@req) {
|
2017-01-05 12:55:46 +01:00
|
|
|
my $agree = $req->{sessionInfo}->{"_openidTrust$trust_root\_$k"};
|
2010-09-28 18:26:35 +02:00
|
|
|
if ($accepted) {
|
2017-01-05 12:55:46 +01:00
|
|
|
unless ( $req->param('confirm') or $agree ) {
|
2010-09-28 18:26:35 +02:00
|
|
|
$accepted = 0;
|
|
|
|
}
|
|
|
|
elsif ( !$agree ) {
|
2010-10-08 18:14:06 +02:00
|
|
|
$toStore{"_openidTrust$trust_root\_$k"} = 1;
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
|
|
|
}
|
2017-01-05 12:55:46 +01:00
|
|
|
my $tmp = $self->conf->{"openIdSreg_$k"};
|
|
|
|
$tmp =~ s/^\$//;
|
2010-09-28 18:26:35 +02:00
|
|
|
$msg{req}->{$k} = $r{$k} =
|
2017-01-05 12:55:46 +01:00
|
|
|
$req->{sessionInfo}->{ $self->{"openIdSreg_$k"} } || '';
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
|
2010-09-28 18:26:35 +02:00
|
|
|
# Optional parameters:
|
|
|
|
foreach my $k (@opt) {
|
2017-01-05 12:55:46 +01:00
|
|
|
my $tmp = $self->conf->{"openIdSreg_$k"};
|
|
|
|
$tmp =~ s/^\$//;
|
|
|
|
my $agree = $req->{sessionInfo}->{"_openidTrust$trust_root\_$k"};
|
2010-09-28 18:26:35 +02:00
|
|
|
if ($accepted) {
|
|
|
|
|
|
|
|
# First, check if already accepted
|
2017-01-05 12:55:46 +01:00
|
|
|
unless ( $req->param('confirm') or defined($agree) ) {
|
2010-09-28 18:26:35 +02:00
|
|
|
$accepted = 0;
|
2017-01-05 12:55:46 +01:00
|
|
|
$r{$k} = $req->{sessionInfo}->{$tmp}
|
2010-09-28 18:26:35 +02:00
|
|
|
|| '';
|
|
|
|
}
|
|
|
|
|
|
|
|
# If confirmation is returned, check the value for this field
|
2017-01-05 12:55:46 +01:00
|
|
|
elsif ( $req->param('confirm') == 1 ) {
|
2010-09-29 08:42:48 +02:00
|
|
|
my $ck = 0;
|
2017-01-05 12:55:46 +01:00
|
|
|
if ( defined( $req->param("sreg_$k") ) ) {
|
|
|
|
$ck = ( $req->param("sreg_$k") eq 'OK' ) || 0;
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
2010-09-29 08:42:48 +02:00
|
|
|
|
|
|
|
# Store the value returned
|
|
|
|
if ( !defined($agree) or $agree != $ck ) {
|
2010-10-08 18:14:06 +02:00
|
|
|
$toStore{"_openidTrust$trust_root\_$k"} = $ck;
|
2010-09-29 08:42:48 +02:00
|
|
|
$agree = $ck;
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-05 12:55:46 +01:00
|
|
|
$msg{opt}->{$k} = $req->{sessionInfo}->{$tmp} || '';
|
2010-09-28 18:26:35 +02:00
|
|
|
|
|
|
|
# Store the value only if user agree it
|
|
|
|
if ($agree) {
|
|
|
|
$r{$k} = $msg{opt}->{$k};
|
|
|
|
$ag{$k} = 1;
|
|
|
|
}
|
2010-09-29 12:09:04 +02:00
|
|
|
elsif ( !defined($agree) ) {
|
|
|
|
$ag{$k} = 1;
|
|
|
|
}
|
2010-09-28 18:26:35 +02:00
|
|
|
else {
|
|
|
|
$ag{$k} = 0;
|
|
|
|
}
|
|
|
|
}
|
2017-10-31 13:04:05 +01:00
|
|
|
$self->p->updatePersistentSession( $req, \%toStore ) if (%toStore);
|
2010-09-28 18:26:35 +02:00
|
|
|
|
|
|
|
# Check if user has agreed request
|
|
|
|
if ($accepted) {
|
2017-02-15 15:16:59 +01:00
|
|
|
$self->userLogger->info(
|
2017-01-05 12:55:46 +01:00
|
|
|
$req->{sessionInfo}->{ $self->conf->{whatToTrace} }
|
2010-09-28 18:26:35 +02:00
|
|
|
. " has accepted OpenID SREG exchange with $trust_root" );
|
|
|
|
return ( 1, \%r );
|
|
|
|
}
|
|
|
|
|
|
|
|
# else build message and return 0
|
|
|
|
else {
|
2018-03-13 07:14:01 +01:00
|
|
|
my ( @mopt, @mreq );
|
2010-10-04 15:04:38 +02:00
|
|
|
|
|
|
|
# No choice for requested parameters: just an information
|
2010-09-28 18:26:35 +02:00
|
|
|
foreach my $k (@req) {
|
2010-10-04 15:53:44 +02:00
|
|
|
utf8::decode( $msg{req}->{$k} );
|
2018-03-13 07:14:01 +01:00
|
|
|
push @mreq, { k => $k, m => $msg{req}->{$k} };
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# For optional parameters: checkboxes are displayed
|
|
|
|
foreach my $k (@opt) {
|
2010-10-04 15:53:44 +02:00
|
|
|
utf8::decode( $msg{opt}->{$k} );
|
2018-03-13 07:14:01 +01:00
|
|
|
push @mopt,
|
|
|
|
{
|
|
|
|
k => $k,
|
|
|
|
m => $msg{opt}->{$k},
|
|
|
|
c => ( $ag{$k} ? 'checked' : '' )
|
|
|
|
};
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
2010-10-04 15:04:38 +02:00
|
|
|
|
2018-07-05 22:56:16 +02:00
|
|
|
$req->data->{_openIdTrustExtMsg} .= $self->loadTemplate(
|
2018-03-13 07:14:01 +01:00
|
|
|
'openIdTrust',
|
|
|
|
params => {
|
|
|
|
required => \@mreq,
|
|
|
|
optional => \@mopt,
|
|
|
|
}
|
|
|
|
);
|
2010-10-04 15:04:38 +02:00
|
|
|
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug('Building validation form');
|
2010-09-28 18:26:35 +02:00
|
|
|
return ( 0, $prm );
|
|
|
|
}
|
2010-09-26 10:16:56 +02:00
|
|
|
}
|
|
|
|
|
2010-09-29 12:09:04 +02:00
|
|
|
## @method private array sregfilter(array attr)
|
|
|
|
# Filter the arguments passed as parameters by checking their compliance with
|
|
|
|
# SREG.
|
2018-07-05 22:56:16 +02:00
|
|
|
# @return fitered data
|
2010-09-28 18:26:35 +02:00
|
|
|
sub sregfilter {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $self, @attr ) = @_;
|
2010-09-28 18:26:35 +02:00
|
|
|
my ( @ret, @rej );
|
2010-10-04 14:06:15 +02:00
|
|
|
|
|
|
|
# Browse attributes
|
2010-09-28 18:26:35 +02:00
|
|
|
foreach my $s (@attr) {
|
|
|
|
if ( $s =~
|
|
|
|
/^(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)$/
|
|
|
|
)
|
|
|
|
{
|
|
|
|
push @ret, $s;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$s =~ s/\W/\./sg;
|
|
|
|
push @rej, $s;
|
|
|
|
}
|
2010-10-04 14:06:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Warn if some parameters are rejected
|
2010-10-04 19:27:32 +02:00
|
|
|
if (@rej) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( "Requested parameter(s) "
|
2010-10-04 19:27:32 +02:00
|
|
|
. join( ',', @rej )
|
2017-02-15 07:41:50 +01:00
|
|
|
. "is(are) not valid OpenID SREG parameter(s)" );
|
2010-10-04 19:27:32 +02:00
|
|
|
}
|
2010-10-04 14:06:15 +02:00
|
|
|
|
|
|
|
# Return valid SREG parameters
|
2010-10-04 19:27:32 +02:00
|
|
|
return @ret;
|
2010-09-28 18:26:35 +02:00
|
|
|
}
|
2010-09-26 10:16:56 +02:00
|
|
|
1;
|