-
Notifications
You must be signed in to change notification settings - Fork 0
/
atsauth.lua
157 lines (123 loc) · 4.56 KB
/
atsauth.lua
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
local M = {}
function M.authenticate()
local cjson = require "cjson"
local jwt = require "resty.jwt"
local os = require "os"
ngx.req.clear_header("X-Auth-UserId")
-- Read token from header
local auth_header = ngx.var.http_Authorization
if auth_header == nil then
ngx.log(ngx.INFO, "No Authorization header")
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- ngx.log(ngx.INFO, "Authorization: " .. auth_header)
-- require Bearer token
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
-- -- Read token from cookie
--
-- local cookie = ngx.var.cookie_jwt
-- if cookie == nil then
-- ngx.log(ngx.INFO, "Missing JWT cookie")
-- ngx.exit(ngx.HTTP_UNAUTHORIZED)
-- end
-- ngx.log(ngx.INFO, "JWT cookie: " .. cookie)
-- local token = cookie
-- Read secret key
secret = os.getenv("JWT_SECRET")
assert(secret ~= nil, "Environment variable JWT_SECRET not set")
-- Verify token
ngx.log(ngx.DEBUG, "Validating token: ", token)
local jwt_obj = jwt:load_jwt(token)
local verified = jwt:verify_jwt_obj(secret, jwt_obj)
if not verified.verified then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.log(ngx.INFO, jwt_obj.reason)
ngx.say(jwt_obj.reason)
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
local parser = require "rds.parser"
ngx.log(ngx.DEBUG, "Check revocation for token: ", token)
local resp = ngx.location.capture("/token/check_revocation/" .. token)
local res, err = parser.parse(resp.body)
local valid = res.resultset[1]["exists"]
if not valid then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.log(ngx.INFO, 'token revoked')
ngx.say('token revoked')
ngx.exit(ngx.HTTP_UNAUTHORIZED)
end
-- write the X-Auth-UserId header
ngx.header["X-Auth-UserId"] = jwt_obj.payload.sub
ngx.req.set_header("X-Auth-UserId", jwt_obj.payload.sub)
end
function M.authorize()
local parser = require "rds.parser"
local function can_use_vm(user, vmname, params)
local resp = ngx.location.capture("/access/vm/" .. user .. "/" .. vmname)
local res, err = parser.parse(resp.body)
return res.resultset[1]["exists"]
end
local function can_access_project(user, projectid, params)
local resp = ngx.location.capture("/access/project/" .. user .. "/" .. projectid)
local res, err = parser.parse(resp.body)
return res.resultset[1]["exists"];
end
local function ok(user, ignored, params)
return true
end
-- Authorization table
-- {"METHOD" (or wildcard), "/path" (lua match pattern), handler}
local paths = {
-- Senza: POST event data
{"POST", "^/android/sensors/.+/(%w+)$", can_use_vm},
-- Senza: retrieve JSON schemas of the event data
{"GET", "^/android/sensors/.+", ok},
-- List/Create vms
{"GET", "^/android$", ok},
{"POST", "^/android$", ok},
-- Projects
{"GET", "^/projects$", ok},
{"POST", "^/projects$", ok},
{"*", "^/projects/(%w+)", can_access_project},
-- Images
{"GET", "^/images$", ok},
-- Common avm actions
{"*", "^/android/(%w+)", can_use_vm},
-- User related
{"POST", "^/user/logout$", ok},
{"GET", "^/user/quota$", ok},
{"GET", "^/user/whoami$", ok},
-- Xtext
{"*", "^/xtext/.+$", ok},
{"*", "^/xtext-service/.+$", ok},
}
local method = ngx.req.get_method()
local uri = ngx.var.uri
local params = ngx.req.get_uri_args()
-- Get the user id from the "response" object, as the authentication
-- component modified it before us
local userid = ngx.resp.get_headers()["X-Auth-UserId"]
for i, rule in pairs(paths) do
local rule_method = rule[1];
local path = rule[2];
local handler = rule[3];
if method == rule_method or rule_method == "*" then
local match = uri:match(path)
if match ~= nil
then
if handler(userid, match, params) then
ngx.log(ngx.DEBUG, "User can access ", uri)
else
-- Failure, serve something else if there is no authorization
ngx.log(ngx.ERR, "User does not have access to ", uri)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
return true;
end
end
end
-- Patch not matched ; assume authorization failure
ngx.log(ngx.ERR, "User does not have access to ", uri)
ngx.exit(ngx.HTTP_FORBIDDEN)
end
return M