forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanalytics_service.rb
More file actions
63 lines (54 loc) · 2.09 KB
/
Copy pathanalytics_service.rb
File metadata and controls
63 lines (54 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
57
58
59
60
61
62
63
require 'duration'
require 'net/http'
require 'securerandom'
module Lti
class AnalyticsService
class Token < Struct.new(:tool, :user, :course, :timestamp, :nonce)
def self.create(tool, user, course)
Token.new(tool, user, course, Time.now, SecureRandom.hex(8))
end
def serialize
key = tool.shard.settings[:encryption_key]
payload = [tool.id, user.id, course.id, timestamp.to_i, nonce].join('-')
"#{payload}-#{Canvas::Security.hmac_sha1(payload, key)}"
end
def self.parse_and_validate(serialized_token)
parts = serialized_token.split('-')
tool = ContextExternalTool.find(parts[0].to_i)
key = tool.shard.settings[:encryption_key]
unless parts.size == 6 && Canvas::Security.hmac_sha1(parts[0..-2].join('-'), key) == parts[-1]
raise BasicLTI::BasicOutcomes::Unauthorized, "Invalid analytics service token"
end
user = User.find(parts[1].to_i)
course = Course.find(parts[2].to_i)
timestamp = parts[3].to_i
nonce = parts[4]
Token.new(tool, user, course, timestamp, nonce)
end
end
def self.create_token(tool, user, course)
Token.create(tool, user, course).serialize
end
def self.log_page_view(token, opts={})
course = token.course
user = token.user
tool = token.tool
duration = opts[:duration]
seconds = duration ? Duration.new(duration).to_i : nil
if seconds
course.all_enrollments.where(:user_id => user).
update_all(['total_activity_time = COALESCE(total_activity_time, 0) + ?', seconds])
end
access = AssetUserAccess.where(user_id: user, asset_code: tool.asset_string).first_or_initialize
access.log(course, group_code: "external_tools", category: "external_tools")
if PageView.page_views_enabled?
PageView.new(user: user, context: course, account: course.account).tap { |p|
p.request_id = SecureRandom.uuid
p.url = opts[:url]
# TODO: override 10m cap?
p.interaction_seconds = seconds
}.save
end
end
end
end