canvas-lms/config
Evan Battaglia 220b44cbf1 Microsoft Sync, initial syncer job
* Lays out framework for getting and caching Microsoft API tokens and
  hitting the Microsoft Graph API.
* Simple sync job which creates a group for the class if it doesn't
  exist and sets the extra LMS/SIS metadata.

NOTE: I discovered the MS API is eventually consistent -- it does not
immediately create a group when we hit the POST /education/classes
endpoint. In a future commit (I added a new ticket) we can work replace
the "sleep" with polling with sleeping or launching a new delayed job.

closes INTEROP-6567
flag=microsoft_group_enrollments_syncing

Test plan:
* Get creds from me and put in dynamic_settings.yml
* Try getting a token and observe it is cached (only the first time you
  run will you see "get service:timeouts:microsoft_sync_login:error_count"
  and "set microsoft_sync_login/<OURTESTTENANT>" calls to the redis cache):
    MicrosoftSync::LoginService.token(<OURTESTTENANT>)
* Put our test tenant (you can get that from me) into your root
  account's settings[:microsoft_sync_tenant]
* Create a course with a name and description that clearly label it
  as your test course for the Microsoft sync project
* From a rails console run:
    c = Course.find(...) # your new test course
    g = MicrosoftSync::Group.create(course: c)
    syncer = MicrosoftSync::Syncer.new(g)
    syncer.sync
* Run the syncer again and observe (from the MicrosoftSync::GraphClient:
  log lines) that we do not create or delete anything.
* Check that the group looks OK on the Microsoft side:
    g = MicrosoftSync::Group.last
    syncer = MicrosoftSync::Syncer.new(MicrosoftSync::Group.last)
    cgs = syncer.canvas_graph_service
    gs = cgs.graph_service
    gs.get_group(g.ms_group_id)
* Check that the extra properties on the group have been set:
    gs.get_group(g.ms_group_id, select:
      %w[microsoft_EducationClassLmsExt microsoft_EducationClassSisExt])
* Update the group's ms_group_id to nil in the database:
    g.update! ms_group_id: nil
  Then rename the course to something similar but slightly different and
  re-rerun the sync job (you may have to run syncer.course.reload and/or
  syncer.group.reload to make the syncer get new values). Then repeat
  the last two steps. In the first of those two steps, the group name,
  but in the second step, the data in microsoft_EducationClassLmsExt
  should be updated. This is because the syncer assumes if a group has
  been created it was created correctly, but it doesn't assume the extra
  metadata was ever set to it re-sets it. Also check that ms_group_id
  has been re-filled in on the group record.
* Change your creds to something invalid and clear the rails cache.
  Run the sync. It should raise an error. Then check that the Group
  record has been updated with workflow_state=errored and
  last_error="Invalid Status Code: Login service returned 401 for tenant
  <OURTENANT>". This is what will be shown to the user (teacher).
* If you need/want to look at the Microsoft admin web console, you can
  get those creds from me. From there you can delete your group, if
  needed. You can also delete your group by using:
    gs.request(:delete, "groups/#{ms_group_id}")

Change-Id: I077497c1c412095420079ea80d461bd172425bca
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/260232
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Wagner Goncalves <wagner.goncalves@instructure.com>
Reviewed-by: Weston Dransfield <wdransfield@instructure.com>
QA-Review: Wagner Goncalves <wagner.goncalves@instructure.com>
Product-Review: Evan Battaglia <ebattaglia@instructure.com>
2021-03-24 14:30:20 +00:00
..
environments automatically allow the configured domain 2021-02-17 17:56:29 +00:00
feature_flags Remove easy_student_view flag 2021-03-18 17:37:27 +00:00
initializers Set up replica identity index for AccessToken 2021-03-16 20:00:56 +00:00
locales update nn translation 2021-03-24 06:00:23 +00:00
saml add first class support for the UK Federation 2017-08-08 20:26:52 +00:00
amazon_s3.yml.example
application.rb Initial work on getting zeitwerk loader running 2021-03-16 19:55:12 +00:00
boot.rb Revert "Speed up boot time with bootsnap" 2017-05-22 23:24:32 +00:00
bounce_notifications.yml.example
brakeman.ignore remove uses of whitelist and blacklist 2020-09-18 15:58:40 +00:00
brandable_css.yml make feature flags for Right To Left layout 2018-03-21 21:09:38 +00:00
browsers.yml Add clarification text to browsers file 2020-09-03 20:37:32 +00:00
cache_store.yml.example add the ability to run parallel rspec processes in container 2021-01-14 21:12:45 +00:00
canvas_cdn.yml.example Remove enabled: setting from canvs_cdn.yml.example 2019-07-22 20:22:10 +00:00
canvas_rails_switcher.rb Initial work on getting zeitwerk loader running 2021-03-16 19:55:12 +00:00
cassandra.yml.example improve cassandra documentation 2017-09-29 19:28:08 +00:00
consul.yml.example Add dc config to jwk set_keys 2018-08-10 17:44:48 +00:00
copyright-template.js [eslint] have --fix add copyright header for you 2018-02-15 20:01:41 +00:00
cutycapt.yml.example
database.yml.example Add password to database.yml.example for Postgres changes 2020-05-05 22:02:48 +00:00
database.yml.travis
delayed_jobs.yml.example allow enabling inst-jobs health checks 2018-05-11 19:22:32 +00:00
docker-compose.override.yml.example volumes were removed from services 2021-01-20 22:18:59 +00:00
domain.yml.example Use same_site none for session store for relative file links 2020-02-27 21:01:01 +00:00
dynamic_settings.yml.example Microsoft Sync, initial syncer job 2021-03-24 14:30:20 +00:00
dynamodb.yml.example dynamo is optional for dev 2020-08-31 19:05:02 +00:00
environment.rb stage 1: audits engine extract 2021-03-04 20:27:06 +00:00
external_migration.yml.example
file_store.yml.example
incoming_mail.yml.example
linked_in.yml.example
local_cache.yml.example allow local cache to use local redis 2020-08-27 19:08:56 +00:00
logging.yml.example
marginalia.yml.example
memcache.yml.example
notification_failures.yml.example
notification_service.yml.example
offline_web.yml.sample
outgoing_mail.yml.example
periodic_jobs.yml.example
puma.rb Add copyright message to remaining .rb files 2018-03-19 13:38:50 +00:00
raven.yml.example
redis.yml.example add the ability to run parallel rspec processes in container 2021-01-14 21:12:45 +00:00
routes.rb MSFT sync group create endpoint 2021-03-16 20:36:57 +00:00
saml.yml.example
security.yml.example Add client_credentials grant_type 2018-09-10 17:07:05 +00:00
selenium.yml.example Support running against headless chrome, fix flakey spec 2021-01-12 16:27:14 +00:00
session_store.yml.example Use same_site none for session store for relative file links 2020-02-27 21:01:01 +00:00
spring.rb add flakey_spec_catcher as a proper spring command 2021-03-02 18:41:36 +00:00
statsd.yml.example
styleguide.yml
testrail.yml.example
twilio.yml.example
twitter.yml.example
vault.yml.example file-based local solution for vault 2020-09-02 15:46:27 +00:00
vault_contents.yml.example Create a mechanism for supplying rails credentials from vault 2021-02-01 16:52:40 +00:00