profile
viewpoint

jeanfei/umami-static 1

Provides static html, css sources for the Umami website.

jeanfei/capistrano-lightning-talk 0

Provides sources for a Capistrano lightning talk.

jeanfei/contentacms.github.io 0

Static site for the Contenta CMS project

jeanfei/contentavuenuxt.github.io 0

this is the demo site for https://github.com/contentacms/contenta_vue_nuxt

jeanfei/contenta_vue_nuxt 0

Nuxt.js + Vue.js client for Contenta CMS demo site - https://contentavuenuxt.github.io/

jeanfei/meetup-blocks-ctools 0

Provides sources of Drupal demo, comparing blocks and ctools content types.

jeanfei/reservoir 0

A back end for your front end: a content repository. Powered by Drupal 8, JSON API and OAuth2.

issue commentdrupal-graphql/graphql

Implement automatic schema generators for all Drupal entities in GraphQL 4.x

Hm, I think I would not add that to the project page, since we don't want to encourage people to use a generated schema.

So I think I would leave the discussion just in this issue for now.

MurzNN

comment created time in 7 hours

issue commentdrupal-graphql/graphql

Implement automatic schema generators for all Drupal entities in GraphQL 4.x

@klausi How about to add link to this discussion to that paragraph on the project page? It took long time for me to find this statements. :-)

Btw, I think it yould be also good to write your statement about schema-generating submodule in 4.x to that paragraph, because it is better to hire potential community work for this than for maintainance of 3.x.

MurzNN

comment created time in 8 hours

push eventdrupal-graphql/graphql

Klaus Purer

commit sha b235e07fd6594dd27cad9a97f9b1808be7ad30e9

fix(files): Fix lock release handling when the file upload does not validate (#1118)

view details

push time in 11 hours

PR merged drupal-graphql/graphql

fix(files): Fix lock release handling when the file upload does not validate 4.x

Follow-up to #1115 . We need to release the lock correctly when file validation fails.

I found the finally keyword in PHP which does exactly what we want, yay! https://www.php.net/manual/en/language.exceptions.php

Did not open a Drupal core issue yet, same bug in FileUploadResource.

+79 -36

0 comment

2 changed files

klausi

pr closed time in 11 hours

PR opened drupal-graphql/graphql

Add image ID to ImageDerivative

Resolves #1120

+1 -0

0 comment

1 changed file

pr created time in 12 hours

issue openeddrupal-graphql/graphql

Composing data producer example is broken

The code snippet that shows how $builder->compose can be used to load the currentUser is broken. The current_user data producer produces an AccountInterface instance, but the entity_load id field requires a string or an int.

The current incorrect snippet is the following part.

$builder->compose(
  $builder->produce('current_user'),
  $builder->produce('entity_load')
    ->map('type', $builder->fromValue('user'))
    ->map('id', $builder->fromParent())
);

For a query

query {
  currentUser { uuid }
}

It causes the following output

{
  "data": {
    "currentUser": null
  },
  "extensions": [
    {
      "message": "Object of class Drupal\\Core\\Session\\UserSession could not be converted to string",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "currentUser"
      ]
    }
  ]
}

created time in 15 hours

issue openeddrupal-graphql/graphql

Add image ID to image derivative

ImageDerivative only returns image url, width, and height. https://github.com/drupal-graphql/graphql/blob/582704b321379323efba68ece4b7a07257e07f65/src/Plugin/GraphQL/DataProducer/Entity/Fields/Image/ImageDerivative.php#L132-L136

I would like to be able to access the entity's ID as well.

created time in 16 hours

PR opened drupal-graphql/graphql

Make the EntityBuffer check access rights

Individual entity loads have access checks in place but if you load them via a QueryConnection wrapper they're skipped entirely. This is probably just a starting point, what have I missed?

+1 -1

0 comment

1 changed file

pr created time in a day

starteddvictori/rapideye_hist2sd

started time in a day

startedglw/gdalcheatsheet

started time in a day

PR opened drupal-graphql/graphql

Reviewers
fix(files): Fix lock release handling when the file upload does not validate 4.x

Follow-up to #1115 . We need to release the lock correctly when file validation fails.

I found the finally keyword in PHP which does exactly what we want, yay! https://www.php.net/manual/en/language.exceptions.php

Did not open a Drupal core issue yet, same bug in FileUploadResource.

+79 -36

