Class: CanvasOauth::CanvasApi

Inherits:
Object
  • Object
show all
Includes:
HTTParty
Defined in:
lib/canvas_oauth/canvas_api.rb

Defined Under Namespace

Classes: Authenticate, Unauthorized

Constant Summary collapse

PER_PAGE =
50

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(canvas_url, canvas_user_id, canvas_root_account_id, token, refresh_token, key, secret) ⇒ CanvasApi

Returns a new instance of CanvasApi.



9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/canvas_oauth/canvas_api.rb', line 9

def initialize(canvas_url, canvas_user_id, , token, refresh_token, key, secret)
  unless [key, secret].all?(&:present?)
    raise "Invalid Qalam oAuth configuration"
  end
  
  self.refresh_token = refresh_token
  self.canvas_url = canvas_url
  self.canvas_user_id = canvas_user_id
  self. = 
  self.token = token
  self.key = key
  self.secret = secret
end

Instance Attribute Details

#canvas_urlObject

Returns the value of attribute canvas_url.



7
8
9
# File 'lib/canvas_oauth/canvas_api.rb', line 7

def canvas_url
  @canvas_url
end

#canvas_user_idObject

Returns the value of attribute canvas_user_id.



7
8
9
# File 'lib/canvas_oauth/canvas_api.rb', line 7

def canvas_user_id
  @canvas_user_id
end

#keyObject

Returns the value of attribute key.



6
7
8
# File 'lib/canvas_oauth/canvas_api.rb', line 6

def key
  @key
end

#refresh_tokenObject

Returns the value of attribute refresh_token.



6
7
8
# File 'lib/canvas_oauth/canvas_api.rb', line 6

def refresh_token
  @refresh_token
end

#secretObject

Returns the value of attribute secret.



6
7
8
# File 'lib/canvas_oauth/canvas_api.rb', line 6

def secret
  @secret
end

#tokenObject

Returns the value of attribute token.



6
7
8
# File 'lib/canvas_oauth/canvas_api.rb', line 6

def token
  @token
end

Instance Method Details

#account_external_tool_update(external_tool_url, tool_id, account_id, publish) ⇒ Object



355
356
357
358
# File 'lib/canvas_oauth/canvas_api.rb', line 355

def (external_tool_url, tool_id, , publish)
  authenticated_put "/api/v1/accounts/#{}/external_tools_url", { body: {"account_navigation"=>{"enabled"=>"#{publish}"},
   "tool_id"=>tool_id, "external_tool_url"=>external_tool_url} }
end

#auth_url(redirect_uri, oauth2_state) ⇒ Object



58
59
60
# File 'lib/canvas_oauth/canvas_api.rb', line 58

def auth_url(redirect_uri, oauth2_state)
  "#{canvas_url}/login/oauth2/auth?client_id=#{key}&response_type=code&state=#{oauth2_state}&redirect_uri=#{redirect_uri}"
end

#authenticated_get(*params) ⇒ Object



95
96
97
# File 'lib/canvas_oauth/canvas_api.rb', line 95

def authenticated_get(*params)
  authenticated_request(:get, *params)
end

#authenticated_post(*params) ⇒ Object



99
100
101
# File 'lib/canvas_oauth/canvas_api.rb', line 99

def authenticated_post(*params)
  authenticated_request(:post, *params)
end

#authenticated_put(*params) ⇒ Object



103
104
105
# File 'lib/canvas_oauth/canvas_api.rb', line 103

def authenticated_put(*params)
  authenticated_request(:put, *params)
end

#authenticated_request(method, *params) ⇒ Object

START AUTH ###



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/canvas_oauth/canvas_api.rb', line 24

def authenticated_request(method, *params)
  params << {} if params.size == 1

  params.last[:headers] ||= {}
  params.last[:headers]['Authorization'] = "Bearer #{token}"

  start = Time.now

  response = self.class.send(method, *params)

  Rails.logger.info {
    stop = Time.now
    elapsed = ((stop - start) * 1000).round(2)

    params.last[:headers].reject! { |k| k == 'Authorization' }
    "API call (#{elapsed}ms): #{method} #{params.inspect}"
  }

  if response && response.unauthorized?
    if refresh_token
      get_access_token_by_refresh_token
      authenticated_request(method, *params)
    else
      if response.headers['WWW-Authenticate'].present?
        raise CanvasApi::Authenticate
      else
        raise CanvasApi::Unauthorized
      end
    end
  else
    return response
  end
