2020-10-27 00:50:13 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-04-28 04:01:09 +08:00
|
|
|
#
|
|
|
|
# Copyright (C) 2014 - 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-05-08 08:05:05 +08:00
|
|
|
require 'cgi'
|
|
|
|
require 'net/http'
|
|
|
|
require 'net/https'
|
|
|
|
require 'json'
|
|
|
|
|
2017-04-13 06:47:03 +08:00
|
|
|
require_dependency 'canvadocs/session'
|
2014-05-08 08:05:05 +08:00
|
|
|
module Canvadocs
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
extend CanvadocsHelper
|
2016-07-30 14:39:25 +08:00
|
|
|
RENDER_O365 = 'office_365'
|
|
|
|
RENDER_BOX = 'box_view'
|
2016-05-12 03:25:31 +08:00
|
|
|
RENDER_CROCODOC = 'crocodoc'
|
2016-07-30 14:39:25 +08:00
|
|
|
RENDER_PDFJS = 'pdfjs'
|
2016-05-12 03:25:31 +08:00
|
|
|
|
2014-05-08 08:05:05 +08:00
|
|
|
# Public: A small ruby client that wraps the Box View api.
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# Canvadocs::API.new(:token => <token>)
|
|
|
|
class API
|
|
|
|
attr_accessor :token, :http, :url
|
|
|
|
|
|
|
|
# Public: The base part of the url that is the same for all api requests.
|
|
|
|
BASE_URL = "https://view-api.box.com/1"
|
|
|
|
|
|
|
|
# Public: Initialize a Canvadocs api object
|
|
|
|
#
|
|
|
|
# opts - A hash of options with which to initialize the object
|
|
|
|
# :token - The api token to use to authenticate requests. Required.
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
# crocodoc = Canvadocs::API.new(:token => <token>)
|
|
|
|
# # => <Canvadocs::API:<id>>
|
|
|
|
def initialize(opts)
|
|
|
|
self.token = opts[:token]
|
|
|
|
|
2014-06-24 05:48:15 +08:00
|
|
|
_, @url = CanvasHttp.validate_url(opts[:base_url] || BASE_URL)
|
|
|
|
@http = CanvasHttp.connection_for_uri(@url)
|
2014-05-08 08:05:05 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
# -- Documents --
|
|
|
|
|
|
|
|
# Public: Create a document with the file at the given url.
|
|
|
|
#
|
|
|
|
# obj - a url string
|
2015-07-15 05:10:08 +08:00
|
|
|
# params - other post params
|
2014-05-08 08:05:05 +08:00
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# upload("http://www.example.com/test.doc")
|
|
|
|
# # => { "id": 1234, "status": "queued" }
|
|
|
|
#
|
|
|
|
# Returns a hash containing the document's id and status
|
2015-07-15 05:10:08 +08:00
|
|
|
def upload(obj, extra_params = {})
|
2014-05-08 08:05:05 +08:00
|
|
|
params = if obj.is_a?(File)
|
2016-07-07 02:44:45 +08:00
|
|
|
{ file: obj }.merge(extra_params)
|
2014-05-08 08:05:05 +08:00
|
|
|
raise Canvadocs::Error, "TODO: support raw files"
|
|
|
|
else
|
2016-07-07 02:44:45 +08:00
|
|
|
{ url: obj.to_s }.merge(extra_params)
|
2014-05-08 08:05:05 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
raw_body = api_call(:post, "documents", params)
|
|
|
|
JSON.parse(raw_body)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Public: Delete a document.
|
|
|
|
#
|
|
|
|
# id - a single document id to delete
|
|
|
|
#
|
|
|
|
def delete(id)
|
|
|
|
api_call(:delete, "documents/#{id}")
|
|
|
|
end
|
|
|
|
|
|
|
|
# -- Sessions --
|
|
|
|
|
|
|
|
# Public: Create a session, which is a unique id with which you can view
|
|
|
|
# the document. Sessions expire 60 minutes after they are generated.
|
|
|
|
#
|
|
|
|
# id - The id of the document for the session
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# session(1234)
|
|
|
|
# # => { "id": "CFAmd3Qjm_2ehBI7HyndnXKsDrQXJ7jHCuzcRv" }
|
|
|
|
#
|
|
|
|
# Returns a hash containing the session id
|
|
|
|
def session(document_id, opts={})
|
|
|
|
raw_body = api_call(:post, "sessions",
|
|
|
|
opts.merge(:document_id => document_id))
|
|
|
|
JSON.parse(raw_body)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Public: Get the url for the viewer for a session.
|
|
|
|
#
|
|
|
|
# session_id - The id of the session (see #session)
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
# view("CFAmd3Qjm_2ehBI7HyndnXKsDrQXJ7jHCuzcRv_V4FAgbSmaBkF")
|
|
|
|
# # => https://view-api.box.com/1/sessions/#{session_id}/view?theme=dark"
|
|
|
|
#
|
|
|
|
# Returns a url string for viewing the session
|
|
|
|
def view(session_id)
|
2015-04-28 00:55:43 +08:00
|
|
|
"#{@url}/sessions/#{session_id}/view?theme=dark"
|
2014-05-08 08:05:05 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# -- API Glue --
|
|
|
|
|
|
|
|
# Internal: Setup the api call, format the parameters, send the request,
|
|
|
|
# parse the response and return it.
|
|
|
|
#
|
|
|
|
# method - The http verb to use, currently :get or :post
|
|
|
|
# endpoint - The api endpoint to hit. this is the part after
|
|
|
|
# +base_url+. please do not include a beginning slash.
|
|
|
|
# params - Parameters to send with the api call
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# api_call(:post,
|
|
|
|
# "documents",
|
|
|
|
# { url: "http://www.example.com/test.doc" })
|
|
|
|
# # => { "id": 1234 }
|
|
|
|
#
|
|
|
|
# Returns the json parsed response body of the call
|
|
|
|
def api_call(method, endpoint, params={})
|
|
|
|
# dispatch to the right method, with the full path (/api/v2 + endpoint)
|
|
|
|
request = self.send("format_#{method}", "#{@url.path}/#{endpoint}", params)
|
|
|
|
request["Authorization"] = "Token #{token}"
|
|
|
|
response = @http.request(request)
|
|
|
|
|
|
|
|
unless response.code =~ /\A20./
|
2020-11-07 02:15:54 +08:00
|
|
|
err_message = "HTTP Error #{response.code}: #{response.body}"
|
|
|
|
klass = Canvadocs::HttpError
|
2020-12-11 03:01:30 +08:00
|
|
|
klass = Canvadocs::ServerError if response.code.to_s == "500"
|
2020-11-07 02:15:54 +08:00
|
|
|
klass = Canvadocs::BadGateway if response.code.to_s == "502"
|
|
|
|
klass = Canvadocs::BadRequest if response.code.to_s == "400"
|
|
|
|
raise klass, err_message
|
2014-05-08 08:05:05 +08:00
|
|
|
end
|
|
|
|
response.body
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# Internal: Format and create a Net::HTTP get request, with query
|
|
|
|
# parameters.
|
|
|
|
#
|
|
|
|
# path - the path to get
|
|
|
|
# params - the params to add as query params to the path
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# format_get("/api/v2/document/status",
|
|
|
|
# { :token => <token>, :uuids => <uuids> })
|
|
|
|
# # => <Net::HTTP::Get:<id>> for
|
|
|
|
# # "/api/v2/document/status?token=<token>&uuids=<uuids>"
|
|
|
|
#
|
|
|
|
# Returns a Net::HTTP::Get object for the path with query params
|
|
|
|
def format_get(path, params)
|
|
|
|
query = params.map { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join("&")
|
|
|
|
Net::HTTP::Get.new("#{path}?#{query}")
|
|
|
|
end
|
|
|
|
|
|
|
|
# Internal: Format and create a Net::HTTP post request, with form
|
|
|
|
# parameters.
|
|
|
|
#
|
|
|
|
# path - the path to get
|
|
|
|
# params - the params to add as form params to the path
|
|
|
|
#
|
|
|
|
# Examples
|
|
|
|
#
|
|
|
|
# format_post("/api/v2/document/upload",
|
|
|
|
# { :token => <token>, :url => <url> })
|
|
|
|
# # => <Net::HTTP::Post:<id>>
|
|
|
|
#
|
|
|
|
# Returns a Net::HTTP::Post object for the path with json-formatted params
|
|
|
|
def format_post(path, params)
|
|
|
|
Net::HTTP::Post.new(path).tap { |req|
|
|
|
|
req["Content-Type"] = "application/json"
|
|
|
|
req.body = params.to_json
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Error < StandardError; end
|
2020-11-07 02:15:54 +08:00
|
|
|
class HttpError < Error; end
|
2020-12-11 03:01:30 +08:00
|
|
|
class ServerError < HttpError; end
|
2020-11-07 02:15:54 +08:00
|
|
|
class BadGateway < HttpError; end
|
|
|
|
class BadRequest < HttpError; end
|
2014-05-08 08:05:05 +08:00
|
|
|
|
|
|
|
def self.config
|
|
|
|
PluginSetting.settings_for_plugin(:canvadocs)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.enabled?
|
|
|
|
!!config
|
|
|
|
end
|
2015-07-15 05:10:08 +08:00
|
|
|
|
|
|
|
def self.annotations_supported?
|
2015-09-05 04:16:48 +08:00
|
|
|
enabled? && Canvas::Plugin.value_to_boolean(config["annotations_supported"])
|
2015-07-15 05:10:08 +08:00
|
|
|
end
|
2017-04-13 06:47:03 +08:00
|
|
|
|
|
|
|
# annotations_supported? calls enabled?
|
|
|
|
def self.hijack_crocodoc_sessions?
|
|
|
|
annotations_supported? && Canvas::Plugin.value_to_boolean(config["hijack_crocodoc_sessions"])
|
|
|
|
end
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
|
2018-09-18 22:55:53 +08:00
|
|
|
def self.user_session_params(current_user, attachment: nil, submission: nil)
|
|
|
|
if submission.nil?
|
|
|
|
return {} if attachment.nil?
|
|
|
|
submission = Submission.find_by(
|
|
|
|
id: AttachmentAssociation.where(context_type: 'Submission', attachment: attachment).select(:context_id)
|
|
|
|
)
|
|
|
|
return {} if submission.nil?
|
|
|
|
end
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
assignment = submission.assignment
|
|
|
|
enrollments = assignment.course.enrollments.index_by(&:user_id)
|
|
|
|
session_params = current_user_session_params(submission, current_user, enrollments)
|
2020-07-22 23:40:13 +08:00
|
|
|
|
|
|
|
# Graders may not have access to other graders' annotations if the
|
|
|
|
# assignment is set that way.
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
if assignment.moderated_grading?
|
|
|
|
session_params[:user_filter] = moderated_grading_user_filter(submission, current_user, enrollments)
|
|
|
|
session_params[:restrict_annotations_to_user_filter] = true
|
|
|
|
elsif assignment.anonymize_students?
|
|
|
|
session_params[:user_filter] = anonymous_unmoderated_user_filter(submission, current_user, enrollments)
|
|
|
|
session_params[:restrict_annotations_to_user_filter] = current_user.id == submission.user_id
|
|
|
|
end
|
|
|
|
|
2020-07-22 23:40:13 +08:00
|
|
|
# Set visibility for students and peer reviewers.
|
|
|
|
if !submission.user_can_read_grade?(current_user)
|
|
|
|
session_params[:restrict_annotations_to_user_filter] = true
|
|
|
|
session_params[:user_filter] ||= [
|
|
|
|
user_filter_entry(
|
|
|
|
current_user,
|
|
|
|
submission,
|
|
|
|
role: canvadocs_user_role(submission.assignment.course, current_user, enrollments),
|
|
|
|
anonymize: false
|
|
|
|
)
|
|
|
|
]
|
|
|
|
|
|
|
|
if assignment.peer_reviews? && submission.user == current_user
|
|
|
|
session_params[:user_filter] = session_params[:user_filter] | peer_review_user_filter(submission, current_user, enrollments)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
session_params
|
|
|
|
end
|
|
|
|
|
|
|
|
class << self
|
|
|
|
private
|
|
|
|
|
|
|
|
def current_user_session_params(submission, current_user, enrollments)
|
|
|
|
# Always include the current user's anonymous ID and real ID, regardless
|
|
|
|
# of the settings for the current assignment
|
|
|
|
current_user_params = {
|
|
|
|
user: current_user,
|
|
|
|
user_id: canvadocs_user_id(current_user),
|
|
|
|
user_role: canvadocs_user_role(submission.assignment.course, current_user, enrollments),
|
|
|
|
user_name: canvadocs_user_name(current_user)
|
|
|
|
}
|
|
|
|
|
|
|
|
# Not calling submission.anonymous_identities here because we want to include
|
|
|
|
# anonymous_ids for moderation_graders that have not yet taken a slot
|
|
|
|
anonymous_id = if submission.user_id == current_user.id
|
|
|
|
submission.anonymous_id
|
|
|
|
elsif submission.assignment.moderated_grading?
|
|
|
|
submission.assignment.moderation_graders.find_by(user: current_user)&.anonymous_id
|
|
|
|
end
|
|
|
|
|
|
|
|
current_user_params[:user_anonymous_id] = anonymous_id if anonymous_id
|
|
|
|
current_user_params
|
|
|
|
end
|
|
|
|
|
2020-07-22 23:40:13 +08:00
|
|
|
def peer_review_user_filter(submission, current_user, enrollments)
|
|
|
|
assessors = User.where(id: submission.assessment_requests.pluck(:assessor_id)).to_a
|
|
|
|
|
|
|
|
assessors.push(current_user).map do |assessor|
|
|
|
|
user_filter_entry(
|
|
|
|
assessor,
|
|
|
|
submission,
|
|
|
|
role: canvadocs_user_role(submission.assignment.course, assessor, enrollments),
|
|
|
|
anonymize: false
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
def moderated_grading_user_filter(submission, current_user, enrollments)
|
2020-09-14 23:59:32 +08:00
|
|
|
submission.moderation_allow_list_for_user(current_user).map do |user|
|
pass user-related params to docviewer
When talking to DocViewer, include relevant data for the current user as
well as the filter of users whose comments should be shown. This commit
enables functionality for anonymous annotations.
closes GRADE-1427
closes GRADE-1456
Test Plan 1: Moderated Assignments
1. Create a moderated assignment and allow for at least two provisional
graders in addition to the final grader. Then, leave at least one
annotation and one comment per provisional grader, final grader, and
the student.
2. When "Graders cannot view student names" is checked, verify that
no instructor or admin can see the students identity on annotaions.
Instead, the student's name should show up simply as 'Student'.
3. When "Graders cannot view each other's names" is checked, verify that
non-admin, non-final-grader provisional graders cannot see each
other's names on annotations. Instead, they should see a generic
grader name such as "Grader 1".
4. When "Final grader can view other grader names" is unchecked, verify
the final grader cannot view the other graders' names on annotations.
Instead, they should see a generic grader name such as "Grader 1".
5. Smoke test the settings listed in steps 2, 3, and 4 in various
combinations of being on or off.
6. While the assignment is still in moderation, verify the student can
only see their own annotations.
7. When grades are published for the assignment, verify the assignment
no longer shows any anonymous annotations.
Test Plan 2: Anonymous, Not Moderated Assignments
1. Create an anonymous assignment. Submit to the assignment as a student
and leave some annotations as the student and as an instructor.
2. Verify the student can only see their own annotations while the
assignment is still muted.
3. An instructor *should* be able to see any annotations made by an
instructor, but DocViewer has not implemented this functionality
on their side yet. As a result, just verify that an instructor
can see the student's annotations but they are anonymized while
the assignment is muted.
4. Unmute the assignment and verify the annotations are no longer
anonymized, and the student can now see annotations from instructors.
Test Plan 3: Normal, Not Anonymous Assignments
1. Do a general smoke test of not anonymous, not moderated assignments
to verify annotations still show up as expected.
Change-Id: I181a6ace3c00ca93ab8e6c7608a034b521ed78b7
Reviewed-on: https://gerrit.instructure.com/161486
Reviewed-by: Derek Bender <djbender@instructure.com>
Tested-by: Jenkins
Reviewed-by: Keith T. Garner <kgarner@instructure.com>
QA-Review: Derek Bender <djbender@instructure.com>
Product-Review: Keith T. Garner <kgarner@instructure.com>
2018-08-11 02:52:14 +08:00
|
|
|
user_filter_entry(
|
|
|
|
user,
|
|
|
|
submission,
|
|
|
|
role: canvadocs_user_role(submission.assignment.course, user, enrollments),
|
|
|
|
anonymize: anonymize_user_for_moderated_assignment?(user, current_user, submission),
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def anonymous_unmoderated_user_filter(submission, current_user, enrollments)
|
|
|
|
[user_filter_entry(
|
|
|
|
submission.user,
|
|
|
|
submission,
|
|
|
|
role: canvadocs_user_role(submission.assignment.course, submission.user, enrollments),
|
|
|
|
anonymize: current_user.id != submission.user_id
|
|
|
|
)]
|
|
|
|
end
|
|
|
|
|
|
|
|
def anonymize_user_for_moderated_assignment?(user, current_user, submission)
|
|
|
|
# You never see your own annotations anonymized, and students never see anonymized annotations from anyone.
|
|
|
|
return false if current_user == user || current_user == submission.user
|
|
|
|
|
|
|
|
if user == submission.user
|
|
|
|
submission.assignment.anonymize_students?
|
|
|
|
else
|
|
|
|
!submission.assignment.can_view_other_grader_identities?(current_user)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def user_filter_entry(user, submission, role:, anonymize:)
|
|
|
|
if anonymize
|
|
|
|
id = submission.anonymous_identities.dig(user.id, :id).to_s
|
|
|
|
type = 'anonymous'
|
|
|
|
name = submission.anonymous_identities.dig(user.id, :name)
|
|
|
|
else
|
|
|
|
id = user.global_id.to_s
|
|
|
|
type = 'real'
|
|
|
|
name = canvadocs_user_name(user)
|
|
|
|
end
|
|
|
|
|
|
|
|
{ id: id, type: type, role: role, name: name }
|
|
|
|
end
|
|
|
|
end
|
2014-05-08 08:05:05 +08:00
|
|
|
end
|