Skip to content

Commit

Permalink
機密性の高いフィールドはAPIから返さない
Browse files Browse the repository at this point in the history
  • Loading branch information
kiy0taka committed Jul 7, 2020
1 parent e8a6e3e commit af00102
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 5 deletions.
21 changes: 16 additions & 5 deletions GraphQL/Types.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\ClassMetadata;
use Eccube\Entity\BaseInfo;
use Eccube\Entity\Customer;
use Eccube\Entity\Member;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;

Expand All @@ -28,10 +31,14 @@ class Types

private $types = [];

private const EXCLUDE_FIELDS = [
BaseInfo::class => ['authentication_key'],
Customer::class => ['password', 'reset_key', 'salt', 'secret_key'],
Member::class => ['password', 'salt'],
];

/**
* Types constructor.
*
* @param EntityManager $entityManager
*/
public function __construct(EntityManager $entityManager)
{
Expand All @@ -42,6 +49,7 @@ public function __construct(EntityManager $entityManager)
* Entityに対応するObjectTypeを返す.
*
* @param $className string Entityクラス名
*
* @return ObjectType
*/
public function get($className)
Expand All @@ -59,11 +67,13 @@ private function createObjectType($className)
'name' => (new \ReflectionClass($className))->getShortName(),
'fields' => function () use ($className) {
$classMetadata = $this->entityManager->getClassMetadata($className);
$fields = array_reduce($classMetadata->fieldMappings, function ($acc, $mapping) {
$fields = array_reduce($classMetadata->fieldMappings, function ($acc, $mapping) use ($classMetadata) {
$type = $this->convertFieldMappingToType($mapping);
$fieldName = $mapping['fieldName'];
$excludes = self::EXCLUDE_FIELDS[$classMetadata->name] ?? [];

if ($type) {
$acc[$mapping['fieldName']] = $type;
if (!in_array($fieldName, $excludes) && $type) {
$acc[$fieldName] = $type;
}

return $acc;
Expand All @@ -73,6 +83,7 @@ private function createObjectType($className)
$acc[$mapping['fieldName']] = [
'type' => $this->convertAssociationMappingToType($mapping),
];

return $acc;
}, $fields);

Expand Down
5 changes: 5 additions & 0 deletions Resource/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ services:
tags:
- { name: kernel.event_listener, event: trikoder.oauth2.user_resolve, method: onUserResolve }

Plugin\Api\GraphQL\Types:
class: Plugin\Api\GraphQL\Types
arguments: ["@doctrine.orm.entity_manager"]
lazy: true

# Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories)
Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory'
Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory'
Expand Down
59 changes: 59 additions & 0 deletions Tests/GraphQL/TypesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Plugin\Api\Tests\GraphQL;

use Eccube\Entity\BaseInfo;
use Eccube\Entity\Customer;
use Eccube\Entity\Member;
use Eccube\Entity\Product;
use Eccube\Tests\EccubeTestCase;
use Plugin\Api\GraphQL\Types;

class TypesTest extends EccubeTestCase
{
/** @var Types */
private $types;

public function setUp()
{
parent::setUp();
$this->types = $this->container->get(Types::class);
}

/**
* @dataProvider hideSensitiveFieldsProvider
*/
public function testHideSensitiveFields($entityClass, $field, $expectExists)
{
$type = $this->types->get($entityClass);

self::assertEquals($expectExists, $type->hasField($field));
}

public function hideSensitiveFieldsProvider()
{
return [
[Product::class, 'name', true],
[Customer::class, 'name01', true],
[Customer::class, 'password', false],
[Customer::class, 'reset_key', false],
[Customer::class, 'salt', false],
[Customer::class, 'secret_key', false],
[Member::class, 'name', true],
[Member::class, 'password', false],
[Member::class, 'salt', false],
[BaseInfo::class, 'authentication_key', false],
];
}
}

0 comments on commit af00102

Please sign in to comment.