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
ccf0d6f1
Commit
ccf0d6f1
authored
Mar 07, 2020
by
Jacob Priddy
👌
Browse files
overhaul some permissions stuff
parent
62dc4fe8
Pipeline
#2922
passed with stages
in 2 minutes and 1 second
Changes
32
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/web/backend/app/Providers/BroadcastServiceProvider.php
deleted
100644 → 0
View file @
62dc4fe8
<?php
namespace
App\Providers
;
use
Illuminate\Support\ServiceProvider
;
use
Illuminate\Support\Facades\Broadcast
;
class
BroadcastServiceProvider
extends
ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public
function
boot
()
{
Broadcast
::
routes
();
require
base_path
(
'routes/channels.php'
);
}
}
src/web/backend/routes/channels.php
deleted
100644 → 0
View file @
62dc4fe8
<?php
/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast
::
channel
(
'App.User.{id}'
,
function
(
$user
,
$id
)
{
return
(
int
)
$user
->
id
===
(
int
)
$id
;
});
src/web/backend/src/Authorization/ApiAuthorizer.php
View file @
ccf0d6f1
...
...
@@ -5,6 +5,7 @@ namespace Source\Authorization;
use
Illuminate\Contracts\Auth\Guard
;
use
Source\Exceptions\AuthorizationException
;
use
Source\Exceptions\EntityNotFoundException
;
use
Source\Gateways\GroupUser\GroupUserRepository
;
class
ApiAuthorizer
implements
Authorizer
...
...
@@ -67,7 +68,17 @@ class ApiAuthorizer implements Authorizer
return
[];
}
return
static
::
groupNames
(
$this
->
groupUserRepository
->
getGroupsForUser
(
$user
));
return
$this
->
getGroupsForUser
(
$user
);
}
/**
* @param string $userId
* @return string[]
* @throws \Source\Exceptions\EntityNotFoundException
*/
protected
function
getGroupsForUser
(
string
$userId
):
array
{
return
static
::
groupNames
(
$this
->
groupUserRepository
->
getGroupsForUser
(
$userId
));
}
/**
...
...
@@ -114,4 +125,46 @@ class ApiAuthorizer implements Authorizer
return
false
;
}
/**
* @inheritDoc
*/
public
function
protect
(
string
$permission
):
void
{
$this
->
protectAll
([
$permission
]);
}
/**
* @inheritDoc
*/
public
function
protectAdminRights
(
string
$userId
,
?string
$groupId
=
null
):
void
{
$user
=
$this
->
groupUserRepository
->
getUser
(
$userId
);
if
(
!
$user
)
{
throw
new
EntityNotFoundException
(
'User not found.'
);
}
$groups
=
$this
->
getGroupsForUser
(
$userId
);
// Only admins have access to other admins
if
(
in_array
(
Permissions
::
ADMIN
,
$groups
,
true
))
{
$this
->
protect
(
Permissions
::
ADMIN
);
}
if
(
$groupId
)
{
$group
=
$this
->
groupUserRepository
->
getGroup
(
$groupId
);
if
(
!
$group
)
{
throw
new
EntityNotFoundException
(
'Group not found.'
);
}
// Only admins can create or remove other admins
if
(
$group
->
hasTitleOf
(
Permissions
::
ADMIN
))
{
$this
->
protect
(
Permissions
::
ADMIN
);
}
}
if
(
$user
->
hasFirstNameOf
(
'admin'
))
{
throw
new
AuthorizationException
(
'You cannot modify the admin user.'
);
}
}
}
src/web/backend/src/Authorization/Authorizer.php
View file @
ccf0d6f1
...
...
@@ -42,4 +42,24 @@ interface Authorizer
* @throws \Source\Exceptions\EntityNotFoundException
*/
public
function
protectOne
(
array
$permissions
):
void
;
/**
* Permissions to check against from \Source\Authorization\Permissions
* The user needs the permission
*
* @param string $permission
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public
function
protect
(
string
$permission
):
void
;
/**
* Protects the admin user from being modified.
*
* @param string $userId
* @param string|null $groupId
* @throws \Source\Exceptions\AuthorizationException
* @throws \Source\Exceptions\EntityNotFoundException
*/
public
function
protectAdminRights
(
string
$userId
,
?string
$groupId
=
null
):
void
;
}
src/web/backend/src/Authorization/AuthorizerServiceProvider.php
View file @
ccf0d6f1
...
...
@@ -21,7 +21,7 @@ class AuthorizerServiceProvider extends ServiceProvider implements DeferrablePro
*/
public
function
register
()
{
$this
->
app
->
b
in
d
(
Authorizer
::
class
,
static
function
(
Application
$app
)
{
$this
->
app
->
s
in
gleton
(
Authorizer
::
class
,
static
function
(
Application
$app
)
{
return
new
ApiAuthorizer
(
$app
->
make
(
ApiGuard
::
class
),
$app
->
make
(
GroupUserRepository
::
class
));
});
}
...
...
src/web/backend/src/Authorization/Permissions.php
View file @
ccf0d6f1
...
...
@@ -10,4 +10,5 @@ class Permissions
public
const
MANAGE_DOORS
=
'manage-doors'
;
public
const
MANAGE_GROUPS
=
'manage-groups'
;
public
const
CODE_QUERY
=
'code-query'
;
public
const
CURRENT_USER
=
'current-user'
;
}
src/web/backend/src/Entities/User.php
View file @
ccf0d6f1
...
...
@@ -236,4 +236,22 @@ class User
{
return
$this
->
getEmail
()
===
strtolower
(
$email
);
}
public
function
hasFirstNameOf
(
?string
$name
):
bool
{
if
(
!
$name
)
{
return
false
;
}
return
$this
->
getFirstName
()
===
$name
;
}
public
function
is
(
?User
$user
):
bool
{
if
(
!
$user
)
{
return
null
;
}
return
$this
->
hasEmailOf
(
$user
);
}
}
src/web/backend/src/Gateways/GroupUser/DatabaseGroupUserRepository.php
View file @
ccf0d6f1
...
...
@@ -55,8 +55,12 @@ class DatabaseGroupUserRepository implements GroupUserRepository
/** @var Group|null $group */
$group
=
Group
::
find
((
int
)
$groupId
);
if
(
!
$user
||
!
$group
)
{
throw
new
EntityNotFoundException
();
if
(
!
$user
)
{
throw
new
EntityNotFoundException
(
'User not found.'
);
}
if
(
!
$group
)
{
throw
new
EntityNotFoundException
(
'Group not found.'
);
}
$user
->
groups
()
->
attach
(
$groupId
);
...
...
@@ -72,10 +76,38 @@ class DatabaseGroupUserRepository implements GroupUserRepository
/** @var Group|null $group */
$group
=
Group
::
find
((
int
)
$groupId
);
if
(
!
$user
||
!
$group
)
{
throw
new
EntityNotFoundException
();
if
(
!
$user
)
{
throw
new
EntityNotFoundException
(
'User not found.'
);
}
if
(
!
$group
)
{
throw
new
EntityNotFoundException
(
'Group not found.'
);
}
$user
->
groups
()
->
detach
(
$groupId
);
}
/**
* @inheritDoc
*/
public
function
getGroup
(
string
$groupId
):
?
\
Source\Entities\Group
{
if
(
$g
=
Group
::
find
((
int
)
$groupId
))
{
return
DatabaseGroupsRepository
::
makeGroupFromDbGroup
(
$g
);
}
return
null
;
}
/**
* @inheritDoc
*/
public
function
getUser
(
string
$userId
):
?
\
Source\Entities\User
{
if
(
$user
=
User
::
find
((
int
)
$userId
))
{
return
DatabaseUsersRepository
::
makeUserFromDbUser
(
$user
);
}
return
null
;
}
}
src/web/backend/src/Gateways/GroupUser/GroupUserRepository.php
View file @
ccf0d6f1
...
...
@@ -3,6 +3,9 @@
namespace
Source\Gateways\GroupUser
;
use
Source\Entities\User
;
use
Source\Entities\Group
;
interface
GroupUserRepository
{
/**
...
...
@@ -32,4 +35,16 @@ interface GroupUserRepository
* @throws \Source\Exceptions\EntityNotFoundException
*/
public
function
removeUserFromGroup
(
string
$userId
,
string
$groupId
):
void
;
/**
* @param string $groupId
* @return \Source\Entities\Group|null
*/
public
function
getGroup
(
string
$groupId
):
?Group
;
/**
* @param string $userId
* @return \Source\Entities\User|null
*/
public
function
getUser
(
string
$userId
):
?User
;
}
src/web/backend/src/Gateways/GroupUser/InMemoryGroupUserRepository.php
View file @
ccf0d6f1
...
...
@@ -3,6 +3,8 @@
namespace
Source\Gateways\GroupUser
;
use
Source\Entities\User
;
use
Source\Entities\Group
;
use
Source\Gateways\Users\UsersRepository
;
use
Source\Gateways\Groups\GroupsRepository
;
use
Source\Exceptions\EntityNotFoundException
;
...
...
@@ -111,4 +113,20 @@ class InMemoryGroupUserRepository implements GroupUserRepository
);
}
}
/**
* @inheritDoc
*/
public
function
getGroup
(
string
$groupId
):
?Group
{
return
$this
->
groups
->
get
(
$groupId
);
}
/**
* @inheritDoc
*/
public
function
getUser
(
string
$userId
):
?User
{
return
$this
->
users
->
get
(
$userId
);
}
}
src/web/backend/src/Gateways/Users/InMemoryUsersRepository.php
View file @
ccf0d6f1
...
...
@@ -122,14 +122,6 @@ class InMemoryUsersRepository implements UsersRepository
return
null
;
}
/**
* Clears the repository
*/
public
function
clear
():
void
{
$this
->
users
=
[];
}
/**
* @inheritDoc
*/
...
...
src/web/backend/src/UseCases/GroupUser/AddUserToGroup/AddUserToGroup.php
View file @
ccf0d6f1
...
...
@@ -2,6 +2,7 @@
namespace
Source\UseCases\GroupUser\AddUserToGroup
;
use
Source\Authorization\Authorizer
;
use
Source\Gateways\GroupUser\GroupUserRepository
;
class
AddUserToGroup
implements
AddUserToGroupUseCase
...
...
@@ -11,9 +12,19 @@ class AddUserToGroup implements AddUserToGroupUseCase
*/
protected
GroupUserRepository
$repository
;
public
function
__construct
(
GroupUserRepository
$repository
)
/**
* @var \Source\Authorization\Authorizer
*/
protected
Authorizer
$authorizer
;
/**
* @param \Source\Authorization\Authorizer $authorizer
* @param \Source\Gateways\GroupUser\GroupUserRepository $repository
*/
public
function
__construct
(
Authorizer
$authorizer
,
GroupUserRepository
$repository
)
{
$this
->
repository
=
$repository
;
$this
->
authorizer
=
$authorizer
;
}
/**
...
...
@@ -21,6 +32,8 @@ class AddUserToGroup implements AddUserToGroupUseCase
*/
public
function
addUserToGroup
(
string
$userId
,
string
$groupId
,
Presenter
$presenter
):
void
{
$this
->
authorizer
->
protectAdminRights
(
$userId
,
$groupId
);
$this
->
repository
->
addUserToGroup
(
$userId
,
$groupId
);
$responseModel
=
new
ResponseModel
(
'Success'
);
...
...
src/web/backend/src/UseCases/GroupUser/AddUserToGroup/AddUserToGroupUseCase.php
View file @
ccf0d6f1
...
...
@@ -10,6 +10,7 @@ interface AddUserToGroupUseCase
* @param string $groupId
* @param \Source\UseCases\GroupUser\AddUserToGroup\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\AuthorizationException
*/
public
function
addUserToGroup
(
string
$userId
,
string
$groupId
,
Presenter
$presenter
):
void
;
}
src/web/backend/src/UseCases/GroupUser/AddUserToGroup/AddUserToGroupUseCaseServiceProvider.php
View file @
ccf0d6f1
...
...
@@ -3,6 +3,7 @@
namespace
Source\UseCases\GroupUser\AddUserToGroup
;
use
Source\Authorization\Authorizer
;
use
Illuminate\Support\ServiceProvider
;
use
Illuminate\Contracts\Foundation\Application
;
use
Source\Gateways\GroupUser\GroupUserRepository
;
...
...
@@ -21,7 +22,7 @@ class AddUserToGroupUseCaseServiceProvider extends ServiceProvider implements De
public
function
register
()
{
$this
->
app
->
bind
(
AddUserToGroupUseCase
::
class
,
static
function
(
Application
$app
)
{
return
new
AddUserToGroup
(
$app
->
make
(
GroupUserRepository
::
class
));
return
new
AddUserToGroup
(
$app
->
make
(
Authorizer
::
class
),
$app
->
make
(
GroupUserRepository
::
class
));
});
}
...
...
src/web/backend/src/UseCases/GroupUser/RemoveUserFromGroup/RemoveUserFromGroup.php
View file @
ccf0d6f1
...
...
@@ -2,6 +2,7 @@
namespace
Source\UseCases\GroupUser\RemoveUserFromGroup
;
use
Source\Authorization\Authorizer
;
use
Source\Gateways\GroupUser\GroupUserRepository
;
class
RemoveUserFromGroup
implements
RemoveUserFromGroupUseCase
...
...
@@ -11,9 +12,15 @@ class RemoveUserFromGroup implements RemoveUserFromGroupUseCase
*/
protected
GroupUserRepository
$repository
;
public
function
__construct
(
GroupUserRepository
$repository
)
/**
* @var \Source\Authorization\Authorizer
*/
protected
Authorizer
$authorizer
;
public
function
__construct
(
Authorizer
$authorizer
,
GroupUserRepository
$repository
)
{
$this
->
repository
=
$repository
;
$this
->
authorizer
=
$authorizer
;
}
/**
...
...
@@ -21,6 +28,8 @@ class RemoveUserFromGroup implements RemoveUserFromGroupUseCase
*/
public
function
removeUserFromGroup
(
string
$userId
,
string
$groupId
,
Presenter
$presenter
):
void
{
$this
->
authorizer
->
protectAdminRights
(
$userId
,
$groupId
);
$this
->
repository
->
removeUserFromGroup
(
$userId
,
$groupId
);
$responseModel
=
new
ResponseModel
(
'Success'
);
...
...
src/web/backend/src/UseCases/GroupUser/RemoveUserFromGroup/RemoveUserFromGroupUseCase.php
View file @
ccf0d6f1
...
...
@@ -6,10 +6,13 @@ namespace Source\UseCases\GroupUser\RemoveUserFromGroup;
interface
RemoveUserFromGroupUseCase
{
/**
* Only Admins can add or remove other admins, but the overall admin user's groups cannot be modified
*
* @param string $userId
* @param string $groupId
* @param \Source\UseCases\GroupUser\RemoveUserFromGroup\Presenter $presenter
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\AuthorizationException
*/
public
function
removeUserFromGroup
(
string
$userId
,
string
$groupId
,
Presenter
$presenter
):
void
;
}
src/web/backend/src/UseCases/GroupUser/RemoveUserFromGroup/RemoveUserFromGroupUseCaseServiceProvider.php
View file @
ccf0d6f1
...
...
@@ -3,6 +3,7 @@
namespace
Source\UseCases\GroupUser\RemoveUserFromGroup
;
use
Source\Authorization\Authorizer
;
use
Illuminate\Support\ServiceProvider
;
use
Illuminate\Contracts\Foundation\Application
;
use
Source\Gateways\GroupUser\GroupUserRepository
;
...
...
@@ -21,7 +22,7 @@ class RemoveUserFromGroupUseCaseServiceProvider extends ServiceProvider implemen
public
function
register
()
{
$this
->
app
->
bind
(
RemoveUserFromGroupUseCase
::
class
,
static
function
(
Application
$app
)
{
return
new
RemoveUserFromGroup
(
$app
->
make
(
GroupUserRepository
::
class
));
return
new
RemoveUserFromGroup
(
$app
->
make
(
Authorizer
::
class
),
$app
->
make
(
GroupUserRepository
::
class
));
});
}
...
...
src/web/backend/src/UseCases/Groups/UpdateGroup/UpdateGroup.php
View file @
ccf0d6f1
...
...
@@ -3,6 +3,7 @@
namespace
Source\UseCases\Groups\UpdateGroup
;
use
Source\Entities\Group
;
use
Source\Authorization\Permissions
;
use
Source\Gateways\Groups\GroupsRepository
;
use
Source\Exceptions\EntityNotFoundException
;
...
...
@@ -32,9 +33,19 @@ class UpdateGroup implements UpdateGroupUseCase
throw
new
EntityNotFoundException
();
}
$reflection
=
new
\
ReflectionClass
(
Permissions
::
class
);
if
(
in_array
(
$group
->
getTitle
(),
$reflection
->
getConstants
(),
true
))
{
// Cannot modify default permission group title
$groupTitle
=
$group
->
getTitle
();
}
else
{
$groupTitle
=
$attributes
[
'title'
];
}
$newGroup
=
new
Group
(
$group
->
getId
(),
$
attributes
[
't
itle
'
]
,
$
groupT
itle
,
$attributes
[
'description'
]
);
...
...
src/web/backend/src/UseCases/Users/DeleteUser/DeleteUser.php
View file @
ccf0d6f1
...
...
@@ -2,6 +2,7 @@
namespace
Source\UseCases\Users\DeleteUser
;
use
Source\Authorization\Authorizer
;
use
Source\Gateways\Users\UsersRepository
;
use
Source\Exceptions\DeleteFailedException
;
use
Source\Exceptions\EntityNotFoundException
;
...
...
@@ -13,8 +14,14 @@ class DeleteUser implements DeleteUserUseCase
*/
protected
UsersRepository
$usersRepository
;
public
function
__construct
(
UsersRepository
$usersRepository
)
/**
* @var \Source\Authorization\Authorizer
*/
protected
Authorizer
$authorizer
;
public
function
__construct
(
Authorizer
$authorizer
,
UsersRepository
$usersRepository
)
{
$this
->
authorizer
=
$authorizer
;
$this
->
usersRepository
=
$usersRepository
;
}
...
...
@@ -23,16 +30,14 @@ class DeleteUser implements DeleteUserUseCase
*/
public
function
delete
(
string
$userId
,
Presenter
$presenter
):
void
{
$this
->
authorizer
->
protectAdminRights
(
$userId
);
$user
=
$this
->
usersRepository
->
get
(
$userId
);
if
(
!
$user
)
{
throw
new
EntityNotFoundException
();
}
if
(
$user
->
getFirstName
()
===
'admin'
)
{
throw
new
DeleteFailedException
(
'Cannot delete super admin user.'
);
}
if
(
!
$this
->
usersRepository
->
delete
(
$userId
))
{
throw
new
DeleteFailedException
(
'Unable to delete user.'
);
}
...
...
src/web/backend/src/UseCases/Users/DeleteUser/DeleteUserUseCase.php
View file @
ccf0d6f1
...
...
@@ -10,6 +10,7 @@ interface DeleteUserUseCase
* @param \Source\UseCases\Users\DeleteUser\Presenter $presenter
* @throws \Source\Exceptions\DeleteFailedException
* @throws \Source\Exceptions\EntityNotFoundException
* @throws \Source\Exceptions\AuthorizationException
*/
public
function
delete
(
string
$userId
,
Presenter
$presenter
):
void
;
}
Prev
1
2
Next
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