Skip to content

Commit

Permalink
anti cheating/spamming measures added to login
Browse files Browse the repository at this point in the history
  • Loading branch information
dxprog committed May 19, 2018
1 parent 75004e9 commit c4363bd
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 16 deletions.
52 changes: 48 additions & 4 deletions api/user.php
Expand Up @@ -82,8 +82,8 @@ public static function authenticateUser($code) {
$user->name = $data->name;
$user->age = (int) $data->created;
$user->ip = $_SERVER['REMOTE_ADDR'];
if ($user->sync()) {
$retVal = true;
if (!$user->sync()) {
$user = null;
}
} else {

Expand All @@ -92,10 +92,16 @@ public static function authenticateUser($code) {
$user->age = (int) $data->created;
$user->sync();
}
$retVal = true;
}

Lib\Session::set('user', $user);
// Save the login attempt before verifying attempt count
self::_logLoginAttempt($user->id);

// Now verify the count
if ($user && self::_verifyLoginAttempts($user->id)) {
Lib\Session::set('user', $user);
$retVal = true;
}
}
}

Expand All @@ -115,6 +121,44 @@ private static function _createOAuth2(User $user = null) {
return $retVal;
}

/**
* Logs a login attempt to the database
*/
private static function _logLoginAttempt($userId) {
$params = [
'userId' => $userId,
'date' => time(),
'ip' => $_SERVER['REMOTE_ADDR']
];

return Lib\Db::Query(
'INSERT INTO `logins` (`user_id`, `login_date`, `login_ip`) VALUES (:userId, :date, :ip)',
$params
);
}

/**
* Verifies that the user trying to login can do so given
* the number of users per IP limitation
*/
private static function _verifyLoginAttempts($userId) {
$params = [
'userId' => $userId,
// Attempts within the last 24 hours
'date' => time() - 86400,
'ip' => $_SERVER['REMOTE_ADDR']
];

// Find all login attempts that aren't this user
$result = Lib\Db::Query(
'SELECT user_id FROM `logins` WHERE `user_id` != :userId AND login_ip=:ip AND login_date >= :date',
$params
);

// If the returned count is over the amount allowed (minus the currently logged in user), no es beuno
return $result->count < MAX_USERS_SHARING_IP;
}

}

}
5 changes: 4 additions & 1 deletion app-config.sample.php
Expand Up @@ -33,4 +33,7 @@
define('VIEW_PATH', '/var/www/brakkit/views');

// ID of a bracket to be featured on the landing page
define('LANDING_FEATURE_BRACKET', 1);
define('LANDING_FEATURE_BRACKET', 1);

// The maximum number of users that can be logged in under the same IP
define('MAX_USERS_SHARING_IP', 5);
29 changes: 18 additions & 11 deletions controller/user.php
Expand Up @@ -29,23 +29,30 @@ public static function generate(array $params) {
header('Location: ' . $redirect);
exit;
} else {
Lib\Display::addKey('content', 'We were unable to verify your account at this time or your account age does not meet the requirements.');
$obj = self::_loginPage();
$obj->error = 'We were unable to verify your account at this time or your account does not meet the requirements.';
Lib\Display::renderAndAddKey('content', 'login', $obj);
}
} else {
$obj = new stdClass;
$obj->loginUrl = Api\User::getLoginUrl(Lib\Url::Get('redirect'));
$obj = self::_loginPage();
Lib\Display::renderAndAddKey('content', 'login', $obj);
}

// Do a mobile check
if (preg_match('/iphone|android|windows phone/i', $_SERVER['HTTP_USER_AGENT'])) {
$obj->loginUrl = str_replace('authorize', 'authorize.compact', $obj->loginUrl);
}
}

$obj->originalUrl = Lib\Url::Get('redirect');
Lib\Display::addKey('page', 'login');
Lib\Display::addKey('title', 'Login' . DEFAULT_TITLE_SUFFIX);
Lib\Display::renderAndAddKey('content', 'login', $obj);
private static function _loginPage() {
$obj = new stdClass;
$obj->loginUrl = Api\User::getLoginUrl(Lib\Url::Get('redirect'));

// Do a mobile check
if (preg_match('/iphone|android|windows phone/i', $_SERVER['HTTP_USER_AGENT'])) {
$obj->loginUrl = str_replace('authorize', 'authorize.compact', $obj->loginUrl);
}

$obj->originalUrl = Lib\Url::Get('redirect');
Lib\Display::addKey('page', 'login');
Lib\Display::addKey('title', 'Login' . DEFAULT_TITLE_SUFFIX);
return $obj;
}

}
Expand Down
5 changes: 5 additions & 0 deletions static/css/dev/login.scss
Expand Up @@ -26,6 +26,11 @@
color: #fff;
}

p.error {
color: get-color(red);
margin-bottom: spacing(4);
}

.read-only {
display: block;
margin-top: 40px;
Expand Down
3 changes: 3 additions & 0 deletions views/login.hbs
Expand Up @@ -2,6 +2,9 @@
<h2>Login</h2>
</header>
<div class="login-form">
{{#if error}}
<p class="error">{{error}}</p>
{{/if}}
<a href="{{loginUrl}}" class="button">Login with Reddit</a>
<h3>What's this?</h3>
<p>To help maintain voting integrity, we require that you authenticate with your reddit account.</p>
Expand Down

0 comments on commit c4363bd

Please sign in to comment.