User Spammer process
Moved from www spam user process Upgraded to python 3.x Change-Id: I38231566b30f293dd0214ee7782be213b9a11eee Signed-off-by: smarcet <smarcet@gmail.com>
This commit is contained in:
parent
8493cee023
commit
163238e6aa
@ -1,5 +1,6 @@
|
|||||||
APP_ENV=local
|
APP_ENV=local
|
||||||
APP_DEBUG=true
|
APP_DEBUG=true
|
||||||
|
DEV_EMAIL_TO=smarcet@gmail.com
|
||||||
APP_KEY=SomeRandomString
|
APP_KEY=SomeRandomString
|
||||||
APP_URL=http://localhost
|
APP_URL=http://localhost
|
||||||
APP_OAUTH_2_0_CLIENT_ID=clientid
|
APP_OAUTH_2_0_CLIENT_ID=clientid
|
||||||
|
4
app/Console/Commands/SpammerProcess/.gitignore
vendored
Normal file
4
app/Console/Commands/SpammerProcess/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
env/
|
||||||
|
.idea/
|
||||||
|
__pycache__/
|
||||||
|
user_classifier.pickle
|
19
app/Console/Commands/SpammerProcess/README.md
Normal file
19
app/Console/Commands/SpammerProcess/README.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
## Dependencies
|
||||||
|
|
||||||
|
````bas
|
||||||
|
$ sudo apt update
|
||||||
|
$ sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools python3-venv
|
||||||
|
libmysqlclient-dev
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
## Virtual Env
|
||||||
|
|
||||||
|
````bash
|
||||||
|
$ python3.6 -m venv env
|
||||||
|
|
||||||
|
$ source env/bin/activate
|
||||||
|
|
||||||
|
$ pip install -r requirements.txt
|
||||||
|
|
||||||
|
````
|
@ -0,0 +1,75 @@
|
|||||||
|
<?php namespace App\Console\Commands\SpammerProcess;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
use Exception;
|
||||||
|
/**
|
||||||
|
* Class RebuildUserSpammerEstimator
|
||||||
|
* @package App\Console\Commands\SpammerProcess
|
||||||
|
*/
|
||||||
|
final class RebuildUserSpammerEstimator extends Command
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = 'user-spam:rebuild';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'user-spam:rebuild';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Rebuild User spam estimator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$command = sprintf(
|
||||||
|
'%s/app/Console/Commands/SpammerProcess/estimator_build.sh "%s" "%s" "%s" "%s" "%s"',
|
||||||
|
base_path(),
|
||||||
|
base_path().'/app/Console/Commands/SpammerProcess',
|
||||||
|
env('DB_HOST','localhost'),
|
||||||
|
env('DB_USERNAME',''),
|
||||||
|
env('DB_PASSWORD',''),
|
||||||
|
env('DB_DATABASE','')
|
||||||
|
);
|
||||||
|
$process = new Process($command);
|
||||||
|
$process->setTimeout(PHP_INT_MAX);
|
||||||
|
$process->setIdleTimeout(PHP_INT_MAX);
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
while ($process->isRunning()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = $process->getOutput();
|
||||||
|
|
||||||
|
if (!$process->isSuccessful()) {
|
||||||
|
throw new Exception("Process Error!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
app/Console/Commands/SpammerProcess/UserSpammerProcessor.php
Normal file
120
app/Console/Commands/SpammerProcess/UserSpammerProcessor.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php namespace App\Console\Commands\SpammerProcess;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use App\libs\Utils\CSVReader;
|
||||||
|
use App\Mail\UserSpammerProcessorResultsEmail;
|
||||||
|
use Auth\Repositories\IUserRepository;
|
||||||
|
use Auth\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\URL;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
use Exception;
|
||||||
|
/**
|
||||||
|
* Class UserSpammerProcessor
|
||||||
|
* @package App\Console\Commands\SpammerProcess
|
||||||
|
*/
|
||||||
|
final class UserSpammerProcessor extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The console command name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $name = 'user-spam:process';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'user-spam:process';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Process User spam estimator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var IUserRepository
|
||||||
|
*/
|
||||||
|
private $user_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MemberSpammerProcessor constructor.
|
||||||
|
* @param IUserRepository $user_repository
|
||||||
|
*/
|
||||||
|
public function __construct(IUserRepository $user_repository)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->user_repository = $user_repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$command = sprintf(
|
||||||
|
'%s/app/Console/Commands/SpammerProcess/estimator_process.sh "%s" "%s" "%s" "%s" "%s"',
|
||||||
|
base_path(),
|
||||||
|
base_path().'/app/Console/Commands/SpammerProcess',
|
||||||
|
env('DB_HOST','localhost'),
|
||||||
|
env('DB_USERNAME',''),
|
||||||
|
env('DB_PASSWORD',''),
|
||||||
|
env('DB_DATABASE','')
|
||||||
|
);
|
||||||
|
$default = Config::get("database.default");
|
||||||
|
$process = new Process($command);
|
||||||
|
$process->setTimeout(PHP_INT_MAX);
|
||||||
|
$process->setIdleTimeout(PHP_INT_MAX);
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
while ($process->isRunning()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
$csv_content = $process->getOutput();
|
||||||
|
|
||||||
|
if (!$process->isSuccessful()) {
|
||||||
|
throw new Exception("Process Error!");
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = CSVReader::load($csv_content);
|
||||||
|
|
||||||
|
// send email with excerpt
|
||||||
|
|
||||||
|
$users = [];
|
||||||
|
|
||||||
|
foreach($rows as $row) {
|
||||||
|
$user_id = intval($row["ID"]);
|
||||||
|
$type = $row["Type"];
|
||||||
|
$user = $this->user_repository->getById($user_id);
|
||||||
|
if(is_null($user) || !$user instanceof User) continue;
|
||||||
|
|
||||||
|
$users[] = [
|
||||||
|
'id' => $user->getId(),
|
||||||
|
'email' => $user->getEmail(),
|
||||||
|
'full_name' => $user->getFullName(),
|
||||||
|
'spam_type' => $type,
|
||||||
|
'edit_link' => URL::route("edit_user", ["user_id" => $user->getId()], true)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($users) > 0){
|
||||||
|
Mail::queue(new UserSpammerProcessorResultsEmail($users));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
app/Console/Commands/SpammerProcess/estimator_build.py
Normal file
36
app/Console/Commands/SpammerProcess/estimator_build.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# !/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from openstack_member_spammer_estimator import EstimatorBuilder
|
||||||
|
import os
|
||||||
|
|
||||||
|
# params
|
||||||
|
db_host = sys.argv[1]
|
||||||
|
db_user = sys.argv[2]
|
||||||
|
db_user_password = sys.argv[3]
|
||||||
|
db_name = sys.argv[4]
|
||||||
|
filename = 'user_classifier.pickle'
|
||||||
|
builder = EstimatorBuilder(filename=filename, db_host=db_host, db_user=db_user, db_user_password=db_user_password,
|
||||||
|
db_name=db_name)
|
||||||
|
script_dir = os.path.dirname(__file__)
|
||||||
|
pickle_file = os.path.join(script_dir, )
|
||||||
|
if os.path.exists(pickle_file):
|
||||||
|
os.remove(pickle_file)
|
||||||
|
|
||||||
|
builder.build()
|
31
app/Console/Commands/SpammerProcess/estimator_build.sh
Executable file
31
app/Console/Commands/SpammerProcess/estimator_build.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright (c) 2020 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
WORK_DIR=$1
|
||||||
|
DB_HOST=$2
|
||||||
|
DB_USER=$3
|
||||||
|
DB_PASSWORD=$4
|
||||||
|
DB_NAME=$5
|
||||||
|
|
||||||
|
export PYTHONPATH="$PYTHONPATH:$WORK_DIR";
|
||||||
|
|
||||||
|
cd $WORK_DIR;
|
||||||
|
|
||||||
|
source env/bin/activate;
|
||||||
|
|
||||||
|
python estimator_build.py $DB_HOST $DB_USER $DB_PASSWORD $DB_NAME;
|
||||||
|
|
||||||
|
deactivate;
|
41
app/Console/Commands/SpammerProcess/estimator_process.py
Normal file
41
app/Console/Commands/SpammerProcess/estimator_process.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from openstack_member_spammer_estimator import EstimatorClassifier
|
||||||
|
import os
|
||||||
|
|
||||||
|
# params
|
||||||
|
db_host = sys.argv[1]
|
||||||
|
db_user = sys.argv[2]
|
||||||
|
db_user_password = sys.argv[3]
|
||||||
|
db_name = sys.argv[4]
|
||||||
|
filename = 'user_classifier.pickle'
|
||||||
|
|
||||||
|
classifier = EstimatorClassifier(db_host=db_host, db_user=db_user, db_user_password=db_user_password, db_name=db_name)
|
||||||
|
script_dir = os.path.dirname(__file__)
|
||||||
|
pickle_file = os.path.join(script_dir, filename)
|
||||||
|
if not os.path.exists(pickle_file):
|
||||||
|
raise Exception('File %s does not exists!' % pickle_file)
|
||||||
|
|
||||||
|
res = classifier.classify(pickle_file)
|
||||||
|
|
||||||
|
# output CSV file
|
||||||
|
print("ID,Type")
|
||||||
|
for row in res:
|
||||||
|
print("%s,%s" % row)
|
31
app/Console/Commands/SpammerProcess/estimator_process.sh
Executable file
31
app/Console/Commands/SpammerProcess/estimator_process.sh
Executable file
@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Copyright (c) 2017 OpenStack Foundation
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
# implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
WORK_DIR=$1
|
||||||
|
DB_HOST=$2
|
||||||
|
DB_USER=$3
|
||||||
|
DB_PASSWORD=$4
|
||||||
|
DB_NAME=$5
|
||||||
|
|
||||||
|
export PYTHONPATH="$PYTHONPATH:$WORK_DIR";
|
||||||
|
|
||||||
|
cd $WORK_DIR;
|
||||||
|
|
||||||
|
source env/bin/activate;
|
||||||
|
|
||||||
|
python estimator_process.py $DB_HOST $DB_USER $DB_PASSWORD $DB_NAME;
|
||||||
|
|
||||||
|
deactivate;
|
26
app/Console/Commands/SpammerProcess/requirements.txt
Normal file
26
app/Console/Commands/SpammerProcess/requirements.txt
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
openstack-member-spammer-estimator==1.0.2
|
||||||
|
pkg-resources==0.0.0
|
||||||
|
attrs==19.3.0
|
||||||
|
configparser==4.0.2
|
||||||
|
HTMLParser==0.0.2
|
||||||
|
importlib-metadata==1.5.0
|
||||||
|
joblib==0.14.1
|
||||||
|
more-itertools==8.2.0
|
||||||
|
mysqlclient==1.4.6
|
||||||
|
nltk==3.4.5
|
||||||
|
numpy==1.18.1
|
||||||
|
packaging==20.3
|
||||||
|
pandas==1.0.1
|
||||||
|
pluggy==0.13.1
|
||||||
|
py==1.8.1
|
||||||
|
pyparsing==2.4.6
|
||||||
|
pytest==5.3.5
|
||||||
|
python-dateutil==2.8.1
|
||||||
|
pytz==2019.3
|
||||||
|
scikit-learn==0.22.2.post1
|
||||||
|
scipy==1.4.1
|
||||||
|
six==1.14.0
|
||||||
|
sklearn==0.0
|
||||||
|
wcwidth==0.1.8
|
||||||
|
zipp==3.1.0
|
||||||
|
|
@ -29,6 +29,8 @@ class Kernel extends ConsoleKernel
|
|||||||
Commands\CleanOAuth2StaleData::class,
|
Commands\CleanOAuth2StaleData::class,
|
||||||
Commands\CleanOpenIdStaleData::class,
|
Commands\CleanOpenIdStaleData::class,
|
||||||
Commands\CreateSuperAdmin::class,
|
Commands\CreateSuperAdmin::class,
|
||||||
|
Commands\SpammerProcess\RebuildUserSpammerEstimator::class,
|
||||||
|
Commands\SpammerProcess\UserSpammerProcessor::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,5 +43,8 @@ class Kernel extends ConsoleKernel
|
|||||||
{
|
{
|
||||||
$schedule->command('idp:oauth2-clean')->dailyAt("02:30")->withoutOverlapping();
|
$schedule->command('idp:oauth2-clean')->dailyAt("02:30")->withoutOverlapping();
|
||||||
$schedule->command('idp:openid-clean')->dailyAt("03:30")->withoutOverlapping();
|
$schedule->command('idp:openid-clean')->dailyAt("03:30")->withoutOverlapping();
|
||||||
|
// user spammer
|
||||||
|
$schedule->command('user-spam:rebuild')->dailyAt("02:30")->withoutOverlapping();
|
||||||
|
$schedule->command('user-spam:process')->dailyAt("03:30")->withoutOverlapping();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
app/Events/UserActivated.php
Normal file
19
app/Events/UserActivated.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php namespace App\Events;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserActivated
|
||||||
|
* @package App\Events
|
||||||
|
*/
|
||||||
|
class UserActivated extends UserEvent {}
|
@ -17,35 +17,4 @@ use Doctrine\ORM\Event\LifecycleEventArgs;
|
|||||||
* Class UserCreated
|
* Class UserCreated
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
final class UserCreated
|
final class UserCreated extends UserEvent {}
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var LifecycleEventArgs
|
|
||||||
*/
|
|
||||||
protected $args;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $user_id, LifecycleEventArgs $args)
|
|
||||||
{
|
|
||||||
$this->user_id = $user_id;
|
|
||||||
$this->args = $args;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
19
app/Events/UserDeactivated.php
Normal file
19
app/Events/UserDeactivated.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php namespace App\Events;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserDeactivated
|
||||||
|
* @package App\Events
|
||||||
|
*/
|
||||||
|
class UserDeactivated extends UserEvent {}
|
@ -11,34 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
/**
|
/**
|
||||||
* Class UserEmailUpdated
|
* Class UserEmailUpdated
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
class UserEmailUpdated
|
class UserEmailUpdated extends UserEvent{}
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $user_id)
|
|
||||||
{
|
|
||||||
$this->user_id = $user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,35 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
/**
|
/**
|
||||||
* Class UserEmailVerified
|
* Class UserEmailVerified
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
final class UserEmailVerified
|
final class UserEmailVerified extends UserEvent {}
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $user_id)
|
|
||||||
{
|
|
||||||
$this->user_id = $user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
44
app/Events/UserEvent.php
Normal file
44
app/Events/UserEvent.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php namespace App\Events;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
/**
|
||||||
|
* Class UserEvent
|
||||||
|
* @package App\Events
|
||||||
|
*/
|
||||||
|
abstract class UserEvent
|
||||||
|
{
|
||||||
|
use SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $user_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UserEvent constructor.
|
||||||
|
* @param int $user_id
|
||||||
|
*/
|
||||||
|
public function __construct(int $user_id)
|
||||||
|
{
|
||||||
|
$this->user_id = $user_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getUserId(): int
|
||||||
|
{
|
||||||
|
return $this->user_id;
|
||||||
|
}
|
||||||
|
}
|
@ -11,35 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UserLocked
|
* Class UserLocked
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
final class UserLocked
|
final class UserLocked extends UserEvent{}
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $user_id)
|
|
||||||
{
|
|
||||||
$this->user_id = $user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,34 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
/**
|
/**
|
||||||
* Class UserPasswordResetRequestCreated
|
* Class UserPasswordResetRequestCreated
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
final class UserPasswordResetRequestCreated
|
final class UserPasswordResetRequestCreated extends UserEvent{}
|
||||||
{
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $id)
|
|
||||||
{
|
|
||||||
$this->id = $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getId(): int
|
|
||||||
{
|
|
||||||
return $this->id;
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,35 +11,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
/**
|
/**
|
||||||
* Class UserPasswordResetSuccessful
|
* Class UserPasswordResetSuccessful
|
||||||
* @package App\Events
|
* @package App\Events
|
||||||
*/
|
*/
|
||||||
final class UserPasswordResetSuccessful
|
final class UserPasswordResetSuccessful extends UserEvent{}
|
||||||
{
|
|
||||||
|
|
||||||
use SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $user_id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UserEmailVerified constructor.
|
|
||||||
* @param int $user_id
|
|
||||||
*/
|
|
||||||
public function __construct(int $user_id)
|
|
||||||
{
|
|
||||||
$this->user_id = $user_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getUserId(): int
|
|
||||||
{
|
|
||||||
return $this->user_id;
|
|
||||||
}
|
|
||||||
}
|
|
22
app/Events/UserSpamStateUpdated.php
Normal file
22
app/Events/UserSpamStateUpdated.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php namespace App\Events;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class UserSpamStateUpdated
|
||||||
|
* @package App\Events
|
||||||
|
*/
|
||||||
|
class UserSpamStateUpdated extends UserEvent
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -141,7 +141,7 @@ Route::group(['namespace' => 'App\Http\Controllers', 'middleware' => 'web' ], fu
|
|||||||
Route::group(array('prefix' => 'users'), function () {
|
Route::group(array('prefix' => 'users'), function () {
|
||||||
Route::get('', 'AdminController@listUsers');
|
Route::get('', 'AdminController@listUsers');
|
||||||
Route::group(array('prefix' => '{user_id}'), function () {
|
Route::group(array('prefix' => '{user_id}'), function () {
|
||||||
Route::get('', 'AdminController@editUser');
|
Route::get('', 'AdminController@editUser')->name("edit_user");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
52
app/Mail/UserSpammerProcessorResultsEmail.php
Normal file
52
app/Mail/UserSpammerProcessorResultsEmail.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php namespace App\Mail;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
/**
|
||||||
|
* Class UserSpammerProcessorResultsEmail
|
||||||
|
* @package App\Mail
|
||||||
|
*/
|
||||||
|
class UserSpammerProcessorResultsEmail extends Mailable
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $users;
|
||||||
|
|
||||||
|
public function __construct(array $users)
|
||||||
|
{
|
||||||
|
$this->users = $users;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
|
||||||
|
$subject = sprintf("[%s] User Spammer Process Result", Config::get('app.app_name'));
|
||||||
|
|
||||||
|
return $this->from(Config::get("mail.from"))
|
||||||
|
->to(Config::get("mail.from"))
|
||||||
|
->subject($subject)
|
||||||
|
->view('emails.user_spammer_process_result');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -31,6 +31,7 @@ final class PublicUserSerializer extends BaseUserSerializer {
|
|||||||
final class PrivateUserSerializer extends BaseUserSerializer {
|
final class PrivateUserSerializer extends BaseUserSerializer {
|
||||||
protected static $array_mappings = [
|
protected static $array_mappings = [
|
||||||
'Email' => 'email:json_string',
|
'Email' => 'email:json_string',
|
||||||
|
'SpamType' => 'spam_type:json_string',
|
||||||
'Identifier' => 'identifier:json_string',
|
'Identifier' => 'identifier:json_string',
|
||||||
'LastLoginDate' => 'last_login_date:datetime_epoch',
|
'LastLoginDate' => 'last_login_date:datetime_epoch',
|
||||||
'Active' => 'active:json_boolean',
|
'Active' => 'active:json_boolean',
|
||||||
|
@ -12,10 +12,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
use App\Events\OAuth2ClientLocked;
|
use App\Events\OAuth2ClientLocked;
|
||||||
|
use App\Events\UserActivated;
|
||||||
|
use App\Events\UserDeactivated;
|
||||||
use App\Events\UserEmailUpdated;
|
use App\Events\UserEmailUpdated;
|
||||||
use App\Events\UserLocked;
|
use App\Events\UserLocked;
|
||||||
use App\Events\UserPasswordResetRequestCreated;
|
use App\Events\UserPasswordResetRequestCreated;
|
||||||
use App\Events\UserPasswordResetSuccessful;
|
use App\Events\UserPasswordResetSuccessful;
|
||||||
|
use App\Events\UserSpamStateUpdated;
|
||||||
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
||||||
use App\Mail\UserLockedEmail;
|
use App\Mail\UserLockedEmail;
|
||||||
use App\Mail\UserPasswordResetMail;
|
use App\Mail\UserPasswordResetMail;
|
||||||
@ -81,6 +84,16 @@ final class EventServiceProvider extends ServiceProvider
|
|||||||
$user_service->sendVerificationEmail($user);
|
$user_service->sendVerificationEmail($user);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Event::listen(UserSpamStateUpdated::class, function($event)
|
||||||
|
{
|
||||||
|
$repository = App::make(IUserRepository::class);
|
||||||
|
$user = $repository->getById($event->getUserId());
|
||||||
|
if(is_null($user)) return;
|
||||||
|
if(! $user instanceof User) return;
|
||||||
|
$user_service = App::make(IUserService::class);
|
||||||
|
$user_service->recalculateUserSpamType($user);
|
||||||
|
});
|
||||||
|
|
||||||
Event::listen(UserEmailUpdated::class, function($event)
|
Event::listen(UserEmailUpdated::class, function($event)
|
||||||
{
|
{
|
||||||
$repository = App::make(IUserRepository::class);
|
$repository = App::make(IUserRepository::class);
|
||||||
@ -93,7 +106,7 @@ final class EventServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
Event::listen(UserPasswordResetRequestCreated::class, function($event){
|
Event::listen(UserPasswordResetRequestCreated::class, function($event){
|
||||||
$repository = App::make(IUserPasswordResetRequestRepository::class);
|
$repository = App::make(IUserPasswordResetRequestRepository::class);
|
||||||
$request = $repository->find($event->getId());
|
$request = $repository->find($event->getUserId());
|
||||||
if(is_null($request)) return;
|
if(is_null($request)) return;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -123,5 +136,14 @@ final class EventServiceProvider extends ServiceProvider
|
|||||||
if(!$client instanceof Client) return;
|
if(!$client instanceof Client) return;
|
||||||
Mail::queue(new \App\Mail\OAuth2ClientLocked($client));
|
Mail::queue(new \App\Mail\OAuth2ClientLocked($client));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Event::listen(\Illuminate\Mail\Events\MessageSending::class, function($event){
|
||||||
|
$devEmail = env('DEV_EMAIL_TO', null);
|
||||||
|
if(in_array(App::environment(), ['local','dev','testing']) && !empty($devEmail)){
|
||||||
|
$event->message->setTo(explode(",", $devEmail));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
app/Repositories/DoctrineSpamEstimatorFeedRepository.php
Normal file
46
app/Repositories/DoctrineSpamEstimatorFeedRepository.php
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php namespace App\Repositories;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use App\libs\Auth\Models\SpamEstimatorFeed;
|
||||||
|
use App\libs\Auth\Repositories\ISpamEstimatorFeedRepository;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
/**
|
||||||
|
* Class DoctrineSpamEstimatorFeedRepository
|
||||||
|
* @package App\Repositories
|
||||||
|
*/
|
||||||
|
final class DoctrineSpamEstimatorFeedRepository
|
||||||
|
extends ModelDoctrineRepository implements ISpamEstimatorFeedRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
protected function getBaseEntity()
|
||||||
|
{
|
||||||
|
return SpamEstimatorFeed::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteByEmail(string $email)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||||
|
$qb->delete(SpamEstimatorFeed::class, 'e');
|
||||||
|
$qb->where('e.email = :email');
|
||||||
|
$qb->setParameter('email', trim($email));
|
||||||
|
$qb->getQuery()->execute();
|
||||||
|
}
|
||||||
|
catch(\Exception $ex){
|
||||||
|
Log::error($ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
use App\libs\Auth\Models\SpamEstimatorFeed;
|
||||||
use App\libs\Auth\Models\UserRegistrationRequest;
|
use App\libs\Auth\Models\UserRegistrationRequest;
|
||||||
use App\libs\Auth\Repositories\IBannedIPRepository;
|
use App\libs\Auth\Repositories\IBannedIPRepository;
|
||||||
use App\libs\Auth\Repositories\IGroupRepository;
|
use App\libs\Auth\Repositories\IGroupRepository;
|
||||||
|
use App\libs\Auth\Repositories\ISpamEstimatorFeedRepository;
|
||||||
use App\libs\Auth\Repositories\IUserExceptionTrailRepository;
|
use App\libs\Auth\Repositories\IUserExceptionTrailRepository;
|
||||||
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
||||||
use App\libs\Auth\Repositories\IUserRegistrationRequestRepository;
|
use App\libs\Auth\Repositories\IUserRegistrationRequestRepository;
|
||||||
@ -216,6 +217,13 @@ final class RepositoriesProvider extends ServiceProvider
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
App::singleton(
|
||||||
|
ISpamEstimatorFeedRepository::class,
|
||||||
|
function(){
|
||||||
|
return EntityManager::getRepository(SpamEstimatorFeed::class);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provides()
|
public function provides()
|
||||||
@ -237,6 +245,7 @@ final class RepositoriesProvider extends ServiceProvider
|
|||||||
IResourceServerRepository::class,
|
IResourceServerRepository::class,
|
||||||
IWhiteListedIPRepository::class,
|
IWhiteListedIPRepository::class,
|
||||||
IUserRegistrationRequestRepository::class,
|
IUserRegistrationRequestRepository::class,
|
||||||
|
ISpamEstimatorFeedRepository::class,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -92,4 +92,10 @@ interface IUserService
|
|||||||
* @throws EntityNotFoundException
|
* @throws EntityNotFoundException
|
||||||
*/
|
*/
|
||||||
public function createRegistrationRequest(string $client_id, array $payload):UserRegistrationRequest;
|
public function createRegistrationRequest(string $client_id, array $payload):UserRegistrationRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function recalculateUserSpamType(User $user):void;
|
||||||
}
|
}
|
@ -14,8 +14,10 @@
|
|||||||
use App\Events\UserPasswordResetSuccessful;
|
use App\Events\UserPasswordResetSuccessful;
|
||||||
use App\libs\Auth\Factories\UserFactory;
|
use App\libs\Auth\Factories\UserFactory;
|
||||||
use App\libs\Auth\Factories\UserRegistrationRequestFactory;
|
use App\libs\Auth\Factories\UserRegistrationRequestFactory;
|
||||||
|
use App\libs\Auth\Models\SpamEstimatorFeed;
|
||||||
use App\libs\Auth\Models\UserRegistrationRequest;
|
use App\libs\Auth\Models\UserRegistrationRequest;
|
||||||
use App\libs\Auth\Repositories\IGroupRepository;
|
use App\libs\Auth\Repositories\IGroupRepository;
|
||||||
|
use App\libs\Auth\Repositories\ISpamEstimatorFeedRepository;
|
||||||
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
use App\libs\Auth\Repositories\IUserPasswordResetRequestRepository;
|
||||||
use App\libs\Auth\Repositories\IUserRegistrationRequestRepository;
|
use App\libs\Auth\Repositories\IUserRegistrationRequestRepository;
|
||||||
use App\Mail\UserEmailVerificationRequest;
|
use App\Mail\UserEmailVerificationRequest;
|
||||||
@ -69,6 +71,11 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
*/
|
*/
|
||||||
private $client_repository;
|
private $client_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ISpamEstimatorFeedRepository
|
||||||
|
*/
|
||||||
|
private $spam_estimator_feed_repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserService constructor.
|
* UserService constructor.
|
||||||
* @param IUserRepository $user_repository
|
* @param IUserRepository $user_repository
|
||||||
@ -76,6 +83,7 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
* @param IUserPasswordResetRequestRepository $request_reset_password_repository
|
* @param IUserPasswordResetRequestRepository $request_reset_password_repository
|
||||||
* @param IUserRegistrationRequestRepository $user_registration_request_repository
|
* @param IUserRegistrationRequestRepository $user_registration_request_repository
|
||||||
* @param IClientRepository $client_repository
|
* @param IClientRepository $client_repository
|
||||||
|
* @param ISpamEstimatorFeedRepository $spam_estimator_feed_repository
|
||||||
* @param IUserNameGeneratorService $name_generator_service
|
* @param IUserNameGeneratorService $name_generator_service
|
||||||
* @param ITransactionService $tx_service
|
* @param ITransactionService $tx_service
|
||||||
*/
|
*/
|
||||||
@ -86,6 +94,7 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
IUserPasswordResetRequestRepository $request_reset_password_repository,
|
IUserPasswordResetRequestRepository $request_reset_password_repository,
|
||||||
IUserRegistrationRequestRepository $user_registration_request_repository,
|
IUserRegistrationRequestRepository $user_registration_request_repository,
|
||||||
IClientRepository $client_repository,
|
IClientRepository $client_repository,
|
||||||
|
ISpamEstimatorFeedRepository $spam_estimator_feed_repository,
|
||||||
IUserNameGeneratorService $name_generator_service,
|
IUserNameGeneratorService $name_generator_service,
|
||||||
ITransactionService $tx_service
|
ITransactionService $tx_service
|
||||||
)
|
)
|
||||||
@ -96,6 +105,7 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
$this->name_generator_service = $name_generator_service;
|
$this->name_generator_service = $name_generator_service;
|
||||||
$this->request_reset_password_repository = $request_reset_password_repository;
|
$this->request_reset_password_repository = $request_reset_password_repository;
|
||||||
$this->user_registration_request_repository = $user_registration_request_repository;
|
$this->user_registration_request_repository = $user_registration_request_repository;
|
||||||
|
$this->spam_estimator_feed_repository = $spam_estimator_feed_repository;
|
||||||
$this->client_repository = $client_repository;
|
$this->client_repository = $client_repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,4 +379,24 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
return $request;
|
return $request;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function recalculateUserSpamType(User $user): void
|
||||||
|
{
|
||||||
|
$this->tx_service->transaction(function() use($user) {
|
||||||
|
$this->spam_estimator_feed_repository->deleteByEmail($user->getEmail());
|
||||||
|
switch($user->getSpamType()){
|
||||||
|
case User::SpamTypeSpam:
|
||||||
|
$feed = SpamEstimatorFeed::buildFromUser($user, User::SpamTypeSpam);
|
||||||
|
$this->spam_estimator_feed_repository->add($feed);
|
||||||
|
break;
|
||||||
|
case User::SpamTypeHam:
|
||||||
|
$feed = SpamEstimatorFeed::buildFromUser($user, User::SpamTypeHam);
|
||||||
|
$this->spam_estimator_feed_repository->add($feed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
@ -274,7 +274,6 @@ final class UserService extends AbstractService implements IUserService
|
|||||||
$user = $this->repository->getById($id);
|
$user = $this->repository->getById($id);
|
||||||
if(is_null($user) || !$user instanceof User)
|
if(is_null($user) || !$user instanceof User)
|
||||||
throw new EntityNotFoundException("user not found");
|
throw new EntityNotFoundException("user not found");
|
||||||
|
|
||||||
$this->repository->delete($user);
|
$this->repository->delete($user);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ class CustomAuthProvider implements UserProvider
|
|||||||
//update user fields
|
//update user fields
|
||||||
$user->setLastLoginDate(new \DateTime('now', new \DateTimeZone('UTC')));
|
$user->setLastLoginDate(new \DateTime('now', new \DateTimeZone('UTC')));
|
||||||
$user->setLoginFailedAttempt(0);
|
$user->setLoginFailedAttempt(0);
|
||||||
$user->setActive(true);
|
$user->activate();
|
||||||
$user->clearResetPasswordRequests();
|
$user->clearResetPasswordRequests();
|
||||||
|
|
||||||
$auth_extensions = $this->auth_extension_service->getExtensions();
|
$auth_extensions = $this->auth_extension_service->getExtensions();
|
||||||
|
@ -134,8 +134,13 @@ final class UserFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($payload['active']))
|
if(isset($payload['active'])) {
|
||||||
$user->setActive(boolval($payload['active']));
|
$active = boolval($payload['active']);
|
||||||
|
if($active)
|
||||||
|
$user->activate();
|
||||||
|
else
|
||||||
|
$user->deActivate();
|
||||||
|
}
|
||||||
|
|
||||||
if(isset($payload['public_profile_show_photo']))
|
if(isset($payload['public_profile_show_photo']))
|
||||||
$user->setPublicProfileShowPhoto(boolval($payload['public_profile_show_photo']));
|
$user->setPublicProfileShowPhoto(boolval($payload['public_profile_show_photo']));
|
||||||
|
149
app/libs/Auth/Models/SpamEstimatorFeed.php
Normal file
149
app/libs/Auth/Models/SpamEstimatorFeed.php
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<?php namespace App\libs\Auth\Models;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use App\Models\Utils\BaseEntity;
|
||||||
|
use Auth\User;
|
||||||
|
use Doctrine\ORM\Mapping AS ORM;
|
||||||
|
/**
|
||||||
|
* @ORM\Entity(repositoryClass="App\Repositories\DoctrineSpamEstimatorFeedRepository")
|
||||||
|
* @ORM\Table(name="users_spam_estimator_feed")
|
||||||
|
* Class SpamEstimatorFeed
|
||||||
|
* @package App\libs\Auth\Models
|
||||||
|
*/
|
||||||
|
class SpamEstimatorFeed extends BaseEntity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="first_name", type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $first_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="last_name", type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $last_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="email", type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="bio", nullable=true, type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $bio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="spam_type", nullable=false, type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $spam_type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFirstName(): ?string
|
||||||
|
{
|
||||||
|
return $this->first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
*/
|
||||||
|
public function setFirstName(string $first_name): void
|
||||||
|
{
|
||||||
|
$this->first_name = $first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLastName(): ?string
|
||||||
|
{
|
||||||
|
return $this->last_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $last_name
|
||||||
|
*/
|
||||||
|
public function setLastName(string $last_name): void
|
||||||
|
{
|
||||||
|
$this->last_name = $last_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEmail(): ?string
|
||||||
|
{
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
*/
|
||||||
|
public function setEmail(string $email): void
|
||||||
|
{
|
||||||
|
$this->email = $email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBio(): ?string
|
||||||
|
{
|
||||||
|
return $this->bio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $bio
|
||||||
|
*/
|
||||||
|
public function setBio(string $bio): void
|
||||||
|
{
|
||||||
|
$this->bio = $bio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSpamType(): ?string
|
||||||
|
{
|
||||||
|
return $this->spam_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $spam_type
|
||||||
|
*/
|
||||||
|
public function setSpamType(string $spam_type): void
|
||||||
|
{
|
||||||
|
$this->spam_type = $spam_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param User $user
|
||||||
|
* @param string $spam_type
|
||||||
|
* @return SpamEstimatorFeed
|
||||||
|
*/
|
||||||
|
public static function buildFromUser(User $user, string $spam_type){
|
||||||
|
$feed = new SpamEstimatorFeed;
|
||||||
|
$feed->spam_type = $spam_type;
|
||||||
|
$feed->email = $user->getEmail();
|
||||||
|
$feed->first_name = $user->getFirstName();
|
||||||
|
$feed->last_name = $user->getLastName();
|
||||||
|
$feed->bio = $user->getBio();
|
||||||
|
return $feed;
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
use App\Events\UserCreated;
|
use App\Events\UserCreated;
|
||||||
use App\Events\UserLocked;
|
use App\Events\UserLocked;
|
||||||
|
use App\Events\UserSpamStateUpdated;
|
||||||
use App\libs\Auth\Models\IGroupSlugs;
|
use App\libs\Auth\Models\IGroupSlugs;
|
||||||
|
use Doctrine\ORM\Event\PreUpdateEventArgs;
|
||||||
use Illuminate\Support\Facades\Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
use App\Events\UserEmailVerified;
|
use App\Events\UserEmailVerified;
|
||||||
use Doctrine\Common\Collections\Criteria;
|
use Doctrine\Common\Collections\Criteria;
|
||||||
@ -48,6 +49,16 @@ class User extends BaseEntity
|
|||||||
use Authenticatable;
|
use Authenticatable;
|
||||||
use CanResetPasswordTrait;
|
use CanResetPasswordTrait;
|
||||||
|
|
||||||
|
const SpamTypeNone = 'None';
|
||||||
|
const SpamTypeSpam = 'Spam';
|
||||||
|
const SpamTypeHam = 'Ham';
|
||||||
|
|
||||||
|
const ValidSpamTypes = [
|
||||||
|
self::SpamTypeNone,
|
||||||
|
self::SpamTypeSpam,
|
||||||
|
self::SpamTypeHam
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(name="identifier", type="string")
|
* @ORM\Column(name="identifier", type="string")
|
||||||
* @var string
|
* @var string
|
||||||
@ -263,6 +274,12 @@ class User extends BaseEntity
|
|||||||
*/
|
*/
|
||||||
private $birthday;
|
private $birthday;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="spam_type", nullable=false, type="string")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $spam_type;
|
||||||
|
|
||||||
// relations
|
// relations
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -803,21 +820,12 @@ class User extends BaseEntity
|
|||||||
return $this->active;
|
return $this->active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $active
|
|
||||||
*/
|
|
||||||
public function setActive(bool $active): void
|
|
||||||
{
|
|
||||||
$this->active = $active;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function lock()
|
public function lock()
|
||||||
{
|
{
|
||||||
$this->active = false;
|
$this->deActivate();
|
||||||
Event::fire(new UserLocked($this->getId()));
|
Event::fire(new UserLocked($this->getId()));
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -827,7 +835,7 @@ class User extends BaseEntity
|
|||||||
*/
|
*/
|
||||||
public function unlock()
|
public function unlock()
|
||||||
{
|
{
|
||||||
$this->active = true;
|
$this->activate();
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,8 +1393,31 @@ SQL;
|
|||||||
$this->bio = $bio;
|
$this->bio = $bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function activate():void {
|
||||||
|
if(!$this->active) {
|
||||||
|
$this->active = true;
|
||||||
|
$this->spam_type = self::SpamTypeHam;
|
||||||
|
Event::fire(new UserSpamStateUpdated(
|
||||||
|
$this->getId()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deActivate():void {
|
||||||
|
if( $this->active) {
|
||||||
|
$this->active = false;
|
||||||
|
$this->spam_type = self::SpamTypeSpam;
|
||||||
|
Event::fire(new UserSpamStateUpdated(
|
||||||
|
$this->getId()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return $this
|
* @return $this
|
||||||
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function verifyEmail()
|
public function verifyEmail()
|
||||||
{
|
{
|
||||||
@ -1449,11 +1480,36 @@ SQL;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\PostPersist
|
* @ORM\postPersist
|
||||||
*/
|
*/
|
||||||
public function inserted($args)
|
public function postPersist($args)
|
||||||
{
|
{
|
||||||
Event::fire(new UserCreated($this->getId(), $args));
|
Event::fire(new UserCreated($this->getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\preRemove
|
||||||
|
*/
|
||||||
|
public function preRemove($args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\preUpdate
|
||||||
|
* @param PreUpdateEventArgs $args
|
||||||
|
*/
|
||||||
|
public function preUpdate(PreUpdateEventArgs $args)
|
||||||
|
{
|
||||||
|
if($this->spam_type != self::SpamTypeNone &&
|
||||||
|
!$args->hasChangedField("active") &&
|
||||||
|
($args->hasChangedField("bio") || $args->hasChangedField("email"))) {
|
||||||
|
// enqueue user for spam re checker
|
||||||
|
$this->resetSpamTypeClassification();
|
||||||
|
Event::fire(new UserSpamStateUpdated($this->getId()));
|
||||||
|
}
|
||||||
|
if($args->hasChangedField("email")) {
|
||||||
|
// record email change
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1554,4 +1610,43 @@ SQL;
|
|||||||
$this->reset_password_requests->clear();
|
$this->reset_password_requests->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getSpamType(): ?string
|
||||||
|
{
|
||||||
|
return $this->spam_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $spam_type
|
||||||
|
* @throws ValidationException
|
||||||
|
*/
|
||||||
|
public function setSpamType(string $spam_type): void
|
||||||
|
{
|
||||||
|
if(!in_array($spam_type, self::ValidSpamTypes))
|
||||||
|
throw new ValidationException(sprintf("Not valid %s spam type value.", $spam_type));
|
||||||
|
$this->spam_type = $spam_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function resetSpamTypeClassification():void{
|
||||||
|
$this->spam_type = self::SpamTypeNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isHam():bool{
|
||||||
|
return $this->spam_type == self::SpamTypeHam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isSpam():bool{
|
||||||
|
return $this->spam_type == self::SpamTypeSpam;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
22
app/libs/Auth/Repositories/ISpamEstimatorFeedRepository.php
Normal file
22
app/libs/Auth/Repositories/ISpamEstimatorFeedRepository.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php namespace App\libs\Auth\Repositories;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use models\utils\IBaseRepository;
|
||||||
|
/**
|
||||||
|
* Interface ISpamEstimatorFeedRepository
|
||||||
|
* @package App\libs\Auth\Repositories
|
||||||
|
*/
|
||||||
|
interface ISpamEstimatorFeedRepository extends IBaseRepository
|
||||||
|
{
|
||||||
|
public function deleteByEmail(string $email);
|
||||||
|
}
|
76
app/libs/Utils/CSVReader.php
Normal file
76
app/libs/Utils/CSVReader.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php namespace App\libs\Utils;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use InvalidArgumentException;
|
||||||
|
/**
|
||||||
|
* Class CSVReader
|
||||||
|
*/
|
||||||
|
final class CSVReader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var resource
|
||||||
|
*/
|
||||||
|
private $file_handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
|
public function __construct($filename = null){
|
||||||
|
if(is_null($filename)) return;
|
||||||
|
if(!file_exists($filename))
|
||||||
|
throw new InvalidArgumentException;
|
||||||
|
$this->file_handle = fopen($filename, "r");
|
||||||
|
if(!$this->file_handle)
|
||||||
|
throw new InvalidArgumentException;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $content
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function load($content)
|
||||||
|
{
|
||||||
|
$data = str_getcsv($content,"\n" );
|
||||||
|
$lines = array();
|
||||||
|
$header = array();
|
||||||
|
$idx = 0;
|
||||||
|
foreach($data as $row)
|
||||||
|
{
|
||||||
|
$row = str_getcsv($row, ",");
|
||||||
|
++$idx;
|
||||||
|
if($idx === 1) { $header = $row; continue;}
|
||||||
|
$line = array();
|
||||||
|
for($i=0; $i < count($header); $i++){
|
||||||
|
$line[$header[$i]] = trim($row[$i]);
|
||||||
|
}
|
||||||
|
$lines[] = $line;
|
||||||
|
|
||||||
|
} //parse the items in rows
|
||||||
|
return $lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
function __destruct() {
|
||||||
|
if($this->file_handle) fclose($this->file_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array|bool
|
||||||
|
*/
|
||||||
|
function getLine(){
|
||||||
|
if (!feof($this->file_handle) ) {
|
||||||
|
return fgetcsv($this->file_handle, 1024);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
91
database/migrations/Version20200306133045.php
Normal file
91
database/migrations/Version20200306133045.php
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?php namespace Database\Migrations;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||||
|
use LaravelDoctrine\Migrations\Schema\Table;
|
||||||
|
use LaravelDoctrine\Migrations\Schema\Builder;
|
||||||
|
/**
|
||||||
|
* Class Version20200306133045
|
||||||
|
* @package Database\Migrations
|
||||||
|
*/
|
||||||
|
class Version20200306133045 extends AbstractMigration
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
$builder = new Builder($schema);
|
||||||
|
if($schema->hasTable("users") && !$builder->hasColumn("users","spam_type") ) {
|
||||||
|
$builder->table('users', function (Table $table) {
|
||||||
|
$table->string('spam_type')->setNotnull(true)->setDefault('None');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$schema->hasTable("users_spam_estimator_feed")) {
|
||||||
|
$builder->create('users_spam_estimator_feed', function (Table $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string("first_name", 100)->setNotnull(false);
|
||||||
|
$table->string("last_name", 100)->setNotnull(false);
|
||||||
|
$table->string("email", 255)->setNotnull(false);
|
||||||
|
$table->unique("email");
|
||||||
|
$table->text("bio")->setNotnull(false);
|
||||||
|
$table->string('spam_type')->setNotnull(true)->setDefault('None');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$schema->hasTable("users_deleted")) {
|
||||||
|
$builder->create('users_deleted', function (Table $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string("first_name", 100)->setNotnull(false);
|
||||||
|
$table->string("last_name", 100)->setNotnull(false);
|
||||||
|
$table->string("email", 255)->setNotnull(false);
|
||||||
|
$table->unique("email");
|
||||||
|
$table->bigInteger("performer_id")->setUnsigned(true);
|
||||||
|
$table->index("performer_id", "performer_id");
|
||||||
|
$table->foreign("users", "performer_id", "id", ["onDelete" => "CASCADE"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$schema->hasTable("users_email_changed")) {
|
||||||
|
$builder->create('users_email_changed', function (Table $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->timestamps();
|
||||||
|
$table->string("former_email", 255)->setNotnull(false);
|
||||||
|
$table->string("new_email", 255)->setNotnull(false);
|
||||||
|
$table->bigInteger("user_id")->setUnsigned(true);
|
||||||
|
$table->index("user_id", "user_id");
|
||||||
|
$table->foreign("users", "user_id", "id", ["onDelete" => "CASCADE"]);
|
||||||
|
$table->bigInteger("performer_id")->setUnsigned(true);
|
||||||
|
$table->index("performer_id", "performer_id");
|
||||||
|
$table->foreign("users", "performer_id", "id", ["onDelete" => "CASCADE"]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function down(Schema $schema)
|
||||||
|
{
|
||||||
|
$builder = new Builder($schema);
|
||||||
|
$builder->dropIfExists("users_email_changed");
|
||||||
|
$builder->dropIfExists("users_deleted");
|
||||||
|
$builder->dropIfExists("users_spam_estimator_feed");
|
||||||
|
}
|
||||||
|
}
|
59
database/migrations/Version20200306135446.php
Normal file
59
database/migrations/Version20200306135446.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php namespace Database\Migrations;
|
||||||
|
/**
|
||||||
|
* Copyright 2020 OpenStack Foundation
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
**/
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema as Schema;
|
||||||
|
/**
|
||||||
|
* Class Version20200306135446
|
||||||
|
* @package Database\Migrations
|
||||||
|
*/
|
||||||
|
class Version20200306135446 extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
$sql = <<<SQL
|
||||||
|
ALTER TABLE users MODIFY spam_type
|
||||||
|
enum(
|
||||||
|
'None', 'Ham', 'Spam'
|
||||||
|
) default 'None' null;
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
$this->addSql($sql);
|
||||||
|
|
||||||
|
$sql = <<<SQL
|
||||||
|
ALTER TABLE users_spam_estimator_feed MODIFY spam_type
|
||||||
|
enum(
|
||||||
|
'None', 'Ham', 'Spam'
|
||||||
|
) default 'None' null;
|
||||||
|
SQL;
|
||||||
|
$this->addSql($sql);
|
||||||
|
|
||||||
|
// reset spam state to Ham
|
||||||
|
$sql = <<<SQL
|
||||||
|
UPDATE users set spam_type = 'Ham';
|
||||||
|
SQL;
|
||||||
|
|
||||||
|
$this->addSql($sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function down(Schema $schema)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ function UsersCrud(urls, perPage) {
|
|||||||
'<td class="user-email"></td>' +
|
'<td class="user-email"></td>' +
|
||||||
'<td class="user-active"><input type="checkbox" class="user-active-checkbox"></td>' +
|
'<td class="user-active"><input type="checkbox" class="user-active-checkbox"></td>' +
|
||||||
'<td class="user-last-login"></td>' +
|
'<td class="user-last-login"></td>' +
|
||||||
|
'<td class="user-spam-type"></td>' +
|
||||||
'<td class="user-actions"> ' + actions + '</td>' +
|
'<td class="user-actions"> ' + actions + '</td>' +
|
||||||
'</tr></tbody>');
|
'</tr></tbody>');
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ function UsersCrud(urls, perPage) {
|
|||||||
'td.user-fname': 'user.first_name',
|
'td.user-fname': 'user.first_name',
|
||||||
'td.user-lname': 'user.last_name',
|
'td.user-lname': 'user.last_name',
|
||||||
'td.user-email': 'user.email',
|
'td.user-email': 'user.email',
|
||||||
|
'td.user-spam-type': 'user.spam_type',
|
||||||
'td.user-last-login': function (arg) {
|
'td.user-last-login': function (arg) {
|
||||||
if (arg.item.last_login_date == null) return 'N/A';
|
if (arg.item.last_login_date == null) return 'N/A';
|
||||||
return moment.unix(arg.item.last_login_date).format();
|
return moment.unix(arg.item.last_login_date).format();
|
||||||
@ -80,7 +82,7 @@ UsersCrud.prototype.init = function () {
|
|||||||
url: url,
|
url: url,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
success: function (data, textStatus, jqXHR) {
|
success: function (data, textStatus, jqXHR) {
|
||||||
|
_this.loadPage();
|
||||||
},
|
},
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
ajaxError(jqXHR, textStatus, errorThrown);
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
@ -178,7 +178,10 @@
|
|||||||
/> Email Verified?
|
/> Email Verified?
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-xs-10 col-sm-4 col-md-12 col-lg-12">
|
||||||
|
<label for="spam-type">Spam Type</label>
|
||||||
|
<input type="text" readonly class="form-control" id="spam-type" name="spam-type" data-lpignore="true" value="{!! $user->spam_type !!}">
|
||||||
|
</div>
|
||||||
<button type="submit" class="btn btn-default btn-lg btn-primary">Save</button>
|
<button type="submit" class="btn btn-default btn-lg btn-primary">Save</button>
|
||||||
<input type="hidden" name="id" id="id" value="{!! $user->id !!}"/>
|
<input type="hidden" name="id" id="id" value="{!! $user->id !!}"/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
<th>Active</th>
|
<th>Active</th>
|
||||||
<th>Last Login Date</th>
|
<th>Last Login Date</th>
|
||||||
|
<th>Spam Type</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
18
resources/views/emails/user_spammer_process_result.blade.php
Normal file
18
resources/views/emails/user_spammer_process_result.blade.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-US">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
<ul>
|
||||||
|
@foreach($users as $user)
|
||||||
|
<li>
|
||||||
|
[{!! $user['spam_type'] !!}] - {!! $user['full_name'] !!} ({!! $user['email'] !!}) <a href="{!! $user['edit_link'] !!}" target="_blank">Edit</a>
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<p>Cheers,<br/>{!! Config::get('app.tenant_name') !!} Support Team</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user