Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions components/Account.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use October\Rain\Auth\AuthException;
use Cms\Classes\Page;
use Cms\Classes\ComponentBase;
use RainLab\User\Models\User as UserModel;
use RainLab\User\Models\Settings as UserSettings;
use Exception;

Expand Down Expand Up @@ -234,6 +235,13 @@ public function onSignin()
throw new AuthException(/*Sorry, this user is currently not activated. Please contact us for further assistance.*/'rainlab.user::lang.account.banned');
}

/*
* Record IP address
*/
if ($ipAddress = Request::ip()) {
$user->touchIpAddress($ipAddress);
}

/*
* Redirect
*/
Expand All @@ -257,6 +265,10 @@ public function onRegister()
throw new ApplicationException(Lang::get(/*Registrations are currently disabled.*/'rainlab.user::lang.account.registration_disabled'));
}

if ($this->isRegisterThrottled()) {
throw new ApplicationException(Lang::get(/*Registration is throttled. Please try again later.*/'rainlab.user::lang.account.registration_throttled'));
}

/*
* Validate input
*/
Expand All @@ -280,6 +292,13 @@ public function onRegister()
throw new ValidationException($validation);
}

/*
* Record IP address
*/
if ($ipAddress = Request::ip()) {
$data['created_ip_address'] = $data['last_ip_address'] = $ipAddress;
}

/*
* Register user
*/
Expand Down Expand Up @@ -563,4 +582,17 @@ protected function redirectForceSecure()

return Redirect::secure(Request::path());
}

/**
* Returns true if user is throttled.
* @return bool
*/
protected function isRegisterThrottled()
{
if (!UserSettings::get('use_register_throttle', false)) {
return false;
}

return UserModel::isRegisterThrottled(Request::ip());
}
}
5 changes: 5 additions & 0 deletions lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
'require_activation_comment' => 'Users must have an activated account to sign in.',
'use_throttle' => 'Throttle attempts',
'use_throttle_comment' => 'Repeat failed sign in attempts will temporarily suspend the user.',
'use_register_throttle' => 'Throttle registration',
'use_register_throttle_comment' => 'Prevent multiple registrations from the same IP in short succession.',
'block_persistence' => 'Prevent concurrent sessions',
'block_persistence_comment' => 'When enabled users cannot sign in to multiple devices at the same time.',
'login_attribute' => 'Login attribute',
Expand Down Expand Up @@ -132,6 +134,8 @@
'status_guest' => 'Guest',
'status_activated' => 'Activated',
'status_registered' => 'Registered',
'created_ip_address' => 'Created IP Address',
'last_ip_address' => 'Last IP Address',
],
'group' => [
'label' => 'Group',
Expand Down Expand Up @@ -183,6 +187,7 @@
'already_active' => 'Your account is already activated!',
'activation_email_sent' => 'An activation email has been sent to your email address.',
'registration_disabled' => 'Registrations are currently disabled.',
'registration_throttled' => 'Registration is throttled. Please try again later.',
'sign_in' => 'Sign in',
'register' => 'Register',
'full_name' => 'Full Name',
Expand Down
1 change: 1 addition & 0 deletions models/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function initSettingsData()
$this->update_requires_password = false;
$this->remember_login = self::REMEMBER_ALWAYS;
$this->min_password_length = self::MIN_PASSWORD_LENGTH_DEFAULT;
$this->use_register_throttle = true;
}

public function getActivateModeOptions()
Expand Down
45 changes: 44 additions & 1 deletion models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Auth;
use Mail;
use Event;
use Carbon\Carbon;
use October\Rain\Auth\Models\User as UserBase;
use RainLab\User\Models\Settings as UserSettings;
use October\Rain\Auth\AuthException;
Expand Down Expand Up @@ -49,7 +50,9 @@ class User extends UserBase
'username',
'email',
'password',
'password_confirmation'
'password_confirmation',
'created_ip_address',
'last_ip_address'
];

/**
Expand Down Expand Up @@ -354,6 +357,46 @@ public function isBanned()
return $throttle ? $throttle->is_banned : false;
}

//
// IP Recording and Throttle
//

/**
* Records the last_ip_address to reflect the last known IP for this user.
* @param string|null $ipAddress
* @return void
*/
public function touchIpAddress($ipAddress)
{
$this
->newQuery()
->where('id', $this->id)
->update(['last_ip_address' => $ipAddress])
;
}

/**
* Returns true if IP address is throttled and cannot register
* again. Maximum 3 registrations every 60 minutes.
* @param string|null $ipAddress
* @return bool
*/
public static function isRegisterThrottled($ipAddress)
{
if (!$ipAddress) {
return false;
}

$timeLimit = Carbon::now()->subMinutes(60);
$count = static::make()
->where('created_ip_address', $ipAddress)
->where('created_at', '>', $timeLimit)
->count()
;

return $count > 2;
}

//
// Last Seen
//
Expand Down
10 changes: 9 additions & 1 deletion models/settings/fields.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ tabs:

# Remeber Login Mode
remember_login:
span: left
span: right
label: rainlab.user::lang.settings.remember_login
commentAbove: rainlab.user::lang.settings.remember_login_comment
type: radio
Expand All @@ -44,6 +44,14 @@ tabs:
type: switch
tab: rainlab.user::lang.settings.registration_tab

# Enable registration throttling
use_register_throttle:
span: right
label: rainlab.user::lang.settings.use_register_throttle
comment: rainlab.user::lang.settings.use_register_throttle_comment
type: switch
tab: rainlab.user::lang.settings.registration_tab

# Minimum password length
min_password_length:
span: left
Expand Down
10 changes: 10 additions & 0 deletions models/user/columns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ columns:
label: rainlab.user::lang.user.is_guest
type: switch
invisible: true

created_ip_address:
label: rainlab.user::lang.user.created_ip_address
searchable: true
invisible: true

last_ip_address:
label: rainlab.user::lang.user.last_ip_address
searchable: true
invisible: true
14 changes: 14 additions & 0 deletions models/user/fields.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ tabs:
type: relation
emptyOption: rainlab.user::lang.user.empty_groups

created_ip_address:
label: rainlab.user::lang.user.created_ip_address
span: auto
disabled: true
tab: rainlab.user::lang.user.account
context: preview

last_ip_address:
label: rainlab.user::lang.user.last_ip_address
span: auto
disabled: true
tab: rainlab.user::lang.user.account
context: preview

secondaryTabs:
fields:

Expand Down
28 changes: 28 additions & 0 deletions updates/users_add_ip_address.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php namespace RainLab\User\Updates;

use Carbon\Carbon;
use Schema;
use October\Rain\Database\Updates\Migration;

class UsersAddIpAddress extends Migration
{
public function up()
{
Schema::table('users', function($table)
{
$table->string('created_ip_address')->nullable();
$table->string('last_ip_address')->nullable();
});
}

public function down()
{
if (Schema::hasColumn('users', 'created_ip_address')) {
Schema::table('users', function($table)
{
$table->dropColumn('created_ip_address');
$table->dropColumn('last_ip_address');
});
}
}
}
3 changes: 3 additions & 0 deletions updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,6 @@
1.4.7: Fixes redirect bug in Account component / Update translations and separate user and group management.
1.4.8: Fixes a bug where calling MailBlocker::removeBlock could remove all mail blocks for the user.
1.5.0: !!! Required password length is now a minimum of 8 characters. Previous passwords will not be affected until the next password change.
1.5.1:
- User IP addresses are now logged. Introduce registration throttle and "remember login" functionality.
- users_add_ip_address.php