bright 1.3 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,21 @@
1
- require 'oauth'
1
+ require "oauth"
2
2
 
3
3
  module Bright
4
4
  module SisApi
5
- class InfiniteCampus < Base
6
-
7
- @@description = "Connects to the Infinite Campus OneRoster API for accessing student information"
8
- @@doc_url = "https://content.infinitecampus.com/sis/latest/documentation/oneroster-api"
9
- @@api_version = "1.1"
5
+ class OneRoster < Base
6
+ @@description = "Connects to the OneRoster API for accessing student information"
7
+ @@doc_url = "https://www.imsglobal.org/sites/default/files/spec/oneroster/v1p2/rostering-informationmodel/OneRosterv1p2RosteringService_InfoModelv1p0.html"
8
+ @@api_version = "1.2"
10
9
 
11
10
  attr_accessor :connection_options, :schools_cache, :school_years_cache
12
11
 
13
12
  DEMOGRAPHICS_CONVERSION = {
14
- "americanIndianOrAlaskaNative"=>"American Indian Or Alaska Native",
15
- "asian"=>"Asian",
16
- "blackOrAfricanAmerican"=>"Black Or African American",
17
- "nativeHawaiianOrOtherPacificIslander"=>"Native Hawaiian Or Other Pacific Islander",
18
- "white"=>"White",
19
- "hispanicOrLatinoEthnicity"=>"Hispanic Or Latino"
13
+ "americanIndianOrAlaskaNative" => "American Indian Or Alaska Native",
14
+ "asian" => "Asian",
15
+ "blackOrAfricanAmerican" => "Black Or African American",
16
+ "nativeHawaiianOrOtherPacificIslander" => "Native Hawaiian Or Other Pacific Islander",
17
+ "white" => "White",
18
+ "hispanicOrLatinoEthnicity" => "Hispanic Or Latino"
20
19
  }
21
20
 
22
21
  def initialize(options = {})
@@ -31,36 +30,36 @@ module Bright
31
30
  end
32
31
 
33
32
  def api_version
34
- Gem::Version.new(self.connection_options.dig(:api_version) || @@api_version)
33
+ Gem::Version.new(connection_options.dig(:api_version) || @@api_version)
35
34
  end
36
35
 
37
36
  def get_student_by_api_id(api_id, params = {})
38
- if api_version <= Gem::Version.new("1.1")
39
- params = {:role => "student"}.merge(params)
37
+ params = if api_version <= Gem::Version.new("1.1")
38
+ {role: "student"}.merge(params)
40
39
  else
41
- params = {:roles => "student"}.merge(params)
40
+ {roles: "student"}.merge(params)
42
41
  end
43
- st_hsh = self.request(:get, "users/#{api_id}", params)
44
- Student.new(convert_to_user_data(st_hsh["user"])) if st_hsh and st_hsh["user"]
42
+ st_hsh = request(:get, "users/#{api_id}", params)
43
+ Student.new(convert_to_user_data(st_hsh["user"])) if st_hsh && st_hsh["user"]
45
44
  end
46
45
 
47
46
  def get_student(params = {}, options = {})
48
- self.get_students(params, options.merge(:limit => 1, :wrap_in_collection => false)).first
47
+ get_students(params, options.merge(limit: 1, wrap_in_collection: false)).first
49
48
  end
50
49
 
51
50
  def get_students(params = {}, options = {})
52
- if api_version <= Gem::Version.new("1.1")
53
- params = {:role => "student"}.merge(params)
51
+ params = if api_version <= Gem::Version.new("1.1")
52
+ {role: "student"}.merge(params)
54
53
  else
55
- params = {:roles => "student"}.merge(params)
54
+ {roles: "student"}.merge(params)
56
55
  end
57
56
  params[:limit] = params[:limit] || options[:limit] || 100
58
- students_response_hash = self.request(:get, 'users', self.map_search_params(params))
57
+ students_response_hash = request(:get, "users", map_search_params(params))
59
58
  total_results = students_response_hash[:response_headers]["x-total-count"].to_i
60
- if students_response_hash and students_response_hash["users"]
59
+ if students_response_hash && students_response_hash["users"]
61
60
  students_hash = [students_response_hash["users"]].flatten
