Commit Graph

62 Commits

Author SHA1 Message Date
Ethan Vizitei 015d7abc62 inflect OAuth for zeitwerk
refs FOO-2476
flag=none

TEST PLAN:
  1) specs pass

Change-Id: I9f73e0021f5efec2be3c2f419e758baf00e6914f
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/275642
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Jacob Burroughs <jburroughs@instructure.com>
QA-Review: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Ethan Vizitei <evizitei@instructure.com>
2021-10-13 16:32:05 +00:00
Jacob Burroughs 214014049f Add asymmetric encryption for service tokens
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>
2021-10-06 15:11:06 +00:00
Cody Cutrer 3ef09eed34 allow configuring token expiration for mobile apps
fixes FOO-2336

Change-Id: Ic7f555ae4d85b8b79c7114f43495a638ca2dead2
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/273587
Reviewed-by: Simon Williams <simon@instructure.com>
Reviewed-by: August Thornton <august@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2021-10-04 20:10:39 +00:00
Cody Cutrer 223aedadff rubocop: update to 1.21
[skip-stages=Flakey]

new cop autocorrected: Layout/LineEndStringConcatenationIndentation

Change-Id: Ib59a7fadeb2d9af68d90eb82b9ac855dead29121
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/274524
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>
2021-09-28 02:40:46 +00:00
Cody Cutrer c65d57737a RuboCop: Layout lib
Change-Id: I0655d9a9d750f2debd6378b03d8ddc1403ebc31b
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/274158
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>
2021-09-22 20:01:52 +00:00
Cody Cutrer 160b3c1f69 don't regenerate force-reuse access tokens for userinfo requests
i.e. instfs

in this case, we're never returning the actual access token, so as
long as the token isn't expired, it doesn't matter. and since force
reuse tokens _can't_ expire, it's fine

Change-Id: I8da6c21755586b25fddcf05df8e35dadf8610afa
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/271998
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>
2021-08-24 18:27:11 +00:00
Cody Cutrer 68768f17b8 always regenerate the access token for force_token_reuse
fixes FOO-2265

no more returning no token, because we don't have it. it makes it impossible
to get it if you lost it. instead, if you're a force_token_reuse integration
you _must_ invalidate prior access tokens everytime you request a new one

Change-Id: I66d52279abf3d58e5a6d2c90d97007077a73e68d
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/271276
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>
2021-08-12 17:58:33 +00:00
Xander Moffatt 7096c0a96d allow site admin to get LTI token for any 1.3 tool
why:
* getting an LTI access token currently requires installing the LTI 1.3
test tool and configuring it then requesting a token,
or otherwise hacking other tools to make a request
to the token endpoint
* it can be very helpful for troubleshooting to have an
LTI access token for any needed tool
* note that 1.1 tools don't have DeveloperKeys, and 2.0 tools use their
own access tokens. this main use case is for 1.3 tools and for the AGS.

test plan:
* choose a 1.3 ContextExternalTool
* navigate to canvas.docker/api/lti/advantage_token?tool_id=<tool's id>
* it should return an access token in the form of a JWT
* choose a DeveloperKey that is an LTI 1.3 key
* navigate to canvas.docker/api/lti/advantage_token?client_id=<key's id>
* it should return an access token
* choose a DeveloperKey that isn't for an LTI tool
* this url should return 400 and say it must be a 1.3 key
* choose a ContextExternalTool that isn't 1.3
* this url should return 400 and say it must be a 1.3 tool
* sign out of Canvas
* this url should return unauthorized
* sign in as a non-site-admin user
* this url should return unauthorized

Change-Id: Ie599fe3c4a8413ad0a65515837360c439ddb3b9c
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/269109
Reviewed-by: Mysti Lilla <mysti@instructure.com>
QA-Review: Mysti Lilla <mysti@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Product-Review: Xander Moffatt <xmoffatt@instructure.com>
2021-07-20 20:07:09 +00:00
Cody Cutrer 06763dd519 add # frozen_string_literal: true for lib
Change-Id: I59b751cac52367a89e03f572477f0cf1d607b405
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/251155
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>
2020-10-27 20:49:50 +00:00
Cody Cutrer cac3e6c869 use find_cached for directly loading a developer key
also be sure and cache nil

