Fix bad merge

This commit is contained in:
Christophe Maudoux 2020-05-25 00:06:31 +02:00
parent b2a1f055c3
commit 557f458803
6 changed files with 1021 additions and 1 deletions

View File

@ -0,0 +1,307 @@
package Lemonldap::NG::Portal::Lib::Choice;
use strict;
use Mouse;
use Safe;
use IO::String;
extends 'Lemonldap::NG::Portal::Lib::Wrapper';
with 'Lemonldap::NG::Portal::Lib::OverConf';
our $VERSION = '2.1.0';
has modules => ( is => 'rw', default => sub { {} } );
has rules => ( is => 'rw', default => sub { {} } );
has type => ( is => 'rw' );
has catch => ( is => 'rw', default => sub { {} } );
has sessionKey => ( is => 'ro', default => '_choice' );
my $_choiceRules;
# INITIALIZATION
# init() must be called by module::init() with a number:
# - 0 for auth
# - 1 for userDB
# - 2 for passwordDB ?
sub init {
my ( $self, $type ) = @_;
$self->type($type);
unless ( $self->conf->{authChoiceModules}
and %{ $self->conf->{authChoiceModules} } )
{
$self->error("'authChoiceModules' is empty");
return 0;
}
foreach my $name ( keys %{ $self->conf->{authChoiceModules} } ) {
my @mods =
split( /[;\|]/, $self->conf->{authChoiceModules}->{$name} );
my $module = '::'
. [ 'Auth', 'UserDB', 'Password' ]->[$type] . '::'
. $mods[$type];
my $over;
if ( $mods[5] ) {
eval { $over = JSON::from_json( $mods[5] ) };
if ($@) {
$self->logger->error("Bad over value ($@), skipped");
}
}
if ( $module = $self->loadModule( $module, $over ) ) {
$self->modules->{$name} = $module;
$self->logger->debug(
[qw(Authentication User Password)]->[$type]
. " module $name selected" );
}
else {
$self->logger->error(
"Choice: unable to load $name, disabling it: " . $self->error );
$self->error('');
}
# Test if auth module wants to catch some path
unless ($type) {
if ( $module->can('catch') ) {
$self->catch->{$name} = $module->catch;
}
}
# Display conditions
my $safe = Safe->new;
my $cond = $mods[4];
if ( defined $cond and $cond !~ /^$/ ) {
$self->logger->debug("Found rule $cond for $name");
$_choiceRules->{$name} =
$safe->reval("sub{my(\$env)=\@_;return ($cond)}");
if ($@) {
$self->logger->error("Bad condition $cond: $@");
return 0;
}
}
else {
$self->logger->debug("No rule for $name");
$_choiceRules->{$name} = sub { 1 };
}
}
unless ( keys %{ $self->modules } ) {
$self->error('Choice: no available modules found, aborting');
return 0;
}
return 1;
}
# RUNNING METHODS
sub checkChoice {
my ( $self, $req ) = @_;
my $name;
# Check Choice from pdata
if ( defined $req->pdata->{_choice} ) {
$name = $req->pdata->{_choice};
$self->logger->debug("Choice $name selected from pdata");
}
unless ($name) {
# Check with catch method
foreach ( keys %{ $self->catch } ) {
if ( $req->path_info =~ $self->catch->{$_} ) {
$name = $_;
$self->logger->debug(
"Choice $name selected from " . $req->path_info );
last;
}
}
}
unless ($name) {
# Check with other methods
$name ||=
$req->param( $self->conf->{authChoiceParam} )
|| $req->userData->{_choice}
|| $req->sessionInfo->{_choice}
or return 0;
$self->logger->debug("Choice $name selected");
}
unless ( defined $self->modules->{$name} ) {
$self->logger->error("Unknown choice '$name'");
return 0;
}
# Store choice if module loops
$req->pdata->{_choice} = $name;
$req->data->{_authChoice} = $name;
return $name if ( $req->data->{ "enabledMods" . $self->type } );
$req->sessionInfo->{_choice} = $name;
$req->data->{ "enabledMods" . $self->type } = [ $self->modules->{$name} ];
$self->p->_authentication->authnLevel("${name}AuthnLevel");
return $name;
}
sub name {
my ( $self, $req, $type ) = @_;
unless ($req) {
return 'Choice';
}
my $n = ref( $req->data->{ "enabledMods" . $self->type }->[0] );
$n =~ s/^Lemonldap::NG::Portal::(?:(?:UserDB|Auth)::)?//;
return $n;
}
sub getForm {
my ( $self, $req ) = @_;
my @authLoop;
# Test authentication choices
unless ( ref $self->conf->{authChoiceModules} eq 'HASH' ) {
$self->logger->warn("No authentication choices defined");
return [];
}
foreach ( sort keys %{ $self->conf->{authChoiceModules} } ) {
my $name = $_;
# Name can have a digit as first character
# for sorting purpose
# Remove it in displayed name
$name =~ s/^(\d*)?(\s*)?//;
# Replace also _ by space for a nice display
$name =~ s/\_/ /g;
# Find modules associated to authChoice
my ( $auth, $userDB, $passwordDB, $url, $condition ) =
split( /[;\|]/, $self->conf->{authChoiceModules}->{$_} );
unless ( $_choiceRules->{$_} ) {
$self->logger->error("$_ has no rule");
$_choiceRules->{$_} = sub { 1 };
}
unless ( $_choiceRules->{$_}->( $req->env ) ) {
$self->logger->debug(
"Condition returns false, authentication choice $_ will not be displayed"
);
}
else {
$self->logger->debug("Displaying authentication choice $_");
if ( $auth and $userDB and $passwordDB ) {
# Default URL
$req->{cspFormAction} ||= '';
if (
defined $url
and not $self->checkXSSAttack( 'URI',
$req->env->{'REQUEST_URI'} )
and $url =~
q%^(https?://)?[^\s/.?#$].[^\s]+$% # URL must be well formatted
)
{
#$url .= $req->env->{'REQUEST_URI'};
# Avoid append same URL
$req->{cspFormAction} .= " $url"
unless $req->{cspFormAction} =~ qr%\b$url\b%;
}
else {
$url .= '#';
}
$self->logger->debug("Use URL $url");
# Options to store in the loop
my $optionsLoop = {
name => $name,
key => $_,
module => $auth,
url => $url,
CHOICE_VALUE => $req->data->{_authChoice},
CHOICE_PARAM => $self->conf->{authChoiceParam},
};
# Get displayType for this module
no strict 'refs';
my $displayType = eval {
"Lemonldap::NG::Portal::Auth::${auth}"
->can('getForm')->( $self, $req );
} || 'logo';
$self->logger->debug( 'Display type '
. ( ref $displayType ? '[ref]' : $displayType )
. ' for module $auth' );
#$optionsLoop->{$displayType} = 1 unless(ref $displayType);
$optionsLoop->{form} = $displayType;
my $logo = $_;
if ( $auth eq 'Custom' ) {
$logo =
( $self->{conf}->{customAuth} =~ /::(\w+)$/ )[0];
}
# If displayType is logo, check if key.png is available
if ( -e $self->conf->{templateDir}
. "/../htdocs/static/common/modules/"
. $logo
. ".png" )
{
$optionsLoop->{logoFile} = $logo . ".png";
}
else {
$optionsLoop->{logoFile} = $auth . ".png";
}
# Register item in loop
push @authLoop, $optionsLoop;
$self->logger->debug(
"Authentication choice $name will be displayed");
}
else {
$req->error("Authentication choice $_ value is invalid");
return 0;
}
}
}
open my $fh,
$self->conf->{templateDir} . '/'
. $self->p->getSkin($req)
. "/choice.tpl"
or die $!;
my $res;
{
local $/ = undef;
$res = readline $fh;
}
close $fh;
while ( $res =~ m#<TMPL_LOOP NAME="AUTH_LOOP">(.*?)</TMPL_LOOP>#s ) {
my $content = $1;
my $new = '';
foreach (@authLoop) {
my $tmp = $content;
if ( my @match = ( $tmp =~ m#<TMPL_VAR NAME="(\w+)">#gs ) ) {
foreach my $key (@match) {
$tmp =~ s#<TMPL_VAR NAME="$key">#$_->{$key}#gs
if defined $_->{$key};
}
}
$tmp =~ s#__LLNG_FORM__#<TMPL_INCLUDE NAME="$_->{form}.tpl">#gs;
$new .= $tmp;
}
$res =~ s#<TMPL_LOOP NAME="AUTH_LOOP">.*?</TMPL_LOOP>#$new#s;
}
$req->tplParams->{CHOICE_PARAM} = $self->conf->{authChoiceParam};
return IO::String->new($res);
}
1;

View File

@ -0,0 +1,181 @@
package Lemonldap::NG::Portal::Lib::LDAP;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Lib::Net::LDAP;
use Lemonldap::NG::Portal::Main::Constants
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS);
extends 'Lemonldap::NG::Common::Module';
our $VERSION = '2.1.0';
# PROPERTIES
has ldap => (
is => 'rw',
lazy => 1,
builder => 'newLdap',
);
has attrs => (
is => 'rw',
lazy => 1,
builder => sub {
return [
values %{ $_[0]->{conf}->{exportedVars} },
values %{ $_[0]->{conf}->{ldapExportedVars} }
];
}
);
sub newLdap {
my $self = $_[0];
my $ldap;
# Build object and test LDAP connexion
unless (
$ldap = Lemonldap::NG::Portal::Lib::Net::LDAP->new(
{ p => $self->{p}, conf => $self->{conf} }
)
)
{
$self->logger->error("LDAP initialization error: $@");
return undef;
}
# Test connection
my $msg = $ldap->bind;
if ( $msg->code ) {
$self->logger->error( 'LDAP test has failed: ' . $msg->error );
}
elsif ( $self->{conf}->{ldapPpolicyControl} and not $ldap->loadPP() ) {
$self->logger->error("LDAP password policy error");
}
return $ldap;
}
has filter => (
is => 'rw',
lazy => 1,
builder => 'buildFilter',
);
has mailFilter => (
is => 'rw',
lazy => 1,
builder => 'buildMailFilter',
);
sub buildFilter {
return $_[0]->_buildFilter( $_[0]->conf->{AuthLDAPFilter}
|| $_[0]->conf->{LDAPFilter}
|| '(&(uid=$user)(objectClass=inetOrgPerson))' );
}
sub buildMailFilter {
my $f = $_[0]->conf->{mailLDAPFilter}
|| '(&(mail=$user)(objectClass=inetOrgPerson))';
$f =~ s/\$mail\b/\$user/g;
return $_[0]->_buildFilter($f);
}
sub _buildFilter {
my ( $self, $filter ) = @_;
my $conf = $self->{conf};
$self->{p}->logger->debug("LDAP Search base: $_[0]->{conf}->{ldapBase}");
$filter =~ s/"/\\"/g;
$filter =~ s/\$(\w+)/".\$req->{sessionInfo}->{$1}."/g;
$filter =~ s/\$req->\{sessionInfo\}->\{user\}/\$req->{user}/g;
$filter =~
s/\$req->\{sessionInfo\}->\{(_?password|mail)\}/\$req->{data}->{$1}/g;
$self->{p}->logger->debug("LDAP transformed filter: $filter");
$filter = "sub{my(\$req)=\$_[0];return \"$filter\";}";
my $res = eval $filter;
if ($@) {
$self->error("Unable to build fiter: $@");
}
return $res;
}
# INITIALIZATION
sub init {
my ($self) = @_;
$self->ldap
or $self->logger->error(
"LDAP initialization has failed, but let's continue");
$self->filter;
}
# RUNNING METHODS
sub getUser {
my ( $self, $req, %args ) = @_;
$self->validateLdap;
unless ( $self->ldap ) {
return PE_LDAPCONNECTFAILED;
}
$self->bind();
my $mesg = $self->ldap->search(
base => $self->conf->{ldapBase},
scope => 'sub',
filter => (
$args{useMail}
? $self->mailFilter->($req)
: $self->filter->($req)
),
defer => $self->conf->{ldapSearchDeref} || 'find',
attrs => $self->attrs,
);
if ( $mesg->code() != 0 ) {
$self->logger->error(
'LDAP Search error ' . $mesg->code . ": " . $mesg->error );
return PE_LDAPERROR;
}
if ( $mesg->count() > 1 ) {
$self->logger->error('More than one entry returned by LDAP directory');
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
unless ( $req->data->{ldapentry} = $mesg->entry(0) ) {
$self->userLogger->warn("$req->{user} was not found in LDAP directory");
eval { $self->p->_authentication->setSecurity($req) };
return PE_BADCREDENTIALS;
}
$req->data->{dn} = $req->data->{ldapentry}->dn();
PE_OK;
}
# Validate LDAP connection before use
sub validateLdap {
my ($self) = @_;
unless ($self->ldap
and $self->ldap->root_dse( attrs => ['supportedLDAPVersion'] ) )
{
$self->ldap->DESTROY if ( $self->ldap );
$self->ldap( $self->newLdap );
}
}
# Bind
sub bind {
my $self = shift;
$self->validateLdap;
return undef unless ( $self->ldap );
my $msg = $self->ldap->bind(@_);
if ( $msg->code ) {
$self->logger->error( $msg->error );
return undef;
}
return 1;
}
1;

View File

@ -0,0 +1,248 @@
## @file
# OpenID SREG extension for Lemonldap::NG::Portal::Issuer::OpenID class
## @class
# OpenID SREG extension for Lemonldap::NG::Portal::Issuer::OpenID class
package Lemonldap::NG::Portal::Lib::OpenID::SREG;
use strict;
use Lemonldap::NG::Common::Regexp;
our $VERSION = '2.1.0';
## @method protected hash sregHook(hash prm)
# Hook called to add SREG parameters to the OpenID response
# @return Hash containing wanted parameters
sub sregHook {
my ( $self, $req, $u, $trust_root, $is_id, $is_trusted, $prm ) = @_;
my ( @req, @opt );
# Refuse federation if rejected by user
if ( $req->param('confirm') and $req->param('confirm') == -1 ) {
my %h;
$h{$_} = undef foreach (
qw(fullname nickname language postcode timezone country gender email dob)
);
$self->p->updatePersistentSession( $req, \%h );
return 0;
}
# If identity is not trusted, does nothing
return ( 0, $prm ) unless ( $is_id and $is_trusted );
$self->logger->debug("SREG start");
my $accepted = 1;
# Check all parameters
my @pol;
while ( my ( $k, $v ) = each %$prm ) {
# Store policy if provided
if ( $k eq 'policy_url' ) {
if ( $v =~ Lemonldap::NG::Common::Regexp::HTTP_URI ) {
push @pol, { url => $v };
# Question: is it important to notify policy changes ?
# if yes, uncomment this
#my $p =
# $req->{sessionInfo}->{"_openidTrust$trust_root\_Policy"};
#$accepted = 0 unless ( $p and $p eq $v );
}
else {
$self->logger->error("Bad policy url");
}
}
# Parse required attributes
elsif ( $k eq 'required' ) {
$self->logger->debug("Required attr $v");
push @req, split( /,/, $v );
}
# Parse optional attributes
elsif ( $k eq 'optional' ) {
$self->logger->debug("Optional attr $v");
push @opt,
grep { defined $self->conf->{"openIdSreg_$trust_root$_"} }
split( /,/, $v );
}
else {
$self->logger->error("Unknown OpenID SREG request $k");
}
}
$req->data->{_openIdTrustExtMsg} .= $self->loadTemplate(
$req,
'openIdPol',
params => {
policies => \@pol,
}
) if (@pol);
# Check if required keys are valid SREG requests
# Question: reject bad SREG request ? Not done yet
@req = sregfilter( $self, @req );
@opt = sregfilter( $self, @opt );
# Return if nothing is asked
return ( 1, {} ) unless ( @req or @opt );
# If a required data is not available, returns nothing
foreach my $k (@req) {
unless ( $self->conf->{"openIdSreg_$k"} ) {
$self->logger->notice(
"Parameter $k is required by $trust_root but not defined in configuration"
);
$req->info(
$self->loadTemplate(
$req, 'simpleInfo',
params => { trspan => "openidRpns,$k" }
)
);
return ( 0, {} );
}
}
# Now set data
my ( %r, %msg, %ag, %toStore );
# Requested parameters: check if already agreed or confirm is set
foreach my $k (@req) {
my $agree = $req->{sessionInfo}->{"_openidTrust$trust_root\_$k"};
if ($accepted) {
unless ( $req->param('confirm') or $agree ) {
$accepted = 0;
}
elsif ( !$agree ) {
$toStore{"_openidTrust$trust_root\_$k"} = 1;
}
}
my $tmp = $self->conf->{"openIdSreg_$k"};
$tmp =~ s/^\$//;
$msg{req}->{$k} = $r{$k} =
$req->{sessionInfo}->{ $self->{"openIdSreg_$k"} } || '';
}
# Optional parameters:
foreach my $k (@opt) {
my $tmp = $self->conf->{"openIdSreg_$k"};
$tmp =~ s/^\$//;
my $agree = $req->{sessionInfo}->{"_openidTrust$trust_root\_$k"};
if ($accepted) {
# First, check if already accepted
unless ( $req->param('confirm') or defined($agree) ) {
$accepted = 0;
$r{$k} = $req->{sessionInfo}->{$tmp}
|| '';
}
# If confirmation is returned, check the value for this field
elsif ( $req->param('confirm') == 1 ) {
my $ck = 0;
if ( defined( $req->param("sreg_$k") ) ) {
$ck = ( $req->param("sreg_$k") eq 'OK' ) || 0;
}
# Store the value returned
if ( !defined($agree) or $agree != $ck ) {
$toStore{"_openidTrust$trust_root\_$k"} = $ck;
$agree = $ck;
}
}
}
$msg{opt}->{$k} = $req->{sessionInfo}->{$tmp} || '';
# Store the value only if user agree it
if ($agree) {
$r{$k} = $msg{opt}->{$k};
$ag{$k} = 1;
}
elsif ( !defined($agree) ) {
$ag{$k} = 1;
}
else {
$ag{$k} = 0;
}
}
$self->p->updatePersistentSession( $req, \%toStore ) if (%toStore);
# Check if user has agreed request
if ($accepted) {
$self->userLogger->info(
$req->{sessionInfo}->{ $self->conf->{whatToTrace} }
. " has accepted OpenID SREG exchange with $trust_root" );
return ( 1, \%r );
}
# else build message and return 0
else {
my ( @mopt, @mreq );
# No choice for requested parameters: just an information
foreach my $k (@req) {
utf8::decode( $msg{req}->{$k} );
push @mreq, { k => $k, m => $msg{req}->{$k} };
}
# For optional parameters: checkboxes are displayed
foreach my $k (@opt) {
utf8::decode( $msg{opt}->{$k} );
push @mopt,
{
k => $k,
m => $msg{opt}->{$k},
c => ( $ag{$k} ? 'checked' : '' )
};
}
$req->data->{_openIdTrustExtMsg} .= $self->loadTemplate(
$req,
'openIdTrust',
params => {
required => \@mreq,
optional => \@mopt,
}
);
$self->logger->debug('Building validation form');
return ( 0, $prm );
}
}
## @method private array sregfilter(array attr)
# Filter the arguments passed as parameters by checking their compliance with
# SREG.
# @return fitered data
sub sregfilter {
my ( $self, @attr ) = @_;
my ( @ret, @rej );
# Browse attributes
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;
}
}
# Warn if some parameters are rejected
if (@rej) {
$self->logger->warn( "Requested parameter(s) "
. join( ',', @rej )
. "is(are) not valid OpenID SREG parameter(s)" );
}
# Return valid SREG parameters
return @ret;
}
1;

