python-slack-sdk icon indicating copy to clipboard operation
python-slack-sdk copied to clipboard

Google Cloud Storage OAuth backend

Open ccaruceru opened this issue 1 year ago • 8 comments

Summary

Add Google Cloud Storage (GCS) support for OAuth installation and state stores, as a follow up from https://github.com/slackapi/bolt-python/issues/962#issuecomment-1745873853. (ported from ccaruceru/slack-multireact/multi_reaction_add/oauth)

Testing

  • create/reuse a slack app and install it in a workspace
  • use Bolt to write a small app to ask the user for some permissions on app installation, in conjunction with the newly added GCS storage e.g.
from google.cloud.storage import Client
from slack_bolt import App
from slack_bolt.oauth.oauth_settings import OAuthSettings
from slack_sdk.oauth.state_store.google_cloud_storage import GoogleCloudStorageOAuthStateStore
from slack_sdk.oauth.installation_store.google_cloud_storage import GoogleCloudStorageInstallationStore

bucket_name = "GOOGLE_BUCKET_NAME"
slack_client_id = "SLACK_CLIENT_ID"
slack_client_secret = "SLACK_CLIENT_SECRET"
slack_signing_secret = "SLACK_SIGNING_SECRET"

storage_client = Client()

app = App(
    signing_secret=slack_signing_secret,
    oauth_settings=OAuthSettings(
        install_page_rendering_enabled=False,
        client_id=slack_client_id,
        client_secret=slack_client_secret,
        scopes=[],  # scopes for bot operations
        user_scopes=["reactions:write"], # scopes for operations on behalf of user
        installation_store=GoogleCloudStorageInstallationStore(
            storage_client=storage_client,
            bucket_name=bucket_name,
            client_id=slack_client_id
        ),
        state_store=GoogleCloudStorageOAuthStateStore(
            storage_client=storage_client,
            bucket_name=bucket_name,
            expiration_seconds=600
        )
    )
)

@app.event("message")
def handle_message_events(event, client, context):
    """Listens for messages containing 'thumbs up' and reacts with a :thumbsup: emoji"""
    text = event.get("text", "").lower()
    channel = event.get("channel")
    timestamp = event.get("ts")
    if "thumbs up" in text:
        client.token = context.user_token
        client.reactions_add(
            channel=channel,
            name="thumbsup",
            timestamp=timestamp,
        )
        print("Added :thumbsup: reaction!")
  • go to app's /slack/install page
    • observe a temporary oauth token is issued in the bucket
  • finish the install flow
    • observe that the temporary token is gone
    • observe that bot* and installer* files are created
  • interact with the newly added app (e.g. for the above app: add/invite the app to a public channel, type a message with "thumbs up" in it and see if the :thumbsup: emoji is added to the message)
    • check that there are no errors in the app logs
    • check that the bot and installer files are unchanged

Category

  • [ ] slack_sdk.web.WebClient (sync/async) (Web API client)
  • [ ] slack_sdk.webhook.WebhookClient (sync/async) (Incoming Webhook, response_url sender)
  • [ ] slack_sdk.socket_mode (Socket Mode client)
  • [ ] slack_sdk.signature (Request Signature Verifier)
  • [x] slack_sdk.oauth (OAuth Flow Utilities)
  • [ ] slack_sdk.models (UI component builders)
  • [ ] slack_sdk.scim (SCIM API client)
  • [ ] slack_sdk.audit_logs (Audit Logs API client)
  • [ ] slack_sdk.rtm_v2 (RTM client)
  • [ ] /docs (Documents)
  • [ ] /tutorial (PythOnBoardingBot tutorial)
  • [x] tests/integration_tests (Automated tests for this library)

Requirements

  • [x] I've read and understood the Contributing Guidelines and have done my best effort to follow them.
  • [x] I've read and agree to the Code of Conduct.
  • [x] I've run python3 -m venv .venv && source .venv/bin/activate && ./scripts/run_validation.sh after making the changes.

ccaruceru avatar Jan 05 '25 19:01 ccaruceru

Since the time I wrote the original code, I saw there are a couple additions to the other installation stores (like the S3 one) compared to what I did, like historical data and more situations to handle when finding and deleting installs. Let me know what are your thoughts on the proposed changes and if we should tackle those too in this PR 🙂

ccaruceru avatar Jan 05 '25 19:01 ccaruceru

Hi @ccaruceru, thanks for sending this pull request! As you can see here, all the existing built-in installation store implementations pass the same set of scenario tests. If we accept a new one, it must pass the same tests. I'm not sure if you have time or are willing to spend more time, but adding complete test assets to ensure the same quality would be appreciated.

seratch avatar Jan 06 '25 09:01 seratch

hi @seratch! I'll have a look at the tests this week and see if I can come up with something similar 👌🏻

ccaruceru avatar Jan 06 '25 11:01 ccaruceru

@seratch I added the tests as you asked and modified the GoogleCloudStorageInstallationStore to meet the expectations of the new test cases. let me know what you're thinking about the implementation now.

ccaruceru avatar Jan 10 '25 18:01 ccaruceru

hi @seratch, do you have time to have another look at this?

ccaruceru avatar Mar 01 '25 11:03 ccaruceru

Codecov Report

Attention: Patch coverage is 93.58974% with 10 lines in your changes missing coverage. Please review.

Project coverage is 85.42%. Comparing base (a659e3c) to head (63fb656).

Files with missing lines Patch % Lines
...nstallation_store/google_cloud_storage/__init__.py 93.75% 7 Missing :warning:
...oauth/state_store/google_cloud_storage/__init__.py 93.18% 3 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1628      +/-   ##
==========================================
+ Coverage   85.36%   85.42%   +0.06%     
==========================================
  Files         113      115       +2     
  Lines       12802    12958     +156     
==========================================
+ Hits        10928    11070     +142     
- Misses       1874     1888      +14     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Mar 02 '25 04:03 codecov[bot]

hi @WilliamBergamin! any chance for a review on this one? 🙏🏻

ccaruceru avatar Sep 15 '25 19:09 ccaruceru

Hi 👋 apologies for the long delay the team has been very busy lately, I've looked at the changes and they seem good 🚀

I just haven't had the time to test things out locally, I'll try an allocate some time to do this soon and approve your changes

WilliamBergamin avatar Sep 25 '25 14:09 WilliamBergamin