Change-Id: I1043ed48609294d76ecb1bfc70770113fc5d44ac
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/248349
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2020-09-23 22:02:49 +00:00
Jacob Fugal 2b3886c5f4 extend client_credentials oauth2 grants for CD2
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>
2020-08-13 18:52:47 +00:00
Rob Orton 56f97d0f12 make access token for real_user
access tokens cannot be created when masquerading a user on purpose,
because this would allow a user to get the real token and use it when
permissions for the user could change in the future. A commit was made
ee50eec4bd to create the access tokens
used when doing an lti launch on the real_user instead of the user, but
this breaks some tools that are not handling all the masquerade data.
c94b34348a reverted that change to create
them on the user again.

This commit is adding a column to access_token so we can audit usage of
the tokens created from an LTI launch. When a token is created while
masquerading we add the real_user_id to the token and make the token
expire in one hour.

test plan
 - masquerade as a user
 - launch an lti_tool that creates an access token
 - the tool should see the end users token
 - in a console verify the token is set to expire in an hour
 - verify that real_user_id is used on the token
 - the token should expire within an hour

fixes KNO-464
flag=none

Change-Id: I1f8913fc536f4e2c8539551efed69b27fbdb6b1a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/236443
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Davis Hyer <dhyer@instructure.com>
QA-Review: Davis Hyer <dhyer@instructure.com>
Product-Review: Davis Hyer <dhyer@instructure.com>
2020-05-20 22:00:00 +00:00
Cody Cutrer c94b34348a Revert "issue access tokens from the real user, not the masqueraded user"
This reverts commit ee50eec4bd.

Reason for revert: need to more fully flesh out how masquerading can
be transparently handled for OAuth consumer.

Change-Id: I340b8914e3eff7c3156e1a06bae1ca6c9d10c1bd
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/236010
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Rob Orton <rob@instructure.com>
QA-Review: Rob Orton <rob@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
2020-05-07 16:47:24 +00:00
Cody Cutrer ee50eec4bd issue access tokens from the real user, not the masqueraded user
fixes USERS-457

test plan:
 * login to the mobile app via qr code while masquerading
 * the app should behave as if you're the masqueraded user
 * inspecting user profiles in the web app, a token should
   have been issued to the masquerading user, but not the
   masqueradee
 * confirm inst-fs works while masquerading

Change-Id: I82b6a310f8b31ffa6cf824b95f0734056292deb6
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/230784
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
Reviewed-by: James Williams <jamesw@instructure.com>
Reviewed-by: Keith Garner <kgarner@instructure.com>
2020-04-15 17:22:29 +00:00
Drake Harper 96b6be4d2d Fix follow oauth2 flow for scopes error handling
Fixes PLAT-4681

Test Plan:
-set up an lti key
-hit /login/oauth2/auth?client_id=tool_id&response_type=code
	&state=YYY&redirect_uri=some_url&scope=url:GET
-verify that redirect was redirected to with error type and description

Change-Id: I724f503e31edd449f29e3a894d492a11cca61279
Reviewed-on: https://gerrit.instructure.com/203250
Tested-by: Jenkins
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Tucker Mcknight <tmcknight@instructure.com>
Product-Review: Jesse Poulos <jpoulos@instructure.com>
2019-08-07 21:04:12 +00:00
Drake Harper 7f06be5d9c Fix json parse error in using jwk via url
refs PLAT-4494

Test Plan:
-make a request that goes through the client credentials flow
-validate that it works

Change-Id: Ic008485f1a286b9923e514abeda17f88b9d39a5c
Reviewed-on: https://gerrit.instructure.com/200219
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
QA-Review: Drake Harper <dharper@instructure.com>
Product-Review: Drake Harper <dharper@instructure.com>
Tested-by: Jenkins
2019-07-05 13:53:39 +00:00
Drake Harper 0447600a63 Use public jwk url in oauth 2 flow
refs PLAT-4494

Test Plan:
-using create and edit devloper key
	-use public jwk url to set public jwk

