This commit adds a basic modal flow UI for dynamic registration. It
doesn't yet include a way for admins to modify placements or scopes.
flag=lti_dynamic_registration
refs INTEROP-8259
Test Plan:
1. Go to developer keys -> + Developer Key -> + LTI Registration
2. Enter the dynamic registration url for a tool that supports it
3. Click "Continue"
4. Install the tool
5. The modal should close automatically and the new key should be
displayed in the list of developer keys
Change-Id: Ieeb5c1f30556d14480eec8fab872411024c500cf
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/333423
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Paul Gray <paul.gray@instructure.com>
Reviewed-by: Tucker Mcknight <tmcknight@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
This commit implements the Lti::ToolConfiguration "interface" in the
Lti::IMS::Regstration class. This allows the DeveloperKey class
to return a Lti::IMS::Registration object, instead of a
Lti::ToolConfiguration when it is based on the former.
test plan:
Install a Dynamic Registration tool, enable the developer key, and make
sure it is installed in the correct places and is launchable.
fixes INTEROP-7954
flag=lti_dynamic_registration
Change-Id: Ib5602869412dadd06007f278ad3fe29e99e29c28
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/331496
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Tucker Mcknight <tmcknight@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
Product-Review: Alexis Nast <alexis.nast@instructure.com>
Note: if the job fails to enqueue on some shard for the max number of
retries, it will still leave some shards unprocessed. But since this is
an intermittent error that's happened once in the fast 3 months, and we
have backoff in the jobs (I think?) I'm guessing that won't happen and
isn't worth the complexity. It would look something like this:
last_error = nil
Shard.with_each_shard(Shard.in_current_region) do
delay(**enqueue_args).manage_external_tools_on_shard(*args)
rescue => e
# not even sure we want an error report if it's semi-expected???
error_report_id = Canvas::Errors.capture(exception_or_info)[:error_report]
end
raise Delayed::Job::RetriableError, "Error report id: #{error_report_id}" if error_report_id
Test plan:
- have a site admin developer key with some tools installed
- in DeveloperKey#manage_external_tools_multi_shard_in_region,
right before the delay() line, add the following:
STDERR.puts "DEBUGRETRY1!"
Rails.logger.error "DEBUGRETRY1!"
unless $debugretry
STDERR.puts "DEBUGRETRY2!"
Rails.logger.error "DEBUGRETRY2!"
$debugretry = true
raise PG::ConnectionBad
end
- Edit the developer key
- Run jobs and check that the job outputted "DEBUGRETRY2!" (if you want
you can also check for a DEBUGRETRY1 after that)
- Check that the tool(s) were updated
closes INTEROP-8238
flag=none
Change-Id: I7e72669db54bacf56786f0aeaabde32f136b8580
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/329798
Reviewed-by: Steve Mcgee <steve.mcgee@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Steve Mcgee <steve.mcgee@instructure.com>
Product-Review: Evan Battaglia <ebattaglia@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
closes INTEROP-8247
flag=none
Why:
- So tools can launch from the right region from the start, e.g. for
data residency reasons
Test plan:
* modify `development` in config/database.yml to add e.g.,
`region: us-west-2`, where `us-west-2` is some region.
added in the tool configuration. Restart canvas.
* In the UI, create / edit an LTI 1.3 DeveloperKey to have an
"oidc_initiation_urls" property in the settings, with two regions,
including the one you put in config/database.yml. The easiest thing is
to just add a different query parameter for each so your tool will
still launch. e.g.:
"oidc_initiation_urls": {
"us-east-1": "https://mytool/login?region=useast1",
"us-west-2": "https://mytool/login?region=uswest2"
}
* open up dev tools. Launch tool in a couple different placements (e.g.,
assignment_selection and an assignment launch), and observe that the
region-specific URL is launched.
- modify the region in config/database.yml so use a region not in
the config. launch the tool. it should use the default
oidc_initiation_url.
- Edit the developer and modify the initiation URL for the current
region to be not a string. It should fail to save. Not that we allow
additional properties, so if you add e.g.
`"somethingmadeup": "http://someurl.com"`, it won't complain. (I'm
open to changing that, but we don't currently do it for any field in
the schema)
- Try changing oidc_initiation_urls to something other than an object.
Saving should fail.
- Build the documentation with `dexec rake doc:api` and visit the
documentation at `/doc/api/file.lti_dev_key_config.html`. Check that
the added JSON in the example is correct, the copy under
`oidc_initiation_urls` makes sense, and that the link to it under
from the `environments` param info work.
Change-Id: Ie370b677700853beac283739457f9541aa6b36a1
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/329301
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
Product-Review: Alexis Nast <alexis.nast@instructure.com>
This commit squashes three previously seperate commits.
The end result is that Canvas issues "service user" access
tokens via a client_credentials grant. The tokens issued
are unencrypted inst_access tokens.
The individual test plans for each commit have been left intact
Closes CNVS-59194,CNVS-59194,CNVS-59215
flag=site_admin_service_auth
Test Plan:
- Create a developer key in your local site admin account
- Create a user in the site admin account and note
their ID. Also make then a site admin admin
- In a rails console, associate the user to the
key as a service user:
```
key = DeveloperKey.find(<new key>)
key.update!(service_user: User.find(<new user>))
```
- Enable the `site_admin_service_auth` flag
- Make a request the token endpoint using a client
credentials grant and valid client ID/Secret:
```
http POST 'http://canvas.docker/login/oauth2/token?\
client_id=<global dev key ID>&\
client_secret=<dev key api_key>&\
grant_type=client_credentials'
```
- Validate an access token is returned
- Use the token to make a request to `/api/v1/users/self`
and validate the token was genereted for the
service user
- Attempt to make the token request with an invalid
client secret
- Validate a token is not returned
- Attempt to make the token request with the associated
feature flag disabled
- Validate a token is not returned
- Make the service user's workflow_state "deleted" and
attempt to make the token request
- Validate a token is not returned
- Set the DeveloperKey's service_user_id to nil and
attempt the token request
- Validate a token is not returned
- Validate you are unable to retrieve a token when
the developer key is in a "deleted" state
Allow client_credentials service grant internally
Test Plan:
- Validate the test plan for g/323440 continues
to pass
- In addition, validate an access token cannot
be retireved via the client_credentials grant
type + service user unless the DeveloperKey
has `internal_service: true`
Use unecrypted inst_access tokens for client_credentials
Also refactor ClientCredentialsProvider initializer to
us kwargs for argument clarity
Test Plan:
- Make a valid token request using a client_credentials
grant type + a DeveloperKey associated with a
service_user
- Verify an access token is returned
- Verify the access token is associated with the
DeveloperKey's service user
- Verify the access token may be used as a bearer
token in Canvas API endpoints
Change-Id: Ib2a2a3beac1cc04712f8b594e31029471eb359dc
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/326978
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Daniel Matyas Vincze <daniel.vincze@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Closes CNVS-59190
flag=none
Test Plan
- Migrations run without error
- Validate you can now set the service_user
association on a developer key record via
the rails console
- Validate the service_user association is nullable
Change-Id: I2e9489b2001d0bbff48ad365f160ba94693e64c0
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/323426
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Migration-Review: Cody Cutrer <cody@instructure.com>
Migration-Review: Isaac Moore <isaac.moore@instructure.com>
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
[skip-stages=Flakey]
Change-Id: I6abefdfa9fed6dd4525c8786e93efa548b3710f2
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/319603
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Isaac Moore <isaac.moore@instructure.com>
QA-Review: Jacob Burroughs <jburroughs@instructure.com>
Product-Review: Jacob Burroughs <jburroughs@instructure.com>
Build-Review: Jacob Burroughs <jburroughs@instructure.com>
Migration-Review: Jacob Burroughs <jburroughs@instructure.com>
refs INTEROP-7952
flags=none
why
This commit adds a table and matching ActiveRecord model to facilitate
Lti Registrations. This will be further used in building support for
Dynamic Registration.
test plan:
Make sure the migrations run, and the `lti_ims_registrations` table is
created.
Change-Id: I1d3f6b46d08de7dd68254553191de65fdf72138e
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/313519
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
Migration-Review: Jacob Burroughs <jburroughs@instructure.com>
Product-Review: Paul Gray <paul.gray@instructure.com>
This also switches to reading the AWS region from the ARN.
refs AE-60
flag=none
test plan:
- specify `sns_creds` in `vault_contents.yml`
- confirm they're loaded correctly when calling `DeveloperKey.sns`
Change-Id: I40f70d1c78100f002b6611f9fb7b7174cd285adf
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/310869
Reviewed-by: Aaron Ogata <aogata@instructure.com>
QA-Review: Isaac Moore <isaac.moore@instructure.com>
Product-Review: Isaac Moore <isaac.moore@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
why:
- some of the DBAs noticed that we were trying to save URIs longer than
255 characters to the database and silently swallowing the errors.
- we've decided to bump up the size of a valid redirect_uri, as 255
characters is quite short in the grand scheme of things.
- additionally, added a validation on the front and backend to ensure we
don't swallow errors like this again.
flag=none
closes INTEROP-7592
test-plan:
- Run the included migration
- In the UI, try and create a key with one of its redirect_uris having
a length greater than 4096 characters. You should get an alert telling
you that redirect_uri is too long.
- In a rails console, try and create a DeveloperKey with one of its
redirect_uris having a length greater than 4096 characters. You should
get an error from ActiveRecord::Validations saying that one of your
redirect_uris is too long.
Change-Id: I86b437d62f95cbee81dac45250ad4a59fcd6b373
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/306735
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
Product-Review: Ryan Hawkins <ryan.hawkins@instructure.com>
Migration-Review: Jacob Burroughs <jburroughs@instructure.com>
QA-Review: Evan Battaglia <ebattaglia@instructure.com>
why:
* marking a tool as an "internal service" based on its developer_key
and launch url will help Quizzes get the data they need
* not required for any internal tools to continue normal functionality
closes INTEROP-7600
flag=none
test plan:
* load a 1.3 test tool in the Rails console
* `tool.internal_service? "http://quizzes.docker"` should return false
* update the tool's developer_key to have internal_service: true
* `tool.internal_service? "http://quizzes.docker"` should return true
* `tool.internal_service? "http://localhost:3000"` should return true
* `tool.internal_service? "http://bad.domain"` should return false
Change-Id: Idc02f8412267972d57c1eed0d8bfbf40a0fa466a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/298590
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
QA-Review: Evan Battaglia <ebattaglia@instructure.com>
Product-Review: Xander Moffatt <xmoffatt@instructure.com>
closes INTEROP-7536
flag=none
Originally, a couple years ago, I made a commit (41300673) which
required the returned developer key account binding (assuming it wasn't
the site admin binding) to be in the same shard as the account. This was
to prevent returning a binding for the wrong account if the account was
on a different shard as the currently-active shard: for instance, if
on shard 123, running
DeveloperKey.find(10).account_binding_for(Account.find(1240000000000001))
Would construct a queries that used just the local ids of the account
chain, so if on shard 123 there was a binding for the key for local
account 1, it would return that binding.
With the change in 75efcf5a, we no longer look up by relative IDs
(because, with CMC, an account chain can be in multiple shards).
However, that commit introduced two problems which I am fixing here:
1. With that 75efcf5a commit we do a partition_by_shard to always look
up bindings on the shards of the accounts we are looking at.
Therefore, we no longer need to check what shard the resulting
bindings are in. Moreover, the `partition { |b| b.shard ==
Shard.current }` orders accounts incorrectly: if a CMC child has a
parent account on another shard, the CMC parent's bindings will
appear AFTER the child's bindings. If the parent is on the same
shard, the parent's bindings will appear first (desired behavior).
1b. To that end, the check for
accounts.map { |a| a.shard.id }.exclude?(binding.shard.id)
will always be true, because we are looking at bindings only on the
shards of all the accounts.
2. We are making queries with the same `developer_key_id`, no matter
what shard we are on. If we are on the developer key's shard when
running account_binding_for(), this developer_key_id will be local
(< 10**13). If we are looking at accounts on another shard, the
local developer key ID will point to the wrong developer key. For
instance, let's say we have:
Shard 1:
Root Account id=2
Developer Key id=1 for account 2
DeveloperKeyAccountBinding id=111: developer key 1, account 2, ON
Shard 2:
Root Account id=123
Developer Key 1 for account 123
If you are on shard 2 and do
DeveloperKey.find(1).account_binding_for(Account.find(10000000000002))
If will find the binding id=111, which is for the WRONG DeveloperKey.
(A similar wrong query can also happen if, instead of passing in an
account on another shard, you pass in a CMC child with a parent on
another shard).
This commit fixes that by using the developer_key, which will be handled by
Switchman, instead of a raw developer_key_id.
Test plan:
- create a site admin developer key, set to "Allow", and make it visible
- under "Inherited" in the Developer Keys pages:
- in the CMC child account (same shard as parent), set to ON
- in the CMC cross-shard child account, set to ON
- in the CMC parent account, set to ON and then OFF
- in the CMC child account, make sure the key now shows as OFF and
cannot be turned on (same behavior as before)
- in the CMC parent account, make sure the key now shows as OFF and
cannot be turned on (new behavior)
- to double-check, go to a console and switch to the shard with site
admin. Get the developer key and check that account_binding_for
for each of the child accounts returns the bindings for the parent
account. Test the return value of account_binding_for with various
shards activated in the console (e.g. acct1.shard.activate!)
dk = DeveloperKey.find(1)
acct1 = Account.find(10000000000003) # or your same-shard child
acct2 = Account.find(20000000000001) # or your cross-shard child
dk.account_binding_for(acct1) # -> should find the parent binding
dk.account_binding_for(acct2) # -> should find the parent binding
- Also, double check that setting the site-admin key to "on" or
"off" overrides parent and child-account bindings.
Change-Id: I5bc14bdbe36e967b88e783ef098f1bc0b391a8b1
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/296211
Reviewed-by: Tucker Mcknight <tmcknight@instructure.com>
Product-Review: Alexis Nast <alexis.nast@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
Don't use read_attribute since that isn't transposed, use attribute
which is transposed appropriately inside switchman
fixes FOO-2991
Change-Id: I2b28b48bd716e49f3e6239f328b21098a69ce9aa
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/296060
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: August Thornton <august@instructure.com>
QA-Review: Jacob Burroughs <jburroughs@instructure.com>
Product-Review: Jacob Burroughs <jburroughs@instructure.com>
why:
* there is no visibility and no metrics for these jobs
* it will be helpful to see how long these updates take to run,
especially across multiple shards
refs INTEROP-7495
flag=none
test plan:
* with a developer key with tools installed from it
* disable the key, tools should be disabled
* enable the key, tools should be enabled
* update the key settings, tools should be
updated to match
* change the update_tools_on_active_shard!
method to raise an exception
* update the key settings
* the tools won't have updated
* check /error_reports and one should have been generated
Change-Id: I9ca397bbf2450e9226da1e382ec539ec642283b9
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/294519
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Ryan Hawkins <ryan.hawkins@instructure.com>
Product-Review: Xander Moffatt <xmoffatt@instructure.com>
Reviewed-by: Alex Slaughter <aslaughter@instructure.com>
Currently, API keys created in a CMC parent account cannot be used in
any child accounts. This is NOT how they should behave.
By updating the permission check to include the CMC parent account in
the account chain, we can fix this problem.
refs INTEROP-7405
flag=none
[pin-commit-multiple_root_accounts=54f345631ab8c98b2eadad02aa93af5e448d4af0]
test-plan:
- See the commit message for associated commit in multiple_root_accounts
for details on how to test this.
Change-Id: I699175634203c148ef875c6db2801976dfa27c84
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/293441
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
Product-Review: Ryan Hawkins <ryan.hawkins@instructure.com>
why:
* the DeveloperKeyAccountBinding tells the tool installation process
that the context is allowed to use a dev key. In a centrally-managed
consortium, dev keys installed at the parent root account level should
be accessible from any context in any child root account
closes INTEROP-7409
flag=none
test plan:
* with a local CMC set up (see comments on INTEROP-7306 for details)
* install an lti-type developer key at the parent level (the 1.3 test
tool is good for this)
* in a course or account under one of the child root accounts, install a
tool using the developer key's global id
* it should install the tool without failing due to access problems
* alternately, in a rails console find the DeveloperKey and child
root Account
* `dk.account_binding_for(a)` should return the binding for the parent
account, and there should not be a binding directly for the child
* specs directly testing this are in a plugin
Change-Id: I4f6d8bfd0b966341ccbf196041abe97c5db49697
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/291617
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Mysti Lilla <mysti@instructure.com>
QA-Review: Mysti Lilla <mysti@instructure.com>
Product-Review: Alexis Nast <alexis.nast@instructure.com>
fixes INTEROP-7221
flag=no_redirect_on_oauth_token_method
Test plan
- With the no_redirect_on_oauth_token_method FF on
- Set up a non-LTI developer key
- Make a curl request to the token endpoint with an error in it like:
curl "http://localhost:3000/login/oauth2/token"
-d "grant_type=authorization_code"
-d "redirect_uri=http://localhost:3000/courses/1"
-d "code=made_up"
-X POST
-u "1000000000003:
5SAUIr5SgduIpEEtIhvlGFxtcrQBe7x8KNqsy7JyNRRudDoxdIUjYerHtJ0RlwCA"
-i
- It should return a 400 or 401 (if invalid client/code or similar)
instead of giving you a redirect
- The auth endpoint should still work the same as previously
Change-Id: Iaff0ad112c71450a021c32303f9c729c48d30ea2
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/291344
Product-Review: Alexis Nast <alexis.nast@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
And fix up one missed case of using permenant_expires_at directly after
token generation.
fixes FOO-2477
flag = none
test plan: create a new token on the profile page with an expiration,
and it should render on the page correctly before a refresh.
Change-Id: I316f86dc7d011e7fcc33edf3a54ca1ef4ba91067
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275546
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: August Thornton <august@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
QA-Review: Simon Williams <simon@instructure.com>
refs FOO-2410
test plan:
- in dynamic_settings.yml, add the following block:
```
store:
canvas:
services-jwt:
# these are all the same JWK but with different kid
# to generate a new key, run the following in a Canvas console:
#
# key = OpenSSL::PKey::RSA.generate(2048)
# key.public_key.to_jwk(kid: Time.now.utc.iso8601).to_json
jwk-past.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-05-18T22:33:20Z_a\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
jwk-present.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-06-18T22:33:20Z_b\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
jwk-future.json: "{\"kty\":\"RSA\",\"e\":\"AQAB\",\"n\":\"uX1MpfEMQCBUMcj0sBYI-iFaG5Nodp3C6OlN8uY60fa5zSBd83-iIL3n_qzZ8VCluuTLfB7rrV_tiX727XIEqQ\",\"kid\":\"2018-07-18T22:33:20Z_c\",\"d\":\"pYwR64x-LYFtA13iHIIeEvfPTws50ZutyGfpHN-kIZz3k-xVpun2Hgu0hVKZMxcZJ9DkG8UZPqD-zTDbCmCyLQ\",\"p\":\"6OQ2bi_oY5fE9KfQOcxkmNhxDnIKObKb6TVYqOOz2JM\",\"q\":\"y-UBef95njOrqMAxJH1QPds3ltYWr8QgGgccmcATH1M\",\"dp\":\"Ol_xkL7rZgNFt_lURRiJYpJmDDPjgkDVuafIeFTS4Ic\",\"dq\":\"RtzDY5wXr5TzrwWEztLCpYzfyAuF_PZj1cfs976apsM\",\"qi\":\"XA5wnwIrwe5MwXpaBijZsGhKJoypZProt47aVCtWtPE\"}"
```
- Ensure /internal/services/jwks loads correctly
- In console, ensure `CanvasSecurity::ServicesJwt.decrypt(Base64.decode64(CanvasSecurity::ServicesJwt.for_user('localhost', User.first)))`
and `CanvasSecurity::ServicesJwt.decrypt(Base64.decode64(CanvasSecurity::ServicesJwt.for_user('localhost', User.first, symmetric: true)))`
both work and produce sensible looking output
Change-Id: I13c6c35cc92ed12d03bf97e89e590614e11c6d47
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275160
QA-Review: August Thornton <august@instructure.com>
Product-Review: August Thornton <august@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
refs FOO-2265
it doesn't make sense
Change-Id: Ice9184fa621fdf7a27370f40af422d354c27e337
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/271277
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
* use api_find in developer key account bindings controller
* use workflow module instead of writing a bunch of stuff manually for the same
concept
* set some columns NOT NULL
* collapse a hand-written query that actually takes two queries into
using Rails relations and only one
* take out a condition in that query entirely, instead of making a non-sensical
comparison
Change-Id: Ifdf88a6c398c1d6353ec273712383bbd3c9c7907
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/269133
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Jacob Burroughs <jburroughs@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
Main changes when creating a LTI key:
1. When pasting a JSON, the redirect uris field will be auto filled with
the target_link_uri from the JSON tool configuration;
2. When pasting a URL, the redirect uris field will not be required
anymore in the UI, and we'll retrive the target_link_uri from JSON tool
configuration and set it to developer_key.redirect_uris attribute;
closes INTEROP-6492
flag=none
test-plan:
* Add a new Developer Keys by choosing LTI key option;
* Choose `Paste JSON` method:
Paste a JSON into LTI 1.3 Configuration field, and check if
`* Redirect URIs` is auto filled with target_link_uri from the JSON
given, you should be able to save the key;
And keep sure that `* Redirect URIs` field is required and render a
flash message error when saving the form without a proper value for
Redirect URIs;
* Choose `Enter URL` method:
Paste a tool configuration url into JSON URL and you should be able to
save the key;
And keep sure that `Redirect URIs` field is not required anymore;
* You should be able to create without `Key Name` and/or `Owner Email`;
Change-Id: I6efb2647f320d13723a3bca49dab9b8cc81ec939
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/259821
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
Product-Review: Karl Lloyd <karl@instructure.com>
Change-Id: I7f40ed058b50882121da69f0cb05966854b8e920
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/250924
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Simon Williams <simon@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
Change-Id: I70825be7ec7e24458afe0c63dc48c5a76158f520
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/251150
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: Simon Williams <simon@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
Closes INTEROP-6140
flag=none
Test Plan:
- Create a new site admin developer key (a key
with a nil root_account)
- Validate that the root_account_id is set to the
ID of the site admin account
Change-Id: I74f2f764d012aa20ca2f8d656ad450613c266648
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/246585
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
Reviewed-by: Mysti Lilla <mysti@instructure.com>
QA-Review: Mysti Lilla <mysti@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
refs SAS-1540
* adds an audience setting to developer keys, so a key can be set to
target external audiences with its credentials grants
* when a key with an external audience grants credentials, the token is
signed with an asymmetric key instead of the internal symmetric key
* external audiences can retrieve the corresponding public keys from
/login/oauth2/jwks
* credentials issued by developer keys with an account id include the
account's guid in a custom claim
includes a refactor of key storage and rotation in consul, which had
already been done for LTI. but it wasn't really a feature of lti, just
something used by LTI, and we needed the same for key management for
this. moved it to be part of Canvas::Security
Change-Id: Ie5c0fcee6fc21687f31c109389a3bcc1ed349c5d
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/243606
QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
Reviewed-by: Jonathan Featherstone <jfeatherstone@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
refs PLAT-5518
flag=none
test plan:
* specs
* if you want, create a new DeveloperKey, set an account on it, and
note its root_account - it shouldn't be nil, and should match
the account's root account
Change-Id: I31810980aa6d6c234eb4ba0cfa3dcc21012ed250
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/234174
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Mysti Lilla <mysti@instructure.com>
QA-Review: Mysti Lilla <mysti@instructure.com>
Product-Review: Mysti Lilla <mysti@instructure.com>
Refs PLAT-5688
flag=site_admin_keys_only
Test Plan:
This plan assumes a local Canvas setup with the following
items in place:
- MRA
- Root Account 1 and Site Admin account living on shard 1
- Root Account 2 living on shard 2
1. Create a developer key in Root Account 1
2. Create a developer key in Root Account 2
3. Navigate to /accounts/site_admin/developer_keys
4. Verify the keys created in steps 1 and 2 are not
visible in the UI
5. Create a key in the site admin account
6. Make the key visible to inheriting accounts by
clicking the "eye" icon
7 Verify the site admin key is visible in the "inherited"
key tabs of Root Account 1 and Root Account 2
Change-Id: I3e58328b40c7289ee9d8eded8c37f35985eded37
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/234014
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
Product-Review: Karl Lloyd <karl@instructure.com>
Endpoint needed by CDC Event Tranformer to look up UUIDs for root
accounts it hasn't seen.
closes PLAT-5515
flag=none
Test plan:
- get an LTI Advantage token for a site admin dev key with the new scope.
This can be done by adding logging to the live-events-lti tool (I
think in app/services/access_token_service.rb#16) or using my
cdc-event-transformer test in CanvasClientTest.java and printing out
cc.getToken().
- hit the new endpoint with header "Authorization: Bearer MYACCESSTOKEN"
web.canvas-lms.docker/api/lti/accounts/123 with varying
values of account ID, including global IDs, accounts that do not
exist, global IDs where the shard does not exist...
- ideally we'd like to test that a dev key only available for one shard
cannot access account info for another shard. This could be done by
creating two dev keys that have the same ID but are on different
shards, and use a token for one dev key to try to access an account on
the other shard. This is probably hard to do locally though. I did
test on prod that DeveloperKey#account_binding_for will return nil
for an account in another shard even if there is a dev key with the
same local ID in the account's shard that has access to it.
Change-Id: I1299ebce9b94ce00d7cb62db01891b81908915ff
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/229580
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
Product-Review: Evan Battaglia <ebattaglia@instructure.com>
closes PLAT-4857
Test Plan:
- Modify a SiteAdmin LTI dev key
- Locally, make sure tools are updated correctly
- On Production, this should no longer cause a timeout
This is only testable on production due to the # of shards
Change-Id: I4326682d14df3eaa3232aa657ec8a9a9e7cb0478
Reviewed-on: https://gerrit.instructure.com/208963
Tested-by: Jenkins
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Xander Moffatt <xmoffatt@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
Product-Review: Clint Furse <cfurse@instructure.com>
refs PLAT-4493
Test Plan:
-create a developer key and validate the public jwk url field
is present
-save developer key
-edit developer key and validate public jwk url field is present
-save edit and validate edits were saved to developer key
Change-Id: I9019d116ad9995931757439f4c3d63b3d67a3a5f
Reviewed-on: https://gerrit.instructure.com/197713
Tested-by: Jenkins
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Product-Review: Jesse Poulos <jpoulos@instructure.com>