You are here

FarmScopeRepository.php in farmOS 2.x

File

modules/core/api/src/Repositories/FarmScopeRepository.php
View source
<?php

namespace Drupal\farm_api\Repositories;

use Drupal\simple_oauth\Repositories\ScopeRepository;
use Drupal\user\RoleInterface;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\ScopeEntityInterface;

/**
 * Decorates the simple_oauth ScopeRepository.
 *
 * Alter the default behavior to account for additional consumer config options:
 *   - consumer.grant_user_access: Always grant the user's roles.
 *   - consumer.limit_requested_access: Always limit to the requested scopes.
 *   - consumer.limit_user_access: Always limit access to what the user has.
 *
 * @ingroup farm
 */
class FarmScopeRepository extends ScopeRepository {

  /**
   * {@inheritdoc}
   */
  public function finalizeScopes(array $scopes, $grant_type, ClientEntityInterface $client_entity, $user_identifier = NULL) {

    // Start a list of allowed roles.
    $allowed_roles = [];

    // Load the consumer entity.

    /** @var \Drupal\consumers\Entity\Consumer $client_drupal_entity */
    $consumer_entity = $client_entity
      ->getDrupalEntity();

    // Load role ids of roles the consumer has.
    $consumer_roles = array_map(function ($role) {
      return $role['target_id'];
    }, $consumer_entity
      ->get('roles')
      ->getValue());

    // Include consumer roles.
    // By default all consumer roles are available to authorization.
    $allowed_roles = array_merge($allowed_roles, $consumer_roles);

    // Load the default user associated with the consumer.
    // This is an optional setting, so it may not exist.
    $default_user = NULL;
    try {
      $default_user = $client_entity
        ->getDrupalEntity()
        ->get('user_id')->entity;
    } catch (\InvalidArgumentException $e) {

      // Do nothing.
    }

    // Load the user associated with the token.
    // If there is no user, use the default user.

    /** @var \Drupal\user\UserInterface $user */
    $user = $user_identifier ? $this->entityTypeManager
      ->getStorage('user')
      ->load($user_identifier) : $default_user;
    if (!$user) {
      return [];
    }

    // Load the user's roles.
    // Load all roles for user 1 so they can be granted all possible scopes.
    if ((int) $user
      ->id() === 1) {
      $user_roles = array_map(function (RoleInterface $role) {
        return $role
          ->id();
      }, $this->entityTypeManager
        ->getStorage('user_role')
        ->loadMultiple());
    }
    else {
      $user_roles = $user
        ->getRoles();
    }

    // Include the user's roles if enabled.
    if ($consumer_entity
      ->get('grant_user_access')->value) {
      $allowed_roles = array_merge($allowed_roles, $user_roles);
    }

    /* Limit the roles granted to the token. */

    // Limit to requested roles if enabled.
    if ($consumer_entity
      ->get('limit_requested_access')->value) {

      // Save the requested scopes (roles) that were passed to this
      // finalizeScopes() method.
      $requested_roles = array_map(function (ScopeEntityInterface $scope) {
        return $scope
          ->getIdentifier();
      }, $scopes);

      // Reduce the requested roles to only those in allowed roles.
      // This prevents additional roles being granted than the user
      // and consumer have available.
      $allowed_requested_roles = array_filter($requested_roles, function ($role_id) use ($allowed_roles) {
        return in_array($role_id, $allowed_roles);
      });

      // Filter the allowed roles to only those requested.
      $allowed_roles = array_intersect($allowed_roles, $allowed_requested_roles);
    }

    // Limit to roles the user already has, if enabled.
    if ($consumer_entity
      ->get('limit_user_access')->value) {
      $allowed_roles = array_intersect($allowed_roles, $user_roles);
    }

    // Always include the authenticated role.
    $allowed_roles[] = RoleInterface::AUTHENTICATED_ID;

    // Build a new list of ScopeEntityInterface to return.
    $scopes = [];
    foreach ($allowed_roles as $role_id) {
      $scopes = $this
        ->addRoleToScopes($scopes, $role_id);
    }
    return $scopes;
  }

}

Classes

Namesort descending Description
FarmScopeRepository Decorates the simple_oauth ScopeRepository.