2021-03-30 06:08:59 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-04-28 03:54:48 +08:00
|
|
|
#
|
|
|
|
# Copyright (C) 2011 - present Instructure, Inc.
|
|
|
|
#
|
|
|
|
# This file is part of Canvas.
|
|
|
|
#
|
|
|
|
# Canvas is free software: you can redistribute it and/or modify it under
|
|
|
|
# the terms of the GNU Affero General Public License as published by the Free
|
|
|
|
# Software Foundation, version 3 of the License.
|
|
|
|
#
|
|
|
|
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
|
|
# details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU Affero General Public License along
|
|
|
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2014-07-24 01:14:22 +08:00
|
|
|
full_path_glob = "(/*full_path)"
|
|
|
|
|
2014-08-14 05:34:22 +08:00
|
|
|
# allow plugins to prepend routes
|
2021-11-23 23:20:14 +08:00
|
|
|
Dir["{gems,vendor}/plugins/*/config/pre_routes.rb"].each do |pre_routes|
|
2014-08-14 05:34:22 +08:00
|
|
|
load pre_routes
|
2021-11-23 23:20:14 +08:00
|
|
|
end
|
2014-08-14 05:34:22 +08:00
|
|
|
|
2014-07-24 01:14:22 +08:00
|
|
|
CanvasRails::Application.routes.draw do
|
2017-05-24 03:32:44 +08:00
|
|
|
post "/api/graphql", to: "graphql#execute"
|
2021-07-09 15:40:31 +08:00
|
|
|
post "/api/graphql/subgraph", to: "graphql#subgraph_execute"
|
|
|
|
# The subgraph endpoint is for use only with the federated API Gateway. See
|
|
|
|
# `app/graphql/README.md` for details.
|
2017-05-24 03:32:44 +08:00
|
|
|
get "graphiql", to: "graphql#graphiql"
|
|
|
|
|
2018-07-27 10:12:42 +08:00
|
|
|
resources :submissions, only: [] do
|
|
|
|
resources :submission_comments, path: :comments, only: :index, defaults: { format: :pdf }
|
2018-08-15 02:33:56 +08:00
|
|
|
resources :docviewer_audit_events, only: [:create], constraints: { format: :json }
|
2018-07-27 10:12:42 +08:00
|
|
|
end
|
autosave comments on navigating to different user in speedgrader
closes CNVS-28529
While in SpeedGrader, if you have something entered in the comments
field and, without submitting those comments, you navigate to a
different user or otherwise navigate away from SpeedGrader, your
comments will now automatically be saved as "draft" comments for
that user's submission.
Draft comments
* don't show up anywhere other than while grading
* are invisible to users whether or not the assignment is muted
* are only "submittable" by the author of the draft comment
test plan:
1. Create a course, with at least two students
2. Add a quiz with at least one essay type question
3. As each student, take the quiz
4. As the teacher, grade the quiz and start up SpeedGrader
5. Enter comments for the first student's submission but do *not*
submit them
6. Navigate to the next student
7. You should see a message telling you your comment was
auto-saved
8. Go back to the previous student
9. You should see your comment styled differently with a red
asterisk before it, indicating a draft comment (also using
aria-label for a11y goodness)
10.Enter another comment and this time submit it
11.You should see your comment styled normally without a red
asterisk before it, indicating a normal (non-draft) comment
12.Try steps 5 through 11 with different ways of leaving that
student in step #6 e.g. using the drop down, or quitting
SpeedGrader altogether and you should see the same results for
draft comments
13.Go back to a submission with a draft comment.
14.Click on the button labelled "Publish" next to your draft
comment.
15.Watch your comment change in appearance from a draft comment
to a regular comment
16.Delete any comment and watch it disappear from the comment
list.
17.Go to the next student
18.Go back to the previous student for whose submission you
deleted the comment
19.Notice the deleted comment remains missing from the comment
list.
20.Verify that, if logged in as a student, you never see draft
comments
Change-Id: If32294a7bed6f847709b54d4c8e4fc21fb2a6eca
Reviewed-on: https://gerrit.instructure.com/77133
Reviewed-by: Spencer Olson <solson@instructure.com>
Reviewed-by: Neil Gupta <ngupta@instructure.com>
Tested-by: Jenkins
QA-Review: Amber Taniuchi <amber@instructure.com>
Product-Review: Christi Wruck
2016-04-14 05:02:28 +08:00
|
|
|
resources :submission_comments, only: [:update, :destroy]
|
2014-09-23 02:52:41 +08:00
|
|
|
|
2015-07-21 05:19:44 +08:00
|
|
|
resources :epub_exports, only: [:index]
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "inbox" => "context#inbox"
|
2015-02-06 07:05:25 +08:00
|
|
|
get "oauth/redirect_proxy" => "oauth_proxy#redirect_proxy"
|
2014-09-23 02:52:41 +08:00
|
|
|
|
|
|
|
get "conversations/unread" => "conversations#index", :as => :conversations_unread, :redirect_scope => "unread"
|
|
|
|
get "conversations/starred" => "conversations#index", :as => :conversations_starred, :redirect_scope => "starred"
|
|
|
|
get "conversations/sent" => "conversations#index", :as => :conversations_sent, :redirect_scope => "sent"
|
|
|
|
get "conversations/archived" => "conversations#index", :as => :conversations_archived, :redirect_scope => "archived"
|
|
|
|
get "conversations/find_recipients" => "search#recipients"
|
|
|
|
|
|
|
|
get "search/recipients" => "search#recipients"
|
|
|
|
post "conversations/mark_all_as_read" => "conversations#mark_all_as_read"
|
|
|
|
get "conversations/batches" => "conversations#batches", :as => :conversation_batches
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :conversations, only: %i[index show update create destroy] do
|
2014-09-23 02:52:41 +08:00
|
|
|
post :add_recipients
|
|
|
|
post :add_message
|
|
|
|
post :remove_messages
|
2011-05-20 00:33:20 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2015-06-26 03:35:25 +08:00
|
|
|
post "/external_auth_observers/redirect_login" => "login/external_auth_observers#redirect_login", :as => :external_auth_validation
|
2015-03-03 01:41:17 +08:00
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
# So, this will look like:
|
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
|
|
|
# http://instructure.com/register/5R32s9iqwLK75Jbbj0
|
2014-09-23 02:52:41 +08:00
|
|
|
match "register/:nonce" => "communication_channels#confirm", :as => :registration_confirmation, :via => [:get, :post]
|
refactor user creation/invitations closes #5833
fixes #5573, #5572, #5753
* communication channels are now only unique within a single user
* UserList changes
* Always resolve pseudonym#unique_ids
* Support looking up by SMS CCs
* Option to either require e-mails match an existing CC,
or e-mails that don't match a Pseudonym will always be
returned unattached (relying on better merging behavior
to not have a gazillion accounts created)
* Method to return users, creating new ones (*without* a
Pseudonym) if necessary. (can't create with a pseudonym,
since Pseudonym#unique_id is still unique, I can't have
multiple outstanding users with the same unique_id)
* EnrollmentsFromUserList is mostly gutted, now using UserList's
functionality directy.
* Use UserList for adding account admins, removing the now
unused Account#add_admin => User#find_by_email/User#assert_by_email
codepath
* Update UsersController#create to not worry about duplicate
communication channels
* Remove AccountsController#add_user, and just use
UsersController#create
* Change SIS::UserImporter to send out a merge opportunity
e-mail if a conflicting CC is found (but still create the CC)
* In /profile, don't worry about conflicting CCs (the CC confirmation
process will now allow merging)
* Remove CommunicationChannelsController#try_merge and #merge
* For the non-simple case of CoursesController#enrollment_invitation
redirect to /register (CommunicationsChannelController#confirm)
* Remove CoursesController#transfer_enrollment
* Move PseudonymsController#registration_confirmation to
CommunicationChannelsController#confirm (have to be able to
register an account without a Pseudonym yet)
* Fold the old direct confirm functionality in, if there are
no available merge opportunities
* Allow merging the new account with the currently logged in user
* Allow changing the Pseudonym#unique_id when registering a new
account (since there might be conflicts)
* Display a list of merge opportunities based on conflicting
communication channels
* Provide link(s) to log in as the other user,
redirecting back to the registration page after login is
complete (to complete the merge as the current user)
* Remove several assert_* methods that are no longer needed
* Update PseudonymSessionsController a bit to deal with the new
way of dealing with conflicting CCs (especially CCs from LDAP),
and to redirect back to the registration/confirmation page when
attempting to do a merge
* Expose the open_registration setting; use it to control if
inviting users to a course is able to create new users
Change-Id: If2f38818a71af656854d3bf8431ddbf5dcb84691
Reviewed-on: https://gerrit.instructure.com/6149
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Jacob Fugal <jacob@instructure.com>
2011-10-13 04:30:48 +08:00
|
|
|
# deprecated
|
2014-09-23 02:52:41 +08:00
|
|
|
get "pseudonyms/:id/register/:nonce" => "communication_channels#confirm", :as => :registration_confirmation_deprecated
|
2014-10-08 01:05:15 +08:00
|
|
|
post "confirmations/:user_id/re_send(/:id)" => "communication_channels#re_send_confirmation", :as => :re_send_confirmation, :id => nil
|
2018-12-21 02:11:08 +08:00
|
|
|
get "confirmations/:user_id/limit_reached(/:id)" => "communication_channels#confirmation_limit_reached", :as => :confirmation_limit_reached, :id => nil
|
2014-11-09 05:27:03 +08:00
|
|
|
match "forgot_password" => "pseudonyms#forgot_password", :as => :forgot_password, :via => [:get, :post]
|
2014-09-23 02:52:41 +08:00
|
|
|
get "pseudonyms/:pseudonym_id/change_password/:nonce" => "pseudonyms#confirm_change_password", :as => :confirm_change_password
|
|
|
|
post "pseudonyms/:pseudonym_id/change_password/:nonce" => "pseudonyms#change_password", :as => :change_password
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
# callback urls for oauth authorization processes
|
2014-09-23 02:52:41 +08:00
|
|
|
get "oauth" => "users#oauth"
|
|
|
|
get "oauth_success" => "users#oauth_success"
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "mr/:id" => "info#message_redirect", :as => :message_redirect
|
|
|
|
get "help_links" => "info#help_links"
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2019-01-19 05:37:35 +08:00
|
|
|
# This is a debug route that makes working on error pages easier
|
|
|
|
get "test_error" => "info#test_error" unless Rails.env.production?
|
2021-11-04 06:09:18 +08:00
|
|
|
get "live_events/heartbeat" => "info#live_events_heartbeat" unless Rails.env.production?
|
2015-09-22 05:06:09 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :question_banks do
|
|
|
|
resources :question_banks do
|
2014-09-23 02:52:41 +08:00
|
|
|
post :bookmark
|
|
|
|
post :reorder
|
|
|
|
get :questions
|
|
|
|
post :move_questions
|
2014-03-07 06:10:04 +08:00
|
|
|
resources :assessment_questions
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :groups do
|
2016-10-15 13:03:08 +08:00
|
|
|
resources :groups, except: :edit
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :group_categories, only: %i[create update destroy]
|
2014-09-23 02:52:41 +08:00
|
|
|
get "group_unassigned_members" => "groups#unassigned_members"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2013-05-07 03:16:06 +08:00
|
|
|
|
2015-07-18 04:07:01 +08:00
|
|
|
resources :group_categories do
|
|
|
|
member do
|
|
|
|
post "clone_with_name"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :files do
|
2016-03-23 21:18:10 +08:00
|
|
|
resources :files, except: [:new] do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "inline" => "files#text_show", :as => :text_inline
|
|
|
|
get "download" => "files#show", :download => "1"
|
|
|
|
get "download.:type" => "files#show", :as => :typed_download, :download => "1"
|
|
|
|
get "preview" => "files#show", :preview => "1"
|
|
|
|
post "inline_view" => "files#show", :inline => "1"
|
|
|
|
get "contents" => "files#attachment_content", :as => :attachment_content
|
file preview endpoint
test plan:
0. upload the following types of files into a course, and
note their IDs:
a) document of some type (such as Word, PDF)
b) image (such as JPEG, PNG, GIF)
c) media (such as MP3, MP4, MOV)
1. enable canvadocs and google docs previews in account
settings.
2. test the document preview by hitting the following
in a new browser tab:
/courses/X/files/Y/file_preview
(where X is the course ID and Y is the file ID
of the document file)
- You should see a Canvadocs preview of the document.
- There should be no Canvas chrome in the window, just
the document preview.
3. disable canvadocs but leave google doc previews
enabled.
4. hit the URL from step 2.
- you should see a Google preview of the document
5. disable Google docs previews.
6. hit the URL from step 2.
- you should see a message indicating that no preview is
available, with a link to download the file.
7. hit the URL from step 2, but substitute the file ID
with the ID of an image instead of a document.
- you should see the image (and nothing else).
8. hit the URL from step 2, but substitute the file ID
with the ID of a media file.
- You should see a functioning media player (or a message
indicating the media has not been converted yet)
9. add a document to a module, and set a "must view"
completion requirement
10. use this endpoint to preview the document, and confirm
that the module completion requirement is fulfilled
fixes CNVS-15827
Change-Id: Id0ecaa7f003248cb3d8f163e48c3b16631ee59cf
Reviewed-on: https://gerrit.instructure.com/42438
Reviewed-by: Ryan Shaw <ryan@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Cosme Salazar <cosme@instructure.com>
2014-10-09 05:27:45 +08:00
|
|
|
get "file_preview" => "file_previews#show"
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
2020-11-11 23:02:08 +08:00
|
|
|
get "folder#{full_path_glob}" => "files#react_files", :format => false, :defaults => { format: "html" }
|
|
|
|
get "search" => "files#react_files", :format => false, :defaults => { format: "html" }
|
2013-06-15 01:09:41 +08:00
|
|
|
get :quota
|
|
|
|
post :reorder
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
2014-10-09 12:10:46 +08:00
|
|
|
get ":file_path" => "files#show_relative", :as => :relative_path, :file_path => /.+/ # needs to stay below react_files route
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :file_images do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "images" => "files#images"
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :relative_files do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "file_contents/:file_path" => "files#show_relative", :as => :relative_file_path, :file_path => /.+/
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
concern :folders do
|
2017-05-24 04:03:16 +08:00
|
|
|
resources :folders
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :media do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "media_download" => "users#media_download"
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :users do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users" => "context#roster"
|
|
|
|
get "user_services" => "context#roster_user_services"
|
|
|
|
get "users/:user_id/usage" => "context#roster_user_usage", :as => :user_usage
|
|
|
|
get "users/:id" => "context#roster_user", :as => :user
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :announcements do
|
|
|
|
resources :announcements
|
2014-09-23 02:52:41 +08:00
|
|
|
post "announcements/external_feeds" => "announcements#create_external_feed"
|
|
|
|
delete "announcements/external_feeds/:id" => "announcements#destroy_external_feed", :as => :announcements_external_feed
|
2012-09-21 05:11:36 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :discussions do
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :discussion_topics, only: %i[index new show edit destroy]
|
2014-09-23 02:52:41 +08:00
|
|
|
get "discussion_topics/:id/:extras" => "discussion_topics#show", :as => :map, :extras => /.+/
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :discussion_entries
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2014-10-10 10:18:35 +08:00
|
|
|
concern :pages do
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :wiki_pages, path: :pages, except: %i[update destroy new], constraints: { id: %r{[^/]+} } do
|
2014-10-10 10:18:35 +08:00
|
|
|
get "revisions" => "wiki_pages#revisions", :as => :revisions
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
2013-06-18 06:31:05 +08:00
|
|
|
|
2014-10-10 10:18:35 +08:00
|
|
|
get "wiki" => "wiki_pages#front_page", :as => :wiki
|
2021-11-18 04:54:51 +08:00
|
|
|
get "wiki/:id" => "wiki_pages#show_redirect", :id => %r{[^/]+}
|
|
|
|
get "wiki/:id/revisions" => "wiki_pages#revisions_redirect", :id => %r{[^/]+}
|
|
|
|
get "wiki/:id/revisions/:revision_id" => "wiki_pages#revisions_redirect", :id => %r{[^/]+}
|
2011-12-06 03:34:06 +08:00
|
|
|
end
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
concern :conferences do
|
|
|
|
resources :conferences do
|
2014-11-08 23:54:55 +08:00
|
|
|
match :join, via: [:get, :post]
|
|
|
|
match :close, via: [:get, :post]
|
2021-11-20 04:05:07 +08:00
|
|
|
get :recording
|
|
|
|
delete :recording, to: "conferences#delete_recording", as: :delete_recording
|
2014-09-23 02:52:41 +08:00
|
|
|
get :settings
|
2011-08-27 08:33:01 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-12-19 22:38:49 +08:00
|
|
|
get "/courses/:course_id/gradebook2", to: redirect("/courses/%{course_id}/gradebook")
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
# There are a lot of resources that are all scoped to the course level
|
|
|
|
# (assignments, files, wiki pages, user lists, forums, etc.). Many of
|
|
|
|
# these resources also apply to groups and individual users. We call
|
|
|
|
# courses, users, groups, or even accounts in this setting, "contexts".
|
|
|
|
# There are some helper methods like the before_filter :get_context in application_controller
|
|
|
|
# and the application_helper method :context_url to make retrieving
|
|
|
|
# these contexts, and also generating context-specific urls, easier.
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :courses do
|
2013-01-29 08:36:31 +08:00
|
|
|
# DEPRECATED
|
2014-09-23 02:52:41 +08:00
|
|
|
get "self_enrollment/:self_enrollment" => "courses#self_enrollment", :as => :self_enrollment
|
|
|
|
post "self_unenrollment/:self_unenrollment" => "courses#self_unenrollment", :as => :self_unenrollment
|
|
|
|
post :unconclude
|
|
|
|
get :students
|
2019-06-14 23:26:35 +08:00
|
|
|
get "observer_pairing_codes.csv", action: :observer_pairing_codes_csv, as: "observer_pairing_codes"
|
2014-09-23 02:52:41 +08:00
|
|
|
post :enrollment_invitation
|
2013-06-15 01:09:41 +08:00
|
|
|
# this needs to come before the users concern, or users/:id will preempt it
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/prior" => "context#prior_users", :as => :prior_users
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :users
|
2014-09-23 02:52:41 +08:00
|
|
|
get :statistics
|
|
|
|
delete "unenroll/:id" => "courses#unenroll_user", :as => :unenroll
|
|
|
|
post "move_enrollment/:id" => "courses#move_enrollment", :as => :move_enrollment
|
|
|
|
delete "unenroll/:id.:format" => "courses#unenroll_user", :as => :formatted_unenroll
|
|
|
|
post "limit_user_grading/:id" => "courses#limit_user", :as => :limit_user_grading
|
|
|
|
delete "conclude_user/:id" => "courses#conclude_user", :as => :conclude_user_enrollment
|
|
|
|
post "unconclude_user/:id" => "courses#unconclude_user", :as => :unconclude_user_enrollment
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :sections, except: %i[index edit new] do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "crosslist/confirm/:new_course_id" => "sections#crosslist_check", :as => :confirm_crosslist
|
|
|
|
post :crosslist
|
|
|
|
delete "crosslist" => "sections#uncrosslist", :as => :uncrosslist
|
|
|
|
end
|
|
|
|
|
|
|
|
get "undelete" => "context#undelete_index", :as => :undelete_items
|
|
|
|
post "undelete/:asset_string" => "context#undelete_item", :as => :undelete_item
|
2014-11-04 11:58:08 +08:00
|
|
|
|
|
|
|
get "settings#{full_path_glob}", action: :settings
|
2014-09-23 02:52:41 +08:00
|
|
|
get :settings
|
|
|
|
get "details" => "courses#settings"
|
|
|
|
post :re_send_invitations
|
|
|
|
post :enroll_users
|
|
|
|
post :link_enrollment
|
|
|
|
post :update_nav
|
2013-06-15 01:09:41 +08:00
|
|
|
resource :gradebook do
|
2020-01-17 05:34:16 +08:00
|
|
|
get "submissions_upload/:assignment_id" => "gradebooks#show_submissions_upload", :as => :show_submissions_upload
|
2014-09-23 02:52:41 +08:00
|
|
|
post "submissions_upload/:assignment_id" => "gradebooks#submissions_zip_upload", :as => :submissions_upload
|
2020-01-17 05:34:16 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
get :change_gradebook_version
|
|
|
|
get :blank_submission
|
2018-12-04 01:15:02 +08:00
|
|
|
get :final_grade_overrides
|
2013-06-15 01:09:41 +08:00
|
|
|
get :speed_grader
|
2013-08-27 07:11:45 +08:00
|
|
|
post :speed_grader_settings
|
2013-06-15 01:09:41 +08:00
|
|
|
get :history
|
|
|
|
post :update_submission
|
2015-04-30 23:18:54 +08:00
|
|
|
post :change_gradebook_column_size
|
|
|
|
post :save_gradebook_column_order
|
2017-06-17 06:37:46 +08:00
|
|
|
get :user_ids
|
2017-07-18 23:24:21 +08:00
|
|
|
get :grading_period_assignments
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-08-14 02:49:58 +08:00
|
|
|
resource :gradebook_csv, only: [:create]
|
2014-02-08 04:27:46 +08:00
|
|
|
|
2013-07-02 11:51:02 +08:00
|
|
|
# DEPRECATED old migration emails pointed the user to this url, leave so the controller can redirect
|
2014-09-23 02:52:41 +08:00
|
|
|
get "imports/list" => "content_imports#index", :as => :import_list
|
2013-07-02 11:51:02 +08:00
|
|
|
# DEPRECATED
|
2014-09-23 02:52:41 +08:00
|
|
|
get "imports" => "content_imports#intro"
|
2015-04-03 01:36:14 +08:00
|
|
|
resource :gradebook_upload do
|
|
|
|
get "data" => "gradebook_uploads#data"
|
|
|
|
end
|
2014-09-23 02:52:41 +08:00
|
|
|
get "grades" => "gradebooks#grade_summary", :id => nil
|
|
|
|
get "grading_rubrics" => "gradebooks#grading_rubrics"
|
|
|
|
get "grades/:id" => "gradebooks#grade_summary", :as => :student_grades
|
sort assignments on course grades page
allow sorting by assignment group, due date, module,
and title on the course grades page. also, store
the user's sort preferences and remember that
preference on subsequent page loads.
closes CNVS-21660
test plan:
- as a student, go to the /courses/:course_id/grades
page.
- verify there is a dropdown to sort assignments by
due date and title. the first time you visit this
page, the dropdown option should default to
ordering by due date. verify each option correctly
sorts the assignments.
- if the course has any Modules, there should be an
option to sort by Module. if the course does not
have any Modules, there should not be a Module sort
option.
- if the course has assignments that belong to different
Assignment Groups, there should be an option to sort
by Assignment Group. if the course does not have any
assignments, or if all of the course's assignments
belong to the same Assignment Group, there should not
be an Assignment Group sort option.
- select any option besides 'Due Date'. next, leave the
page and return back to the page. verify the selected
dropdown option matches the option you selected before
leaving the page.
- repeat the steps above while logged in as a teacher, TA,
student view student, and admin. when logged in as a teacher,
TA, or admin, the url will be /courses/:course_id/grades/
:student_id
- verify the dropdown is accessible
- note: if a student is enrolled in multiple courses, the
dropdown for the sort order should be on the right-hand
side of the /courses/:course_id/grades page (and the
dropdown for the course selection should be on the
left-hand side). if a student is only enrolled in
one course, the dropdown for sort order should be on
the left-hand side of the page.
Change-Id: Idbcbea2d25051cb5d933bfb395daebeedc630855
Reviewed-on: https://gerrit.instructure.com/69419
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
QA-Review: KC Naegle <knaegle@instructure.com>
Product-Review: Spencer Olson <solson@instructure.com>
2015-12-22 12:35:21 +08:00
|
|
|
post "save_assignment_order" => "gradebooks#save_assignment_order", :as => :save_assignment_order
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :announcements
|
2018-04-25 09:08:08 +08:00
|
|
|
get "calendar" => "calendars#show"
|
2014-09-23 02:52:41 +08:00
|
|
|
get :locks
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :discussions
|
|
|
|
resources :assignments do
|
2015-08-20 05:14:47 +08:00
|
|
|
get "moderate" => "assignments#show_moderate"
|
2018-05-02 19:23:01 +08:00
|
|
|
|
|
|
|
get "anonymous_submissions/:anonymous_id", to: "submissions/anonymous_previews#show",
|
2021-11-23 23:20:14 +08:00
|
|
|
constraints: lambda { |request|
|
2018-05-02 19:23:01 +08:00
|
|
|
request.query_parameters.key?(:preview) && request.format == :html
|
2021-11-23 23:20:14 +08:00
|
|
|
}
|
2018-05-02 19:23:01 +08:00
|
|
|
|
|
|
|
get "anonymous_submissions/:anonymous_id", to: "submissions/anonymous_downloads#show",
|
2021-11-23 23:20:14 +08:00
|
|
|
constraints: lambda { |request|
|
2018-05-02 19:23:01 +08:00
|
|
|
request.query_parameters.key?(:download)
|
2021-11-23 23:20:14 +08:00
|
|
|
}
|
2018-05-02 19:23:01 +08:00
|
|
|
|
|
|
|
get "anonymous_submissions/:anonymous_id", to: "anonymous_submissions#show", as: :anonymous_submission
|
|
|
|
|
cleanup SubmissionsController#show
fixes CNVS-25767
- Simplifies SubmissionsController#show & adds test coverage.
- Adds Submissions::DownloadsController#show to handle submission
download functionality.
- Adds Submissions::PreviewsController#show to handle submission preview
functionality.
test plan:
- As a teacher, add assignments for each online submission type: Text
Entry, Website URL & File Uploads.
- As a student, provide a submission for each of these assignments.
Provide two submissions for at least one of the assignments.
- As the student, view each of these submissions via the submission
details page. URL path looks like:
/courses/1/assignments/1/submissions/2,
and can be accessed from assignment page.
- Observe that the body of the submission shows up in the Submission
Detail page.
- Observe that for file uploads, the files can be downloaded.
- As the teacher, access the speed grader for each submission.
- Observe that the submission body appears in the speed grader.
- Observe that, for file uploads, the files are displayed inline (this
doesn't work for every media type and it will tell you as much if it's
not supported).
- Observe that if there are multiple files provided, the list of files
appears in the left hand column, and the teacher can tolggle between
them.
- Observe that if the submission has multiple versions, in the left hand
column there is a dropdown labeled 'Submission to view:', and toggling
the selected datetime will change the submission that is displayed.
- As the teacher viewing a submission in the speed grader, leave a
comment in the right hand column, and attach a file.
- As the student, view the submission details page.
- Observe that there is a link to the fiel in the right hand column, and
that the file can be downloaded.
Change-Id: Ib3fff3909f47873b37c373e53ab26cb8176b94e1
Reviewed-on: https://gerrit.instructure.com/68559
Tested-by: Jenkins
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
QA-Review: Michael Hargiss <mhargiss@instructure.com>
Product-Review: Jason Sparks <jsparks@instructure.com>
2015-12-04 00:15:27 +08:00
|
|
|
get "submissions/:id", to: "submissions/previews#show",
|
2021-11-23 23:20:14 +08:00
|
|
|
constraints: lambda { |request|
|
cleanup SubmissionsController#show
fixes CNVS-25767
- Simplifies SubmissionsController#show & adds test coverage.
- Adds Submissions::DownloadsController#show to handle submission
download functionality.
- Adds Submissions::PreviewsController#show to handle submission preview
functionality.
test plan:
- As a teacher, add assignments for each online submission type: Text
Entry, Website URL & File Uploads.
- As a student, provide a submission for each of these assignments.
Provide two submissions for at least one of the assignments.
- As the student, view each of these submissions via the submission
details page. URL path looks like:
/courses/1/assignments/1/submissions/2,
and can be accessed from assignment page.
- Observe that the body of the submission shows up in the Submission
Detail page.
- Observe that for file uploads, the files can be downloaded.
- As the teacher, access the speed grader for each submission.
- Observe that the submission body appears in the speed grader.
- Observe that, for file uploads, the files are displayed inline (this
doesn't work for every media type and it will tell you as much if it's
not supported).
- Observe that if there are multiple files provided, the list of files
appears in the left hand column, and the teacher can tolggle between
them.
- Observe that if the submission has multiple versions, in the left hand
column there is a dropdown labeled 'Submission to view:', and toggling
the selected datetime will change the submission that is displayed.
- As the teacher viewing a submission in the speed grader, leave a
comment in the right hand column, and attach a file.
- As the student, view the submission details page.
- Observe that there is a link to the fiel in the right hand column, and
that the file can be downloaded.
Change-Id: Ib3fff3909f47873b37c373e53ab26cb8176b94e1
Reviewed-on: https://gerrit.instructure.com/68559
Tested-by: Jenkins
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
QA-Review: Michael Hargiss <mhargiss@instructure.com>
Product-Review: Jason Sparks <jsparks@instructure.com>
2015-12-04 00:15:27 +08:00
|
|
|
request.query_parameters.key?(:preview) && request.format == :html
|
2021-11-23 23:20:14 +08:00
|
|
|
}
|
2018-05-02 19:23:01 +08:00
|
|
|
|
cleanup SubmissionsController#show
fixes CNVS-25767
- Simplifies SubmissionsController#show & adds test coverage.
- Adds Submissions::DownloadsController#show to handle submission
download functionality.
- Adds Submissions::PreviewsController#show to handle submission preview
functionality.
test plan:
- As a teacher, add assignments for each online submission type: Text
Entry, Website URL & File Uploads.
- As a student, provide a submission for each of these assignments.
Provide two submissions for at least one of the assignments.
- As the student, view each of these submissions via the submission
details page. URL path looks like:
/courses/1/assignments/1/submissions/2,
and can be accessed from assignment page.
- Observe that the body of the submission shows up in the Submission
Detail page.
- Observe that for file uploads, the files can be downloaded.
- As the teacher, access the speed grader for each submission.
- Observe that the submission body appears in the speed grader.
- Observe that, for file uploads, the files are displayed inline (this
doesn't work for every media type and it will tell you as much if it's
not supported).
- Observe that if there are multiple files provided, the list of files
appears in the left hand column, and the teacher can tolggle between
them.
- Observe that if the submission has multiple versions, in the left hand
column there is a dropdown labeled 'Submission to view:', and toggling
the selected datetime will change the submission that is displayed.
- As the teacher viewing a submission in the speed grader, leave a
comment in the right hand column, and attach a file.
- As the student, view the submission details page.
- Observe that there is a link to the fiel in the right hand column, and
that the file can be downloaded.
Change-Id: Ib3fff3909f47873b37c373e53ab26cb8176b94e1
Reviewed-on: https://gerrit.instructure.com/68559
Tested-by: Jenkins
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
QA-Review: Michael Hargiss <mhargiss@instructure.com>
Product-Review: Jason Sparks <jsparks@instructure.com>
2015-12-04 00:15:27 +08:00
|
|
|
get "submissions/:id", to: "submissions/downloads#show",
|
2021-11-23 23:20:14 +08:00
|
|
|
constraints: lambda { |request|
|
cleanup SubmissionsController#show
fixes CNVS-25767
- Simplifies SubmissionsController#show & adds test coverage.
- Adds Submissions::DownloadsController#show to handle submission
download functionality.
- Adds Submissions::PreviewsController#show to handle submission preview
functionality.
test plan:
- As a teacher, add assignments for each online submission type: Text
Entry, Website URL & File Uploads.
- As a student, provide a submission for each of these assignments.
Provide two submissions for at least one of the assignments.
- As the student, view each of these submissions via the submission
details page. URL path looks like:
/courses/1/assignments/1/submissions/2,
and can be accessed from assignment page.
- Observe that the body of the submission shows up in the Submission
Detail page.
- Observe that for file uploads, the files can be downloaded.
- As the teacher, access the speed grader for each submission.
- Observe that the submission body appears in the speed grader.
- Observe that, for file uploads, the files are displayed inline (this
doesn't work for every media type and it will tell you as much if it's
not supported).
- Observe that if there are multiple files provided, the list of files
appears in the left hand column, and the teacher can tolggle between
them.
- Observe that if the submission has multiple versions, in the left hand
column there is a dropdown labeled 'Submission to view:', and toggling
the selected datetime will change the submission that is displayed.
- As the teacher viewing a submission in the speed grader, leave a
comment in the right hand column, and attach a file.
- As the student, view the submission details page.
- Observe that there is a link to the fiel in the right hand column, and
that the file can be downloaded.
Change-Id: Ib3fff3909f47873b37c373e53ab26cb8176b94e1
Reviewed-on: https://gerrit.instructure.com/68559
Tested-by: Jenkins
Reviewed-by: Mike Nomitch <mnomitch@instructure.com>
QA-Review: Michael Hargiss <mhargiss@instructure.com>
Product-Review: Jason Sparks <jsparks@instructure.com>
2015-12-04 00:15:27 +08:00
|
|
|
request.query_parameters.key?(:download)
|
2021-11-23 23:20:14 +08:00
|
|
|
}
|
2018-05-02 19:23:01 +08:00
|
|
|
|
2018-05-02 20:26:46 +08:00
|
|
|
put "anonymous_submissions/:anonymous_id", to: "anonymous_submissions#update"
|
Allow reassignment from SpeedGrader
closes OUT-4033
[fsc-timeout=50]
flag=reassign_assignments
This feature allows teachers to reassign an assignment
to a student after they've submitted to the assignment
and the teacher has provided feedback via comments.
The reassignment will appear in their planner with
a "Redo" tag visible next to the assignment.
Only supports assignments of submission type "Online".
test plan:
- enable "Reassign Assignments" feature option
- in a course, create a student account
- as a teacher, create an assignment with a due date
- as a student, confirm the assignment appears in
their planner
- as a student, submit to the assignment
- as a teacher, open the submission in SpeedGrader
- reassign the assignment to the student by:
* adding a comment to the assignment
* clicking the "Reassign Assignment" button
- as a student, confirm the assignment appears
with a "Redo" pill in the planner, along with
the comment from the teacher
- as a student, resubmit to the assignment and
confirm the assignment shows as completed again
in the planner without the "Redo" pill
- repeat the above steps, except with an assignment
that has "Anonymous Grading" enabled and it should
behave in the same way
- repeat the above steps but with more students and
no due date on the assignment, but with various
assignment overrides with due dates and some students
assigned to those overrides (using course sections)
and confirm the "Resassign Assignment" button only
appears for those students with assignment overrides
(and hence due dates), with the button being disabled
until the student both submits to the assignment and
the teacher has provided a comment.
Change-Id: Id745b50f3810378804e0728e544ebf6bff8f756a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/251663
QA-Review: Kai Bjorkman <kbjorkman@instructure.com>
Product-Review: Jody Sailor
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Pat Renner <prenner@instructure.com>
2020-10-28 03:49:42 +08:00
|
|
|
put "anonymous_submissions/:anonymous_id/reassign", to: "anonymous_submissions#redo_submission"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :submissions do
|
2016-12-02 01:37:20 +08:00
|
|
|
get "originality_report/:asset_string" => "submissions#originality_report", :as => :originality_report
|
2014-09-23 02:52:41 +08:00
|
|
|
post "turnitin/resubmit" => "submissions#resubmit_to_turnitin", :as => :resubmit_to_turnitin
|
|
|
|
get "turnitin/:asset_string" => "submissions#turnitin_report", :as => :turnitin_report
|
2016-04-27 08:12:02 +08:00
|
|
|
post "vericite/resubmit" => "submissions#resubmit_to_vericite", :as => :resubmit_to_vericite
|
|
|
|
get "vericite/:asset_string" => "submissions#vericite_report", :as => :vericite_report
|
2018-09-15 05:38:23 +08:00
|
|
|
get "audit_events" => "submissions#audit_events", :as => :audit_events
|
Allow reassignment from SpeedGrader
closes OUT-4033
[fsc-timeout=50]
flag=reassign_assignments
This feature allows teachers to reassign an assignment
to a student after they've submitted to the assignment
and the teacher has provided feedback via comments.
The reassignment will appear in their planner with
a "Redo" tag visible next to the assignment.
Only supports assignments of submission type "Online".
test plan:
- enable "Reassign Assignments" feature option
- in a course, create a student account
- as a teacher, create an assignment with a due date
- as a student, confirm the assignment appears in
their planner
- as a student, submit to the assignment
- as a teacher, open the submission in SpeedGrader
- reassign the assignment to the student by:
* adding a comment to the assignment
* clicking the "Reassign Assignment" button
- as a student, confirm the assignment appears
with a "Redo" pill in the planner, along with
the comment from the teacher
- as a student, resubmit to the assignment and
confirm the assignment shows as completed again
in the planner without the "Redo" pill
- repeat the above steps, except with an assignment
that has "Anonymous Grading" enabled and it should
behave in the same way
- repeat the above steps but with more students and
no due date on the assignment, but with various
assignment overrides with due dates and some students
assigned to those overrides (using course sections)
and confirm the "Resassign Assignment" button only
appears for those students with assignment overrides
(and hence due dates), with the button being disabled
until the student both submits to the assignment and
the teacher has provided a comment.
Change-Id: Id745b50f3810378804e0728e544ebf6bff8f756a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/251663
QA-Review: Kai Bjorkman <kbjorkman@instructure.com>
Product-Review: Jody Sailor
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Adrian Packel <apackel@instructure.com>
Reviewed-by: Pat Renner <prenner@instructure.com>
2020-10-28 03:49:42 +08:00
|
|
|
put "reassign" => "submissions#redo_submission", :as => :reassign
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
Reenable anon plagiarism in SG for Turnitin
For assignments using Turnitin (but not Vericite), re-enable the
SpeedGrader link to the similarity report and the resubmit button even
for assignments that are currently anonymizing.
closes GRADE-1883
Test plan:
- Create an anonymous assignment (with or without file submissions;
see creation steps below)
- In a Rails console, create some OriginalityReport objects for multiple
submissions (see below)
- Give at least one a valid score and workflow_state of 'scored'
- Maybe enter a value for originality_report_url for one of them
- Give at least one a workflow_state of 'error'
- (or use "pending", in which case leave the score blank)
- If your assignment involves file submissions, ensure each report's
attachment_id matches an existent attachment
- Open these submissions in SpeedGrader and check the following:
- For 'scored' reports, you should see a clickable similarity score
that links to a URL of the form:
- .../anonymous_submissions/3oPSs/originality_report/asset_id
(asset_id will be, e.g., submission_34 or attachment_999)
- Visiting that URL should take you to the report's custom URL
if defined, or else return you to SpeedGrader saying that
a report couldn't be found (which is expected since our data
is made up)
- For 'pending'/'error' reports, you should see an error icon that
reveals a 'Resubmit' button when clicked
- Clicking 'Resubmit' should make a request to a URL
of the form (you can check this in your logs):
.../anonymous_submissions/3oPSs/turnitin/resubmit
- This should then redirect you to the submission in SpeedGrader
- Unmute the assignment
- The above URLs should now be in the familiar
'submissions/<submission ID>' form, but work identically
- The one change should be that the above links redirect you to the
submission details page instead of SpeedGrader
APPENDIX: Creating Turnitin originality data:
For a given submission:
> submission.originality_reports.create!(
workflow_state; 'scored', # or 'error' or 'pending'
originality_score: 88.0, # 0 = bad, 100 = great
originality_report_url: <a custom URL if desired>
attachment_id: <specific attachment ID or nil>
)
If your assignment involves submitting files, you will need to specify a
valid attachment ID for attachment_id; otherwise, leave it blank.
APPENDIX 2: A note on Turnitin
It is also possible to set up an LTI-based assignment that uses Turnitin
but this is not strictly required to view originality scores, and
furthermore this author was not sure how to configure it (beyond the
directions given in Confluence) to result in anything other than an
error when opening it, apparently because we were trying to pass a
context_id that was already in use.
Change-Id: Ibf14e6c83e77516ae34d2dde409b623e693d5677
Reviewed-on: https://gerrit.instructure.com/175816
Reviewed-by: Gary Mei <gmei@instructure.com>
Reviewed-by: Keith Garner <kgarner@instructure.com>
Tested-by: Jenkins
QA-Review: Gary Mei <gmei@instructure.com>
Product-Review: Sidharth Oberoi <soberoi@instructure.com>
2018-12-15 00:46:42 +08:00
|
|
|
|
|
|
|
get "anonymous_submissions/:anonymous_id/originality_report/:asset_string",
|
|
|
|
to: "anonymous_submissions#originality_report",
|
|
|
|
as: :anonymous_submission_originality_report
|
|
|
|
post "anonymous_submissions/:anonymous_id/turnitin/resubmit",
|
|
|
|
to: "anonymous_submissions#resubmit_to_turnitin",
|
|
|
|
as: :anonymous_submission_resubmit_to_turnitin
|
|
|
|
get "anonymous_submissions/:anonymous_id/turnitin/:asset_string",
|
|
|
|
to: "anonymous_submissions#turnitin_report",
|
|
|
|
as: :anonymous_submission_turnitin_report
|
|
|
|
post "anonymous_submissions/:anonymous_id/vericite/resubmit",
|
|
|
|
to: "anonymous_submissions#resubmit_to_vericite",
|
|
|
|
as: :anonymous_submission_resubmit_to_vericite
|
|
|
|
get "anonymous_submissions/:anonymous_id/vericite/:asset_string",
|
|
|
|
to: "anonymous_submissions#vericite_report",
|
|
|
|
as: :anonymous_submission_vericite_report
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get :rubric
|
|
|
|
resource :rubric_association, path: :rubric do
|
|
|
|
resources :rubric_assessments, path: :assessments
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get :peer_reviews
|
|
|
|
post :assign_peer_reviews
|
|
|
|
delete "peer_reviews/:id" => "assignments#delete_peer_review", :as => :delete_peer_review
|
|
|
|
post "peer_reviews/:id" => "assignments#remind_peer_review", :as => :remind_peer_review
|
|
|
|
post "peer_reviews/users/:reviewer_id" => "assignments#assign_peer_review", :as => :assign_peer_review
|
|
|
|
put "mute" => "assignments#toggle_mute"
|
2013-06-15 01:09:41 +08:00
|
|
|
|
|
|
|
collection do
|
|
|
|
get :syllabus
|
|
|
|
get :submissions
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
|
|
|
|
member do
|
|
|
|
get :list_google_docs
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2017-05-19 02:28:16 +08:00
|
|
|
|
|
|
|
get "lti/resource/:resource_link_id", controller: "lti/message",
|
|
|
|
action: "resource", as: :resource_link_id
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2012-11-20 03:41:51 +08:00
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :grading_standards, only: %i[index create update destroy]
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :assignment_groups do
|
2014-09-23 02:52:41 +08:00
|
|
|
post "reorder" => "assignment_groups#reorder_assignments", :as => :reorder_assignments
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
post :reorder
|
2012-11-20 03:41:51 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2012-11-20 03:41:51 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "external_tools/sessionless_launch" => "external_tools#sessionless_launch"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :external_tools do
|
2017-11-25 00:35:39 +08:00
|
|
|
match :resource_selection, via: [:get, :post]
|
2014-09-23 02:52:41 +08:00
|
|
|
get :homework_submission
|
|
|
|
get :finished
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
get :retrieve
|
|
|
|
get :homework_submissions
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-05-25 22:29:15 +08:00
|
|
|
get "lti/resource/:resource_link_id", controller: "lti/message",
|
|
|
|
action: "resource", as: :resource_link_id
|
2015-10-29 05:58:10 +08:00
|
|
|
get "lti/basic_lti_launch_request/:message_handler_id", controller: "lti/message",
|
|
|
|
action: "basic_lti_launch_request", as: :basic_lti_launch_request
|
2017-11-07 05:59:52 +08:00
|
|
|
post "lti/tool_proxy_registration", controller: "lti/message", action: "registration", as: :tool_proxy_registration
|
2015-10-29 05:58:10 +08:00
|
|
|
get "lti/tool_proxy_reregistration/:tool_proxy_id", controller: "lti/message", action: "reregistration",
|
|
|
|
as: :tool_proxy_reregistration
|
2017-01-25 03:28:26 +08:00
|
|
|
get "lti/registration_return", controller: "lti/message", action: "registration_return",
|
2015-10-29 05:58:10 +08:00
|
|
|
as: :registration_return
|
2014-08-06 00:47:33 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :submissions
|
|
|
|
resources :calendar_events
|
|
|
|
|
|
|
|
concerns :files, :file_images, :relative_files, :folders
|
|
|
|
concerns :groups
|
2014-10-10 10:18:35 +08:00
|
|
|
concerns :pages
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :conferences
|
|
|
|
concerns :question_banks
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "quizzes/publish" => "quizzes/quizzes#publish"
|
|
|
|
post "quizzes/unpublish" => "quizzes/quizzes#unpublish"
|
2014-01-28 05:07:09 +08:00
|
|
|
|
2019-09-18 21:21:31 +08:00
|
|
|
post "assignments/publish/quiz" => "assignments#publish_quizzes"
|
|
|
|
post "assignments/unpublish/quiz" => "assignments#unpublish_quizzes"
|
|
|
|
|
2017-10-25 04:02:17 +08:00
|
|
|
post "quizzes/new" => "quizzes/quizzes#new" # use POST instead of GET (not idempotent)
|
|
|
|
resources :quizzes, controller: "quizzes/quizzes", except: :new do
|
2014-09-23 02:52:41 +08:00
|
|
|
get :managed_quiz_data
|
|
|
|
get :submission_versions
|
|
|
|
get :history
|
|
|
|
get :statistics
|
|
|
|
get :read_only
|
|
|
|
get :submission_html
|
|
|
|
|
|
|
|
resources :quiz_submissions, controller: "quizzes/quiz_submissions", path: :submissions do
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
put :backup
|
2016-03-03 05:41:12 +08:00
|
|
|
post :backup
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
member do
|
2013-10-15 13:53:37 +08:00
|
|
|
get :record_answer
|
2013-06-15 01:09:41 +08:00
|
|
|
post :record_answer
|
|
|
|
end
|
2015-02-06 05:09:02 +08:00
|
|
|
resources :events, controller: "quizzes/quiz_submission_events", path: "log#{full_path_glob}"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "extensions/:user_id" => "quizzes/quiz_submissions#extensions", :as => :extensions
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :quiz_questions, controller: "quizzes/quiz_questions", path: :questions, only: %i[create update destroy show]
|
|
|
|
resources :quiz_groups, controller: "quizzes/quiz_groups", path: :groups, only: %i[create update destroy] do
|
2013-11-12 03:24:24 +08:00
|
|
|
member do
|
|
|
|
post :reorder
|
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
match "take" => "quizzes/quizzes#show", :take => "1", :via => [:get, :post]
|
|
|
|
get "take/questions/:question_id" => "quizzes/quizzes#show", :as => :question, :take => "1"
|
|
|
|
get :moderate
|
|
|
|
get :lockdown_browser_required
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
resources :collaborations
|
2016-05-19 04:11:50 +08:00
|
|
|
get "lti_collaborations" => "collaborations#lti_index"
|
2016-07-12 00:48:13 +08:00
|
|
|
get "lti_collaborations/*all" => "collaborations#lti_index"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :gradebook_uploads
|
|
|
|
resources :rubrics
|
|
|
|
resources :rubric_associations do
|
2014-09-23 02:52:41 +08:00
|
|
|
post "remind/:assessment_request_id" => "rubric_assessments#remind", :as => :remind_assessee
|
|
|
|
resources :rubric_assessments, path: "assessments"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "outcomes/users/:user_id" => "outcomes#user_outcome_results", :as => :user_outcomes_results
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :outcomes do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "alignments/:id" => "outcomes#alignment_redirect", :as => :alignment_redirect
|
|
|
|
post "alignments" => "outcomes#align", :as => :align
|
|
|
|
delete "alignments/:id" => "outcomes#remove_alignment", :as => :remove_alignment
|
|
|
|
get "results" => "outcomes#outcome_results"
|
|
|
|
get "results/:id" => "outcomes#outcome_result", :as => :result
|
|
|
|
get :details
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
get :list
|
|
|
|
post :add_outcome
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :outcome_groups, only: %i[create update destroy] do
|
2014-09-23 02:52:41 +08:00
|
|
|
post :reorder
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :context_modules, path: :modules do
|
|
|
|
post "items" => "context_modules#add_item", :as => :add_item
|
|
|
|
post "reorder" => "context_modules#reorder_items", :as => :reorder
|
|
|
|
post "collapse" => "context_modules#toggle_collapse", :as => :toggle_collapse
|
|
|
|
get "prerequisites/:code" => "context_modules#content_tag_prerequisites_needing_finishing", :as => :prerequisites_needing_finishing
|
|
|
|
get "items/last" => "context_modules#module_redirect", :as => :last_redirect, :last => 1
|
|
|
|
get "items/first" => "context_modules#module_redirect", :as => :first_redirect, :first => 1
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
post :reorder
|
|
|
|
get :progressions
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-02-16 00:10:48 +08:00
|
|
|
get "blackout_dates" => "blackout_dates#index"
|
2022-04-08 00:00:38 +08:00
|
|
|
get "course_pacing" => "course_paces#index"
|
Initial pace plans import
This change brings in the basic pace plans frontend with
styled-components and several other smaller libraries replaced with
InstUI 7 components. It also adds the 'reselect' library as a direct
dependency (which we already had through @instructure/outcomes-ui) and
'tsc-files' for type-checking of staged TS files on commit. There were
also some tweaks to typescript and eslint configs, mostly to get both
up to speed with the typescript code.
Finally, this also adds a `pace_plans` endpoint to
`courses_controller` to bootstrap the frontend-- this will get moved
to `pace_plans_controller` once it has been merged.
It's also worth noting that no frontend tests are included with this
change-- the existing tests were written with enzyme and are heavily
snapshot-based, so we will be replacing those with
@testing-library/react tests in later updates (in keeping with current
testing best practices at Instructure).
closes LS-2431, LS-2432, LS-2433, LS-2434, LS-2452
flag = pace_plans
Test plan:
- Set up a course with at least one module and several module items
- Turn on the pace_plans feature flag in the account associated with
that course
- Turn on the "Enable pace plans" setting in course settings
- Create a pace plan for the course via the Rails console:
c = Course.find<id>
pp = c.pace_plans.create! workflow_state: 'active'
c.context_module_tags.each_with_index do |t, i|
pp.pace_plan_module_items.create! module_item: t, duration: i*2
end
- Go to the course as a teacher or admin
- Expect to see a "Pace Plans" link in the course navigation
- Click it, expect the pace plan you created earlier to load and
render
- Expect to be able to pick dates, change durations, and toggle
checkboxes (although saves will fail, since there is no API yet).
- Expect to not see the "Pace Plans" course nav link when the feature
flag or course setting is off
- Expect /courses/<id>/pace_plans to return a 404 when the feature
flag or course setting is off
- Expect to not see the "Pace Plans" course nav link as a student
- Expect /courses/<id>/pace_plans to display an "Unauthorized" page
as a student
Change-Id: If4dc5d17f2c6a2109d4b4cb652c9e9ef00d7cc33
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/271650
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
QA-Review: Ed Schiebel <eschiebel@instructure.com>
Product-Review: Jeff Largent <jeff.largent@instructure.com>
2021-08-18 05:14:24 +08:00
|
|
|
|
2020-07-24 04:47:30 +08:00
|
|
|
post "collapse_all_modules" => "context_modules#toggle_collapse_all"
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :content_exports, only: %i[create index destroy show]
|
2016-12-01 05:41:27 +08:00
|
|
|
get "offline_web_exports" => "courses#offline_web_exports"
|
2016-12-16 05:38:58 +08:00
|
|
|
post "start_offline_web_export" => "courses#start_offline_web_export"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "modules/items/assignment_info" => "context_modules#content_tag_assignment_data", :as => :context_modules_assignment_info
|
2017-01-21 05:12:38 +08:00
|
|
|
get "modules/items/master_course_info" => "context_modules#content_tag_master_course_data", :as => :context_modules_master_course_info
|
2014-09-23 02:52:41 +08:00
|
|
|
get "modules/items/:id" => "context_modules#item_redirect", :as => :context_modules_item_redirect
|
implement cyoe gear option for score-able objects
refs CYOE-304
test plan:
- there should be no changes in the student view
- part 1:
- create a new course with cyoe disabled
- create two new assignments (one graded, one ungraded), four new
quizzes (one graded, one practice, one survey, one graded survey),
and two discussions (one graded, one ungraded), one page
- create a new module and add the items from above as module items
- check the cog menu on the created items and ensure that there
is no "Mastery Paths" option in any of the following views:
- assignments index page
- quizzes index page
- discussions index page
- all items on the modules page
- part 2:
- enable cyoe in the course from part 1
- create a new page with "allow in mastery paths" checkbox checked
- create a module item for the new page
- check the same four index pages as before (assignments, quizzes,
discussions, and modules) and make sure that:
- the following items have a "Mastery Paths" cog menu option:
- the graded assignment
- the graded discussion
- the graded quiz
- clicking on the "Mastery Paths" menu option on any
of the above menus navigates to the correct edit page with the
mastery paths tab opened on page load
- the following items do not have the "Mastery Paths" option:
- the ungraded assignment
- the ungraded discussion
- the practice quiz
- the survey
- the graded survey
- both pages
Change-Id: I20c905d764fd3533ae8e68dbd99b7b73fcff81ed
Reviewed-on: https://gerrit.instructure.com/91129
Tested-by: Jenkins
Reviewed-by: Christian Prescott <cprescott@instructure.com>
Reviewed-by: Michael Brewer-Davis <mbd@instructure.com>
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Felix Milea-Ciobanu <fmileaciobanu@instructure.com>
2016-09-22 23:23:50 +08:00
|
|
|
get "modules/items/:id/edit_mastery_paths" => "context_modules#item_redirect_mastery_paths"
|
2016-08-17 20:20:01 +08:00
|
|
|
get "modules/items/:id/choose" => "context_modules#choose_mastery_path"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "modules/items/sequence/:id" => "context_modules#item_details", :as => :context_modules_item_details
|
|
|
|
delete "modules/items/:id" => "context_modules#remove_item", :as => :context_modules_remove_item
|
|
|
|
put "modules/items/:id" => "context_modules#update_item", :as => :context_modules_update_item
|
|
|
|
get "confirm_action" => "courses#confirm_action"
|
|
|
|
get :copy, as: :start_copy
|
|
|
|
post "copy" => "courses#copy_course", :as => :copy_course
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :media
|
2014-09-23 02:52:41 +08:00
|
|
|
get "user_notes" => "user_notes#user_notes"
|
|
|
|
get "details/sis_publish" => "courses#sis_publish_status", :as => :sis_publish_status
|
|
|
|
post "details/sis_publish" => "courses#publish_to_sis", :as => :publish_to_sis
|
2016-09-29 01:41:49 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :user_lists, only: :create
|
2016-09-29 01:41:49 +08:00
|
|
|
post "invite_users" => "users#invite_users", :as => :invite_users
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "reset" => "courses#reset_content"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :alerts
|
Allow easy toggle student view
Places a button at the top of most course pages allowing teachers
to switch into student view quickly. Supported pages are listed in
application_controller.rb:2740. Hides the student view button from
the homepage when this flag is enabled. Adds optional param to the
student_view route which controls whether the user is directed back
to the referer or to the homepage after entering student view (for
use in settings page, when we want the user to hit the homepage).
flag=easy_student_view
closes LS-1250
Test plan:
- In a course, enable the flag
- On supported pages (i.e. not course settings, dashboard, files,
etc), expect to see the student view button in the top-right
corner
- Click on the button, expect to switch to student view on the
current page
- Click leave, expect to switch back to teacher view on the same
page
- Expect to see the old student view button gone from the course
home page, but present on the course settings page
- Disable a page, navigate to that page, expect the student view
button to be gone
- Navigate the course as a student, should never see any student
view references
Change-Id: I8ff08f04050d6e2ab71f246b725d65217594a8c7
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/252169
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Ed Schiebel <eschiebel@instructure.com>
QA-Review: Robin Kuss <rkuss@instructure.com>
Product-Review: Peyton Craighill <pcraighill@instructure.com>
2020-11-07 03:34:38 +08:00
|
|
|
post "student_view(/:redirect_to_referer)" => "courses#student_view", :as => :student_view
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "student_view" => "courses#leave_student_view"
|
|
|
|
delete "test_student" => "courses#reset_test_student"
|
|
|
|
get "content_migrations" => "content_migrations#index"
|
2015-07-10 04:33:36 +08:00
|
|
|
get "link_validator" => "courses#link_validator", :as => :link_validator
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2011-05-10 05:20:58 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "quiz_statistics/:quiz_statistics_id/files/:file_id/download" => "files#show", :as => :quiz_statistics_download, :download => "1"
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :page_views, only: :update
|
2021-10-08 01:51:08 +08:00
|
|
|
post "media_objects" => "media_objects#create_media_object", :as => :create_media_object
|
|
|
|
get "media_objects/:id" => "media_objects#media_object_inline", :as => :media_object
|
|
|
|
get "media_objects/:id/redirect" => "media_objects#media_object_redirect", :as => :media_object_redirect
|
|
|
|
get "media_objects/:id/thumbnail" => "media_objects#media_object_thumbnail", :as => :media_object_thumbnail
|
2014-09-23 02:52:41 +08:00
|
|
|
get "media_objects/:media_object_id/info" => "media_objects#show", :as => :media_object_info
|
2019-08-22 06:43:45 +08:00
|
|
|
get "media_objects_iframe/:media_object_id" => "media_objects#iframe_media_player", :as => :media_object_iframe
|
2019-09-13 05:39:39 +08:00
|
|
|
get "media_objects_iframe" => "media_objects#iframe_media_player", :as => :media_object_iframe_href
|
2014-09-23 02:52:41 +08:00
|
|
|
get "media_objects/:media_object_id/media_tracks/:id" => "media_tracks#show", :as => :show_media_tracks
|
|
|
|
post "media_objects/:media_object_id/media_tracks" => "media_tracks#create", :as => :create_media_tracks
|
|
|
|
delete "media_objects/:media_object_id/media_tracks/:media_track_id" => "media_tracks#destroy", :as => :delete_media_tracks
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2015-05-13 04:27:58 +08:00
|
|
|
get "external_content/success/:service" => "external_content#success", :as => :external_content_success
|
2016-04-15 23:17:56 +08:00
|
|
|
get "external_content/success/:service/:id" => "external_content#success", :as => :external_content_update
|
2014-09-23 02:52:41 +08:00
|
|
|
get "external_content/retrieve/oembed" => "external_content#oembed_retrieve", :as => :external_content_oembed_retrieve
|
|
|
|
get "external_content/cancel/:service" => "external_content#cancel", :as => :external_content_cancel
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course group].each do |context|
|
2018-12-07 00:21:58 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id"
|
|
|
|
post "#{prefix}/deep_linking_response", controller: "lti/ims/deep_linking", action: :deep_linking_response, as: "#{context}_deep_linking_response"
|
|
|
|
end
|
|
|
|
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course group user].each do |context|
|
2015-05-02 00:42:00 +08:00
|
|
|
match "#{context.pluralize}/:#{context}_id/external_content/success/:service" => "external_content#success", :as => "#{context}_external_content_success", :via => [:get, :post]
|
2016-04-15 23:17:56 +08:00
|
|
|
match "#{context.pluralize}/:#{context}_id/external_content/success/:service/:id" => "external_content#success", :as => "#{context}_external_content_update", :via => [:get, :post]
|
2015-05-02 00:42:00 +08:00
|
|
|
end
|
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
# We offer a bunch of atom and ical feeds for the user to get
|
|
|
|
# data out of Instructure. The :feed_code attribute is keyed
|
|
|
|
# off of either a user, and enrollment, a course, etc. based on
|
|
|
|
# that item's uuid. In config/initializers/active_record.rb you'll
|
2011-12-07 00:38:32 +08:00
|
|
|
# find a feed_code method to generate the code, and in
|
2011-02-01 09:57:29 +08:00
|
|
|
# application_controller there's a get_feed_context to get it back out.
|
2013-06-15 01:09:41 +08:00
|
|
|
scope "/feeds" do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "calendars/:feed_code" => "calendar_events_api#public_feed", :as => :feeds_calendar
|
|
|
|
get "calendars/:feed_code.:format" => "calendar_events_api#public_feed", :as => :feeds_calendar_format
|
|
|
|
get "forums/:feed_code" => "discussion_topics#public_feed", :as => :feeds_forum
|
|
|
|
get "forums/:feed_code.:format" => "discussion_topics#public_feed", :as => :feeds_forum_format
|
|
|
|
get "topics/:discussion_topic_id/:feed_code" => "discussion_entries#public_feed", :as => :feeds_topic
|
|
|
|
get "topics/:discussion_topic_id/:feed_code.:format" => "discussion_entries#public_feed", :as => :feeds_topic_format
|
|
|
|
get "announcements/:feed_code" => "announcements#public_feed", :as => :feeds_announcements
|
|
|
|
get "announcements/:feed_code.:format" => "announcements#public_feed", :as => :feeds_announcements_format
|
|
|
|
get "courses/:feed_code" => "courses#public_feed", :as => :feeds_course
|
|
|
|
get "courses/:feed_code.:format" => "courses#public_feed", :as => :feeds_course_format
|
|
|
|
get "groups/:feed_code" => "groups#public_feed", :as => :feeds_group
|
|
|
|
get "groups/:feed_code.:format" => "groups#public_feed", :as => :feeds_group_format
|
|
|
|
get "enrollments/:feed_code" => "courses#public_feed", :as => :feeds_enrollment
|
|
|
|
get "enrollments/:feed_code.:format" => "courses#public_feed", :as => :feeds_enrollment_format
|
|
|
|
get "users/:feed_code" => "users#public_feed", :as => :feeds_user
|
|
|
|
get "users/:feed_code.:format" => "users#public_feed", :as => :feeds_user_format
|
|
|
|
get "eportfolios/:eportfolio_id.:format" => "eportfolios#public_feed", :as => :feeds_eportfolio
|
|
|
|
get "conversations/:feed_code" => "conversations#public_feed", :as => :feeds_conversation
|
|
|
|
get "conversations/:feed_code.:format" => "conversations#public_feed", :as => :feeds_conversation_format
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :assessment_questions do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "files/:id/download" => "files#assessment_question_show", :as => :map, :download => "1"
|
|
|
|
get "files/:id/preview" => "files#assessment_question_show", :preview => "1"
|
|
|
|
get "files/:id/:verifier" => "files#assessment_question_show", :as => :verified_file, :download => "1"
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :eportfolios, except: :index do
|
|
|
|
post :reorder_categories
|
|
|
|
post ":eportfolio_category_id/reorder_entries" => "eportfolios#reorder_entries", :as => :reorder_entries
|
|
|
|
resources :categories, controller: :eportfolio_categories
|
|
|
|
resources :entries, controller: :eportfolio_entries do
|
|
|
|
resources :page_comments, path: :comments, only: [:create, :destroy]
|
|
|
|
get "files/:attachment_id" => "eportfolio_entries#attachment", :as => :view_file
|
|
|
|
get "submissions/:submission_id" => "eportfolio_entries#submission", :as => :preview_submission
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get :export, as: :export_portfolio
|
|
|
|
get ":category_name" => "eportfolio_categories#show", :as => :named_category
|
|
|
|
get ":category_name/:entry_name" => "eportfolio_entries#show", :as => :named_category_entry
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
resources :groups do
|
|
|
|
concerns :users
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "remove_user/:user_id" => "groups#remove_user", :as => :remove_user
|
|
|
|
post :add_user
|
|
|
|
get "accept_invitation/:uuid" => "groups#accept_invitation", :as => :accept_invitation
|
|
|
|
get "members" => "groups#context_group_members"
|
|
|
|
get "undelete" => "context#undelete_index", :as => :undelete_items
|
|
|
|
post "undelete/:asset_string" => "context#undelete_item", :as => :undelete_item
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :announcements
|
|
|
|
concerns :discussions
|
|
|
|
resources :calendar_events
|
|
|
|
concerns :files, :file_images, :relative_files, :folders
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :external_tools, only: :show do
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
get :retrieve
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-10 10:18:35 +08:00
|
|
|
concerns :pages
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :conferences
|
|
|
|
concerns :media
|
|
|
|
|
|
|
|
resources :collaborations
|
2016-05-19 06:04:37 +08:00
|
|
|
get "lti_collaborations" => "collaborations#lti_index"
|
2016-07-12 00:48:13 +08:00
|
|
|
get "lti_collaborations/*all" => "collaborations#lti_index"
|
2018-04-25 09:08:08 +08:00
|
|
|
get "calendar" => "calendars#show"
|
2015-04-10 01:30:56 +08:00
|
|
|
|
|
|
|
resources :external_tools do
|
|
|
|
get :finished
|
2017-11-25 00:35:39 +08:00
|
|
|
match :resource_selection, via: [:get, :post]
|
2015-04-10 01:30:56 +08:00
|
|
|
collection do
|
|
|
|
get :retrieve
|
|
|
|
end
|
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
resources :accounts do
|
2016-04-20 03:27:58 +08:00
|
|
|
get "search(/:tab)", action: :course_user_search
|
2014-11-04 11:58:08 +08:00
|
|
|
get "settings#{full_path_glob}", action: :settings
|
2019-04-19 04:18:15 +08:00
|
|
|
get :reports_tab
|
2014-09-23 02:52:41 +08:00
|
|
|
get :settings
|
|
|
|
get :admin_tools
|
2019-12-13 07:01:21 +08:00
|
|
|
get :eportfolio_moderation
|
2016-04-09 03:00:29 +08:00
|
|
|
get "search" => "accounts#course_user_search", :as => :course_user_search
|
2014-09-23 02:52:41 +08:00
|
|
|
post "account_users" => "accounts#add_account_user", :as => :add_account_user
|
|
|
|
delete "account_users/:id" => "accounts#remove_account_user", :as => :remove_account_user
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :grading_standards, only: %i[index create update destroy]
|
2014-09-23 02:52:41 +08:00
|
|
|
get :statistics
|
|
|
|
get "statistics/over_time/:attribute" => "accounts#statistics_graph", :as => :statistics_graph
|
|
|
|
get "statistics/over_time/:attribute.:format" => "accounts#statistics_graph", :as => :formatted_statistics_graph
|
|
|
|
get :turnitin_confirmation
|
2016-04-27 08:12:02 +08:00
|
|
|
get :vericite_confirmation
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :permissions, controller: :role_overrides, only: [:index, :create] do
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
post :add_role
|
|
|
|
delete :remove_role
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-08-15 02:42:55 +08:00
|
|
|
scope(controller: :brand_configs) do
|
|
|
|
get "theme_editor", action: :new, as: :theme_editor
|
2016-01-19 03:29:32 +08:00
|
|
|
get "brand_configs", action: :index
|
2015-08-15 02:42:55 +08:00
|
|
|
post "brand_configs", action: :create
|
|
|
|
delete "brand_configs", action: :destroy
|
|
|
|
post "brand_configs/save_to_account", action: :save_to_account
|
|
|
|
post "brand_configs/save_to_user_session", action: :save_to_user_session
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :role_overrides, only: [:index, :create] do
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
post :add_role
|
|
|
|
delete :remove_role
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :terms, except: %i[show new edit]
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :sub_accounts
|
2013-11-16 00:01:13 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get :avatars
|
|
|
|
get :sis_import
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :sis_imports, only: %i[create show index], controller: :sis_imports_api
|
2020-08-11 02:19:07 +08:00
|
|
|
get "users" => "accounts#users", :as => "users"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "users" => "users#create", :as => :add_user
|
|
|
|
get "users/:user_id/delete" => "accounts#confirm_delete_user", :as => :confirm_delete_user
|
|
|
|
delete "users/:user_id" => "accounts#remove_user", :as => :delete_user
|
2014-06-25 00:40:30 +08:00
|
|
|
|
clean up user "deletion"
fixes CNVS-1552
any time the UI/API tries to "delete" a user, it should only be trying
to remove it from some root account (the @domain_root_account if not
otherwise specified). if that root account was the last root account the
user was associated with, then the remnants of the user are fully
deleted, but only then. leave User#destroy as a short-cut to delete the
user from all their accounts at once, but should not be invoked directly
from any UI/API actions.
test-plan:
PERMISSIONS
being able to remove a user from an account entails being able to:
- DELETE http://accounts-domain/users/:user
- DELETE /accounts/:account/users/:user
both should fail or succeed together
* given
- Sally who's an admin with the :manage_user_logins
permission on one account (Account1) and a student on another
account (Account2)
- Bob who's a student on both accounts
- Alice who's an admin on Account1 with greater permissions than
Sally
* Sally should:
- see "Delete My Account" on her Account1 profile
- not see "Delete My Account" on her Account2 profile
- not see "Delete My Account" on Bob's Account1 profile
- not see "Delete My Account" on Alice's Account1 profile
- see "Delete from Account1" at /users/:sally
- see "Delete from Account1" at /users/:bob
- not see "Delete from Account2" at /users/:sally
- not see "Delete from Account2" at /users/:bob
- not see "Delete from Account1" at /users/:alice
- be able to remove herself from Account1
- be able to remove Bob from Account1
- not be able to remove herself from Account2
- not be able to remove Bob from Account2
- not be able to remove Alice from Account1
* given Sally's Account1 pseudonym has a SIS ID but her Account2
pseudonym doesn't, Sally should:
- no longer see "Delete My Account" on her Account1 profile
- no longer see "Delete from Account1" at /users/:sally
- still see "Delete from Account1" at /users/:bob
- no longer be able to remove herself from Account1
- still be able to remove Bob from Account1
EFFECTS
* as Sally, remove Bob from Account1 via
DELETE http://account1-domain/users/:bob
- Bob's pseudonyms, enrollments, etc. in Account1 should be removed
- Bob's pseudonyms, enrollments, etc. in Account2 should be untouched
* repeat using DELETE /accounts/:account1/users/:bob, with the same
expectations
Change-Id: Ib7612f95d1c7e4cca36d8486950565ec096b4ab1
Reviewed-on: https://gerrit.instructure.com/41591
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
2014-09-23 07:04:03 +08:00
|
|
|
# create/delete are handled by specific routes just above
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :users, only: %i[new edit show update]
|
|
|
|
resources :account_notifications, only: %i[create update destroy]
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :announcements
|
|
|
|
resources :submissions
|
2018-04-25 05:49:30 +08:00
|
|
|
delete "authentication_providers" => "authentication_providers#destroy_all", :as => :remove_all_authentication_providers
|
|
|
|
put "sso_settings" => "authentication_providers#update_sso_settings",
|
refactor views for unified AAC administration
closes CNVS-20076
First, pull a presenter out of the AAC index
This thing needs more flexibility before introducing
multiple OAuth connectors. This commit adds a couple characterization
specs for the AAC controller, then drives out a presenter to pull
as much logic and config out of the nested views as possible.
Then, this commit refactors the
previously-somewhat-bespoke-and-presumptive sac
configuration into a workflow that shows each aac
in turn according to it's type, creating forms for
each type at the bottom, and
showing the relevant form for a new one based on
selection on the right.
Have regression tested in the browser to the level
of CRUD functionality, but also deserves solid QA
for SSO functionality post-configuration.
DONE:
-successful CAS creation/editing/deletion
-successful LDAP creation/editing/deletion
-proper differentiation between LDAP primary and secondary
-proper SAML creation/editing
-move away from "update_all" deprecated endpoint
-Selenium Spec fixes
-ensure discovery URL and debugging workflows for saml
-remove duplication from views
-tear down old JS workflow
-apply appropriate tests for new behavior
-remove presenter methods that are no longer valuable
-Moved change_password_url and login_handle_name
-up to account settings, removed them from AACs, and built
-migrations to manage the transition.
-Found and fixed all references to change_password_url on AACs
-Found and fixes all references to login_handle_name on AACs
-add datafixup for migrating AAC data to account settings
-unify repetative individual files into single form delcarations \o/
-remove old SAML editing js
-Make sure SAML still works
-Make LDAP partial flow just like SAML/CAS
-Unify position information across all types
-update "acts_as_list" to support STI classes
-move discovery URL into account auth form
-remove discover URL js management
-Unify form generation between new/existing aacs
-deprecate discovery url API endpoints
-update docs for authorization settings to deprecate their usage in AAC
api and redirect their values to current settings for now
-make delete links non-js-y to stop this silly page refresh on api
completion
-make form submissions actually submit the form rather than do this silly
page refresh on api completion
-See if anything needs “Edit Details” button, remove if not
-Wire up removing account settings by blanking out form
-Removed "cancel" button from form because fields are always open
-placate gergich
-Test removing config info
-Test population fixup on real data
-write docs for authorization settings
-fix existing specs
-fix routing and docs to not break doc generation
-fix stupid jenkins task that thinks it can’t see controls
-re-fix selenium
-fix saml debugging workflow
-write tests for acts_as_list behavior
-write tests for authorization settings
-remove auth_info types of things
-clean up and unify styles where possible
TEST PLAN:
Regression test creating/deleting/editing and logging
in with SSO solutions for CAS, LDAP, and SAML.
Should be no functional behavior modification, though
workflow will be a little more unified between the
3 currently supported types (each one will
require using the menu in the right sidebar
to add a new AAC).
Also test setting and deleting account settings through
the form underneath the configs when there are AACs in existence.
Finally, make sure that the SAML Debugging workflow still works.
Change-Id: I448db10185512d1b9469c2a425be0a3bcf9e6ebf
Reviewed-on: https://gerrit.instructure.com/53448
Tested-by: Jenkins
Reviewed-by: Cody Cutrer <cody@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Ethan Vizitei <evizitei@instructure.com>
2015-04-28 05:23:04 +08:00
|
|
|
:as => :update_sso_settings
|
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :authentication_providers, only: %i[index create update destroy] do
|
2018-09-01 05:29:39 +08:00
|
|
|
get :debugging, action: :debug_data
|
|
|
|
put :debugging, action: :start_debugging
|
|
|
|
delete :debugging, action: :stop_debugging
|
|
|
|
end
|
2018-04-25 05:49:30 +08:00
|
|
|
get "test_ldap_connections" => "authentication_providers#test_ldap_connection"
|
|
|
|
get "test_ldap_binds" => "authentication_providers#test_ldap_bind"
|
|
|
|
get "test_ldap_searches" => "authentication_providers#test_ldap_search"
|
|
|
|
match "test_ldap_logins" => "authentication_providers#test_ldap_login", :via => [:get, :post]
|
2014-09-23 02:52:41 +08:00
|
|
|
|
|
|
|
get "external_tools/sessionless_launch" => "external_tools#sessionless_launch"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :external_tools do
|
2014-09-23 02:52:41 +08:00
|
|
|
get :finished
|
2017-11-25 00:35:39 +08:00
|
|
|
match :resource_selection, via: [:get, :post]
|
2015-01-22 00:37:45 +08:00
|
|
|
collection do
|
|
|
|
get :retrieve
|
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2017-05-25 22:29:15 +08:00
|
|
|
get "lti/resource/:resource_link_id", controller: "lti/message",
|
|
|
|
action: "resource", as: :resource_link_id
|
2015-10-29 05:58:10 +08:00
|
|
|
get "lti/basic_lti_launch_request/:message_handler_id", controller: "lti/message",
|
|
|
|
action: "basic_lti_launch_request", as: :basic_lti_launch_request
|
2017-11-07 05:59:52 +08:00
|
|
|
post "lti/tool_proxy_registration", controller: "lti/message", action: "registration", as: :tool_proxy_registration
|
2015-10-29 05:58:10 +08:00
|
|
|
get "lti/tool_proxy_reregistration/:tool_proxy_id", controller: "lti/message", action: "reregistration",
|
|
|
|
as: :tool_proxy_reregistration
|
2017-01-25 03:28:26 +08:00
|
|
|
get "lti/registration_return", controller: "lti/message", action: "registration_return",
|
2015-10-29 05:58:10 +08:00
|
|
|
as: :registration_return
|
2014-08-06 00:47:33 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "outcomes/users/:user_id" => "outcomes#user_outcome_results", :as => :user_outcomes_results
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :outcomes do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "results" => "outcomes#outcome_results"
|
|
|
|
get "results/:id" => "outcomes#outcome_result", :as => :result
|
2016-05-17 06:00:59 +08:00
|
|
|
get "alignments/:id" => "outcomes#alignment_redirect", :as => :alignment_redirect
|
2014-09-23 02:52:41 +08:00
|
|
|
get :details
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
get :list
|
|
|
|
post :add_outcome
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :outcome_groups, only: %i[create update destroy] do
|
2014-09-23 02:52:41 +08:00
|
|
|
post :reorder
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
resources :rubrics
|
|
|
|
resources :rubric_associations do
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :rubric_assessments, path: "assessments"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
concerns :files, :file_images, :relative_files, :folders
|
|
|
|
concerns :media
|
|
|
|
concerns :groups
|
|
|
|
|
|
|
|
resources :outcomes
|
2014-09-23 02:52:41 +08:00
|
|
|
get :courses
|
|
|
|
get "courses/:id" => "accounts#courses_redirect", :as => :courses_redirect
|
|
|
|
get "user_notes" => "user_notes#user_notes"
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :alerts
|
|
|
|
resources :question_banks do
|
2014-09-23 02:52:41 +08:00
|
|
|
post :bookmark
|
|
|
|
post :reorder
|
|
|
|
get :questions
|
|
|
|
post :move_questions
|
2014-03-07 06:10:04 +08:00
|
|
|
resources :assessment_questions
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :user_lists, only: :create
|
2013-06-15 01:09:41 +08:00
|
|
|
|
|
|
|
member do
|
|
|
|
get :statistics
|
|
|
|
end
|
2015-08-22 04:48:05 +08:00
|
|
|
resources :developer_keys, only: :index
|
2021-04-22 04:26:07 +08:00
|
|
|
|
|
|
|
get "release_notes" => "release_notes#manage", :as => :release_notes_manage
|
2022-02-16 00:10:48 +08:00
|
|
|
|
|
|
|
get "blackout_dates" => "blackout_dates#index"
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "images/users/:user_id" => "users#avatar_image", :as => :avatar_image
|
|
|
|
get "images/thumbnails/:id/:uuid" => "files#image_thumbnail", :as => :thumbnail_image
|
|
|
|
get "images/thumbnails/show/:id/:uuid" => "files#show_thumbnail", :as => :show_thumbnail_image
|
|
|
|
post "images/users/:user_id/report" => "users#report_avatar_image", :as => :report_avatar_image
|
|
|
|
put "images/users/:user_id" => "users#update_avatar_image", :as => :update_avatar_image
|
|
|
|
get "grades" => "users#grades"
|
feature flag for 'All Grading Periods' totals
Add grading period dropdowns on the 'grades' page,
and add a "Display Totals for 'All Grading Periods'"
feature flag. By default, the feature will be turned
'off'.
When the feature is 'off':
- Totals will not display in the gradebook
or the 'student grades' page when the 'All
Grading Periods' option is selected.
- The grading period dropdowns on the 'grades'
page will not have an 'All Grading Periods'
option.
When the feature is 'on':
- Totals will display in the gradebook and the
'student grades' page when the 'All Grading
Periods' option is selected.
- The grading period dropdowns on the 'grades'
page will have an 'All Grading Periods' option.
closes CNVS-23995
test plan:
1) as a teacher, enable the 'multiple grading
periods' feature (do not enable the 'display
totals for all grading periods' feature yet).
a) verify the gradebook does not show totals
when the 'All Grading Periods' option is
selected.
b) verify the 'student grades page'
(courses/4/grades/9#tab-assignments) does
not show totals, and the calculation of
'what-if' grades is disabled when the
'All Grading Periods' option is selected.
c) turn on the 'display totals for all
grading periods' feature. repeat steps
a & b and verify that the totals now
show up (and you can calculate what-if
grades on the student grades page when
'All Grading Periods is selected')
2) sign in as a student that is enrolled in
3 courses: 1 course with MGP disabled, 1
course with MGP enabled and 'display all
grading periods totals' (DAGPT) disabled,
and 1 course with MGP enabled and DAGPT
enabled. go the the 'grades' page (/grades).
a) verify there is a grading period dropdown
next to the totals for courses that have
MGP enabled. verify there is not a grading
period dropdown next to the total for the
course with MGP disabled.
b) verify that the current grading period is
selected by default, if one exists. if a
current grading period does not exist, then:
- the dropdown next to the total for the
course with DAGPT disabled should show
'Select a grading period' and the total
grade should show as '--'.
- the dropdown next to the total for the
course with DAGPT enabled should show
'All Grading Periods' and the total grade
should be displayed.
c) verify clicking a grading period in the
dropdown changes the total, and shows
the correct total for that grading period.
3) repeat steps 2a-c, but sign in as an observer that
is observing at least 3 students in 3 different
courses(1 course with MGP disabled, 1 with MGP
enabled and DAGPT disabled, and 1 course with
MGP enabled + DAGPT enabled).
4) verify that the grading period dropdowns that were
added are accessible.
Note: The 'grades' page (/grades) will _always_
display the total for 'All Grading Periods' when
signed in as a teacher. We are aware of this
existing bug and we're working on a solution.
Change-Id: If501b47aa57121d17d4e6629d1dcdbc8676971a2
Reviewed-on: https://gerrit.instructure.com/65847
Tested-by: Jenkins
Reviewed-by: Strand McCutchen <smccutchen@instructure.com>
Reviewed-by: Dylan Ross <dross@instructure.com>
Reviewed-by: Derek Bender <djbender@instructure.com>
QA-Review: Jason Carter <jcarter@instructure.com>
Product-Review: Spencer Olson <solson@instructure.com>
2015-10-14 03:20:03 +08:00
|
|
|
get "grades_for_student" => "users#grades_for_student"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login" => "login#new"
|
2019-05-31 00:52:34 +08:00
|
|
|
get "login/session_token" => "login#session_token", :as => :login_session_token
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
delete "logout" => "login#destroy"
|
2017-07-13 00:35:35 +08:00
|
|
|
get "logout" => "login#logout_landing"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login/canvas" => "login/canvas#new", :as => :canvas_login
|
|
|
|
post "login/canvas" => "login/canvas#create"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login/ldap" => "login/ldap#new"
|
|
|
|
post "login/ldap" => "login/ldap#create"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login/cas" => "login/cas#new"
|
|
|
|
get "login/cas/:id" => "login/cas#new", :as => :cas_login
|
|
|
|
post "login/cas" => "login/cas#destroy", :as => :cas_logout
|
|
|
|
post "login/cas/:id" => "login/cas#destroy"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2018-12-06 05:20:08 +08:00
|
|
|
get "login/saml" => "login/saml#new", :as => :saml_login_base
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login/saml/logout" => "login/saml#destroy"
|
2019-12-17 03:39:34 +08:00
|
|
|
post "login/saml/logout" => "login/saml#destroy"
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
# deprecated alias
|
|
|
|
get "saml_logout" => "login/saml#destroy"
|
|
|
|
get "login/saml/:id" => "login/saml#new", :as => :saml_login
|
2015-03-03 01:41:17 +08:00
|
|
|
get "saml_observee" => "login/saml#observee_validation", :as => :saml_observee
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
post "login/saml" => "login/saml#create"
|
2016-06-04 05:51:54 +08:00
|
|
|
# deprecated alias; no longer advertised
|
|
|
|
post "saml_consume" => "login/saml#create"
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
|
2018-12-06 05:20:08 +08:00
|
|
|
get "login/saml_idp_discovery" => "login/saml_idp_discovery#new"
|
|
|
|
get "login/saml_idp_discovery/:id" => "login/saml_idp_discovery#new", :as => :saml_idp_discovery_login
|
|
|
|
|
2015-05-15 01:43:41 +08:00
|
|
|
# the callback URL for all OAuth1.0a based SSO
|
|
|
|
get "login/oauth/callback" => "login/oauth#create", :as => :oauth_login_callback
|
2015-05-14 03:31:29 +08:00
|
|
|
# the callback URL for all OAuth2 based SSO
|
|
|
|
get "login/oauth2/callback" => "login/oauth2#create", :as => :oauth2_login_callback
|
2020-05-29 06:56:06 +08:00
|
|
|
# the callback URL for Sign in with Apple
|
|
|
|
post "login/oauth2/callback" => "login/oauth2#create"
|
2015-05-14 03:31:29 +08:00
|
|
|
# ActionController::TestCase can't deal with aliased controllers when finding
|
|
|
|
# routes, so we let this route exist only for tests
|
|
|
|
get "login/oauth2" => "login/oauth2#new" if Rails.env.test?
|
|
|
|
|
2020-05-29 06:56:06 +08:00
|
|
|
get "login/apple" => "login/apple#new", :as => :apple_login
|
2016-03-11 06:48:35 +08:00
|
|
|
get "login/clever" => "login/clever#new", :as => :clever_login
|
|
|
|
# Clever gets their own callback, cause we have to add additional processing
|
|
|
|
# for their Instant Login feature
|
|
|
|
get "login/clever/callback" => "login/clever#create", :as => :clever_callback
|
|
|
|
get "login/clever/:id" => "login/clever#new"
|
2015-05-14 03:31:29 +08:00
|
|
|
get "login/facebook" => "login/facebook#new", :as => :facebook_login
|
2015-05-14 04:52:21 +08:00
|
|
|
get "login/github" => "login/github#new", :as => :github_login
|
2015-05-19 04:06:28 +08:00
|
|
|
get "login/google" => "login/google#new", :as => :google_login
|
2015-10-13 04:08:46 +08:00
|
|
|
get "login/google/:id" => "login/google#new"
|
2015-05-15 04:13:46 +08:00
|
|
|
get "login/linkedin" => "login/linkedin#new", :as => :linkedin_login
|
2016-02-19 02:53:10 +08:00
|
|
|
get "login/microsoft" => "login/microsoft#new"
|
|
|
|
get "login/microsoft/:id" => "login/microsoft#new", :as => :microsoft_login
|
2015-05-19 04:06:28 +08:00
|
|
|
get "login/openid_connect" => "login/openid_connect#new"
|
|
|
|
get "login/openid_connect/:id" => "login/openid_connect#new", :as => :openid_connect_login
|
2015-05-15 01:43:41 +08:00
|
|
|
get "login/twitter" => "login/twitter#new", :as => :twitter_login
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
get "login/otp" => "login/otp#new", :as => :otp_login
|
|
|
|
post "login/otp/sms" => "login/otp#send_via_sms", :as => :send_otp_via_sms
|
|
|
|
post "login/otp" => "login/otp#create"
|
2013-06-20 14:20:21 +08:00
|
|
|
get "users/self/otps" => "one_time_passwords#index", :as => :one_time_passwords
|
|
|
|
delete "users/self/otps" => "one_time_passwords#destroy_all", :as => :destroy_all_one_time_passwords
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
|
|
|
|
# deprecated redirect
|
|
|
|
get "login/:id" => "login#new"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
refactor PseudonymSessionsController
fixes CNVS-20394
split it into appropriate concerns. main points are:
* /login never renders a login form - it redirects forward to the
default auth controller based on the first account
authorization config (or discovery url on the account)
* /login/canvas is the new home of the old login form. this form is
never rendered in-situ anymore - other places that used to render
it now redirect to /login (and then forward to here), reducing
their knowledge of SSO
* /login/ldap ends up at the same place (cause LDAP auth is handled
transparently)
* /login/cas and /login/saml redirect forward to the first SSO
configuration of the appropriate type. /login/:auth_type/:id can
be used to select a specific one
* if an SSO fails, it redirects back to /login with flash[:error]
set. this can forward to the discovery url appropriately, or
render an error page appropriately (the old no_auto=1, but now
it's not layered on top of the login partial that didn't show a
login form)
* ?canvas_login=1 is deprecated. just go directly to /login/canvas
* /saml_consume, /saml_logout are deprecated. they are processed
directly by /login/saml and /login/saml/logout
* /login/:id is deprecated - it forwards to /login/:auth_type/:id
as appropriate (presumably only saml, since that was the only
one that previously should have been using these links)
* OTP has been split into its own controller, and separated into
multiple actions instead of one all-in-one action
* /logout has been vastly simplified. the login controller should
set session[:login_aac], and on logout it will check with that
AAC for a url to redirect to after logout, instead of /login.
SSO logout is handled by each controller if they support it
test plan:
* regression test the following functionality -
* login with canvas auth
* login with LDAP auth
* login with SAML auth - and multiple SAMLs
* login with CAS auth
* MFA (configure, using, auto-setup)
* Canvas as OAuth Provider flow
* redirects to the login page when you're not
logged in
* failure of SAML/CAS (i.e. can't find user)
show a decent error page and allows retry
* "sticky" site admin auth (site admin is CAS/SAML,
going directly to another domain logs you in with
site admin)
Change-Id: I1bb9d81a101939f812cbd5020e20749e883fdc0f
Reviewed-on: https://gerrit.instructure.com/53220
QA-Review: August Thornton <august@instructure.com>
Tested-by: Jenkins
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Product-Review: Cody Cutrer <cody@instructure.com>
2015-05-01 03:58:57 +08:00
|
|
|
delete "users/:user_id/mfa" => "login/otp#destroy", :as => :disable_mfa
|
|
|
|
get "file_session/clear" => "login#clear_file_session", :as => :clear_file_session
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "register" => "users#new"
|
|
|
|
get "register_from_website" => "users#new"
|
|
|
|
get "enroll/:self_enrollment_code" => "self_enrollments#new", :as => :enroll
|
|
|
|
get "services" => "users#services"
|
|
|
|
get "search/bookmarks" => "users#bookmark_search", :as => :bookmark_search
|
|
|
|
get "search/rubrics" => "search#rubrics"
|
2013-09-26 03:01:06 +08:00
|
|
|
get "search/all_courses" => "search#all_courses"
|
2017-10-07 00:05:02 +08:00
|
|
|
resources :users, except: [:destroy, :index] do
|
2014-09-23 02:52:41 +08:00
|
|
|
match "masquerade", via: [:get, :post]
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :files, :file_images
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :page_views, only: :index
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :folders do
|
2014-09-23 02:52:41 +08:00
|
|
|
get :download
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
resources :calendar_events
|
2014-09-23 02:52:41 +08:00
|
|
|
get "external_tools/:id" => "users#external_tool", :as => :external_tool
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :rubrics
|
|
|
|
resources :rubric_associations do
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :rubric_assessments, path: :assessments
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :pseudonyms, except: :index
|
|
|
|
resources :question_banks, only: :index
|
|
|
|
get :admin_merge
|
2020-10-28 01:14:42 +08:00
|
|
|
get :admin_split
|
2014-09-23 02:52:41 +08:00
|
|
|
post :merge
|
|
|
|
get :grades
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :user_notes
|
2014-09-23 02:52:41 +08:00
|
|
|
get :manageable_courses
|
|
|
|
get "outcomes" => "outcomes#user_outcome_results"
|
|
|
|
get "teacher_activity/course/:course_id" => "users#teacher_activity", :as => :course_teacher_activity
|
|
|
|
get "teacher_activity/student/:student_id" => "users#teacher_activity", :as => :student_teacher_activity
|
|
|
|
get :media_download
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :messages, only: %i[index create show] do
|
2014-09-23 02:52:41 +08:00
|
|
|
get :html_message
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "show_message_template" => "messages#show_message_template"
|
|
|
|
get "message_templates" => "messages#templates"
|
|
|
|
resource :profile, controller: :profile, only: [:show, :update] do
|
|
|
|
resources :pseudonyms, except: :index
|
|
|
|
resources :tokens, except: :index
|
2013-06-15 01:09:41 +08:00
|
|
|
member do
|
|
|
|
put :update_profile
|
|
|
|
get :communication
|
|
|
|
put :communication_update
|
|
|
|
get :settings
|
2019-09-05 05:29:34 +08:00
|
|
|
get :content_shares
|
2014-07-04 04:12:17 +08:00
|
|
|
get :observees
|
2013-03-26 02:13:42 +08:00
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2020-05-15 00:33:37 +08:00
|
|
|
get "account_notifications" => "account_notifications#render_past_global_announcements"
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
scope "/profile" do
|
2014-09-23 02:52:41 +08:00
|
|
|
post "toggle_disable_inbox" => "profile#toggle_disable_inbox"
|
|
|
|
get "profile_pictures" => "profile#profile_pics", :as => :profile_pics
|
2020-04-03 07:07:04 +08:00
|
|
|
get "qr_mobile_login" => "profile#qr_mobile_login", :as => :qr_mobile_login
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "user_services/:id" => "users#delete_user_service", :as => :profile_user_service
|
|
|
|
post "user_services" => "users#create_user_service", :as => :profile_create_user_service
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
2012-05-19 00:57:21 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "about/:id" => "profile#show", :as => :user_profile
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :communication_channels
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "" => "users#user_dashboard", :as => "dashboard"
|
|
|
|
get "dashboard-sidebar" => "users#dashboard_sidebar", :as => :dashboard_sidebar
|
2017-01-12 06:41:05 +08:00
|
|
|
post "users/toggle_hide_dashcard_color_overlays" => "users#toggle_hide_dashcard_color_overlays"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "styleguide" => "info#styleguide"
|
2015-12-05 00:57:07 +08:00
|
|
|
get "accounts/:account_id/theme-preview" => "brand_configs#show"
|
2014-09-23 02:52:41 +08:00
|
|
|
root to: "users#user_dashboard", as: "root", via: :get
|
2011-03-16 03:50:08 +08:00
|
|
|
# backwards compatibility with the old /dashboard url
|
2014-09-23 02:52:41 +08:00
|
|
|
get "dashboard" => "users#user_dashboard", :as => :dashboard_redirect
|
2011-03-16 03:50:08 +08:00
|
|
|
|
2011-02-01 09:57:29 +08:00
|
|
|
# Thought this idea of having dashboard-scoped urls was a good idea at the
|
|
|
|
# time... now I'm not as big a fan.
|
2014-09-23 02:52:41 +08:00
|
|
|
resource :dashboard, only: [] do
|
|
|
|
resources :content_exports, path: :data_exports
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
scope "/dashboard" do
|
2016-08-31 06:28:25 +08:00
|
|
|
get "stream_items" => "users#dashboard_stream_items", :as => :dashboard_stream_items
|
2018-08-21 23:41:56 +08:00
|
|
|
get "dashboard_cards" => "users#dashboard_cards", :as => :dashboard_dashboard_cards
|
2017-03-17 05:27:21 +08:00
|
|
|
put "view" => "users#dashboard_view"
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "account_notifications/:id" => "users#close_notification", :as => :dashboard_close_notification
|
|
|
|
get "eportfolios" => "eportfolios#user_index", :as => :dashboard_eportfolios
|
|
|
|
post "comment_session" => "services_api#start_kaltura_session", :as => :dashboard_comment_session
|
|
|
|
delete "ignore_stream_item/:id" => "users#ignore_stream_item", :as => :dashboard_ignore_stream_item
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :plugins, only: %i[index show update]
|
2014-09-23 02:52:41 +08:00
|
|
|
|
2018-04-25 09:08:08 +08:00
|
|
|
get "calendar" => "calendars#show"
|
|
|
|
get "calendar2" => "calendars#show"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "course_sections/:course_section_id/calendar_events/:id" => "calendar_events#show", :as => :course_section_calendar_event
|
|
|
|
get "files" => "files#index"
|
2020-11-11 23:02:08 +08:00
|
|
|
get "files/folder#{full_path_glob}", controller: "files", action: "react_files", format: false, defaults: { format: "html" }
|
|
|
|
get "files/search", controller: "files", action: "react_files", format: false, defaults: { format: "html" }
|
2014-09-23 02:52:41 +08:00
|
|
|
get "files/:id/public_url" => "files#public_url", :as => :public_url
|
|
|
|
post "files/pending" => "files#create_pending", :as => :file_create_pending
|
|
|
|
resources :assignments, only: :index do
|
|
|
|
resources :files, only: [] do
|
|
|
|
post "inline_view" => "files#show", :inline => "1"
|
request scribd re-render when no preview available
test plan:
1. work in an account with scribd enabled
and google doc previews disabled
(in console, add "-google_docs_previews" to the
Accounts's allowed_services)
2. upload a scribd-previewable file type in the files tab
(it needs to be a new file that is not already in
the canvas instance)
3. make sure it previews properly (it may take a minute
after uploading for the scribd rendering to complete)
4. delete the file
5. undelete the file (/courses/X/undelete)
6. reload the files tab, and click on the filename on the
left side.
- on the right, you should see a message like
"the preview for this document is unavailable;
please try again later".
7. reload the files tab again, then click on the filename.
- if the scribd rendering has completed, you should see
a scribd preview. if you don't, wait a few minutes and
reload the files page again, to give scribd some time.
8. test other areas documents can be previewed. (it's
permissible to simply delete the scribd_doc in the console
via attachment.delete_scribd_doc, then try to preview,
see that a "try again later" message appears, and the
scribd preview appears in later page views.)
a. documents embedded in rich text via the wiki sidebar
b. student submissions, as viewed by the student
("submission details" button, "preview" icon)
c. student submissions, as viewed by the teacher
in SpeedGrader(TM)
fixes CNVS-7019
Change-Id: I37be820a776637252e14b6a28a1be389b718ff9f
Reviewed-on: https://gerrit.instructure.com/22438
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
2013-07-17 06:02:44 +08:00
|
|
|
end
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :appointment_groups, only: %i[index show edit]
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2021-11-23 01:43:13 +08:00
|
|
|
resources :errors, only: %i[show index create], path: :error_reports
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "health_check" => "info#health_check"
|
2019-04-02 03:44:49 +08:00
|
|
|
get "health_prognosis" => "info#health_prognosis"
|
2021-08-26 02:13:58 +08:00
|
|
|
get "readiness" => "info#readiness"
|
2021-09-14 22:29:29 +08:00
|
|
|
get "deep" => "info#deep"
|
|
|
|
|
2020-07-29 21:51:42 +08:00
|
|
|
get "web-app-manifest/manifest.json" => "info#web_app_manifest"
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2015-01-13 04:08:04 +08:00
|
|
|
get "browserconfig.xml", to: "info#browserconfig", defaults: { format: "xml" }
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "object_snippet" => "context#object_snippet"
|
2017-04-12 01:04:24 +08:00
|
|
|
get "saml2" => "login/saml#metadata"
|
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-05 03:20:31 +08:00
|
|
|
get "internal/services/jwks" => "security#jwks"
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
# Routes for course exports
|
2014-09-23 02:52:41 +08:00
|
|
|
get "xsd/:version.xsd" => "content_exports#xml_schema"
|
|
|
|
resources :jobs, only: [:index, :show] do
|
2013-06-15 01:09:41 +08:00
|
|
|
collection do
|
|
|
|
post "batch_update"
|
|
|
|
end
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
|
2022-02-02 09:39:14 +08:00
|
|
|
resources :jobs_v2, only: [:index]
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "equation_images/:id" => "equation_images#show", :as => :equation_images, :id => /.+/
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
# assignments at the top level (without a context) -- we have some specs that
|
2016-05-01 04:48:02 +08:00
|
|
|
# assert these routes exist, but just 404 unless it is a download from local
|
|
|
|
# storage. I'm not sure we ever actually want top-level assignments available,
|
|
|
|
# maybe we should change the specs instead.
|
|
|
|
# Note, if local storage is used, a file is fetched from this top level
|
|
|
|
# (i.e. SpeedGrader document preview with Google Docs viewer)
|
|
|
|
resources :assignments, only: [:index, :show] do
|
|
|
|
get "files/:id/download" => "files#show", :download => "1"
|
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2016-03-23 21:18:10 +08:00
|
|
|
resources :files, except: [:new] do
|
2014-09-23 02:52:41 +08:00
|
|
|
get "download" => "files#show", :download => "1"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
resources :rubrics do
|
2014-09-23 02:52:41 +08:00
|
|
|
resources :rubric_assessments, path: :assessments
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2011-12-07 00:38:32 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "selection_test" => "external_content#selection_test"
|
2011-04-30 11:25:24 +08:00
|
|
|
|
2015-10-08 05:47:14 +08:00
|
|
|
scope "/quizzes/quiz_submissions/:quiz_submission_id", as: "quiz_submission" do
|
2013-06-15 01:09:41 +08:00
|
|
|
concerns :files
|
|
|
|
end
|
2011-04-30 11:25:24 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/outcome_rollups" => "outcome_results#rollups", :as => "course_outcome_rollups"
|
2014-03-08 16:07:36 +08:00
|
|
|
|
2015-01-17 02:25:53 +08:00
|
|
|
get "terms_of_use" => "legal_information#terms_of_use", :as => "terms_of_use_redirect"
|
|
|
|
get "privacy_policy" => "legal_information#privacy_policy", :as => "privacy_policy_redirect"
|
|
|
|
|
2011-08-05 00:31:00 +08:00
|
|
|
### API routes ###
|
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
# TODO: api routes can't yet take advantage of concerns for DRYness, because of
|
|
|
|
# the way ApiRouteSet works. For now we get around it by defining methods
|
|
|
|
# inline in the routes file, but getting concerns working would rawk.
|
|
|
|
ApiRouteSet::V1.draw(self) do
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :courses) do
|
|
|
|
get "courses", action: :index, as: "courses"
|
|
|
|
put "courses/:id", action: :update
|
|
|
|
get "courses/:id", action: :show, as: "course"
|
|
|
|
delete "courses/:id", action: :destroy
|
|
|
|
post "accounts/:account_id/courses", action: :create
|
|
|
|
get "courses/:course_id/students", action: :students
|
2019-01-03 05:46:35 +08:00
|
|
|
get "courses/:course_id/settings", action: :api_settings, as: "course_settings"
|
2014-09-23 02:52:41 +08:00
|
|
|
put "courses/:course_id/settings", action: :update_settings
|
|
|
|
get "courses/:course_id/recent_students", action: :recent_students, as: "course_recent_students"
|
|
|
|
get "courses/:course_id/users", action: :users, as: "course_users"
|
2016-05-20 23:41:19 +08:00
|
|
|
get "courses/:course_id/collaborations", controller: :collaborations, action: :api_index, as: "course_collaborations_index"
|
2016-06-02 22:48:55 +08:00
|
|
|
delete "courses/:course_id/collaborations/:id", controller: :collaborations, action: :destroy
|
2020-01-28 05:39:55 +08:00
|
|
|
put "courses/:id/quizzes", action: "new_quizzes_selection_update", as: "course_new_quizzes_selection_update"
|
2021-11-23 23:11:20 +08:00
|
|
|
post "courses/:id/dismiss_migration_limitation_message", action: "dismiss_migration_limitation_msg", as: "course_dismiss_migration_limitation_msg"
|
2016-06-02 22:48:55 +08:00
|
|
|
|
2013-07-12 06:53:50 +08:00
|
|
|
# this api endpoint has been removed, it was redundant with just courses#users
|
|
|
|
# we keep it around for backward compatibility though
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/search_users", action: :users
|
|
|
|
get "courses/:course_id/users/:id", action: :user, as: "course_user"
|
2021-01-22 02:55:52 +08:00
|
|
|
get "courses/:course_id/users/:user_id/progress", action: :user_progress
|
2019-08-30 06:22:16 +08:00
|
|
|
get "courses/:course_id/content_share_users", action: :content_share_users, as: "course_content_share_users"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/activity_stream", action: :activity_stream, as: "course_activity_stream"
|
|
|
|
get "courses/:course_id/activity_stream/summary", action: :activity_stream_summary, as: "course_activity_stream_summary"
|
2021-08-06 06:31:32 +08:00
|
|
|
get "courses/:course_id/bulk_user_progress", action: :bulk_user_progress, as: "course_bulk_user_progress"
|
2017-12-06 06:16:35 +08:00
|
|
|
get "courses/:course_id/todo", action: :todo_items, as: "course_todo_list_items"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/preview_html", action: :preview_html
|
|
|
|
post "courses/:course_id/course_copy", controller: :content_imports, action: :copy_course_content
|
|
|
|
get "courses/:course_id/course_copy/:id", controller: :content_imports, action: :copy_course_status, as: :course_copy_status
|
|
|
|
get "courses/:course_id/files", controller: :files, action: :api_index, as: "course_files"
|
|
|
|
post "courses/:course_id/files", action: :create_file, as: "course_create_file"
|
2015-02-06 06:24:17 +08:00
|
|
|
get "courses/:course_id/folders", controller: :folders, action: :list_all_folders, as: "course_folders"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/folders", controller: :folders, action: :create
|
|
|
|
get "courses/:course_id/folders/by_path/*full_path", controller: :folders, action: :resolve_path
|
|
|
|
get "courses/:course_id/folders/by_path", controller: :folders, action: :resolve_path
|
2021-07-22 11:37:53 +08:00
|
|
|
get "courses/:course_id/folders/buttons_and_icons", controller: :folders, action: :buttons_and_icons_folder
|
2019-04-20 04:43:30 +08:00
|
|
|
get "courses/:course_id/folders/media", controller: :folders, action: :media_folder
|
|
|
|
get "courses/:course_id/folders/:id", controller: :folders, action: :show, as: "course_folder"
|
2019-10-02 23:07:18 +08:00
|
|
|
get "media_objects", controller: "media_objects", action: :index, as: :media_objects
|
2019-10-31 02:12:24 +08:00
|
|
|
get "courses/:course_id/media_objects", controller: "media_objects", action: :index, as: :course_media_objects
|
2020-09-16 01:26:52 +08:00
|
|
|
get "groups/:group_id/media_objects", controller: "media_objects", action: :index, as: :group_media_objects
|
2019-04-20 04:43:30 +08:00
|
|
|
put "accounts/:account_id/courses", action: :batch_update
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/ping", action: :ping, as: "course_ping"
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2015-07-10 04:33:36 +08:00
|
|
|
get "courses/:course_id/link_validation", action: :link_validation, as: "course_link_validation"
|
2014-10-16 03:10:46 +08:00
|
|
|
post "courses/:course_id/link_validation", action: :start_link_validation
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2014-12-27 02:05:00 +08:00
|
|
|
post "courses/:course_id/reset_content", action: :reset_content
|
2016-07-06 21:48:16 +08:00
|
|
|
get "users/:user_id/courses", action: :user_index, as: "user_courses"
|
2016-11-22 03:09:05 +08:00
|
|
|
get "courses/:course_id/effective_due_dates", action: :effective_due_dates, as: "course_effective_due_dates"
|
2016-12-08 07:02:36 +08:00
|
|
|
get "courses/:course_id/permissions", action: :permissions
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2020-04-02 00:55:21 +08:00
|
|
|
get "courses/:course_id/student_view_student", action: :student_view_student
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :account_notifications) do
|
|
|
|
post "accounts/:account_id/account_notifications", action: :create, as: "account_notification"
|
2016-01-13 01:47:39 +08:00
|
|
|
put "accounts/:account_id/account_notifications/:id", action: :update, as: "account_notification_update"
|
2018-02-06 02:09:11 +08:00
|
|
|
get "accounts/:account_id/account_notifications", action: :user_index, as: "user_account_notifications" # to change the api docs
|
|
|
|
get "accounts/:account_id/users/:user_id/account_notifications", action: :user_index_deprecated # for back compat
|
|
|
|
get "accounts/:account_id/account_notifications/:id", action: :show, as: "user_account_notification_show"
|
|
|
|
get "accounts/:account_id/users/:user_id/account_notifications/:id", action: :show_deprecated
|
|
|
|
delete "accounts/:account_id/account_notifications/:id", action: :user_close_notification, as: "user_account_notification"
|
|
|
|
delete "accounts/:account_id/users/:user_id/account_notifications/:id", action: :user_close_notification_deprecated
|
2014-07-10 03:16:18 +08:00
|
|
|
end
|
|
|
|
|
2016-07-08 07:12:35 +08:00
|
|
|
scope(controller: :brand_configs_api) do
|
|
|
|
get "brand_variables", action: :show
|
|
|
|
end
|
|
|
|
|
2019-07-31 23:49:04 +08:00
|
|
|
scope(controller: :accounts) do
|
|
|
|
get "terms_of_service_custom_content", action: :terms_of_service_custom_content
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :tabs) do
|
2019-07-11 01:50:54 +08:00
|
|
|
get "accounts/:account_id/tabs", action: :index, as: "account_tabs"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/tabs", action: :index, as: "course_tabs"
|
|
|
|
get "groups/:group_id/tabs", action: :index, as: "group_tabs"
|
2019-07-09 05:46:10 +08:00
|
|
|
get "users/:user_id/tabs", action: :index, as: "user_profile_tabs"
|
2014-09-23 02:52:41 +08:00
|
|
|
put "courses/:course_id/tabs/:tab_id", action: :update
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2021-10-13 03:13:30 +08:00
|
|
|
scope(controller: :gradebook_filters_api) do
|
|
|
|
get "courses/:course_id/gradebook_filters", action: :index
|
|
|
|
post "courses/:course_id/gradebook_filters", action: :create
|
|
|
|
get "courses/:course_id/gradebook_filters/:id", action: :show
|
|
|
|
put "courses/:course_id/gradebook_filters/:id", action: :update
|
|
|
|
delete "courses/:course_id/gradebook_filters/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
2018-01-26 07:03:18 +08:00
|
|
|
scope(controller: :scopes_api) do
|
|
|
|
get "accounts/:account_id/scopes", action: :index
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :sections) do
|
|
|
|
get "courses/:course_id/sections", action: :index, as: "course_sections"
|
|
|
|
get "courses/:course_id/sections/:id", action: :show, as: "course_section"
|
|
|
|
get "sections/:id", action: :show
|
|
|
|
post "courses/:course_id/sections", action: :create
|
|
|
|
put "sections/:id", action: :update
|
|
|
|
delete "sections/:id", action: :destroy
|
|
|
|
post "sections/:id/crosslist/:new_course_id", action: :crosslist
|
|
|
|
delete "sections/:id/crosslist", action: :uncrosslist
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :enrollments_api) do
|
|
|
|
get "courses/:course_id/enrollments", action: :index, as: "course_enrollments"
|
|
|
|
get "sections/:section_id/enrollments", action: :index, as: "section_enrollments"
|
|
|
|
get "users/:user_id/enrollments", action: :index, as: "user_enrollments"
|
|
|
|
get "accounts/:account_id/enrollments/:id", action: :show, as: "enrollment"
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/enrollments", action: :create
|
|
|
|
post "sections/:section_id/enrollments", action: :create
|
2017-12-05 03:18:48 +08:00
|
|
|
post "courses/:course_id/enrollments/:id/accept", action: :accept
|
|
|
|
post "courses/:course_id/enrollments/:id/reject", action: :reject
|
2013-06-15 01:09:41 +08:00
|
|
|
|
2017-12-19 01:24:35 +08:00
|
|
|
put "courses/:course_id/users/:user_id/last_attended", action: :last_attended
|
2015-11-21 00:44:25 +08:00
|
|
|
put "courses/:course_id/enrollments/:id/reactivate", action: :reactivate, as: "reactivate_enrollment"
|
|
|
|
|
2017-11-22 23:01:59 +08:00
|
|
|
delete "courses/:course_id/enrollments/:id", action: :destroy, as: "destroy_enrollment"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :terms_api) do
|
|
|
|
get "accounts/:account_id/terms", action: :index, as: "enrollment_terms"
|
2019-06-29 03:08:39 +08:00
|
|
|
get "accounts/:account_id/terms/:id", action: :show, as: "enrollment_term"
|
2013-06-20 10:28:12 +08:00
|
|
|
end
|
|
|
|
|
2014-12-31 05:01:26 +08:00
|
|
|
scope(controller: :terms) do
|
|
|
|
post "accounts/:account_id/terms", action: :create
|
|
|
|
put "accounts/:account_id/terms/:id", action: :update
|
|
|
|
delete "accounts/:account_id/terms/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :authentication_audit_api) do
|
|
|
|
get "audit/authentication/logins/:login_id", action: :for_login, as: "audit_authentication_login"
|
|
|
|
get "audit/authentication/accounts/:account_id", action: :for_account, as: "audit_authentication_account"
|
|
|
|
get "audit/authentication/users/:user_id", action: :for_user, as: "audit_authentication_user"
|
2013-06-28 06:43:15 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :grade_change_audit_api) do
|
|
|
|
get "audit/grade_change/assignments/:assignment_id", action: :for_assignment, as: "audit_grade_change_assignment"
|
|
|
|
get "audit/grade_change/courses/:course_id", action: :for_course, as: "audit_grade_change_course"
|
|
|
|
get "audit/grade_change/students/:student_id", action: :for_student, as: "audit_grade_change_student"
|
|
|
|
get "audit/grade_change/graders/:grader_id", action: :for_grader, as: "audit_grade_change_grader"
|
2017-06-03 07:24:41 +08:00
|
|
|
get "audit/grade_change/courses/:course_id/assignments/:assignment_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_assignment"
|
|
|
|
get "audit/grade_change/courses/:course_id/assignments/:assignment_id/graders/:grader_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_assignment_grader"
|
|
|
|
get "audit/grade_change/courses/:course_id/assignments/:assignment_id/graders/:grader_id/students/:student_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_assignment_grader_student"
|
|
|
|
get "audit/grade_change/courses/:course_id/assignments/:assignment_id/students/:student_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_assignment_student"
|
|
|
|
get "audit/grade_change/courses/:course_id/graders/:grader_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_grader"
|
|
|
|
get "audit/grade_change/courses/:course_id/graders/:grader_id/students/:student_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_grader_student"
|
|
|
|
get "audit/grade_change/courses/:course_id/students/:student_id",
|
|
|
|
action: :for_course_and_other_parameters, as: "audit_grade_change_course_student"
|
2020-09-23 22:03:12 +08:00
|
|
|
get "audit/grade_change", action: :query, as: "audit_grade_change"
|
2013-11-05 02:56:25 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :course_audit_api) do
|
|
|
|
get "audit/course/courses/:course_id", action: :for_course, as: "audit_course_for_course"
|
2020-03-21 04:25:02 +08:00
|
|
|
get "audit/course/accounts/:account_id", action: :for_account, as: "audit_course_for_account"
|
2013-12-21 05:08:27 +08:00
|
|
|
end
|
|
|
|
|
batch operations on assignment overrides
- supports cyoe ability to make multiple overrides for a single
student
closes CYOE-279
Test plan:
Consult generated api documentation for parameters for the following requests:
1. As teacher or TA or student, retrieve multiple assignment overrides via
GET /api/v1/courses/<id>/assignments/overrides
Should respect override visibility, student visibility
2. As teacher or TA, update assignment overrides via
PUT /api/v1/courses/<id>/assignments/overrides
Should respect validity, permissions, visibility, etc.
3. As teacher or TA, create assignment overrides via
POST /api/v1/courses/<id>/assignments/overrides
Should respect validity, permissions, visibility, etc.
Change-Id: I72f3bdae87f16bb6ff49727cb7880f7728ff60a7
Reviewed-on: https://gerrit.instructure.com/88817
Tested-by: Jenkins
Reviewed-by: Christian Prescott <cprescott@instructure.com>
QA-Review: Christian Prescott <cprescott@instructure.com>
Product-Review: Michael Brewer-Davis <mbd@instructure.com>
2016-08-25 02:43:51 +08:00
|
|
|
scope(controller: :assignment_overrides) do
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/overrides", action: :index
|
|
|
|
post "courses/:course_id/assignments/:assignment_id/overrides", action: :create
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/overrides/:id", action: :show, as: "assignment_override"
|
|
|
|
put "courses/:course_id/assignments/:assignment_id/overrides/:id", action: :update
|
|
|
|
delete "courses/:course_id/assignments/:assignment_id/overrides/:id", action: :destroy
|
|
|
|
get "sections/:course_section_id/assignments/:assignment_id/override", action: :section_alias
|
|
|
|
get "groups/:group_id/assignments/:assignment_id/override", action: :group_alias
|
|
|
|
get "courses/:course_id/assignments/overrides", action: :batch_retrieve
|
|
|
|
put "courses/:course_id/assignments/overrides", action: :batch_update
|
|
|
|
post "courses/:course_id/assignments/overrides", action: :batch_create
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :assignments_api) do
|
2017-01-14 05:54:51 +08:00
|
|
|
get "courses/:course_id/assignments/gradeable_students", controller: :submissions_api, action: :multiple_gradeable_students, as: "multiple_assignments_gradeable_students"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/assignments", action: :index, as: "course_assignments"
|
2018-10-04 00:09:26 +08:00
|
|
|
get "courses/:course_id/assignment_groups/:assignment_group_id/assignments", action: :index, as: "course_assignment_group_assignments"
|
2015-11-25 00:42:41 +08:00
|
|
|
get "users/:user_id/courses/:course_id/assignments", action: :user_index, as: "user_course_assignments"
|
2020-03-16 22:23:32 +08:00
|
|
|
put "courses/:course_id/assignments/bulk_update", action: :bulk_update
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/assignments/:id", action: :show, as: "course_assignment"
|
|
|
|
post "courses/:course_id/assignments", action: :create
|
|
|
|
put "courses/:course_id/assignments/:id", action: :update
|
2017-06-06 01:01:32 +08:00
|
|
|
post "courses/:course_id/assignments/:assignment_id/duplicate", action: :duplicate
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "courses/:course_id/assignments/:id", action: :destroy, controller: :assignments
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2018-11-16 02:45:49 +08:00
|
|
|
scope(controller: "assignment_extensions") do
|
|
|
|
post "courses/:course_id/assignments/:assignment_id/extensions", action: :create, as: "course_assignment_extensions_create"
|
|
|
|
end
|
|
|
|
|
2015-06-18 00:34:45 +08:00
|
|
|
scope(controller: :peer_reviews_api) do
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/peer_reviews", action: :index
|
|
|
|
get "sections/:section_id/assignments/:assignment_id/peer_reviews", action: :index
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :index
|
|
|
|
get "sections/:section_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :index
|
|
|
|
post "courses/:course_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :create
|
|
|
|
post "sections/:section_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :create
|
|
|
|
delete "courses/:course_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :destroy
|
|
|
|
delete "sections/:section_id/assignments/:assignment_id/submissions/:submission_id/peer_reviews", action: :destroy
|
|
|
|
end
|
|
|
|
|
2015-09-15 06:27:24 +08:00
|
|
|
scope(controller: :moderation_set) do
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/moderated_students", action: :index, as: :moderated_students
|
2015-09-19 06:51:47 +08:00
|
|
|
post "courses/:course_id/assignments/:assignment_id/moderated_students", action: :create, as: :add_moderated_students
|
2015-09-15 06:27:24 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :submissions_api) do
|
2021-11-18 06:07:40 +08:00
|
|
|
[%w[course course], %w[section course_section]].each do |(context, path_prefix)|
|
2015-03-17 15:26:47 +08:00
|
|
|
post "#{context.pluralize}/:#{context}_id/submissions/update_grades", action: :bulk_update
|
2014-09-27 07:44:45 +08:00
|
|
|
put "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/read", action: :mark_submission_read, as: "#{context}_submission_mark_read"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/read", action: :mark_submission_unread, as: "#{context}_submission_mark_unread"
|
2021-09-24 08:59:32 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/document_annotations/read", action: :document_annotations_read_state, as: "#{path_prefix}_submission_document_annotations_read_state"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/document_annotations/read", action: :mark_document_annotations_read, as: "#{path_prefix}_submission_document_annotations_mark_read"
|
2021-09-25 00:40:18 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/rubric_comments/read", action: :rubric_comments_read_state, as: "#{path_prefix}_submission_rubric_comments_read_state"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/rubric_comments/read", action: :mark_rubric_comments_read, as: "#{path_prefix}_submission_rubric_comments_mark_read"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions", action: :index, as: "#{path_prefix}_assignment_submissions"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/students/submissions", controller: :submissions_api, action: :for_students, as: "#{path_prefix}_student_submissions"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id", action: :show, as: "#{path_prefix}_assignment_submission"
|
2021-10-02 03:11:53 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/anonymous_submissions/:anonymous_id", action: :show_anonymous
|
2014-09-23 02:52:41 +08:00
|
|
|
post "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions", action: :create, controller: :submissions
|
|
|
|
post "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id/files", action: :create_file
|
|
|
|
put "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/:user_id", action: :update
|
2021-10-02 03:11:53 +08:00
|
|
|
put "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/anonymous_submissions/:anonymous_id", action: :update_anonymous
|
2014-12-31 01:37:42 +08:00
|
|
|
post "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submissions/update_grades", action: :bulk_update
|
2017-06-01 05:36:37 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/assignments/:assignment_id/submission_summary", action: :submission_summary, as: "#{path_prefix}_assignment_submission_summary"
|
2012-03-21 06:08:20 +08:00
|
|
|
end
|
2015-09-12 00:38:43 +08:00
|
|
|
get "courses/:course_id/assignments/:assignment_id/gradeable_students", action: :gradeable_students, as: "course_assignment_gradeable_students"
|
2011-08-05 00:31:00 +08:00
|
|
|
end
|
|
|
|
|
2018-05-27 01:08:03 +08:00
|
|
|
scope(controller: :anonymous_provisional_grades) do
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/anonymous_provisional_grades/status",
|
|
|
|
action: :status, as: "course_assignment_anonymous_provisional_status"
|
|
|
|
end
|
2016-11-03 01:54:06 +08:00
|
|
|
|
copy to final provisional grade
test plan:
1. create a moderated assignment
2. associate a rubric with the assignment
3. add a student to the moderation set, using g/63360, or if that's
not available yet, the Rails console:
assignment.moderated_grading_selections.create! student: student
4. submit to the assignment as a student
5. grade the assignment as a TA in speedgrader, commenting and marking
the rubric in the process
6. as a teacher, view the submission using the "Get a single submission"
API endpoint, including provisional_grades, submission_comments,
and rubric_assessment
GET /api/v1/courses/{course_id}/assignments/{assignment_id}/submissions/{user_id}?include[]=provisional_grades&include[]=submission_comments&include[]=rubric_assessment
7. retrieve the provisional_grade_id from the above, to use in the next step
8. as a teacher, call the copy_to_final_grade endpoint to copy the TA's
provisional grade to the "final" provisional grade editable by
moderators
POST /api/v1/courses/{course_id}/assignments/{assignment_id}/provisional_grades/{provisional_grade_id}/copy_to_final_mark
9. as a teacher, repeat the GET from step 6 and ensure that the provisional
grade appears twice, once with the TA as the scorer_id and once with the teacher
- the teacher's entry should have final=true while the TA's is false
- the comments and rubric assessment written by the TA should be included
in the teacher's provisional grade, but still attributed to the TA's user id
closes CNVS-23300
Change-Id: Id09f828ddb4c262ef5452a62702a3a1828091486
Reviewed-on: https://gerrit.instructure.com/63563
Reviewed-by: James Williams <jamesw@instructure.com>
Tested-by: Jenkins
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Jeremy Stanley <jeremy@instructure.com>
2015-09-18 08:18:45 +08:00
|
|
|
scope(controller: :provisional_grades) do
|
2018-08-18 03:09:54 +08:00
|
|
|
put "courses/:course_id/assignments/:assignment_id/provisional_grades/bulk_select",
|
|
|
|
action: :bulk_select, as: "bulk_select_provisional_grades"
|
|
|
|
get "courses/:course_id/assignments/:assignment_id/provisional_grades/status",
|
|
|
|
action: :status, as: "course_assignment_provisional_status"
|
|
|
|
post "courses/:course_id/assignments/:assignment_id/provisional_grades/publish",
|
|
|
|
action: :publish, as: "publish_provisional_grades"
|
|
|
|
put "courses/:course_id/assignments/:assignment_id/provisional_grades/:provisional_grade_id/select",
|
|
|
|
action: :select, as: "select_provisional_grade"
|
copy to final provisional grade
test plan:
1. create a moderated assignment
2. associate a rubric with the assignment
3. add a student to the moderation set, using g/63360, or if that's
not available yet, the Rails console:
assignment.moderated_grading_selections.create! student: student
4. submit to the assignment as a student
5. grade the assignment as a TA in speedgrader, commenting and marking
the rubric in the process
6. as a teacher, view the submission using the "Get a single submission"
API endpoint, including provisional_grades, submission_comments,
and rubric_assessment
GET /api/v1/courses/{course_id}/assignments/{assignment_id}/submissions/{user_id}?include[]=provisional_grades&include[]=submission_comments&include[]=rubric_assessment
7. retrieve the provisional_grade_id from the above, to use in the next step
8. as a teacher, call the copy_to_final_grade endpoint to copy the TA's
provisional grade to the "final" provisional grade editable by
moderators
POST /api/v1/courses/{course_id}/assignments/{assignment_id}/provisional_grades/{provisional_grade_id}/copy_to_final_mark
9. as a teacher, repeat the GET from step 6 and ensure that the provisional
grade appears twice, once with the TA as the scorer_id and once with the teacher
- the teacher's entry should have final=true while the TA's is false
- the comments and rubric assessment written by the TA should be included
in the teacher's provisional grade, but still attributed to the TA's user id
closes CNVS-23300
Change-Id: Id09f828ddb4c262ef5452a62702a3a1828091486
Reviewed-on: https://gerrit.instructure.com/63563
Reviewed-by: James Williams <jamesw@instructure.com>
Tested-by: Jenkins
QA-Review: Jahnavi Yetukuri <jyetukuri@instructure.com>
Product-Review: Jeremy Stanley <jeremy@instructure.com>
2015-09-18 08:18:45 +08:00
|
|
|
end
|
|
|
|
|
2020-02-07 06:43:24 +08:00
|
|
|
scope(controller: :submission_comments_api) do
|
|
|
|
post "/courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/files", action: :create_file
|
|
|
|
put "courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/:id", action: :update
|
|
|
|
delete "courses/:course_id/assignments/:assignment_id/submissions/:user_id/comments/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
2020-04-04 08:13:51 +08:00
|
|
|
post "/courses/:course_id/assignments/:assignment_id/submissions/:user_id/annotation_notification", action: :annotation_notification, controller: :submission_comments_api
|
2013-12-03 08:04:14 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :gradebook_history_api) do
|
|
|
|
get "courses/:course_id/gradebook_history/days", action: :days, as: "gradebook_history"
|
|
|
|
get "courses/:course_id/gradebook_history/feed", action: :feed, as: "gradebook_history_feed"
|
|
|
|
get "courses/:course_id/gradebook_history/:date", action: :day_details, as: "gradebook_history_for_day"
|
|
|
|
get "courses/:course_id/gradebook_history/:date/graders/:grader_id/assignments/:assignment_id/submissions", action: :submissions, as: "gradebook_history_submissions"
|
gradebook history api
fixes #CNVS-2802
This provides a reimplementation of
the functionality in 'lib/submission_list.rb'.
That lib file has been used to produce
a grade book history page, but it loads
the entire history of the course at once,
which is untenable. This take all the same data,
and provides it through a paginated
API endpoint. Using this API, a rich front
end will be possible to create in order to replace
the current large grade book history page,
one that makes API calls to reveal data further d
own the tree as it is requested. This is an
unusual API endpoint in that it does not present
data as it is in the database, there is a series
of transformations that the submission data is
put through to arrive at a versioned history
where each node contains within itself some
contextual knowledge of the flow of the
submission progress (each version knows
what the grade of the version before it was,
and what the grade is today, for example).
TEST PLAN:
This is a new API endpoint and does not
yet get used by any front end code yet.
It can be played with by performing some
valid API queries against the following paths:
/courses/:course_id/gradebook_history/days
/courses/:course_id/gradebook_history/:date
^ date is like "2013-01-31" ^
/courses/:course_id/gradebook_history/:date/graders/:grader_id/assignments/:assignment_id/submissions
(yes, that last one is huge, but it does follow
the nested structure described by the original
grade book history page).
The user that is selected for testing needs to
have the "manage_grades"
permission on the referenced course. API
documentation is available on the controller class
app/controllers/gradebook_history_api_controller.rb
Change-Id: I18e0b4b967d6c20ad47b86e98adbc15b87276098
Reviewed-on: https://gerrit.instructure.com/17366
QA-Review: Clare Hetherington <clare@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Brian Palmer <brianp@instructure.com>
2013-02-01 08:35:16 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/assignment_groups", controller: :assignment_groups, action: :index
|
|
|
|
scope(controller: :assignment_groups_api) do
|
|
|
|
resources :assignment_groups, path: "courses/:course_id/assignment_groups", name_prefix: "course_", except: :index
|
2013-05-25 06:28:18 +08:00
|
|
|
end
|
2011-08-05 00:31:00 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :discussion_topics) do
|
|
|
|
get "courses/:course_id/discussion_topics", action: :index, as: "course_discussion_topics"
|
|
|
|
get "groups/:group_id/discussion_topics", action: :index, as: "group_discussion_topics"
|
2011-08-05 00:31:00 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :content_migrations) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course group user].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations/migrators", action: :available_migrators, as: "#{context}_content_migration_migrators_list"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations/:id", action: :show, as: "#{context}_content_migration"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations", action: :index, as: "#{context}_content_migration_list"
|
|
|
|
post "#{context.pluralize}/:#{context}_id/content_migrations", action: :create, as: "#{context}_content_migration_create"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/content_migrations/:id", action: :update, as: "#{context}_content_migration_update"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations/:id/selective_data", action: :content_list, as: "#{context}_content_migration_selective_data"
|
2014-04-23 01:55:08 +08:00
|
|
|
end
|
2013-03-14 05:23:24 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :migration_issues) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course group user].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations/:content_migration_id/migration_issues/:id", action: :show, as: "#{context}_content_migration_migration_issue"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/content_migrations/:content_migration_id/migration_issues", action: :index, as: "#{context}_content_migration_migration_issue_list"
|
|
|
|
post "#{context.pluralize}/:#{context}_id/content_migrations/:content_migration_id/migration_issues", action: :create, as: "#{context}_content_migration_migration_issue_create"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/content_migrations/:content_migration_id/migration_issues/:id", action: :update, as: "#{context}_content_migration_migration_issue_update"
|
2014-04-23 01:55:08 +08:00
|
|
|
end
|
2013-03-14 05:23:24 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :discussion_topics_api) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id", action: :show, as: "#{context}_discussion_topic"
|
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics", controller: :discussion_topics, action: :create
|
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id", controller: :discussion_topics, action: :update
|
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics/reorder", controller: :discussion_topics, action: :reorder
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id", controller: :discussion_topics, action: :destroy
|
|
|
|
|
|
|
|
get "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/view", action: :view, as: "#{context}_discussion_topic_view"
|
2017-06-20 03:27:39 +08:00
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/duplicate", action: :duplicate
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entry_list", action: :entry_list, as: "#{context}_discussion_topic_entry_list"
|
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries", action: :add_entry, as: "#{context}_discussion_add_entry"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries", action: :entries, as: "#{context}_discussion_entries"
|
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:entry_id/replies", action: :add_reply, as: "#{context}_discussion_add_reply"
|
|
|
|
get "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:entry_id/replies", action: :replies, as: "#{context}_discussion_replies"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:id", controller: :discussion_entries, action: :update, as: "#{context}_discussion_update_reply"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:id", controller: :discussion_entries, action: :destroy, as: "#{context}_discussion_delete_reply"
|
|
|
|
|
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/read", action: :mark_topic_read, as: "#{context}_discussion_topic_mark_read"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/read", action: :mark_topic_unread, as: "#{context}_discussion_topic_mark_unread"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/read_all", action: :mark_all_read, as: "#{context}_discussion_topic_mark_all_read"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/read_all", action: :mark_all_unread, as: "#{context}_discussion_topic_mark_all_unread"
|
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:entry_id/read", action: :mark_entry_read, as: "#{context}_discussion_topic_discussion_entry_mark_read"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:entry_id/read", action: :mark_entry_unread, as: "#{context}_discussion_topic_discussion_entry_mark_unread"
|
2014-10-15 18:38:00 +08:00
|
|
|
post "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/entries/:entry_id/rating",
|
|
|
|
action: :rate_entry, as: "#{context}_discussion_topic_discussion_entry_rate"
|
2014-09-23 02:52:41 +08:00
|
|
|
put "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/subscribed", action: :subscribe_topic, as: "#{context}_discussion_topic_subscribe"
|
|
|
|
delete "#{context.pluralize}/:#{context}_id/discussion_topics/:topic_id/subscribed", action: :unsubscribe_topic, as: "#{context}_discussion_topic_unsubscribe"
|
discussion topics materialized view api, refs #7567
This is a specialized, optimized view of the entire discussion,
including a nested view on all the entries and participants, and the
current user's unread entry list.
An upcoming commit will cache these views to the database, and generate
them asynchronously, rather than in-request.
test plan: No UI yet. GET /api/v1/courses/X/discussion_topics/Y/view ,
and verify the formatting of the response, including the nesting of
arbitrarily nested discussion entires (also only creatable via the api,
right now). verify that deleted entries are returned, but without a
user_id or summary and with a deleted flag.
Change-Id: Ib7332743f92cca40cc2a861973bf492b1f294a02
Reviewed-on: https://gerrit.instructure.com/9305
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
2012-03-09 03:53:58 +08:00
|
|
|
end
|
2011-11-04 05:51:29 +08:00
|
|
|
end
|
|
|
|
|
2021-05-14 05:11:05 +08:00
|
|
|
scope(controller: :discussion_topic_users) do
|
|
|
|
get "courses/:course_id/discussion_topics/:topic_id/messageable_users", action: :search, as: "course_discussion_messageable_users"
|
|
|
|
get "groups/:group_id/discussion_topics/:topic_id/messageable_users", action: :search, as: "group_discussion_messageable_users"
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :collaborations) do
|
|
|
|
get "collaborations/:id/members", action: :members, as: "collaboration_members"
|
2016-12-09 06:36:54 +08:00
|
|
|
get "courses/:course_id/potential_collaborators", action: :potential_collaborators, as: "course_potential_collaborators"
|
|
|
|
get "groups/:group_id/potential_collaborators", action: :potential_collaborators, as: "group_potential_collaborators"
|
2012-12-19 05:59:09 +08:00
|
|
|
end
|
|
|
|
|
2021-03-06 06:49:57 +08:00
|
|
|
scope(controller: "microsoft_sync/groups") do
|
2021-03-11 02:29:18 +08:00
|
|
|
post "courses/:course_id/microsoft_sync/group", action: :create
|
2021-03-06 06:49:57 +08:00
|
|
|
get "courses/:course_id/microsoft_sync/group", action: :show
|
2021-03-10 06:37:22 +08:00
|
|
|
delete "courses/:course_id/microsoft_sync/group", action: :destroy
|
2021-04-14 13:06:29 +08:00
|
|
|
post "courses/:course_id/microsoft_sync/schedule_sync", action: :sync
|
2021-03-06 06:49:57 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :external_tools) do
|
2020-09-26 03:40:03 +08:00
|
|
|
post "/accounts/:account_id/external_tools/rce_favorites/:id", action: :add_rce_favorite, as: :account_external_tools_add_rce_favorite
|
|
|
|
delete "/accounts/:account_id/external_tools/rce_favorites/:id", action: :remove_rce_favorite, as: :account_external_tools_remove_rce_favorite
|
|
|
|
|
2021-03-11 04:38:18 +08:00
|
|
|
get "/courses/:course_id/external_tools/visible_course_nav_tools", action: :visible_course_nav_tools, as: :visible_course_nav_tools
|
2021-05-25 12:28:45 +08:00
|
|
|
get "/external_tools/visible_course_nav_tools", action: :all_visible_nav_tools, as: :all_visible_nav_tools
|
2021-03-11 04:38:18 +08:00
|
|
|
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context}s/:#{context}_id/external_tools/sessionless_launch", action: :generate_sessionless_launch, as: "#{context}_external_tool_sessionless_launch"
|
|
|
|
get "#{context}s/:#{context}_id/external_tools/:external_tool_id", action: :show, as: "#{context}_external_tool_show"
|
|
|
|
get "#{context}s/:#{context}_id/external_tools", action: :index, as: "#{context}_external_tools"
|
|
|
|
post "#{context}s/:#{context}_id/external_tools", action: :create, as: "#{context}_external_tools_create"
|
2016-09-23 01:56:37 +08:00
|
|
|
post "#{context}s/:#{context}_id/create_tool_with_verification", action: :create_tool_with_verification, as: "#{context}_create_tool_with_verification"
|
2014-09-23 02:52:41 +08:00
|
|
|
put "#{context}s/:#{context}_id/external_tools/:external_tool_id", action: :update, as: "#{context}_external_tools_update"
|
|
|
|
delete "#{context}s/:#{context}_id/external_tools/:external_tool_id", action: :destroy, as: "#{context}_external_tools_delete"
|
2011-12-21 05:17:51 +08:00
|
|
|
end
|
2016-06-11 00:53:41 +08:00
|
|
|
|
|
|
|
get "groups/:group_id/external_tools", action: :index, as: "group_external_tools"
|
2014-09-20 00:12:25 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: "lti/lti_apps") do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context}s/:#{context}_id/lti_apps/launch_definitions", action: :launch_definitions, as: "#{context}_launch_definitions"
|
2014-12-12 23:50:57 +08:00
|
|
|
get "#{context}s/:#{context}_id/lti_apps", action: :index, as: "#{context}_app_definitions"
|
2014-09-20 00:12:25 +08:00
|
|
|
end
|
2011-12-21 05:17:51 +08:00
|
|
|
end
|
|
|
|
|
2014-12-10 08:11:34 +08:00
|
|
|
scope(controller: "lti/tool_proxy") do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2015-10-29 05:58:10 +08:00
|
|
|
delete "#{context}s/:#{context}_id/tool_proxies/:tool_proxy_id", action: :destroy,
|
|
|
|
as: "#{context}_delete_tool_proxy"
|
|
|
|
put "#{context}s/:#{context}_id/tool_proxies/:tool_proxy_id", action: :update,
|
|
|
|
as: "#{context}_update_tool_proxy"
|
|
|
|
|
|
|
|
delete "#{context}s/:#{context}_id/tool_proxies/:tool_proxy_id/update", action: :dismiss_update,
|
|
|
|
as: "#{context}_dismiss_update_tool_proxy"
|
|
|
|
put "#{context}s/:#{context}_id/tool_proxies/:tool_proxy_id/update", action: :accept_update,
|
|
|
|
as: "#{context}_accept_update_tool_proxy"
|
2019-08-16 05:28:38 +08:00
|
|
|
|
|
|
|
get "#{context}s/:#{context}_id/tool_proxies/:tool_proxy_id/recreate_subscriptions", action: :recreate_subscriptions,
|
|
|
|
as: "#{context}_recreate_subscriptions_tool_proxy"
|
2014-12-10 08:11:34 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :external_feeds) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context}s/:#{context}_id/external_feeds", action: :index, as: "#{context}_external_feeds"
|
|
|
|
post "#{context}s/:#{context}_id/external_feeds", action: :create, as: "#{context}_external_feeds_create"
|
|
|
|
delete "#{context}s/:#{context}_id/external_feeds/:external_feed_id", action: :destroy, as: "#{context}_external_feeds_delete"
|
2012-08-01 07:22:48 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :sis_imports_api) do
|
|
|
|
post "accounts/:account_id/sis_imports", action: :create
|
2016-12-22 04:47:12 +08:00
|
|
|
put "accounts/:account_id/sis_imports/abort_all_pending", action: :abort_all_pending
|
2018-10-15 13:16:30 +08:00
|
|
|
get "accounts/:account_id/sis_imports/importing", action: :importing
|
2014-09-23 02:52:41 +08:00
|
|
|
get "accounts/:account_id/sis_imports/:id", action: :show
|
2015-06-17 05:07:59 +08:00
|
|
|
get "accounts/:account_id/sis_imports", action: :index, as: "account_sis_imports"
|
2017-01-04 06:31:35 +08:00
|
|
|
put "accounts/:account_id/sis_imports/:id/abort", action: :abort
|
2018-05-13 09:48:34 +08:00
|
|
|
put "accounts/:account_id/sis_imports/:id/restore_states", action: :restore_states
|
2011-04-06 05:56:50 +08:00
|
|
|
end
|
2011-08-23 03:00:57 +08:00
|
|
|
|
2018-01-25 13:23:01 +08:00
|
|
|
scope(controller: :sis_import_errors_api) do
|
|
|
|
get "accounts/:account_id/sis_imports/:id/errors", action: :index, as: :sis_batch_import_errors
|
|
|
|
get "accounts/:account_id/sis_import_errors", action: :index, as: :account_sis_import_errors
|
|
|
|
end
|
|
|
|
|
2018-02-24 06:18:42 +08:00
|
|
|
scope(controller: :outcome_imports_api) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course].each do |context|
|
2021-09-28 14:33:30 +08:00
|
|
|
post "#{context}s/:#{context}_id/outcome_imports(/group/:learning_outcome_group_id)", action: :create
|
2018-02-24 06:18:42 +08:00
|
|
|
get "#{context}s/:#{context}_id/outcome_imports/:id", action: :show
|
Allow the user to import into a specific group in the UI
closes OUT-4683
flag=improved_outcomes_management
Test plan:
- create or download fixture CSV files:
- CSV file with NO parent_guid:
vendor_guid,object_type,title
new_outcome,outcome,New Outcome
https://bit.ly/32pJ6VD
- CSV file with parent_guid:
vendor_guid,object_type,title,parent_guids
new_group_from_csv,group,New Group from CSV,
new_outcome,outcome,New Outcome from CSV,new_group_from_csv
https://bit.ly/3oLLX2C
- at the default account level:
- navigate to `Outcomes`
- create a child group with title 'Child Group'
- select `Child Group` and click in the import button at the header
- import `CSV file with NO parent_guid`
- assert that, at the root group:
- there's a new outcome titled `New Outcome`
- select `Child Group` and click in the import button at the header
- import `CSV file with parent_guid`
- assert that, at the root group:
- there's a new group titled `New Group from CSV`:
- containing an outcome titled `New Outcome from CSV`
- select `Child Group` and click in the import option from the kebab
- import `CSV file with NO parent_guid`
- assert that, at `Child Group`:
- there's a new Outcome titled `New Outcome`
- select `Child Group` and click in the import option from the kebab
- import `CSV file with parent_guid`
- refresh the page (TODO, OUT-4798)
- assert that, at `Child Group`:
- there's a new group titled `New Group from CSV`:
- containing an outcome titled `New Outcome from CSV`
- create a course:
- repeat these steps at the course level
Change-Id: I568e85a636d8b84d20f12640bad52e6b19023978
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/274711
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Kyle Rosenbaum <krosenbaum@instructure.com>
QA-Review: Chrystal Langston <chrystal.langston@instructure.com>
Product-Review: Ben Friedman <ben.friedman@instructure.com>
2021-11-01 05:10:09 +08:00
|
|
|
get "#{context}s/:#{context}_id/outcome_imports/:id/created_group_ids", action: :created_group_ids
|
2018-02-24 06:18:42 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
Outcome proficiency endpoints
closes OUT-1855, OUT-2214
test plan:
- create an access token, which will be used below
to perform HTTP requests, see:
https://canvas.instructure.com/doc/api/file.oauth.html#using-access-tokens
- using a tool like Postman, set an outcome proficiency
for an account. perform a POST request at the endpoint
`http://canvas.docker/api/v1/accounts/1/outcome_proficiency`
with a `Content-Type` header value `application/json`
and body with content like:
{
"ratings": [
{
"description": "great work",
"points": 10,
"mastery": true,
"color": "00ff00"
}
]
}
- retrieve the saved proficiency by performing GET request
at the endpoint
`http://canvas.docker/api/v1/accounts/1/outcome_proficiency`.
it should match the proficiency created above.
- update the proficiency by doing another POST request, but
with multiple ratings, like:
{
"ratings": [
{
"description": "great work",
"points": 10,
"mastery": true,
"color": "00ff00"
},
{
"description": "bad work",
"points": 0,
"mastery": false,
"color": "ff0000"
}
]
}
- do a GET request to confirm the above changes were saved
- do several other POST requests with multiple ratings
that contain either multiple mastery ratings or none.
these requests should fail with a 422 status code
and an error message that contains `Only one rating can have mastery`.
Change-Id: Ib301c0394a99dbf55d7d85ceef28a95075faaec2
Reviewed-on: https://gerrit.instructure.com/150095
Reviewed-by: Frank Murphy <fmurphy@instructure.com>
Tested-by: Jenkins
Reviewed-by: Rob Orton <rob@instructure.com>
Reviewed-by: Matt Berns <mberns@instructure.com>
QA-Review: Andrew Porter <hporter-c@instructure.com>
Product-Review: Michael Brewer-Davis <mbd@instructure.com>
2018-04-14 06:16:16 +08:00
|
|
|
scope(controller: :outcome_proficiency_api) do
|
|
|
|
post "accounts/:account_id/outcome_proficiency", action: :create
|
|
|
|
get "accounts/:account_id/outcome_proficiency", action: :show
|
2020-10-07 03:16:28 +08:00
|
|
|
post "courses/:course_id/outcome_proficiency", action: :create
|
|
|
|
get "courses/:course_id/outcome_proficiency", action: :show
|
Outcome proficiency endpoints
closes OUT-1855, OUT-2214
test plan:
- create an access token, which will be used below
to perform HTTP requests, see:
https://canvas.instructure.com/doc/api/file.oauth.html#using-access-tokens
- using a tool like Postman, set an outcome proficiency
for an account. perform a POST request at the endpoint
`http://canvas.docker/api/v1/accounts/1/outcome_proficiency`
with a `Content-Type` header value `application/json`
and body with content like:
{
"ratings": [
{
"description": "great work",
"points": 10,
"mastery": true,
"color": "00ff00"
}
]
}
- retrieve the saved proficiency by performing GET request
at the endpoint
`http://canvas.docker/api/v1/accounts/1/outcome_proficiency`.
it should match the proficiency created above.
- update the proficiency by doing another POST request, but
with multiple ratings, like:
{
"ratings": [
{
"description": "great work",
"points": 10,
"mastery": true,
"color": "00ff00"
},
{
"description": "bad work",
"points": 0,
"mastery": false,
"color": "ff0000"
}
]
}
- do a GET request to confirm the above changes were saved
- do several other POST requests with multiple ratings
that contain either multiple mastery ratings or none.
these requests should fail with a 422 status code
and an error message that contains `Only one rating can have mastery`.
Change-Id: Ib301c0394a99dbf55d7d85ceef28a95075faaec2
Reviewed-on: https://gerrit.instructure.com/150095
Reviewed-by: Frank Murphy <fmurphy@instructure.com>
Tested-by: Jenkins
Reviewed-by: Rob Orton <rob@instructure.com>
Reviewed-by: Matt Berns <mberns@instructure.com>
QA-Review: Andrew Porter <hporter-c@instructure.com>
Product-Review: Michael Brewer-Davis <mbd@instructure.com>
2018-04-14 06:16:16 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :users) do
|
|
|
|
get "users/self/activity_stream", action: :activity_stream, as: "user_activity_stream"
|
|
|
|
get "users/activity_stream", action: :activity_stream # deprecated
|
|
|
|
get "users/self/activity_stream/summary", action: :activity_stream_summary, as: "user_activity_stream_summary"
|
2013-09-06 06:02:22 +08:00
|
|
|
delete "users/self/activity_stream/:id", action: "ignore_stream_item"
|
|
|
|
delete "users/self/activity_stream", action: "ignore_all_stream_items"
|
2011-09-21 06:35:17 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
put "users/:user_id/followers/self", action: :follow
|
|
|
|
delete "users/:user_id/followers/self", action: :unfollow
|
2012-05-26 05:26:17 +08:00
|
|
|
|
2017-12-06 06:16:35 +08:00
|
|
|
get "users/self/todo", action: :todo_items, as: "user_todo_list_items"
|
2017-11-28 06:43:02 +08:00
|
|
|
get "users/self/todo_item_count", action: :todo_item_count
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/self/upcoming_events", action: :upcoming_events
|
2017-06-02 03:48:57 +08:00
|
|
|
get "users/:user_id/missing_submissions", action: :missing_submissions, as: "user_missing_submissions"
|
2012-06-09 05:17:18 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "users/self/todo/:asset_string/:purpose", action: :ignore_item, as: "users_todo_ignore"
|
|
|
|
post "accounts/:account_id/users", action: :create
|
2015-09-26 05:04:19 +08:00
|
|
|
post "accounts/:account_id/self_registration", action: :create_self_registered_user
|
2019-08-31 05:37:15 +08:00
|
|
|
get "accounts/:account_id/users", action: :api_index, as: "account_users"
|
2012-01-12 23:31:51 +08:00
|
|
|
|
2015-02-27 05:25:11 +08:00
|
|
|
get "users/:id", action: :api_show
|
2014-09-23 02:52:41 +08:00
|
|
|
put "users/:id", action: :update
|
2021-01-12 21:49:00 +08:00
|
|
|
delete "users/:id", action: :destroy, as: "destroy_user"
|
2021-10-26 02:17:16 +08:00
|
|
|
delete "users/:id/sessions", action: :terminate_sessions
|
2012-07-07 03:45:00 +08:00
|
|
|
|
2021-10-26 02:17:16 +08:00
|
|
|
post "users/:user_id/files", action: :create_file
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/files", controller: :files, action: :api_index, as: "user_files"
|
2015-02-06 06:24:17 +08:00
|
|
|
get "users/:user_id/folders", controller: :folders, action: :list_all_folders, as: "user_folders"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "users/:user_id/folders", controller: :folders, action: :create
|
|
|
|
get "users/:user_id/folders/by_path/*full_path", controller: :folders, action: :resolve_path
|
|
|
|
get "users/:user_id/folders/by_path", controller: :folders, action: :resolve_path
|
|
|
|
get "users/:user_id/folders/:id", controller: :folders, action: :show, as: "user_folder"
|
2013-05-07 06:18:56 +08:00
|
|
|
|
2013-06-15 01:09:41 +08:00
|
|
|
get "users/:id/settings", controller: "users", action: "settings"
|
2014-09-23 02:52:41 +08:00
|
|
|
put "users/:id/settings", controller: "users", action: "settings", as: "user_settings"
|
2013-12-24 03:02:37 +08:00
|
|
|
|
2015-04-07 05:54:23 +08:00
|
|
|
get "users/:id/colors", controller: "users", action: "get_custom_colors"
|
|
|
|
get "users/:id/colors/:asset_string", controller: "users", action: "get_custom_color"
|
|
|
|
put "users/:id/colors/:asset_string", controller: "users", action: "set_custom_color"
|
|
|
|
|
2017-02-22 05:59:51 +08:00
|
|
|
get "users/:id/new_user_tutorial_statuses", action: "get_new_user_tutorial_statuses"
|
|
|
|
put "users/:id/new_user_tutorial_statuses/:page_name", action: "set_new_user_tutorial_status"
|
|
|
|
|
2016-10-14 00:54:57 +08:00
|
|
|
get "users/:id/dashboard_positions", controller: "users", action: "get_dashboard_positions"
|
|
|
|
put "users/:id/dashboard_positions", controller: "users", action: "set_dashboard_positions"
|
|
|
|
|
2013-12-24 03:02:37 +08:00
|
|
|
put "users/:id/merge_into/:destination_user_id", controller: "users", action: "merge_into"
|
|
|
|
put "users/:id/merge_into/accounts/:destination_account_id/users/:destination_user_id", controller: "users", action: "merge_into"
|
2020-10-28 01:14:42 +08:00
|
|
|
post "users/:id/split", controller: "users", action: "split", as: "split"
|
2014-06-04 08:16:09 +08:00
|
|
|
|
2018-06-07 06:26:47 +08:00
|
|
|
post "users/self/pandata_events_token", controller: "users", action: "pandata_events_token"
|
2018-03-20 06:23:39 +08:00
|
|
|
|
2018-12-12 00:10:15 +08:00
|
|
|
get "dashboard/dashboard_cards", controller: "users", action: "dashboard_cards", as: :dashboard_dashboard_cards
|
|
|
|
|
2019-03-28 02:11:01 +08:00
|
|
|
get "users/:id/graded_submissions", controller: "users", action: "user_graded_submissions", as: :user_submissions
|
|
|
|
|
2022-03-25 03:03:07 +08:00
|
|
|
get "users/:id/show_k5_dashboard", controller: "users", action: "show_k5_dashboard"
|
|
|
|
|
2019-05-22 03:33:13 +08:00
|
|
|
post "users/:id/clear_cache", action: :clear_cache, as: "clear_cache"
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :user_observees) do
|
2020-04-10 06:31:43 +08:00
|
|
|
get "users/:user_id/observers", action: :observers, as: "user_observers"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/observees", action: :index, as: "user_observees"
|
2014-06-04 08:16:09 +08:00
|
|
|
post "users/:user_id/observees", action: :create
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/observees/:observee_id", action: :show, as: "user_observee"
|
2020-04-10 06:31:43 +08:00
|
|
|
get "users/:user_id/observers/:observer_id", action: :show_observer, as: "user_observer"
|
2014-06-04 08:16:09 +08:00
|
|
|
put "users/:user_id/observees/:observee_id", action: :update
|
|
|
|
delete "users/:user_id/observees/:observee_id", action: :destroy
|
|
|
|
end
|
2018-05-04 04:18:23 +08:00
|
|
|
|
2021-11-25 02:03:28 +08:00
|
|
|
scope(controller: :login) do
|
Allow the user to import into a specific group in the UI
closes OUT-4683
flag=improved_outcomes_management
Test plan:
- create or download fixture CSV files:
- CSV file with NO parent_guid:
vendor_guid,object_type,title
new_outcome,outcome,New Outcome
https://bit.ly/32pJ6VD
- CSV file with parent_guid:
vendor_guid,object_type,title,parent_guids
new_group_from_csv,group,New Group from CSV,
new_outcome,outcome,New Outcome from CSV,new_group_from_csv
https://bit.ly/3oLLX2C
- at the default account level:
- navigate to `Outcomes`
- create a child group with title 'Child Group'
- select `Child Group` and click in the import button at the header
- import `CSV file with NO parent_guid`
- assert that, at the root group:
- there's a new outcome titled `New Outcome`
- select `Child Group` and click in the import button at the header
- import `CSV file with parent_guid`
- assert that, at the root group:
- there's a new group titled `New Group from CSV`:
- containing an outcome titled `New Outcome from CSV`
- select `Child Group` and click in the import option from the kebab
- import `CSV file with NO parent_guid`
- assert that, at `Child Group`:
- there's a new Outcome titled `New Outcome`
- select `Child Group` and click in the import option from the kebab
- import `CSV file with parent_guid`
- refresh the page (TODO, OUT-4798)
- assert that, at `Child Group`:
- there's a new group titled `New Group from CSV`:
- containing an outcome titled `New Outcome from CSV`
- create a course:
- repeat these steps at the course level
Change-Id: I568e85a636d8b84d20f12640bad52e6b19023978
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/274711
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Kyle Rosenbaum <krosenbaum@instructure.com>
QA-Review: Chrystal Langston <chrystal.langston@instructure.com>
Product-Review: Ben Friedman <ben.friedman@instructure.com>
2021-11-01 05:10:09 +08:00
|
|
|
get "login/session_token", action: :session_token, as: :login_session_token
|
2021-11-25 02:03:28 +08:00
|
|
|
end
|
|
|
|
|
2018-05-23 05:58:44 +08:00
|
|
|
scope(controller: :observer_alerts_api) do
|
|
|
|
get "users/:user_id/observer_alerts/unread_count", action: :alerts_count
|
|
|
|
get "users/:user_id/observer_alerts/:student_id", action: :alerts_by_student, as: "observer_alerts_by_student"
|
|
|
|
put "users/:user_id/observer_alerts/:observer_alert_id/:workflow_state", action: :update
|
|
|
|
end
|
|
|
|
|
2018-05-04 04:18:23 +08:00
|
|
|
scope(controller: :observer_alert_thresholds_api) do
|
|
|
|
get "users/:user_id/observer_alert_thresholds", action: :index
|
|
|
|
post "users/:user_id/observer_alert_thresholds", action: :create
|
|
|
|
get "users/:user_id/observer_alert_thresholds/:observer_alert_threshold_id", action: :show
|
|
|
|
put "users/:user_id/observer_alert_thresholds/:observer_alert_threshold_id", action: :update
|
|
|
|
delete "users/:user_id/observer_alert_thresholds/:observer_alert_threshold_id", action: :destroy
|
|
|
|
end
|
2018-06-06 01:53:44 +08:00
|
|
|
|
|
|
|
scope(controller: :observer_pairing_codes_api) do
|
|
|
|
post "users/:user_id/observer_pairing_codes", action: :create
|
|
|
|
end
|
2011-08-23 03:00:57 +08:00
|
|
|
end
|
2011-08-24 05:27:19 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :custom_data) do
|
2014-07-24 01:14:22 +08:00
|
|
|
glob = "(/*scope)"
|
2014-03-04 03:55:14 +08:00
|
|
|
get "users/:user_id/custom_data#{glob}", action: "get_data"
|
|
|
|
put "users/:user_id/custom_data#{glob}", action: "set_data"
|
|
|
|
delete "users/:user_id/custom_data#{glob}", action: "delete_data"
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :pseudonyms) do
|
|
|
|
get "accounts/:account_id/logins", action: :index, as: "account_pseudonyms"
|
|
|
|
get "users/:user_id/logins", action: :index, as: "user_pseudonyms"
|
|
|
|
post "accounts/:account_id/logins", action: :create
|
|
|
|
put "accounts/:account_id/logins/:id", action: :update
|
|
|
|
delete "users/:user_id/logins/:id", action: :destroy
|
2012-01-12 06:32:07 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :accounts) do
|
|
|
|
get "accounts", action: :index, as: :accounts
|
2014-09-28 01:10:48 +08:00
|
|
|
get "course_accounts", action: :course_accounts, as: :course_accounts
|
2021-04-21 00:18:23 +08:00
|
|
|
get "manageable_accounts", action: :manageable_accounts, as: :manageable_accounts
|
2014-09-23 02:52:41 +08:00
|
|
|
get "accounts/:id", action: :show, as: :account
|
|
|
|
put "accounts/:id", action: :update
|
2017-11-28 05:40:45 +08:00
|
|
|
get "accounts/:account_id/terms_of_service", action: :terms_of_service
|
2018-08-04 00:33:42 +08:00
|
|
|
get "accounts/:account_id/help_links", action: :help_links
|
2014-09-23 02:52:41 +08:00
|
|
|
get "accounts/:account_id/courses", action: :courses_api, as: "account_courses"
|
|
|
|
get "accounts/:account_id/sub_accounts", action: :sub_accounts, as: "sub_accounts"
|
|
|
|
get "accounts/:account_id/courses/:id", controller: :courses, action: :show, as: "account_course_show"
|
2018-03-30 05:00:45 +08:00
|
|
|
get "accounts/:account_id/permissions", action: :permissions
|
Show Account settings and edit MSFT Sync settings
Added an endpoint that allows you to view the specified accounts
settings, as long as you're authorized.
In addition, update the update_api action to allow updating Microsoft Teams
Sync settings, namely :microsoft_sync_enabled, :microsoft_sync_tenant,
and :microsoft_sync_login_attribute.
closes INTEROP-6631, INTEROP-6630
test-plan:
- Ensure you have an authorization token with AccountAdmin privileges or
higher.
- Using curl/Postman/Insomnia, try to enable Microsoft Sync with the
feature flag disabled. Ensure a 400 is returned.
- Enable the :microsoft_group_enrollments_syncing feature flag
- Try to enable Microsoft Sync without a tenant or login_attribute and
ensure a 400 is returned. Gotta have that info
- Try to enable Microsoft Sync with an invalid login_attribute. Choose
any random string at all. Ensure you get a 400.
- try to enable Microsoft Sync without a valid tenant/domain name, such
as "://$$$$$", or "invalidtenant-". Ensure a 400 is returned.
- Enable Microsoft Sync with a valid tenant and login_attribute. Ensure
a 200 is returned.
- Try and modify settings as an unauthenticated user. You should get
back a 401.
- To test the show settings endpoint, make sure you have some account
settings set.
- Try to access the account settings as an unauthenticated user. Make
sure you get a 401.
- Access the account settings as an authorized user (Account Admin).
Ensure that you get back a JSON object that represents all of your
current account settings.
flag = microsoft_group_enrollments_syncing
Change-Id: Ib785987621e090a80ffa63fb48be3ed63243fe56
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/261189
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Mysti Lilla <mysti@instructure.com>
Product-Review: Ryan Hawkins <ryan.hawkins@instructure.com>
Reviewed-by: Evan Battaglia <ebattaglia@instructure.com>
2021-03-20 06:45:15 +08:00
|
|
|
get "accounts/:account_id/settings", action: :show_settings
|
2021-10-02 00:56:26 +08:00
|
|
|
get "manually_created_courses_account", action: :manually_created_courses_account
|
clean up user "deletion"
fixes CNVS-1552
any time the UI/API tries to "delete" a user, it should only be trying
to remove it from some root account (the @domain_root_account if not
otherwise specified). if that root account was the last root account the
user was associated with, then the remnants of the user are fully
deleted, but only then. leave User#destroy as a short-cut to delete the
user from all their accounts at once, but should not be invoked directly
from any UI/API actions.
test-plan:
PERMISSIONS
being able to remove a user from an account entails being able to:
- DELETE http://accounts-domain/users/:user
- DELETE /accounts/:account/users/:user
both should fail or succeed together
* given
- Sally who's an admin with the :manage_user_logins
permission on one account (Account1) and a student on another
account (Account2)
- Bob who's a student on both accounts
- Alice who's an admin on Account1 with greater permissions than
Sally
* Sally should:
- see "Delete My Account" on her Account1 profile
- not see "Delete My Account" on her Account2 profile
- not see "Delete My Account" on Bob's Account1 profile
- not see "Delete My Account" on Alice's Account1 profile
- see "Delete from Account1" at /users/:sally
- see "Delete from Account1" at /users/:bob
- not see "Delete from Account2" at /users/:sally
- not see "Delete from Account2" at /users/:bob
- not see "Delete from Account1" at /users/:alice
- be able to remove herself from Account1
- be able to remove Bob from Account1
- not be able to remove herself from Account2
- not be able to remove Bob from Account2
- not be able to remove Alice from Account1
* given Sally's Account1 pseudonym has a SIS ID but her Account2
pseudonym doesn't, Sally should:
- no longer see "Delete My Account" on her Account1 profile
- no longer see "Delete from Account1" at /users/:sally
- still see "Delete from Account1" at /users/:bob
- no longer be able to remove herself from Account1
- still be able to remove Bob from Account1
EFFECTS
* as Sally, remove Bob from Account1 via
DELETE http://account1-domain/users/:bob
- Bob's pseudonyms, enrollments, etc. in Account1 should be removed
- Bob's pseudonyms, enrollments, etc. in Account2 should be untouched
* repeat using DELETE /accounts/:account1/users/:bob, with the same
expectations
Change-Id: Ib7612f95d1c7e4cca36d8486950565ec096b4ab1
Reviewed-on: https://gerrit.instructure.com/41591
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
2014-09-23 07:04:03 +08:00
|
|
|
delete "accounts/:account_id/users/:user_id", action: :remove_user
|
2020-04-14 02:19:16 +08:00
|
|
|
put "accounts/:account_id/users/:user_id/restore", action: :restore_user
|
2011-08-24 05:27:19 +08:00
|
|
|
end
|
2011-08-25 05:20:55 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :sub_accounts) do
|
|
|
|
post "accounts/:account_id/sub_accounts", action: :create
|
2017-10-05 13:51:48 +08:00
|
|
|
delete "accounts/:account_id/sub_accounts/:id", action: :destroy
|
2013-11-16 00:01:13 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :role_overrides) do
|
|
|
|
get "accounts/:account_id/roles", action: :api_index, as: "account_roles"
|
2014-09-08 20:48:45 +08:00
|
|
|
get "accounts/:account_id/roles/:id", action: :show
|
2014-09-23 02:52:41 +08:00
|
|
|
post "accounts/:account_id/roles", action: :add_role
|
2014-09-08 20:48:45 +08:00
|
|
|
post "accounts/:account_id/roles/:id/activate", action: :activate_role
|
|
|
|
put "accounts/:account_id/roles/:id", action: :update
|
|
|
|
delete "accounts/:account_id/roles/:id", action: :remove_role
|
2015-02-03 13:43:14 +08:00
|
|
|
get "accounts/:account_id/permissions/:permission", action: :check_account_permission
|
2011-12-17 05:27:59 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :account_reports) do
|
|
|
|
get "accounts/:account_id/reports/:report", action: :index
|
|
|
|
get "accounts/:account_id/reports", action: :available_reports
|
|
|
|
get "accounts/:account_id/reports/:report/:id", action: :show
|
|
|
|
post "accounts/:account_id/reports/:report", action: :create, as: "account_create_report"
|
|
|
|
delete "accounts/:account_id/reports/:report/:id", action: :destroy
|
2012-06-21 04:07:22 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :admins) do
|
|
|
|
post "accounts/:account_id/admins", action: :create
|
|
|
|
delete "accounts/:account_id/admins/:user_id", action: :destroy
|
|
|
|
get "accounts/:account_id/admins", action: :index, as: "account_admins"
|
2011-12-13 05:19:43 +08:00
|
|
|
end
|
|
|
|
|
2018-04-25 05:49:30 +08:00
|
|
|
scope(controller: :authentication_providers) do
|
2015-07-17 04:54:13 +08:00
|
|
|
get "accounts/:account_id/sso_settings", action: :show_sso_settings, as: "account_show_sso_settings_url"
|
|
|
|
put "accounts/:account_id/sso_settings", action: :update_sso_settings, as: "account_update_sso_settings_url"
|
|
|
|
|
|
|
|
get "accounts/:account_id/authentication_providers", action: :index
|
|
|
|
get "accounts/:account_id/authentication_providers/:id", action: :show
|
|
|
|
post "accounts/:account_id/authentication_providers", action: :create, as: "account_create_ap"
|
|
|
|
put "accounts/:account_id/authentication_providers/:id", action: :update, as: "account_update_ap"
|
|
|
|
delete "accounts/:account_id/authentication_providers/:id", action: :destroy, as: "account_delete_ap"
|
2011-12-13 03:48:36 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/page_views", controller: :page_views, action: :index, as: "user_page_views"
|
|
|
|
get "users/:user_id/profile", controller: :profile, action: :settings
|
|
|
|
get "users/:user_id/avatars", controller: :profile, action: :profile_pics
|
2011-09-02 23:34:12 +08:00
|
|
|
|
2012-08-14 03:50:18 +08:00
|
|
|
# deprecated routes, second one is solely for YARD. preferred API is api/v1/search/recipients
|
2014-09-23 02:52:41 +08:00
|
|
|
get "conversations/find_recipients", controller: :search, action: :recipients
|
|
|
|
get "conversations/find_recipients", controller: :conversations, action: :find_recipients
|
|
|
|
|
|
|
|
scope(controller: :conversations) do
|
|
|
|
get "conversations", action: :index, as: "conversations"
|
|
|
|
post "conversations", action: :create
|
2016-08-02 22:55:27 +08:00
|
|
|
get "conversations/deleted", action: :deleted_index, as: "deleted_conversations"
|
2016-08-06 02:13:06 +08:00
|
|
|
put "conversations/restore", action: :restore_message
|
2014-09-23 02:52:41 +08:00
|
|
|
post "conversations/mark_all_as_read", action: :mark_all_as_read
|
|
|
|
get "conversations/batches", action: :batches, as: "conversations_batches"
|
|
|
|
get "conversations/unread_count", action: :unread_count
|
|
|
|
get "conversations/:id", action: :show
|
|
|
|
put "conversations/:id", action: :update # stars, subscribed-ness, workflow_state
|
|
|
|
delete "conversations/:id", action: :destroy
|
|
|
|
post "conversations/:id/add_message", action: :add_message
|
|
|
|
post "conversations/:id/add_recipients", action: :add_recipients
|
|
|
|
post "conversations/:id/remove_messages", action: :remove_messages
|
|
|
|
put "conversations", action: :batch_update
|
|
|
|
delete "conversations/:id/delete_for_all", action: :delete_for_all
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :communication_channels) do
|
|
|
|
get "users/:user_id/communication_channels", action: :index, as: "communication_channels"
|
|
|
|
post "users/:user_id/communication_channels", action: :create
|
2015-10-07 12:27:50 +08:00
|
|
|
post "users/:user_id/communication_channels/:id", action: :reset_bounce_count, as: "reset_bounce_count"
|
2020-10-31 04:44:52 +08:00
|
|
|
get "accounts/:account_id/bounced_communication_channels.csv", action: :bouncing_channel_report, defaults: { format: :csv }
|
|
|
|
get "accounts/:account_id/bounced_communication_channels", action: :bouncing_channel_report
|
2017-09-13 00:13:41 +08:00
|
|
|
post "accounts/:account_id/bounced_communication_channels/reset", action: :bulk_reset_bounce_counts
|
2020-10-31 04:44:52 +08:00
|
|
|
get "accounts/:account_id/unconfirmed_communication_channels.csv", action: :unconfirmed_channel_report, defaults: { format: :csv }
|
|
|
|
get "accounts/:account_id/unconfirmed_communication_channels", action: :unconfirmed_channel_report
|
2016-03-19 06:41:46 +08:00
|
|
|
post "accounts/:account_id/unconfirmed_communication_channels/confirm", action: :bulk_confirm
|
2018-03-16 03:23:13 +08:00
|
|
|
delete "users/self/communication_channels/push", action: :delete_push_token
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "users/:user_id/communication_channels/:id", action: :destroy
|
|
|
|
delete "users/:user_id/communication_channels/:type/:address", action: :destroy, constraints: { address: %r{[^/?]+} }
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :notification_preferences) do
|
2013-11-15 02:22:07 +08:00
|
|
|
get "users/:user_id/communication_channels/:communication_channel_id/notification_preferences", action: :index
|
2015-07-08 00:23:39 +08:00
|
|
|
get "users/:user_id/communication_channels/:communication_channel_id/notification_preference_categories", action: :category_index
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/communication_channels/:type/:address/notification_preferences", action: :index, constraints: { address: %r{[^/?]+} }
|
2013-11-15 02:22:07 +08:00
|
|
|
get "users/:user_id/communication_channels/:communication_channel_id/notification_preferences/:notification", action: :show
|
2014-09-23 02:52:41 +08:00
|
|
|
get "users/:user_id/communication_channels/:type/:address/notification_preferences/:notification", action: :show, constraints: { address: %r{[^/?]+} }
|
2013-11-15 02:22:07 +08:00
|
|
|
put "users/self/communication_channels/:communication_channel_id/notification_preferences/:notification", action: :update
|
2014-09-23 02:52:41 +08:00
|
|
|
put "users/self/communication_channels/:type/:address/notification_preferences/:notification", action: :update, constraints: { address: %r{[^/?]+} }
|
2013-11-15 02:22:07 +08:00
|
|
|
put "users/self/communication_channels/:communication_channel_id/notification_preferences", action: :update_all
|
2014-09-23 02:52:41 +08:00
|
|
|
put "users/self/communication_channels/:type/:address/notification_preferences", action: :update_all, constraints: { address: %r{[^/?]+} }
|
2015-07-08 00:23:39 +08:00
|
|
|
put "users/self/communication_channels/:communication_channel_id/notification_preference_categories/:category", action: :update_preferences_by_category
|
2014-09-23 02:52:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :comm_messages_api) do
|
|
|
|
get "comm_messages", action: :index, as: "comm_messages"
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :services_api) do
|
|
|
|
get "services/kaltura", action: :show_kaltura_config
|
|
|
|
post "services/kaltura_session", action: :start_kaltura_session
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :calendar_events_api) do
|
|
|
|
get "calendar_events", action: :index, as: "calendar_events"
|
2015-10-31 04:20:11 +08:00
|
|
|
get "users/:user_id/calendar_events", action: :user_index, as: "user_calendar_events"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "calendar_events", action: :create
|
2016-04-22 13:28:04 +08:00
|
|
|
get "calendar_events/visible_contexts", action: :visible_contexts
|
2014-09-23 02:52:41 +08:00
|
|
|
get "calendar_events/:id", action: :show, as: "calendar_event"
|
|
|
|
put "calendar_events/:id", action: :update
|
|
|
|
delete "calendar_events/:id", action: :destroy
|
|
|
|
post "calendar_events/:id/reservations", action: :reserve
|
|
|
|
post "calendar_events/:id/reservations/:participant_id", action: :reserve, as: "calendar_event_reserve"
|
2017-04-29 08:45:15 +08:00
|
|
|
get "calendar_events/:id/participants", action: :participants, as: "calendar_event_participants"
|
2016-04-22 11:18:35 +08:00
|
|
|
post "calendar_events/save_selected_contexts", action: :save_selected_contexts
|
2021-11-25 09:29:26 +08:00
|
|
|
|
2016-07-25 23:34:36 +08:00
|
|
|
get "courses/:course_id/calendar_events/timetable", action: :get_course_timetable
|
|
|
|
post "courses/:course_id/calendar_events/timetable", action: :set_course_timetable
|
|
|
|
post "courses/:course_id/calendar_events/timetable_events", action: :set_course_timetable_events
|
2014-09-23 02:52:41 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :appointment_groups) do
|
|
|
|
get "appointment_groups", action: :index, as: "appointment_groups"
|
|
|
|
post "appointment_groups", action: :create
|
2016-10-13 01:50:07 +08:00
|
|
|
get "appointment_groups/next_appointment", action: :next_appointment
|
2014-09-23 02:52:41 +08:00
|
|
|
get "appointment_groups/:id", action: :show, as: "appointment_group"
|
|
|
|
put "appointment_groups/:id", action: :update
|
|
|
|
delete "appointment_groups/:id", action: :destroy
|
|
|
|
get "appointment_groups/:id/users", action: :users, as: "appointment_group_users"
|
|
|
|
get "appointment_groups/:id/groups", action: :groups, as: "appointment_group_groups"
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: :groups) do
|
|
|
|
resources :groups, except: :index
|
|
|
|
get "users/self/groups", action: :index, as: "current_user_groups"
|
|
|
|
get "accounts/:account_id/groups", action: :context_index, as: "account_user_groups"
|
|
|
|
get "courses/:course_id/groups", action: :context_index, as: "course_user_groups"
|
|
|
|
get "groups/:group_id/users", action: :users, as: "group_users"
|
2018-09-05 04:54:22 +08:00
|
|
|
get "groups/:group_id/permissions", action: :permissions
|
2014-09-23 02:52:41 +08:00
|
|
|
post "groups/:group_id/invite", action: :invite
|
|
|
|
post "groups/:group_id/files", action: :create_file
|
|
|
|
post "groups/:group_id/preview_html", action: :preview_html
|
|
|
|
post "group_categories/:group_category_id/groups", action: :create
|
|
|
|
get "groups/:group_id/activity_stream", action: :activity_stream, as: "group_activity_stream"
|
|
|
|
get "groups/:group_id/activity_stream/summary", action: :activity_stream_summary, as: "group_activity_stream_summary"
|
|
|
|
put "groups/:group_id/followers/self", action: :follow
|
|
|
|
delete "groups/:group_id/followers/self", action: :unfollow
|
2016-05-20 23:41:19 +08:00
|
|
|
get "groups/:group_id/collaborations", controller: :collaborations, action: :api_index, as: "group_collaborations_index"
|
2016-06-02 22:48:55 +08:00
|
|
|
delete "groups/:group_id/collaborations/:id", controller: :collaborations, action: :destroy
|
2014-09-23 02:52:41 +08:00
|
|
|
|
|
|
|
scope(controller: :group_memberships) do
|
2015-04-25 04:49:43 +08:00
|
|
|
resources :memberships, path: "groups/:group_id/memberships", name_prefix: "group_", controller: :group_memberships
|
|
|
|
resources :users, path: "groups/:group_id/users", name_prefix: "group_", controller: :group_memberships, except: [:index, :create]
|
2012-06-02 03:18:32 +08:00
|
|
|
end
|
2012-07-07 03:45:00 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "groups/:group_id/files", controller: :files, action: :api_index, as: "group_files"
|
2015-02-06 06:24:17 +08:00
|
|
|
get "groups/:group_id/folders", controller: :folders, action: :list_all_folders, as: "group_folders"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "groups/:group_id/folders", controller: :folders, action: :create
|
|
|
|
get "groups/:group_id/folders/by_path/*full_path", controller: :folders, action: :resolve_path
|
|
|
|
get "groups/:group_id/folders/by_path", controller: :folders, action: :resolve_path
|
2019-04-20 04:43:30 +08:00
|
|
|
get "groups/:group_id/folders/media", controller: :folders, action: :media_folder
|
2014-09-23 02:52:41 +08:00
|
|
|
get "groups/:group_id/folders/:id", controller: :folders, action: :show, as: "group_folder"
|
2012-01-04 04:30:49 +08:00
|
|
|
end
|
2012-03-21 06:08:20 +08:00
|
|
|
|
2018-03-17 04:59:43 +08:00
|
|
|
scope(controller: :developer_key_account_bindings) do
|
2018-03-20 01:09:59 +08:00
|
|
|
post "accounts/:account_id/developer_keys/:developer_key_id/developer_key_account_bindings", action: :create_or_update
|
2018-03-17 04:59:43 +08:00
|
|
|
get "accounts/:account_id/developer_key_account_bindings", action: :index
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :developer_keys) do
|
|
|
|
delete "developer_keys/:id", action: :destroy
|
|
|
|
put "developer_keys/:id", action: :update
|
2015-08-22 04:48:05 +08:00
|
|
|
|
2016-07-02 05:46:12 +08:00
|
|
|
get "accounts/:account_id/developer_keys", action: :index, as: "account_developer_keys"
|
2015-08-22 04:48:05 +08:00
|
|
|
post "accounts/:account_id/developer_keys", action: :create
|
2012-05-17 13:52:32 +08:00
|
|
|
end
|
2012-05-05 04:16:03 +08:00
|
|
|
|
2019-04-27 00:29:55 +08:00
|
|
|
scope(controller: :internet_image) do
|
|
|
|
get "image_search", action: :image_search
|
2019-05-15 04:55:45 +08:00
|
|
|
post "image_selection/:id", action: :image_selection
|
2019-04-27 00:29:55 +08:00
|
|
|
end
|
|
|
|
|
2019-09-18 03:37:58 +08:00
|
|
|
scope(controller: :immersive_reader) do
|
|
|
|
get "immersive_reader/authenticate", action: :authenticate
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :search) do
|
|
|
|
get "search/rubrics", action: "rubrics", as: "search_rubrics"
|
|
|
|
get "search/recipients", action: "recipients", as: "search_recipients"
|
2013-09-26 03:01:06 +08:00
|
|
|
get "search/all_courses", action: "all_courses", as: "search_all_courses"
|
2012-04-16 23:27:28 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
post "files/:id/create_success", controller: :files, action: :api_create_success, as: "files_create_success"
|
|
|
|
get "files/:id/create_success", controller: :files, action: :api_create_success
|
2012-07-04 03:35:43 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :files) do
|
|
|
|
post "files/:id/create_success", action: :api_create_success
|
|
|
|
get "files/:id/create_success", action: :api_create_success
|
2016-04-22 01:14:44 +08:00
|
|
|
match "/api/v1/files/:id/create_success", via: [:options], action: :api_create_success_cors
|
inst-fs upload preflight (and capture fixes)
fixes CNVS-38591
when the inst-fs service is enabled, generate a preflight response
tailored for inst-fs instead of for S3. the service will then receive
the POSTed file data, generate it, and ping Canvas at the embedded
capture URL. compatible with existing Canvas UI.
along the way, some cleanup refactoring in api_attachment_preflight:
* instead of taking submission_context and inferring a folder from
that, have the submission API be responsible for determining the
folder and then just specify it. note that the folder inference was
the only use of submission_context, the submission API was the only
caller of api_preflight_json to specify submission_context, and the
folder option we took over was previously both broken and unused.
* simplify the remaining folder inference code. if a folder is
specified by the code (vs. the user in params), assume they have
necessary access (the :manage_contents permission would fail for a
student making a submission)
* correctly abort if params[:on_duplicate] is invalid. before, if the
UI provided an explicit but invalid value, it would cause a double
render error.
* inline process_attachment_params for update, and skip it on
preflight. the UI never provides any of the possible params but
display_name for preflight, which is then ignored from the
process_attachment_params result because it's treated separately
TODO: tests
* InstFS.upload_preflight_json
* api_attachment_preflight:
- uploading a file to a submission (submissions_api#create_file) when the
submissions_folder feature is enabled stores the file in the user's
submissions folder
- student uploading a file to a submission is not blocked by permissions
- user with :manage_contents permission on a folder is not blocked when
uploading to that folder
- user without :manage_contents permission on a folder is blocked when
attempting to upload to that folder
- no double render error on on_duplicate=invalid
- updates to lock_at, etc., on a file (via files#api_update) stick
* files#api_capture:
- reject if over quota and not flagged quota_exempt
- attachment.locked based on usage rights settings
- attachment.handle_duplicates
- content migration success callback triggered
* InstFS.authenticated_url:
- includes iat claim
- expiration is a timestamp
test-plan:
inst-fs upload happy path:
- have inst-fs service running, have canvas configured to be able to
find and share a secret with it, and enable the inst-fs plugin setting
- go to the files area, or a discussion, or a conversation, etc., and
upload a file.
- the file should be successfully uploaded
- NOTE: known issue, there seems to be a race condition in the service
responding 201 Created with a Location before Canvas is ready to
respond to that Location. This will make the upload appear to fail.
But if you refresh the page, the file should be present. This race
condition will be fixed in a later commit; it has already been filed
as a separate bug.
- attempt to download/preview the file
- download/preview should work, and should be served from inst-fs
quota enforcement:
- configure a course to have a quota
- select a file that should exceed that quota when uploaded
- bypassing the canvas UI, access the preflight endpoint directly
while providing the true size; preflight should fail
- access the preflight endpoint directly while providing a false size
that would fit inside the quota; preflight should succeed
- attempt to POST the file to the returned upload_url with the
returned upload_params; the upload should fail
locking pending usage rights:
- configure the account to lock files without usage rights
- upload a file
- the newly created file should be locked
- assign usage rights to the new file
- it should unlock
path collisions:
- upload a file to a folder
- upload a distinct file but with the same filename to the same folder
- should be prompted to rename or overwrite
- select rename; the newly uploaded file should have the filename
modified to avoid the collision
- repeat, but selecting overwrite; the filename should now refer to
the new file, and the old file should not be accessible in the UI
non-inst-fs unharmed:
- disable the inst-fs plugin setting
- do general regression tests on file uploads (whether S3 or local
storage)
Change-Id: I2bff1e3c31a3ed0955c29e677a422b7149253318
Reviewed-on: https://gerrit.instructure.com/124929
Tested-by: Jenkins
Reviewed-by: Andrew Huff <ahuff@instructure.com>
QA-Review: Collin Parrish <cparrish@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
2017-09-06 02:53:02 +08:00
|
|
|
post "files/capture", action: :api_capture, as: "files_capture"
|
2016-04-22 01:14:44 +08:00
|
|
|
|
modules api, closes #10404
also modifies the discussion topic and assignment API
controllers to make sure "must_view" requirements are
fulfilled
test plan:
* check the API documentation; ensure it looks okay
* create a course with module items of each supported type
* set completion criteria of each supported type
* create another module, so you can set prerequisites
* use the list modules API and verify its output matches
the course and the documentation
* as a teacher, "state" should be missing
* as a student, "state" should be "locked", "unlocked",
"started", or "completed"
* use the show module API and verify the correct information
is returned for a single module
* use the list module items API and verify the output
* as a teacher, the "completion_requirement" omits the
"completed" flag
* as a student, "completed" should be true or false,
depending on whether the requirement was met
* use the show module API and verify the correct information
is returned for a single module item
* last but not least, verify "must view" requirements can
be fulfilled through the api_data_endpoints supplied
for files, pages, discussions, and assignments
* files are viewed when downloading their content
* pages are viewed by the show action (where content
is returned)
* discussions are viewed when marked read via the
mark_topic_read or mark_all_read actions
* assignments are viewed by the show action
(where description is returned). they are not viewed
if the assignment is locked and the user does not
have access to the content yet.
Change-Id: I0cbbbc542f69215e7b396a501d4d86ff2f76c149
Reviewed-on: https://gerrit.instructure.com/13626
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Simon Williams <simon@instructure.com>
2012-09-12 01:16:48 +08:00
|
|
|
# 'attachment' (rather than 'file') is used below so modules API can use polymorphic_url to generate an item API link
|
2014-09-23 02:52:41 +08:00
|
|
|
get "files/:id", action: :api_show, as: "attachment"
|
|
|
|
delete "files/:id", action: :destroy
|
|
|
|
put "files/:id", action: :api_update
|
2020-01-21 23:56:54 +08:00
|
|
|
post "files/:id/reset_verifier", action: :reset_verifier
|
2018-09-15 00:54:29 +08:00
|
|
|
|
|
|
|
# exists as an alias of GET for backwards compatibility
|
|
|
|
#
|
|
|
|
# older API clients were told to POST to the value of the Location header
|
|
|
|
# returned after upload to S3, when that was the create_success URL.
|
|
|
|
# that's no longer necessary, but they are still given a Location header
|
|
|
|
# pointed at this endpoint which they can GET for the file details (which
|
2019-05-14 03:12:37 +08:00
|
|
|
# create_success would have provided).
|
|
|
|
#
|
|
|
|
# such behavior is now undocumented, and subject to removal once open
|
|
|
|
# sourcing of inst-fs is complete.
|
2018-09-15 00:54:29 +08:00
|
|
|
#
|
|
|
|
# to actually change the file metadata (e.g. rename), the PUT route above
|
|
|
|
# must be used.
|
|
|
|
post "files/:id", action: :api_show
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "files/:id/:uuid/status", action: :api_file_status, as: "file_status"
|
|
|
|
get "files/:id/public_url", action: :public_url
|
2022-03-08 04:35:01 +08:00
|
|
|
get "courses/:course_id/files/file_ref/:migration_id", action: :file_ref
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group user].each do |context|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{context}s/:#{context}_id/files/quota", action: :api_quota
|
2015-04-01 03:17:17 +08:00
|
|
|
get "#{context}s/:#{context}_id/files/:id", action: :api_show, as: "#{context}_attachment"
|
2014-03-07 07:54:34 +08:00
|
|
|
end
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :folders) do
|
|
|
|
get "folders/:id", action: :show
|
|
|
|
get "folders/:id/folders", action: :api_index, as: "list_folders"
|
|
|
|
get "folders/:id/files", controller: :files, action: :api_index, as: "list_files"
|
|
|
|
delete "folders/:id", action: :api_destroy
|
|
|
|
put "folders/:id", action: :update
|
|
|
|
post "folders/:folder_id/folders", action: :create, as: "create_folder"
|
|
|
|
post "folders/:folder_id/files", action: :create_file
|
2015-02-04 07:13:09 +08:00
|
|
|
post "folders/:dest_folder_id/copy_file", action: :copy_file
|
|
|
|
post "folders/:dest_folder_id/copy_folder", action: :copy_folder
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
2014-09-23 02:52:41 +08:00
|
|
|
|
|
|
|
scope(controller: :favorites) do
|
|
|
|
get "users/self/favorites/courses", action: :list_favorite_courses, as: :list_favorite_courses
|
|
|
|
post "users/self/favorites/courses/:id", action: :add_favorite_course, as: :add_favorite_course
|
|
|
|
delete "users/self/favorites/courses/:id", action: :remove_favorite_course, as: :remove_favorite_course
|
|
|
|
delete "users/self/favorites/courses", action: :reset_course_favorites
|
2015-09-02 03:55:42 +08:00
|
|
|
get "users/self/favorites/groups", action: :list_favorite_groups, as: :list_favorite_groups
|
2016-08-17 03:43:47 +08:00
|
|
|
post "users/self/favorites/groups/:id", action: :add_favorite_groups, as: :add_favorite_groups
|
|
|
|
delete "users/self/favorites/groups/:id", action: :remove_favorite_groups, as: :remove_favorite_groups
|
|
|
|
delete "users/self/favorites/groups", action: :reset_groups_favorites
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :wiki_pages_api) do
|
|
|
|
get "courses/:course_id/front_page", action: :show_front_page
|
|
|
|
get "groups/:group_id/front_page", action: :show_front_page
|
|
|
|
put "courses/:course_id/front_page", action: :update_front_page
|
|
|
|
put "groups/:group_id/front_page", action: :update_front_page
|
Add the ability to duplicate pages.
* Closes FALCOR-139
* Closes FALCOR-140
* Closes FALCOR-141
Test Plan:
* Create a course, and make a wiki page.
* If "Duplicate Enabled" feature option is set, then a duplicate
option should occur on the cog next to the page you created.
* When this is clicked, a new page should pop up below unpublished,
with focus on the cog of the new page.
* (If you make a page that is an assignment, the new page will also
show up on the assignments list)
* A student should not be able to see this option, and if the
feature flag is off, this option also should not appear.
* A wiki page assignment can now also be duplicated from the
"Assignments" list as well.
* Discussion and Quizzes still cannot be duplicated from the
"Assignments" list
* Title convention: If title does not end in "Copy" or "Copy #"
will append "Copy" to the end of the title.
* After doing the above, finds the lowest number that doesn't
duplicate an existing assignment or wiki page name (if a number
is needed to effect this)
* In the above search, if a "#" is present on the title, *always*
starts from the # given. So "Copy 7" will go to "Copy 8" even
if 1-6 are not used.
Change-Id: Ib595a859b9186f934626b56e94a00eea231baa5a
Reviewed-on: https://gerrit.instructure.com/115934
Tested-by: Jenkins
Reviewed-by: Steven Burnett <sburnett@instructure.com>
Reviewed-by: Dan Minkevitch <dan@instructure.com>
QA-Review: Deepeeca Soundarrajan <dsoundarrajan@instructure.com>
Product-Review: Mary Jane Anderson <manderson@instructure.com>
2017-06-14 01:25:49 +08:00
|
|
|
post "courses/:course_id/pages/:url/duplicate", action: :duplicate
|
2013-08-22 23:43:03 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/pages", action: :index, as: "course_wiki_pages"
|
|
|
|
get "groups/:group_id/pages", action: :index, as: "group_wiki_pages"
|
|
|
|
get "courses/:course_id/pages/:url", action: :show, as: "course_wiki_page"
|
|
|
|
get "groups/:group_id/pages/:url", action: :show, as: "group_wiki_page"
|
|
|
|
get "courses/:course_id/pages/:url/revisions", action: :revisions, as: "course_wiki_page_revisions"
|
|
|
|
get "groups/:group_id/pages/:url/revisions", action: :revisions, as: "group_wiki_page_revisions"
|
|
|
|
get "courses/:course_id/pages/:url/revisions/latest", action: :show_revision
|
|
|
|
get "groups/:group_id/pages/:url/revisions/latest", action: :show_revision
|
|
|
|
get "courses/:course_id/pages/:url/revisions/:revision_id", action: :show_revision
|
|
|
|
get "groups/:group_id/pages/:url/revisions/:revision_id", action: :show_revision
|
|
|
|
post "courses/:course_id/pages/:url/revisions/:revision_id", action: :revert
|
|
|
|
post "groups/:group_id/pages/:url/revisions/:revision_id", action: :revert
|
|
|
|
post "courses/:course_id/pages", action: :create
|
|
|
|
post "groups/:group_id/pages", action: :create
|
|
|
|
put "courses/:course_id/pages/:url", action: :update
|
|
|
|
put "groups/:group_id/pages/:url", action: :update
|
|
|
|
delete "courses/:course_id/pages/:url", action: :destroy
|
|
|
|
delete "groups/:group_id/pages/:url", action: :destroy
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :context_modules_api) do
|
|
|
|
get "courses/:course_id/modules", action: :index, as: "course_context_modules"
|
|
|
|
get "courses/:course_id/modules/:id", action: :show, as: "course_context_module"
|
|
|
|
put "courses/:course_id/modules", action: :batch_update
|
2017-10-09 23:04:57 +08:00
|
|
|
post "courses/:course_id/modules/:module_id/duplicate", action: :duplicate
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/modules", action: :create, as: "course_context_module_create"
|
|
|
|
put "courses/:course_id/modules/:id", action: :update, as: "course_context_module_update"
|
|
|
|
delete "courses/:course_id/modules/:id", action: :destroy
|
2015-02-18 22:22:43 +08:00
|
|
|
put "courses/:course_id/modules/:id/relock", action: :relock
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :context_module_items_api) do
|
|
|
|
get "courses/:course_id/modules/:module_id/items", action: :index, as: "course_context_module_items"
|
|
|
|
get "courses/:course_id/modules/:module_id/items/:id", action: :show, as: "course_context_module_item"
|
2015-04-24 16:13:20 +08:00
|
|
|
put "courses/:course_id/modules/:module_id/items/:id/done", action: :mark_as_done, as: "course_context_module_item_done"
|
|
|
|
delete "courses/:course_id/modules/:module_id/items/:id/done", action: :mark_as_not_done, as: "course_context_module_item_not_done"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/module_item_redirect/:id", action: :redirect, as: "course_context_module_item_redirect"
|
|
|
|
get "courses/:course_id/module_item_sequence", action: :item_sequence
|
|
|
|
post "courses/:course_id/modules/:module_id/items", action: :create, as: "course_context_module_items_create"
|
|
|
|
put "courses/:course_id/modules/:module_id/items/:id", action: :update, as: "course_context_module_item_update"
|
|
|
|
delete "courses/:course_id/modules/:module_id/items/:id", action: :destroy
|
2014-12-02 07:30:29 +08:00
|
|
|
post "courses/:course_id/modules/:module_id/items/:id/mark_read", action: :mark_item_read
|
2016-08-23 22:04:31 +08:00
|
|
|
post "courses/:course_id/modules/:module_id/items/:id/select_mastery_path", action: :select_mastery_path
|
2017-10-04 05:02:03 +08:00
|
|
|
post "courses/:course_id/modules/items/:id/duplicate", action: :duplicate, as: :course_context_module_item_duplicate
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_assignment_overrides") do
|
|
|
|
get "courses/:course_id/quizzes/assignment_overrides", action: :index, as: "course_quiz_assignment_overrides"
|
2020-02-22 01:24:29 +08:00
|
|
|
get "courses/:course_id/new_quizzes/assignment_overrides", action: :new_quizzes, as: "course_new_quizzes_assignment_overrides"
|
quiz index optimizations
Closes CNVS-15109, CNVS-15173
CHANGES
-------
- "auto-grading" of due submissions that was previously done
synchronously in the index action is now done in a DJ
- when viewing the index page, you don't get to see due/available
dates on load, instead the dates are fetched on the client-side and
load progressively
- new API endpoint for retrieving assignment overrides for a bunch of
quizzes at [GET] /courses/:course_id/quizzes/assignment_overrides
- we now cache the user's quiz permissions
- Canvas AMS API serializer now accepts a new option, see docs
- QuizSerializer behavior changed radically:
- "takeable", "submitted_students", "unsubmitted_students" disabled
- all associations disabled including the submission, assignment
group, and any student participants
- it can now utilize preloaded permissions
Rationale behind disabling things in the serializer is that these were
exclusive for the "show" action, so the next step forwards is to
allow the serializer to recognize different "modes" for output (e.g, for
index and one for show) and tailor the associations/fields accordingly.
Using "#filter" right now isn't cutting it, because assocs get loaded
anyway.
REFACTORING
-----------
- broke down index into three actions for visibility:
1. default, Draft-State version
2. legacy non-DS version that's not reachable in the UI, kept around
until we upgrade the tests
3. ember version
- legacy non-DS ERB code goes into its own file
- moved code that used to grade due submissions inside index to
SubmissionGrader in preparation to remove it from there entirely
- cleaned up internal docs for the Canvas AMS api serializer
TEST PLAN
---- ----
- create ~30 quizzes
+ make one of them have many questions
+ make a good number of submissions (i tested with 420 and 20
students)
- create multiple sections
+ specify date overrides for certain sections, and have at least one
student enrolled in that section
- as a teacher and/or an observer, go to quizzes index
+ verify the page renders fine
+ verify that you see "loading indicators" in the due/available
field which get replaced with actual dates when they're loaded
+ verify it's faster than the version in master (should be at least
60% faster)
- as a student in the general section, go to quizzes index
+ verify the page renders
+ verify you see the same loading behavior for dates as in teacher
view
- as a student in one of the section with overrides, go to index:
+ verify you see the overridden date
Change-Id: I741d89625da1b858148baa95e881fcc75c1802e5
Reviewed-on: https://gerrit.instructure.com/40350
Reviewed-by: Derek DeVries <ddevries@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Trevor deHaan <tdehaan@instructure.com>
Product-Review: Ahmad Amireh <ahmad@instructure.com>
2014-08-31 15:20:52 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quizzes_api") do
|
|
|
|
get "courses/:course_id/quizzes", action: :index, as: "course_quizzes"
|
|
|
|
post "courses/:course_id/quizzes", action: :create, as: "course_quiz_create"
|
|
|
|
get "courses/:course_id/quizzes/:id", action: :show, as: "course_quiz"
|
|
|
|
put "courses/:course_id/quizzes/:id", action: :update, as: "course_quiz_update"
|
|
|
|
delete "courses/:course_id/quizzes/:id", action: :destroy, as: "course_quiz_destroy"
|
|
|
|
post "courses/:course_id/quizzes/:id/reorder", action: :reorder, as: "course_quiz_reorder"
|
2015-06-02 05:31:42 +08:00
|
|
|
post "courses/:course_id/quizzes/:id/validate_access_code", action: :validate_access_code, as: "course_quiz_validate_access_code"
|
2013-06-15 01:09:41 +08:00
|
|
|
end
|
|
|
|
|
2019-11-21 06:46:21 +08:00
|
|
|
scope(controller: "quizzes_next/quizzes_api") do
|
|
|
|
get "courses/:course_id/all_quizzes", action: :index, as: "course_all_quizzes"
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_submission_users") do
|
|
|
|
get "courses/:course_id/quizzes/:id/submission_users", action: :index, as: "course_quiz_submission_users"
|
|
|
|
post "courses/:course_id/quizzes/:id/submission_users/message", action: :message, as: "course_quiz_submission_users_message"
|
2014-03-05 00:33:05 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_groups") do
|
2015-07-31 02:27:09 +08:00
|
|
|
get "courses/:course_id/quizzes/:quiz_id/groups/:id", action: :show, as: "course_quiz_group"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/quizzes/:quiz_id/groups", action: :create, as: "course_quiz_group_create"
|
|
|
|
put "courses/:course_id/quizzes/:quiz_id/groups/:id", action: :update, as: "course_quiz_group_update"
|
|
|
|
delete "courses/:course_id/quizzes/:quiz_id/groups/:id", action: :destroy, as: "course_quiz_group_destroy"
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/groups/:id/reorder", action: :reorder, as: "course_quiz_group_reorder"
|
2013-10-17 04:50:57 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_questions") do
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/questions", action: :index, as: "course_quiz_questions"
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/questions/:id", action: :show, as: "course_quiz_question"
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/questions", action: :create, as: "course_quiz_question_create"
|
|
|
|
put "courses/:course_id/quizzes/:quiz_id/questions/:id", action: :update, as: "course_quiz_question_update"
|
|
|
|
delete "courses/:course_id/quizzes/:quiz_id/questions/:id", action: :destroy, as: "course_quiz_question_destroy"
|
2013-09-07 00:04:41 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_reports") do
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/reports", action: :create, as: "course_quiz_reports_create"
|
2014-10-29 00:11:34 +08:00
|
|
|
delete "courses/:course_id/quizzes/:quiz_id/reports/:id", action: :abort, as: "course_quiz_reports_abort"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/quizzes/:quiz_id/reports", action: :index, as: "course_quiz_reports"
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/reports/:id", action: :show, as: "course_quiz_report"
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: "quizzes/quiz_submission_files") do
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/submissions/self/files", action: :create, as: "quiz_submission_files"
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: "quizzes/quiz_submissions_api") do
|
2016-06-29 05:51:09 +08:00
|
|
|
get "courses/:course_id/quizzes/:quiz_id/submission", action: :submission, as: "course_quiz_user_submission"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/quizzes/:quiz_id/submissions", action: :index, as: "course_quiz_submissions"
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/submissions/:id", action: :show, as: "course_quiz_submission"
|
2015-04-28 06:59:03 +08:00
|
|
|
get "courses/:course_id/quizzes/:quiz_id/submissions/:id/time", action: :time, as: "course_quiz_submission_time"
|
2014-09-23 02:52:41 +08:00
|
|
|
post "courses/:course_id/quizzes/:quiz_id/submissions", action: :create, as: "course_quiz_submission_create"
|
|
|
|
put "courses/:course_id/quizzes/:quiz_id/submissions/:id", action: :update, as: "course_quiz_submission_update"
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/submissions/:id/complete", action: :complete, as: "course_quiz_submission_complete"
|
2013-11-08 00:46:59 +08:00
|
|
|
end
|
2015-02-20 07:28:33 +08:00
|
|
|
|
2014-09-25 06:11:20 +08:00
|
|
|
scope(controller: "quizzes/outstanding_quiz_submissions") do
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/outstanding_quiz_submissions", action: :index, path_name: "outstanding_quiz_submission_index"
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/outstanding_quiz_submissions", action: :grade, path_name: "outstanding_quiz_submission_grade"
|
|
|
|
end
|
2013-11-08 00:46:59 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_extensions") do
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/extensions", action: :create, as: "course_quiz_extensions_create"
|
2014-05-20 04:04:00 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/course_quiz_extensions") do
|
|
|
|
post "courses/:course_id/quiz_extensions", action: :create
|
2014-08-28 05:05:23 +08:00
|
|
|
end
|
|
|
|
|
2014-11-18 11:52:39 +08:00
|
|
|
scope(controller: "quizzes/quiz_submission_events_api") do
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/submissions/:id/events", action: :index, as: "course_quiz_submission_events"
|
|
|
|
post "courses/:course_id/quizzes/:quiz_id/submissions/:id/events", action: :create, as: "create_quiz_submission_events"
|
2014-10-09 08:29:43 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_submission_questions") do
|
|
|
|
get "/quiz_submissions/:quiz_submission_id/questions", action: :index, as: "quiz_submission_questions"
|
|
|
|
post "/quiz_submissions/:quiz_submission_id/questions", action: :answer, as: "quiz_submission_question_answer"
|
2021-01-28 03:11:18 +08:00
|
|
|
get "/quiz_submissions/:quiz_submission_id/questions/:id/formatted_answer", action: :formatted_answer, as: "quiz_submission_question_formatted_answer"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "/quiz_submissions/:quiz_submission_id/questions/:id", action: :show, as: "quiz_submission_question"
|
|
|
|
put "/quiz_submissions/:quiz_submission_id/questions/:id/flag", action: :flag, as: "quiz_submission_question_flag"
|
|
|
|
put "/quiz_submissions/:quiz_submission_id/questions/:id/unflag", action: :unflag, as: "quiz_submission_question_unflag"
|
Quiz Submission Questions API - Update
This patch provides support for answering Quiz Questions via the API.
closes CNVS-9844, CNVS-10225
TEST PLAN
---- ----
Testing this will be a bit rough because there are many variations and
validations to cover. I'll spare the validations that are covered by
specs from the test plan.
Create a quiz with a question of *each* type except "Text" and "File
Upload". There's a script that creates a quiz with its questions
automatically for you if you don't want to keep doing this manually. See
references.
> Answering Questions
Now you need to answer each question via the API. Most of them vary in
formats, but they are fully specified in the API documentation page
(along with examples). See DOCUMENTATION for more info.
> Flagging Questions
Flagging, and unflagging, a question is the same regardless of its type,
see the "EXAMPLE REQUESTS" section.
> Access Validations
Here are some generic, non-question based validations to verify. You
should NOT be able to answer a question if:
- the quiz submission has been turned in
- the quiz submission is overdue
- the Access Code for the quiz is invalid
- the IP filter of the Quiz prohibits you from taking the quiz
- the quiz submission :validation_token is incorrectly specified (ie,
other students shouldn't be able to answer your questions)
- you don't specify the latest :attempt, so if the Quiz has multiple
attempts, and this is your 2nd take, you specify an :attempt of 1,
3, or anything but 2 should fail
- NEW: turn quiz into an OQAAT quiz with the "Can't go back" flag on;
the API should not reject all requests to modify any of the
questions with a 501 error saying that type of quizzes is not
supported yet (support will come in CNVS-10224)
> Grading
Also, when you're done answering the questions, take a look at the
grades and make sure everything gets graded just like it does when using
the UI directly.
> Verifying results in the browser
While taking a quiz in the canvas UI, the scripts perform backups in the
background that would overwrite any changes you do via the API. If you
want to verify the changes you make via the API from the UI, you must
append "?backup=false" to the take quiz page URL, something like this:
http://localhost:3000/courses/1/quizzes/1/take?backup=false
Setting that flag will (for now) disable the backup behaviour and should
make things tick.
EXAMPLE REQUESTS
------- --------
Don't forget to set the 'Content-Type' header to 'application/json'!
> Answering a Multiple-Choice question
[PUT] /api/v1/quiz_submissions/:quiz_submission_id/questions/:id
{
"attempt": 1,
"validation_token": "1babd0...",
"answer": 10
}
> Flagging a question
[PUT] /api/v1/quiz_submissions/:quiz_submission_id/questions/:id/flag
{
"attempt": 1,
"validation_token": "1babd0..."
}
> Unflagging a question
[PUT] /api/v1/quiz_submissions/:quiz_submission_id/questions/:id/unflag
{
"attempt": 1,
"validation_token": "1babd0..."
}
DOCUMENTATION
-------------
Run `bundle exec rake doc:api` and check out the Quiz Submission
Questions page. There's an Appendix that contains example requests for
each question type, as well as the errors produced by each handler.
LINKS
-----
- bootstrap script:
https://gist.github.com/amireh/e7e8f835ffbf1d053e4c
- direct link to the API documentation page:
http://canvas.docs.kodoware.com/quiz_submission_questions.html
Change-Id: I9a958323ece8854bc21a24c2affd8dc3972e46d5
Reviewed-on: https://gerrit.instructure.com/27206
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Derek DeVries <ddevries@instructure.com>
QA-Review: Myller de Araujo <myller@instructure.com>
Product-Review: Ahmad Amireh <ahmad@instructure.com>
2013-12-10 17:15:01 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_ip_filters") do
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/ip_filters", action: :index, as: "course_quiz_ip_filters"
|
Quiz IP Filters API controller - #index
This patch moves rendering of IP filters from the QuizzesController into
a separate, specialized API controller - QuizzesIpFilters.
The rendered IP filter object is backwards-compatible, as in it provides
the same three attributes: name, account, and filter. However, the endpoint
output has been modified to scope the array of filters under "quiz_ip_filters".
The front-end/JS part has been adjusted to accommodate this change.
REFACTORING
-----------
In an effort to reduce complexity, I've also taken to refactor all the
:before_filters that were looking up Quiz in the current context across
all Quiz controllers (where it was applicable), and that was done by
introducing a new component set: API Helpers.
API Helpers are modules that can be mixed-in, just like the API Modules,
that are really just a place to hold routines common between the API
and the regular controllers. I've put the first one in
lib/api/v1/helpers, namespaced under Api::V1::Helpers...
TEST PLAN
---- ----
- Create a Quiz. No questions.
- Set an IP filter of 192.168.1.1 on the Quiz
- the restriction should still hold like it usually does
- Perform a GET request to this endpoint:
/courses/:course_id/quizzes/:quiz_id/ip_filters
- A list of filters should be returned in JSON-API format containing
the filter you set for the Quiz
- Add one or more IP Filters on the account-level, and:
- Re-perform the GET query:
- The list should contain both the Quiz and the Account filters
- Using the IP Filter search box from the Quiz settings page:
- It should still properly list the available filters
refs CNVS-8988, CNVS-9586
Change-Id: I75c1b85024a58e6accd1627b7bee3da1185d2658
Reviewed-on: https://gerrit.instructure.com/26440
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Derek DeVries <ddevries@instructure.com>
QA-Review: Myller de Araujo <myller@instructure.com>
Product-Review: Ahmad Amireh <ahmad@instructure.com>
2013-11-19 17:06:49 +08:00
|
|
|
end
|
2014-04-29 04:35:20 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "quizzes/quiz_statistics") do
|
|
|
|
get "courses/:course_id/quizzes/:quiz_id/statistics", action: :index, as: "course_quiz_statistics"
|
2014-03-03 21:00:35 +08:00
|
|
|
end
|
Quiz IP Filters API controller - #index
This patch moves rendering of IP filters from the QuizzesController into
a separate, specialized API controller - QuizzesIpFilters.
The rendered IP filter object is backwards-compatible, as in it provides
the same three attributes: name, account, and filter. However, the endpoint
output has been modified to scope the array of filters under "quiz_ip_filters".
The front-end/JS part has been adjusted to accommodate this change.
REFACTORING
-----------
In an effort to reduce complexity, I've also taken to refactor all the
:before_filters that were looking up Quiz in the current context across
all Quiz controllers (where it was applicable), and that was done by
introducing a new component set: API Helpers.
API Helpers are modules that can be mixed-in, just like the API Modules,
that are really just a place to hold routines common between the API
and the regular controllers. I've put the first one in
lib/api/v1/helpers, namespaced under Api::V1::Helpers...
TEST PLAN
---- ----
- Create a Quiz. No questions.
- Set an IP filter of 192.168.1.1 on the Quiz
- the restriction should still hold like it usually does
- Perform a GET request to this endpoint:
/courses/:course_id/quizzes/:quiz_id/ip_filters
- A list of filters should be returned in JSON-API format containing
the filter you set for the Quiz
- Add one or more IP Filters on the account-level, and:
- Re-perform the GET query:
- The list should contain both the Quiz and the Account filters
- Using the IP Filter search box from the Quiz settings page:
- It should still properly list the available filters
refs CNVS-8988, CNVS-9586
Change-Id: I75c1b85024a58e6accd1627b7bee3da1185d2658
Reviewed-on: https://gerrit.instructure.com/26440
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Derek DeVries <ddevries@instructure.com>
QA-Review: Myller de Araujo <myller@instructure.com>
Product-Review: Ahmad Amireh <ahmad@instructure.com>
2013-11-19 17:06:49 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "polling/polls") do
|
|
|
|
get "polls", action: :index, as: "polls"
|
|
|
|
post "polls", action: :create, as: "poll_create"
|
|
|
|
get "polls/:id", action: :show, as: "poll"
|
|
|
|
put "polls/:id", action: :update, as: "poll_update"
|
|
|
|
delete "polls/:id", action: :destroy, as: "poll_destroy"
|
2014-04-29 04:35:20 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "polling/poll_choices") do
|
|
|
|
get "polls/:poll_id/poll_choices", action: :index, as: "poll_choices"
|
|
|
|
post "polls/:poll_id/poll_choices", action: :create, as: "poll_choices_create"
|
|
|
|
get "polls/:poll_id/poll_choices/:id", action: :show, as: "poll_choice"
|
|
|
|
put "polls/:poll_id/poll_choices/:id", action: :update, as: "poll_choice_update"
|
|
|
|
delete "polls/:poll_id/poll_choices/:id", action: :destroy, as: "poll_choice_destroy"
|
2014-05-06 05:58:49 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "polling/poll_sessions") do
|
|
|
|
get "polls/:poll_id/poll_sessions", action: :index, as: "poll_sessions"
|
|
|
|
post "polls/:poll_id/poll_sessions", action: :create, as: "poll_sessions_create"
|
|
|
|
get "polls/:poll_id/poll_sessions/:id", action: :show, as: "poll_session"
|
|
|
|
put "polls/:poll_id/poll_sessions/:id", action: :update, as: "poll_session_update"
|
|
|
|
delete "polls/:poll_id/poll_sessions/:id", action: :destroy, as: "poll_session_destroy"
|
|
|
|
get "polls/:poll_id/poll_sessions/:id/open", action: :open, as: "poll_session_publish"
|
|
|
|
get "polls/:poll_id/poll_sessions/:id/close", action: :close, as: "poll_session_close"
|
2014-05-28 05:24:34 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "poll_sessions/opened", action: :opened, as: "poll_sessions_opened"
|
|
|
|
get "poll_sessions/closed", action: :closed, as: "poll_sessions_closed"
|
2014-05-06 05:58:49 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "polling/poll_submissions") do
|
|
|
|
post "polls/:poll_id/poll_sessions/:poll_session_id/poll_submissions", action: :create, as: "poll_submissions_create"
|
|
|
|
get "polls/:poll_id/poll_sessions/:poll_session_id/poll_submissions/:id", action: :show, as: "poll_submission"
|
2014-04-29 04:35:20 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "live_assessments/assessments") do
|
2015-06-26 03:35:25 +08:00
|
|
|
get "courses/:course_id/live_assessments", action: :index, as: "course_live_assessments"
|
|
|
|
post "courses/:course_id/live_assessments", action: :create, as: "course_live_assessment_create"
|
2014-05-17 08:48:33 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: "live_assessments/results") do
|
2015-06-26 03:35:25 +08:00
|
|
|
get "courses/:course_id/live_assessments/:assessment_id/results", action: :index, as: "course_live_assessment_results"
|
|
|
|
post "courses/:course_id/live_assessments/:assessment_id/results", action: :create, as: "course_live_assessment_result_create"
|
2014-05-17 08:48:33 +08:00
|
|
|
end
|
|
|
|
|
2016-08-10 05:59:02 +08:00
|
|
|
scope(controller: "support_helpers/turnitin") do
|
|
|
|
get "support_helpers/turnitin/md5", action: :md5
|
|
|
|
get "support_helpers/turnitin/error2305", action: :error2305
|
|
|
|
get "support_helpers/turnitin/shard", action: :shard
|
|
|
|
get "support_helpers/turnitin/assignment", action: :assignment
|
|
|
|
get "support_helpers/turnitin/pending", action: :pending
|
|
|
|
get "support_helpers/turnitin/expired", action: :expired
|
2017-01-04 06:34:08 +08:00
|
|
|
get "support_helpers/turnitin/refresh_lti_attachment", action: :lti_attachment
|
2016-08-10 05:59:02 +08:00
|
|
|
end
|
|
|
|
|
2018-11-16 04:57:26 +08:00
|
|
|
scope(controller: "support_helpers/plagiarism_platform") do
|
|
|
|
get "support_helpers/plagiarism_platform/add_service", action: :add_service
|
2018-11-28 06:58:22 +08:00
|
|
|
get "support_helpers/plagiarism_platform/resubmit_for_assignment/:assignment_id", action: :resubmit_for_assignment
|
2018-11-16 04:57:26 +08:00
|
|
|
end
|
|
|
|
|
2016-10-26 23:16:23 +08:00
|
|
|
scope(controller: "support_helpers/crocodoc") do
|
|
|
|
get "support_helpers/crocodoc/shard", action: :shard
|
|
|
|
get "support_helpers/crocodoc/submission", action: :submission
|
|
|
|
end
|
|
|
|
|
2018-05-01 06:38:31 +08:00
|
|
|
scope(controller: "support_helpers/due_date_cache") do
|
|
|
|
get "support_helpers/due_date_cache/course", action: :course
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :outcome_groups_api) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[global account course].each do |context|
|
2012-08-07 04:43:30 +08:00
|
|
|
prefix = (context == "global" ? context : "#{context}s/:#{context}_id")
|
2014-01-15 08:15:38 +08:00
|
|
|
unless context == "global"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{prefix}/outcome_groups", action: :index, as: "#{context}_outcome_groups"
|
|
|
|
get "#{prefix}/outcome_group_links", action: :link_index, as: "#{context}_outcome_group_links"
|
2014-01-15 08:15:38 +08:00
|
|
|
end
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{prefix}/root_outcome_group", action: :redirect, as: "#{context}_redirect"
|
|
|
|
get "#{prefix}/outcome_groups/account_chain", action: :account_chain, as: "#{context}_account_chain"
|
|
|
|
get "#{prefix}/outcome_groups/:id", action: :show, as: "#{context}_outcome_group"
|
|
|
|
put "#{prefix}/outcome_groups/:id", action: :update
|
|
|
|
delete "#{prefix}/outcome_groups/:id", action: :destroy
|
|
|
|
get "#{prefix}/outcome_groups/:id/outcomes", action: :outcomes, as: "#{context}_outcome_group_outcomes"
|
|
|
|
get "#{prefix}/outcome_groups/:id/available_outcomes", action: :available_outcomes, as: "#{context}_outcome_group_available_outcomes"
|
|
|
|
post "#{prefix}/outcome_groups/:id/outcomes", action: :link
|
|
|
|
put "#{prefix}/outcome_groups/:id/outcomes/:outcome_id", action: :link, as: "#{context}_outcome_link"
|
|
|
|
delete "#{prefix}/outcome_groups/:id/outcomes/:outcome_id", action: :unlink
|
|
|
|
get "#{prefix}/outcome_groups/:id/subgroups", action: :subgroups, as: "#{context}_outcome_group_subgroups"
|
|
|
|
post "#{prefix}/outcome_groups/:id/subgroups", action: :create
|
|
|
|
post "#{prefix}/outcome_groups/:id/import", action: :import, as: "#{context}_outcome_group_import"
|
|
|
|
post "#{prefix}/outcome_groups/:id/batch", action: :batch, as: "#{context}_outcome_group_batch"
|
2012-08-07 04:43:30 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :outcomes_api) do
|
|
|
|
get "outcomes/:id", action: :show, as: "outcome"
|
|
|
|
put "outcomes/:id", action: :update
|
|
|
|
delete "outcomes/:id", action: :destroy
|
2018-08-23 00:33:49 +08:00
|
|
|
get "courses/:course_id/outcome_alignments", action: :outcome_alignments
|
2012-08-07 04:43:30 +08:00
|
|
|
end
|
2012-12-19 05:23:45 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :outcome_results) do
|
|
|
|
get "courses/:course_id/outcome_rollups", action: :rollups, as: "course_outcome_rollups"
|
|
|
|
get "courses/:course_id/outcome_results", action: :index, as: "course_outcome_results"
|
2013-12-18 08:44:23 +08:00
|
|
|
end
|
|
|
|
|
2020-07-24 01:08:50 +08:00
|
|
|
scope(controller: :outcomes_academic_benchmark_import_api) do
|
2015-04-30 08:14:16 +08:00
|
|
|
# These can be uncommented when implemented
|
|
|
|
# get "global/outcomes_import", action: :index
|
|
|
|
# get "global/outcomes_import/:id", action: :show
|
|
|
|
# put "global/outcomes_import/:id", action: :cancel
|
|
|
|
# get "global/outcomes_import/list/:guid", action: :list
|
|
|
|
get "global/outcomes_import/available", action: :available
|
|
|
|
post "global/outcomes_import", action: :create
|
2015-07-09 03:50:17 +08:00
|
|
|
get "global/outcomes_import/migration_status/:migration_id", action: :migration_status
|
2015-04-30 08:14:16 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :group_categories) do
|
|
|
|
resources :group_categories, except: [:index, :create]
|
|
|
|
get "accounts/:account_id/group_categories", action: :index, as: "account_group_categories"
|
|
|
|
get "courses/:course_id/group_categories", action: :index, as: "course_group_categories"
|
|
|
|
post "accounts/:account_id/group_categories", action: :create
|
|
|
|
post "courses/:course_id/group_categories", action: :create
|
2020-09-26 00:51:55 +08:00
|
|
|
post "group_categories/:group_category_id/import", action: :import
|
2014-09-23 02:52:41 +08:00
|
|
|
get "group_categories/:group_category_id/groups", action: :groups, as: "group_category_groups"
|
|
|
|
get "group_categories/:group_category_id/users", action: :users, as: "group_category_users"
|
2020-10-07 14:59:13 +08:00
|
|
|
get "group_categories/:group_category_id/export", action: :export, as: "group_category_export", defaults: { format: :csv }
|
2014-09-23 02:52:41 +08:00
|
|
|
post "group_categories/:group_category_id/assign_unassigned_members", action: "assign_unassigned_members", as: "group_category_assign_unassigned_members"
|
2012-12-19 05:23:45 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :progress) do
|
|
|
|
get "progress/:id", action: :show, as: "progress"
|
2013-01-16 07:37:54 +08:00
|
|
|
end
|
2013-04-30 00:12:46 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :app_center) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2013-05-07 02:56:22 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id/app_center"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{prefix}/apps", action: :index, as: "#{context}_app_center_apps"
|
|
|
|
get "#{prefix}/apps/:app_id/reviews", action: :reviews, as: "#{context}_app_center_app_reviews"
|
|
|
|
get "#{prefix}/apps/:app_id/reviews/self", action: :review, as: "#{context}_app_center_app_review"
|
|
|
|
post "#{prefix}/apps/:app_id/reviews/self", action: :add_review
|
2013-05-07 02:56:22 +08:00
|
|
|
end
|
2013-04-30 00:12:46 +08:00
|
|
|
end
|
feature flags infrastructure and API
test plan:
- install the test_features plugin (since no real features exist yet)
- render and consult the feature flags documentation
- have a test environment with a root account,
sub-account, course in sub-account, and user
- Use the "list features" endpoint as a root account admin
(with no site admin privileges), on the root account context, and
confirm that hidden features do not show up
- Use the "list features" endpoint as a site admin user,
on the root account context, and confirm that hidden features
show up
- Use the "list features" endpoint on the site admin account
and confirm the hidden features show up
- Use the "set feature flag" endpoint on a hidden feature on site
admin and ensure the feature becomes visible in all root accounts
- Use the "set feature flag endpoint" on a hidden feature on a
single root account, and ensure the feature becomes visible to
that root account and not others
- Confirm that root_opt_in features appear "Off" by default
in root accounts, after being "Allowed" in code or site admin
- Confirm a feature flag that is set to "on" or "off" (vs. "allowed")
cannot be overridden in a lower context (and the API returns
locked=true for them)
- Confirm that setting locking_account_id requires admin rights
in the locking account
- Confirm that a feature flag with locking_account_id cannot be
changed without admin rights in the locking account (e.g.,
set a feature flag on a course, locked with the root account's id,
and make sure a teacher who is not an account admin can't change it)
- Confirm feature flags can be deleted with the "remove feature flag"
endpoint (and they are only deleted where they are defined, not
when called on an object that inherits a flag)
Change-Id: I3e12e23b4454889b6e8b263f1315e82d8f2ada52
Reviewed-on: https://gerrit.instructure.com/25502
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Matt Fairbourn <mfairbourn@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
2013-10-22 23:28:26 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :feature_flags) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account user].each do |context|
|
feature flags infrastructure and API
test plan:
- install the test_features plugin (since no real features exist yet)
- render and consult the feature flags documentation
- have a test environment with a root account,
sub-account, course in sub-account, and user
- Use the "list features" endpoint as a root account admin
(with no site admin privileges), on the root account context, and
confirm that hidden features do not show up
- Use the "list features" endpoint as a site admin user,
on the root account context, and confirm that hidden features
show up
- Use the "list features" endpoint on the site admin account
and confirm the hidden features show up
- Use the "set feature flag" endpoint on a hidden feature on site
admin and ensure the feature becomes visible in all root accounts
- Use the "set feature flag endpoint" on a hidden feature on a
single root account, and ensure the feature becomes visible to
that root account and not others
- Confirm that root_opt_in features appear "Off" by default
in root accounts, after being "Allowed" in code or site admin
- Confirm a feature flag that is set to "on" or "off" (vs. "allowed")
cannot be overridden in a lower context (and the API returns
locked=true for them)
- Confirm that setting locking_account_id requires admin rights
in the locking account
- Confirm that a feature flag with locking_account_id cannot be
changed without admin rights in the locking account (e.g.,
set a feature flag on a course, locked with the root account's id,
and make sure a teacher who is not an account admin can't change it)
- Confirm feature flags can be deleted with the "remove feature flag"
endpoint (and they are only deleted where they are defined, not
when called on an object that inherits a flag)
Change-Id: I3e12e23b4454889b6e8b263f1315e82d8f2ada52
Reviewed-on: https://gerrit.instructure.com/25502
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Matt Fairbourn <mfairbourn@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
2013-10-22 23:28:26 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id/features"
|
2021-11-11 02:24:05 +08:00
|
|
|
get prefix.to_s, action: :index, as: "#{context}_features"
|
2014-09-23 02:52:41 +08:00
|
|
|
get "#{prefix}/enabled", action: :enabled_features, as: "#{context}_enabled_features"
|
|
|
|
get "#{prefix}/flags/:feature", action: :show
|
|
|
|
put "#{prefix}/flags/:feature", action: :update
|
|
|
|
delete "#{prefix}/flags/:feature", action: :delete
|
feature flags infrastructure and API
test plan:
- install the test_features plugin (since no real features exist yet)
- render and consult the feature flags documentation
- have a test environment with a root account,
sub-account, course in sub-account, and user
- Use the "list features" endpoint as a root account admin
(with no site admin privileges), on the root account context, and
confirm that hidden features do not show up
- Use the "list features" endpoint as a site admin user,
on the root account context, and confirm that hidden features
show up
- Use the "list features" endpoint on the site admin account
and confirm the hidden features show up
- Use the "set feature flag" endpoint on a hidden feature on site
admin and ensure the feature becomes visible in all root accounts
- Use the "set feature flag endpoint" on a hidden feature on a
single root account, and ensure the feature becomes visible to
that root account and not others
- Confirm that root_opt_in features appear "Off" by default
in root accounts, after being "Allowed" in code or site admin
- Confirm a feature flag that is set to "on" or "off" (vs. "allowed")
cannot be overridden in a lower context (and the API returns
locked=true for them)
- Confirm that setting locking_account_id requires admin rights
in the locking account
- Confirm that a feature flag with locking_account_id cannot be
changed without admin rights in the locking account (e.g.,
set a feature flag on a course, locked with the root account's id,
and make sure a teacher who is not an account admin can't change it)
- Confirm feature flags can be deleted with the "remove feature flag"
endpoint (and they are only deleted where they are defined, not
when called on an object that inherits a flag)
Change-Id: I3e12e23b4454889b6e8b263f1315e82d8f2ada52
Reviewed-on: https://gerrit.instructure.com/25502
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Matt Fairbourn <mfairbourn@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
2013-10-22 23:28:26 +08:00
|
|
|
end
|
2021-02-03 04:17:53 +08:00
|
|
|
get "features/environment", action: :environment
|
feature flags infrastructure and API
test plan:
- install the test_features plugin (since no real features exist yet)
- render and consult the feature flags documentation
- have a test environment with a root account,
sub-account, course in sub-account, and user
- Use the "list features" endpoint as a root account admin
(with no site admin privileges), on the root account context, and
confirm that hidden features do not show up
- Use the "list features" endpoint as a site admin user,
on the root account context, and confirm that hidden features
show up
- Use the "list features" endpoint on the site admin account
and confirm the hidden features show up
- Use the "set feature flag" endpoint on a hidden feature on site
admin and ensure the feature becomes visible in all root accounts
- Use the "set feature flag endpoint" on a hidden feature on a
single root account, and ensure the feature becomes visible to
that root account and not others
- Confirm that root_opt_in features appear "Off" by default
in root accounts, after being "Allowed" in code or site admin
- Confirm a feature flag that is set to "on" or "off" (vs. "allowed")
cannot be overridden in a lower context (and the API returns
locked=true for them)
- Confirm that setting locking_account_id requires admin rights
in the locking account
- Confirm that a feature flag with locking_account_id cannot be
changed without admin rights in the locking account (e.g.,
set a feature flag on a course, locked with the root account's id,
and make sure a teacher who is not an account admin can't change it)
- Confirm feature flags can be deleted with the "remove feature flag"
endpoint (and they are only deleted where they are defined, not
when called on an object that inherits a flag)
Change-Id: I3e12e23b4454889b6e8b263f1315e82d8f2ada52
Reviewed-on: https://gerrit.instructure.com/25502
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Matt Fairbourn <mfairbourn@instructure.com>
Product-Review: Matt Goodwin <mattg@instructure.com>
Reviewed-by: Zach Pendleton <zachp@instructure.com>
2013-10-22 23:28:26 +08:00
|
|
|
end
|
2013-12-17 00:56:46 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :conferences) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group].each do |context|
|
2013-12-17 00:56:46 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id/conferences"
|
2014-09-23 02:52:41 +08:00
|
|
|
get prefix, action: :index, as: "#{context}_conferences"
|
2021-11-11 02:24:05 +08:00
|
|
|
post prefix.to_s, action: :create
|
2015-04-08 07:24:18 +08:00
|
|
|
post "#{prefix}/:conference_id/recording_ready", action: :recording_ready, as: "#{context}_conferences_recording_ready"
|
2013-12-17 00:56:46 +08:00
|
|
|
end
|
2020-03-19 02:55:42 +08:00
|
|
|
|
|
|
|
get "conferences", action: :for_user, as: "conferences"
|
2013-12-17 00:56:46 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :custom_gradebook_columns_api) do
|
2013-12-07 14:08:03 +08:00
|
|
|
prefix = "courses/:course_id/custom_gradebook_columns"
|
2014-09-23 02:52:41 +08:00
|
|
|
get prefix, action: :index, as: "course_custom_gradebook_columns"
|
|
|
|
post prefix, action: :create
|
2015-06-26 03:35:25 +08:00
|
|
|
post "#{prefix}/reorder", action: :reorder, as: "custom_gradebook_columns_reorder"
|
|
|
|
put "#{prefix}/:id", action: :update, as: "course_custom_gradebook_column"
|
2014-09-23 02:52:41 +08:00
|
|
|
delete "#{prefix}/:id", action: :destroy
|
2013-12-07 14:08:03 +08:00
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :custom_gradebook_column_data_api) do
|
2013-12-07 14:08:03 +08:00
|
|
|
prefix = "courses/:course_id/custom_gradebook_columns/:id/data"
|
2014-09-23 02:52:41 +08:00
|
|
|
get prefix, action: :index, as: "course_custom_gradebook_column_data"
|
|
|
|
put "#{prefix}/:user_id", action: :update, as: "course_custom_gradebook_column_datum"
|
2018-07-10 05:21:24 +08:00
|
|
|
put "courses/:course_id/custom_gradebook_column_data", action: :bulk_update, as: "course_custom_gradebook_column_bulk_data"
|
2013-12-07 14:08:03 +08:00
|
|
|
end
|
2014-01-08 23:24:44 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :content_exports_api) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group user].each do |context|
|
zip content exports for course, group, user
test plan:
1. use the content exports api with export_type=zip
to export files from courses, groups, and users
a. confirm only users who have permission to
download files from these contexts can perform
the export
b. confirm that deleted files and folders do not show
up in the downloaded archive
c. confirm that students cannot download locked files
or folders from courses this way
d. check the progress endpoint and make sure
it increments sanely
2. perform selective content exports by passing an array
of ids in select[folders] and/or select[attachments].
for example,
?select[folders][]=123&select[folders][]=456
?select[attachments][]=345
etc.
a. any selected files, plus the full contents of any
selected folders (that the caller has permission
to see) should be included
- that means locked files and subfolders should
be excluded from the archive
b. if all selected files and folders are descendants
of the same subfolder X, the export should be named
"X_export.zip" and all paths inside the zip should be
relative to it. for example, if you are exporting A/B/1
and A/C/2, you should get "A_export.zip" containing
files "B/1" and "C/2".
3. use the index and show endpoints to list and view
content exports in courses, groups, and users
a. confirm students cannot view non-zip course exports
(such as common cartridge exports)
b. confirm students cannot view other users' file (zip)
exports, in course, group, and user context
c. confirm teachers cannot view other users' file (zip)
exports, in course, group, and user context
(but can still view course [cc] exports initiated by
other teachers)
4. look at /courses/X/content_exports (web, not API)
a. confirm teachers see file exports they performed
b. confirm teachers do not see file exports performed by
other teachers
c. confirm teachers see all non-zip course exports
(cc/qti) including those initiated by other teachers
5. as a site admin user, perform a zip export of another
user's files. then, as that other user, go to
/dashboard/data_exports and confirm that the export
performed by the site admin user is not shown.
fixes CNVS-12706
Change-Id: Ie9b58e44ac8006a9c9171b3ed23454bf135385b0
Reviewed-on: https://gerrit.instructure.com/34341
Reviewed-by: James Williams <jamesw@instructure.com>
QA-Review: Trevor deHaan <tdehaan@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Product-Review: Jon Willesen <jonw@instructure.com>
2014-07-18 04:00:32 +08:00
|
|
|
context_prefix = "#{context.pluralize}/:#{context}_id"
|
|
|
|
prefix = "#{context_prefix}/content_exports"
|
2014-09-23 02:52:41 +08:00
|
|
|
get prefix, action: :index, as: "#{context}_content_exports"
|
|
|
|
post prefix, action: :create
|
|
|
|
get "#{prefix}/:id", action: :show
|
2021-02-10 07:14:29 +08:00
|
|
|
put "#{prefix}/:id/fail", action: :fail
|
zip content exports for course, group, user
test plan:
1. use the content exports api with export_type=zip
to export files from courses, groups, and users
a. confirm only users who have permission to
download files from these contexts can perform
the export
b. confirm that deleted files and folders do not show
up in the downloaded archive
c. confirm that students cannot download locked files
or folders from courses this way
d. check the progress endpoint and make sure
it increments sanely
2. perform selective content exports by passing an array
of ids in select[folders] and/or select[attachments].
for example,
?select[folders][]=123&select[folders][]=456
?select[attachments][]=345
etc.
a. any selected files, plus the full contents of any
selected folders (that the caller has permission
to see) should be included
- that means locked files and subfolders should
be excluded from the archive
b. if all selected files and folders are descendants
of the same subfolder X, the export should be named
"X_export.zip" and all paths inside the zip should be
relative to it. for example, if you are exporting A/B/1
and A/C/2, you should get "A_export.zip" containing
files "B/1" and "C/2".
3. use the index and show endpoints to list and view
content exports in courses, groups, and users
a. confirm students cannot view non-zip course exports
(such as common cartridge exports)
b. confirm students cannot view other users' file (zip)
exports, in course, group, and user context
c. confirm teachers cannot view other users' file (zip)
exports, in course, group, and user context
(but can still view course [cc] exports initiated by
other teachers)
4. look at /courses/X/content_exports (web, not API)
a. confirm teachers see file exports they performed
b. confirm teachers do not see file exports performed by
other teachers
c. confirm teachers see all non-zip course exports
(cc/qti) including those initiated by other teachers
5. as a site admin user, perform a zip export of another
user's files. then, as that other user, go to
/dashboard/data_exports and confirm that the export
performed by the site admin user is not shown.
fixes CNVS-12706
Change-Id: Ie9b58e44ac8006a9c9171b3ed23454bf135385b0
Reviewed-on: https://gerrit.instructure.com/34341
Reviewed-by: James Williams <jamesw@instructure.com>
QA-Review: Trevor deHaan <tdehaan@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
Product-Review: Jon Willesen <jonw@instructure.com>
2014-07-18 04:00:32 +08:00
|
|
|
end
|
2014-09-23 02:52:41 +08:00
|
|
|
get "courses/:course_id/content_list", action: :content_list, as: "course_content_list"
|
2014-01-08 23:24:44 +08:00
|
|
|
end
|
2014-01-17 03:55:53 +08:00
|
|
|
|
2015-07-21 05:19:44 +08:00
|
|
|
scope(controller: :epub_exports) do
|
|
|
|
get "courses/:course_id/epub_exports/:id", {
|
|
|
|
action: :show
|
|
|
|
}
|
|
|
|
get "epub_exports", {
|
|
|
|
action: :index
|
|
|
|
}
|
|
|
|
post "courses/:course_id/epub_exports", {
|
|
|
|
action: :create
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2016-12-14 07:08:27 +08:00
|
|
|
scope(controller: :web_zip_exports) do
|
|
|
|
get "courses/:course_id/web_zip_exports", action: :index, as: "web_zip_exports"
|
|
|
|
get "courses/:course_id/web_zip_exports/:id", action: :show
|
|
|
|
end
|
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
scope(controller: :grading_standards_api) do
|
2015-07-23 23:23:17 +08:00
|
|
|
get "courses/:course_id/grading_standards", action: :context_index
|
|
|
|
get "accounts/:account_id/grading_standards", action: :context_index
|
2017-07-27 23:40:06 +08:00
|
|
|
get "courses/:course_id/grading_standards/:grading_standard_id", action: :context_show
|
|
|
|
get "accounts/:account_id/grading_standards/:grading_standard_id", action: :context_show
|
2014-09-23 02:52:41 +08:00
|
|
|
post "accounts/:account_id/grading_standards", action: :create
|
|
|
|
post "courses/:course_id/grading_standards", action: :create
|
2014-02-19 05:31:26 +08:00
|
|
|
end
|
2014-06-11 14:49:14 +08:00
|
|
|
|
2014-09-23 02:52:41 +08:00
|
|
|
get "/crocodoc_session", controller: "crocodoc_sessions", action: "show", as: :crocodoc_session
|
2014-06-11 14:49:14 +08:00
|
|
|
get "/canvadoc_session", controller: "canvadoc_sessions", action: "show", as: :canvadoc_session
|
2021-03-09 12:25:06 +08:00
|
|
|
post "/canvadoc_session", controller: "canvadoc_sessions", action: "create"
|
2014-06-11 14:49:14 +08:00
|
|
|
|
2016-04-27 10:10:14 +08:00
|
|
|
scope(controller: :grading_period_sets) do
|
|
|
|
get "accounts/:account_id/grading_period_sets", action: :index, as: :account_grading_period_sets
|
|
|
|
post "accounts/:account_id/grading_period_sets", action: :create
|
|
|
|
patch "accounts/:account_id/grading_period_sets/:id", action: :update, as: :account_grading_period_set
|
|
|
|
delete "accounts/:account_id/grading_period_sets/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
2014-10-09 03:53:39 +08:00
|
|
|
scope(controller: :grading_periods) do
|
2016-04-22 06:09:15 +08:00
|
|
|
# FIXME: This route will be removed/replaced with CNVS-27101
|
|
|
|
get "accounts/:account_id/grading_periods", action: :index, as: :account_grading_periods
|
|
|
|
|
|
|
|
get "courses/:course_id/grading_periods", action: :index, as: :course_grading_periods
|
|
|
|
get "courses/:course_id/grading_periods/:id", action: :show, as: :course_grading_period
|
|
|
|
patch "courses/:course_id/grading_periods/batch_update",
|
|
|
|
action: :batch_update, as: :course_grading_period_batch_update
|
|
|
|
put "courses/:course_id/grading_periods/:id", action: :update, as: :course_grading_period_update
|
|
|
|
delete "courses/:course_id/grading_periods/:id", action: :destroy, as: :course_grading_period_destroy
|
2016-06-07 00:28:17 +08:00
|
|
|
delete "accounts/:account_id/grading_periods/:id", action: :destroy, as: :account_grading_period_destroy
|
2016-06-02 09:29:09 +08:00
|
|
|
|
|
|
|
patch "grading_period_sets/:set_id/grading_periods/batch_update",
|
|
|
|
action: :batch_update, as: :grading_period_set_periods_update
|
2014-10-09 03:53:39 +08:00
|
|
|
end
|
2014-11-14 02:35:24 +08:00
|
|
|
|
|
|
|
scope(controller: :usage_rights) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course group user].each do |context|
|
2014-11-14 02:35:24 +08:00
|
|
|
content_prefix = "#{context.pluralize}/:#{context}_id"
|
|
|
|
put "#{content_prefix}/usage_rights", action: :set_usage_rights
|
|
|
|
delete "#{content_prefix}/usage_rights", action: :remove_usage_rights
|
|
|
|
get "#{content_prefix}/content_licenses", action: :licenses
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-05-10 12:23:05 +08:00
|
|
|
scope(controller: "bookmarks/bookmarks") do
|
|
|
|
get "users/self/bookmarks/", action: :index, as: :bookmarks
|
|
|
|
get "users/self/bookmarks/:id", action: :show
|
|
|
|
post "users/self/bookmarks", action: :create
|
|
|
|
delete "users/self/bookmarks/:id", action: :destroy
|
|
|
|
put "users/self/bookmarks/:id", action: :update
|
|
|
|
end
|
2015-05-14 00:30:19 +08:00
|
|
|
|
2015-10-15 21:19:41 +08:00
|
|
|
scope(controller: :course_nicknames) do
|
|
|
|
get "users/self/course_nicknames", action: :index, as: :course_nicknames
|
|
|
|
get "users/self/course_nicknames/:course_id", action: :show
|
|
|
|
put "users/self/course_nicknames/:course_id", action: :update
|
|
|
|
delete "users/self/course_nicknames/:course_id", action: :delete
|
|
|
|
delete "users/self/course_nicknames", action: :clear
|
|
|
|
end
|
|
|
|
|
2016-01-19 03:29:32 +08:00
|
|
|
scope(controller: :shared_brand_configs) do
|
|
|
|
post "accounts/:account_id/shared_brand_configs", action: :create
|
|
|
|
put "accounts/:account_id/shared_brand_configs/:id", action: :update
|
|
|
|
delete "shared_brand_configs/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
2015-05-14 00:30:19 +08:00
|
|
|
scope(controller: :errors) do
|
|
|
|
post "error_reports", action: :create
|
|
|
|
end
|
2015-10-30 04:03:20 +08:00
|
|
|
|
|
|
|
scope(controller: :jwts) do
|
|
|
|
post "jwts", action: :create
|
2017-02-23 00:16:49 +08:00
|
|
|
post "jwts/refresh", action: :refresh
|
2015-10-30 04:03:20 +08:00
|
|
|
end
|
2016-04-19 00:18:20 +08:00
|
|
|
|
2021-07-22 05:20:34 +08:00
|
|
|
scope(controller: :inst_access_tokens) do
|
2021-07-28 13:49:16 +08:00
|
|
|
post "inst_access_tokens", action: :create
|
InstID tokens, part 1: generation
fixes INTEROP-6913, INTEROP-6892, INTEROP-6893, INTEROP-6920
flag = none
This commit introduces the InstID token, a signed and encrypted JWT (aka
JWE) that will soon be usable for Canvas API access (that's "part 2").
If the InstID class is configured with a private signing key and public
encryption key, it will be able to produce encrypted JWTs and validate
and deserialize decrypted JWTs. If it is configured with only a public
signing key, it cannot produce tokens but it can still validate and
deserialize decrypted ones. Therefore this class can be used by the
identity provider (currently Canvas) to produce tokens, but also by any
services that want to use InstID tokens for authentication.
test plan:
1) generate two RSA keypairs. one way to generate a keypair is from a
rails console:
> keypair = Canvas::Security::RSAKeyPair.new
> puts keypair.private_key.to_s
> puts keypair.public_key.to_s
2) choose which one is for signing and which is for encryption, then add
the private signing key and the public encryption key to your rails
credentials:
- run `bin/rails credentials:edit`
- add an entry like the following, and then save and close your
editor:
```
inst_id:
encryption_key: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvY1EMlGm1daM87ejGuFX
<...snip...>
/wIDAQAB
-----END PUBLIC KEY-----
signing_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAnDwED/QOB0f0H6TOZqLmjaPqA7m8c40NDXkAa6u5cK8zCbk3
<...snip...>
QhjPgifBwTrzj21484CfiPfy5oe756Exerj8PIlRrE/hxWRSDwBIOg==
-----END RSA PRIVATE KEY-----
```
3) open a rails console and do:
> id = InstID.for_user('user-uuid')
> id.to_token # make sure this doesn't blow up
> token = id.to_unencrypted_token
> decoded_id = InstID.from_token(token)
> id.jwt_payload == decoded_id.jwt_payload # => true
TODO in followup commits:
- make canvas accept InstID tokens for auth
Change-Id: Ie550c17507c26f9944bd62a747a6a63161e8e770
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/268872
Reviewed-by: Ethan Vizitei <evizitei@instructure.com>
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
QA-Review: Michael Ziwisky <mziwisky@instructure.com>
Product-Review: Michael Ziwisky <mziwisky@instructure.com>
2021-07-13 11:46:17 +08:00
|
|
|
end
|
|
|
|
|
2016-04-19 00:18:20 +08:00
|
|
|
scope(controller: :gradebook_settings) do
|
|
|
|
put "courses/:course_id/gradebook_settings", action: :update, as: :course_gradebook_settings_update
|
|
|
|
end
|
2016-06-10 07:08:08 +08:00
|
|
|
|
|
|
|
scope(controller: :announcements_api) do
|
|
|
|
get "announcements", action: :index, as: :announcements
|
|
|
|
end
|
2016-08-13 04:40:02 +08:00
|
|
|
|
2021-04-22 04:26:07 +08:00
|
|
|
scope(controller: :release_notes) do
|
|
|
|
get "release_notes", action: :index, as: :release_notes
|
|
|
|
post "release_notes", action: :create
|
|
|
|
get "release_notes/latest", action: :latest
|
2021-05-11 06:05:48 +08:00
|
|
|
get "release_notes/unread_count", action: :unread_count
|
2021-04-22 04:26:07 +08:00
|
|
|
put "release_notes/:id", action: :update
|
|
|
|
delete "release_notes/:id", action: :destroy
|
|
|
|
put "release_notes/:id/published", action: :publish
|
|
|
|
delete "release_notes/:id/published", action: :unpublish
|
|
|
|
end
|
|
|
|
|
2016-08-13 04:40:02 +08:00
|
|
|
scope(controller: :rubrics_api) do
|
|
|
|
get "accounts/:account_id/rubrics", action: :index, as: :account_rubrics
|
|
|
|
get "accounts/:account_id/rubrics/:id", action: :show
|
|
|
|
get "courses/:course_id/rubrics", action: :index, as: :course_rubrics
|
|
|
|
get "courses/:course_id/rubrics/:id", action: :show
|
2017-05-11 14:18:27 +08:00
|
|
|
post "courses/:course_id/rubrics", controller: :rubrics, action: :create
|
|
|
|
put "courses/:course_id/rubrics/:id", controller: :rubrics, action: :update
|
2019-02-05 01:36:27 +08:00
|
|
|
delete "courses/:course_id/rubrics/:id", controller: :rubrics, action: :destroy
|
2016-08-13 04:40:02 +08:00
|
|
|
end
|
2017-02-10 04:33:08 +08:00
|
|
|
|
2019-02-06 02:18:13 +08:00
|
|
|
scope(controller: :rubric_associations) do
|
|
|
|
post "courses/:course_id/rubric_associations", action: :create
|
|
|
|
put "courses/:course_id/rubric_associations/:id", action: :update
|
|
|
|
delete "courses/:course_id/rubric_associations/:id", action: :destroy
|
|
|
|
end
|
|
|
|
|
Expose Rubric Assessment API endpoints CUD
Test Plan.
Use postman or curl to test the following endpoints
Remember to change the:
:course_id with the appropiate course_id
:rubric_association_id with the appropiate rubric_association_id
:id with the rubric_assessment_id
POST 'courses/:course_id/rubric_associations/
:rubric_association_id/rubric_assessments'
params example: {
"rubric_assessment": {
"user_id": "22",
"assessment_type": "grading",
"criterion__7226": {
"points": "3",
"comments": "",
"save_comment": "0"
}
},
"graded_anonymously": "false"
}
PUT 'courses/:course_id/rubric_associations/
:rubric_association_id/rubric_assessments/:id'
params example: {
"rubric_assessment": {
"user_id": "22",
"assessment_type": "grading",
"criterion__7226": {
"points": "3",
"comments": "",
"save_comment": "0"
}
},
"graded_anonymously": "false"
}
DELETE 'courses/:course_id/rubric_associations/
:rubric_association_id/rubric_assessments/:id'
refs: PFS-11756
Change-Id: Ib67898f2dec37c3438e1d8f5745c20f1c41113e0
Reviewed-on: https://gerrit.instructure.com/180683
Tested-by: Jenkins
QA-Review: Aiona Rae Hernandez <ahernandez@instructure.com>
QA-Review: Brian Watson <bwatson@instructure.com>
Reviewed-by: Neil Gupta <ngupta@instructure.com>
Reviewed-by: Colin Cromar <ccromar@instructure.com>
Reviewed-by: Augusto Callejas <acallejas@instructure.com>
Product-Review: Augusto Callejas <acallejas@instructure.com>
(cherry picked from commit d17de50121f60104c136b0a1831db786b816231c)
Reviewed-on: https://gerrit.instructure.com/183188
Product-Review: Neil Gupta <ngupta@instructure.com>
2019-02-06 06:34:04 +08:00
|
|
|
scope(controller: :rubric_assessment_api) do
|
|
|
|
post "courses/:course_id/rubric_associations/:rubric_association_id/rubric_assessments", controller: :rubric_assessments, action: :create
|
|
|
|
put "courses/:course_id/rubric_associations/:rubric_association_id/rubric_assessments/:id", controller: :rubric_assessments, action: :update
|
|
|
|
delete "courses/:course_id/rubric_associations/:rubric_association_id/rubric_assessments/:id", controller: :rubric_assessments, action: :destroy
|
|
|
|
end
|
|
|
|
|
2017-02-10 04:33:08 +08:00
|
|
|
scope(controller: "master_courses/master_templates") do
|
|
|
|
get "courses/:course_id/blueprint_templates/:template_id", action: :show
|
|
|
|
get "courses/:course_id/blueprint_templates/:template_id/associated_courses", action: :associated_courses, as: :course_blueprint_associated_courses
|
|
|
|
put "courses/:course_id/blueprint_templates/:template_id/update_associations", action: :update_associations
|
2017-04-28 05:15:46 +08:00
|
|
|
get "courses/:course_id/blueprint_templates/:template_id/unsynced_changes", action: :unsynced_changes, as: :course_blueprint_unsynced_changes
|
2017-02-16 01:18:11 +08:00
|
|
|
|
|
|
|
post "courses/:course_id/blueprint_templates/:template_id/migrations", action: :queue_migration
|
|
|
|
get "courses/:course_id/blueprint_templates/:template_id/migrations", action: :migrations_index, as: :course_blueprint_migrations
|
|
|
|
get "courses/:course_id/blueprint_templates/:template_id/migrations/:id", action: :migrations_show
|
2017-03-11 05:58:45 +08:00
|
|
|
get "courses/:course_id/blueprint_templates/:template_id/migrations/:id/details", action: :migration_details
|
2017-03-15 22:14:57 +08:00
|
|
|
|
|
|
|
put "courses/:course_id/blueprint_templates/:template_id/restrict_item", action: :restrict_item
|
2017-05-24 03:57:22 +08:00
|
|
|
|
2018-08-03 04:22:38 +08:00
|
|
|
get "courses/:course_id/blueprint_subscriptions", action: :subscriptions_index, as: :course_blueprint_subscriptions
|
2017-05-24 03:57:22 +08:00
|
|
|
get "courses/:course_id/blueprint_subscriptions/:subscription_id/migrations", action: :imports_index, as: :course_blueprint_imports
|
|
|
|
get "courses/:course_id/blueprint_subscriptions/:subscription_id/migrations/:id", action: :imports_show
|
|
|
|
get "courses/:course_id/blueprint_subscriptions/:subscription_id/migrations/:id/details", action: :import_details
|
2017-02-10 04:33:08 +08:00
|
|
|
end
|
2017-04-17 23:06:07 +08:00
|
|
|
|
|
|
|
scope(controller: :late_policy) do
|
|
|
|
get "courses/:id/late_policy", action: :show
|
|
|
|
post "courses/:id/late_policy", action: :create
|
|
|
|
patch "courses/:id/late_policy", action: :update
|
|
|
|
end
|
2017-05-11 12:40:45 +08:00
|
|
|
|
2018-05-05 03:11:51 +08:00
|
|
|
scope(controller: :planner) do
|
|
|
|
get "planner/items", action: :index, as: :planner_items
|
2019-09-07 03:43:05 +08:00
|
|
|
get "users/:user_id/planner/items", action: :index, as: :user_planner_items
|
2018-05-05 03:11:51 +08:00
|
|
|
end
|
|
|
|
|
2017-05-11 12:40:45 +08:00
|
|
|
scope(controller: :planner_overrides) do
|
2017-05-19 07:19:20 +08:00
|
|
|
get "planner/overrides", action: :index, as: :planner_overrides
|
2017-05-19 03:32:04 +08:00
|
|
|
get "planner/overrides/:id", action: :show
|
|
|
|
put "planner/overrides/:id", action: :update
|
2017-05-11 12:40:45 +08:00
|
|
|
post "planner/overrides", action: :create
|
2017-05-19 03:32:04 +08:00
|
|
|
delete "planner/overrides/:id", action: :destroy
|
2017-05-11 12:40:45 +08:00
|
|
|
end
|
2017-05-18 23:37:42 +08:00
|
|
|
|
|
|
|
scope(controller: :planner_notes) do
|
|
|
|
get "planner_notes", action: :index, as: :planner_notes
|
2017-06-09 10:52:02 +08:00
|
|
|
get "planner_notes/:id", action: :show, as: :planner_notes_show
|
2017-05-18 23:37:42 +08:00
|
|
|
put "planner_notes/:id", action: :update
|
|
|
|
post "planner_notes", action: :create
|
|
|
|
delete "planner_notes/:id", action: :destroy
|
|
|
|
end
|
2018-11-16 05:32:51 +08:00
|
|
|
|
2019-08-08 08:13:59 +08:00
|
|
|
scope(controller: :content_shares) do
|
|
|
|
post "users/:user_id/content_shares", action: :create
|
2019-08-20 02:42:30 +08:00
|
|
|
get "users/:user_id/content_shares/sent", action: :index, defaults: { list: "sent" }, as: :user_sent_content_shares
|
|
|
|
get "users/:user_id/content_shares/received", action: :index, defaults: { list: "received" }, as: :user_received_content_shares
|
2019-09-27 11:14:32 +08:00
|
|
|
get "users/:user_id/content_shares/unread_count", action: :unread_count
|
2019-08-20 02:42:30 +08:00
|
|
|
get "users/:user_id/content_shares/:id", action: :show
|
|
|
|
delete "users/:user_id/content_shares/:id", action: :destroy
|
|
|
|
post "users/:user_id/content_shares/:id/add_users", action: :add_users
|
|
|
|
put "users/:user_id/content_shares/:id", action: :update
|
2019-08-08 08:13:59 +08:00
|
|
|
end
|
|
|
|
|
2018-11-16 05:32:51 +08:00
|
|
|
scope(controller: :csp_settings) do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2018-11-16 05:32:51 +08:00
|
|
|
get "#{context.pluralize}/:#{context}_id/csp_settings", action: :get_csp_settings
|
|
|
|
put "#{context.pluralize}/:#{context}_id/csp_settings", action: :set_csp_setting
|
|
|
|
end
|
2019-01-30 23:38:03 +08:00
|
|
|
put "accounts/:account_id/csp_settings/lock", action: :set_csp_lock
|
2018-11-16 05:32:51 +08:00
|
|
|
post "accounts/:account_id/csp_settings/domains", action: :add_domain
|
2019-01-24 23:27:26 +08:00
|
|
|
post "accounts/:account_id/csp_settings/domains/batch_create", action: :add_multiple_domains
|
2018-11-16 05:32:51 +08:00
|
|
|
delete "accounts/:account_id/csp_settings/domains", action: :remove_domain
|
2019-03-26 04:34:48 +08:00
|
|
|
get "accounts/:account_id/csp_log", action: :csp_log
|
2018-11-16 05:32:51 +08:00
|
|
|
end
|
2019-05-21 04:08:01 +08:00
|
|
|
|
2021-10-08 01:51:08 +08:00
|
|
|
scope(controller: :media_objects) do
|
2019-05-21 04:08:01 +08:00
|
|
|
post "media_objects", action: "create_media_object", as: :create_media_object
|
|
|
|
end
|
2019-10-31 02:12:24 +08:00
|
|
|
|
|
|
|
scope(controller: :media_objects) do
|
|
|
|
put "media_objects/:media_object_id", action: "update_media_object", as: :update_media_object
|
|
|
|
end
|
2020-01-28 03:08:41 +08:00
|
|
|
|
|
|
|
scope(controller: :media_tracks) do
|
|
|
|
get "media_objects/:media_object_id/media_tracks", action: "index", as: :list_media_tracks
|
|
|
|
put "media_objects/:media_object_id/media_tracks", action: "update", as: :update_media_tracks
|
|
|
|
end
|
|
|
|
|
2020-06-05 22:44:11 +08:00
|
|
|
scope(controller: "conditional_release/rules") do
|
|
|
|
# TODO: can rearrange so assignment is in path if desired once we're no longer maintaining backwards compat
|
|
|
|
get "courses/:course_id/mastery_paths/rules", action: "index"
|
|
|
|
get "courses/:course_id/mastery_paths/rules/:id", action: "show"
|
|
|
|
post "courses/:course_id/mastery_paths/rules", action: "create"
|
|
|
|
put "courses/:course_id/mastery_paths/rules/:id", action: "update"
|
|
|
|
delete "courses/:course_id/mastery_paths/rules/:id", action: "destroy"
|
|
|
|
end
|
|
|
|
|
|
|
|
scope(controller: "conditional_release/stats") do
|
|
|
|
# TODO: can rearrange so assignment is in path if desired once we're no longer maintaining backwards compat
|
|
|
|
get "courses/:course_id/mastery_paths/stats/students_per_range", action: "students_per_range"
|
|
|
|
get "courses/:course_id/mastery_paths/stats/student_details", action: "student_details"
|
|
|
|
end
|
2020-06-24 04:35:54 +08:00
|
|
|
|
|
|
|
scope(controller: :history) do
|
|
|
|
get "users/:user_id/history", action: "index", as: :user_history
|
|
|
|
end
|
2020-12-01 04:45:32 +08:00
|
|
|
|
|
|
|
scope(controller: :gradebooks) do
|
|
|
|
put "courses/:course_id/update_final_grade_overrides", action: "update_final_grade_overrides"
|
2021-11-18 03:33:16 +08:00
|
|
|
put "courses/:course_id/apply_score_to_ungraded_submissions", action: "apply_score_to_ungraded_submissions"
|
2020-12-01 04:45:32 +08:00
|
|
|
end
|
2021-08-25 23:36:38 +08:00
|
|
|
|
2022-03-08 08:35:34 +08:00
|
|
|
scope(controller: :course_paces) do
|
2022-04-08 00:00:38 +08:00
|
|
|
post "courses/:course_id/course_pacing", action: :create
|
|
|
|
get "courses/:course_id/course_pacing/new", action: :new
|
|
|
|
get "courses/:course_id/course_pacing/:id", action: :api_show
|
|
|
|
put "courses/:course_id/course_pacing/:id", action: :update
|
|
|
|
post "courses/:course_id/course_pacing/:id/publish", action: :publish
|
|
|
|
post "courses/:course_id/course_pacing/compress_dates", action: :compress_dates
|
2021-08-25 23:36:38 +08:00
|
|
|
end
|
2021-09-21 10:09:43 +08:00
|
|
|
|
2022-02-16 00:10:48 +08:00
|
|
|
scope(controller: :blackout_dates) do
|
|
|
|
get "courses/:course_id/blackout_dates", action: :index
|
|
|
|
get "accounts/:account_id/blackout_dates", action: :index
|
|
|
|
post "courses/:course_id/blackout_dates", action: :create
|
|
|
|
post "accounts/:account_id/blackout_dates", action: :create
|
|
|
|
get "courses/:course_id/blackout_dates/new", action: :new
|
|
|
|
get "accounts/:account_id/blackout_dates/new", action: :new
|
|
|
|
get "courses/:course_id/blackout_dates/:id", action: :show
|
|
|
|
get "accounts/:account_id/blackout_dates/:id", action: :show
|
|
|
|
put "courses/:course_id/blackout_dates/:id", action: :update
|
|
|
|
put "accounts/:account_id/blackout_dates/:id", action: :update
|
|
|
|
delete "courses/:course_id/blackout_dates/:id", action: :destroy
|
|
|
|
delete "accounts/:account_id/blackout_dates/:id", action: :destroy
|
2022-03-29 06:10:41 +08:00
|
|
|
put "courses/:course_id/blackout_dates", action: :bulk_update
|
2022-02-16 00:10:48 +08:00
|
|
|
end
|
|
|
|
|
2021-09-21 10:09:43 +08:00
|
|
|
scope(controller: :eportfolios_api) do
|
|
|
|
get "users/:user_id/eportfolios", action: :index, as: :eportfolios
|
|
|
|
get "eportfolios/:id", action: :show
|
|
|
|
delete "eportfolios/:id", action: :delete
|
|
|
|
get "eportfolios/:eportfolio_id/pages", action: :pages, as: :eportfolio_pages
|
|
|
|
put "eportfolios/:eportfolio_id/moderate", action: :moderate
|
|
|
|
put "users/:user_id/eportfolios", action: :moderate_all
|
|
|
|
put "eportfolios/:eportfolio_id/restore", action: :restore
|
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|
|
|
|
|
2019-10-31 02:12:24 +08:00
|
|
|
# this is not a "normal" api endpoint in the sense that it is not documented or
|
2015-10-10 06:43:00 +08:00
|
|
|
# generally available to hosted customers. it also does not respect the normal
|
|
|
|
# pagination options; however, jobs_controller already accepts `limit` and `offset`
|
|
|
|
# paramaters and defines a sane default limit
|
|
|
|
ApiRouteSet::V1.draw(self) do
|
|
|
|
scope(controller: :jobs) do
|
|
|
|
get "jobs", action: :index
|
|
|
|
get "jobs/:id", action: :show
|
|
|
|
post "jobs/batch_update", action: :batch_update
|
|
|
|
end
|
2022-02-23 07:38:46 +08:00
|
|
|
|
|
|
|
# jobs_v2 actually does do regular pagination, but the comments above
|
|
|
|
# otherwise still apply
|
|
|
|
scope(controller: :jobs_v2) do
|
2022-03-16 04:21:09 +08:00
|
|
|
get "jobs2/:bucket/by_:group/search", action: :search
|
2022-03-01 05:05:06 +08:00
|
|
|
get "jobs2/:bucket/by_:group", action: :grouped_info, as: :jobs_grouped_info
|
2022-03-24 05:10:30 +08:00
|
|
|
get "jobs2/:bucket", action: :list, as: :jobs_list, constraints: { bucket: /running|queued|future|failed/ }
|
|
|
|
get "jobs2/:id", action: :lookup, constraints: { id: /\d+/ }
|
2022-02-23 07:38:46 +08:00
|
|
|
end
|
2021-09-22 05:21:00 +08:00
|
|
|
end
|
2015-10-10 06:43:00 +08:00
|
|
|
|
2012-03-21 06:08:20 +08:00
|
|
|
# this is not a "normal" api endpoint in the sense that it is not documented
|
|
|
|
# or called directly, it's used as the redirect in the file upload process
|
|
|
|
# for local files. it also doesn't use the normal oauth authentication
|
|
|
|
# system, so we can't put it in the api uri namespace.
|
2014-09-23 02:52:41 +08:00
|
|
|
post "files_api" => "files#api_create", :as => :api_v1_files_create
|
2021-11-25 09:05:50 +08:00
|
|
|
|
2015-04-02 00:06:16 +08:00
|
|
|
get "login/oauth2/auth" => "oauth2_provider#auth", :as => :oauth2_auth
|
|
|
|
post "login/oauth2/token" => "oauth2_provider#token", :as => :oauth2_token
|
|
|
|
get "login/oauth2/confirm" => "oauth2_provider#confirm", :as => :oauth2_auth_confirm
|
|
|
|
post "login/oauth2/accept" => "oauth2_provider#accept", :as => :oauth2_auth_accept
|
|
|
|
get "login/oauth2/deny" => "oauth2_provider#deny", :as => :oauth2_auth_deny
|
|
|
|
delete "login/oauth2/token" => "oauth2_provider#destroy", :as => :oauth2_logout
|
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-05 03:20:31 +08:00
|
|
|
get "login/oauth2/jwks" => "security#jwks", :as => :oauth2_jwks
|
2013-06-15 01:09:41 +08:00
|
|
|
|
|
|
|
ApiRouteSet.draw(self, "/api/lti/v1") do
|
2014-09-23 02:52:41 +08:00
|
|
|
post "tools/:tool_id/grade_passback", controller: :lti_api, action: :grade_passback, as: "lti_grade_passback_api"
|
|
|
|
post "tools/:tool_id/ext_grade_passback", controller: :lti_api, action: :legacy_grade_passback, as: "blti_legacy_grade_passback_api"
|
2014-10-16 04:47:36 +08:00
|
|
|
post "xapi/:token", controller: :lti_api, action: :xapi_service, as: "lti_xapi"
|
2015-01-28 04:33:11 +08:00
|
|
|
post "caliper/:token", controller: :lti_api, action: :caliper_service, as: "lti_caliper"
|
2014-09-25 06:12:22 +08:00
|
|
|
post "logout_service/:token", controller: :lti_api, action: :logout_service, as: "lti_logout_service"
|
2015-07-28 06:15:34 +08:00
|
|
|
post "turnitin/outcomes_placement/:tool_id", controller: :lti_api, action: :turnitin_outcomes_placement, as: "lti_turnitin_outcomes_placement"
|
2011-11-01 05:48:30 +08:00
|
|
|
end
|
|
|
|
|
2014-05-24 06:30:13 +08:00
|
|
|
ApiRouteSet.draw(self, "/api/lti") do
|
2018-09-11 05:32:37 +08:00
|
|
|
scope(controller: "lti/tool_configurations_api") do
|
2018-09-21 09:26:49 +08:00
|
|
|
put "developer_keys/:developer_key_id/tool_configuration", action: :update
|
2018-09-28 22:54:49 +08:00
|
|
|
post "accounts/:account_id/developer_keys/tool_configuration", action: :create
|
2018-09-11 05:32:37 +08:00
|
|
|
delete "developer_keys/:developer_key_id/tool_configuration", action: :destroy
|
2019-05-10 23:56:36 +08:00
|
|
|
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[account course].each do |context|
|
2019-05-10 22:40:18 +08:00
|
|
|
get "#{context}s/:#{context}_id/developer_keys/:developer_key_id/tool_configuration", action: :show, as: "#{context}_show_tool_configuration"
|
2019-05-10 23:56:36 +08:00
|
|
|
end
|
2018-09-11 05:32:37 +08:00
|
|
|
end
|
|
|
|
|
LTI2 API webhook subscription service
Fixes: PLAT-2129 PLAT-2126
Test Plan:
- Verify you can create and retrieve a TCP
with the new subscription service and
capabilities.
- Install an LTI2 tool using the split secret
capability. The tool's security contract
should use the new webhook service.
Example security contract:
"tp_half_shared_secret"=>
"873f5...",
"tool_service"=>
[{"@type"=>"RestServiceProfile",
"service"=>"vnd.Canvas.webhooksSubscription",
"action"=>["GET", "POST"]}]}
- Do a POST request to /api/lti/subscriptions with the
following body:
{
"subscription":{
"EventTypes":[
"submission_created"
],
"ContextType":"course",
"ContextId":<valid course id here>,
"Format":"live-event",
"TransportType":"sqs",
"TransportMetadata":{
"Url":"http://sqs.docker"
}
}
}
- Verify a 401 is returned
- Using https://docs.google.com/document/d
/12x6Peif-I-0zvl2uMv2JVbQdZumGGqMtspWKYTqlL9o/edit
attempt to create each subscription type (in bold)
and verify 401s are returned in each case.
- Using the same document, verify that adding one of
the capabilities listed under a subscription types
allows you to create the subscription
- Verify that using the vnd.instructure.webhooks.root_account.all
capability allows you to create any subscription.
- Install an LTI2 tool in a course
- Attempt to create a subscription in another course and
verify a 401 is given.
Change-Id: I322e4bb2c49209afdc6f0a3c3a8b5c73e339996e
Reviewed-on: https://gerrit.instructure.com/102272
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Andrew Butterfield <abutterfield@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
2017-02-14 23:55:06 +08:00
|
|
|
scope(controller: "lti/subscriptions_api") do
|
|
|
|
post "subscriptions", action: :create
|
2017-02-24 00:04:22 +08:00
|
|
|
delete "subscriptions/:id", action: :destroy
|
2017-02-27 23:41:21 +08:00
|
|
|
get "subscriptions/:id", action: :show
|
2017-02-27 23:41:21 +08:00
|
|
|
put "subscriptions/:id", action: :update
|
2017-02-28 03:28:59 +08:00
|
|
|
get "subscriptions", action: :index
|
LTI2 API webhook subscription service
Fixes: PLAT-2129 PLAT-2126
Test Plan:
- Verify you can create and retrieve a TCP
with the new subscription service and
capabilities.
- Install an LTI2 tool using the split secret
capability. The tool's security contract
should use the new webhook service.
Example security contract:
"tp_half_shared_secret"=>
"873f5...",
"tool_service"=>
[{"@type"=>"RestServiceProfile",
"service"=>"vnd.Canvas.webhooksSubscription",
"action"=>["GET", "POST"]}]}
- Do a POST request to /api/lti/subscriptions with the
following body:
{
"subscription":{
"EventTypes":[
"submission_created"
],
"ContextType":"course",
"ContextId":<valid course id here>,
"Format":"live-event",
"TransportType":"sqs",
"TransportMetadata":{
"Url":"http://sqs.docker"
}
}
}
- Verify a 401 is returned
- Using https://docs.google.com/document/d
/12x6Peif-I-0zvl2uMv2JVbQdZumGGqMtspWKYTqlL9o/edit
attempt to create each subscription type (in bold)
and verify 401s are returned in each case.
- Using the same document, verify that adding one of
the capabilities listed under a subscription types
allows you to create the subscription
- Verify that using the vnd.instructure.webhooks.root_account.all
capability allows you to create any subscription.
- Install an LTI2 tool in a course
- Attempt to create a subscription in another course and
verify a 401 is given.
Change-Id: I322e4bb2c49209afdc6f0a3c3a8b5c73e339996e
Reviewed-on: https://gerrit.instructure.com/102272
Tested-by: Jenkins
QA-Review: August Thornton <august@instructure.com>
Reviewed-by: Andrew Butterfield <abutterfield@instructure.com>
Product-Review: Weston Dransfield <wdransfield@instructure.com>
2017-02-14 23:55:06 +08:00
|
|
|
end
|
|
|
|
|
2017-09-22 03:52:17 +08:00
|
|
|
scope(controller: "lti/users_api") do
|
|
|
|
get "users/:id", action: :show
|
2018-01-23 03:48:17 +08:00
|
|
|
get "groups/:group_id/users", action: :group_index, as: "lti_user_group_index"
|
2017-09-22 03:52:17 +08:00
|
|
|
end
|
|
|
|
|
2019-06-01 00:36:59 +08:00
|
|
|
scope(controller: "lti/plagiarism_assignments_api") do
|
2017-11-17 03:42:37 +08:00
|
|
|
get "assignments/:assignment_id", action: :show
|
|
|
|
end
|
|
|
|
|
2018-11-09 03:53:34 +08:00
|
|
|
scope(controller: "lti/ims/authentication") do
|
|
|
|
post "authorize_redirect", action: :authorize_redirect
|
2019-01-08 23:38:58 +08:00
|
|
|
get "authorize_redirect", action: :authorize_redirect
|
2018-11-09 03:53:34 +08:00
|
|
|
get "authorize", action: :authorize, as: :lti_1_3_authorization
|
|
|
|
end
|
|
|
|
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2014-05-24 06:30:13 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id"
|
2018-12-06 01:45:16 +08:00
|
|
|
|
2017-03-29 02:05:34 +08:00
|
|
|
post "#{prefix}/authorize", controller: "lti/ims/authorization", action: :authorize, as: "#{context}_lti_oauth2_authorize"
|
2017-02-10 09:43:04 +08:00
|
|
|
get "#{prefix}/tool_consumer_profile(/:tool_consumer_profile_id)", controller: "lti/ims/tool_consumer_profile",
|
2015-10-29 05:58:10 +08:00
|
|
|
action: "show", as: "#{context}_tool_consumer_profile"
|
|
|
|
post "#{prefix}/tool_proxy", controller: "lti/ims/tool_proxy", action: :re_reg,
|
|
|
|
as: "re_reg_#{context}_lti_tool_proxy", constraints: Lti::ReRegConstraint.new
|
|
|
|
post "#{prefix}/tool_proxy", controller: "lti/ims/tool_proxy", action: :create,
|
|
|
|
as: "create_#{context}_lti_tool_proxy"
|
2015-08-12 00:38:06 +08:00
|
|
|
get "#{prefix}/jwt_token", controller: "external_tools", action: :jwt_token
|
2017-10-07 12:30:48 +08:00
|
|
|
get "tool_proxy/:tool_proxy_guid/#{prefix}/tool_setting", controller: "lti/ims/tool_setting", action: :show, as: "show_#{context}_tool_setting"
|
|
|
|
get "tool_proxy/:tool_proxy_guid/#{prefix}/resource_link_id/:resource_link_id/tool_setting", controller: "lti/ims/tool_setting", action: :show, as: "show_#{context}_resource_link_id_tool_setting"
|
|
|
|
put "tool_proxy/:tool_proxy_guid/#{prefix}/tool_setting", controller: "lti/ims/tool_setting", action: :update, as: "update_#{context}_tool_setting"
|
|
|
|
put "tool_proxy/:tool_proxy_guid/#{prefix}/resource_link_id/:resource_link_id/tool_setting", controller: "lti/ims/tool_setting", action: :update, as: "update_#{context}_update_resource_link_id_tool_setting"
|
2014-05-24 06:30:13 +08:00
|
|
|
end
|
2014-08-27 03:50:51 +08:00
|
|
|
# Tool Setting Services
|
2017-10-07 12:30:48 +08:00
|
|
|
get "tool_settings/:tool_setting_id", controller: "lti/ims/tool_setting", action: :show, as: :show_lti_tool_settings
|
|
|
|
get "tool_proxy/:tool_proxy_guid/tool_setting", controller: "lti/ims/tool_setting", action: :show, as: :show_tool_proxy_lti_tool_settings
|
|
|
|
put "tool_settings/:tool_setting_id", controller: "lti/ims/tool_setting", action: :update, as: :update_lti_tool_settings
|
|
|
|
put "tool_proxy/:tool_proxy_guid/tool_setting", controller: "lti/ims/tool_setting", action: :update, as: :update_tool_proxy_lti_tool_settings
|
2014-08-27 03:50:51 +08:00
|
|
|
|
|
|
|
# Tool Proxy Services
|
2014-12-10 04:38:16 +08:00
|
|
|
get "tool_proxy/:tool_proxy_guid", controller: "lti/ims/tool_proxy", action: :show, as: "show_lti_tool_proxy"
|
2016-03-08 01:20:29 +08:00
|
|
|
|
|
|
|
# Membership Service
|
2016-04-22 01:13:53 +08:00
|
|
|
get "courses/:course_id/membership_service", controller: "lti/membership_service", action: :course_index, as: :course_membership_service
|
|
|
|
get "groups/:group_id/membership_service", controller: "lti/membership_service", action: :group_index, as: :group_membership_service
|
2017-01-21 05:29:32 +08:00
|
|
|
|
2017-03-11 06:53:20 +08:00
|
|
|
# Submissions Service
|
|
|
|
scope(controller: "lti/submissions_api") do
|
|
|
|
get "assignments/:assignment_id/submissions/:submission_id", action: :show
|
|
|
|
get "assignments/:assignment_id/submissions/:submission_id/history", action: :history
|
2017-03-14 20:32:23 +08:00
|
|
|
get "assignments/:assignment_id/submissions/:submission_id/attachment/:attachment_id", action: :attachment, as: :lti_submission_attachment_download
|
2017-03-11 06:53:20 +08:00
|
|
|
end
|
|
|
|
|
2017-01-21 05:29:32 +08:00
|
|
|
# Originality Report Service
|
|
|
|
scope(controller: "lti/originality_reports_api") do
|
|
|
|
post "assignments/:assignment_id/submissions/:submission_id/originality_report", action: :create
|
|
|
|
put "assignments/:assignment_id/submissions/:submission_id/originality_report/:id", action: :update
|
2017-08-17 23:44:18 +08:00
|
|
|
put "assignments/:assignment_id/files/:file_id/originality_report", action: :update
|
2017-01-21 05:29:32 +08:00
|
|
|
get "assignments/:assignment_id/submissions/:submission_id/originality_report/:id", action: :show
|
2017-08-17 23:44:18 +08:00
|
|
|
get "assignments/:assignment_id/files/:file_id/originality_report", action: :show
|
2017-01-21 05:29:32 +08:00
|
|
|
end
|
2017-03-11 06:53:20 +08:00
|
|
|
|
2020-04-11 06:21:27 +08:00
|
|
|
# Line Item Service (LTI AGS)
|
2018-01-24 01:03:35 +08:00
|
|
|
scope(controller: "lti/ims/line_items") do
|
|
|
|
post "courses/:course_id/line_items", action: :create, as: :lti_line_item_create
|
|
|
|
get "courses/:course_id/line_items/:id", action: :show, as: :lti_line_item_show
|
2018-02-10 05:29:03 +08:00
|
|
|
get "courses/:course_id/line_items", action: :index, as: :lti_line_item_index
|
2018-01-24 01:03:35 +08:00
|
|
|
put "courses/:course_id/line_items/:id", action: :update, as: :lti_line_item_edit
|
|
|
|
delete "courses/:course_id/line_items/:id", action: :destroy, as: :lti_line_item_delete
|
|
|
|
end
|
2018-01-30 06:45:38 +08:00
|
|
|
|
2020-04-11 06:21:27 +08:00
|
|
|
# Scores Service (LTI AGS)
|
2018-01-30 06:45:38 +08:00
|
|
|
scope(controller: "lti/ims/scores") do
|
|
|
|
post "courses/:course_id/line_items/:line_item_id/scores", action: :create, as: :lti_result_create
|
|
|
|
end
|
2018-01-24 06:45:13 +08:00
|
|
|
|
2021-02-19 05:04:01 +08:00
|
|
|
# Result Service (LTI AGS)
|
2018-01-24 06:45:13 +08:00
|
|
|
scope(controller: "lti/ims/results") do
|
|
|
|
get "courses/:course_id/line_items/:line_item_id/results/:id", action: :show, as: :lti_result_show
|
|
|
|
get "courses/:course_id/line_items/:line_item_id/results", action: :index
|
|
|
|
end
|
2018-06-19 03:31:55 +08:00
|
|
|
|
2021-02-19 05:04:01 +08:00
|
|
|
# Progress Service (LTI AGS)
|
|
|
|
scope(controller: "lti/ims/progress") do
|
|
|
|
get "courses/:course_id/progress/:id", action: :show, as: :lti_progress_show
|
|
|
|
end
|
|
|
|
|
2019-06-11 01:24:39 +08:00
|
|
|
# Public JWK Service
|
2019-05-18 01:46:07 +08:00
|
|
|
scope(controller: "lti/public_jwk") do
|
|
|
|
put "/developer_key/update_public_jwk", action: :update, as: :public_jwk_update
|
|
|
|
end
|
|
|
|
|
2020-04-29 19:00:03 +08:00
|
|
|
# Context External Tools Service
|
|
|
|
scope(controller: "lti/account_external_tools") do
|
|
|
|
post "/accounts/:account_id/external_tools", action: :create, as: :account_external_tools_create
|
|
|
|
get "/accounts/:account_id/external_tools/:external_tool_id", action: :show, as: :account_external_tools_show
|
|
|
|
get "/accounts/:account_id/external_tools", action: :index, as: :account_external_tools_index
|
|
|
|
delete "/accounts/:account_id/external_tools/:external_tool_id", action: :destroy, as: :account_external_tools_destroy
|
|
|
|
end
|
|
|
|
|
2019-08-22 01:21:07 +08:00
|
|
|
# Data Services Service
|
|
|
|
scope(controller: "lti/data_services") do
|
|
|
|
post "/accounts/:account_id/data_services", action: :create, as: :data_services_create
|
2019-08-24 00:37:12 +08:00
|
|
|
get "/accounts/:account_id/data_services/:id", action: :show, as: :data_services_show
|
2019-08-24 01:18:18 +08:00
|
|
|
put "/accounts/:account_id/data_services/:id", action: :update, as: :data_services_update
|
2019-08-23 07:44:31 +08:00
|
|
|
get "/accounts/:account_id/data_services", action: :index, as: :data_services_index
|
2019-08-31 03:30:34 +08:00
|
|
|
get "/accounts/:account_id/event_types", action: :event_types_index, as: :data_services_event_types
|
2019-08-24 01:42:38 +08:00
|
|
|
delete "/accounts/:account_id/data_services/:id", action: :destroy, as: :data_services_destroy
|
2019-08-22 01:21:07 +08:00
|
|
|
end
|
|
|
|
|
2020-03-11 07:11:46 +08:00
|
|
|
# Account Lookup service
|
|
|
|
scope(controller: "lti/account_lookup") do
|
|
|
|
get "/accounts/:account_id", action: :show
|
|
|
|
end
|
|
|
|
|
2018-09-18 08:08:52 +08:00
|
|
|
# Names and Roles Provisioning (NRPS) v2 Service
|
|
|
|
scope(controller: "lti/ims/names_and_roles") do
|
|
|
|
get "courses/:course_id/names_and_roles", controller: "lti/ims/names_and_roles", action: :course_index, as: :course_names_and_roles
|
|
|
|
get "groups/:group_id/names_and_roles", controller: "lti/ims/names_and_roles", action: :group_index, as: :group_names_and_roles
|
|
|
|
end
|
|
|
|
|
2018-06-19 03:31:55 +08:00
|
|
|
# Security
|
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-05 03:20:31 +08:00
|
|
|
scope(controller: "security") do
|
2018-06-19 03:31:55 +08:00
|
|
|
get "security/jwks", action: :jwks, as: :jwks_show
|
|
|
|
end
|
2019-09-25 09:30:37 +08:00
|
|
|
|
|
|
|
# Feature Flags
|
|
|
|
scope(controller: "lti/feature_flags") do
|
2021-11-18 06:07:40 +08:00
|
|
|
%w[course account].each do |context|
|
2019-09-25 09:30:37 +08:00
|
|
|
prefix = "#{context}s/:#{context}_id"
|
|
|
|
get "/#{prefix}/feature_flags/:feature", action: :show
|
|
|
|
end
|
|
|
|
end
|
2021-07-15 01:21:49 +08:00
|
|
|
|
|
|
|
# LTI Access Tokens (Site Admin only)
|
|
|
|
get "advantage_token", controller: "lti/token", action: :advantage_access_token, as: :lti_advantage_token_site_admin
|
2015-05-16 04:43:16 +08:00
|
|
|
end
|
2015-06-17 09:17:28 +08:00
|
|
|
|
|
|
|
ApiRouteSet.draw(self, "/api/sis") do
|
|
|
|
scope(controller: :sis_api) do
|
|
|
|
get "accounts/:account_id/assignments", action: "sis_assignments", as: :sis_account_assignments
|
|
|
|
get "courses/:course_id/assignments", action: "sis_assignments", as: :sis_course_assignments
|
|
|
|
end
|
2017-05-09 06:07:09 +08:00
|
|
|
scope(controller: :disable_post_to_sis_api) do
|
|
|
|
put "courses/:course_id/disable_post_to_sis", action: "disable_post_to_sis", as: :disable_post_to_sis_course_assignments
|
|
|
|
end
|
2015-06-17 09:17:28 +08:00
|
|
|
end
|
2011-02-01 09:57:29 +08:00
|
|
|
end
|