Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

google cloud adapter: allow to inject visibility handler #160

Conversation

syffer
Copy link
Contributor

@syffer syffer commented Mar 18, 2024

Hi,

This pr offers to simplify the configuration of the google adapter when there is a need to change the default visibility handler.

For example, when using a bucket with uniform acl, it is required to redefine the google adapter, the bucket, and the visibility handler like so:

flysystem:
    storages:
        storage.public.cdn:
            adapter: 'app.flysystem.adapter.public.cdn.custom'

services:
    app.flysystem.adapter.public.cdn.custom:
        class: League\Flysystem\GoogleCloudStorage\GoogleCloudStorageAdapter
        arguments:
            $bucket: '@app.uploads_cdn.gcloud_client_service.bucket'
            $prefix: '%uploads.cdn.gcp.storage.path_prefix%'
            $visibilityHandler: '@League\Flysystem\GoogleCloudStorage\UniformBucketLevelAccessVisibility' 

    League\Flysystem\GoogleCloudStorage\UniformBucketLevelAccessVisibility: ~

    app.uploads_cdn.gcloud_client_service:
        class: Google\Cloud\Storage\StorageClient
        arguments:
            $config:
                keyFilePath: '%uploads.cdn.gcp.authentication_file.path%'

    app.uploads_cdn.gcloud_client_service.bucket:
        class: Google\Cloud\Storage\Bucket
        factory: ['@app.uploads_cdn.gcloud_client_service', 'bucket']
        arguments:
            $name: '%uploads.cdn.gcp.storage.bucket_name%'

This pr would allow to do this instead :

flysystem:
    storages:
        storage.public.cdn:
            adapter: 'gcloud'
            options:
                client: 'app.uploads_cdn.gcloud_client_service'
                bucket: '%uploads.cdn.gcp.storage.bucket_name%'
                prefix: '%uploads.cdn.gcp.storage.path_prefix%'
                visibility_handler: League\Flysystem\GoogleCloudStorage\UniformBucketLevelAccessVisibility

services:
    app.uploads_cdn.gcloud_client_service:
        class: Google\Cloud\Storage\StorageClient
        arguments:
            $config:
                keyFilePath: '%uploads.cdn.gcp.authentication_file.path%'

At first, I wanted to add a VisibilityHandlerGuesser directlry in thephpleague/flysystem (by using the bucket's method info, as described here with the iamConfiguration, but the client might not have enough rights to do so).

Copy link
Collaborator

@maxhelias maxhelias left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's great! Thank you for your contribution !

/**
* @internal
*/
class GcloudFactoryPass implements CompilerPassInterface
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this CompilerPass necessary? I'm not sure we need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback.

I initially wanted to declare those services in the GcloudAdapterDefinitionBuilder (as they are only related to the google part), but it's obvious this class isn't where those services should be.

So, I added the services registrations in a CompilerPass to make it obvious it's only related to the google part, and in case other services would be needed for other parts as well (aws for example). So in my mind, it was just a question an organization purpose.

If you rather have the definition elsewhere (in the FlysystemBundle.php I assume), I would gladly modify this.

Copy link
Collaborator

@maxhelias maxhelias Mar 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see yes, in the current state of the builders it is not possible to register any other service.

More generally, the creation of storage shoud be reworked to extend the possibility of allowing external builders and also to register services according to the builders activated.
This last case is quite rare, because for exemple for other rights we register a new service like this :

protected function createUnixDefinition(array $permissions, string $defaultVisibilityForDirectories): Definition
{
return (new Definition(PortableVisibilityConverter::class))
->setFactory([PortableVisibilityConverter::class, 'fromArray'])
->addArgument([
'file' => [
'public' => (int) $permissions['file']['public'],
'private' => (int) $permissions['file']['private'],
],
'dir' => [
'public' => (int) $permissions['dir']['public'],
'private' => (int) $permissions['dir']['private'],
],
])
->addArgument($defaultVisibilityForDirectories)
->setShared(false)
;
}

And this service is declared as no-shared to manage different rights per storage.

From what I can see for GCloud, it's a bit different. It uses predefined rights for these entities, I don't use GCloud and I don't know if these values can change in relation to its configuration.
So at first lok, I don't see any other way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also don't know about the predefined rights for GCloud, I only worked with GCloud recently in order to use it as a cdn, which has a uniform acl.

Maybe I thought too much about it, and doing as the other builders is enough (meaning creating a new visibility handler per GCloud adapter when it is given in the config), and not having to create 2 others "global" visibility handler services

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't hesitate if you think you can improve it, in the meantime I'll merge it.

@maxhelias maxhelias merged commit a69de47 into thephpleague:3.x Mar 21, 2024
19 checks passed
@maxhelias
Copy link
Collaborator

maxhelias commented Mar 21, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants