First set of code for #461

This commit is contained in:
James Cole
2016-12-13 17:21:28 +01:00
parent 8a8279f97a
commit a9e57e1c34
14 changed files with 331 additions and 46 deletions

View File

@@ -0,0 +1,41 @@
<?php
/**
* BlockedBadLogin.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use Illuminate\Queue\SerializesModels;
/**
* Class LockedOutUser
*
* @package FireflyIII\Events
*/
class BlockedBadLogin extends Event
{
use SerializesModels;
public $email;
public $ipAddress;
/**
* Create a new event instance. This event is triggered when a user gets themselves locked out.
*
* @param string $email
* @param string $ipAddress
*/
public function __construct(string $email, string $ipAddress)
{
$this->email = $email;
$this->ipAddress = $ipAddress;
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* BlockedUserLogin.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use FireflyIII\User;
use Illuminate\Queue\SerializesModels;
/**
* Class BlockedUserLogin
*
* @package FireflyIII\Events
*/
class BlockedUserLogin extends Event
{
use SerializesModels;
public $ipAddress;
public $user;
/**
* Create a new event instance. This event is triggered when a blocked user logs in.
*
* @param User $user
* @param string $ipAddress
*/
public function __construct(User $user, string $ipAddress)
{
$this->user = $user;
$this->ipAddress = $ipAddress;
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* LockedOutUser.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International License.
*
* See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Events;
use Illuminate\Queue\SerializesModels;
/**
* Class LockedOutUser
*
* @package FireflyIII\Events
*/
class LockedOutUser extends Event
{
use SerializesModels;
public $email;
public $ipAddress;
/**
* Create a new event instance. This event is triggered when a user gets themselves locked out.
*
* @param string $email
* @param string $ipAddress
*/
public function __construct(string $email, string $ipAddress)
{
$this->email = $email;
$this->ipAddress = $ipAddress;
}
}

View File

@@ -15,8 +15,11 @@ namespace FireflyIII\Handlers\Events;
use Exception;
use FireflyConfig;
use FireflyIII\Events\BlockedBadLogin;
use FireflyIII\Events\BlockedUserLogin;
use FireflyIII\Events\ConfirmedUser;
use FireflyIII\Events\DeletedUser;
use FireflyIII\Events\LockedOutUser;
use FireflyIII\Events\RegisteredUser;
use FireflyIII\Events\RequestedNewPassword;
use FireflyIII\Events\ResentConfirmation;
@@ -77,6 +80,109 @@ class UserEventHandler
return true;
}
/**
* @param BlockedBadLogin $event
*
* @return bool
*/
public function respondToBlockedBadLogin(BlockedBadLogin $event)
{
$email = $event->email;
$ipAddress = $event->ipAddress;
/** @var Configuration $sendmail */
$sendmail = FireflyConfig::get('mail_for_bad_login', config('firefly.configuration.mail_for_bad_login'));
Log::debug(sprintf('Now in respondToBlockedBadLogin for email address %s', $email));
if (is_null($sendmail) || (!is_null($sendmail) && $sendmail->data === false)) {
Log::error(sprintf('User %s tried to login with bad credentials.', $email));
return true;
}
// send email message:
try {
Mail::send(
['emails.blocked-bad-creds-html', 'emails.blocked-bad-creds-text'], ['email' => $email, 'ip' => $ipAddress], function (Message $message) use ($email) {
$message->to($email, $email)->subject('Blocked login attempt with bad credentials');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
return true;
}
/**
* @param BlockedUserLogin $event
*
* @return bool
*/
public function respondToBlockedUserLogin(BlockedUserLogin $event): bool
{
$user = $event->user;
$email = $user->email;
$ipAddress = $event->ipAddress;
/** @var Configuration $sendmail */
$sendmail = FireflyConfig::get('mail_for_blocked_login', config('firefly.configuration.mail_for_blocked_login'));
Log::debug(sprintf('Now in respondToBlockedUserLogin for email address %s', $email));
if (is_null($sendmail) || (!is_null($sendmail) && $sendmail->data === false)) {
Log::error(sprintf('User #%d (%s) has their accout blocked (blocked_code is "%s") but tried to login.', $user->id, $email, $user->blocked_code));
return true;
}
// send email message:
try {
Mail::send(
['emails.blocked-login-html', 'emails.blocked-login-text'],
[
'user_id' => $user->id,
'user_address' => $email,
'ip' => $ipAddress,
'code' => $user->blocked_code,
], function (Message $message) use ($email, $user) {
$message->to($email, $email)->subject('Blocked login attempt of blocked user');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
return true;
}
/**
* @param LockedOutUser $event
*
* @return bool
*/
public function respondToLockout(LockedOutUser $event): bool
{
$email = $event->email;
$ipAddress = $event->ipAddress;
/** @var Configuration $sendmail */
$sendmail = FireflyConfig::get('mail_for_lockout', config('firefly.configuration.mail_for_lockout'));
Log::debug(sprintf('Now in respondToLockout for email address %s', $email));
if (is_null($sendmail) || (!is_null($sendmail) && $sendmail->data === false)) {
Log::error(sprintf('User %s was locked out after too many invalid login attempts.', $email));
return true;
}
// send email message:
try {
Mail::send(
['emails.locked-out-html', 'emails.locked-out-text'], ['email' => $email, 'ip' => $ipAddress], function (Message $message) use ($email) {
$message->to($email, $email)->subject('User was locked out');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
return true;
}
/**
* @param DeletedUser $event
*

View File

@@ -62,7 +62,16 @@ class ConfigurationController extends Controller
$mustConfirmAccount = FireflyConfig::get('must_confirm_account', config('firefly.configuration.must_confirm_account'))->data;
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
return view('admin.configuration.index', compact('subTitle', 'subTitleIcon', 'singleUserMode', 'mustConfirmAccount', 'isDemoSite'));
// email settings:
$sendErrorMessage = [
'mail_for_lockout' => FireflyConfig::get('mail_for_lockout', config('firefly.configuration.mail_for_lockout'))->data,
'mail_for_blocked_domain' => FireflyConfig::get('mail_for_blocked_domain', config('firefly.configuration.mail_for_blocked_domain'))->data,
'mail_for_blocked_email' => FireflyConfig::get('mail_for_blocked_email', config('firefly.configuration.mail_for_blocked_email'))->data,
'mail_for_bad_login' => FireflyConfig::get('mail_for_bad_login', config('firefly.configuration.mail_for_bad_login'))->data,
'mail_for_blocked_login' => FireflyConfig::get('mail_for_blocked_login', config('firefly.configuration.mail_for_blocked_login'))->data,
];
return view('admin.configuration.index', compact('subTitle', 'subTitleIcon', 'singleUserMode', 'mustConfirmAccount', 'isDemoSite', 'sendErrorMessage'));
}
@@ -81,6 +90,13 @@ class ConfigurationController extends Controller
FireflyConfig::set('must_confirm_account', $data['must_confirm_account']);
FireflyConfig::set('is_demo_site', $data['is_demo_site']);
// email settings
FireflyConfig::set('mail_for_lockout', $data['mail_for_lockout']);
FireflyConfig::set('mail_for_blocked_domain', $data['mail_for_blocked_domain']);
FireflyConfig::set('mail_for_blocked_email', $data['mail_for_blocked_email']);
FireflyConfig::set('mail_for_bad_login', $data['mail_for_bad_login']);
FireflyConfig::set('mail_for_blocked_login', $data['mail_for_blocked_login']);
// flash message
Session::flash('success', strval(trans('firefly.configuration_updated')));
Preferences::mark();

View File

@@ -14,15 +14,14 @@ namespace FireflyIII\Http\Controllers\Auth;
use Config;
use FireflyConfig;
use FireflyIII\Events\BlockedBadLogin;
use FireflyIII\Events\BlockedUserLogin;
use FireflyIII\Events\LockedOutUser;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Lang;
use Log;
use Mail;
use Swift_TransportException;
/**
* Class LoginController
@@ -75,6 +74,8 @@ class LoginController extends Controller
if ($lockedOut) {
$this->fireLockoutEvent($request);
event(new LockedOutUser($request->get('email'), $request->ip()));
return $this->sendLockoutResponse($request);
}
@@ -90,10 +91,13 @@ class LoginController extends Controller
/** @var User $foundUser */
$foundUser = User::where('email', $credentials['email'])->where('blocked', 1)->first();
if (!is_null($foundUser)) {
// if it exists, show message:
// user exists, but is blocked:
$code = strlen(strval($foundUser->blocked_code)) > 0 ? $foundUser->blocked_code : 'general_blocked';
$errorMessage = strval(trans('firefly.' . $code . '_error', ['email' => $credentials['email']]));
$this->reportBlockedUserLoginAttempt($foundUser, $code, $request->ip());
event(new BlockedUserLogin($foundUser, $request->ip()));
}
if (is_null($foundUser)) {
event(new BlockedBadLogin($credentials['email'], $request->ip()));
}
// If the login attempt was unsuccessful we will increment the number of attempts
@@ -163,34 +167,4 @@ class LoginController extends Controller
]
);
}
/**
* Send a message home about the blocked attempt to login.
* Perhaps in a later stage, simply log these messages.
*
* @param User $user
* @param string $code
* @param string $ipAddress
*/
private function reportBlockedUserLoginAttempt(User $user, string $code, string $ipAddress)
{
try {
$email = env('SITE_OWNER', false);
$fields = [
'user_id' => $user->id,
'user_address' => $user->email,
'code' => $code,
'ip' => $ipAddress,
];
Mail::send(
['emails.blocked-login-html', 'emails.blocked-login-text'], $fields, function (Message $message) use ($email, $user) {
$message->to($email, $email)->subject('Blocked a login attempt from ' . trim($user->email) . '.');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
}
}

View File

@@ -36,9 +36,14 @@ class ConfigurationRequest extends Request
public function getConfigurationData(): array
{
return [
'single_user_mode' => intval($this->get('single_user_mode')) === 1,
'must_confirm_account' => intval($this->get('must_confirm_account')) === 1,
'is_demo_site' => intval($this->get('is_demo_site')) === 1,
'single_user_mode' => intval($this->get('single_user_mode')) === 1,
'must_confirm_account' => intval($this->get('must_confirm_account')) === 1,
'is_demo_site' => intval($this->get('is_demo_site')) === 1,
'mail_for_lockout' => intval($this->get('mail_for_lockout')) === 1,
'mail_for_blocked_domain' => intval($this->get('mail_for_blocked_domain')) === 1,
'mail_for_blocked_email' => intval($this->get('mail_for_blocked_email')) === 1,
'mail_for_bad_login' => intval($this->get('mail_for_bad_login')) === 1,
'mail_for_blocked_login' => intval($this->get('mail_for_blocked_login')) === 1,
];
}
@@ -48,9 +53,14 @@ class ConfigurationRequest extends Request
public function rules()
{
$rules = [
'single_user_mode' => 'between:0,1|numeric',
'must_confirm_account' => 'between:0,1|numeric',
'is_demo_site' => 'between:0,1|numeric',
'single_user_mode' => 'between:0,1|numeric',
'must_confirm_account' => 'between:0,1|numeric',
'is_demo_site' => 'between:0,1|numeric',
'mail_for_lockout' => 'between:0,1|numeric',
'mail_for_blocked_domain' => 'between:0,1|numeric',
'mail_for_blocked_email' => 'between:0,1|numeric',
'mail_for_bad_login' => 'between:0,1|numeric',
'mail_for_blocked_login' => 'between:0,1|numeric',
];
return $rules;

View File

@@ -41,10 +41,23 @@ class EventServiceProvider extends ServiceProvider
[
'FireflyIII\Handlers\Events\UserEventHandler@storeConfirmationIpAddress',
],
'FireflyIII\Events\DeletedUser' => // is a User related event.
[
'FireflyIII\Handlers\Events\UserEventHandler@saveEmailAddress',
],
'FireflyIII\Events\LockedOutUser' => // is a User related event.
[
'FireflyIII\Handlers\Events\UserEventHandler@respondToLockout',
],
'FireflyIII\Events\BlockedUserLogin' => // is a User related event.
[
'FireflyIII\Handlers\Events\UserEventHandler@respondToBlockedUserLogin',
],
'FireflyIII\Events\BlockedBadLogin' => // is a User related event.
[
'FireflyIII\Handlers\Events\UserEventHandler@respondToBlockedBadLogin',
],
'FireflyIII\Events\RegisteredUser' => // is a User related event.
[
'FireflyIII\Handlers\Events\UserEventHandler@sendRegistrationMail',