Commit 3e51d4cb authored by Jacob Priddy's avatar Jacob Priddy 👌

sort out doorcode hashing... Also progress on authorization

parent 7036407b
......@@ -3,6 +3,16 @@
namespace App;
class Group
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Group extends Model
{
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function groups(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
}
......@@ -5,6 +5,7 @@ namespace App;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class User extends Authenticatable
{
......@@ -24,10 +25,18 @@ class User extends Authenticatable
];
/**
* @return HasMany
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function tokens(): HasMany
{
return $this->hasMany(Token::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function groups(): BelongsToMany
{
return $this->belongsToMany(Group::class);
}
}
<?php
namespace Source\Authorization;
use Illuminate\Contracts\Auth\Guard;
use Source\Exceptions\AuthorizationException;
class ApiAuthorizer implements Authorizer
{
protected Guard $guard;
public function __construct(Guard $guard)
{
$this->guard = $guard;
}
/**
* @inheritDoc
*/
public function allows(array $permissions): bool
{
$user = $this->guard->user();
if (!$user) {
return false;
}
return true;
}
/**
* @inheritDoc
*/
public function protect(array $permissions): void
{
if (!$this->allows($permissions)) {
throw new AuthorizationException();
}
}
}
<?php
namespace Source\Authorization;
interface Authorizer
{
/**
* @param array $permissions
* @return bool
*/
public function allows(array $permissions): bool;
/**
* @param array $permissions
* @throws \Source\Exceptions\AuthorizationException
*/
public function protect(array $permissions): void;
}
<?php
namespace Source\Authorization;
class Permissions
{
public const ADMIN = 'admin';
public const MODIFY_USER = 'user:modify';
public const READ_USERS = 'user:read';
}
......@@ -5,8 +5,20 @@ namespace Source\Gateways\Users;
use Source\Entities\User;
// TODO: Write tests for this
class DatabaseUsersRepository implements UsersRepository
{
protected function secureDoorcode(string $doorcode): string
{
// As of PHP 7 the salt parameter to password_hash has been depreciated.
// As we need to be able to search for users by doorcode they either all need to have the same salt
// (in this case, the app key) or no salt (I'd prefer a salt). This way the doorcode can be hashed and
// then easily searched for in the database without having to check against every user and rehash every
// time with the new salt. As such it is not as easy to use BCRYPT :(
// So I'll just shred it twice using sha512 with with the application key.
return hash('sha512', hash('sha512', $doorcode . config('app.key')));
}
/**
* @inheritDoc
*/
......@@ -84,7 +96,7 @@ class DatabaseUsersRepository implements UsersRepository
);
}
protected function fillBasicUserAttrs(User $user, \App\User $dbUser): \App\User
protected function fillBasicUserAttrs(User $user, \App\User $dbUser, bool $includeDoorcode = true): \App\User
{
$dbUser->first_name = $user->getFirstName();
$dbUser->last_name = $user->getLastName();
......@@ -92,8 +104,14 @@ class DatabaseUsersRepository implements UsersRepository
$dbUser->emplid = $user->getEmplid();
$dbUser->email = $user->getEmail();
$dbUser->password = bcrypt($user->getPassword());
$dbUser->doorcode = hash('sha256', $user->getDoorcode());
$dbUser->expires_at = $user->getExpiresAt();
// If the doorcode exists and is the same as provided, don't change
// Else regenerate
if (!isset($dbUser->doorcode) || (isset($dbUser->doorcode) && $dbUser->doorcode !== $user->getDoorcode())) {
$dbUser->doorcode = $this->secureDoorcode($user->getDoorcode());
}
return $dbUser;
}
......@@ -179,7 +197,7 @@ class DatabaseUsersRepository implements UsersRepository
*/
public function findByDoorcode(string $doorcode): ?User
{
$doorcode = hash('sha256', $doorcode);
$doorcode = $this->secureDoorcode($doorcode);
$user = \App\User::where('doorcode', $doorcode)->first();
......
......@@ -136,7 +136,7 @@ class UseCaseTest extends TestCase
$this->handleTest('69', $this->createUserAttributes($updatedUser, null, null));
$this->assertEquals('pass', $this->response->getUser()->getPassword());
$this->assertEquals('door', $this->response->getUser()->getDoorcode());
$this->assertEquals(null, $this->response->getUser()->getDoorcode());
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment