Skip to content

[add-resource] New Plugin: Google Drive Auth (gdrive-auth) #4348

Description

@sandymac

Please add this plugin to GPM.

What it does: Google sign-in for a Grav 2 Google Drive plugin family. A site connects a Google account once, either as an OAuth user through its own Google Cloud "Web application" client (PKCE S256, offline access, revoke) or as a service account (RS256 JWT signed with openssl_sign), and plugins built on it call Gdrive::drive($account, $scopes) for a thin Drive v3 client (Shared Drives on every call, 401 → refresh-once, backoff on 429/5xx, resumable single-PUT upload). Dependent plugins declare the account and scopes they need through an onGdriveScopes event; an OAuth account that hasn't granted a scope is refused with scope_not_granted.

The Admin2 settings page (two custom fields plus server-rendered display fields) has a guided setup that asks a few questions and shows only the steps that apply, an Accounts tab (add by upload or paste, Test, Connect in a popup, Remove) and full OAuth, service-account and Troubleshooting guides with the site's redirect URI, service-account emails and needed scopes filled in. Its routes live under /api/v1/gdrive behind a dedicated api.gdrive.manage permission; the public OAuth callback at /gdrive-oauth/callback is the only front-end route. No Composer dependencies: curl and openssl only.

Security notes (SECURITY.md has the full list): credentials live only in user/data/gdrive/auth/, written atomically with mode 0600, never in config, logs or API responses; account names are validated before any path is built and uploaded JSON is shape-checked; sign-in and token requests go only to Google's own endpoints whatever an uploaded file says; the callback trusts a single-use, 10-minute, server-side state (32 random bytes stored by SHA-256) plus PKCE and answers a generic 400 otherwise, with the reason logged; the redirect URI follows system.custom_base_url and Google exact-matches it, so a forged Host header goes nowhere; the callback page sends a nonce CSP, X-Frame-Options: DENY, Cache-Control: no-store and Referrer-Policy: no-referrer.

Testing: tests/smoke.php (fake transports, no network: JWT, PKCE, state single-use and expiry, scope enforcement, retry and 401 logic, upload request shape, pinned endpoints, credential and name validation, the settings page's rows and guides, a Troubleshooting anchor for every reason code, version drift), PHPStan level 6 against Grav 2.0.23 / api 1.0.41 and Grav 2.2.4 / api 1.0.44, PHP 8.3 and 8.4, all in CI. Clicked through on a production site running Grav 2.2.4, api 1.0.44, admin2 2.1.27, PHP 8.3: every tab renders, Test passes against Drive.

Note: the two plugins built on it (gdrive-images, gdrive-backup) are still private and will be submitted separately once they're ready, so the README's links to them don't resolve yet.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions