slackapi / bolt-python

A framework to build Slack apps using Python
https://tools.slack.dev/bolt-python/
MIT License
1.06k stars 245 forks source link

Oauth bug trying to get download in app directory #890

Closed ryanrestivo closed 1 year ago

ryanrestivo commented 1 year ago

(Filling out the following details about bugs will help us solve your issue sooner.)

So I have an app that is working with the /slack/install route when I have a flask app deployed, but when users install it for the OAuth Add to Slack button they get an eror page

Oops, Something Went Wrong! Please try again from [here]([LINK to]/slack/install) or contact the app owner (reason: invalid_browser: This can occur due to page reload, not beginning the OAuth flow from the valid starting URL, or the /slack/install URL not using https://)

but I have the proper code to set up the app

## OAUTH functionality...

from slack_bolt import App
from slack_bolt.oauth.oauth_settings import OAuthSettings
from slack_sdk.oauth.installation_store import FileInstallationStore
from slack_sdk.oauth.state_store import FileOAuthStateStore
from slack_bolt.adapter.flask import SlackRequestHandler
from slack_sdk.oauth.installation_store.sqlalchemy import SQLAlchemyInstallationStore
from slack_sdk.oauth.state_store.sqlalchemy import SQLAlchemyOAuthStateStore

from slack_sdk.oauth.installation_store import InstallationStore

import sqlalchemy
from sqlalchemy.engine import Engine

database_url = os.environ["dbURL"]

logger = logging.getLogger(__name__)
client_id, client_secret, signing_secret = (
    os.environ["SLACK_CLIENT_ID"],
    os.environ["SLACK_CLIENT_SECRET"],
    os.environ["SLACK_SIGNING_SECRET"],
)

engine: Engine = sqlalchemy.create_engine(database_url)
installation_store = SQLAlchemyInstallationStore(
    client_id=client_id,
    engine=engine,
    logger=logger,
)
oauth_state_store = SQLAlchemyOAuthStateStore(
    expiration_seconds=120,
    engine=engine,
    logger=logger,
)

try:
    engine.execute("select count(*) from slack_bots")
except Exception as e:
    installation_store.metadata.create_all(engine)
    oauth_state_store.metadata.create_all(engine)

app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=oauth_state_store,
        scopes=["channels:join","channels:read","chat:write","chat:write.public","commands","im:read","im:write","mpim:write"],
        user_scopes=["chat:write"] 
    ),
)

app.enable_token_revocation_listeners()

### CORE FLASK APP ###
from flask import Flask, request, render_template, jsonify, abort

flask_app = Flask(__name__)
handler = SlackRequestHandler(app)
@flask_app.route("/slack/install", methods=["GET"])
def install():
    return handler.handle(request)

@flask_app.route("/slack/oauth_redirect", methods=["GET"])
def oauth_redirect():
    return handler.handle(request)

but every time they seemingly hit this oauth button they are getting 400 and have to go to the click here slack/install link which updates the state and works for them...

is there a way to use that button on the slack/install or because it always changes the state value, its impossible?

I have implemented what you all said in my previous issue https://github.com/slackapi/bolt-python/issues/782 but now looking at the logs I see 400 errors on that link so I know people will have to stpe through to install it, but I've seen others that havent had to do this step...

The slack app directory is saying that tehy cant seem to install it and I would like to get in there, so I dont know how to resolve. Can you please help?

I am using

slack-bolt==1.17.0
slack-sdk==3.20.2

and my app is a Flask app andI checked that it is on https, so I'm not sure the exact issue.

I'll add more but I used issue 782 to resolve what I needed to get it to install across multiple workspaces, but now the button seems to generate an error eery time I try to hit it...

srajiang commented 1 year ago

Hi @ryanrestivo! Can I check that for your app you have enabled App Distribution? Go to Settings > Basic Information > Installing Your App and select Install from App Directory - see attached screenshot and supply your full slack/install endpoint.

ryanrestivo commented 1 year ago

Oh I had it as visit site to install, so that wont work for Slack app directory review, right @srajiang ?

ryanrestivo commented 1 year ago

So when I add my link in there I see that Slack says

Your application’s redirect URL must return a status code of 302 to a slack.com url.

but that is my install endpoint. I could make a redirect to that page from there but i dont think that would work..

is this waht you meant?

In the logs I see 200 statuses coming through when that URL is being hit.

Screen Shot 2023-04-26 at 12 02 01 PM
srajiang commented 1 year ago

@ryanrestivo - Can you try setting install_page_rendering_enabled=False in the App constructor under oauth_settings?

Something like this:

app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        # your other settings
        ...
        install_page_rendering_enabled=False,
    ),
)
ryanrestivo commented 1 year ago

I added that setting to my code but it still returns the same error when I try to use the install to slack button

I changed it to

app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=oauth_state_store,
        scopes=["channels:join","channels:read","chat:write","chat:write.public","commands","im:read","im:write","mpim:write"],
        user_scopes=["chat:write"],
        install_page_rendering_enabled=False,
    ),

I get

Oops, Something Went Wrong!
Please try again from [here](https://[APP URL]/slack/install) or contact the app owner (reason: invalid_browser: This can occur due to page reload, not beginning the OAuth flow from the valid starting URL, or the /slack/install URL not using https://)

I'm using next JS to make the button on my page and its constructed like this - I removed the client_id, but the button clicks and redirects to the allow page, but when you click allow is when you get the error above ...

export function AppStoreLink({ color = 'black' }) {
  return (
    <>
    <Link
            href="https://slack.com/oauth/v2/authorize?client_id={CLIENT_ID}&scope=chat:write,chat:write.public,commands,im:write,mpim:write,channels:read,channels:join,im:read&user_scope=chat:write"
            target="_blank"
          >
            <img
              alt="Add to Slack"
              height="40"
              width="139"
              src="https://platform.slack-edge.com/img/add_to_slack.png"
              srcSet="https://platform.slack-edge.com/img/add_to_slack.png 1x, 
                https://platform.slack-edge.com/img/add_to_slack@2x.png 2x"
            />
          </Link>
    </>
  )
}

are there other settings that need to be in here to make that work?

I also just added the redirect url of {URL}/slack/oauth_redirect to it but that did not seem to change anything

app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=oauth_state_store,
        scopes=["channels:join","channels:read","chat:write","chat:write.public","commands","im:read","im:write","mpim:write"],
        user_scopes=["chat:write"],
        install_page_rendering_enabled=False,
        redirect_uri=os.environ["redirectURL"]
    ),
)
github-actions[bot] commented 1 year ago

👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.

ryanrestivo commented 1 year ago

Is there anything else I can do to prevent this oauth error from showing up? I tried teh first solution but I have heard that people still have errors with it when they try with the button

seratch commented 1 year ago

@ryanrestivo

https://slack.com/oauth/v2/authorize

To properly use bolt-python's state paraemter validation, you cannot use this slack.com URL as the starting point of the OAuth flow (because it does not provide state parameter, which is highly recommended for general OAuth security; see https://auth0.com/docs/secure/attack-protection/state-parameters for details). You can set your /slack/install URL instead of https://slack.com/oauth/v2/authorize.

ryanrestivo commented 1 year ago

thanks! so that slack/install URL for the button is the proper usage for that spot. thank you! I'll make that change.