-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlambda_function.rb
More file actions
64 lines (60 loc) · 1.49 KB
/
lambda_function.rb
File metadata and controls
64 lines (60 loc) · 1.49 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
64
require 'aws-sdk-dynamodb'
require 'json'
DDB = Aws::DynamoDB::Client.new
DDB_TABLE = ENV['DDB_TABLE_NAME']
DENIED = {isAuthorized: false}
def lambda_handler(event:, context:)
return nil unless authorizer_event?(event)
(t, id, r, m, ip) = parse_event(event)
ts = Time.now.to_i
return DENIED if t.nil?
db_req = {
key: {
'token' => t,
'path' => "#{id}#{r}",
},
table_name: DDB_TABLE,
}
db_res = DDB.get_item(db_req)
return DENIED unless (item = db_res.item)
return DENIED unless item['valid']
if item['methods'].class == Array
return DENIED unless item['methods'].include?(m)
end
if item['valid_from']
return DENIED unless ts >= item['valid_from']
end
if item['valid_until']
return DENIED unless ts <= item['valid_until']
end
allowed = {isAuthorized: true}
allowed[:context] = item['context'] if item['context'].class == Hash
allowed
end
def authorizer_event?(e)
e['version'] == '2.0' && e['type'] == 'REQUEST'
end
def parse_event(e)
r = e['routeKey'].split(nil, 2)[1]
t = e.dig('identitySource', 0)
id = e.dig('requestContext', 'apiId')
m = e.dig('requestContext', 'http', 'method')
m.downcase! if m.class == String
ip = e.dig('requestContext', 'http', 'sourceIp')
if t.class == String
ta = t.split(nil, 2)
case ta.length
when 0
t = nil
when 1
t = ta[0]
when 2
if ta[0] == 'Basic' || ta[0] == 'Bearer'
t = ta[1]
else
t = nil
end
end
end
[t, id, r, m, ip]
end