Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add permission to only view current users API authorizations #1516

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions app/modules/web/Controllers/AuthTokenController.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ final class AuthTokenController extends ControllerBase implements CrudController
*/
protected $authTokenService;

/**
* @var UserService
*/
protected $userService;

/**
* Search action
*
Expand Down Expand Up @@ -152,10 +157,16 @@ protected function setViewData($authTokenId = null)
$this->view->addTemplate('auth_token', 'itemshow');

$authToken = $authTokenId ? $this->authTokenService->getById($authTokenId) : new AuthTokenData();

$this->view->assign('authToken', $authToken);

$this->view->assign('users', SelectItemAdapter::factory(UserService::getItemsBasic())->getItemsFromModelSelected([$authToken->getUserId()]));
if($this->acl->checkUserAccess(Acl::AUTHTOKEN_ONLY_USER) && !$this->session->getUserData()->getIsAdminApp()) {
$tokenUserId = $this->session->getUserData()->getId();
$selectItems = [$this->userService->getById($tokenUserId)];
} else {
$selectItems = UserService::getItemsBasic();
}

$this->view->assign('users', SelectItemAdapter::factory($selectItems)->getItemsFromModelSelected([$authToken->getUserId()]));
$this->view->assign('actions', SelectItemAdapter::factory(AuthTokenService::getTokenActions())->getItemsFromArraySelected([$authToken->getActionId()]));

$this->view->assign('nextAction', Acl::getActionRoute(Acl::ACCESS_MANAGE));
Expand All @@ -182,8 +193,9 @@ public function editAction($id)
{
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$tokenUserId = $this->authTokenService->getById($id)->getUserId();

if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT)) {
if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT) || !$this->authTokenOnlyUser($tokenUserId)) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
}

Expand Down Expand Up @@ -217,8 +229,9 @@ public function deleteAction($id = null)
{
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$tokenUserId = $this->authTokenService->getById($id)->getUserId();

if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_DELETE)) {
if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_DELETE) || !$this->authTokenOnlyUser($tokenUserId)) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
}

Expand Down Expand Up @@ -264,14 +277,16 @@ public function saveCreateAction()
{
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$tokenUserId = $this->session->getUserData()->getId();

if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_CREATE)) {
if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_CREATE) || (!$this->session->getUserData()->getIsAdminApp() && $tokenUserId !== $this->request->analyzeInt('users'))) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
}


$form = new AuthTokenForm($this->dic);
$form->validate(Acl::AUTHTOKEN_CREATE);
$form->validate(Acl::AUTHTOKEN_ONLY_USER);

$apiTokenData = $form->getItemData();

Expand Down Expand Up @@ -304,12 +319,12 @@ public function saveEditAction($id)
{
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$tokenUserId = $this->authTokenService->getById($id)->getUserId();

if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT)) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_EDIT) || !$this->authTokenOnlyUser($tokenUserId)) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
}


$form = new AuthTokenForm($this->dic, $id);
$form->validate(Acl::AUTHTOKEN_EDIT);

Expand Down Expand Up @@ -358,8 +373,9 @@ public function viewAction($id)
{
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$tokenUserId = $this->authTokenService->getById($id)->getUserId();

if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_VIEW)) {
if (!$this->acl->checkUserAccess(Acl::AUTHTOKEN_VIEW) || !$this->authTokenOnlyUser($tokenUserId)) {
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('You don\'t have permission to do this operation'));
}

Expand Down Expand Up @@ -398,5 +414,10 @@ protected function initialize()
$this->checkLoggedIn();

$this->authTokenService = $this->dic->get(AuthTokenService::class);
$this->userService = $this->dic->get(UserService::class);
}

protected function authTokenOnlyUser($tokenUserId) {
return $this->session->getUserData()->getIsAdminApp() || ($this->acl->checkUserAccess(Acl::AUTHTOKEN_ONLY_USER) && $tokenUserId == $this->session->getUserData()->getId());
}
}
}
1 change: 1 addition & 0 deletions app/modules/web/Forms/UserProfileForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ protected function analyzeRequestData()
$profileData->setMgmGroups($this->request->analyzeBool('profile_groups', false));
$profileData->setMgmProfiles($this->request->analyzeBool('profile_profiles', false));
$profileData->setMgmApiTokens($this->request->analyzeBool('profile_apitokens', false));
$profileData->setMgmApiOnlyUser($this->request->analyzeBool('profile_mgmapionlyuser', false));
$profileData->setMgmPublicLinks($this->request->analyzeBool('profile_publinks', false));
$profileData->setMgmAccounts($this->request->analyzeBool('profile_accounts', false));
$profileData->setMgmFiles($this->request->analyzeBool('profile_files', false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,24 @@ $profileData = $_getvar('profileData');
</span>
</li>

<li class="mdl-list__item mdl-list__item--two-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">vpn_key</i>
<span><?php echo __('API Authorization only for current user'); ?></span>
<span class="mdl-list__item-sub-title"><?php echo __('Will allow to show only API Authorizations for current user'); ?></span>
</span>

<span class="mdl-list__item-secondary-action">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect"
for="profile_mgmapionlyuser">
<input type="checkbox"
id="profile_mgmapionlyuser"
class="mdl-switch__input"
name="profile_mgmapionlyuser" <?php echo $profileData->isMgmApiOnlyUser() ? 'CHECKED' : ''; ?> <?php echo $_getvar('disabled'); ?>/>
</label>
</span>
</li>

<li class="mdl-list__item mdl-list__item--two-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">vpn_key</i>
Expand Down
2 changes: 2 additions & 0 deletions lib/SP/Core/Acl/Acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ public function checkUserAccess($action, $userId = 0)
case self::AUTHTOKEN_EDIT:
case self::AUTHTOKEN_DELETE:
return $userProfile->isMgmApiTokens();
case self::AUTHTOKEN_ONLY_USER:
return $userProfile->isMgmApiOnlyUser();
case self::ITEMPRESET:
case self::ITEMPRESET_SEARCH:
case self::ITEMPRESET_VIEW:
Expand Down
3 changes: 2 additions & 1 deletion lib/SP/Core/Acl/ActionsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ interface ActionsInterface
const AUTHTOKEN_CREATE = 1004;
const AUTHTOKEN_EDIT = 1005;
const AUTHTOKEN_DELETE = 1006;
const AUTHTOKEN_ONLY_USER = 1007;
const PLUGIN = 1101;
const PLUGIN_SEARCH = 1102;
const PLUGIN_VIEW = 1103;
Expand Down Expand Up @@ -186,4 +187,4 @@ interface ActionsInterface
const SECURITY_MANAGE = 5003;
const USERSETTINGS = 5010;
const USERSETTINGS_GENERAL = 5011;
}
}
24 changes: 24 additions & 0 deletions lib/SP/DataModel/ProfileData.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ class ProfileData
* @var bool
*/
protected $mgmApiTokens = false;
/**
* @var bool
*/
protected $mgmApiOnlyUser = false;
/**
* @var bool
*/
Expand Down Expand Up @@ -754,6 +758,26 @@ public function setAccPrivateGroup($accPrivateGroup)
return $this;
}

/**
* @return boolean
*/
public function isMgmApiOnlyUser()
{
return $this->mgmApiOnlyUser;
}

/**
* @param boolean $mgmApiOnlyUser
*
* @return ProfileData
*/
public function setMgmApiOnlyUser($mgmApiOnlyUser)
{
$this->mgmApiOnlyUser = $mgmApiOnlyUser;

return $this;
}

/**
* @return $this
*/
Expand Down
6 changes: 5 additions & 1 deletion lib/SP/Repositories/AuthToken/AuthTokenRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ public function search(ItemSearchData $itemSearchData)
$queryData->setFrom('AuthToken
INNER JOIN User ON AuthToken.userid = User.id');

if($this->context->getUserProfile()->isMgmApiOnlyUser() && !$this->context->getUserData()->getIsAdminApp()) {
$queryData->setWhere('User.id = ' . $this->context->getUserData()->getId());
}

if ($itemSearchData->getSeachString() !== '') {
$queryData->setWhere('User.login LIKE ? OR User.name LIKE ?');

Expand Down Expand Up @@ -467,4 +471,4 @@ public function getTokenByToken($actionId, $token)

return $this->db->doSelect($queryData);
}
}
}