Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
SECURITY: Prevent email from being nil in InviteRedeemer (#19004)
This commit adds some protections in InviteRedeemer to ensure that email can never be nil, which could cause issues with inviting the invited person to private topics since there was an incorrect inner join. If the email is nil and the invite is scoped to an email, we just use that invite.email unconditionally. If a redeeming_user (an existing user) is passed in when redeeming an email, we use their email to override the passed in email. Otherwise we just use the passed in email. We now raise an error after all this if the email is still nil. This commit also adds some tests to catch the private topic fix, and some general improvements and comments around the invite code. This commit also includes a migration to delete TopicAllowedUser records for users who were mistakenly added to topics as part of the invite redemption process.
- Loading branch information
1 parent
78157b4
commit a414520
Showing
6 changed files
with
506 additions
and
213 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
db/migrate/20221103051248_remove_invalid_topic_allowed_users_from_invites.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| class RemoveInvalidTopicAllowedUsersFromInvites < ActiveRecord::Migration[7.0] | ||
| def up | ||
| # We are getting all the topic_allowed_users records that | ||
| # match an invited user, which is created as part of the invite | ||
| # redemption flow. The original invite would _not_ have had a topic_invite | ||
| # record, and the user should have been added to the topic in the brief | ||
| # period between creation of the invited_users record and the update of | ||
| # that record. | ||
| # | ||
| # Having > 2 topic allowed users disqualifies messages sent only | ||
| # by the system or an admin to the user. | ||
| subquery_sql = <<~SQL | ||
| SELECT DISTINCT id | ||
| FROM ( | ||
| SELECT tau.id, tau.user_id, COUNT(*) OVER (PARTITION BY tau.user_id) | ||
| FROM topic_allowed_users tau | ||
| JOIN invited_users iu ON iu.user_id = tau.user_id | ||
| LEFT JOIN topic_invites ti ON ti.invite_id = iu.invite_id AND tau.topic_id = ti.topic_id | ||
| WHERE ti.id IS NULL | ||
| AND tau.created_at BETWEEN iu.created_at AND iu.updated_at | ||
| AND iu.redeemed_at > '2022-10-27' | ||
| ) AS matching_topic_allowed_users | ||
| WHERE matching_topic_allowed_users.count > 2 | ||
| SQL | ||
|
|
||
| # Back up the records we are going to change in case we are too | ||
| # brutal, and for further inspection. | ||
| # | ||
| # TODO DROP this table (topic_allowed_users_backup_nov_2022) in a later migration. | ||
| DB.exec(<<~SQL) | ||
| CREATE TABLE topic_allowed_users_backup_nov_2022 | ||
| ( | ||
| id INT NOT NULL, | ||
| user_id INT NOT NULL, | ||
| topic_id INT NOT NULL | ||
| ); | ||
| INSERT INTO topic_allowed_users_backup_nov_2022(id, user_id, topic_id) | ||
| SELECT id, user_id, topic_id | ||
| FROM topic_allowed_users | ||
| WHERE id IN ( | ||
| #{subquery_sql} | ||
| ) | ||
| SQL | ||
|
|
||
| # Delete the invalid topic allowed users that should not be there. | ||
| DB.query(<<~SQL) | ||
| DELETE | ||
| FROM topic_allowed_users | ||
| WHERE id IN ( | ||
| #{subquery_sql} | ||
| ) | ||
| SQL | ||
| end | ||
|
|
||
| def down | ||
| raise ActiveRecord::IrreversibleMigration | ||
| end | ||
| end |
Oops, something went wrong.