Problem/Motivation

I have Key and Shield modules installed for a project and I want to use Shield with credentials stored outside the database (in a .key file). The configured .key file's location is set as "private://my_key_file.key" (stream wrapper is allowed here). When getKeyValue() is invoked (in src/Plugin/KeyProvider/FileKeyProvider.php), the key file gets checked for existence and readability. But it always returns FALSE since it can't recognise the path "private://..." (bootstrap still not loaded since this is HTTP Auth provided by Shield). When absolute path is used (like /var/www/files-private), it works. But I need the stream wrapper path for my case.

Steps to reproduce

Add a key in the Key module (Section "Type settings" > Key type > "User/password"; Section "Provider Settings" > Key provider > "File" and for "File location", add "private://..." or "public://..."), and use the same key when configuring Shield (Credentials > Credential Provider > "Key module (User/password)" and under "User/password", select your key).

Proposed resolution

We can get the file's real path by just adding \Drupal::service('file_system')->realpath($file) when the stream wrapper is used.

Issue fork key-3300224

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

kmakaveev created an issue. See original summary.

kmakaveev’s picture

StatusFileSize
new702 bytes
angel.h’s picture

Status: Active » Needs work

We should not limit this to the public and private schemas. Maybe you should use something like:

    if (StreamWrapperManager::getScheme($file)) {
      $file = \Drupal::service('file_system')->realpath($file);
    }

anoopsingh92 made their first commit to this issue’s fork.

anoopsingh92’s picture

Status: Needs work » Needs review

Hi @angel.h, I have updated your changes in the MR6.
I have raised an MR please review if it is fine then please merge it.

MR: https://git.drupalcode.org/project/key/-/merge_requests/6
Thanks

kmakaveev’s picture

kmakaveev’s picture

Sorry, I missed to use the class StreamWrapperManager in the patch. Fixed and updated.

kmakaveev’s picture

anoopsingh92’s picture

Assigned: Unassigned » anoopsingh92

Thanks for informing @kmakaveev, I am updating your changes in MR. Thanks

anoopsingh92’s picture

Assigned: anoopsingh92 » Unassigned

MR #6 updated. Thanks

cmlara’s picture

Title: Key file not loaded when Stream Wrapper is used for file location » Key file not loaded when Stream Wrapper is used for file location before Drupal bootstrap completes
Status: Needs review » Needs work

I will note that the use of realPath() is discouraged. See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21File%21Fi...

I'm not sure how often a site may want a key file on a remote streamWrapper, however if this change is accepted as-is it could break existing deployments.

At a minimal I believe this may need some work to ensure it does not impact remote streamWrappers.

Adjusting title to capture that this should only an issue before bootstrap completes.

rajeshreeputra made their first commit to this issue’s fork.

rajeshreeputra’s picture

Status: Needs work » Needs review

We can use the realpath() method of FileSystem.

I have validated the MR changes with shield module and it work as expected. Hence requesting review.

cmlara’s picture

We can use the realpath() method of FileSystem.

Given the following documentation of the API Method can you provide more justification?

    * The use of this method is discouraged, because it does not work for
     * remote URIs. Except in rare cases, URIs should not be manually resolved.
     *
     * Only use this function if you know that the stream wrapper in the URI uses
     * the local file system, and you need to pass an absolute path to a function
     * that is incompatible with stream URIs.
     *

— FileSystemInterface::realpath()

Does the key module know that a path is a local filesystem? Is this a rare case? If so why? Does the module need to pass an absolute path to a function? If so which function only accepts absolute paths?

ankitv18’s picture

Status: Needs review » Needs work

Minor suggestion ~~ Please check, moving into NW

rajeshreeputra’s picture

StatusFileSize
new109.51 KB

Hello @cmlara,

I am currently experiencing an issue when provided file path located on a different server or outside the Drupal project scope, as it is returning an following error. Hence I mentioned that we can use the realpath() method of FileSystem.

error when file path if from different server.

Could you please let me know if there's anything I'm missing that would enable me to provide a file path located on a different server or outside the Drupal project scope?

cmlara’s picture

Could you please let me know if there's anything I'm missing that would enable me to provide a file path located on a different server or outside the Drupal project scope?

Using the S3fs module with the file at s3://test.txt would be an example that works key when this patch is not applied. Once this patch enforces realpath I would expect the following to no longer function.

> file_put_contents('s3://test.txt', 'testkey');
= 7

> file_get_contents('s3://test.txt');
= "testkey"

> Drupal::service('key.repository')->getKey('s3key')->getKeyValue()
= "testkey"
rajeshreeputra’s picture

Hello @cmlara, updated to work with realpath, stream wrapper and remote urls. Could you please validate with s3 once. Will keep this in needs work status.

rajeshreeputra’s picture

I have not yet utilized the s3fs module in Drupal, but I will give it a try. Then accordingly update here.

vishalkhode’s picture

In !MR 6 Looks like there's a complete new feature has been introduced i.e Provide support for external file url for key. I'm not sure if this should be supported or not. In any case, this should be implemented and discussed separately. We should limit this ticket to fix the bug only.

rajeshreeputra’s picture

With the understanding how the public:// and private:// stream wrappers function with S3FS. Will close the MR!6(keeping for future reference) and create new one.

rajeshreeputra changed the visibility of the branch 3300224-key-file-not to hidden.

cmlara’s picture

Status: Needs review » Postponed

From MR comments it appears this should be Postponed on #3356052: KeyProviderInterface::getKeyValue() doesn't always return a string as there is question if NULL is an acceptable return type.

It is used in one location in existing code however is not documented in the API to be allowed.

Until a decison is made to update the API new deviations should likely not be added. (Avoid creating more work for others if the API is correct.)

rajeshreeputra’s picture

rajeshreeputra’s picture

Status: Postponed » Needs review

Based on the ongoing discussions in the referenced issues, will proceed with the exact ask of this issue without introducing new validations.

Requesting review.

chandu7929’s picture

Status: Needs review » Reviewed & tested by the community

Overall, the changes in MR!47 look good to me. I validated the behavior using both private://myfile.key and public://myfile.key paths, and was able to retrieve the key value when using this patch. However, without the patch, the value returns null. Therefore, marking this as RTBC.

mxr576’s picture

Version: 8.x-1.15 » 8.x-1.x-dev
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs change record

Since constructor arguments changed on a public class, I think this deserves a change record.

rajeshreeputra’s picture

Status: Needs work » Needs review
mxr576’s picture

I think the CR is too lengthy compared with other announcements about new constructor arguments - I assume the LLM went too far here :)

I expected nothing more than
* https://www.drupal.org/node/3404140
* https://www.drupal.org/node/3440755
* https://www.drupal.org/node/3419963

mxr576’s picture

Status: Needs review » Reviewed & tested by the community

The code looks for me.