Repository navigation
One user gets "Although the app should be installed into this workspace", while other does not. #664
Description
Activity
Interestingly enough, this error has a comment in bolt library, stating:
# This situation can arise if: # * A developer installed the app from the "Install to Workspace" button in Slack app config page # * The InstallationStore failed to save or deleted the installation for this workspaceBut that's clearly not the case. The app was installed via
/slack/install.
The SlackInstallation is clearly saved since it can be properly used by one of the users.It seems like when receiving a message, Bolt tries to match the user who posted a message with a bot_token in SlackInstallation table. In case of the regular user, who reinstalled the app it finds it and in case if a workspace owner, who deleted the app through config page, but didn't reinstall it, Bolt matches it with an old SlackInstallation that is no longer valid and since it does not give any control to the developer, there is no way to tell bolt to use the newer token from the most recent SlackInstallation.
(Or was bolt supposed to delete SlackInstallation when the workspace owner removed the app somehow? If it's the case it's clearly did not happen and it does not seem to be a very reliable design - since if it was supposed to delete it by receiving some kind of a webhook, and the webhook never fired)
Reacted by bhaktatejas922Also tried inviting a completely new user who didn’t interact with the app in this scenario in slack and adding her in the same channel - event listener gets called without any problems (and she clearly does not have any associated slack installation records in the database).
the problem with the messages coming from workspace admin still persists.
- addedquestionFurther information is requestedFurther information is requested
on Jun 1, 2022 @srajiang could you please specify what kind of info do you need?
Can it probably be fixed with changing the implementation of
DjangoInstallationStore.find_installation?I've come up with a temporary fix.
I've modifiedDjangoInstallationStore.find_installationand made it user_id-agnostic.
Basically I've reduced this part:if user_id is None: rows = ( SlackInstallation.objects.filter(client_id=self.client_id) .filter(enterprise_id=e_id) .filter(team_id=t_id) .order_by(F("installed_at").desc())[:1] ) else: rows = ( SlackInstallation.objects.filter(client_id=self.client_id) .filter(enterprise_id=e_id) .filter(team_id=t_id) .filter(user_id=user_id) .order_by(F("installed_at").desc())[:1] )
to this (without the same user_id, just the recent one):
rows = ( SlackInstallation.objects.filter(client_id=self.client_id) .filter(enterprise_id=e_id) .filter(team_id=t_id) .order_by(F("installed_at").desc())[:1] )
I am not sure if it will cause any problems, though – it seems like it could if the token won't have the same permission scope as expected.
Is there any way to fix this properly?
@DataGreed Thanks for letting us know the details of the issue that you encountered. And I agree that this is a bug on the installation store implementation in the Django example app. Also, the same potential issue can arise even with all the built-in installation store available here.
Changing the query to be user_id agnostic does not work for the use cases where the OAuth flow has both bot scopes and user scopes. Thus, I am thinking of the following changes:
- Run two queries with the installation database table
- 1 - run a query without user_id to fetch the latest bot token data
- 2 - run a query with user_id to fetch the latest user token for the user (if exists)
Merging these query results into one unified Installation data should resolve the issue described here.
Also, as an improvement that you can immediately do, I would suggest subscribing token revocation / uninstallation events and enabling built-in event listeners to properly maintain installation data. Please refer to my comment at #663 (comment) for more details.
Thanks again for sharing this. I will work on the fix later today (in my local time Japan Standard Time +09:00)
Reacted by Alexey- Run two queries with the installation database table
- addedbugSomething isn't workingSomething isn't workingarea:examplesissues related to example or sample codeissues related to example or sample codeand removedquestionFurther information is requestedFurther information is requested
on Jun 2, 2022 @seratch first of all, thank you so much for a quick response and proposed fix, I really appreciate this.
Changing the query to be user_id agnostic does not work for the use cases where the OAuth flow has both bot scopes and user scopes. Thus, I am thinking of the following changes:
-
Run two queries with the installation database table
- 1 - run a query without user_id to fetch the latest bot token data
- 2 - run a query with user_id to fetch the latest user token for the user (if exists)
Merging these query results into one unified Installation data should resolve the issue described here.
@seratch could you please suggest the best way to merge them to avoid any potential problems? Should I get
user_id,user_tokenanduser_scopesfrom theInstallationfound byuser_idand get all other fields from the most recentInstallation?Something like this:
return Installation( app_id=recent_installation.app_id, enterprise_id=recent_installation.enterprise_id, team_id=recent_installation.team_id, bot_token=recent_installation.bot_token, bot_id=recent_installation.bot_id, bot_user_id=recent_installation.bot_user_id, bot_scopes=recent_installation.bot_scopes, # user-specific fields user_id=user_installation.user_id if user_installation else recent_installation.user_id, user_token=user_installation.user_id.user_token if user_installation else recent_installation.user_token, user_scopes=user_installation.user_scopes if user_installation else recent_installation.user_scopes, incoming_webhook_url=recent_installation.incoming_webhook_url, incoming_webhook_channel_id=recent_installation.incoming_webhook_channel_id, incoming_webhook_configuration_url=recent_installation.incoming_webhook_configuration_url, installed_at=recent_installation.installed_at.timestamp(), )
?
Also, as an improvement that you can immediately do, I would suggest subscribing token revocation / uninstallation events and enabling built-in event listeners to properly maintain installation data. Please refer to my comment at #663 (comment) for more details.
Thanks again for sharing this. I will work on the fix later today (in my local time Japan Standard Time +09:00)
Thanks! I somehow overlooked this, I will definitely subscribe to these events.
-
Hi @DataGreed, here is a fix for this issue: #665 Could you verify if it works for your use case?
@seratch sorry for the late answer, I am in UTC+1 and had a sleepless night 😅 Yes, it does fix the problem, thank you!
- added a commit that references this issue
on Jun 2, 2022
Reproducible in:
The
slack_boltversion(same bug with slack-bolt=1.6.0, I've updated hoping it was resolved)
Python runtime version
Python 3.8.9OS info
Steps to reproduce:
app.event("message")listener/slack/installview – by a regular user and a workspace owner#some-channel.app.event("message")listener being triggered properly.#some-channelby regular user.app.event("message")listener being triggered properly.Expected result:
app.event("message")listener being triggered properly for all users when message is posted, not just the one who installed the app againActual result:
Workspace owner gets slack midleware error: