Merge branch 'v2.0'
This commit is contained in:
commit
52be87b012
|
@ -5,6 +5,11 @@
|
|||
# ~/CN=(?<CN>[^/]+) $CN;
|
||||
#}
|
||||
|
||||
# FastCGI backend definition
|
||||
upstream llng_portal_upstream {
|
||||
server unix:__FASTCGISOCKDIR__/llng-fastcgi.sock;
|
||||
}
|
||||
|
||||
server {
|
||||
listen __PORT__;
|
||||
server_name auth.__DNSDOMAIN__;
|
||||
|
@ -30,7 +35,7 @@ server {
|
|||
|
||||
# FastCGI configuration
|
||||
include /etc/nginx/fastcgi_params;
|
||||
fastcgi_pass unix:__FASTCGISOCKDIR__/llng-fastcgi.sock;
|
||||
fastcgi_pass llng_portal_upstream;
|
||||
fastcgi_param LLTYPE psgi;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_split_path_info ^(.*\.psgi)(/.*)$;
|
||||
|
@ -47,6 +52,30 @@ server {
|
|||
# Uncomment this if you use Auth SSL:
|
||||
#uwsgi_param SSL_CLIENT_S_DN_CN $ssl_client_s_dn_cn;
|
||||
|
||||
# REST/SOAP functions for sessions management (disabled by default)
|
||||
location ~ ^/index.psgi/adminSessions {
|
||||
fastcgi_pass llng_portal_upstream;
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for sessions access (disabled by default)
|
||||
location ~ ^/index.psgi/sessions {
|
||||
fastcgi_pass llng_portal_upstream;
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for configuration access (disabled by default)
|
||||
location ~ ^/index.psgi/config {
|
||||
fastcgi_pass llng_portal_upstream;
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for notification insertion (disabled by default)
|
||||
location ~ ^/index.psgi/notification {
|
||||
fastcgi_pass llng_portal_upstream;
|
||||
deny all;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
index index.psgi;
|
||||
|
@ -61,26 +90,6 @@ server {
|
|||
alias __PORTALSTATICDIR__;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for sessions management (disabled by default)
|
||||
location /index.psgi/adminSessions {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for sessions access (disabled by default)
|
||||
location /index.psgi/sessions {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for configuration access (disabled by default)
|
||||
location /index.psgi/config {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# REST/SOAP functions for notification insertion (disabled by default)
|
||||
location /index.psgi/notification {
|
||||
deny all;
|
||||
}
|
||||
|
||||
# DEBIAN
|
||||
# If install was made with USEDEBIANLIBS (official releases), uncomment this
|
||||
#location /javascript/ {
|
||||
|
|
|
@ -1153,7 +1153,7 @@ lemonldap-ng (1.2.3) stable; urgency=low
|
|||
urn:/Lemonldap::NG::Common::CGI::SOAPService
|
||||
* [LEMONLDAP-546] - Form replay: POST request is not sent
|
||||
* [LEMONLDAP-541] - Handler SOAP errors : setAttributes is not an
|
||||
authorizated function
|
||||
authorized function
|
||||
* [LEMONLDAP-547] - Update Browseable documentation in case of SAML in use
|
||||
* [LEMONLDAP-565] - Update META.yml files
|
||||
* [LEMONLDAP-581] - Clean Perl dependencies
|
||||
|
|
|
@ -98,7 +98,7 @@ Then, go in <code>OpenID parameters</code>:
|
|||
</li>
|
||||
<li class="level1"><div class="li"> <strong>Secret token</strong>: used to check integrity of OpenID response.</div>
|
||||
</li>
|
||||
<li class="level1"><div class="li"> <strong>Authorizated domain</strong>:</div>
|
||||
<li class="level1"><div class="li"> <strong>Authorized domain</strong>:</div>
|
||||
<ul>
|
||||
<li class="level2"><div class="li"> <strong>List type</strong>: choose white list to define allowed domains or black list to define forbidden domains</div>
|
||||
</li>
|
||||
|
|
|
@ -97,7 +97,7 @@ Sessions for connected users <em>(used by <a href="authproxy.html" class="wikili
|
|||
Authorizations for connected users (always enabled):
|
||||
</p>
|
||||
<ul>
|
||||
<li class="level1"><div class="li"> GET /mysession/?authorizationfor=<base64-encoded-url>: ask if url is authorizated</div>
|
||||
<li class="level1"><div class="li"> GET /mysession/?authorizationfor=<base64-encoded-url>: ask if url is authorized</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ To configure sessions, go in Manager, <code>General Parameters</code> » <code>S
|
|||
<h1 class="sectionedit2" id="command-line_tools">Command-line tools</h1>
|
||||
<div class="level1">
|
||||
<ul>
|
||||
<li class="level1"><div class="li"> LLNG Portal provides a simple tool to delete a session: <code>llngDeleteSession</code>. To use it, simply give it the user identifier <em>(wildcard are authorizated)</em>:</div>
|
||||
<li class="level1"><div class="li"> LLNG Portal provides a simple tool to delete a session: <code>llngDeleteSession</code>. To use it, simply give it the user identifier <em>(wildcard are authorized)</em>:</div>
|
||||
</li>
|
||||
</ul>
|
||||
<pre class="code shell"># Delete all sessions opened by user "dwho"
|
||||
|
|
|
@ -68,7 +68,7 @@ SOAP functions are not accessible by network by default. SOAP functions are prot
|
|||
</li>
|
||||
<li class="level2"><div class="li"> <strong>isAuthorizedURI(cookieValue,url)</strong>: check if user is granted to access to the function</div>
|
||||
</li>
|
||||
<li class="level2"><div class="li"> <strong>getMenuApplications(cookieValue)</strong>: return a list of authorizated applications (based on menu calculation)</div>
|
||||
<li class="level2"><div class="li"> <strong>getMenuApplications(cookieValue)</strong>: return a list of authorized applications (based on menu calculation)</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
@ -11,8 +11,8 @@ our $VERSION = '2.1.0';
|
|||
|
||||
## @cmethod Lemonldap::NG::Common::PSGI::SOAPService new(object obj,string @func)
|
||||
# Constructor
|
||||
# @param $obj object which will be called for SOAP authorizated methods
|
||||
# @param @func authorizated methods
|
||||
# @param $obj object which will be called for SOAP authorized methods
|
||||
# @param @func authorized methods
|
||||
# @return Lemonldap::NG::Common::PSGI::SOAPService object
|
||||
sub new {
|
||||
my ( $class, $obj, $req, @func ) = @_;
|
||||
|
@ -24,7 +24,7 @@ sub new {
|
|||
# Call the wanted function with the object given to the constructor.
|
||||
# AUTOLOAD() is a magic method called by Perl interpreter fon non existent
|
||||
# functions. Here, we use it to call the wanted function (given by $AUTOLOAD)
|
||||
# if it is authorizated
|
||||
# if it is authorized
|
||||
# @return data provided by the exported function
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
|
|
|
@ -96,6 +96,7 @@ sub set_custom {
|
|||
sub set_header_in {
|
||||
my ( $class, $request, %headers ) = @_;
|
||||
while ( my ( $h, $v ) = each %headers ) {
|
||||
utf8::downgrade($v);
|
||||
$request->env->{'psgi.r'}->headers_in->set( $h => $v );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ count(4);
|
|||
# Authentified queries
|
||||
# --------------------
|
||||
|
||||
# Authorizated query
|
||||
# Authorized query
|
||||
ok( $res = $client->_get( '/', undef, undef, "lemonldap=$sessionId" ),
|
||||
'Authentified query' );
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
|
|
|
@ -19,7 +19,7 @@ ok(
|
|||
'test3.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'DevOps'
|
||||
),
|
||||
'Authorizated query'
|
||||
'Authorized query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
count(2);
|
||||
|
@ -30,7 +30,7 @@ ok(
|
|||
'test3.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'DevOps'
|
||||
),
|
||||
'Authorizated query'
|
||||
'Authorized query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
count(2);
|
||||
|
|
|
@ -32,7 +32,7 @@ count(4);
|
|||
# Authentified queries
|
||||
# --------------------
|
||||
|
||||
# Authorizated query
|
||||
# Authorized query
|
||||
ok(
|
||||
$res =
|
||||
$client->_get( '/', undef, 'test.example.org', "lemonldap=$sessionId" ),
|
||||
|
|
|
@ -498,7 +498,7 @@ EOF
|
|||
printf STDERR $format, $self->handlerStatusConstantsFile;
|
||||
|
||||
# Handler Status file
|
||||
my $content = <<EOF;
|
||||
$content = <<EOF;
|
||||
# This file is generated by $module. Don't modify it by hand
|
||||
package Lemonldap::NG::Handler::Lib::StatusConstants;
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ sub tree {
|
|||
'passwordPolicyMinUpper',
|
||||
'passwordPolicyMinDigit',
|
||||
'portalDisplayPasswordPolicy',
|
||||
'portalDisplayGeneratePassword',
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -660,7 +659,9 @@ sub tree {
|
|||
title => 'mailOther',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'mailUrl', 'mailTimeout',
|
||||
'mailUrl',
|
||||
'mailTimeout',
|
||||
'portalDisplayGeneratePassword',
|
||||
'randomPasswordRegexp',
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -301,12 +301,18 @@ sub run {
|
|||
}
|
||||
|
||||
# Delete TOTP 2F device
|
||||
my $TOTPName;
|
||||
foreach (@$_2fDevices) {
|
||||
$TOTPName = $_->{name} if $_->{epoch} eq $epoch;
|
||||
}
|
||||
@$_2fDevices = grep { $_->{epoch} ne $epoch } @$_2fDevices;
|
||||
$self->logger->debug(
|
||||
"Delete 2F Device : { type => 'TOTP', epoch => $epoch }");
|
||||
"Delete 2F Device : { type => 'TOTP', epoch => $epoch, name => $TOTPName }"
|
||||
);
|
||||
$self->p->updatePersistentSession( $req,
|
||||
{ _2fDevices => to_json($_2fDevices) } );
|
||||
$self->userLogger->notice('TOTP deletion succeed');
|
||||
$self->userLogger->notice(
|
||||
"TOTP $TOTPName unregistration succeeds for $user");
|
||||
return [
|
||||
200,
|
||||
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
|
||||
|
|
|
@ -288,12 +288,18 @@ sub run {
|
|||
}
|
||||
|
||||
# Delete U2F device
|
||||
my $keyName;
|
||||
foreach (@$_2fDevices) {
|
||||
$keyName = $_->{name} if $_->{epoch} eq $epoch;
|
||||
}
|
||||
@$_2fDevices = grep { $_->{epoch} ne $epoch } @$_2fDevices;
|
||||
$self->logger->debug(
|
||||
"Delete 2F Device : { type => 'U2F', epoch => $epoch }");
|
||||
"Delete 2F Device : { type => 'U2F', epoch => $epoch, name => $keyName }"
|
||||
);
|
||||
$self->p->updatePersistentSession( $req,
|
||||
{ _2fDevices => to_json($_2fDevices) } );
|
||||
$self->userLogger->notice('U2F key unregistration succeed');
|
||||
$self->userLogger->notice(
|
||||
"U2F key $keyName unregistration succeeds for $user");
|
||||
return [
|
||||
200,
|
||||
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
|
||||
|
|
|
@ -181,12 +181,18 @@ sub run {
|
|||
}
|
||||
|
||||
# Delete Yubikey device
|
||||
my $UBKName;
|
||||
foreach (@$_2fDevices) {
|
||||
$UBKName = $_->{name} if $_->{epoch} eq $epoch;
|
||||
}
|
||||
@$_2fDevices = grep { $_->{epoch} ne $epoch } @$_2fDevices;
|
||||
$self->logger->debug(
|
||||
"Delete 2F Device : { type => 'UBK', epoch => $epoch }");
|
||||
"Delete 2F Device : { type => 'UBK', epoch => $epoch, name => $UBKName }"
|
||||
);
|
||||
$self->p->updatePersistentSession( $req,
|
||||
{ _2fDevices => to_json($_2fDevices) } );
|
||||
$self->userLogger->notice('Yubikey deletion succeed');
|
||||
$self->userLogger->notice(
|
||||
"Yubikey $UBKName unregistration succeeds for $user");
|
||||
return [
|
||||
200,
|
||||
[ 'Content-Type' => 'application/json', 'Content-Length' => 12, ],
|
||||
|
|
|
@ -255,7 +255,7 @@ sub run {
|
|||
unless ( $rule->( $req, $req->sessionInfo ) ) {
|
||||
$self->userLogger->warn( 'User '
|
||||
. $req->sessionInfo->{ $self->conf->{whatToTrace} }
|
||||
. "was not authorized to access to $rp" );
|
||||
. " was not authorized to access to $rp" );
|
||||
return PE_UNAUTHORIZEDPARTNER;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -388,7 +388,7 @@ sub run {
|
|||
unless ( $rule->( $req, $req->sessionInfo ) ) {
|
||||
$self->userLogger->warn( 'User '
|
||||
. $req->sessionInfo->{ $self->conf->{whatToTrace} }
|
||||
. "was not authorizated to access to $sp" );
|
||||
. " was not authorized to access to $sp" );
|
||||
return PE_UNAUTHORIZEDPARTNER;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,7 +291,12 @@ sub display {
|
|||
# 3 Authentication has been refused OR first access
|
||||
$skinfile = 'login';
|
||||
my $login = $self->userId($req);
|
||||
$login = '' if ( $login eq 'anonymous' );
|
||||
if ( $login eq 'anonymous' ) {
|
||||
$login = '';
|
||||
}
|
||||
elsif ( $req->user ) {
|
||||
$login = $req->{user};
|
||||
}
|
||||
%templateParams = (
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
|
|
|
@ -509,6 +509,9 @@ sub buildCookie {
|
|||
);
|
||||
}
|
||||
}
|
||||
$self->userLogger->notice(
|
||||
"User $req->{user} successfully authenticated at level $req->{sessionInfo}->{authenticationLevel}"
|
||||
);
|
||||
PE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
# - Authorizations for connected users (always):
|
||||
# * GET /mysession/?whoami : get "my" uid
|
||||
# * GET /mysession/?authorizationfor=<base64-encoded-url>: ask if url is
|
||||
# authorizated
|
||||
# authorized
|
||||
# * PUT /mysession/<type> : update some
|
||||
# persistent data
|
||||
# (restricted)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Generated by CoffeeScript 1.12.8
|
||||
// Generated by CoffeeScript 1.12.7
|
||||
|
||||
/*
|
||||
LemonLDAP::NG TOTP registration script
|
||||
|
|
|
@ -117,7 +117,7 @@ m#iframe src="http://auth.idp.com(/saml/relaySingleLogoutPOST)\?(relay=.*?)"#s,
|
|||
ok(
|
||||
getHeader( $res, 'Content-Security-Policy' ) =~
|
||||
/child-src auth.idp.com/,
|
||||
' Frame is authorizated'
|
||||
' Frame is authorized'
|
||||
)
|
||||
or explain( $res->[1],
|
||||
'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
|
@ -132,7 +132,7 @@ m#iframe src="http://auth.idp.com(/saml/relaySingleLogoutPOST)\?(relay=.*?)"#s,
|
|||
'Get iframe'
|
||||
);
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) !~ /frame-ancestors/,
|
||||
' Framing authorizated' )
|
||||
' Framing authorized' )
|
||||
or explain( $res->[1], 'No frame-ancestors' );
|
||||
( $host, $url, $query ) =
|
||||
expectAutoPost( $res, 'auth.sp.com', '/saml/proxySingleLogout',
|
||||
|
|
|
@ -126,7 +126,7 @@ m#iframe src="http://auth.sp.com(/saml/proxySingleLogout)\?(SAMLRequest=.*?)"#,
|
|||
my $query = $2;
|
||||
ok(
|
||||
getHeader( $res, 'Content-Security-Policy' ) =~ /child-src auth.sp.com/,
|
||||
'Frame is authorizated'
|
||||
'Frame is authorized'
|
||||
)
|
||||
or explain( $res->[1],
|
||||
'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
|
|
|
@ -209,7 +209,7 @@ count(1);
|
|||
my $url = $1;
|
||||
$query = $2;
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) =~ /child-src auth.idp.com/,
|
||||
'Frame is authorizated' )
|
||||
'Frame is authorized' )
|
||||
or
|
||||
explain( $res->[1], 'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
count(1);
|
||||
|
|
|
@ -209,7 +209,7 @@ count(1);
|
|||
my $url = $1;
|
||||
$query = $2;
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) =~ /child-src auth.idp.com/,
|
||||
'Frame is authorizated' )
|
||||
'Frame is authorized' )
|
||||
or
|
||||
explain( $res->[1], 'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
count(1);
|
||||
|
|
|
@ -177,7 +177,7 @@ count(1);
|
|||
my $url = $1;
|
||||
$query = $2;
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) =~ /child-src auth.idp.com/,
|
||||
'Frame is authorizated' )
|
||||
'Frame is authorized' )
|
||||
or
|
||||
explain( $res->[1], 'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
count(1);
|
||||
|
|
|
@ -169,7 +169,7 @@ count(1);
|
|||
my $url = $1;
|
||||
$query = $2;
|
||||
ok( getHeader( $res, 'Content-Security-Policy' ) =~ /child-src auth.idp.com/,
|
||||
'Frame is authorizated' )
|
||||
'Frame is authorized' )
|
||||
or
|
||||
explain( $res->[1], 'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
count(1);
|
||||
|
|
|
@ -262,7 +262,7 @@ SKIP: {
|
|||
ok(
|
||||
getHeader( $res, 'Content-Security-Policy' ) =~
|
||||
/child-src auth.idp.com/,
|
||||
'Frame is authorizated'
|
||||
'Frame is authorized'
|
||||
)
|
||||
or explain( $res->[1],
|
||||
'Content-Security-Policy => ...child-src auth.idp.com' );
|
||||
|
|
Loading…
Reference in New Issue