Skip to content
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
13 changes: 11 additions & 2 deletions BDEzPlatformGraphQLBundle.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
<?php

namespace BD\EzPlatformGraphQLBundle;

use BD\EzPlatformGraphQLBundle\DependencyInjection\Compiler;
use BD\EzPlatformGraphQLBundle\DependencyInjection\Security\PolicyProvider;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class BDEzPlatformGraphQLBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container); // TODO: Change the autogenerated stub
parent::build($container);

$container->addCompilerPass(new Compiler\FieldValueTypesPass());
$container->addCompilerPass(new Compiler\FieldValueBuildersPass());
$container->addCompilerPass(new Compiler\SchemaWorkersPass());
$container->addCompilerPass(new Compiler\SchemaBuildersPass());

$this->loadPolicyProviders($container);
}

private function loadPolicyProviders(ContainerBuilder $container)
{
$extension = $container->getExtension('ezpublish');
// Add the policy provider.
$extension->addPolicyProvider(new PolicyProvider());
}
}
12 changes: 12 additions & 0 deletions DependencyInjection/Security/PolicyProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
namespace BD\EzPlatformGraphQLBundle\DependencyInjection\Security;

use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Security\PolicyProvider\YamlPolicyProvider;

class PolicyProvider extends YamlPolicyProvider
{
protected function getFiles()
{
return [__DIR__ . '/../../Resources/config/policies.yml'];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,19 @@ public function buildDefinition(FieldDefinition $fieldDefinition)
$isMultiple
);

return ['type' => $type, 'resolve' => $resolver];
$field = [
'type' => $type,
'resolve' => $resolver
];

if (isset($contentType)) {
$field['public'] = sprintf(
'@=service("ezplatform_graphql.can_user").viewContentOfType("%s")',
$contentType->identifier
);
}

return $field;
}

private function mapFieldTypeIdentifierToGraphQLType($fieldTypeIdentifier)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function work(array &$schema, array $args)
'type' => sprintf("[%s]", $this->getContentName($contentType)),
// @todo Improve description to mention that it is a collection ?
'description' => isset($descriptions['eng-GB']) ? $descriptions['eng-GB'] : 'No description available',
'public' => $this->getPublicValue($contentType),
'resolve' => sprintf(
'@=resolver("DomainContentItemsByTypeIdentifier", ["%s", args])',
$contentType->identifier
Expand All @@ -47,6 +48,7 @@ public function work(array &$schema, array $args)
'type' => $this->getContentName($contentType),
'description' => isset($descriptions['eng-GB']) ? $descriptions['eng-GB'] : 'No description available',
'resolve' => sprintf('@=resolver("DomainContentItem", [args, "%s"])', $contentType->identifier),
'public' => $this->getPublicValue($contentType),
'args' => [
// @todo How do we constraint this so that it only takes an id of an item of that type ?
// same approach than GlobalId ? (<type>-<id>)
Expand Down Expand Up @@ -140,4 +142,16 @@ private function isFieldDefined(ContentTypeGroup $contentTypeGroup, ContentType
[$this->getContentCollectionField($contentType)]
);
}

/**
* @param $contentType
* @return string
*/
protected function getPublicValue($contentType): string
{
return sprintf(
'@=service("ezplatform_graphql.can_user").viewContentOfType("%s")',
$contentType->identifier
);
}
}
28 changes: 28 additions & 0 deletions GraphQL/ExpressionLanguage/Access/BaseAccessFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access;

use Overblog\GraphQLBundle\ExpressionLanguage\ExpressionFunction;

abstract class BaseAccessFunction extends ExpressionFunction
{
protected function buildHasAccessCode(array $policies)
{
$checks = array_map(
function($policy) {
list($module, $function) = explode('/', $policy);
return sprintf(
'(true === ($access = $pr->hasAccess("%s", "%s")) || is_array($access))',
$module,
$function
);
},
$policies
);

return sprintf('(function() use ($globalVariable) {
$pr = $globalVariable->get("container")->get("eZ\Publish\API\Repository\PermissionResolver");
return %s;
})()', implode('||', $checks));
}

}
18 changes: 18 additions & 0 deletions GraphQL/ExpressionLanguage/Access/EzCanUserFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access;

/**
* Expression language function that checks if the current user has access to a policy.
*/
class EzCanUserFunction extends BaseAccessFunction
{
public function __construct()
{
parent::__construct(
'ezCanUser',
function ($policy) {
return $this->buildHasAccessCode([str_replace('"', '', $policy)]);
}
);
}
}
15 changes: 15 additions & 0 deletions GraphQL/ExpressionLanguage/Access/HasAdminAccessFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access;