end

#canvas_root_account_id=(value) ⇒ Object



135
136
137
# File 'lib/canvas_oauth/canvas_api.rb', line 135

def (value)
  @canvas_root_account_id = value
end

#course_account_id(course_id) ⇒ Object



311
312
313
314
# File 'lib/canvas_oauth/canvas_api.rb', line 311

def (course_id)
  course = get_course(course_id)
  course['account_id'] if course
end

#course_external_tool_update(external_tool_url, tool_id, account_id, publish) ⇒ Object



350
351
352
353
# File 'lib/canvas_oauth/canvas_api.rb', line 350

def course_external_tool_update(external_tool_url, tool_id, , publish)
  authenticated_put "/api/v1/accounts/#{}/external_tools_url", { body: {"course_navigation"=>{"enabled"=>"#{publish}"},
   "tool_id"=>tool_id, "external_tool_url"=>external_tool_url} }
end

#course_root_account_id(course_id) ⇒ Object



324
325
326
# File 'lib/canvas_oauth/canvas_api.rb', line 324

def (course_id)
  ((course_id))
end

#create_assignment(course_id, params) ⇒ Object



295
296
297
# File 'lib/canvas_oauth/canvas_api.rb', line 295

def create_assignment(course_id, params)
  authenticated_post "/api/v1/courses/#{course_id}/assignments", { body: { assignment: params } }
end

#get_access_token(code) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/canvas_oauth/canvas_api.rb', line 66

def get_access_token(code)
  params = {
    body: {
      client_id: key,
      client_secret: secret,
      code: code
    }
  }
  
  response = self.class.post '/login/oauth2/token', params
  self.refresh_token = response['refresh_token']
  self.token = response['access_token']
end

#get_access_token_by_refresh_tokenObject



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/canvas_oauth/canvas_api.rb', line 80

def get_access_token_by_refresh_token
  params = {
    body: {
      grant_type: 'refresh_token',
      client_id: key,
      client_secret: secret,
      refresh_token: refresh_token
    }
  }
  
  response = self.class.post '/login/oauth2/token', params
  self.token = response['access_token']
  CanvasOauth::Authorization.update_token(refresh_token, token)
end

#get_account(account_id) ⇒ Object



227
228
229
# File 'lib/canvas_oauth/canvas_api.rb', line 227

def ()
  authenticated_get "/api/v1/accounts/#{}"
end

#get_account_courses(account_id) ⇒ Object



235
236
237
# File 'lib/canvas_oauth/canvas_api.rb', line 235

def ()
  paginated_get "/api/v1/accounts/#{}/courses"
end

#get_account_sub_accounts(account_id) ⇒ Object



231
232
233
# File 'lib/canvas_oauth/canvas_api.rb', line 231

def ()
  paginated_get "/api/v1/accounts/#{}/sub_accounts", { query: { :recursive => true } }
end

#get_account_users(account_id) ⇒ Object



239
240
241
# File 'lib/canvas_oauth/canvas_api.rb', line 239

def ()
  paginated_get "/api/v1/accounts/#{}/users"
end

#get_accounts_provisioning_report(account_id) ⇒ Object



219
220
221
# File 'lib/canvas_oauth/canvas_api.rb', line 219

def get_accounts_provisioning_report()
  get_report(, :provisioning_csv, 'parameters[accounts]' => true)
end

#get_all_course_users(course_id) ⇒ Object



259
260
261
# File 'lib/canvas_oauth/canvas_api.rb', line 259

def get_all_course_users(course_id)
  paginated_get "/api/v1/courses/#{course_id}/users", { query: {enrollment_state: ["active","invited","rejected","completed","inactive"] } }
end

#get_assignment(course_id, assignment_id) ⇒ Object



287
288
289
# File 'lib/canvas_oauth/canvas_api.rb', line 287

def get_assignment(course_id, assignment_id)
  authenticated_get "/api/v1/courses/#{course_id}/assignments/#{assignment_id}"
end

#get_assignments(course_id) ⇒ Object



283
284
285
# File 'lib/canvas_oauth/canvas_api.rb', line 283

def get_assignments(course_id)
  paginated_get "/api/v1/courses/#{course_id}/assignments"
end

#get_canvas_user_profileObject

get_canvas_user_profile get_course_active_pages course_external_tool_update account_external_tool_update get_school_details get_grade_students get_classroom_students



338
339
340
# File 'lib/canvas_oauth/canvas_api.rb', line 338

def 
  authenticated_get "/api/v1/users/#{canvas_user_id}/profile"
end

#get_classroom_students(account_id, class_id) ⇒ Object



368
369
370
# File 'lib/canvas_oauth/canvas_api.rb', line 368

def get_classroom_students(, class_id)
  paginated_get "/api/v1/accounts/#{}/classroom_students/#{class_id}"
end

#get_course(course_id) ⇒ Object



243
244
245
# File 'lib/canvas_oauth/canvas_api.rb', line 243

def get_course(course_id)
  authenticated_get "/api/v1/courses/#{course_id}"
end

#get_course_active_pages(course_id, publish = nil) ⇒ Object



342
343
344
345
346
347
348
# File 'lib/canvas_oauth/canvas_api.rb', line 342

def get_course_active_pages(course_id, publish=nil)
  unless publish.nil?
    paginated_get "/api/v1/courses/#{course_id}/pages?published=#{publish}&sort=created_at&order=desc"
  else
    paginated_get "/api/v1/courses/#{course_id}/pages?sort=created_at&order=desc"
  end
end

#get_course_active_students(course_id) ⇒ Object



271
272
273
# File 'lib/canvas_oauth/canvas_api.rb', line 271

def get_course_active_students(course_id)
  paginated_get "/api/v1/courses/#{course_id}/active_users"
end

#get_course_students(course_id) ⇒ Object



267
268
269
# File 'lib/canvas_oauth/canvas_api.rb', line 267

def get_course_students(course_id)
  paginated_get "/api/v1/courses/#{course_id}/students"
end

#get_course_teachers_and_tas(course_id) ⇒ Object



263
264
265
# File 'lib/canvas_oauth/canvas_api.rb', line 263

def get_course_teachers_and_tas(course_id)
  paginated_get "/api/v1/courses/#{course_id}/users", { query: { enrollment_type: ['teacher', 'ta'] } }
end

#get_course_users(course_id) ⇒ Object



255
256
257
# File 'lib/canvas_oauth/canvas_api.rb', line 255

def get_course_users(course_id)
  paginated_get "/api/v1/courses/#{course_id}/users"
end

#get_coursesObject



223
224
225
# File 'lib/canvas_oauth/canvas_api.rb', line 223

def get_courses
  paginated_get "/api/v1/courses"
end

#get_file(file_id) ⇒ Object



215
216
217
# File 'lib/canvas_oauth/canvas_api.rb', line 215

def get_file(file_id)
  authenticated_get "/api/v1/files/#{file_id}"
end

#get_grade_students(account_id, grade_id) ⇒ Object



364
365
366
# File 'lib/canvas_oauth/canvas_api.rb', line 364

def get_grade_students(, grade_id)
  paginated_get "/api/v1/accounts/#{}/grade_students/#{grade_id}"
end

#get_report(account_id, report_type, params) ⇒ Object

get_report get_file get_accounts_provisioning_report get_courses get_account get_account_sub_accounts get_account_courses get_account_users get_course get_section_enrollments get_user_enrollments get_course_users get_all_course_users get_course_teachers_and_tas get_course_students get_course_active_students get_section get_sections get_assignments get_assignment get_user_profile create_assignment update_assignment grade_assignment get_submission course_account_id root_account_id course_root_account_id



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/canvas_oauth/canvas_api.rb', line 198

def get_report(, report_type, params)
  report = authenticated_post("/api/v1/accounts/#{}/reports/#{report_type}", { body: params })
  report = authenticated_get "/api/v1/accounts/#{}/reports/#{report_type}/#{report['id']}"
  while (report['status'] == 'created' || report['status'] == 'running')
    sleep(4)
    report = authenticated_get "/api/v1/accounts/#{}/reports/#{report_type}/#{report['id']}"
  end

  if report['status'] == 'complete'
    file_id = report['file_url'].match(/files\/([0-9]+)\/download/)[1]
    file = get_file(file_id)
    return hash_csv(self.class.get(file['url'], limit: 15, parser: DefaultUTF8Parser).parsed_response)
  else
    return report
  end
end

#get_school_details(account_id) ⇒ Object



360
361
362
# File 'lib/canvas_oauth/canvas_api.rb', line 360

def get_school_details()
  authenticated_get "/api/v1/accounts/#{}/school_details"
end

#get_section(section_id) ⇒ Object