Change-Id: Iaa80a89dd37052ffd6866ad8d019e8779eaa67b3
Reviewed-on: https://gerrit.instructure.com/198518
Tested-by: Jenkins
Reviewed-by: Marc Phillips <mphillips@instructure.com>
Product-Review: Drake Harper <dharper@instructure.com>
QA-Review: Drake Harper <dharper@instructure.com>
2019-07-03 21:40:54 +00:00
Boudewijn van Groos 2d210624e3 Include missing scopes in error message
refs: GH-1466

Test Plan:
- Set up a developer key with scopes enabled.
- Using a tool like oauth2-client-shell request access at
  https://<canvas-install-url>/login/oauth2/auth with at least a
  single scope which is not enabled on the developer key.
- Observe the error message (it should contain the requested scope
  which is missing, but none of the scopes which are requested, but
  not enabled).

Change-Id: I66789f556f7105377459a34fddd43ffdb6e6f93e
Reviewed-on: https://gerrit.instructure.com/198402
Tested-by: Jenkins
Reviewed-by: Spencer Olson <solson@instructure.com>
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Bryan Petty <bpetty@instructure.com>
Product-Review: Bryan Petty <bpetty@instructure.com>
2019-07-03 14:55:09 +00:00
Marc Phillips 3d7d728f9d Fix ClientCredentials for local development
Was hardcoding the aud to be https, when we
are requiring http endpoints.

refs PLAT-4474

Test Plan:
 - Use of the 1.3 tool to do services should work

Change-Id: Id8bd6ce92dcefecb6d046316704cf7db937fdebc
Reviewed-on: https://gerrit.instructure.com/193079
Tested-by: Jenkins
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Product-Review: Marc Phillips <mphillips@instructure.com>
2019-05-13 19:06:46 +00:00
Rob Orton 4296381ded don’t try stuff on nil
fixes CANVAS-5DQZ - show_helper 133k
fixes CANVAS-4VFR - quizzes_controller 293k
fixes CANVAS-4VFT - oauth/providor 287k
fixes CANVAS-5T4G - oauth2_providor_controller 11k
fixes CANVAS-4VQF - context_modules_controller 13k
fixes CANVAS-4W6A - grades.html.erb 1k
fixes CANVAS-4SNC - discussion_entry 46k
fixes CANVAS-4VJY - dup of discussion_entry 16k
fixes CANVAS-4SYM - users_controller 51k
fixes CANVAS-4VRJ - quiz_submission_history 3.3k
fixes CANVAS-4Y92 - gmail 51k
fixes CANVAS-4VM8 - media_object 7.8k
fixes CANVAS-4VHB - quiz_submission_events 9.2k
fixes CANVAS-6WSZ - course.rb 5
fixes CANVAS-5SD6 - active_record 33
fixes CANVAS-6WYD - dup of active_record 1
fixes CANVAS-4VHG - collaborations_controller 24k
fixes CANVAS-6PFH - files/show 2.2k
fixes CANVAS-4VSR - pv4_client 14k

Change-Id: I12cf698c6930ef4674ecfee02bc341e3650ef7fc
Reviewed-on: https://gerrit.instructure.com/188120
Tested-by: Jenkins
Reviewed-by: Brent Burgoyne <bburgoyne@instructure.com>
QA-Review: Brent Burgoyne <bburgoyne@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
2019-05-03 21:01:35 +00:00
James Williams d1b16a0dd3 Revert "don't refresh oauth token if recently changed"
This reverts commit 07b074e16e.

closes #CORE-2432

Change-Id: Ie0b1d99d74ddec72008f51611fdf58b7510732c8
Reviewed-on: https://gerrit.instructure.com/180890
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: Cody Cutrer <cody@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2019-03-26 20:23:50 +00:00
Marc Phillips 52fe806eaa Fix oauth2 authorization code client_id check
Global_ids where not able to be used in the authorization
code workflow. Now global ids can be used.

closes PLAT-4146

Change-Id: Iad60f2cd197616f0773648ec8c747e2541d1e055
Reviewed-on: https://gerrit.instructure.com/182344
Tested-by: Jenkins
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Product-Review: Marc Phillips <mphillips@instructure.com>
2019-02-22 17:15:21 +00:00
wdransfield 7de0f76588 Handle string claims and protocol in client credentials grant
Closes PLAT-4143

