diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm
index 02a49b5b0..e7c54434b 100644
--- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm
+++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/NewLocationWarning.pm
@@ -4,16 +4,33 @@ use strict;
use Mouse;
use POSIX qw(strftime);
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK);
+use List::MoreUtils qw/uniq/;
our $VERSION = '2.0.14';
+has locationAttribute => ( is => 'rw' );
+has locationDisplayAttribute => ( is => 'rw' );
+has locationMaxValues => ( is => 'rw' );
+
+has mailSessionKey => (
+ is => 'rw',
+ lazy => 1,
+ default => sub {
+ return
+ $_[0]->{conf}->{newLocationWarningMailAttribute}
+ || $_[0]->{conf}->{mailSessionKey}
+ || 'mail';
+ }
+);
+
extends qw(
Lemonldap::NG::Portal::Lib::SMTP
Lemonldap::NG::Portal::Main::Plugin
);
# Entrypoint
-use constant aroundSub => { storeHistory => 'check' };
+use constant afterSub => { setLocalGroups => 'checkNewLocation' };
+use constant endAuth => 'sendWarningEmail';
sub init {
my ($self) = @_;
@@ -29,38 +46,76 @@ sub init {
'"NewLocationWarning" plugin enabled WITHOUT "History" plugin');
return 0;
}
+
+ $self->locationAttribute( $self->conf->{newLocationWarningLocationAttribute}
+ || 'ipAddr' );
+ $self->locationDisplayAttribute(
+ $self->conf->{newLocationWarningLocationDisplayAttribute}
+ || $self->locationAttribute );
+ $self->locationMaxValues( $self->conf->{newLocationWarningMaxValues} || 0 );
return 1;
}
-sub check {
- my ( $self, $sub, $req ) = @_;
- my $successLogin = $req->sessionInfo->{_loginHistory}->{successLogin};
- my $failedLogin = $req->sessionInfo->{_loginHistory}->{failedLogin};
- my $sourceIP = $req->env->{ipAddr};
- $self->logger->debug("Source IP: $sourceIP");
+sub checkNewLocation {
+ my ( $self, $req ) = @_;
- my %knownIPs = map { $_->{ipAddr} => 1 } ( @$successLogin, @$failedLogin );
+ my $successLogin = $req->sessionInfo->{_loginHistory}->{successLogin} || [];
- if ( $knownIPs{$sourceIP} ) {
- $self->logger->debug('Known location');
- return $sub->($req);
+ my $location = $req->sessionInfo->{ $self->locationAttribute };
+
+ unless ($location) {
+ $self->logger->debug( "Could not find location of user " . $req->user );
+ }
+
+ # Get all non-empty, unique values of location attribute through list of
+ # successful logins
+ my @envHistory =
+ grep { $_ // "" }
+ uniq( map { $_->{ $self->locationAttribute } // "" } @{$successLogin} );
+
+ # Only consider some of the past unique locations
+ my $maxLocations = $self->locationMaxValues;
+ splice @envHistory, $maxLocations
+ if ( $maxLocations and ( scalar @envHistory > $maxLocations ) );
+
+ if ( grep { $_ eq $location } @envHistory ) {
+ $self->userLogger->debug(
+ "User " . $req->user . " logged in from known location $location" );
}
else {
- $self->logger->warn("New location found: $sourceIP");
- $self->_sendMail($req);
- return $sub->($req);
+ # Not the first location in history, warn if new location
+ if (@envHistory) {
+ $self->userLogger->info( "User "
+ . $req->user
+ . " logged in from unknown location $location" );
+ my $riskLevel = ( $req->sessionInfo->{_riskLevel} || 0 ) + 1;
+ $req->sessionInfo->{_riskDetails}->{newLocation} =
+ $req->sessionInfo->{ $self->locationDisplayAttribute };
+ }
+ else {
+ $self->userLogger->info( "User "
+ . $req->user
+ . " logged with empty location history from location $location"
+ );
+ }
}
+ return PE_OK;
+}
+
+sub sendWarningEmail {
+ my ( $self, $req ) = @_;
+ if ( $req->sessionInfo->{_riskDetails}->{newLocation} ) {
+ return $self->_sendMail($req);
+ }
+ return PE_OK;
}
sub _sendMail {
my ( $self, $req ) = @_;
my $date = strftime( '%F %X', localtime );
- my $sourceIP = $req->env->{ipAddr};
- my $host = $req->env->{HTTP_HOST};
+ my $location = $req->sessionInfo->{_riskDetails}->{newLocation};
my $ua = $req->env->{HTTP_USER_AGENT};
- my $mail =
- $req->sessionInfo->{ $self->conf->{newLocationWarningMailAttribute}
- || 'mail' };
+ my $mail = $req->sessionInfo->{ $self->mailSessionKey };
# Build mail content
my $tr = $self->translate($req);
@@ -78,10 +133,10 @@ sub _sendMail {
$body = $self->conf->{newLocationWarningMailBody};
# Replace variables in body
- $body =~ s/\$newLocationUserAgent/$ua/ge;
- $body =~ s/\$newLocationIP/$sourceIP/ge;
- $body =~ s/\$newLocationDate/$date/ge;
- $body =~ s/\$newLocationHost/$host/ge;
+ $body =~ s/\$ua\b/$ua/ge;
+ $body =~ s/\$location\b/$location/ge;
+ $body =~ s/\$date\b/$date/ge;
+ $body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge;
}
else {
@@ -91,10 +146,9 @@ sub _sendMail {
'mail_new_location_warning',
filter => $tr,
params => {
- session_ipAddr => $sourceIP,
- date => $date,
- host => $host,
- ua => $ua
+ location => $location,
+ date => $date,
+ ua => $ua
},
);
$html = 1;
diff --git a/lemonldap-ng-portal/site/templates/common/mail/ar.json b/lemonldap-ng-portal/site/templates/common/mail/ar.json
index fed1c585a..cb8d33045 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/ar.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/ar.json
@@ -7,6 +7,7 @@
"goToPortal":"انتقل إلى البوابة",
"hello":"مرحبا ",
"host":"Host",
+"location": "Location",
"mail2fSubject":"[LemonLDAP::NG] تسجيل الدخول الخاص بك هو ",
"mailConfirmSubject":"تأكيد إعادة تعيين كلمة المرور[LemonLDAP::NG]",
"mailSubject":"كلمة المرور الجديدة [LemonLDAP::NG]",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/en.json b/lemonldap-ng-portal/site/templates/common/mail/en.json
index 506606e9e..e18aee857 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/en.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/en.json
@@ -7,6 +7,7 @@
"goToPortal":"Go to portal",
"hello":"Hello",
"host":"Host",
+"location": "Location",
"mail2fSubject":"[LemonLDAP::NG] Your login code",
"mailConfirmSubject": "[LemonLDAP::NG] Password reset confirmation",
"mailSubject": "[LemonLDAP::NG] Your new password",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/es.json b/lemonldap-ng-portal/site/templates/common/mail/es.json
index 2a62fce1a..56494fa47 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/es.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/es.json
@@ -7,6 +7,7 @@
"goToPortal":"Ir al portal",
"hello":"Hola",
"host":"Host",
+"location": "Location",
"mail2fSubject":"[LemonLDAP::NG] Su código de acceso",
"mailConfirmSubject":"[LemonLDAP::NG] Confirmación de reinicio de contraseña",
"mailSubject":"[LemonLDAP::NG] Su nueva contraseña",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/fi.json b/lemonldap-ng-portal/site/templates/common/mail/fi.json
index c039f932c..265ef7dca 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/fi.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/fi.json
@@ -7,6 +7,7 @@
"goToPortal":"Siirry portaaliin",
"hello":"Hei",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] Your login code",
"mailConfirmSubject":"[LemonLDAP::NG] Salasanan nollauksen vahvistus",
"mailSubject":"[LemonLDAP::NG] Uusi salasanasi",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/fr.json b/lemonldap-ng-portal/site/templates/common/mail/fr.json
index 84ffa14a8..fa2f9d70c 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/fr.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/fr.json
@@ -7,6 +7,7 @@
"goToPortal":"Aller au portail",
"hello":"Bonjour",
"host":"Hôte",
+"location":"Localisation",
"mail2fSubject":"[LemonLDAP::NG] Votre code de connexion",
"mailConfirmSubject": "[LemonLDAP::NG] Confirmation de réinitialisation de mot de passe",
"mailSubject": "[LemonLDAP::NG] Votre nouveau mot de passe",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/it.json b/lemonldap-ng-portal/site/templates/common/mail/it.json
index a90ce4d9c..2308f665e 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/it.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/it.json
@@ -7,6 +7,7 @@
"goToPortal":"Vai al portale",
"hello":"Salve",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP :: NG] Il tuo codice di accesso",
"mailConfirmSubject":"Conferma reimpostazione password [LemonLDAP::NG] ",
"mailSubject":"[LemonLDAP::NG] La tua nuova password",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/ms.json b/lemonldap-ng-portal/site/templates/common/mail/ms.json
index 30382392b..c51b428bb 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/ms.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/ms.json
@@ -7,6 +7,7 @@
"goToPortal":"Go to portal",
"hello":"Hello",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] Kod login anda",
"mailConfirmSubject":"[LemonLDAP::NG] Pengesahan penetapan semula kata laluan",
"mailSubject":"[LemonLDAP::NG] Kata laluan baru anda",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/tr.json b/lemonldap-ng-portal/site/templates/common/mail/tr.json
index 90a4b7f25..007afe18f 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/tr.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/tr.json
@@ -7,6 +7,7 @@
"goToPortal":"Portala git",
"hello":"Merhaba",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] Giriş kodunuz",
"mailConfirmSubject":"[LemonLDAP::NG] Parola sıfırlama onayı",
"mailSubject":"[LemonLDAP::NG] Yeni parolanız",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/vi.json b/lemonldap-ng-portal/site/templates/common/mail/vi.json
index a032a689a..dc0ba8c55 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/vi.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/vi.json
@@ -7,6 +7,7 @@
"goToPortal":"Đi tới cổng thông tin",
"hello":"Xin chào",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] Your login code",
"mailConfirmSubject":"[LemonLDAP::NG] Xác nhận thiết lập lại mật khẩu",
"mailSubject":"[LemonLDAP::NG] Mật khẩu mới của bạn",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/zh_CN.json b/lemonldap-ng-portal/site/templates/common/mail/zh_CN.json
index 254831821..d777f21c9 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/zh_CN.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/zh_CN.json
@@ -7,6 +7,7 @@
"goToPortal":"回到首页",
"hello":"您好",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] Your login code",
"mailConfirmSubject":"[LemonLDAP::NG] 密码重置确认",
"mailSubject":"[LemonLDAP::NG] 您的新密码",
diff --git a/lemonldap-ng-portal/site/templates/common/mail/zh_TW.json b/lemonldap-ng-portal/site/templates/common/mail/zh_TW.json
index 3848db65f..34ce5dcc8 100644
--- a/lemonldap-ng-portal/site/templates/common/mail/zh_TW.json
+++ b/lemonldap-ng-portal/site/templates/common/mail/zh_TW.json
@@ -7,6 +7,7 @@
"goToPortal":"回到首頁",
"hello":"您好",
"host":"Host",
+"location":"Location",
"mail2fSubject":"[LemonLDAP::NG] 您的登入代碼",
"mailConfirmSubject":"[LemonLDAP::NG] 確認重設密碼",
"mailSubject":"[LemonLDAP::NG] 您的新密碼",
diff --git a/lemonldap-ng-portal/site/templates/common/mail_new_location_warning.tpl b/lemonldap-ng-portal/site/templates/common/mail_new_location_warning.tpl
index ef94ada5d..fd44a1b76 100644
--- a/lemonldap-ng-portal/site/templates/common/mail_new_location_warning.tpl
+++ b/lemonldap-ng-portal/site/templates/common/mail_new_location_warning.tpl
@@ -4,7 +4,7 @@
Hello ,
Your account was signed in to from a new location
-Host
+Location
Date
UA