diff --git a/.github/workflows/back-to-dev.yml b/.github/workflows/back-to-dev.yml deleted file mode 100644 index abe8a4f..0000000 --- a/.github/workflows/back-to-dev.yml +++ /dev/null @@ -1,17 +0,0 @@ -# .github/workflows/release.yml -name: Back to dev -on: - release: - types: [created] -jobs: - phpunit: - name: PHPUnit Coverage Tests - runs-on: ubuntu-latest - container: - image: pookmish/drupal8ci:latest - steps: - - uses: actions/checkout@v3 - - name: Back to Dev - run: | - composer global require su-sws/stanford-caravan:dev-8.x-2.x - ~/.composer/vendor/bin/sws-caravan back-to-dev $GITHUB_REF $GITHUB_WORKSPACE main diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d902f6..0845ddb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,11 +8,21 @@ on: jobs: build: runs-on: ubuntu-latest + if: github.event.pull_request.merged steps: - name: Tag + id: tag uses: K-Phoen/semver-release-action@master with: release_branch: main tag_format: "%major%.%minor%.%patch%" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v3 + with: + ref: 'main' + - name: Back to Dev + if: ${{ steps.tag.outputs.tag }} + run: | + composer global require su-sws/stanford-caravan:dev-8.x-2.x + ~/.composer/vendor/bin/sws-caravan back-to-dev $GITHUB_REF $GITHUB_WORKSPACE main diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc1636..5536fe6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Stanford Fields +8.2.1 +-------------------------------------------------------------------------------- +_Release Date: 2022-10-19_ + +- Added access check to hide the "Outline" tab from book module. + 8.2.0 -------------------------------------------------------------------------------- _Release Date: 2022-10-13_ diff --git a/src/Routing/StanfordFieldsRouteSubscriber.php b/src/Routing/StanfordFieldsRouteSubscriber.php index a816cd1..aa0dc57 100644 --- a/src/Routing/StanfordFieldsRouteSubscriber.php +++ b/src/Routing/StanfordFieldsRouteSubscriber.php @@ -18,6 +18,10 @@ protected function alterRoutes(RouteCollection $collection) { if ($route = $collection->get('book.admin_edit')) { $route->setDefault('_form', '\Drupal\stanford_fields\Form\StanfordFieldBookAdminEditForm'); } + + if ($route = $collection->get('entity.node.book_outline_form')) { + $route->setRequirement('_custom_access', 'book.manager:checkBookOutlineAccess'); + } } } diff --git a/src/Service/StanfordFieldsBookManager.php b/src/Service/StanfordFieldsBookManager.php index fa1d2e2..b7f4720 100644 --- a/src/Service/StanfordFieldsBookManager.php +++ b/src/Service/StanfordFieldsBookManager.php @@ -5,7 +5,10 @@ use Drupal\book\BookManagerInterface; use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\SortArray; +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; @@ -29,8 +32,10 @@ class StanfordFieldsBookManager implements BookManagerInterface { * Config factory service. * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher * Event dispatcher service. + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * Entity type manager service. */ - public function __construct(protected BookManagerInterface $bookManager, protected ConfigFactoryInterface $configFactory, protected EventDispatcherInterface $eventDispatcher) { + public function __construct(protected BookManagerInterface $bookManager, protected ConfigFactoryInterface $configFactory, protected EventDispatcherInterface $eventDispatcher, protected EntityTypeManagerInterface $entityTypeManager) { } /** @@ -468,4 +473,23 @@ public function checkNodeIsRemovable(NodeInterface $node) { return $this->bookManager->checkNodeIsRemovable($node); } + /** + * Check for access on the "Outline" book route. + * + * @param \Drupal\Core\Session\AccountInterface $account + * Current account. + * @param int $node + * Node entity id. + * + * @return \Drupal\Core\Access\AccessResultReasonInterface + * Resulting access. + */ + public function checkBookOutlineAccess(AccountInterface $account, int $node): AccessResultInterface { + $node = $this->entityTypeManager->getStorage('node')->load($node); + if ($node && $this->nodeAllowedInBook($node)) { + return AccessResult::allowedIfHasPermission($account, 'administer book outlines'); + } + return AccessResult::forbidden(); + } + } diff --git a/src/StanfordFieldsServiceProvider.php b/src/StanfordFieldsServiceProvider.php index a2577fe..ce0fafe 100644 --- a/src/StanfordFieldsServiceProvider.php +++ b/src/StanfordFieldsServiceProvider.php @@ -22,6 +22,7 @@ public function register(ContainerBuilder $container) { ->addArgument(new Reference('stanford_fields.book_manager.inner')) ->addArgument(new Reference('config.factory')) ->addArgument(new Reference('event_dispatcher')) + ->addArgument(new Reference('entity_type.manager')) ->setPublic(FALSE); } } diff --git a/stanford_fields.info.yml b/stanford_fields.info.yml index f10e727..4ae8377 100755 --- a/stanford_fields.info.yml +++ b/stanford_fields.info.yml @@ -3,6 +3,6 @@ type: module description: 'Field types, widgets and formatters to enhance Drupal and Contrib.' core_version_requirement: ^9 || ^10 package: Stanford -version: 8.2.0 +version: 8.2.1 dependencies: - drupal:field diff --git a/tests/src/Kernel/Service/StanfordFieldBookManagerTest.php b/tests/src/Kernel/Service/StanfordFieldBookManagerTest.php index f6ffaf9..05166be 100644 --- a/tests/src/Kernel/Service/StanfordFieldBookManagerTest.php +++ b/tests/src/Kernel/Service/StanfordFieldBookManagerTest.php @@ -5,9 +5,12 @@ use Drupal\Core\Form\FormState; use Drupal\Core\Render\Element; use Drupal\Core\Session\AccountProxyInterface; +use Drupal\Core\Url; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; use Drupal\Tests\stanford_fields\Kernel\StanfordFieldKernelTestBase; +use Drupal\user\Entity\User; +use Drupal\user\RoleInterface; /** * Decorated book manager service tests. @@ -142,4 +145,37 @@ public function testUpdateOutline() { $this->assertEquals(24, $node->book['weight']); } + public function testOutlineAccess() { + // Create user 1 first. + User::create(['name' => $this->randomMachineName()])->save(); + + $account = User::create(['name' => $this->randomMachineName()]); + + $account->save(); + $account = User::load($account->id()); + $this->container->get('current_user')->setAccount($account); + + $access = Url::fromRoute('entity.node.book_outline_form', ['node' => 999]) + ->access($account); + $this->assertFalse($access); + + $access = Url::fromRoute('entity.node.book_outline_form', ['node' => $this->book->id()]) + ->access($account); + $this->assertFalse($access); + + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['administer book outlines']); + $access = Url::fromRoute('entity.node.book_outline_form', ['node' => $this->book->id()]) + ->access($account); + $this->assertTrue($access); + + \Drupal::configFactory()->getEditable('book.settings') + ->set('allowed_types', ['foobar_page']) + ->set('child_type', 'foobar_page') + ->save(); + + $access = Url::fromRoute('entity.node.book_outline_form', ['node' => $this->book->id()]) + ->access($account); + $this->assertFalse($access); + } + } diff --git a/tests/src/Kernel/StanfordFieldKernelTestBase.php b/tests/src/Kernel/StanfordFieldKernelTestBase.php index 947919f..fbf817e 100644 --- a/tests/src/Kernel/StanfordFieldKernelTestBase.php +++ b/tests/src/Kernel/StanfordFieldKernelTestBase.php @@ -2,7 +2,6 @@ namespace Drupal\Tests\stanford_fields\Kernel; -use Drupal\Core\Session\AccountInterface; use Drupal\KernelTests\KernelTestBase; use Drupal\node\Entity\NodeType; use Drupal\user\Entity\Role; @@ -38,8 +37,10 @@ protected function setUp(): void { $this->installSchema('node', ['node_access']); NodeType::create(['type' => 'page'])->save(); - Role::create(['id' => AccountInterface::ANONYMOUS_ROLE])->save(); + Role::create(['id' => RoleInterface::ANONYMOUS_ID])->save(); + Role::create(['id' => RoleInterface::AUTHENTICATED_ID])->save(); user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, ['access content']); + user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['access content']); } }