0 comment

2 changed files

pr created time in 2 days

Pull request review commentdrupal-graphql/graphql

Entity query data producer.

+<?php++namespace Drupal\graphql\Plugin\GraphQL\DataProducer\Entity;++use Drupal\graphql\GraphQL\Execution\FieldContext;++/**+ * Builds and executes Drupal entity query.+ *+ * @DataProducer(+ *   id = "entity_query",+ *   name = @Translation("Load entities"),

This data producer doesn't actually load entities but only finds their IDs

rthideaway

comment created time in 2 days

Pull request review commentdrupal-graphql/graphql

Entity query data producer.

+<?php++namespace Drupal\graphql\Plugin\GraphQL\DataProducer\Entity;++use Drupal\graphql\GraphQL\Execution\FieldContext;++/**+ * Builds and executes Drupal entity query.+ *+ * @DataProducer(+ *   id = "entity_query",+ *   name = @Translation("Load entities"),+ *   description = @Translation("Loads entities."),+ *   produces = @ContextDefinition("string",+ *     label = @Translation("Entity IDs"),+ *     multiple = TRUE+ *   ),+ *   consumes = {+ *     "type" = @ContextDefinition("string",+ *       label = @Translation("Entity type")+ *     ),+ *     "limit" = @ContextDefinition("integer",+ *       label = @Translation("Limit"),+ *       required = FALSE,+ *       default_value = 10+ *     ),+ *     "offset" = @ContextDefinition("integer",+ *       label = @Translation("Offset"),+ *       required = FALSE,+ *       default_value = 0+ *     ),

Offset based queries in Drupal are somewhat difficult in Drupal because Drupal allows access handlers that can not be put into a database query. This means that access filtering will be done after the fact which could mean that 10 entities are selected but none are actually sent back to the client.

For this same reason, generic "count" queries are not often seen in GraphQL schemas. On one hand because GraphQL is created for data sets where this isn't pratcial, on the other hand because access a single access check may make a count inaccurate.

rthideaway

comment created time in 2 days

push eventdrupal-graphql/graphql

Klaus Purer

commit sha 582704b321379323efba68ece4b7a07257e07f65

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012 (#1115)

view details

push time in 2 days

PR merged drupal-graphql/graphql

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012

https://www.drupal.org/sa-core-2020-012 also affects our custom file upload service.

We don't want to depend on REST module in Drupal core, so I duplicated the code from FileUploadResource and modified it to what we need.

Not really nice, but should cover the security fix and give us comprehensive file name coverage.

We don't need to report this to the Drupal security team because graphql's file upload service is not in any release yet and has just been introduced in #1112 .

+298 -166

1 comment

4 changed files

klausi

pr closed time in 2 days

pull request commentdrupal-graphql/graphql

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012

I will merge this now and create a follow-up for the lock bug.

klausi

comment created time in 2 days

issue openeddrupal-graphql/graphql

Add language option to the entity buffer

In a multilingual context it should be possible to create a query which returns only the entities that have a specific translation. That is currently possible. But it is not possible to use the entity buffer to load those entities in the requested translation. The method \Drupal\graphql\GraphQL\Buffers\EntityBuffer::add() therefore needs to be extended by a third parameter - $language.

created time in 2 days

Pull request review commentdrupal-graphql/graphql

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012

 public function createTemporaryFileUpload(UploadedFile $file, array $settings):       throw new \RuntimeException('uri_scheme or file_directory missing in settings');     } -    // Make sure the destination directory exists.-    $uploadDir = $settings['uri_scheme'] . '://' . trim($settings['file_directory'], '/');-    if (!$this->fileSystem->prepareDirectory($uploadDir, FileSystem::CREATE_DIRECTORY)) {-      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $file->getClientOriginalName()]));-      $this->logger->error('Could not create directory "@upload_directory".', ["@upload_directory" => $uploadDir]);+    $destination = $this->getUploadLocation($settings);++    // Check the destination file path is writable.+    if (!$this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {+      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $uploaded_file->getClientOriginalName()]));+      $this->logger->error('Could not create directory "@upload_directory".', ["@upload_directory" => $destination]);       return $response;     }-    $name = $file->getClientOriginalName();-    $mime = $this->mimeTypeGuesser->guess($name);-    $destination = $this->fileSystem->getDestinationFilename("{$uploadDir}/{$name}", $this->fileSystem::EXISTS_RENAME); -    // Begin building file entity.-    $values = [-      'uid' => $this->currentUser->id(),-      'status' => 0,-      'filename' => $name,-      'uri' => $destination,-      'filesize' => $file->getSize(),-      'filemime' => $mime,-    ];-    $storage = $this->entityTypeManager->getStorage('file');-    /** @var \Drupal\file\FileInterface $fileEntity */-    $fileEntity = $storage->create($values);+    $validators = $this->getUploadValidators($settings); -    // Validate the entity values.-    $violations = $fileEntity->validate();-    if ($violations->count()) {-      foreach ($violations as $violation) {-        $response->addViolation($violation->getMessage());-      }+    $prepared_filename = $this->prepareFilename($uploaded_file->getClientOriginalName(), $validators);++    // Create the file.+    $file_uri = "{$destination}/{$prepared_filename}";++    $temp_file_path = $uploaded_file->getRealPath();++    $file_uri = $this->fileSystem->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME);++    // Lock based on the prepared file URI.+    $lock_id = $this->generateLockIdFromFileUri($file_uri);++    if (!$this->lock->acquire($lock_id)) {+      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $uploaded_file->getClientOriginalName()]));       return $response;     } -    // Validate the file name length.-    if ($violations = file_validate($fileEntity, $this->getUploadValidators($settings))) {-      $response->addViolations($violations);+    // Begin building file entity.+    /** @var \Drupal\file\FileInterface $file */+    $file = $this->fileStorage->create([]);+    $file->setOwnerId($this->currentUser->id());+    $file->setFilename($prepared_filename);+    $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));+    $file->setFileUri($file_uri);+    // Set the size. This is done in File::preSave() but we validate the file+    // before it is saved.+    $file->setSize(@filesize($temp_file_path));++    // Validate the file entity against entity-level validation and field-level+    // validators.+    if (!$this->validate($file, $validators, $response)) {       return $response;