Test Plan:
- Attempt to retrieve an access token using the client
  credentials grant type. Make the exp or iat claims
  non-numeric
- Verify Canvas responds with a 400 and error message
- Verify the aud must be https

Change-Id: Iefc9b286d9198f0afd759c9a05b1dd8b22647aa4
Reviewed-on: https://gerrit.instructure.com/177837
Tested-by: Jenkins
Reviewed-by: Marc Phillips <mphillips@instructure.com>
QA-Review: Marc Phillips <mphillips@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
2019-01-16 19:12:22 +00:00
Marc Phillips 6f6e5f8c48 Fix client_credentials grant tokens
Erroneously checking the jti as if it was a nonce.
This allows the tokens to be used more often than
once.

closes PLAT-4084

Test Plan:

Generate a ccg token and attempt to make a call
a few times. Note that it works. Make sure that
you have redis enabled locally.

Change-Id: I4eeed1019ac9ca04956713ed84a2a922b4ffdde0
Reviewed-on: https://gerrit.instructure.com/176586
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: Nathan Mills <nathanm@instructure.com>
Tested-by: Jenkins
Product-Review: Marc Phillips <mphillips@instructure.com>
2019-01-02 21:25:58 +00:00
James Williams 07b074e16e don't refresh oauth token if recently changed
closes #CORE-1113

Change-Id: Id9ba35e2f0f4b4fc710a84d8c94d20b315bee1ab
Reviewed-on: https://gerrit.instructure.com/175522
Reviewed-by: Cody Cutrer <cody@instructure.com>
Tested-by: Jenkins
QA-Review: James Williams <jamesw@instructure.com>
Product-Review: James Williams <jamesw@instructure.com>
2018-12-14 16:11:56 +00:00
Cody Cutrer 14edde158d add effective_locale to a few API responses
closes CORE-1847

test plan:
 * have your user inheriting the default locale
 * go to /api/v1/users/self, /api/v1/users/self/profile. they should
   both have a non-null value for effective_locale, even though
   locale is null
 * to through the OAuth flow. notice that a value is provided
   for effective_locale in the user portion of the /token response

Change-Id: Ia8b5b555168db395fe15075d70b296c264a59d6d
Reviewed-on: https://gerrit.instructure.com/171446
Tested-by: Jenkins
Reviewed-by: James Williams <jamesw@instructure.com>
QA-Review: Jeremy Putnam <jeremyp@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2018-11-14 05:34:57 +00:00
Marc Phillips efdba8d77c Add client_credentials grant_type
Oauth2.0 client_credentials grant_type is added as a means
to support LTI Advantage services. Will accept only the
client_assertion_type of jwt-bearer and returns a JWS as
the access token. LTI services using the jws will be able to
authenticate, but other api endpoints will fail when using
this jwt.

closes PLAT-3659

Test Plan:
 - Create an oauth 2.0 request using a jwt signed by a
   developer key
 - Request should be validated and returns a jwt with
   the correct scopes

Change-Id: I786b71e39f8d3c2c9c71aa3eff4ea490f6d56285
Reviewed-on: https://gerrit.instructure.com/161245
Tested-by: Jenkins
QA-Review: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
Product-Review: Marc Alan Phillips <mphillips@instructure.com>
2018-09-10 17:07:05 +00:00
Marc Phillips a66493c16d Refactor Oauth2 Provier controller into GrantTypes
To make adding additional grant_types easier and cleaner in the
future, refactor the existing Oauth2_provider_controller to
push the token generation to grant type objects.

refs PLAT-3659

Test plan:
 - Run through the oauth 2 flow for both grant types
 - Everything should still work

Change-Id: Ic5fe4a4cc39231620003977c33350f4d98879b0f
Reviewed-on: https://gerrit.instructure.com/160484
Tested-by: Jenkins
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Marc Alan Phillips <mphillips@instructure.com>
2018-08-16 21:53:25 +00:00
Marc Phillips a9a8ce9ff7 Ensure Requested Scopes Valid for Key
fixes PLAT-3310