View File

@ -0,0 +1,232 @@
## @file
# Subclass of Net::OpenID::Server that manage OpenID extensions
## @class
# Subclass of Net::OpenID::Server that manage OpenID extensions
package Lemonldap::NG::Portal::Lib::OpenID::Server;
use strict;
use base qw(Net::OpenID::Server);
use fields qw(_extensions);
use Net::OpenID::Server;
use Lemonldap::NG::Common::Regexp;
use constant DEBUG => 0;
our $VERSION = '2.1.0';
use constant OPENID2_NS => 'http://specs.openid.net/auth/2.0';
use constant OPENID2_ID_SELECT =>
'http://specs.openid.net/auth/2.0/identifier_select';
*_push_url_arg =
( $Net::OpenID::Server::VERSION >= 1.09 )
? *OpenID::util::push_url_arg
: *Net::OpenID::Server::_push_url_arg;
## @cmethod Lemonldap::NG::Portal::Lib::OpenID::Server new(hash opts)
# Call Net::OpenID::Server::new() and store extensions
# @param %opts Net::OpenID::Server options
# @return Lemonldap::NG::Portal::Lib::OpenID::Server new object
sub new {
my $class = shift;
my $self = fields::new($class);
my %opts = @_;
$self->$_( delete $opts{$_} ) foreach (qw(extensions));
$self->SUPER::new(%opts);
#$self->{get_args} = sub { $self->param(@_) };
}
## @method protected void extensions()
# Manage "extensions" constructor parameter
sub extensions {
my $self = shift;
$self->{_extensions} = shift;
}
## @method protected list _mode_checkid(string mode, boolean redirect_for_setup)
# Overload Net::OpenID::Server::_mode_checkid to call extensions hook
# @param $mode OpenID mode
# @param $redirect_for_setup indicates that user must be redirected or not for
# setup
# @return (string $type, hashref parameters)
sub _mode_checkid {
my Lemonldap::NG::Portal::Lib::OpenID::Server $self = shift;
my ( $mode, $redirect_for_setup ) = @_;
my $return_to = $self->args("openid.return_to");
return $self->_fail("no_return_to")
unless ( $return_to
and $return_to =~ m!^https?://! );
my $trust_root = $self->args("openid.trust_root") || $return_to;
$trust_root = $self->args("openid.realm")
if $self->args('openid.ns') eq OPENID2_NS;
return $self->_fail("invalid_trust_root")
unless ( $trust_root =~ Lemonldap::NG::Common::Regexp::HTTP_URI
and Net::OpenID::Server::_url_is_under( $trust_root, $return_to ) );
my $identity = $self->args("openid.identity");
# chop off the query string, in case our trust_root came from the return_to URL
$trust_root =~ s/\?.*//;
my $u = $self->_proxy("get_user");
if ( $self->args('openid.ns') eq OPENID2_NS
&& $identity eq OPENID2_ID_SELECT )
{
$identity = $self->_proxy( "get_identity", $u, $identity );
}
my $is_identity = $self->_proxy( "is_identity", $u, $identity );
my $is_trusted =
$self->_proxy( "is_trusted", $u, $trust_root, $is_identity );
my ( %extVars, %is_ext_trusted );
my $is_exts_trusted = 1;
if ( ref( $self->{_extensions} ) ) {
my @list = $self->args->();
my %extArgs;
foreach my $arg (@list) {
next unless ( $arg =~ /^openid\.(\w+)\.([\w\.]+)?/ );
my $tmp = $1;
my $val = $2;
$extArgs{$tmp}->{$val} = scalar $self->args->($arg);
}
foreach my $ns ( keys %{ $self->{_extensions} } ) {
print STDERR "Launching OpenIP $ns hook\n" if (DEBUG);
my $h;
( $is_ext_trusted{$ns}, $h ) = $self->{_extensions}->{$ns}->(
$u, $trust_root, $is_identity, $is_trusted,
delete( $extArgs{$ns} ) || {}
);
if ($h) {
while ( my ( $k, $v ) = each %$h ) {
print STDERR "$ns returned data: $k => $v\n" if (DEBUG);
$extVars{"$ns.$k"} = $v;
}
}
$is_exts_trusted &&= $is_ext_trusted{$ns};
}
# TODO: warn if keys(%extArgs)
}
# assertion path:
if ( $is_identity && $is_trusted && $is_exts_trusted ) {
my %sArgs = (
identity => $identity,
claimed_id => $self->args('openid.claimed_id'),
return_to => $return_to,
assoc_handle => $self->args("openid.assoc_handle"),
ns => $self->args('openid.ns'),
);
$sArgs{additional_fields} = \%extVars if (%extVars);
my $ret_url = $self->signed_return_url(%sArgs);
return ( "redirect", $ret_url );
}
# Assertion could not be made, so user requires setup (login/trust...
# something). Two ways that can happen: caller might have asked us for an
# immediate return with a setup URL (the default), or explictly said that
# we're in control of the user-agent's full window, and we can do whatever
# we want with them now.
# TODO: call extension sub for setup
my %setup_args = (
$self->_setup_map("trust_root"), $trust_root,
$self->_setup_map("realm"), $trust_root,
$self->_setup_map("return_to"), $return_to,
$self->_setup_map("identity"), $identity,
$self->_setup_map("assoc_handle"), $self->args("openid.assoc_handle"),
%extVars,
);
$setup_args{ $self->_setup_map('ns') } = $self->args('openid.ns')
if $self->args('openid.ns');
my $setup_url = $self->{setup_url}
or Carp::croak("No setup_url defined.");
_push_url_arg( \$setup_url, %setup_args );
if ( $mode eq "checkid_immediate" ) {
my $ret_url = $return_to;
if ( $self->args('openid.ns') eq OPENID2_NS ) {
_push_url_arg( \$ret_url, "openid.ns", $self->args('openid.ns') );
_push_url_arg( \$ret_url, "openid.mode", "setup_needed" );
}
else {
_push_url_arg( \$ret_url, "openid.mode", "id_res" );
_push_url_arg( \$ret_url, "openid.user_setup_url", $setup_url );
}
return ( "redirect", $ret_url );
}
else {
# the "checkid_setup" mode, where we take control of the user-agent
# and return to their return_to URL later.
if ($redirect_for_setup) {
return ( "redirect", $setup_url );
}
else {
return ( "setup", \%setup_args );
}
}
}
1;
__END__
=encoding utf8
=head1 NAME
Lemonldap::NG::Portal::Lib::OpenID::Server - Add capability to manage extensions to
Net::OpenID::Server
=head1 DESCRIPTION
Lemonldap::NG::Portal::Lib::OpenID::Server adds capability to manage extensions to
Net::OpenID::Server.
=head1 SEE ALSO
L<http://lemonldap-ng.org>, L<Net::OpenID::Server>
=head1 AUTHORS
=over
=item LemonLDAP::NG team L<http://lemonldap-ng.org/team>
=back
=head1 BUG REPORT
Use OW2 system to report bug or ask for features:
L<https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues>
=head1 DOWNLOAD
Lemonldap::NG is available at
L<http://forge.objectweb.org/project/showfiles.php?group_id=274>
=head1 COPYRIGHT AND LICENSE
See COPYING file for details.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see L<http://www.gnu.org/licenses/>.
=cut

View File

@ -0,0 +1,52 @@
##@file
# Slave common functions
##@class
# Slave common functions
package Lemonldap::NG::Portal::Lib::Slave;
use Exporter;
use base qw(Exporter);
use strict;
our @EXPORT = qw(checkIP checkHeader);
our $VERSION = '2.1.0';
# RUNNING METHODS
## @method Lemonldap::NG::Portal::_Slave checkIP()
# @return true if remote IP is accredited in LL::NG conf
sub checkIP {
my ( $self, $req ) = @_;
my $remoteIP = $req->address;
return 1
if (!$self->conf->{slaveMasterIP}
|| $self->conf->{slaveMasterIP} =~ /\b$remoteIP\b/ );
$self->userLogger->warn('Client IP not accredited for Slave module');
return 0;
}
## @method Lemonldap::NG::Portal::_Slave checkHeader()
# @return true if header content matches LL::NG conf
sub checkHeader {
my ( $self, $req ) = @_;
return 1
unless ( $self->conf->{slaveHeaderName}
and $self->conf->{slaveHeaderContent} );
my $slave_header = 'HTTP_' . uc( $self->{conf}->{slaveHeaderName} );
$slave_header =~ s/\-/_/g;
my $headerContent = $req->env->{$slave_header};
$self->logger->debug(
"Required Slave header => $self->{conf}->{slaveHeaderName}");
$self->logger->debug("Received Slave header content => $headerContent");
return 1
if ( $headerContent
and $self->conf->{slaveHeaderContent} =~ /\b$headerContent\b/ );
$self->userLogger->warn('Matching header not found for Slave module ');
return 0;
}
1;

View File

@ -3,7 +3,7 @@ package Lemonldap::NG::Portal::Lib::_tokenRule;
use strict;
use Mouse;
our $VERSION = '2.1';
our $VERSION = '2.1.0';
has ottRule => (
is => 'rw',