class HasAdminAccessFunction extends BaseAccessFunction
{
public function __construct()
{
parent::__construct(
'hasAdminAccess',
function () {
return $this->buildHasAccessCode(["section/view", "class/create", "role/read"]);
}
);
}
}
18 changes: 18 additions & 0 deletions GraphQL/ExpressionLanguage/Access/HasEzAccessToFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access;

/**
* Expression language function that checks if the current user has access to a policy.
*/
class HasEzAccessToFunction extends BaseAccessFunction
{
public function __construct()
{
parent::__construct(
'hasEzAccessTo',
function ($policy) {
return $this->buildHasAccessCode([str_replace('"', '', $policy)]);
}
);
}
}
26 changes: 26 additions & 0 deletions GraphQL/ExpressionLanguage/Access/HasEzAccessToOneOfFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access;

/**
* Expression language function that checks if the current user has access to at least one
* of the given policies, with or without limitations.
*/
class HasEzAccessToOneOfFunction extends BaseAccessFunction
{
public function __construct()
{
parent::__construct(
'hasEzAccessToOneOf',
function () {
return $this->buildHasAccessCode(
array_map(
function($value) {
return str_replace('"', '', $value);
},
func_get_args()
)
);
}
);
}
}
28 changes: 28 additions & 0 deletions GraphQL/Resolver/ViewerResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
namespace BD\EzPlatformGraphQLBundle\GraphQL\Resolver;

use eZ\Publish\API\Repository\Repository;

class ViewerResolver
{
/**
* @var Repository
*/
private $repository;

public function __construct(Repository $repository)
{
$this->repository = $repository;
}

public function resolveViewer()
{
return $this->repository->sudo(
function (Repository $repository) {
return $repository->getUserService()->loadUser(
$repository->getPermissionResolver()->getCurrentUserReference()->getUserId()
);
}
);
}
}
6 changes: 5 additions & 1 deletion Resources/config/graphql/Platform.types.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ Platform:
_repository:
type: Repository
resolve: { }
description: "eZ Platform repository API"
description: "eZ Platform repository API"
public: "@=hasEzAccessToOneOf('section/view', 'class/create', 'role/read')"
viewer:
type: User
resolve: "@=resolver('Viewer')"
5 changes: 5 additions & 0 deletions Resources/config/policies.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
graphql:
content_type_view:
- Class
content:
- Class
4 changes: 4 additions & 0 deletions Resources/config/resolvers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ services:
- { name: overblog_graphql.resolver, alias: "UserGroupSubGroups", method: "resolveUserGroupSubGroups" }
- { name: overblog_graphql.resolver, alias: "UsersOfGroup", method: "resolveUsersOfGroup" }

BD\EzPlatformGraphQLBundle\GraphQL\Resolver\ViewerResolver:
tags:
- { name: overblog_graphql.resolver, alias: "Viewer", method: "resolveViewer" }

BD\EzPlatformGraphQLBundle\GraphQL\Resolver\ContentTypeResolver:
tags:
- { name: overblog_graphql.resolver, alias: "ContentTypeById", method: "resolveContentTypeById" }
Expand Down
16 changes: 16 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,19 @@ services:
- { name: "overblog_graphql.mutation", alias: "DeleteSection", method: "deleteSection" }

BD\EzPlatformGraphQLBundle\GraphQL\InputMapper\SearchQueryMapper: ~

BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access\HasAdminAccessFunction:
tags: ['overblog_graphql.expression_function']

BD\EzPlatformGraphQLBundle\GraphQL\ExpressionLanguage\Access\HasEzAccessToOneOfFunction:
tags: ['overblog_graphql.expression_function']

ezplatform_graphql.can_user:
autowire: true
class: 'BD\EzPlatformGraphQLBundle\Security\CanUser'

BD\EzPlatformGraphQLBundle\Security\ApiKeyUserProvider:
autowire: true

BD\EzPlatformGraphQLBundle\Security\ApiKeyAuthenticator:
autowire: true
15 changes: 15 additions & 0 deletions Security/ApiKeyAuthenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: bdunogier
* Date: 11/11/2018
* Time: 22:10
*/

namespace BD\EzPlatformGraphQLBundle\Security;


class ApiKeyAuthenticator
{

}
Loading