Test Plan:
 - Create a dev key with scopes enabled
 - After creating dev key, create an oauth 2
   Access Token by hitting the endpoint as
   described in
https://canvas.instructure.com/doc/api/file.oauth_endpoints.html#get-login-oauth2-auth
 - Should throw an error with invalid_scope as the error
 - Create an access token using the same flow with require_scopes
   turned off, should be true

Change-Id: Id487888bc0323a6003740f1879107f0bbc677568
Reviewed-on: https://gerrit.instructure.com/151291
Tested-by: Jenkins
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Marc Alan Phillips <mphillips@instructure.com>
2018-05-24 21:00:23 +00:00
Jacob Fugal 59e375fc47 include real user in oauth token
closes RECNVS-417

We want to give InstFS accurate information about who is actually
accessing files in canvas, even if they're masquerading as someone else.
This commit adds that additional information without breaking the normal
oauth flow for other apps that use oauth.

test plan:
* Check out g/148868 in your instfs repo
* Have canvas configured with inst-fs
* Log in to canvas as an admin
* While masqueraded as another user
  - delete your inst-fs session cookie
  (Go to api.instfs.docker and clear your cookies for that site)
  - visit a canvas page displaying inst-fs files; this will
  regenerate your inst-fs session
* base64 decode the new inst-fs session cookie; verify that it holds
  the admin's user id and not the masqueraded-as user's id

Change-Id: I0790be317bf41290bcbeec672145dc64625573a0
Reviewed-on: https://gerrit.instructure.com/148142
Tested-by: Jenkins
Reviewed-by: Jacob Fugal <jacob@instructure.com>
QA-Review: Collin Parrish <cparrish@instructure.com>
Product-Review: Andrew Huff <ahuff@instructure.com>
Reviewed-by: Andrew Huff <ahuff@instructure.com>
2018-05-07 21:52:53 +00:00
Simon Williams f3c150716c Revert "report the logged in user in oauth response"
This reverts commit a25dbdf21f.

We discovered there's a bug in the non-trusted key flow, and we
discovered this impacts our support and admin teams providing support
for LTI tools. We have some ideas to do this better, but for now, we're
just reverting while we re-evaluate.

closes RECNVS-405

test plan: see reverted commit

Change-Id: I5147c6dff093b609bba8095cad1d5febb312d993
Reviewed-on: https://gerrit.instructure.com/145840
Reviewed-by: Cody Cutrer <cody@instructure.com>
Reviewed-by: Michael Jasper <mjasper@instructure.com>
Tested-by: Jenkins
QA-Review: Collin Parrish <cparrish@instructure.com>
Product-Review: Simon Williams <simon@instructure.com>
2018-04-04 20:07:12 +00:00
Jacob Fugal a25dbdf21f report the logged in user in oauth response
refs RECNVS-264

in the case where the logged in user has an existing session in which
they're masquerading as another user, the oauth negotiation should
report the former, not the latter.

test-plan:
- have two users, one an admin
- have two oauth2 developer keys, one trusted
- log in as the admin then masquerade as the other user
- attempt to oauth against canvas using the untrusted developer key;
  should redirect to the login page with an error about the masquerading
  instead of redirecting to the confirmation page
- attempt to oauth against canvas using the trusted developer key;
  should succeed, and when exchanging the returned code it should
  identify the admin instead of the other user

Change-Id: I5d8c0fa47bd672d3b4ddb53bccb85f8596f708ff
Reviewed-on: https://gerrit.instructure.com/142365
Reviewed-by: Cody Cutrer <cody@instructure.com>
Tested-by: Jenkins
QA-Review: Jonathan Featherstone <jfeatherstone@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
2018-03-06 22:51:43 +00:00
Cody Cutrer 94abfb09ce fix remember me for /auth/userinfo tokens
fixes CORE-630

reverts commit d5e851f

test plan:
 * create a new developer key (one with auto_expire_tokens=true, which
   should be the default)
 * go through the oauth flow, without checking remember me, but with
   specifying scope=/auth/userinfo
 * the token you get back should have access_token= null, and
   expires_at= null
 * go through the process again, but check remember me this time
 * same result
 * go through the process a third time, and this time it shouldn't even
   prompt you to approve the login

