Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Guardians of the Kretschmar Elock System
Doorcode
Commits
c9728c92
Commit
c9728c92
authored
May 16, 2020
by
Jacob Priddy
👌
Browse files
Add override check in door access
parent
d2fa260b
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/web/backend/src/UseCases/Door/Access/Access.php
View file @
c9728c92
...
...
@@ -12,6 +12,7 @@ use Source\Gateways\Entries\EntriesRepository;
use
Source\Gateways\Attempts\AttemptsRepository
;
use
Source\UseCases\DoorUserGroup\DoorUserGroupMapUseCase
;
use
Source\UseCases\Door\Access\Authorizers\DoorOpenModeCheck\DoorOpenModeCheck
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
;
use
Source\UseCases\Door\Access\Authorizers\UserDoorcodeCheck\UserDoorcodeCheck
;
use
Source\UseCases\Door\Access\Authorizers\GroupScheduleCheck\GroupScheduleCheck
;
...
...
@@ -49,11 +50,17 @@ class Access implements AccessUseCase
*/
protected
EntriesRepository
$entries
;
/**
* @var \Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
*/
protected
DoorOverrideCheck
$overrideCheck
;
public
function
__construct
(
DoorOpenModeCheck
$openModeCheck
,
UserDoorcodeCheck
$userCheck
,
GroupScheduleCheck
$scheduleCheck
,
DoorUserGroupMapUseCase
$doorUserMapper
,
DoorOverrideCheck
$overrideCheck
,
AttemptsRepository
$attempts
,
EntriesRepository
$entries
)
{
...
...
@@ -63,6 +70,7 @@ class Access implements AccessUseCase
$this
->
doorUserMapper
=
$doorUserMapper
;
$this
->
attempts
=
$attempts
;
$this
->
entries
=
$entries
;
$this
->
overrideCheck
=
$overrideCheck
;
}
protected
function
logUserAccess
(
string
$doorId
,
string
$userId
,
bool
$success
):
void
...
...
@@ -102,17 +110,21 @@ class Access implements AccessUseCase
* 1. Check doorId
* - door (continue)
* - no door (deny)
* 2. Check for open mode on the door
* 2. Check for door overrides
* - door in open mode (allow)
* - door in closed mode (deny)
* - no override (continue)
* 3. Check for open mode on the door
* - open mode on (allow)
* - open mode off (continue)
*
3
. Get user from door code
*
4
. Get user from door code
* - user exists (continue)
* - no user found (deny and log attempt)
*
4
. Get group intersection of doors and users
*
5
. Foreach group check all user access schedules
*
5
. Get group intersection of doors and users
*
6
. Foreach group check all user access schedules
* - schedule has currently active event (allow and log entry)
* - schedule doe snot have currently active event (continue)
*
6
. Now all allowing conditions hit (deny and log entry)
*
7
. Now all allowing conditions hit (deny and log entry)
*/
if
(
!
$doorId
)
{
throw
new
AuthenticationException
();
...
...
@@ -120,11 +132,30 @@ class Access implements AccessUseCase
$now
=
Carbon
::
now
();
/*
* Check overrides
*/
$overrideStatus
=
$this
->
overrideCheck
->
checkForOverrides
(
$doorId
,
$now
);
if
(
$overrideStatus
===
DoorOverrideCheck
::
OPEN
)
{
return
;
}
if
(
$overrideStatus
===
DoorOverrideCheck
::
CLOSED
)
{
throw
new
AuthorizationException
();
}
/*
* Check for open mode
*/
if
(
$this
->
openModeCheck
->
checkOpenMode
(
$doorId
,
$now
))
{
// No logging needed to be done as we are in open mode. Just return without throwing any exceptions
return
;
}
/*
* Check for user
*/
if
(
!
(
$user
=
$this
->
userCheck
->
checkDoorCode
(
$doorcode
)))
{
$this
->
logDoorAttempt
(
$doorId
);
throw
new
AuthorizationException
();
...
...
@@ -146,6 +177,9 @@ class Access implements AccessUseCase
// throw new AuthorizationException();
// }
/*
* Check for user schedule
*/
if
(
$this
->
scheduleCheck
->
checkScheduleForGroups
(
$groups
,
$now
))
{
// Log the successful entry
$this
->
logUserAccess
(
$doorId
,
$userId
,
true
);
...
...
src/web/backend/src/UseCases/Door/Access/AccessUseCaseServiceProvider.php
View file @
c9728c92
...
...
@@ -8,15 +8,18 @@ use Source\Gateways\Users\UsersRepository;
use
Source\Gateways\Entries\EntriesRepository
;
use
Illuminate\Contracts\Foundation\Application
;
use
Source\Gateways\Attempts\AttemptsRepository
;
use
Source\Gateways\Overrides\OverridesRepository
;
use
Source\Gateways\Schedules\SchedulesRepository
;
use
Illuminate\Contracts\Support\DeferrableProvider
;
use
Source\Gateways\DoorSchedule\DoorScheduleRepository
;
use
Source\Gateways\RecurrenceSet\RecurrenceSetRepository
;
use
Source\UseCases\DoorUserGroup\DoorUserGroupMapUseCase
;
use
Source\UseCases\Door\Access\Authorizers\DoorOpenModeCheck\DoorOpenModeCheck
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
;
use
Source\UseCases\Door\Access\Authorizers\UserDoorcodeCheck\UserDoorcodeCheck
;
use
Source\UseCases\Door\Access\Authorizers\GroupScheduleCheck\GroupScheduleCheck
;
use
Source\UseCases\Door\Access\Authorizers\DoorOpenModeCheck\DefaultDoorOpenModeCheck
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DefaultDoorOverrideCheck
;
use
Source\UseCases\Door\Access\Authorizers\UserDoorcodeCheck\DefaultUserDoorcodeCheck
;
use
Source\UseCases\Door\Access\Authorizers\GroupScheduleCheck\DefaultGroupScheduleCheck
;
...
...
@@ -53,12 +56,17 @@ class AccessUseCaseServiceProvider extends ServiceProvider implements Deferrable
);
});
$this
->
app
->
bind
(
DoorOverrideCheck
::
class
,
static
function
(
Application
$app
)
{
return
new
DefaultDoorOverrideCheck
(
$app
->
make
(
OverridesRepository
::
class
));
});
$this
->
app
->
bind
(
AccessUseCase
::
class
,
static
function
(
Application
$app
)
{
return
new
Access
(
$app
->
make
(
DoorOpenModeCheck
::
class
),
$app
->
make
(
UserDoorcodeCheck
::
class
),
$app
->
make
(
GroupScheduleCheck
::
class
),
$app
->
make
(
DoorUserGroupMapUseCase
::
class
),
$app
->
make
(
DoorOverrideCheck
::
class
),
$app
->
make
(
AttemptsRepository
::
class
),
$app
->
make
(
EntriesRepository
::
class
)
);
...
...
@@ -84,6 +92,7 @@ class AccessUseCaseServiceProvider extends ServiceProvider implements Deferrable
DoorOpenModeCheck
::
class
,
GroupScheduleCheck
::
class
,
UserDoorcodeCheck
::
class
,
DoorOverrideCheck
::
class
,
];
}
}
src/web/backend/src/UseCases/Door/Access/Authorizers/DoorOverrideCheck/DefaultDoorOverrideCheck.php
0 → 100644
View file @
c9728c92
<?php
namespace
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck
;
use
Carbon\Carbon
;
use
Source\Entities\Override
;
use
Source\Gateways\Overrides\OverridesRepository
;
class
DefaultDoorOverrideCheck
implements
DoorOverrideCheck
{
/**
* @var \Source\Gateways\Overrides\OverridesRepository
*/
protected
OverridesRepository
$overrides
;
/**
* @param \Source\Gateways\Overrides\OverridesRepository $overrides
*/
public
function
__construct
(
OverridesRepository
$overrides
)
{
$this
->
overrides
=
$overrides
;
}
/**
* @inheritDoc
*/
public
function
checkForOverrides
(
string
$doorId
,
Carbon
$date
):
int
{
$active
=
$this
->
overrides
->
activeOverrideForDoor
(
$doorId
,
$date
);
if
(
!
$active
)
{
return
DoorOverrideCheck
::
NO_ACTION
;
}
switch
(
$active
->
getType
())
{
case
Override
::
TYPE_LOCKED
:
return
DoorOverrideCheck
::
CLOSED
;
case
Override
::
TYPE_OPEN
:
return
DoorOverrideCheck
::
OPEN
;
default
:
return
DoorOverrideCheck
::
NO_ACTION
;
}
}
}
src/web/backend/src/UseCases/Door/Access/Authorizers/DoorOverrideCheck/DoorOverrideCheck.php
0 → 100644
View file @
c9728c92
<?php
namespace
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck
;
use
Carbon\Carbon
;
interface
DoorOverrideCheck
{
public
const
OPEN
=
0
;
public
const
CLOSED
=
1
;
public
const
NO_ACTION
=
2
;
/**
* Returns one of the constants defined on DoorOverrideCheck
*
* @param string $doorId
* @param \Carbon\Carbon $date
* @return mixed
*/
public
function
checkForOverrides
(
string
$doorId
,
Carbon
$date
):
int
;
}
src/web/backend/tests/Doubles/Access/DoorOverrideCheckStub.php
0 → 100644
View file @
c9728c92
<?php
namespace
Tests\Doubles\Access
;
use
Carbon\Carbon
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
;
class
DoorOverrideCheckStub
implements
DoorOverrideCheck
{
public
int
$return
=
DoorOverrideCheck
::
NO_ACTION
;
/**
* @inheritDoc
*/
public
function
checkForOverrides
(
string
$doorId
,
Carbon
$date
):
int
{
return
$this
->
return
;
}
}
src/web/backend/tests/Unit/Source/UseCases/Door/Access/Authorizers/DoorOverrideCheckTest.php
0 → 100644
View file @
c9728c92
<?php
namespace
Tests\Unit\Source\UseCases\Door\Access\Authorizers
;
use
Carbon\Carbon
;
use
Source\Entities\Override
;
use
PHPUnit\Framework\TestCase
;
use
Source\Gateways\Overrides\InMemoryOverridesRepository
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DefaultDoorOverrideCheck
;
class
DoorOverrideCheckTest
extends
TestCase
{
/**
* @var \Source\Gateways\Overrides\InMemoryOverridesRepository
*/
protected
InMemoryOverridesRepository
$overrides
;
/**
* @var \Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DefaultDoorOverrideCheck
*/
protected
DefaultDoorOverrideCheck
$authorizer
;
public
function
setUp
():
void
{
parent
::
setUp
();
$this
->
overrides
=
new
InMemoryOverridesRepository
();
$this
->
authorizer
=
new
DefaultDoorOverrideCheck
(
$this
->
overrides
);
}
/**
* @test
*/
public
function
no_action_if_no_overrides
():
void
{
$this
->
assertEquals
(
DoorOverrideCheck
::
NO_ACTION
,
$this
->
authorizer
->
checkForOverrides
(
'1'
,
Carbon
::
now
()));
}
/**
* @test
*/
public
function
locks_if_lock_override
():
void
{
$this
->
overrides
->
addOverride
(
new
Override
(
0
,
1
,
1
,
Override
::
TYPE_LOCKED
,
Carbon
::
now
()
->
subMinute
(),
Carbon
::
now
()
->
addMinute
()
));
$this
->
assertEquals
(
DoorOverrideCheck
::
CLOSED
,
$this
->
authorizer
->
checkForOverrides
(
'1'
,
Carbon
::
now
()));
}
/**
* @test
*/
public
function
unlocks_if_open_override
():
void
{
$this
->
overrides
->
addOverride
(
new
Override
(
0
,
1
,
1
,
Override
::
TYPE_OPEN
,
Carbon
::
now
()
->
subMinute
(),
Carbon
::
now
()
->
addMinute
()
));
$this
->
assertEquals
(
DoorOverrideCheck
::
OPEN
,
$this
->
authorizer
->
checkForOverrides
(
'1'
,
Carbon
::
now
()));
}
}
src/web/backend/tests/Unit/Source/UseCases/Door/Access/UseCaseTest.php
View file @
c9728c92
...
...
@@ -11,10 +11,12 @@ use Source\Exceptions\AuthorizationException;
use
Source\Exceptions\AuthenticationException
;
use
Tests\Doubles\Access\DoorUserGroupMapStub
;
use
Tests\Doubles\Access\DoorOpenModeCheckStub
;
use
Tests\Doubles\Access\DoorOverrideCheckStub
;
use
Tests\Doubles\Access\UserDoorcodeCheckStub
;
use
Tests\Doubles\Access\GroupScheduleCheckStub
;
use
Source\Gateways\Entries\InMemoryEntriesRepository
;
use
Source\Gateways\Attempts\InMemoryAttemptsRepository
;
use
Source\UseCases\Door\Access\Authorizers\DoorOverrideCheck\DoorOverrideCheck
;
class
UseCaseTest
extends
TestCase
{
...
...
@@ -57,6 +59,11 @@ class UseCaseTest extends TestCase
*/
protected
DoorUserGroupMapStub
$doorUserGroupMap
;
/**
* @var \Tests\Doubles\Access\DoorOverrideCheckStub
*/
protected
DoorOverrideCheckStub
$overrideCheck
;
public
function
setUp
():
void
{
parent
::
setUp
();
...
...
@@ -64,6 +71,7 @@ class UseCaseTest extends TestCase
$this
->
openModeCheck
=
new
DoorOpenModeCheckStub
();
$this
->
userDoorcodeCheck
=
new
UserDoorcodeCheckStub
();
$this
->
groupScheduleCheck
=
new
GroupScheduleCheckStub
();
$this
->
overrideCheck
=
new
DoorOverrideCheckStub
();
$this
->
doorUserGroupMap
=
new
DoorUserGroupMapStub
();
$this
->
attempts
=
new
InMemoryAttemptsRepository
();
$this
->
entries
=
new
InMemoryEntriesRepository
();
...
...
@@ -72,6 +80,7 @@ class UseCaseTest extends TestCase
$this
->
userDoorcodeCheck
,
$this
->
groupScheduleCheck
,
$this
->
doorUserGroupMap
,
$this
->
overrideCheck
,
$this
->
attempts
,
$this
->
entries
,
);
...
...
@@ -184,4 +193,32 @@ class UseCaseTest extends TestCase
$this
->
assertCount
(
1
,
$this
->
entries
->
all
());
$this
->
assertTrue
(
$this
->
entries
->
all
()[
0
]
->
wasSuccessful
());
}
/**
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\AuthorizationException
*/
public
function
it_respects_lock_override
():
void
{
$this
->
expectException
(
AuthorizationException
::
class
);
$this
->
overrideCheck
->
return
=
DoorOverrideCheck
::
CLOSED
;
$this
->
userDoorcodeCheck
->
setReturnUser
(
self
::
createValidUser
(
'doorcode'
));
$this
->
handleTest
(
self
::
DOOR_ID
,
'doorcode'
);
}
/**
* @test
* @throws \Source\Exceptions\AuthenticationException
* @throws \Source\Exceptions\AuthorizationException
*/
public
function
it_respects_open_override
():
void
{
$this
->
overrideCheck
->
return
=
DoorOverrideCheck
::
OPEN
;
$this
->
handleTest
(
self
::
DOOR_ID
,
''
);
// It does nothing on success, otherwise it throws an exception
$this
->
assertTrue
(
true
);
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment