Skip to content

Commit

Permalink
Issue CollaboraOnline#27: Split access checking into a service.
Browse files Browse the repository at this point in the history
  • Loading branch information
donquixote committed Sep 9, 2024
1 parent a259820 commit 27e8137
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
6 changes: 6 additions & 0 deletions collabora_online.services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
_defaults:
autoconfigure: true
autowire: true
Drupal\collabora_online\Access\CollaboraAccessCheck: { }

42 changes: 42 additions & 0 deletions src/Access/CollaboraAccessCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Drupal\collabora_online\Access;

use Drupal\Core\Session\AccountInterface;

/**
* Access handler for Collabora routes and operations.
*
* @see \Drupal\media\MediaAccessControlHandler
*/
class CollaboraAccessCheck {

/**
* Determines access for a Collabora operation.
*
* @param string $operation
* The operation to perform with a media in Collabora.
* One of 'preview' or 'edit'.
* @param \Drupal\Core\Session\AccountInterface $account
* User account to check access for.
*
* @return bool
* TRUE to grant access, FALSE to deny it.
*
* @todo Add fine-grained permissions per media type.
* @todo Return an access result object.
*/
public function mediaAccess(
string $operation,
AccountInterface $account,
): bool {
$permission = match ($operation) {
'preview' => 'preview any media in collabora',
'edit' => 'edit any media in collabora',
};
return $account->hasPermission($permission);
}

}
6 changes: 4 additions & 2 deletions src/Controller/ViewerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Drupal\collabora_online\Controller;

use Drupal\collabora_online\Access\CollaboraAccessCheck;
use Drupal\collabora_online\Cool\CoolUtils;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Render\RendererInterface;
Expand All @@ -27,6 +28,7 @@ class ViewerController extends ControllerBase {
*/
public function __construct(
private readonly RendererInterface $renderer,
private readonly CollaboraAccessCheck $accessCheck,
) {}

/**
Expand All @@ -43,7 +45,7 @@ public function editor(Media $media, $edit = false) {

$user = \Drupal::currentUser();

if (!$user->hasPermission('preview media in collabora')) {
if (!$this->accessCheck->mediaAccess('preview', $user)) {
$error_msg = 'Authentication failed.';
\Drupal::logger('cool')->error($error_msg);
return new Response(
Expand All @@ -54,7 +56,7 @@ public function editor(Media $media, $edit = false) {
}

/* Make sure that the user is a collaborator if edit is true */
$edit = $edit && $user->hasPermission('edit any media in collabora');
$edit = $edit && $this->accessCheck->mediaAccess('edit', $user);

$render_array = CoolUtils::getViewerRender($media, $edit, $options);

Expand Down
13 changes: 12 additions & 1 deletion src/Controller/WopiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Drupal\collabora_online\Controller;

use Drupal\collabora_online\Access\CollaboraAccessCheck;
use Drupal\collabora_online\Cool\CoolUtils;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\File\FileSystemInterface;
Expand All @@ -25,6 +26,16 @@
*/
class WopiController extends ControllerBase {

/**
* Constructor.
*
* @param \Drupal\collabora_online\Access\CollaboraAccessCheck $accessCheck
* Collabora access checker.
*/
public function __construct(
private readonly CollaboraAccessCheck $accessCheck,
) {}

static function permissionDenied() {
return new Response(
'Authentication failed.',
Expand All @@ -46,7 +57,7 @@ function wopiCheckFileInfo(string $id, Request $request) {
$user = User::load($jwt_payload->uid);
$can_write = $jwt_payload->wri;

if ($can_write && !$user->hasPermission('edit any media in collabora')) {
if ($can_write && !$this->accessCheck->mediaAccess('edit', $user)) {
\Drupal::logger('cool')->error('Token and user permissions do not match.');
return static::permissionDenied();
}
Expand Down

0 comments on commit 27e8137

Please sign in to comment.