Change-Id: Ia55833f179783d385e73a193f03548bd4bc33f25
Reviewed-on: https://gerrit.instructure.com/132664
Tested-by: Jenkins
Reviewed-by: Rob Orton <rob@instructure.com>
QA-Review: Tucker McKnight <tmcknight@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2017-11-16 18:48:03 +00:00
Andrew Huff 759b6c13b4 add global_id field to oauth token
closes CNVS-39998

test plan: specs

Change-Id: I4d3cce2f4ca0765947cfab17e0abf810f9ca2078
Reviewed-on: https://gerrit.instructure.com/129864
Tested-by: Jenkins
Reviewed-by: Jacob Fugal <jacob@instructure.com>
QA-Review: Jacob Fugal <jacob@instructure.com>
Product-Review: Andrew Huff <ahuff@instructure.com>
2017-10-16 21:30:12 +00:00
Rob Orton d5e851f45d ignore remember_authorization when scopes are passed to oath2
fixes CNVS-38969

test plan
 - requesting GET login/oauth2/auth with
   scope=/auth/userinfo and check the  box to
   "Remember my authorization for this service"
 - it should ignore the remember_authorization

Change-Id: I19ab585300aeb604243553c3fe31eaa360901f8a
Reviewed-on: https://gerrit.instructure.com/126857
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: Tucker McKnight <tmcknight@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
2017-09-27 19:16:45 +00:00
Landon Wilkins f1359d33e2 da licença part 27
add consistent license headers to all source files
(ruby, coffeescript, javascript)

except for vendor files

Change-Id: I331826e3e3be8b7d73bbf4f6afe3a79ec1340f54
Reviewed-on: https://gerrit.instructure.com/110051
Tested-by: Jenkins
Reviewed-by: Jon Jensen <jon@instructure.com>
Product-Review: Jon Jensen <jon@instructure.com>
QA-Review: Jon Jensen <jon@instructure.com>
2017-04-27 21:53:31 +00:00
Cody Cutrer 22e6f2edc1 validate response_type param to OAuth2 auth endpoint
fixes CNVS-28860, CNVS-28861

and redirect back with error, instead of rendering directly

test plan:
 * try oauth flow without a response_type param; it should redirect
   back to you with an error=unsupported_response_type query param
 * try oauth flow with a key not associated with the current root
   account; it should redirect back to you with an
   error=unauthorized_client

Change-Id: I2ea2e15f6ceb4d6858c0b40d3b44298dfeba7a60
Reviewed-on: https://gerrit.instructure.com/77650
Tested-by: Jenkins
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Nathan Mills <nathanm@instructure.com>
Reviewed-by: Rob Orton <rob@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2016-04-22 22:23:54 +00:00
Cody Cutrer 11ac0d76f1 include token_type: 'Bearer' in oauth access token response
fixes CNVS-28863

test plan:
 * go through oauth flow
 * the response giving you your access token should include
   "token_type": "Bearer"

Change-Id: I8a94f4f6df8db8fb5be3a50143af646c0ba61c31
Reviewed-on: https://gerrit.instructure.com/77642
Tested-by: Jenkins
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2016-04-22 20:24:18 +00:00
Cody Cutrer 0db7878007 validate client id on refresh token "renewal"
fixes CNVS-28858

also get rid of deprecated messages, and return a proper 401 for
invalid client credentials, as per spec

test plan:
 * have a developer key, go through the oauth flow, and get a refresh
   token
 * user the refresh token to get a new access token making sure it works
 * create a second developer key; try to get a new access token with
   your existing refresh token, but authenticating with the new
   client credentials
 * it should fail

Change-Id: Ide95e317dd8768abd9fb3ab4eb67225a6e58bbcb
Reviewed-on: https://gerrit.instructure.com/77634
Tested-by: Jenkins
Reviewed-by: Simon Williams <simon@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2016-04-22 20:24:12 +00:00
Brad Horrocks ee6c8072cb Don't send refresh_token if value is nil
Fixes PLAT-1298

Test Plan:
Make sure when refreshing a token we aren't
sending back refresh_token

Change-Id: I85fdc9504143021f8ffd7c1320fad538d37a38d3
Reviewed-on: https://gerrit.instructure.com/69037
Reviewed-by: Nathan Mills <nathanm@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Brad Horrocks <bhorrocks@instructure.com>
2015-12-18 18:02:50 +00:00
Brad Horrocks 62847b535b reset expiration on access_token regeneration
Fixes PLAT-1289

Test Plan:
do a refresh_token call
make sure the expiration is reset back to 3600 (an hour)

Change-Id: I17095e77211c49c43ea8ff217013d5986e6b6c91
Reviewed-on: https://gerrit.instructure.com/67373
Tested-by: Jenkins
Reviewed-by: Brad Humphrey <brad@instructure.com>
Product-Review: Brad Horrocks <bhorrocks@instructure.com>
QA-Review: August Thornton <august@instructure.com>
2015-11-18 16:56:41 +00:00
Nathan Mills 2bceb54da7 start expiring access tokens created by new dev keys
add warning message to the api docs about expiring access tokens

fixes PLAT-1263 PLAT-1243

test plan:
*create a developer key before cherry picking change set
*cherry-pick change set
*generate an Access Token using the old dev key
*it should not have an expiration

*create a new developer key
*create an access token with the new dev key
*it should have an expiration

*check the api doc on the oauth page for the warning message

Change-Id: Id53d9b7fab4b8b308a0abbae0268c1c25a2d4c6f
Reviewed-on: https://gerrit.instructure.com/64881
Reviewed-by: Brad Horrocks <bhorrocks@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Nathan Mills <nathanm@instructure.com>
2015-10-28 22:00:55 +00:00
Brad Horrocks 63fb5ab470 Generate a access token with the refresh token
Added grant_type request param. It will default to authorization_code if
its not set AND the code param is supplied.

Updated errors to be OAuth2 compliant. At some point we should remove
the legacy keys from Canvas::Oauth::RequestError.ERROR_MAP

Fixes PLAT-1219

Test Plan:
You MUST have a developer key
You MUST have a valid refresh_token
See test plan if you need the above: https://gerrit.instructure.com/#/c/63256/

Sample curl (plz change refresh_token, client_id, and client_secret):
curl 'http://blackmesa.canvas.dev/login/oauth2/token' --data
'refresh_token=1c8d2ff5498eb879db9737d494a4bbd64810c84cf7e1776d1f4cebdb9699244c6209add4838d02f0d67b969a599cee589fecbeef5f84ababb1ef6e4cb9099b68&client_id=30000000000001&client_secret=AHv7hXoImZdplvbTEcZaJ9zJF51F7ny82iHz0dCnmbIdqndA2cGU75iJnrezH5QB&grant_type=refresh_token'

Change-Id: I02d3f9c7dd01f26076720d74dea61a8c682b8f9a
Reviewed-on: https://gerrit.instructure.com/64433
Tested-by: Jenkins
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Brad Horrocks <bhorrocks@instructure.com>
2015-10-08 21:53:53 +00:00
Nathan Mills 7e4ffb6ffc remove expiration code for oauth tokens
test-plan:
when you get an access via oauth2 token you shouldn't get an expiration, and it shouldn't be set in the db

Change-Id: Ie0b15b54ef789b9a94b726026c09fe9497f0adc5
Reviewed-on: https://gerrit.instructure.com/64749
Reviewed-by: Brad Horrocks <bhorrocks@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Nathan Mills <nathanm@instructure.com>
2015-10-07 21:59:34 +00:00
Brad Horrocks 62eb09cdb6 As a OAuth consumer I want to get a refresh token during OAuth2 Registration
refresh token is now returned in oath registration

Fixes PLAT-1218

Test Plan:
Create a dev_key that has an invalid redirect_ur, this makes it easier
to subvert the oauth process later.

attempt to authorize your new key with a user. I used something like
blackmesa.canvas.dev/login/oauth2/auth?client_id=30000000000001&response_type=code&redirect_uri=http://blackmesa.dev/redirect&state=YYY

Sign in and authorize. You should be redirected to something similar to
http://blackmesa.dev/redirect?code=1c8d2ff5498eb879db9737d494a4bbd64810c84cf7e1776d1f4cebdb9699244c6209add4838d02f0d67b969a599cee589fecbeef5f84ababb1ef6e4cb9099b68&state=YYY

Take the code out of the url. open up
[postman](<https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en)
create a new post request with the following params
    code: #{code}
    client_id: #{your dev key's client id}
    client_secret: #{your dev key's client secret}

make sure the response includes a refresh_token property. A postman
request that can be imported [can be found
here](https://gist.github.com/defektive/f1cced73b08e5f6a2925)

 ________
< Thanks >
 --------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Change-Id: I8a8a8450825309232c903251231dec8c5d4e7463
Reviewed-on: https://gerrit.instructure.com/63256
Tested-by: Jenkins
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Brad Horrocks <bhorrocks@instructure.com>
2015-09-23 20:59:34 +00:00
Nathan Mills 00f5e79abe set expiration time for oauth2 generated access tokens
fixes: PLAT-1220

test-plan:
*using the oauth flow generate an access token
*you shouldl get an expires_in time with the token
*the token should expire after the expire_in time lapses

Change-Id: If25bea7a11dbd0c8e717d53eb131fdae6c156606
Reviewed-on: https://gerrit.instructure.com/62951
Tested-by: Jenkins
Reviewed-by: Brad Horrocks <bhorrocks@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Nathan Mills <nathanm@instructure.com>
2015-09-21 16:10:13 +00:00
Brad Horrocks 1aff77fe8b allow deactivating developer keys
Fixes PLAT-1232

test plan:
* go to developer keys UI
* you should be to deactive and reactivate keys
* deactivate a key that you have a token for
* the token should no longer work, even though it's not expired

Change-Id: I7388226c710ab0841692902886a49146a037e615
Reviewed-on: https://gerrit.instructure.com/50008
Tested-by: Jenkins
Reviewed-by: Nathan Mills <nathanm@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Brad Horrocks <bhorrocks@instructure.com>
2015-09-16 18:31:33 +00:00
Alex Boyd a52af1503f Clear other access tokens under the same key when requested
Fixes PLAT-991

Test plan:
 - Run through an OAuth flow in the usual manner with a given
   developer key
 - Run through it again, this time giving replace_tokens=1 to the
   call to /login/oauth2/token
 - Ensure that the old token was nuked and only the new one remains
 - Set replace_tokens to true on the developer key you're using
 - Run through the OAuth flow again, without giving replace_tokens=1
   to /login/oauth2/token, and ensure that the old token was once
   again nuked

Change-Id: Id2b40bfd16918ab3d0852dabc13ed7b500277dc9
Reviewed-on: https://gerrit.instructure.com/52286
Reviewed-by: Brad Humphrey <brad@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Product-Review: Alex Boyd <aboyd@instructure.com>
2015-04-23 18:40:26 +00:00
Cody Cutrer 6049f83830 move oauth2 methods to their own controller
test plan:
 * smoke test obtaining (or denying) an access token
   via the oauth flow

Change-Id: Ibd57f5ff971cb3302af786c81bae7b2bcee8470f
Reviewed-on: https://gerrit.instructure.com/51373
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-04-21 20:54:29 +00:00
Bracken Mosbacker d6f0f40f98 add force_token_reuse to developer key
API consumers should generally  try to reuse the api tokens that
they generate. This property makes it so that new tokens
won't be issued to a developer key for a user if that user
has a token that is still valid for that key.

Test Plan:
 * for both a trusted and an unstrusted developer key:
 * without force_token_reuse set on the key:
 * do the token request flow twice, you should get a new token each time
 * with force_token_reuse set:
 * do the token request flow twice, the second time access_token should be blank

closes PLAT-767

Change-Id: I94e7dfbe24ce534cca0ecba940c1e0b3af15b0cd
Reviewed-on: https://gerrit.instructure.com/44393
Reviewed-by: Dave Donahue <ddonahue@instructure.com>
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Product-Review: Bracken Mosbacker <bracken@instructure.com>
2015-02-24 18:33:27 +00:00