canvas-lms/lib/canvadocs.rb

350 lines
12 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
#
# 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/>.
require 'cgi'
require 'net/http'
require 'net/https'
require 'json'
require_dependency 'canvadocs/session'
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
Include pdfjs in preferred_plugins array Instead of sending a separate param to canvadocs for pdfjs as a preferred plugin, just put it in the preferred_plugins array (which used to be called preferred_renders) Refs CNVS-30582 Test Plan: - This is very difficult to test manually, particularly without changing any code. The reason for this is that canvadocs doesn't currently do anything with the pdfjs preferred plugin so you can't just check for that behavior. However, this is something you can do even tho it isn't ideal (and this is how I tested this patch in development): - get canvas working with a canvadocs instance on which you can modify code. By modifying the canvadocs instead of the canvas, the integrity of this patch is maintained for test purposes. - In the canvadocs session controller (app/controllers/session_controller.js), add a log statement to display what comes in in the body of the request. Something like: - console.log('Request body: ') - console.dir(req.body) - Submit an assignment to a course as a student. - As a teacher, open speedgrader from that assignment. This will cause a new canvadocs viewing session to be created. - In the console output of the canvadocs instance, see that the body did not include a preferred_plugin of pdfjs. - Toggle the feature flag to enable new annotations. - Repeat opening speedgrader but this time observe that the body includes pdfjs in the list of preferred_plugins. Change-Id: Ie3e16e1331fcdd757e96888f033e8341e7d6a0bc Reviewed-on: https://gerrit.instructure.com/86549 Tested-by: Jenkins QA-Review: Caleb Guanzon <cguanzon@instructure.com> Reviewed-by: Brad Horrocks <bhorrocks@instructure.com> Product-Review: Benjamin Porter <bporter@instructure.com>
2016-07-30 14:39:25 +08:00
RENDER_O365 = 'office_365'
RENDER_BOX = 'box_view'
RENDER_CROCODOC = 'crocodoc'
Include pdfjs in preferred_plugins array Instead of sending a separate param to canvadocs for pdfjs as a preferred plugin, just put it in the preferred_plugins array (which used to be called preferred_renders) Refs CNVS-30582 Test Plan: - This is very difficult to test manually, particularly without changing any code. The reason for this is that canvadocs doesn't currently do anything with the pdfjs preferred plugin so you can't just check for that behavior. However, this is something you can do even tho it isn't ideal (and this is how I tested this patch in development): - get canvas working with a canvadocs instance on which you can modify code. By modifying the canvadocs instead of the canvas, the integrity of this patch is maintained for test purposes. - In the canvadocs session controller (app/controllers/session_controller.js), add a log statement to display what comes in in the body of the request. Something like: - console.log('Request body: ') - console.dir(req.body) - Submit an assignment to a course as a student. - As a teacher, open speedgrader from that assignment. This will cause a new canvadocs viewing session to be created. - In the console output of the canvadocs instance, see that the body did not include a preferred_plugin of pdfjs. - Toggle the feature flag to enable new annotations. - Repeat opening speedgrader but this time observe that the body includes pdfjs in the list of preferred_plugins. Change-Id: Ie3e16e1331fcdd757e96888f033e8341e7d6a0bc Reviewed-on: https://gerrit.instructure.com/86549 Tested-by: Jenkins QA-Review: Caleb Guanzon <cguanzon@instructure.com> Reviewed-by: Brad Horrocks <bhorrocks@instructure.com> Product-Review: Benjamin Porter <bporter@instructure.com>
2016-07-30 14:39:25 +08:00
RENDER_PDFJS = 'pdfjs'
# 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]
_, @url = CanvasHttp.validate_url(opts[:base_url] || BASE_URL)
@http = CanvasHttp.connection_for_uri(@url)
end
# -- Documents --
# Public: Create a document with the file at the given url.
#
# obj - a url string
# params - other post params
#
# Examples
#
# upload("http://www.example.com/test.doc")
# # => { "id": 1234, "status": "queued" }
#
# Returns a hash containing the document's id and status
def upload(obj, extra_params = {})
params = if obj.is_a?(File)
Add feature flag for canvadocs preferred plugin When the new canvadocs annotation stuff is ready, we want to be able to selectively turn it on to slowly roll it out. This adds a feature flag to the course that allows the new annotations to be enabled by course. There is also an account-level flag that allows the feature to be turned off globally per account, turned on, or simply "allowed" which delegates to the course. Refs CNVS-26668 Test Plan: - Open up the account settings and observe that there is a feature flag called 'New Annotations' - See that the feature flag can be either Off, Allowed, or On - Inside a course belonging to the account, see that there is a feature flag for New Annotations that can be toggled on/off when the account level setting is 'Allowed', or is Off when the account is off or On when the account is on. If you have rails console access: - Submit an attachment to an assignment in the course with the new annotations flag turned off - Observe that the preferred_plugin on the associated Canvadoc object is 'nil' - canvadoc_obj = Canvadoc.last # or whatever - # send has to be used cause #preferred_plugin is a private - # method. Returns nil or 'pdfjs' - canvadoc_obj.send(:preferred_plugin) - Turn the feature flag on for the course (either through the course settings or through the account) - you should not need to resubmit, and shoudl see that the preferred_plugin gets set to 'pdfjs'. It should toggle from pdfjs to nil and back when turning the feature flag on and off, whether at the account level or the course level Change-Id: I6dd70fa2b379d527315dd7e14ee6ff8cceda024e Reviewed-on: https://gerrit.instructure.com/84956 Tested-by: Jenkins QA-Review: Caleb Guanzon <cguanzon@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Product-Review: Benjamin Porter <bporter@instructure.com>
2016-07-07 02:44:45 +08:00
{ file: obj }.merge(extra_params)
raise Canvadocs::Error, "TODO: support raw files"
else
Add feature flag for canvadocs preferred plugin When the new canvadocs annotation stuff is ready, we want to be able to selectively turn it on to slowly roll it out. This adds a feature flag to the course that allows the new annotations to be enabled by course. There is also an account-level flag that allows the feature to be turned off globally per account, turned on, or simply "allowed" which delegates to the course. Refs CNVS-26668 Test Plan: - Open up the account settings and observe that there is a feature flag called 'New Annotations' - See that the feature flag can be either Off, Allowed, or On - Inside a course belonging to the account, see that there is a feature flag for New Annotations that can be toggled on/off when the account level setting is 'Allowed', or is Off when the account is off or On when the account is on. If you have rails console access: - Submit an attachment to an assignment in the course with the new annotations flag turned off - Observe that the preferred_plugin on the associated Canvadoc object is 'nil' - canvadoc_obj = Canvadoc.last # or whatever - # send has to be used cause #preferred_plugin is a private - # method. Returns nil or 'pdfjs' - canvadoc_obj.send(:preferred_plugin) - Turn the feature flag on for the course (either through the course settings or through the account) - you should not need to resubmit, and shoudl see that the preferred_plugin gets set to 'pdfjs'. It should toggle from pdfjs to nil and back when turning the feature flag on and off, whether at the account level or the course level Change-Id: I6dd70fa2b379d527315dd7e14ee6ff8cceda024e Reviewed-on: https://gerrit.instructure.com/84956 Tested-by: Jenkins QA-Review: Caleb Guanzon <cguanzon@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> Reviewed-by: Keith T. Garner <kgarner@instructure.com> Product-Review: Benjamin Porter <bporter@instructure.com>
2016-07-07 02:44:45 +08:00
{ url: obj.to_s }.merge(extra_params)
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)
"#{@url}/sessions/#{session_id}/view?theme=dark"
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./
err_message = "HTTP Error #{response.code}: #{response.body}"
klass = Canvadocs::HttpError
klass = Canvadocs::ServerError if response.code.to_s == "500"
klass = Canvadocs::BadGateway if response.code.to_s == "502"
klass = Canvadocs::BadRequest if response.code.to_s == "400"
raise klass, err_message
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
class HttpError < Error; end
class ServerError < HttpError; end
class BadGateway < HttpError; end
class BadRequest < HttpError; end
def self.config
PluginSetting.settings_for_plugin(:canvadocs)
end
def self.enabled?
!!config
end
def self.annotations_supported?
enabled? && Canvas::Plugin.value_to_boolean(config["annotations_supported"])
end
# 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
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)
# 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
# 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
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)
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
end