Add infrastructure for Duo privacy notice in non-public Slack contexts
What does this MR do and why?
Infrastructure foundation for the Duo-in-Slack privacy notice, split out of !244130 (closed) per reviewer suggestion (!244130 (comment 3550890954)) to separate the parts requiring database review from the feature behavior and docs.
Duo-from-Slack sessions are recorded in the shared duo-workspace project and visible to everyone with access to it, which may be a wider audience than a private channel or group DM in Slack. A follow-up MR shows a one-time ephemeral privacy notice when the bot is mentioned in a non-public conversation. This MR adds the pieces that notice needs:
- Database (requires database review): adds a nullable
duo_privacy_notice_acknowledged_attimestamp column tochat_names, withChatName#duo_privacy_notice_acknowledged?andChatName#acknowledge_duo_privacy_notice!helpers. The acknowledgement is stored per user per Slack workspace. - Slack scopes and API: requests the
channels:read,groups:read,im:read, andmpim:readbot scopes on app installation and addsSlack::API#conversation_info(conversations.info) so the app can determine whether a conversation is public, private, a DM, or a group DM. Also allows passing Block KitblockstoSlack::API#post_ephemeralso the notice can render interactive buttons. SlackBlockActions::BaseHandler: a base class for Slack block action button handlers, providing shared button-value parsing, Slack installation lookup, andresponse_urlmessage replacement. This directly addresses reviewer feedback about duplicated logic between the two privacy notice handlers (!244130 (comment 3550890942)); both handlers in the follow-up MR inherit from it.
No user-facing behavior changes in this MR: the new column is unread, the new scopes are only requested on (re)installation, and the base handler has no subclasses yet.
Split plan
| MR | Content |
|---|---|
| This MR | Infrastructure foundation (database, Slack scopes/API, base handler) |
| Follow-up | Feature behavior (privacy notice in AppMentionedService, acknowledge/decline handlers) |
| Follow-up | Docs (requires technical writer review) |
References
- Resolves part of https://gitlab.com/gitlab-org/gitlab/-/work_items/603712
- Split out of !244130 (closed)
Screenshots or screen recordings
No visible changes.
How to set up and validate locally
-
Run the migration and confirm the column exists:
bin/rails db:migrate ChatName.column_names.include?('duo_privacy_notice_acknowledged_at') # => true -
Check the helper methods:
chat_name = ChatName.first chat_name.duo_privacy_notice_acknowledged? # => false chat_name.acknowledge_duo_privacy_notice! chat_name.duo_privacy_notice_acknowledged? # => true -
Verify the new scopes are part of the installation request:
SlackIntegration::SCOPES # includes channels:read, groups:read, im:read, mpim:read -
With a Slack app configured against your GDK,
Slack::API#conversation_infocan be exercised from the console:slack_installation = SlackIntegration.with_bot.first Slack::API.new(slack_installation).conversation_info(channel: '<channel-id>')
Database
Adds a nullable timestamptz column (no default, no index, no FK) to
chat_names, a small table. Migration tested in the parent MR against
GitLab.com data: 4.2 s runtime, +0.00 B size change
(see the database testing pipeline comment on the parent MR).
The db:gitlabcom-database-testing job has been triggered on this MR and
will post its results as a comment.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.