Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
open-source
MetaGer
Commits
29c3c29c
Commit
29c3c29c
authored
Aug 12, 2020
by
Dominik Hebeler
Browse files
added interface to make dynamic bans
parent
e8b064cc
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app/Console/Commands/LoadSpam.php
0 → 100644
View file @
29c3c29c
<?php
namespace
App\Console\Commands
;
use
Carbon
;
use
Illuminate\Console\Command
;
use
Illuminate\Support\Facades\Redis
;
class
LoadSpam
extends
Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected
$signature
=
'spam:load'
;
/**
* The console command description.
*
* @var string
*/
protected
$description
=
'Loads a list of current Spams into redis'
;
/**
* Create a new command instance.
*
* @return void
*/
public
function
__construct
()
{
parent
::
__construct
();
}
/**
* Execute the console command.
*
* @return mixed
*/
public
function
handle
()
{
$filePath
=
\
storage_path
(
'logs/metager/ban.txt'
);
$bans
=
[];
if
(
\
file_exists
(
$filePath
))
{
$bans
=
json_decode
(
file_get_contents
(
$filePath
),
true
);
}
$bansToLoad
=
[];
foreach
(
$bans
as
$ban
)
{
$bannedUntil
=
Carbon
::
createFromFormat
(
"Y-m-d H:i:s"
,
$ban
[
"banned-until"
]);
if
(
$bannedUntil
->
isAfter
(
Carbon
::
now
()))
{
$bansToLoad
[]
=
$ban
[
"regexp"
];
}
}
Redis
::
pipeline
(
function
(
$redis
)
use
(
$bansToLoad
)
{
$redis
->
del
(
"spam"
);
foreach
(
$bansToLoad
as
$ban
)
{
$redis
->
rpush
(
"spam"
,
$ban
);
}
});
}
}
app/Console/Kernel.php
View file @
29c3c29c
...
...
@@ -28,7 +28,7 @@ class Kernel extends ConsoleKernel
$schedule
->
command
(
'requests:gather'
)
->
everyFifteenMinutes
();
$schedule
->
command
(
'requests:useragents'
)
->
everyFiveMinutes
();
$schedule
->
command
(
'logs:gather'
)
->
everyMinute
();
$schedule
->
command
(
'spam:load'
)
->
everyFiveMinutes
();
$schedule
->
call
(
function
()
{
DB
::
table
(
'monthlyrequests'
)
->
truncate
();
DB
::
disconnect
(
'mysql'
);
...
...
app/Http/Controllers/AdminSpamController.php
0 → 100644
View file @
29c3c29c
<?php
namespace
App\Http\Controllers
;
use
Carbon
;
use
Illuminate\Http\Request
;
use
Illuminate\Support\Facades\Redis
;
class
AdminSpamController
extends
Controller
{
public
function
index
()
{
$queries
=
$this
->
getQueries
();
$currentBans
=
$this
->
getBans
();
$loadedBans
=
Redis
::
lrange
(
"spam"
,
0
,
-
1
);
return
view
(
"admin.spam"
)
->
with
(
'title'
,
"Spam Konfiguration - MetaGer"
)
->
with
(
'queries'
,
$queries
)
->
with
(
'bans'
,
$currentBans
)
->
with
(
'loadedBans'
,
$loadedBans
);
}
public
function
ban
(
Request
$request
)
{
$banTime
=
$request
->
input
(
'ban-time'
);
$banRegexp
=
$request
->
input
(
'regexp'
);
$file
=
storage_path
(
'logs/metager/ban.txt'
);
$bans
=
[];
if
(
file_exists
(
$file
))
{
$bans
=
json_decode
(
file_get_contents
(
$file
),
true
);
}
$bans
[]
=
[
"banned-until"
=>
Carbon
::
now
()
->
add
(
$banTime
)
->
format
(
"Y-m-d H:i:s"
),
"regexp"
=>
$banRegexp
];
\
file_put_contents
(
$file
,
json_encode
(
$bans
));
return
redirect
(
url
(
'admin/spam'
));
}
public
function
jsonQueries
()
{
$queries
=
$this
->
getQueries
();
return
response
()
->
json
(
$queries
);
}
public
function
queryregexp
(
Request
$request
)
{
$data
=
json_decode
(
$request
->
getContent
(),
true
);
$queries
=
$data
[
"queries"
];
$regexps
=
[
$data
[
"regexp"
]];
$bans
=
$this
->
getBans
();
foreach
(
$bans
as
$ban
)
{
$regexps
[]
=
$ban
[
"regexp"
];
}
$resultData
=
[];
foreach
(
$queries
as
$query
)
{
$matches
=
false
;
foreach
(
$regexps
as
$regexp
)
{
try
{
if
(
preg_match
(
$regexp
,
$query
))
{
$matches
=
true
;
}
}
catch
(
\
Exception
$e
)
{
// Exceptions are expected when no valid regexp is given
}
}
$resultData
[]
=
[
"query"
=>
$query
,
"matches"
=>
$matches
,
];
}
return
response
()
->
json
(
$resultData
);
}
private
function
getQueries
()
{
$minuteToFetch
=
Carbon
::
now
()
->
subMinutes
(
2
);
$logFile
=
storage_path
(
"logs/metager/"
.
$minuteToFetch
->
format
(
"Y/m/d"
)
.
".log"
);
$result
=
shell_exec
(
"cat
$logFile
| grep "
.
$minuteToFetch
->
format
(
"H:i:"
));
$result
=
explode
(
PHP_EOL
,
$result
);
$queries
=
array
();
foreach
(
$result
as
$line
)
{
if
(
$query
=
\
preg_match
(
"/.*eingabe=(.*)$/"
,
$line
,
$matches
))
{
$queries
[]
=
$matches
[
1
];
}
}
return
$queries
;
}
public
function
getBans
()
{
$file
=
\
storage_path
(
'logs/metager/ban.txt'
);
$bans
=
[];
if
(
file_exists
(
$file
))
{
$tmpBans
=
json_decode
(
file_get_contents
(
$file
),
true
);
foreach
(
$tmpBans
as
$ban
)
{
#dd($ban["banned-until"]);
$bannedUntil
=
Carbon
::
createFromFormat
(
'Y-m-d H:i:s'
,
$ban
[
"banned-until"
]);
if
(
$bannedUntil
->
isAfter
(
Carbon
::
now
()))
{
$bans
[]
=
$ban
;
}
}
}
file_put_contents
(
$file
,
json_encode
(
$bans
));
return
$bans
;
}
public
function
deleteRegexp
(
Request
$request
)
{
$file
=
\
storage_path
(
'logs/metager/ban.txt'
);
$bans
=
[];
if
(
file_exists
(
$file
))
{
$bans
=
json_decode
(
file_get_contents
(
$file
),
true
);
}
$regexpToDelete
=
$request
->
input
(
'regexp'
);
$newBans
=
[];
foreach
(
$bans
as
$ban
)
{
if
(
$ban
[
"regexp"
]
!==
$regexpToDelete
)
{
$newBans
[]
=
$ban
;
}
}
file_put_contents
(
$file
,
json_encode
(
$newBans
));
return
redirect
(
url
(
'admin/spam'
));
}
}
app/Http/Controllers/HumanVerification.php
View file @
29c3c29c
...
...
@@ -7,6 +7,7 @@ use Carbon;
use
Illuminate\Hashing\BcryptHasher
as
Hasher
;
use
Illuminate\Http\Request
;
use
Illuminate\Support\Facades\Cache
;
use
Illuminate\Support\Facades\Redis
;
use
Input
;
class
HumanVerification
extends
Controller
...
...
@@ -198,20 +199,16 @@ class HumanVerification extends Controller
public
static
function
couldBeSpammer
(
$ip
)
{
$possibleSpammer
=
false
;
# Check for recent Spams
$eingabe
=
\
Request
::
input
(
'eingabe'
);
if
(
\
preg_match
(
"/^susimail\s+-site:[^\s]+\s-site:/si"
,
$eingabe
))
{
return
true
;
}
else
if
(
\
preg_match
(
"/^\s*site:
\"
linkedin\.com[^
\"
]*
\"
\s+/si"
,
$eingabe
))
{
return
true
;
}
else
if
(
\
preg_match
(
"/^\d+.(php|asp)\s+\?.*=.*/si"
,
$eingabe
))
{
return
true
;
$spams
=
Redis
::
lrange
(
"spam"
,
0
,
-
1
);
foreach
(
$spams
as
$spam
)
{
if
(
\
preg_match
(
$spam
,
$eingabe
))
{
return
true
;
}
}
return
$possibleSpammer
;
return
false
;
}
public
function
botOverview
(
Request
$request
)
...
...
resources/views/admin/spam.blade.php
0 → 100644
View file @
29c3c29c
@
extends
(
'layouts.subPages'
)
@
section
(
'title'
,
$title
)
@
section
(
'content'
)
<
style
>
#head {
display
:
flex
;
align
-
items
:
center
;
margin
-
bottom
:
16
px
;
}
#head > button {
margin
-
left
:
16
px
;
}
#head > h1 {
margin
:
0
;
}
#queries {
display
:
flex
;
flex
-
wrap
:
wrap
;
justify
-
content
:
space
-
between
;
}
.
matches
{
background
-
color
:
#c9f4c9;
}
#block-requests {
margin
-
bottom
:
16
px
;
}
#regexp {
margin
-
bottom
:
8
px
;
}
#ban-time {
margin
-
bottom
:
8
px
;
}
</
style
>
<
div
id
=
"block-requests"
>
<
form
method
=
"post"
>
<
input
class
=
"form-control"
type
=
"text"
name
=
"regexp"
id
=
"regexp"
placeholder
=
"Type in regexp to match queries..."
>
<
select
name
=
"ban-time"
id
=
"ban-time"
class
=
"form-control"
>
<
option
value
=
"1 day"
>
Einen
Tag
</
option
>
<
option
value
=
"1 week"
>
Eine
Woche
</
option
>
<
option
value
=
"2 weeks"
>
Zwei
Wochen
</
option
>
<
option
value
=
"1 month"
selected
>
Einen
Monat
</
option
>
</
select
>
<
button
type
=
"submit"
class
=
"btn btn-default btn-sm"
>
Sperren
</
button
>
</
form
>
</
div
>
<
div
id
=
"head"
>
<
h1
>
Letzte
Suchanfragen
</
h1
>
<
button
type
=
"button"
class
=
"btn btn-success btn-sm"
>
Aktualisierung
stoppen
(
60
)
</
button
>
</
div
>
<
input
class
=
"form-control"
type
=
"text"
name
=
""
id
=
"check-against"
placeholder
=
"Match against..."
>
<
div
id
=
"queries"
>
@
foreach
(
$queries
as
$query
)
<
div
class
=
"query card"
>
{{
$query
}}
</
div
>
@
endforeach
</
div
>
<
div
id
=
"bans"
>
<
h1
>
Current
Bans
</
h1
>
<
table
class
=
"table table-striped"
>
<
thead
>
<
tr
>
<
td
>
Regexp
</
td
>
<
td
>
Banned
until
</
td
>
<
td
>
Actions
</
td
>
</
tr
>
</
thead
>
<
tbody
>
@
foreach
(
$bans
as
$ban
)
<
tr
>
<
td
>
{{
$ban
[
"regexp"
]
}}
</
td
>
<
td
>
{{
Carbon
::
createFromFormat
(
"Y-m-d H:i:s"
,
$ban
[
"banned-until"
])
->
format
(
"d.m.Y H:i:s"
)}}
({{
Carbon
::
createFromFormat
(
"Y-m-d H:i:s"
,
$ban
[
"banned-until"
])
->
diffInDays
(
Carbon
::
now
())
}}
Days
)
</
td
>
<
td
>
<
form
action
=
"{{ url("
admin
/
spam
/
deleteRegexp
") }}"
method
=
"post"
>
<
input
type
=
"hidden"
name
=
"regexp"
value
=
"{{
$ban["regexp"]
}}"
>
<
button
type
=
"submit"
>&
#128465;</button>
</
form
>
</
td
>
</
tr
>
@
endforeach
</
tbody
>
</
table
>
</
div
>
<
div
id
=
"loadedbans"
>
<
h1
>
Loaded
Bans
</
h1
>
<
table
class
=
"table table-striped"
>
<
thead
>
<
tr
>
<
td
>
Regexp
</
td
>
</
tr
>
</
thead
>
<
tbody
>
@
foreach
(
$loadedBans
as
$ban
)
<
tr
>
<
td
>
{{
$ban
}}
</
td
>
</
tr
>
@
endforeach
</
tbody
>
</
table
>
</
div
>
<
script
>
var
lastUpdate
=
Date
.
now
();
var
updating
=
true
;
var
buttonText
=
"Aktualisierung stoppen"
;
var
interval
=
setInterval
(
updateQueries
,
1000
);
$
(
"#regexp"
)
.
on
(
"input"
,
checkRegexp
);
$
(
"#check-against"
)
.
on
(
"input"
,
checkRegexp
);
$
(
document
)
.
ready
(
function
(){
checkRegexp
();
});
$
(
"#head > button"
)
.
click
(
function
()
{
if
(
!
updating
)
{
$
(
"#head > button"
)
.
removeClass
(
"btn-danger"
);
$
(
"#head > button"
)
.
addClass
(
"btn-success"
);
buttonText
=
"Aktualisierung stoppen"
;
interval
=
setInterval
(
updateQueries
,
1000
);
}
var
updateAt
=
lastUpdate
+
60000
;
var
updateIn
=
Math
.
round
((
updateAt
-
Date
.
now
())
/
1000
);
$
(
"#head > button"
)
.
html
(
buttonText
+
" ("
+
updateIn
+
")"
);
updating
=
!
updating
;
});
function
updateQueries
()
{
var
updateAt
=
lastUpdate
+
60000
;
var
updateIn
=
Math
.
round
((
updateAt
-
Date
.
now
())
/
1000
);
if
(
!
updating
){
$
(
"#head > button"
)
.
removeClass
(
"btn-success"
);
$
(
"#head > button"
)
.
addClass
(
"btn-danger"
);
buttonText
=
"Aktualisierung starten"
;
clearInterval
(
interval
);
}
$
(
"#head > button"
)
.
html
(
buttonText
+
" ("
+
updateIn
+
")"
);
if
(
updateAt
>
Date
.
now
()){
return
;
}
fetch
(
"{{ url('admin/spam/jsonQueries') }}"
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
$
(
"#queries"
)
.
html
(
""
);
$
(
data
)
.
each
(
function
(
index
,
el
){
$
(
"#queries"
)
.
append
(
"<div class=
\"
query card
\"
>"
+
el
+
"</div>"
);
});
lastUpdate
=
Date
.
now
();
checkRegexp
();
});
}
function
checkRegexp
()
{
var
val
=
$
(
"#regexp"
)
.
val
();
var
queries
=
[];
$
(
"#queries > .query"
)
.
each
(
function
(
index
,
el
){
queries
.
push
(
$
(
el
)
.
html
());
});
queries
.
push
(
$
(
"#check-against"
)
.
val
());
var
url
=
"{{ url('admin/spam/queryregexp') }}"
;
var
options
=
{
method
:
'POST'
,
body
:
JSON
.
stringify
({
"queries"
:
queries
,
"regexp"
:
val
}),
headers
:
{
'Content-Type'
:
'application/json'
}
};
fetch
(
url
,
options
)
.
then
(
response
=>
response
.
json
())
.
then
(
data
=>
{
$
(
"#queries > .query"
)
.
each
(
function
(
index
,
el
){
if
(
data
[
index
][
"matches"
]){
$
(
el
)
.
addClass
(
"matches"
);
}
else
{
$
(
el
)
.
removeClass
(
"matches"
);
}
});
if
(
data
[
data
.
length
-
1
][
"matches"
]){
$
(
"#check-against"
)
.
addClass
(
"matches"
);
}
else
{
$
(
"#check-against"
)
.
removeClass
(
"matches"
);
}
});
}
</
script
>
@
endsection
routes/web.php
View file @
29c3c29c
...
...
@@ -182,6 +182,13 @@ Route::group(
});
Route
::
get
(
'bot'
,
'HumanVerification@botOverview'
);
Route
::
post
(
'bot'
,
'HumanVerification@botOverviewChange'
);
Route
::
group
([
'prefix'
=>
'spam'
],
function
()
{
Route
::
get
(
'/'
,
'AdminSpamController@index'
);
Route
::
post
(
'/'
,
'AdminSpamController@ban'
);
Route
::
get
(
'jsonQueries'
,
'AdminSpamController@jsonQueries'
);
Route
::
post
(
'queryregexp'
,
'AdminSpamController@queryregexp'
);
Route
::
post
(
'deleteRegexp'
,
'AdminSpamController@deleteRegexp'
);
});
});
Route
::
get
(
'settings'
,
function
()
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment