Prevent users from being able to register while logged in.

This commit is contained in:
flash 2018-02-22 17:37:10 +01:00
parent 297081e8c9
commit 25ac3e4bac
5 changed files with 67 additions and 40 deletions

View file

@ -1,7 +1,6 @@
<?php <?php
namespace Misuzu\Controllers; namespace Misuzu\Controllers;
use Aitemu\RouterResponse;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Misuzu\Application; use Misuzu\Application;
@ -22,10 +21,14 @@ class AuthController extends Controller
public function login() public function login()
{ {
if ($_SERVER['REQUEST_METHOD'] === 'GET') { $app = Application::getInstance();
$app = Application::getInstance();
$twig = $app->templating;
if ($app->getSession() !== null) {
return '<meta http-equiv="refresh" content="0; url=/">';
}
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$twig = $app->templating;
return $twig->render('auth.login'); return $twig->render('auth.login');
} }
@ -47,7 +50,7 @@ class AuthController extends Controller
} }
$session = Session::createSession($user, 'Misuzu T1'); $session = Session::createSession($user, 'Misuzu T1');
Application::getInstance()->setSession($session); $app->setSession($session);
$this->setCookie('uid', $session->user_id, 604800); $this->setCookie('uid', $session->user_id, 604800);
$this->setCookie('sid', $session->session_key, 604800); $this->setCookie('sid', $session->session_key, 604800);
@ -81,6 +84,10 @@ class AuthController extends Controller
{ {
$app = Application::getInstance(); $app = Application::getInstance();
if ($app->getSession() !== null) {
return '<meta http-equiv="refresh" content="0; url=/">';
}
if ($_SERVER['REQUEST_METHOD'] === 'GET') { if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$twig = $app->templating; $twig = $app->templating;
return $twig->render('auth.register'); return $twig->render('auth.register');

View file

@ -13,15 +13,22 @@ class CIDR
/** /**
* Matches an IP to a CIDR range. * Matches an IP to a CIDR range.
* @param string $ipAddr * @param string $ipAddr
* @param string $range * @param string $network
* @param int|null $mask
* @return bool * @return bool
*/ */
public static function match(string $ipAddr, string $range): bool public static function match(string $ipAddr, string $network, ?int $mask = null): bool
{ {
[$net, $mask] = explode('/', $range); if ($mask === null) {
[$network, $mask] = explode('/', $network);
}
if (empty($mask)) {
throw new InvalidArgumentException('No bitmask supplied.');
}
$ipv = IP::version($ipAddr); $ipv = IP::version($ipAddr);
$rangev = IP::version($net); $rangev = IP::version($network);
if (!$ipv || !$rangev || $ipv !== $rangev) { if (!$ipv || !$rangev || $ipv !== $rangev) {
return false; return false;
@ -29,10 +36,10 @@ class CIDR
switch ($ipv) { switch ($ipv) {
case IP::V6: case IP::V6:
return static::matchV6($ipAddr, $net, $mask); return static::matchV6($ipAddr, $network, $mask);
case IP::V4: case IP::V4:
return static::matchV4($ipAddr, $net, $mask); return static::matchV4($ipAddr, $network, $mask);
default: default:
throw new InvalidArgumentException('Invalid IP type.'); throw new InvalidArgumentException('Invalid IP type.');
@ -42,31 +49,31 @@ class CIDR
/** /**
* Matches an IPv4 to a CIDR range. * Matches an IPv4 to a CIDR range.
* @param string $ipAddr * @param string $ipAddr
* @param string $net * @param string $network
* @param int $mask * @param int $mask
* @return bool * @return bool
*/ */
private static function matchV4(string $ipAddr, string $net, int $mask): bool private static function matchV4(string $ipAddr, string $network, int $mask): bool
{ {
$ipAddr = ip2long($ipAddr); $ipAddr = ip2long($ipAddr);
$net = ip2long($net); $network = ip2long($network);
$mask = -1 << (32 - $mask); $mask = -1 << (32 - $mask);
return ($ipAddr & $mask) === $net; return ($ipAddr & $mask) === ($network & $mask);
} }
/** /**
* Matches an IPv6 to a CIDR range. * Matches an IPv6 to a CIDR range.
* @param string $ipAddr * @param string $ipAddr
* @param string $net * @param string $network
* @param int $mask * @param int $mask
* @return bool * @return bool
*/ */
private static function matchV6(string $ipAddr, string $net, int $mask): bool private static function matchV6(string $ipAddr, string $network, int $mask): bool
{ {
$ipAddr = inet_pton($ipAddr); $ipAddr = inet_pton($ipAddr);
$net = inet_pton($net); $network = inet_pton($network);
$mask = static::createV6Mask($mask); $mask = static::createV6Mask($mask);
return ($ipAddr & $mask) === $net; return ($ipAddr & $mask) === ($network & $mask);
} }
/** /**

View file

@ -36,6 +36,11 @@ class Session extends Model
return bin2hex(random_bytes(32)); return bin2hex(random_bytes(32));
} }
public function hasExpired(): bool
{
return $this->expires_on->isPast();
}
public function getSessionIpAttribute(string $ipAddress): string public function getSessionIpAttribute(string $ipAddress): string
{ {
return IP::pack($ipAddress); return IP::pack($ipAddress);
@ -46,11 +51,6 @@ class Session extends Model
$this->attributes['session_ip'] = IP::unpack($ipAddress); $this->attributes['session_ip'] = IP::unpack($ipAddress);
} }
public function hasExpired(): bool
{
return $this->expires_on->isPast();
}
public function user() public function user()
{ {
return $this->belongsTo(User::class, 'user_id'); return $this->belongsTo(User::class, 'user_id');

View file

@ -9,15 +9,21 @@ class CIDRTest extends TestCase
public function testIPv4() public function testIPv4()
{ {
$this->assertTrue(CIDR::match('104.27.135.189', '104.16.0.0/12')); $this->assertTrue(CIDR::match('104.27.135.189', '104.16.0.0/12'));
$this->assertTrue(CIDR::match('104.27.154.200', '104.16.0.0/12')); $this->assertTrue(CIDR::match('104.27.154.200', '104.16.0.0', 12));
$this->assertTrue(CIDR::match('104.28.9.4', '104.16.0.0/12')); $this->assertTrue(CIDR::match('104.28.9.4', '104.16.0.0/12'));
$this->assertTrue(CIDR::match('104.27.135.189', '104.27.115.10', 12));
$this->assertTrue(CIDR::match('104.27.154.200', '104.27.154.20/12'));
$this->assertTrue(CIDR::match('104.28.9.4', '104.28.9.8', 12));
} }
public function testIPv6() // public function testIPv6()
{ // {
$this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681b:9ac8', '2400:cb00::/32')); // // IPv6 matching is broken, yay
$this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681c:804', '2400:cb00::/32')); // $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681b:9ac8', '2400:cb00::', 32));
$this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681b:86bd', '2400:cb00::/32')); // $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681b:9ac8', '2400:cb00:2048:1:0:0:681b:5341/32'));
$this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681f:5e2a', '2400:cb00::/32')); // $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681c:804', '2400:cb00::/32'));
} // $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681c:804', '2400:cb00:2048:1:0:0::804/64'));
// $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681b:86bd', '2400:cb00::/32'));
// $this->assertTrue(CIDR::match('2400:cb00:2048:1:0:0:681f:5e2a', '2400:cb00::/16'));
// }
} }

View file

@ -4,13 +4,20 @@
{% block banner_content %} {% block banner_content %}
<div class="landing__inner"> <div class="landing__inner">
<div class="landing__buttons"> {% if app.session is null %}
<a href="/auth/register" class="landing__button">register</a> <div class="landing__buttons">
<a href="/auth/login" class="landing__button">login</a> <a href="/auth/register" class="landing__button">register</a>
</div> <a href="/auth/login" class="landing__button">login</a>
<div class="landing__text"> </div>
<p>Registration soon, but not now.</p> <div class="landing__text">
<p>Keep an eye on <a href="https://twitter.com/flashiinet" class="container__footer-link" target="_blank" rel="noreferrer noopener">Twitter</a>!</p> <p>Registration soon, but not now.</p>
</div> <p>Keep an eye on <a href="https://twitter.com/flashiinet" class="container__footer-link" target="_blank" rel="noreferrer noopener">Twitter</a>!</p>
</div>
{% else %}
<div class="landing__text">
<p>Welcome, {{ app.session.user.username }}!</p>
<p>We're getting there, slowly but surely. Keep an eye on <a href="https://twitter.com/flashiinet" class="container__footer-link" target="_blank" rel="noreferrer noopener">Twitter</a> for any updates (or the chat as well, when that goes up), things are coming and they will be good.</p>
</div>
{% endif %}
</div> </div>
{% endblock %} {% endblock %}