nice, you just found a bug in core's FileUploadResource which we copied :)

klausi

comment created time in 4 days

Pull request review commentdrupal-graphql/graphql

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012

 public function createTemporaryFileUpload(UploadedFile $file, array $settings):       throw new \RuntimeException('uri_scheme or file_directory missing in settings');     } -    // Make sure the destination directory exists.-    $uploadDir = $settings['uri_scheme'] . '://' . trim($settings['file_directory'], '/');-    if (!$this->fileSystem->prepareDirectory($uploadDir, FileSystem::CREATE_DIRECTORY)) {-      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $file->getClientOriginalName()]));-      $this->logger->error('Could not create directory "@upload_directory".', ["@upload_directory" => $uploadDir]);+    $destination = $this->getUploadLocation($settings);++    // Check the destination file path is writable.+    if (!$this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY)) {+      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $uploaded_file->getClientOriginalName()]));+      $this->logger->error('Could not create directory "@upload_directory".', ["@upload_directory" => $destination]);       return $response;     }-    $name = $file->getClientOriginalName();-    $mime = $this->mimeTypeGuesser->guess($name);-    $destination = $this->fileSystem->getDestinationFilename("{$uploadDir}/{$name}", $this->fileSystem::EXISTS_RENAME); -    // Begin building file entity.-    $values = [-      'uid' => $this->currentUser->id(),-      'status' => 0,-      'filename' => $name,-      'uri' => $destination,-      'filesize' => $file->getSize(),-      'filemime' => $mime,-    ];-    $storage = $this->entityTypeManager->getStorage('file');-    /** @var \Drupal\file\FileInterface $fileEntity */-    $fileEntity = $storage->create($values);+    $validators = $this->getUploadValidators($settings); -    // Validate the entity values.-    $violations = $fileEntity->validate();-    if ($violations->count()) {-      foreach ($violations as $violation) {-        $response->addViolation($violation->getMessage());-      }+    $prepared_filename = $this->prepareFilename($uploaded_file->getClientOriginalName(), $validators);++    // Create the file.+    $file_uri = "{$destination}/{$prepared_filename}";++    $temp_file_path = $uploaded_file->getRealPath();++    $file_uri = $this->fileSystem->getDestinationFilename($file_uri, FileSystemInterface::EXISTS_RENAME);++    // Lock based on the prepared file URI.+    $lock_id = $this->generateLockIdFromFileUri($file_uri);++    if (!$this->lock->acquire($lock_id)) {+      $response->addViolation($this->t('Unknown error while uploading the file "@file".', ['@file' => $uploaded_file->getClientOriginalName()]));       return $response;     } -    // Validate the file name length.-    if ($violations = file_validate($fileEntity, $this->getUploadValidators($settings))) {-      $response->addViolations($violations);+    // Begin building file entity.+    /** @var \Drupal\file\FileInterface $file */+    $file = $this->fileStorage->create([]);+    $file->setOwnerId($this->currentUser->id());+    $file->setFilename($prepared_filename);+    $file->setMimeType($this->mimeTypeGuesser->guess($prepared_filename));+    $file->setFileUri($file_uri);+    // Set the size. This is done in File::preSave() but we validate the file+    // before it is saved.+    $file->setSize(@filesize($temp_file_path));++    // Validate the file entity against entity-level validation and field-level+    // validators.+    if (!$this->validate($file, $validators, $response)) {       return $response;