62
61
 
63
- students = students_hash.compact.collect {|st_hsh|
62
+ students = students_hash.compact.collect { |st_hsh|
64
63
  Student.new(convert_to_user_data(st_hsh))
65
64
  }
66
65
  end
@@ -69,14 +68,14 @@ module Bright
69
68
  load_more_call = proc { |page|
70
69
  # pages start at one, so add a page here
71
70
  params[:offset] = (params[:limit].to_i * page)
72
- api.get_students(params, {:wrap_in_collection => false})
71
+ api.get_students(params, {wrap_in_collection: false})
73
72
  }
74
73
  ResponseCollection.new({
75
- :seed_page => students,
76
- :total => total_results,
77
- :per_page => params[:limit],
78
- :load_more_call => load_more_call,
79
- :no_threads => options[:no_threads]
74
+ seed_page: students,
75
+ total: total_results,
76
+ per_page: params[:limit],
77
+ load_more_call: load_more_call,
78
+ no_threads: options[:no_threads]
80
79
  })
81
80
  else
82
81
  students
@@ -92,22 +91,22 @@ module Bright
92
91
  end
93
92
 
94
93
  def get_school_by_api_id(api_id, params = {})
95
- sc_hsh = self.request(:get, "schools/#{api_id}", params)
96
- School.new(convert_to_school_data(sc_hsh["org"])) if sc_hsh and sc_hsh["org"]
94
+ sc_hsh = request(:get, "schools/#{api_id}", params)
95
+ School.new(convert_to_school_data(sc_hsh["org"])) if sc_hsh && sc_hsh["org"]
97
96
  end
98
97
 
99
98
  def get_school(params = {}, options = {})
100
- self.get_schools(params, options.merge(:limit => 1, :wrap_in_collection => false)).first
99
+ get_schools(params, options.merge(limit: 1, wrap_in_collection: false)).first
101
100
  end
102
101
 
103
102
  def get_schools(params = {}, options = {})
104
103
  params[:limit] = params[:limit] || options[:limit] || 100
105
- schools_response_hash = self.request(:get, 'schools', self.map_school_search_params(params))
104
+ schools_response_hash = request(:get, "schools", map_school_search_params(params))
106
105
  total_results = schools_response_hash[:response_headers]["x-total-count"].to_i
107
- if schools_response_hash and schools_response_hash["orgs"]
106
+ if schools_response_hash && schools_response_hash["orgs"]
108
107
  schools_hash = [schools_response_hash["orgs"]].flatten
109
108
 
110
- schools = schools_hash.compact.collect {|sc_hsh|
109
+ schools = schools_hash.compact.collect { |sc_hsh|
111
110
  School.new(convert_to_school_data(sc_hsh))
112
111
  }
113
112
  end
@@ -116,27 +115,27 @@ module Bright
116
115
  load_more_call = proc { |page|
117
116
  # pages start at one, so add a page here
118
117
  params[:offset] = (params[:limit].to_i * page)
119
- api.get_schools(params, {:wrap_in_collection => false})
118
+ api.get_schools(params, {wrap_in_collection: false})
120
119
  }
121
120
  ResponseCollection.new({
122
- :seed_page => schools,
123
- :total => total_results,
124
- :per_page => params[:limit],
125
- :load_more_call => load_more_call,
126
- :no_threads => options[:no_threads]
121
+ seed_page: schools,
122
+ total: total_results,
123
+ per_page: params[:limit],
124
+ load_more_call: load_more_call,
125
+ no_threads: options[:no_threads]
127
126
  })
128
127
  else
129
128
  schools
130
129
  end
131
130
  end
132
131
 
133
- def get_contact_by_api_id(api_id, params ={})
134
- contact_hsh = self.request(:get, "users/#{api_id}", params)
135
- Contact.new(convert_to_user_data(contact_hsh["user"], bright_type: "Contact")) if contact_hsh and contact_hsh["user"]
132
+ def get_contact_by_api_id(api_id, params = {})
133
+ contact_hsh = request(:get, "users/#{api_id}", params)
134
+ Contact.new(convert_to_user_data(contact_hsh["user"], bright_type: "Contact")) if contact_hsh && contact_hsh["user"]
136
135
  end
137
136
 
138
137
  def request(method, path, params = {})
139
- uri = "#{self.connection_options[:uri]}/#{path}"
138
+ uri = "#{connection_options[:uri]}/#{path}"
140
139
  body = nil
141
140
  if method == :get
142
141
  query = URI.encode_www_form(params)
@@ -147,7 +146,7 @@ module Bright
147
146
 
148
147
  response = connection_retry_wrapper {
149
148
  connection = Bright::Connection.new(uri)
150
- headers = self.headers_for_auth(uri)
149
+ headers = headers_for_auth(uri)
151
150
  connection.request(method, body, headers)
152
151
  }
153
152
 
@@ -155,8 +154,8 @@ module Bright
155
154
  response_hash = JSON.parse(response.body)
156
155
  response_hash[:response_headers] = response.headers
157
156
  else
158
- puts "#{response.inspect}"
159
- puts "#{response.body}"
157
+ puts response.inspect
158
+ puts response.body
160
159
  end
161
160
  response_hash
162
161
  end
@@ -164,48 +163,46 @@ module Bright
164
163
  protected
165
164
 
166
165
  def headers_for_auth(uri)
167
- case api_version
168
- when Gem::Version.new("1.1")
169
- site = URI.parse(self.connection_options[:uri])
170
- site = "#{site.scheme}://#{site.host}"
171
- consumer = OAuth::Consumer.new(self.connection_options[:client_id], self.connection_options[:client_secret], { :site => site, :scheme => :header })
172
- options = {:timestamp => Time.now.to_i, :nonce => SecureRandom.uuid}
173
- {"Authorization" => consumer.create_signed_request(:get, uri, nil, options)["Authorization"]}
174
- when Gem::Version.new("1.2")
175
- if self.connection_options[:access_token].nil? or self.connection_options[:access_token_expires] < Time.now
176
- self.retrieve_access_token
166
+ if api_version >= Gem::Version.new("1.2") || connection_options[:token_uri].present?
167
+ if connection_options[:access_token].nil? || (connection_options[:access_token_expires] < Time.now)
168
+ retrieve_access_token
177
169
  end
178
170
  {
179
- "Authorization" => "Bearer #{self.connection_options[:access_token]}",
180
- "Accept" => "application/json;charset=UTF-8",
181
- "Content-Type" =>"application/json;charset=UTF-8"
171
+ "Authorization" => "Bearer #{connection_options[:access_token]}",
172
+ "Accept" => "application/json",
173
+ "Content-Type" => "application/json"
182
174
  }
175
+ else
176
+ site = URI.parse(connection_options[:uri])
177
+ site = "#{site.scheme}://#{site.host}"
178
+ consumer = OAuth::Consumer.new(connection_options[:client_id], connection_options[:client_secret], {site: site, scheme: :header})
179
+ options = {timestamp: Time.now.to_i, nonce: SecureRandom.uuid}
180
+ {"Authorization" => consumer.create_signed_request(:get, uri, nil, options)["Authorization"]}
183
181
  end
184
182
  end
185
183
 
186
184
  def retrieve_access_token
187
- connection = Bright::Connection.new(self.connection_options[:token_uri])
185
+ connection = Bright::Connection.new(connection_options[:token_uri])
188
186
  response = connection.request(:post,
189
187
  {
190
188
  "grant_type" => "client_credentials",
191
- "username" => self.connection_options[:client_id],
192
- "password" => self.connection_options[:client_secret]
189
+ "username" => connection_options[:client_id],
190
+ "password" => connection_options[:client_secret]
193
191
  },
194
- self.headers_for_access_token
195
- )
192
+ headers_for_access_token)
196
193
  if !response.error?
197
194
  response_hash = JSON.parse(response.body)
198
195
  end
199
196
  if response_hash["access_token"]
200
- self.connection_options[:access_token] = response_hash["access_token"]
201
- self.connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
197
+ connection_options[:access_token] = response_hash["access_token"]
198
+ connection_options[:access_token_expires] = (Time.now - 10) + response_hash["expires_in"]
202
199
  end
203
200
  response_hash
204
201
  end
205
202
 
206
203
  def headers_for_access_token
207
204
  {
208
- "Authorization" => "Basic #{Base64.strict_encode64("#{self.connection_options[:client_id]}:#{self.connection_options[:client_secret]}")}",
205
+ "Authorization" => "Basic #{Base64.strict_encode64("#{connection_options[:client_id]}:#{connection_options[:client_secret]}")}",
209
206
  "Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
210
207
  }
211
208
  end
@@ -215,7 +212,7 @@ module Bright
215
212
  default_params = {}
216
213
 
217
214
  filter = []
218
- params.each do |k,v|
215
+ params.each do |k, v|
219
216
  case k.to_s
220
217
  when "first_name"
221
218
  filter << "givenName='#{v}'"
@@ -236,14 +233,14 @@ module Bright
236
233
  unless filter.empty?
237
234
  params = {"filter" => filter.join(" AND ")}
238
235
  end
239
- default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
236
+ default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
240
237
  end
241
238
 
242
239
  def map_school_search_params(params)
243
240
  params = params.dup
244
241
  default_params = {}
245
242
  filter = []
246
- params.each do |k,v|
243
+ params.each do |k, v|
247
244
  case k.to_s
248
245
  when "number"
249
246
  filter << "identifier='#{v}'"
@@ -256,50 +253,46 @@ module Bright
256
253
  unless filter.empty?
257
254
  params = {"filter" => filter.join(" AND ")}
258
255
  end
259
- default_params.merge(params).reject{|k,v| v.respond_to?(:empty?) ? v.empty? : v.nil?}
256
+ default_params.merge(params).reject { |k, v| v.respond_to?(:empty?) ? v.empty? : v.nil? }
260
257
  end
261
258
 
262
259
  def convert_to_school_data(school_params)
263
260
  return {} if school_params.blank?
264
- school_data_hsh = {
265
- :api_id => school_params["sourcedId"],
266
- :name => school_params["name"],
267
- :number => school_params["identifier"],
268
- :last_modified => school_params["dateLastModified"]
261
+ {
262
+ api_id: school_params["sourcedId"],
263
+ name: school_params["name"],
264
+ number: school_params["identifier"],
265
+ last_modified: school_params["dateLastModified"]
269
266
  }
270
- return school_data_hsh
271
267
  end
272
268
 
273
269
  def convert_to_user_data(user_params, bright_type: "Student")
274
270
  return {} if user_params.blank?
275
271
  user_data_hsh = {
276
- :api_id => user_params["sourcedId"],
277
- :first_name => user_params["givenName"],
278
- :middle_name => user_params["middleName"],
279
- :last_name => user_params["familyName"],
280
- :last_modified => user_params["dateLastModified"]
281
- }.reject{|k,v| v.blank?}
272
+ api_id: user_params["sourcedId"],
273
+ first_name: user_params["givenName"],
274
+ middle_name: user_params["middleName"],
275
+ last_name: user_params["familyName"],
276
+ last_modified: user_params["dateLastModified"]
277
+ }.reject { |k, v| v.blank? }
282
278
  unless user_params["identifier"].blank?
283
279
  user_data_hsh[:sis_student_id] = user_params["identifier"]
284
280
  end
285
- unless user_params["userMasterIdentifier"].blank?
286
- user_data_hsh[:state_student_id] = user_params["userMasterIdentifier"]
287
- end
288
281
  unless user_params["userIds"].blank?
289
- if (state_id_hsh = user_params["userIds"].detect{|user_id_hsh| user_id_hsh["type"] == "stateID"})
282
+ if (state_id_hsh = user_params["userIds"].detect { |user_id_hsh| user_id_hsh["type"] == "stateID" })
290
283
  user_data_hsh[:state_student_id] = state_id_hsh["identifier"]
291
284
  end
292
285
  end
293
286
  unless user_params["email"].blank?
294
287
  user_data_hsh[:email_address] = {
295
- :email_address => user_params["email"]
288
+ email_address: user_params["email"]
296
289
  }
297
290
  end
298
291
  unless user_params["orgs"].blank?
299
- if (s = user_params["orgs"].detect{|org| org["href"] =~ /\/schools\//})
292
+ if (s = user_params["orgs"].detect { |org| org["href"] =~ /\/schools\// })
300
293
  self.schools_cache ||= {}
301
294
  if (attending_school = self.schools_cache[s["sourcedId"]]).nil?
302
- attending_school = self.get_school_by_api_id(s["sourcedId"])
295
+ attending_school = get_school_by_api_id(s["sourcedId"])
303
296
  self.schools_cache[attending_school.api_id] = attending_school
304
297
  end
305
298
  end
@@ -308,26 +301,24 @@ module Bright
308
301
  end
309
302
  end
310
303
  unless user_params["phone"].blank?
311
- user_data_hsh[:phone_numbers] = [{:phone_number => user_params["phone"]}]
304
+ user_data_hsh[:phone_numbers] = [{phone_number: user_params["phone"]}]
312
305
  end
313
306
  unless user_params["sms"].blank?
314
307
  user_data_hsh[:phone_numbers] ||= []
315
- user_data_hsh[:phone_numbers] << {:phone_number => user_params["sms"]}
308
+ user_data_hsh[:phone_numbers] << {phone_number: user_params["sms"]}
316
309
  end
317
310
 
318
- #add the demographic information
311
+ # add the demographic information
319
312
  demographics_hash = get_demographic_information(user_data_hsh[:api_id])
320
313
  user_data_hsh.merge!(demographics_hash) unless demographics_hash.blank?
321
314
 
322
- #if you're a student, build the contacts too
323
- if bright_type == "Student" and !user_params["agents"].blank?
315
+ # if you're a student, build the contacts too
316
+ if (bright_type == "Student") && !user_params["agents"].blank?
324
317
  user_data_hsh[:contacts] = user_params["agents"].collect do |agent_hsh|
325
- begin
326
- self.get_contact_by_api_id(agent_hsh["sourcedId"])
327
- rescue Bright::ResponseError => e
328
- if !e.message.to_s.include?("404")
329
- raise e
330
- end
318
+ get_contact_by_api_id(agent_hsh["sourcedId"])
319
+ rescue Bright::ResponseError => e
320
+ if !e.message.to_s.include?("404")
321
+ raise e
331
322
  end
332
323
  end.compact
333
324
  user_data_hsh[:grade] = (user_params["grades"] || []).first
@@ -336,7 +327,7 @@ module Bright
336
327
  end
337
328
  end
338
329
 
339
- return user_data_hsh
330
+ user_data_hsh
340
331
  end
341
332
 
342
333
  def get_demographic_information(api_id)
@@ -345,7 +336,7 @@ module Bright
345
336
  begin
346
337
  demographics_params = request(:get, "demographics/#{api_id}")["demographics"]
347
338
  rescue Bright::ResponseError => e
348
- if e.message.to_s.include?('404')
339
+ if e.message.to_s.include?("404")
349
340
  return demographic_hsh
350
341
  else
351
342
  raise e
@@ -368,22 +359,21 @@ module Bright
368
359
  end
369
360
  end
370
361
  end
371
- return demographic_hsh
362
+ demographic_hsh
372
363
  end
373
364
 
374
365
  def get_grade_school_year(date = Date.today)
375
- #return the school year of a specific date
366
+ # return the school year of a specific date
376
367
  self.school_years_cache ||= {}
377
368
  if self.school_years_cache[date].nil?
378
- academic_periods_params = self.request(:get, "academicSessions", {"filter" => "startDate<='#{date.to_s}' AND endDate>='#{date.to_s}' AND status='active'"})["academicSessions"]
379
- school_years = academic_periods_params.map{|ap| ap["schoolYear"]}.uniq
369
+ academic_periods_params = request(:get, "academicSessions", {"filter" => "startDate<='#{date}' AND endDate>='#{date}' AND status='active'"})["academicSessions"]
370
+ school_years = academic_periods_params.map { |ap| ap["schoolYear"] }.uniq
380
371
  if school_years.size == 1
381
372
  self.school_years_cache[date] = school_years.first
382
373
  end
383
374
  end
384
- return self.school_years_cache[date]
375
+ self.school_years_cache[date]
385
376
  end
386
-
387
377
  end
388
378
  end
389
379
  end