Commit 1212cd9b authored by Christophe Maudoux's avatar Christophe Maudoux 🐛

Merge branch 'v2.0'

parents 89179afb baf4a96c
......@@ -35,6 +35,7 @@ UNCOMPRESS=tar xzf
LISTCOMPRESSED=tar tzf
COMPRESSSUFFIX=tar.gz
NGINX=/usr/sbin/nginx
UGLIFYJSVERSION:=$(shell uglifyjs --version|perl -pe 's/^[^\d]*(\d).*$$/$$1/')
# Default directories install
# ---------------------------
......@@ -311,7 +312,11 @@ $(SRCMANAGERDIR)/site/htdocs/static/js/%.js: $(SRCMANAGERDIR)/site/coffee/%.coff
%.min.js: %.js
@echo "Compressing $*.js"
@uglifyjs $*.js --compress --mangle --comments='/Copyr/i' --source-map $*.min.js.map -o $*.min.js
if test "$(UGLIFYJSVERSION)" = 2; then \
uglifyjs $*.js --compress --mangle --comments='/Copyr/i' --source-map $*.min.js.map -o $*.min.js; \
else \
uglifyjs $*.js --compress --mangle --comments='/Copyr/i' --source-map -o $*.min.js; \
fi
fastcgi-server/man/llng-fastcgi-server.1p: fastcgi-server/sbin/llng-fastcgi-server
@echo Update FastCGI server man page
......
......@@ -4,7 +4,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Manager virtual host (manager.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
......@@ -7,7 +7,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Manager virtual host (manager.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
......@@ -7,7 +7,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Manager virtual host (manager.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
log_format lm_combined '$remote_addr - $lmremote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
'"$http_referer" "$http_user_agent" $lmremote_custom';
log_format lm_app '$remote_addr - $upstream_http_lm_remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
'"$http_referer" "$http_user_agent" $lmremote_custom';
......@@ -4,7 +4,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Portal Virtual Host (auth.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
......@@ -7,7 +7,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Portal Virtual Host (auth.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
......@@ -7,7 +7,7 @@
# To insert LLNG user id in Apache logs, declare this format and use it in
# CustomLog directive
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
#LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
# Portal Virtual Host (auth.__DNSDOMAIN__)
<VirtualHost __VHOSTLISTEN__>
......
......@@ -58,6 +58,7 @@ server {
##################################
auth_request /lmauth;
auth_request_set $lmremote_user $upstream_http_lm_remote_user;
auth_request_set $lmremote_custom $upstream_http_lm_remote_custom;
auth_request_set $lmlocation $upstream_http_location;
# If CDA is used, uncomment this
#auth_request_set $cookie_value $upstream_http_set_cookie;
......@@ -88,8 +89,9 @@ server {
# Uncomment this if you use https only
#add_header Strict-Transport-Security "max-age=15768000";
# Set REMOTE_USER (for FastCGI apps only)
# Set REMOTE_USER and REMOTE_CUSTOM (for FastCGI apps only)
#fastcgi_param REMOTE_USER $lmremote_user;
#fastcgi_param REMOTE_CUSTOM $lmremote_custom;
}
# Handle test CGI
......@@ -100,6 +102,7 @@ server {
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.*\.pl)(/.+)$;
fastcgi_param REMOTE_USER $lmremote_user;
fastcgi_param REMOTE_CUSTOM $lmremote_custom;
# Or with uWSGI
#include /etc/nginx/uwsgi_params;
......
......@@ -25,7 +25,7 @@ LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so
</Directory>
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O" llng
LogFormat "%v:%p %h %l %{Lm-Remote-User}o %t \"%r\" %>s %O %{Lm-Remote-Custom}o" llng
ErrorLog conf/apache2.log
CustomLog conf/apache2.log vhost_combined
......
......@@ -207,5 +207,6 @@
"sessionDataToRemember": {},
"timeout": 72000,
"userDB": "Same",
"whatToTrace": "_whatToTrace"
"whatToTrace": "_whatToTrace",
"customToTrace": "mail"
}
......@@ -37,6 +37,7 @@ server {
try_files $uri $uri/ =404;
auth_request /lmauth;
auth_request_set $lmremote_user $upstream_http_lm_remote_user;
auth_request_set $lmremote_custom $upstream_http_lm_remote_custom;
auth_request_set $lmlocation $upstream_http_location;
error_page 401 $lmlocation;
include conf/nginx-lua-headers.conf;
......
......@@ -372,10 +372,11 @@ languages = fr, en, it, vi, ar
; Manager modules enabled
; Set here the list of modules you want to see in manager interface
; The first will be used as default module displayed
enabledModules = conf, sessions, notifications, 2ndFA, viewer
;enabledModules = conf, sessions, notifications, 2ndFA, viewer
enabledModules = conf, sessions, notifications, 2ndFA
; To avoid restricted users to edit configuration, defaulModule MUST be different than 'conf'
; 'viewer' is set by default
; 'conf' is set by default
;defaultModule = viewer
; Viewer module allows us to edit configuration in read-only mode
......@@ -384,7 +385,7 @@ enabledModules = conf, sessions, notifications, 2ndFA, viewer
;viewerAllowDiff = $uid ne 'dwho'
;
; Viewer options - Default values
;viewerHiddenKeys = samlIDPMetaDataNodes samlSPMetaDataNodes
;viewerHiddenKeys = samlIDPMetaDataNodes samlSPMetaDataNodes managerPassword ManagerDn globalStorageOptions persistentStorageOptions
;viewerAllowBrowser = 0
;viewerAllowDiff = 0
......
......@@ -129,7 +129,7 @@ sub defaultValues {
'ldapVersion' => 3,
'linkedInAuthnLevel' => 1,
'linkedInFields' => 'id,first-name,last-name,email-address',
'linkedInScope' => 'r_basicprofile r_emailaddress',
'linkedInScope' => 'r_liteprofile r_emailaddress',
'linkedInUserField' => 'emailAddress',
'localSessionStorage' => 'Cache::FileCache',
'localSessionStorageOptions' => {
......
......@@ -276,11 +276,11 @@ sub getMod {
my ( $self, $req ) = @_;
my ( $s, $m );
unless ( $s = $req->params('sessionType') ) {
$self->error('Session type is required');
$self->error($req->error('Session type is required'));
return ();
}
unless ( $m = $self->sessionTypes->{$s} ) {
$self->error('Unknown (or unconfigured) session type');
$self->error($req->error('Unknown (or unconfigured) session type'));
return ();
}
if ( my $kind = $req->params('kind') ) {
......
......@@ -92,6 +92,10 @@ sub handler {
if ( $hdrs{'Lm-Remote-User'} ) {
$r->user( $hdrs{'Lm-Remote-User'} );
}
if ( $hdrs{'Lm-Remote-Custom'} ) {
$r->subprocess_env( REMOTE_CUSTOM => $hdrs{'Lm-Remote-Custom'} );
}
my $i = 1;
while ( $hdrs{"Headername$i"} ) {
$r->headers_in->set( $hdrs{"Headername$i"} => $hdrs{"Headervalue$i"} )
......
......@@ -81,6 +81,15 @@ sub set_user {
$request->env->{'psgi.r'}->user($user);
}
## @method void set_custom(string custom)
# sets remote_custom
# @param custom string custom_header
sub set_custom {
my ( $class, $request, $custom ) = @_;
$request->env->{'psgi.r'}->subprocess_env( REMOTE_CUSTOM => $custom )
if defined $custom;
}
## @method void set_header_in(hash headers)
# sets or modifies request headers
# @param headers hash containing header names => header value
......
......@@ -176,6 +176,13 @@ sub user {
|| _whatToTrace => 'anonymous' };
}
## @method hashRef custom()
# @return hash of custom data
sub custom {
my ( $self, $req ) = @_;
return { $Lemonldap::NG::Handler::Main::tsv->{customToTrace} };
}
## @method string userId()
# @return user identifier to log
sub userId {
......@@ -195,7 +202,7 @@ sub group {
}
## @method PSGI::Response sendError($req,$err,$code)
# Add user di to $err before calling Lemonldap::NG::Common::PSGI::sendError()
# Add user id to $err before calling Lemonldap::NG::Common::PSGI::sendError()
# @param $req Lemonldap::NG::Common::PSGI::Request
# @param $err String to push
# @code int HTTP error code (default to 500)
......
......@@ -197,7 +197,7 @@ sub defaultValuesInit {
securedCookie timeout timeoutActivity
timeoutActivityInterval useRedirectOnError useRedirectOnForbidden
useSafeJail whatToTrace handlerInternalCache
handlerServiceTokenTTL
handlerServiceTokenTTL customToTrace
)
);
......
......@@ -147,6 +147,7 @@ sub run {
# ACCOUNTING (1. Inform web server)
$class->set_user( $req, $session->{ $class->tsv->{whatToTrace} } );
$class->set_custom( $req, $session->{ $class->tsv->{customToTrace} } );
# AUTHORIZATION
return ( $class->forbidden( $req, $session ), $session )
......
......@@ -41,6 +41,15 @@ sub set_user {
push @{ $req->{respHeaders} }, 'Lm-Remote-User' => $user;
}
## @method void set_custom(string custom)
# sets remote_custom in response headers
# @param custom string custom_value
sub set_custom {
my ( $class, $req, $custom ) = @_;
push @{ $req->{respHeaders} }, 'Lm-Remote-Custom' => $custom
if defined $custom;
}
## @method void set_header_in(hash headers)
# sets or modifies request headers
# @param headers hash containing header names => header value
......
......@@ -39,6 +39,7 @@ sub unset_header_in {
*setServerSignature = *Lemonldap::NG::Handler::PSGI::Main::setServerSignature;
*thread_share = *Lemonldap::NG::Handler::PSGI::Main::thread_share;
*set_user = *Lemonldap::NG::Handler::PSGI::Main::set_user;
*set_custom = *Lemonldap::NG::Handler::PSGI::Main::set_custom;
*set_header_out = *Lemonldap::NG::Handler::PSGI::Main::set_header_out;
*is_initial_req = *Lemonldap::NG::Handler::PSGI::Main::is_initial_req;
*print = *Lemonldap::NG::Handler::PSGI::Main::print;
......
......@@ -72,7 +72,7 @@ sub handler {
my $i = 0;
while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs;
if ( $k =~ /^(?:Lm-Remote-User|Cookie)$/ ) {
if ( $k =~ /^(?:Lm-Remote-(?:User|Custom)|Cookie)$/ ) {
push @convertedHdrs, $k, $v;
}
else {
......
......@@ -52,7 +52,7 @@ sub init {
return 0;
}
$self->{enabledModules} ||= "conf, sessions, notifications, 2ndFA, viewer";
$self->{enabledModules} ||= "conf, sessions, notifications, 2ndFA";
my @links;
my @enabledModules =
map { push @links, $_; "Lemonldap::NG::Manager::" . ucfirst($_) }
......@@ -88,10 +88,10 @@ sub init {
);
# Avoid restricted users to access configuration by default route
my $defaultMod = $self->{defaultModule} || 'viewer';
my $defaultMod = $self->{defaultModule} || 'conf';
$self->logger->debug("Default module -> $defaultMod");
my ($index) =
grep { $working[$_] =~ /::$defaultMod$/ } ( 0 .. $#working );
grep { $working[$_] =~ /::$defaultMod$/i } ( 0 .. $#working );
$index //= $#working;
$self->logger->debug("Default index -> $index");
$self->defaultRoute( $working[$index]->defaultRoute );
......
......@@ -1022,6 +1022,9 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'customRegister' => {
'type' => 'text'
},
'customToTrace' => {
'type' => 'lmAttrOrMacro'
},
'customUserDB' => {
'type' => 'text'
},
......@@ -1555,7 +1558,7 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'type' => 'text'
},
'linkedInScope' => {
'default' => 'r_basicprofile r_emailaddress',
'default' => 'r_liteprofile r_emailaddress',
'type' => 'text'
},
'linkedInUserField' => {
......
......@@ -891,6 +891,11 @@ sub attributes {
documentation => 'Session parameter used to fill REMOTE_USER',
flags => 'hp',
},
customToTrace => {
type => 'lmAttrOrMacro',
documentation => 'Session parameter used to fill REMOTE_CUSTOM',
flags => 'hp',
},
lwpOpts => {
type => 'keyTextContainer',
documentation => 'Options given to LWP::UserAgent',
......@@ -3163,7 +3168,7 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
},
linkedInUserField => { type => 'text', default => 'emailAddress' },
linkedInScope =>
{ type => 'text', default => 'r_basicprofile r_emailaddress' },
{ type => 'text', default => 'r_liteprofile r_emailaddress' },
# WebID
webIDAuthnLevel => {
......
......@@ -250,7 +250,9 @@ sub cTrees {
]
},
],
casAppMetaDataNode => [ {
casAppMetaDataNode => [
'casAppMetaDataExportedVars',
{
title => 'casAppMetaDataOptions',
form => 'simpleInputContainer',
nodes => [
......@@ -259,7 +261,6 @@ sub cTrees {
'casAppMetaDataOptionsRule'
]
},
'casAppMetaDataExportedVars',
],
};
}
......
......@@ -511,7 +511,7 @@ sub tree {
title => 'logParams',
help => 'logs.html',
form => 'simpleInputContainer',
nodes => [ 'whatToTrace', 'hiddenAttributes' ]
nodes => [ 'whatToTrace', 'customToTrace', 'hiddenAttributes' ]
},
{
title => 'cookieParams',
......
......@@ -383,6 +383,7 @@ sub _scanNodes {
}
elsif ($h) {
hdebug(' opened');
$self->confChanged(1);
$self->set( $target, $key, $leaf->{title},
$leaf->{data} );
}
......@@ -451,6 +452,7 @@ sub _scanNodes {
}
elsif ($h) {
hdebug(' opened');
$self->confChanged(1);
$self->set( $target, $key, $leaf->{title},
$leaf->{data} );
}
......
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
* 2ndFA Session explorer
......
......@@ -10,28 +10,6 @@ function templates(tpl,key) {
switch(tpl){
case 'casAppMetaDataNode':
return [
{
"_nodes" : [
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
"title" : "casAppMetaDataOptionsService"
},
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsUserAttribute",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsUserAttribute",
"title" : "casAppMetaDataOptionsUserAttribute"
},
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
"title" : "casAppMetaDataOptionsRule"
}
],
"id" : "casAppMetaDataOptions",
"title" : "casAppMetaDataOptions",
"type" : "simpleInputContainer"
},
{
"cnodes" : tpl+"s/"+key+"/"+"casAppMetaDataExportedVars",
"default" : [
......@@ -57,6 +35,28 @@ function templates(tpl,key) {
"id" : tpl+"s/"+key+"/"+"casAppMetaDataExportedVars",
"title" : "casAppMetaDataExportedVars",
"type" : "keyTextContainer"
},
{
"_nodes" : [
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsService",
"title" : "casAppMetaDataOptionsService"
},
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsUserAttribute",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsUserAttribute",
"title" : "casAppMetaDataOptionsUserAttribute"
},
{
"get" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
"id" : tpl+"s/"+key+"/"+"casAppMetaDataOptionsRule",
"title" : "casAppMetaDataOptionsRule"
}
],
"id" : "casAppMetaDataOptions",
"title" : "casAppMetaDataOptions",
"type" : "simpleInputContainer"
}
]
;
......
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
LemonLDAP::NG Manager client
......
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
* Sessions explorer
......
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.12.8
/*
LemonLDAP::NG Viewer client
......
......@@ -205,6 +205,7 @@
"customPassword":"وحدة كلمة المرورالمخصصة",
"customPortalSkin":"غلاف البوابة مخصص",
"customRegister":"وحدة تسجيل مخصص",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"وحدة قاعدة البيانات المخصصة",
"date":"تاريخ",
"dbiAuthChain":"سلسلة",
......
......@@ -205,6 +205,7 @@
"customPassword":"Custom password module",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Custom user DB module",
"date":"Datum",
"dbiAuthChain":"Chain",
......
......@@ -205,6 +205,7 @@
"customPassword":"Custom password module",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Custom user DB module",
"date":"Date",
"dbiAuthChain":"Chain",
......
......@@ -205,6 +205,7 @@
"customPassword":"Module de mots-de-passe personnalisé",
"customPortalSkin":"Style personnalisé du portail",
"customRegister":"Module d'enregistrement personnalisé",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Module BD utilisateurs personnalisé",
"date":"Date",
"dbiAuthChain":"Chaîne",
......
......@@ -205,6 +205,7 @@
"customPassword":"Personalizza il modulo password",
"customPortalSkin":"Personalizza faccia del portale ",
"customRegister":"Personalizza modulo di registro",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Personalizza modulo utente DB",
"date":"Data",
"dbiAuthChain":"Catena",
......
......@@ -205,6 +205,7 @@
"customPassword":"Mô đun mật khẩu tùy chỉnh",
"customPortalSkin":"Tùy chỉnh giao diện cổng thông tin",
"customRegister":"Module đăng ký tùy chỉnh",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Mô đun DB người dùng tùy chỉnh",
"date":"Ngày",
"dbiAuthChain":"Chuỗi",
......
......@@ -205,6 +205,7 @@
"customPassword":"Custom password module",
"customPortalSkin":"Custom portal skin",
"customRegister":"Custom register module",
"customToTrace":"REMOTE_CUSTOM",
"customUserDB":"Custom user DB module",
"date":"日期",
"dbiAuthChain":"Chain",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -21,7 +21,7 @@
<!-- Last buttons, available languages -->
</div>
<ul class="hidden-xs nav navbar-nav" role="grid">
<li ng-repeat="l in links" id="l in links"><a href="{{l.target}}" role="row" ng-mouseup="clickStyle={color: '#ffb84d'}"><strong><i ng-if="activeModule == l.title" ng-style="myStyle" class="glyphicon glyphicon-{{l.icon}}"></i><i ng-if="activeModule != l.title" class="glyphicon glyphicon-{{l.icon}}" ng-style="clickStyle"></i> <span ng-if="activeModule == l.title" ng-style="myStyle" ng-bind="translate(l.title)"></span><span ng-if="activeModule != l.title" ng-bind="translate(l.title)" ng-style="clickStyle"></span></strong></a></li>
<li ng-repeat="l in links" id="l in links"><a href="{{l.target}}" role="row"><strong><i ng-if="activeModule == l.title" ng-style="myStyle" class="glyphicon glyphicon-{{l.icon}}"></i><i ng-if="activeModule != l.title" class="glyphicon glyphicon-{{l.icon}}" ng-style="clickStyle"></i> <span ng-if="activeModule == l.title" ng-style="myStyle" ng-bind="translate(l.title)"></span><span ng-if="activeModule != l.title" ng-bind="translate(l.title)" ng-style="clickStyle"></span></strong></a></li>
</ul>
<ul class="hidden-xs nav navbar-nav navbar-right">
<li uib-dropdown>
......
......@@ -119,13 +119,6 @@ sub getForm {
return [ split /[, ]\s*/, $self->conf->{combinationForms} ]
if ( $self->conf->{combinationForms} );
if ( $req->{error} > PE_OK ) {
$self->logger->notice('Start over combination schema');
my $stack = $self->stackSub->( $req->env );
my ( $res, $name ) = $stack->[0]->[0]->( 'getForm', $req );
return $res;
}
my ( $nb, $stack ) = (
$req->data->{dataKeep}->{combinationTry},
$req->data->{combinationStack}
......@@ -198,6 +191,7 @@ sub try {
# If more than 1 scheme is available
my ( $res, $name );
if ( $nb < @$stack - 1 ) {
# TODO: change logLevel for userLog()
......
......@@ -50,7 +50,16 @@ has linkedInPeopleEndpoint => (
lazy => 1,
default => sub {
$_[0]->conf->{linkedInPeopleEndpoint}
|| 'https://api.linkedin.com/v1/people/';
|| 'https://api.linkedin.com/v2/me';
}
);
has linkedInEmailEndpoint => (
is => 'ro',
lazy => 1,
default => sub {
$_[0]->conf->{linkedInEmailEndpoint}
|| 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))';
}
);
......@@ -123,13 +132,11 @@ sub extractFormInfo {
$self->logger->debug("Get access token $access_token from LinkedIn");
# Build People EndPoint URI
my $linkedInPeopleEndpoint =
$self->linkedInPeopleEndpoint . "~:("
. $self->conf->{linkedInFields}
. ")?format=json";
# Call People EndPoint URI
$self->logger->debug(
"Call LinkedIn People Endpoint " . $self->linkedInPeopleEndpoint );
my $people_response = $self->ua->get( $linkedInPeopleEndpoint,
my $people_response = $self->ua->get( $self->linkedInPeopleEndpoint,
"Authorization" => "Bearer $access_token" );
if ( $people_response->is_error ) {
......@@ -141,6 +148,9 @@ sub extractFormInfo {
my $people_content = $people_response->decoded_content;
$self->logger->debug(
"Response from LinkedIn People API: $people_content");
eval {
$json_hash = from_json( $people_content, { allow_nonref => 1 } );
};
......@@ -153,6 +163,39 @@ sub extractFormInfo {
$req->data->{linkedInData}->{$_} = $json_hash->{$_};
}
# Call Email EndPoint URI
if ( $self->conf->{linkedInScope} =~ /r_emailaddress/ ) {
$self->logger->debug( "Call LinkedIn Email Endpoint "
. $self->linkedInEmailEndpoint );
my $email_response = $self->ua->get( $self->linkedInEmailEndpoint,
"Authorization" => "Bearer $access_token" );
if ( $email_response->is_error ) {
$self->logger->error(
"Bad authorization response: " . $email_response->message );
$self->logger->debug( $email_response->content );
return PE_ERROR;
}
my $email_content = $email_response->decoded_content;
$self->logger->debug(
"Response from LinkedIn Email API: $email_content");
eval {
$json_hash = from_json( $email_content, { allow_nonref => 1 } );
};
if ($@) {
$self->logger->error("Unable to decode JSON $email_content");
return PE_ERROR;
}
$req->data->{linkedInData}->{"emailAddress"} =