Skip to content

Instantly share code, notes, and snippets.

@danielefrisanco
Last active January 28, 2018 14:32
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save danielefrisanco/737471a124bfd67cd1711a953364d965 to your computer and use it in GitHub Desktop.
creates and exam, a document for it, adds a student and sends the emails
require 'net/http/post/multipart'
require 'uri'
require 'cgi'
require 'erb'
require 'net/http'
require 'openssl'
require 'time'
require 'json'
require 'rack/test'
api_token = "YOUR_API_TOKEN"
# declare your params for the exam
# do not use the key course because it is deprecated
# use the user api_token that can be found in Your settings
# nonce is an integer that is unique between all the nonce used in the previous 24 hours
params = {
name: "Exam name",
duration: 60,
mobile_cam: true,
type: "classic",
start_time: (Time.now + (2*24*60*60)).to_i,
end_time: (Time.now + (3*24*60*60)).to_i,
upload_exam: false,
restrictions: "Text for reviewers test[ @ ]",
for_reviewing: true,
timestamp: (Time.now.to_f*1000).to_i,
nonce: Time.now.to_i,
api_token: api_token,
}
# use the user secret_key that can be found in Your settings
secret_key = "YOUR_SECRET_KEY"
# build a signature using the user secret_key and a string build using params ordered in alphabetical order by key and joined with "?" in the form "key=value"
signature = OpenSSL::HMAC.hexdigest(
OpenSSL::Digest.new('sha256'),
secret_key,
params.keys.sort.map{|key|"#{key}=#{params[key]}"}.join("?")
)
# add signature to params
params[:signature] = signature
# build the url appending params in "key=value" form joined by "&"
url = URI("https://web.proctorexam.com/api/exams?#{params.map{|key, value|"#{key}=#{value.class.name == "String" ? ERB::Util.url_encode(value) : value}"}.join("&")}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["cache-control"] = 'no-cache'
response = http.request(request)
#get exam id from response
exam_id = JSON.parse(response.read_body)["id"]
puts "exam created id: #{exam_id}"
#########################################################################################################################
# to avoid problems with Time.now
sleep(1)
#add a empty document to the exam (hack that will be fixed in the next release)
document_params = {
exam_id: exam_id,
document_text: " ",
timestamp: (Time.now.to_f*1000).to_i,
nonce: Time.now.to_i,
api_token: api_token,
}
# build a signature using the user secret_key and a string build using document_params ordered in alphabetical order by key and joined with "?" in the form "key=value"
signature = OpenSSL::HMAC.hexdigest(
OpenSSL::Digest.new('sha256'),
secret_key,
document_params.keys.sort.map{|key|"#{key}=#{document_params[key]}"}.join("?")
)
# add signature to document_params
document_params[:signature] = signature
# build the url appending document_params in "key=value" form joined by "&"
url = URI("https://web.proctorexam.com/api/documents?#{document_params.map{|key, value|"#{key}=#{value.class.name == "String" ? ERB::Util.url_encode(value) : value}"}.join("&")}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["cache-control"] = 'no-cache'
response = http.request(request)
# response will contain document id
document = JSON.parse(response.read_body)
puts "document added id: #{document['id']}"
#########################################################################################################################
# to avoid problems with Time.now
sleep(1)
#add a student to the exam
student_params = {
name: "Student name",
email: "email@example.com",
timestamp: (Time.now.to_f*1000).to_i,
nonce: Time.now.to_i,
api_token: api_token,
id: exam_id
}
# build a signature using the user secret_key and a string build using student_params ordered in alphabetical order by key and joined with "?" in the form "key=value"
signature = OpenSSL::HMAC.hexdigest(
OpenSSL::Digest.new('sha256'),
secret_key,
student_params.keys.sort.map{|key|"#{key}=#{student_params[key]}"}.join("?")
)
# student_params[:name] = "Student%20name"
# add signature to student_params
student_params[:signature] = signature
# build the url appending student_params in "key=value" form joined by "&"
url = URI("https://web.proctorexam.com/api/exams/#{exam_id}/add_student?#{student_params.map{|key, value|"#{key}=#{value.class.name == "String" ? ERB::Util.url_encode(value) : value}"}.join("&")}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
# binding.pry
request = Net::HTTP::Post.new(url)
request["cache-control"] = 'no-cache'
response = http.request(request)
# response will contain student
puts response.read_body
student = JSON.parse(response.read_body)["student_session"]
puts "student added: #{student}"
#########################################################################################################################
# to avoid problems with Time.now
sleep(1)
#add attachments
attachment_params = {
id: document['id'],
timestamp: (Time.now.to_f*1000).to_i,
nonce: Time.now.to_i,
api_token: api_token
}
# build a signature using the user secret_key and a string build using attachment_params(without file) ordered in alphabetical order by key and joined with "?" in the form "key=value"
signature = OpenSSL::HMAC.hexdigest(
OpenSSL::Digest.new('sha256'),
secret_key,
attachment_params.keys.sort.map{|key|"#{key}=#{attachment_params[key]}"}.join("?")
)
# add signature to attachment_params
attachment_params[:signature] = signature
# build the url appending attachment_params in "key=value" form joined by "&"
url = URI("https://web.proctorexam.com/api/documents/#{document['id']}/add_attachment?#{attachment_params.map{|key, value|"#{key}=#{value.class.name == "String" ? ERB::Util.url_encode(value) : value}"}.join("&")}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
File.open("/home/daniele/Desktop/retrospective") do |f|
request = Net::HTTP::Post::Multipart.new url,
"file" => UploadIO.new(f, "text/plain", "retrospective")
response = http.request(request)
end
puts response.read_body
# response will contain student
attachment = JSON.parse(response.read_body)["attachment"]
puts "attachment added: #{attachment}"
#########################################################################################################################
# to avoid problems with Time.now
sleep(1)
#send_email to students
student_email_params = {
id: exam_id,
timestamp: (Time.now.to_f*1000).to_i,
nonce: Time.now.to_i,
api_token: api_token,
}
# build a signature using the user secret_key and a string build using student_email_params ordered in alphabetical order by key and joined with "?" in the form "key=value"
signature = OpenSSL::HMAC.hexdigest(
OpenSSL::Digest.new('sha256'),
secret_key,
student_email_params.keys.sort.map{|key|"#{key}=#{student_email_params[key]}"}.join("?")
)
# add signature to student_email_params
student_email_params[:signature] = signature
# build the url appending student_email_params in "key=value" form joined by "&"
url = URI("https://web.proctorexam.com/api/exams/#{exam_id}/send_emails?#{student_email_params.map{|key, value|"#{key}=#{value.class.name == "String" ? ERB::Util.url_encode(value) : value}"}.join("&")}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["cache-control"] = 'no-cache'
response = http.request(request)
# response will contain students to whom email got send
students = JSON.parse(response.read_body)["student_sessions"]
puts "email sent to students : #{students}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment