Commit Graph

1 Commits

Author SHA1 Message Date
Jeremy Stanley 26fc3d406a create read-only "secondary" db user for dev/test
and activate this user while on the "secondary" in tests

Canvas uses read-only secondary database replicas, but before now,
GuardRail.activate(:secondary) had no effect in specs. The result
is that specs wouldn't catch attempts to write to a secondary,
and the error would be discovered in production, often requiring
a hotfix.

This patchset sets up a migration that creates a `canvas_readonly_user`
in the database and sets up SELECT permissions for it in each
shard's schema. (The migration does nothing in production.)

It also stubs out GuardRail in specs to run
`SET ROLE canvas_readonly_user` when activating the secondary,
and `RESET ROLE` when returning to the primary.

test plan:
 - specs pass (this PS includes specs that attempt to write to
   the secondary and verify the correct error is raised)
 - use the read-only user in development by adding the following
   to the development section in config/database.yml:

     secondary:
       username: canvas_readonly_user

   then try to write to the secondary in the rails console and
   ensure you get a permission denied error. for example,

     GuardRail.activate(:secondary) { User.create! }

   should result in

     PG::InsufficientPrivilege: ERROR:  permission denied for
     table users (ActiveRecord::StatementInvalid)

flag = none
closes LS-2818

Change-Id: Ibfa75af821eb7f5d65f6b26aea03417378ab255a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/161086
QA-Review: Isaac Moore <isaac.moore@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2021-11-10 22:21:23 +00:00