shouldn't we release the lock before returning response?

klausi

comment created time in 4 days

PR opened drupal-graphql/graphql

fix(files): Implement file upload renaming security fix from SA-CORE-2020-012

https://www.drupal.org/sa-core-2020-012 also affects our custom file upload service.

We don't want to depend on REST module in Drupal core, so I duplicated the code from FileUploadResource and modified it to what we need.

Not really nice, but should cover the security fix and give us comprehensive file name coverage.

We don't need to report this to the Drupal security team because graphql's file upload service is not in any release yet and has just been introduced in #1112 .

+295 -164

0 comment

4 changed files

pr created time in 7 days

push eventdrupal-graphql/graphql

Klaus Purer

commit sha 794ce3c59183693b51b56e24f3ab19f0b501d0eb

feat(response): Add merge violations helper method (#1114)

view details

push time in 9 days

PR merged drupal-graphql/graphql

feat(response): Add merge violations helper method

When you want to combine violations of 2 response classes then a helper would be convenient.

+12 -0

1 comment

2 changed files

klausi

pr closed time in 9 days

pull request commentdrupal-graphql/graphql

feat(response): Add merge violations helper method

This is a small API break since we are changing an interface here, but I think this is not in wide use and most people inherit from the Response base class anyway.

klausi

comment created time in 9 days

PR opened drupal-graphql/graphql

feat(response): Add merge violations helper method

When you want to combine violations of 2 response classes then a helper would be convenient.

+12 -0

0 comment

2 changed files

pr created time in 9 days

push eventdrupal-graphql/graphql

Klaus Purer

commit sha ca46d1baebfe9fa4772a64b7f35227bf909dc270

refactor(files): Remove response wrappers that have moved

view details

push time in 10 days

pull request commentdrupal-graphql/graphql

Rewrite fromPath to use PropertyPath data producer

The only real difference I see is the call to $manager->createDataDefinition which creates the data definition for $manager->create. $manager->create is mocked, but $manager->createDataDefinition is not.

The old Path class used the following line instead:

    $type = $this->type instanceof DataDefinitionInterface ? $this->type : DataDefinition::create($this->type);

I think this is also the cause of the difference in behaviour that I originally mentioned when using multiple Path resolvers in a chain.

I think if we add a mock for createDataDefinition here then we're done (since that functionality is not under test and thus can be mocked).


An alternative route that we can go would require more test changes (and could be done in a follow-up too):

The PropertyPath data producer doesn't currently have a test, but should probably receive one. The current fromPath test for the ResolverBuilder tests its functionality (with the mock above) and could be used.

The fromPath test can then be reduced to ensuring that ResolverBuilder::fromPath returns a properly configured PropertyPath data producer (since it's not the fromPath's responsibility that the underlying data producer behaves correctly).

Kingdutch

comment created time in 10 days

push eventdrupal-graphql/graphql

Klaus Purer

commit sha 0b1eb534155da123a520fa51800a000b0190b0d2

tests(files): Add tests for file upload service and refactor responses (#1112)

view details

push time in 10 days

PR merged drupal-graphql/graphql

feat(files): Add File upload service wit tests 4.x

Follow-up to #818

+327 -19

2 comments

6 changed files

klausi

pr closed time in 10 days

pull request commentdrupal-graphql/graphql

Add a file upload utility

Merging this here for credits, will then merge #1112

rthideaway

comment created time in 10 days

more