Some user related stuff.

This commit is contained in:
flash 2018-02-11 14:55:24 +01:00
parent e120d26cbf
commit 1acfcc3d98
4 changed files with 85 additions and 37 deletions

View file

@ -12,6 +12,14 @@ use Misuzu\Users\Session;
class AuthController extends Controller class AuthController extends Controller
{ {
private const USERNAME_VALIDATION_ERRORS = [
'trim' => 'Your username may not start or end with spaces!',
'short' => "Your username is too short, it has to be at least " . User::USERNAME_MIN_LENGTH . " characters!",
'long' => "Your username is too long, it can't be longer than " . User::USERNAME_MAX_LENGTH . " characters!",
'invalid' => 'Your username contains invalid characters.',
'spacing' => 'Please use either underscores or spaces, not both!',
];
public function login() public function login()
{ {
if ($_SERVER['REQUEST_METHOD'] === 'GET') { if ($_SERVER['REQUEST_METHOD'] === 'GET') {
@ -38,14 +46,7 @@ class AuthController extends Controller
return ['error' => 'Invalid username or password!']; return ['error' => 'Invalid username or password!'];
} }
$session = new Session; $session = Session::createSession($user, 'Misuzu T1');
$session->user_id = $user->user_id;
$session->session_ip = IP::remote();
$session->user_agent = 'Misuzu Testing 1';
$session->expires_on = Carbon::now()->addMonth();
$session->session_key = bin2hex(random_bytes(32));
$session->save();
Application::getInstance()->setSession($session); Application::getInstance()->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);
@ -128,12 +129,12 @@ class AuthController extends Controller
} }
$username = $_POST['username'] ?? ''; $username = $_POST['username'] ?? '';
$username_validate = $this->validateUsername($username); $username_validate = User::validateUsername($username);
$password = $_POST['password'] ?? ''; $password = $_POST['password'] ?? '';
$email = $_POST['email'] ?? ''; $email = $_POST['email'] ?? '';
if ($username_validate !== '') { if ($username_validate !== '') {
return ['error' => $username_validate]; return ['error' => self::USERNAME_VALIDATION_ERRORS[$username_validate]];
} }
try { try {
@ -183,31 +184,4 @@ class AuthController extends Controller
return '<meta http-equiv="refresh" content="1; url=/">'; return '<meta http-equiv="refresh" content="1; url=/">';
} }
private function validateUsername(string $username): string
{
$username_length = strlen($username);
if (($username ?? '') !== trim($username)) {
return 'Your username may not start or end with spaces!';
}
if ($username_length < 3) {
return "Your username is too short, it has to be at least 3 characters!";
}
if ($username_length > 16) {
return "Your username is too long, it can't be longer than 16 characters!";
}
if (strpos($username, ' ') !== false || !preg_match('#^[A-Za-z0-9-\[\]_ ]+$#u', $username)) {
return 'Your username contains invalid characters.';
}
if (strpos($username, '_') !== false && strpos($username, ' ') !== false) {
return 'Please use either underscores or spaces, not both!';
}
return '';
}
} }

View file

@ -9,6 +9,32 @@ class Session extends Model
protected $primaryKey = 'session_id'; protected $primaryKey = 'session_id';
protected $dates = ['expires_on']; protected $dates = ['expires_on'];
public static function createSession(
User $user,
?string $userAgent = null,
Carbon $expires = null,
?string $ipAddress = null
): Session {
$ipAddress = $ipAddress ?? IP::remote();
$userAgent = $userAgent ?? 'Misuzu';
$expires = $expires ?? Carbon::now()->addMonth();
$session = new Session;
$session->user_id = $user->user_id;
$session->session_ip = $ipAddress;
$session->user_agent = $userAgent;
$session->expires_on = $expires;
$session->session_key = self::generateKey();
$session->save();
return $session;
}
public static function generateKey(): string
{
return bin2hex(random_bytes(32));
}
public function getSessionIpAttribute(string $ipAddress): string public function getSessionIpAttribute(string $ipAddress): string
{ {
return IP::pack($ipAddress); return IP::pack($ipAddress);

View file

@ -11,6 +11,9 @@ class User extends Model
private const PASSWORD_HASH_ALGO = PASSWORD_ARGON2I; private const PASSWORD_HASH_ALGO = PASSWORD_ARGON2I;
public const USERNAME_MIN_LENGTH = 3;
public const USERNAME_MAX_LENGTH = 16;
protected $primaryKey = 'user_id'; protected $primaryKey = 'user_id';
public static function createUser( public static function createUser(
@ -33,6 +36,33 @@ class User extends Model
return $user; return $user;
} }
public static function validateUsername(string $username): string
{
$username_length = strlen($username);
if ($username !== trim($username)) {
return 'trim';
}
if ($username_length < self::USERNAME_MIN_LENGTH) {
return 'short';
}
if ($username_length > self::USERNAME_MAX_LENGTH) {
return 'long';
}
if (strpos($username, ' ') !== false || !preg_match('#^[A-Za-z0-9-\[\]_ ]+$#u', $username)) {
return 'invalid';
}
if (strpos($username, '_') !== false && strpos($username, ' ') !== false) {
return 'spacing';
}
return '';
}
public function getRegisterIpAttribute(string $ipAddress): string public function getRegisterIpAttribute(string $ipAddress): string
{ {
return IP::pack($ipAddress); return IP::pack($ipAddress);

18
tests/UserTest.php Normal file
View file

@ -0,0 +1,18 @@
<?php
namespace MisuzuTests;
use PHPUnit\Framework\TestCase;
use Misuzu\Users\User;
class UserTest extends TestCase
{
public function testUsernameValidation()
{
$this->assertEquals(User::validateUsername('flashwave'), '');
$this->assertEquals(User::validateUsername(' flash '), 'trim');
$this->assertEquals(User::validateUsername('f'), 'short');
$this->assertEquals(User::validateUsername('flaaaaaaaaaaaaaaaash'), 'long');
$this->assertEquals(User::validateUsername('F|@$h'), 'invalid');
$this->assertEquals(User::validateUsername('fl ash_wave'), 'spacing');
}
}