275
276
277
# File 'lib/canvas_oauth/canvas_api.rb', line 275

def get_section(section_id)
  authenticated_get "/api/v1/sections/#{section_id}"
end

#get_section_enrollments(section_id) ⇒ Object



247
248
249
# File 'lib/canvas_oauth/canvas_api.rb', line 247

def get_section_enrollments(section_id)
  paginated_get "/api/v1/sections/#{section_id}/enrollments"
end

#get_sections(course_id) ⇒ Object



279
280
281
# File 'lib/canvas_oauth/canvas_api.rb', line 279

def get_sections(course_id)
  paginated_get "/api/v1/courses/#{course_id}/sections", { query: { :include => ['students', 'avatar_url', 'enrollments'] } }
end

#get_submission(course_id, assignment_id, user_id) ⇒ Object



307
308
309
# File 'lib/canvas_oauth/canvas_api.rb', line 307

def get_submission(course_id, assignment_id, user_id)
  authenticated_get "/api/v1/courses/#{course_id}/assignments/#{assignment_id}/submissions/#{user_id}"
end

#get_user_enrollments(user_id) ⇒ Object



251
252
253
# File 'lib/canvas_oauth/canvas_api.rb', line 251

def get_user_enrollments(user_id)
  paginated_get "/api/v1/users/#{user_id}/enrollments"
end

#get_user_profile(user_id) ⇒ Object



291
292
293
# File 'lib/canvas_oauth/canvas_api.rb', line 291

def (user_id)
  authenticated_get "/api/v1/users/#{user_id}/profile"
end

#grade_assignment(course_id, assignment_id, user_id, params) ⇒ Object



303
304
305
# File 'lib/canvas_oauth/canvas_api.rb', line 303

def grade_assignment(course_id, assignment_id, user_id, params)
  authenticated_put "/api/v1/courses/#{course_id}/assignments/#{assignment_id}/submissions/#{user_id}", { body: params }
end

#hash_csv(csv_string) ⇒ Object

Needs to be refactored to somewhere more generic



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/canvas_oauth/canvas_api.rb', line 149

def hash_csv(csv_string)
  require 'csv'

  csv = csv_string.is_a?(String) ? CSV.parse(csv_string) : csv_string
  headers = csv.shift
  output = []

  csv.each do |row|
    hash = {}
    headers.each do |header|
      hash[header] = row.shift.to_s
    end
    output << hash
  end

  return output
end

#hex_sis_id(name, value) ⇒ Object



139
140
141
142
# File 'lib/canvas_oauth/canvas_api.rb', line 139

def hex_sis_id(name, value)
  hex = value.unpack("H*")[0]
  return "hex:#{name}:#{hex}"
end

#paginated_get(url, params = {}) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/canvas_oauth/canvas_api.rb', line 107

def paginated_get(url, params = {})
  params[:query] ||= {}
  params[:query][:per_page] = PER_PAGE

  all_pages = []

  while url && current_page = authenticated_get(url, params) do
    all_pages.concat(current_page) if valid_page?(current_page)

    links = LinkHeader.parse(current_page.headers['link'])
    url = links.find_link(["rel", "next"]).try(:href)
    params[:query] = nil if params[:query]
  end

  all_pages
end

#qalam_auth_url(qalam_url, redirect_uri, oauth2_state) ⇒ Object



62
63
64
# File 'lib/canvas_oauth/canvas_api.rb', line 62

def qalam_auth_url(qalam_url, redirect_uri, oauth2_state)
  "#{qalam_url}/login/oauth2/auth?client_id=#{key}&response_type=code&state=#{oauth2_state}&redirect_uri=#{redirect_uri}"
end

#root_account_id(account_id) ⇒ Object



316
317
318
319
320
321
322
# File 'lib/canvas_oauth/canvas_api.rb', line 316

def ()
  if  &&  = ()
    root_id = ['root_account_id']
  end

  root_id || 
end

#update_assignment(course_id, assignment_id, params) ⇒ Object



299
300
301
# File 'lib/canvas_oauth/canvas_api.rb', line 299

def update_assignment(course_id, assignment_id, params)
  authenticated_put "/api/v1/courses/#{course_id}/assignments/#{assignment_id}", { body: { assignment: params } }
end

#valid_page?(page) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
# File 'lib/canvas_oauth/canvas_api.rb', line 144

def valid_page?(page)
  page && page.size > 0
end