-
Notifications
You must be signed in to change notification settings - Fork 2
/
ignorepollers.patch
122 lines (122 loc) · 3.1 KB
/
ignorepollers.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
--- a/usr/share/perl5/Lemonldap/NG/Portal/Main/Plugins.pm
+++ b/usr/share/perl5/Lemonldap/NG/Portal/Main/Plugins.pm
@@ -38,6 +38,7 @@ our @pList = (
checkHIBP => '::Plugins::CheckHIBP',
checkEntropy => '::Plugins::CheckEntropy',
initializePasswordReset => '::Plugins::InitializePasswordReset',
+ ignorePollers => '::Plugins::IgnorePollers',
adaptativeAuthenticationLevelRules =>
'::Plugins::AdaptativeAuthenticationLevel',
refreshSessions => '::Plugins::Refresh',
--- /dev/null
+++ b/usr/share/perl5/Lemonldap/NG/Portal/Plugins/IgnorePollers.pm
@@ -0,0 +1,109 @@
+package Lemonldap::NG::Portal::Plugins::IgnorePollers;
+
+use strict;
+use Mouse;
+use JSON;
+
+use Lemonldap::NG::Portal::Main::Constants qw(
+ PE_OK
+ PE_SENDRESPONSE
+);
+
+our $VERSION = '2.19.0';
+
+extends 'Lemonldap::NG::Portal::Main::Plugin';
+
+# Entrypoint
+use constant beforeAuth => 'check';
+
+has lastCall => (
+ is => 'rw',
+ default => sub { {} },
+);
+
+has maxSameCall => (
+ is => 'rw',
+ default => 5,
+);
+
+has timeout => (
+ is => 'rw',
+ default => 300,
+);
+
+use constant HeaderToKeep => qw(
+ HTTP_X_FORWARDED_FOR
+ HTTP_USER_AGENT
+ REQUEST_METHOD
+ REQUEST_URI
+ QUERY_STRING
+);
+
+sub init {
+ my ($self) = @_;
+ $self->maxSameCall( $self->conf->{ignorePollersLimit} )
+ if $self->conf->{ignorePollersLimit};
+ $self->timeout( $self->conf->{ignorePollersDelay} )
+ if $self->conf->{ignorePollersDelay};
+ $self->addUnauthRoute( 'resetip.js' => 'resetScript' );
+ return 1;
+}
+
+sub check {
+ my ( $self, $req ) = @_;
+ my $nb = $self->setCall($req);
+ return PE_OK if $nb < $self->maxSameCall;
+ $req->response(
+ $req->wantJSON
+ ? $self->sendJSONresponse( $req, { status => "ok" } )
+ : [
+ 200,
+ [],
+ [
+'<html><body><script src="/resetip.js?reload"></script><a href="/?cancel=1">Go to portal</a></body></html>'
+ ]
+ ]
+ );
+ return PE_SENDRESPONSE;
+}
+
+sub setCall {
+ my ( $self, $req ) = @_;
+ my $ip = $req->address;
+ $self->lastCall->{$ip} //= {};
+ if ( $self->lastCall->{$ip}->{'time'}
+ && $self->lastCall->{$ip}->{'time'} < time - $self->timeout )
+ {
+ $self->lastCall->{$ip} = {};
+ }
+ my $url = $self->_fingerprint($req);
+ if ( $url and $self->lastCall->{$ip}->{url} and $url ne $self->lastCall->{$ip}->{url} ) {
+ $self->lastCall->{$ip}->{url} = $url;
+ $self->lastCall->{$ip}->{nb} = 1;
+ }
+ else {
+ $self->lastCall->{$ip}->{nb}++;
+ }
+
+ $self->lastCall->{$ip}->{'time'} = time;
+ return $self->lastCall->{$ip}->{nb};
+}
+
+sub resetScript {
+ my ( $self, $req ) = @_;
+ $self->setCall($req);
+ return [
+ 200,
+ [ 'Content-Type' => 'applications/javascript' ],
+ ['console.log("reset poller")']
+ ];
+}
+
+sub _fingerprint {
+ my ($self, $req) = @_;
+ my $ret = '';
+ $ret .= ($req->env->{$_} // '') foreach (HeaderToKeep);
+ return $ret;
+}
+
+1;