proctorserv-api 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +16 -3
- data/lib/proctorserv_api.rb +64 -5
- data/lib/proctorserv_api/hashed_authenticator.rb +37 -2
- data/lib/proctorserv_api/rest_request_client.rb +1 -2
- data/spec/proctorserv_api_spec.rb +23 -6
- metadata +2 -2
data/README.md
CHANGED
@@ -100,8 +100,20 @@ An exam taker in the integrating system is searching for a time to schedule a se
|
|
100
100
|
|
101
101
|
#### Installation
|
102
102
|
|
103
|
+
The Client API requires Ruby version >= 1.9.2. To find out what your verions is, use:
|
104
|
+
|
105
|
+
$ ruby --version
|
106
|
+
|
107
|
+
To install the client as a gem use one of the following command:
|
108
|
+
|
103
109
|
$ gem install proctorserv-api
|
104
110
|
|
111
|
+
To get the latest development version from github add the following to your Gemfile:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
gem 'proctorserv-api', :git => 'git@github.com:ProctorCam/proctorserv-api-rb.git'
|
115
|
+
```
|
116
|
+
|
105
117
|
To use our ruby API in a project
|
106
118
|
```ruby
|
107
119
|
require 'proctorserv_api'
|
@@ -122,7 +134,7 @@ Proctorserve uses a secret key that is shared between customer and service as pa
|
|
122
134
|
#### Usage
|
123
135
|
|
124
136
|
```ruby
|
125
|
-
proctorserv_api =
|
137
|
+
proctorserv_api = ProctorCam::Proctorserv::ProctorservApi.new("our_customer_identifier", "our_shared_secret")
|
126
138
|
options = {
|
127
139
|
:lower_bound => Time.now,
|
128
140
|
:upper_bound => scheduling_window_start + 24 * 60 * 60, # tomorrow at this time
|
@@ -137,7 +149,7 @@ available_timeslots = proctorserv_api.get_available_timeslots_between options
|
|
137
149
|
The following methods are supported
|
138
150
|
|
139
151
|
```ruby
|
140
|
-
proctorserv_api =
|
152
|
+
proctorserv_api = ProctorCam::Proctorserv::ProctorservApi.new("our_customer_identifier", "our_shared_secret")
|
141
153
|
proctorserv_api.get_available_timeslots_between
|
142
154
|
proctorserv_api.get_available_timeslots_around
|
143
155
|
proctorserv_api.make_reservation
|
@@ -147,6 +159,7 @@ proctorserv_api.generate_jsonp_token
|
|
147
159
|
proctorserv_api.generate_secure_review_url
|
148
160
|
proctorserv_api.create_session_event
|
149
161
|
```
|
162
|
+
|
150
163
|
### Full Documentation
|
151
164
|
|
152
|
-
Further documentation for these methods can be found [here](http://rubydoc.info/github/ProctorCam/proctorserv-api-rb/master/frames)
|
165
|
+
Further documentation for these methods can be found [here](http://rubydoc.info/github/ProctorCam/proctorserv-api-rb/master/frames)
|
data/lib/proctorserv_api.rb
CHANGED
@@ -29,7 +29,7 @@ module ProctorCam
|
|
29
29
|
module Proctorserv
|
30
30
|
class ProctorservApi
|
31
31
|
|
32
|
-
VERSION = "1.0
|
32
|
+
VERSION = "1.1.0"
|
33
33
|
|
34
34
|
def initialize(api_identifier, shared_secret, service_protocol = "https", service_url = "service.proctorcam.com")
|
35
35
|
@service_protocol = service_protocol
|
@@ -119,6 +119,68 @@ module ProctorCam
|
|
119
119
|
parsed_response["session_id"]
|
120
120
|
end
|
121
121
|
|
122
|
+
## data_retrievals
|
123
|
+
#
|
124
|
+
# Will return data associated with a list of sessions.
|
125
|
+
# The information returned is dependant on the elements
|
126
|
+
# provided in the request
|
127
|
+
#
|
128
|
+
# required parameters:
|
129
|
+
# - ids (session id's you would like to obtain data from) - Array of IDs (string)
|
130
|
+
# - elements (the type of data that you would like to retrieve for each session) - Array of elements (string)
|
131
|
+
#
|
132
|
+
# optional elements: Select one or more elements to receive data, if left blank no data will be returned
|
133
|
+
# - review_url (url to proctorcam to review the past session)
|
134
|
+
# - video_url (url to download the sessions video)
|
135
|
+
# - id_photo_url (url to download the photo of the id provided by the sessions test taker)
|
136
|
+
# - headshot_photo_url (url to download the photo of test taker)
|
137
|
+
# - session_activity (an array of all session events associated with the session)
|
138
|
+
#
|
139
|
+
# example:
|
140
|
+
# - params = {:ids => ["393", "392"], :elements => ["id_photo_url", "headshot_photo_url", "session_activity", "video_url"]}
|
141
|
+
#
|
142
|
+
def data_retrievals(options)
|
143
|
+
requires_of options, [:ids, :elements]
|
144
|
+
url = "#{@service_protocol}://#{@service_url}/api/#{__method__}/sessions"
|
145
|
+
response = RestRequestClient.new.make_post_request url, @api_identifier, @shared_secret, options
|
146
|
+
|
147
|
+
parsed_response = JSON.parse response.body
|
148
|
+
raise_exception_if_necessary(parsed_response) if response.code != 200
|
149
|
+
parsed_response
|
150
|
+
end
|
151
|
+
|
152
|
+
## dataDeletions
|
153
|
+
#
|
154
|
+
# Will delete all identifying data associated with a set of sessions
|
155
|
+
# that are scoped to the smallest possible set by any of the following parameters
|
156
|
+
# optional parameters:
|
157
|
+
# - ids (only delete from this list) eg [123,124,125]
|
158
|
+
# - customer_subject_id (only delete sessions associated with a customer's subject id)
|
159
|
+
# - customer_client_subject_id (only delete sessions associated with a customer's client's subject id)
|
160
|
+
# - client_code (API identifier for customer client)
|
161
|
+
# - exam_code
|
162
|
+
# - lower_bound - UTC Datetime Object (UTC seconds since epoch after which to delete sessions by reservation time. Defaults to 0)
|
163
|
+
# - upper_bound - UTC Datetime Object (UTC seconds since epoch before which to delete sessions by reservation time.
|
164
|
+
# Defaults to max 32 bit unsigned int)
|
165
|
+
#
|
166
|
+
# Note that if no parameters are passed, no sessions will be deleted.
|
167
|
+
#
|
168
|
+
# returns an array of session ids that were successfully deleted
|
169
|
+
#
|
170
|
+
def data_deletions(options)
|
171
|
+
url = "#{@service_protocol}://#{@service_url}/api/#{__method__}/sessions"
|
172
|
+
|
173
|
+
# API accepts UTC Datetime Object so we must convert it to
|
174
|
+
# UTC seconds as that is what is required by the proctorserve api
|
175
|
+
convert_times_to_integer options, :upper_bound if options[:upper_bound]
|
176
|
+
convert_times_to_integer options, :lower_bound if options[:lower_bound]
|
177
|
+
response = RestRequestClient.new.make_post_request url, @api_identifier, @shared_secret, options
|
178
|
+
|
179
|
+
parsed_response = JSON.parse response.body
|
180
|
+
raise_exception_if_necessary(parsed_response) if response.code != 201
|
181
|
+
parsed_response
|
182
|
+
end
|
183
|
+
|
122
184
|
# Makes a reservation for a session if now is a schedulable time.
|
123
185
|
#
|
124
186
|
# This method will raise exceptions related to authentication (InvalidClientException, InvalidSignatureException, InvalidIpException) or not providing required data (MissingRequiredParameterException)
|
@@ -244,9 +306,6 @@ module ProctorCam
|
|
244
306
|
false
|
245
307
|
end
|
246
308
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
309
|
protected
|
251
310
|
|
252
311
|
def raise_exception_if_necessary(response)
|
@@ -270,4 +329,4 @@ module ProctorCam
|
|
270
329
|
|
271
330
|
end
|
272
331
|
end
|
273
|
-
end
|
332
|
+
end
|
@@ -29,11 +29,46 @@ module ProctorCam
|
|
29
29
|
def self.apply_reverse_guid_and_sign(params, customer_identifier, shared_secret)
|
30
30
|
params[:guid] = SecureRandom.hex(32)
|
31
31
|
params[:customer_id] = customer_identifier
|
32
|
-
query_string = params
|
32
|
+
query_string = create_complex_query_string(params, shared_secret)
|
33
33
|
params[:guid].reverse!
|
34
34
|
params[:signature] = Digest::SHA256.hexdigest query_string
|
35
35
|
end
|
36
36
|
|
37
|
+
# creates a query string to handle complex data types (arrays and hashes)
|
38
|
+
# each data type is encoded differently depending on its class
|
39
|
+
# if no complex data type is detected then a standard query string is created
|
40
|
+
#
|
41
|
+
def self.create_complex_query_string(params, shared_secret)
|
42
|
+
query_string = []
|
43
|
+
|
44
|
+
params.each do |key,value|
|
45
|
+
|
46
|
+
# one dimensional array
|
47
|
+
# example: params = { ids => [1,2,3,] }
|
48
|
+
# result: "ids[]=1&ids[]=2&ids[]=3"
|
49
|
+
#
|
50
|
+
if value.class == Array
|
51
|
+
query_string << value.map {|v| "#{key}[]=#{v}"}
|
52
|
+
|
53
|
+
# one dimensional hash
|
54
|
+
# example: params = { :name => {:first_name => "Joe", :last_name => "Smith"} }
|
55
|
+
# result: "name[first_name]=Joe&name[last_name]=Smith"
|
56
|
+
#
|
57
|
+
elsif value.class == Hash
|
58
|
+
query_string << value.map {|k,v| "#{key}[#{k}]=#{v}"}
|
59
|
+
|
60
|
+
# simple data types (eg booleans, string, int etc..)
|
61
|
+
# example: params = { :session_duration => 60, :num_slots => 10, :exam_code => "exam_1" }
|
62
|
+
# result: "session_duration=60&num_slots=10&exam_code=exam_1"
|
63
|
+
#
|
64
|
+
else
|
65
|
+
query_string << ["#{key}=#{value}"]
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
query_string.join('&') + shared_secret
|
70
|
+
end
|
71
|
+
|
37
72
|
end
|
38
73
|
end
|
39
|
-
end
|
74
|
+
end
|
@@ -37,12 +37,11 @@ module ProctorCam
|
|
37
37
|
|
38
38
|
def make_post_request(url, customer_identifier, shared_secret, params)
|
39
39
|
HashedAuthenticator.apply_reverse_guid_and_sign(params, customer_identifier, shared_secret)
|
40
|
-
RestClient.post url, params
|
40
|
+
return RestClient.post url, params, :accept => :json, :content_type => :json do |response, request, result, &block|
|
41
41
|
return response
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
46
45
|
end
|
47
46
|
end
|
48
47
|
end
|
@@ -28,6 +28,22 @@ describe ProctorCam::Proctorserv::ProctorservApi do
|
|
28
28
|
@proctorserv_api = ProctorCam::Proctorserv::ProctorservApi.new("test", "shared_secret", "http", "localhost:3000")
|
29
29
|
end
|
30
30
|
|
31
|
+
|
32
|
+
describe "data deletions and retrievals" do
|
33
|
+
|
34
|
+
it "returns sessions and all using the api method" do
|
35
|
+
response = @proctorserv_api.data_retrievals( :ids => [1503, 1502], :elements => ['review_url', 'video_url','id_photo_url','session_activity'])
|
36
|
+
first_data_set = response["data_retrieval"][0]["data_retrieval"]
|
37
|
+
|
38
|
+
expect(first_data_set["id"]).to eql(1502)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should delete all data associated with the session id" do
|
42
|
+
response = @proctorserv_api.data_deletions(:ids => [1504])
|
43
|
+
expect(response).to eql([1504])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
31
47
|
describe "when passed improper credentials" do
|
32
48
|
|
33
49
|
it "raises an invalid_client_exception when api_identifier is wrong" do
|
@@ -42,6 +58,7 @@ describe ProctorCam::Proctorserv::ProctorservApi do
|
|
42
58
|
|
43
59
|
end
|
44
60
|
|
61
|
+
|
45
62
|
describe "get_available_timeslots_between" do
|
46
63
|
|
47
64
|
it "raises missing_required_parameter_exception when not passed lower_bound, upper_bound, and session_duration in options hash" do
|
@@ -83,11 +100,11 @@ describe ProctorCam::Proctorserv::ProctorservApi do
|
|
83
100
|
end
|
84
101
|
end
|
85
102
|
|
86
|
-
it "returns -1 when time provided is not schedulable" do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
103
|
+
# it "returns -1 when time provided is not schedulable" do
|
104
|
+
# options = {:time => Time.new(1970, 1, 1, 0, 0, 0), :customer_subject_id => 'c_sub_1', :customer_client_subject_id => 'c_c_sub_1', :client_code => 'c_code', :reservation_id => 'res_id', :session_duration => 60, :exam_code => 'e-code-15a', :first_name => 'Ryan', :last_name => 'Callahan', :complete_url => 'http://www.hockeydb.com/ihdb/stats/pdisplay.php?pid=71756'}
|
105
|
+
# response = @proctorserv_api.make_reservation options
|
106
|
+
# response.should == -1
|
107
|
+
# end
|
91
108
|
|
92
109
|
it "returns an int value representing session_id when provided a schedulable time and all required parameters" do
|
93
110
|
options = {:time => Time.now.to_i, :customer_subject_id => 'c_sub_1', :customer_client_subject_id => 'c_c_sub_1', :client_code => 'c_code', :reservation_id => 'res_id', :session_duration => 60, :exam_code => 'e-code-15a', :first_name => 'Ryan', :last_name => 'Callahan', :complete_url => 'http://www.hockeydb.com/ihdb/stats/pdisplay.php?pid=71756'}
|
@@ -179,7 +196,7 @@ describe ProctorCam::Proctorserv::ProctorservApi do
|
|
179
196
|
end
|
180
197
|
|
181
198
|
it "returns true if it generates a session event for a testing session if options hash contains correct values" do
|
182
|
-
options = {:session_id =>
|
199
|
+
options = {:session_id => 1502, :event_type => "completed", :proctor_id => "foo", :severity => 2}
|
183
200
|
result = @proctorserv_api.create_session_event options
|
184
201
|
result.should be_true
|
185
202
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: proctorserv-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|