Skip to content

Commit

Permalink
Added json api role based access.
Browse files Browse the repository at this point in the history
  • Loading branch information
arshadkhan53 committed Jun 12, 2020
1 parent a379bbf commit 1af6fbd
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Jsonapi Role Based Access
type: module
description: 'Provides feature to give or restrict access to jsonapi resources.'
package: Web services
core_version_requirement: ^8 || ^9
configure: ezcontent_jsonapi_role_access.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ezcontent_jsonapi_role_access.config:
path: '/admin/config/ezcontent-jsonapi-role-access/settings'
defaults:
_form: '\Drupal\ezcontent_jsonapi_role_access\Form\JsonapiRoleAccessSettingsForm'
_title: 'Jsonapi Role Based Access Settings'
requirements:
_permission: 'access content'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
ezcontent_jsonapi_role_access.event_subscriber:
class: Drupal\ezcontent_jsonapi_role_access\EventSubscriber\CheckUserRolePermissionEvent
arguments: ['@config.factory']
tags:
- { name: event_subscriber }
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Drupal\ezcontent_jsonapi_role_access\EventSubscriber;

use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Response;

/**
* Checks subscriptions for user role access for json api API keys.
*/
class CheckUserRolePermissionEvent implements EventSubscriberInterface {

/**
* The config object.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $config;

/**
* Drupal\Core\Session\AccountProxy definition.
*
* @var \Drupal\Core\Session\AccountProxy
*/
protected $currentUser;

/**
* Constructs this factory object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory.
*/
public function __construct(ConfigFactoryInterface $configFactory) {
$this->config = $configFactory->get('ezcontent_jsonapi_role_access.settings');
}

/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * ['eventName' => 'methodName']
* * ['eventName' => ['methodName', $priority]]
* * ['eventName' => [['methodName1', $priority], ['methodName2']]]
*
* @return array
* The event names to listen to.
*/
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = ['checkUserRoleAccess', 30];
return $events;
}

/**
* Check if user has subscription, if not redirect to subscription page.
*/
public function checkUserRoleAccess(Event $event) {
if (!$event->getRequest()
->isXmlHttpRequest() && str_starts_with($event->getRequest()
->get('_route'), 'jsonapi')) {
$actionType = $this->config->get('action_type');
$roles = $this->config->get('roles');
$roles = array_filter($roles);
$userRoles = \Drupal::currentUser()->getRoles();
if ($actionType && !empty($roles) && !in_array('administrator', $userRoles)) {
if (($actionType === 'allow' && empty(array_intersect($roles, $userRoles))) || ($actionType === 'restrict' && !empty(array_intersect($roles, $userRoles)))) {
$response = new Response('Access denied', Response::HTTP_FORBIDDEN);
$event->setResponse($response);
}

}

}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace Drupal\ezcontent_jsonapi_role_access\Form;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
* Configure JSON:API user role access settings for this site.
*/
class JsonapiRoleAccessSettingsForm extends ConfigFormBase {

/**
* Config settings.
*
* @var string
*/
const SETTINGS = 'ezcontent_jsonapi_role_access.settings';

/**
* The entityTypeManager object.
*
* @var \Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;

/**
* Constructs a \Drupal\system\ConfigFormBase object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The factory for configuration objects.
* @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
* The entityTypeManager objects.
*/
public function __construct(ConfigFactoryInterface $config_factory, EntityTypeManager $entityTypeManager) {
parent::__construct($config_factory);
$this->entityTypeManager = $entityTypeManager;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory'),
$container->get('entity_type.manager')
);
}

/**
* {@inheritdoc}
*/
public function getFormId() {
return 'ezcontent_jsonapi_role_access_form';
}

/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config(static::SETTINGS);
$roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple();
$rolesOptions = [];
foreach ($roles as $role) {
if ($role->id() != 'administrator') {
$rolesOptions[$role->id()] = $role->id();
}
}
$form['action_type'] = [
'#type' => 'radios',
'#title' => $this->t('Option'),
'#description' => $this->t('Select a action type.'),
'#options' => [
'allow' => $this->t('Allow selected role to access jsonapi resource'),
'restrict' => $this->t('Restrict selected role to not able to access jsonapi resource'),
],
'#default_value' => $config->get('action_type') ? $config->get('action_type') : 'allow',
'#required' => TRUE,
];
$form['roles'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Select User Roles'),
'#description' => $this->t('Select roles for which you want to allow or restrict access to jsonapi resources, (Administrator role has all permissions).'),
'#multiple' => TRUE,
'#options' => $rolesOptions,
'#required' => TRUE,
'#default_value' => $config->get('roles'),
];
return parent::buildForm($form, $form_state);
}

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$config = $this->config(static::SETTINGS);
foreach ($form_state->cleanValues()->getValues() as $key => $value) {
$config->set($key, $value);
}
$config->save();
}

/**
* {@inheritdoc}
*/
protected function getEditableConfigNames() {
return [
static::SETTINGS,
];
}

}

0 comments on commit 1af6fbd

Please sign in to comment.