Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
rimi-itk committed Jun 13, 2022
2 parents 12850a0 + e343587 commit 6aa5fad
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 6 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
"drupal/menu_link_attributes": "^1.2",
"drupal/openid_connect": "^2.0",
"drupal/system_status": "^2.9",
"drupal/webform_remote_select": "^1.0",
"drush/drush": "^10.6",
"itk-dev/getorganized-api-client-php": "dev-develop",
"itk-dev/os2forms_cpr_lookup": "^1.6.3",
Expand Down
79 changes: 74 additions & 5 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions config/sync/core.extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ module:
webform_node: 0
webform_node_element: 0
webform_remote_handlers: 0
webform_remote_select: 0
webform_rest: 0
webform_revisions: 0
webform_scheduled_email: 0
Expand Down
18 changes: 18 additions & 0 deletions config/sync/rest.resource.entity.file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
uuid: 68ff09f3-e9d3-4722-b547-3d51556a489e
langcode: da
status: true
dependencies:
module:
- file
- os2forms_rest_api
- serialization
id: entity.file
plugin_id: 'entity:file'
granularity: resource
configuration:
methods:
- GET
formats:
- json
authentication:
- key_auth
68 changes: 68 additions & 0 deletions web/modules/custom/os2forms_rest_api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ user must also have the “API user (write)” (`api_user_write`) role.
| Webform Fields | `/webform_rest/{webform_id}/fields` | GET |
| Webform Submission | `/webform_rest/{webform_id}/submission/{uuid}` | GET |
| Webform Submit | `/webform_rest/submit` | POST |
| File | `/entity/file/{file_id}` | GET |

## Examples

### Submit webform

Request:

```sh
Expand All @@ -51,6 +54,68 @@ Response:

(the `sid`value is a webform submission uuid).

### Get document from webform id and submission uuid

Example uses `some_webform_id` as webform id, `some_submission_id` as
submission id and `dokumenter` as the webform document element key.

Request:

```sh
> curl --silent --header 'api-key: …' https://127.0.0.1:8000/webform_rest/some_webform_id/submission/some_submission_uuid
```

Response:

```json
{
…,
"data": {
"navn": "Jeppe",
"telefon": "87654321"
"dokumenter": {
"some_document_id",
"some_other_docuent_id"
}
}
}
```

Use the file endpoint from above to get information on a file,
substituting `{file_id}` with the actual file id (`some_document_id`)
from the previous request.

Request:

```sh
> curl --silent --header 'api-key: …' https://127.0.0.1:8000/webform_rest/entity/file/some_document_id
```

Response:

```json
{
…,
"uri": [
{
"value": "private:…",
"url": "/system/files/webform/some_webform_id/…"
}
],
}
```

Finally, you can get the actual file by combining the base url
with the url from above response:

```sh
> curl --silent --header 'api-key: …' http://127.0.0.1:8000/system/files/webform/some_webform_id/…
```

Response:
The actual document.

## Custom access control

To limit access to webforms, you can specify a list of API users that are
Expand All @@ -66,3 +131,6 @@ The custom access check is implemented in an event subscriber listening on the
`KernelEvents::REQUEST` event. See
[EventSubscriber::onRequest](src/EventSubscriber/EventSubscriber.php) for
details.

In order to make documents accessible for api users the Key auth `authentication_provider`
service has been overwritten to be global. See [os2forms_rest_api.services](os2forms_rest_api.services.yml).
7 changes: 7 additions & 0 deletions web/modules/custom/os2forms_rest_api/os2forms_rest_api.module
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ use Drupal\os2forms_rest_api\WebformHelper;
function os2forms_rest_api_webform_third_party_settings_form_alter(array &$form, FormStateInterface $form_state) {
\Drupal::service(WebformHelper::class)->webformThirdPartySettingsFormAlter($form, $form_state);
}

/**
* Implements hook_file_download().
*/
function os2forms_rest_api_file_download(string $uri) {
return \Drupal::service(WebformHelper::class)->fileDownload($uri);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ services:
arguments:
- '@entity_type.manager'
- '@current_user'
- '@key_auth.authentication.key_auth'

Drupal\os2forms_rest_api\EventSubscriber\EventSubscriber:
arguments:
Expand All @@ -11,3 +12,11 @@ services:
- '@Drupal\os2forms_rest_api\WebformHelper'
tags:
- { name: 'event_subscriber' }

# Overwrite, adding global tag
# @see https://www.drupal.org/docs/drupal-apis/services-and-dependency-injection/altering-existing-services-providing-dynamic-services
key_auth.authentication.key_auth:
class: Drupal\key_auth\Authentication\Provider\KeyAuth
arguments: [ '@key_auth' ]
tags:
- { name: authentication_provider, provider_id: 'key_auth', priority: 200, global: true }
40 changes: 39 additions & 1 deletion web/modules/custom/os2forms_rest_api/src/WebformHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\key_auth\Authentication\Provider\KeyAuth;
use Drupal\webform\WebformInterface;
use Drupal\webform\WebformSubmissionInterface;

Expand All @@ -30,12 +31,20 @@ class WebformHelper {
*/
private AccountProxyInterface $currentUser;

/**
* The key authentication service.
*
* @var \Drupal\key_auth\Authentication\Provider\KeyAuth
*/
private KeyAuth $keyAuth;

/**
* Constructor.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, AccountProxyInterface $currentUser) {
public function __construct(EntityTypeManagerInterface $entityTypeManager, AccountProxyInterface $currentUser, KeyAuth $keyAuth) {
$this->entityTypeManager = $entityTypeManager;
$this->currentUser = $currentUser;
$this->keyAuth = $keyAuth;
}

/**
Expand Down Expand Up @@ -226,4 +235,33 @@ private function loadUsers(array $spec): array {
->loadMultiple(array_column($spec, 'target_id'));
}

/**
* Implements hook_file_download().
*/
public function fileDownload(string $uri) {
$request = \Drupal::request();

if ($user = $this->keyAuth->authenticate($request)) {
// Find webform id from uri, see example uri.
// @Example: private://webform/some_webform_id/119/some_file_name.png
$pattern = '/private:\/\/webform\/(?<webform>[^\/]*)/';
if (!preg_match($pattern, $uri, $matches)) {
// Something is not right, deny access.
return -1;
}

// User has API access.
$webform = \Drupal::entityTypeManager()->getStorage('webform')->load($matches['webform']);
$settings = $webform->getThirdPartySetting('os2forms', 'os2forms_rest_api');

$allowedUsers = $this->loadUsers($settings['allowed_users'] ?? []);

// If allowed users is non-empty and user is not in there deny access.
if (!empty($allowedUsers) && !isset($allowedUsers[$user->id()])) {
return -1;
}
}
return NULL;
}

}

0 comments on commit 6aa5fad

Please sign in to comment.