|
1 module:set_global(); |
|
2 |
|
3 local http = require "util.http"; |
|
4 local jid = require "util.jid"; |
|
5 local json = require "util.json"; |
|
6 local usermanager = require "core.usermanager"; |
|
7 local errors = require "util.error"; |
|
8 |
|
9 local function oauth_error(err_name, err_desc) |
|
10 return errors.new({ |
|
11 type = "modify"; |
|
12 condition = "bad-request"; |
|
13 code = err_name == "invalid_client" and 401 or 400; |
|
14 text = err_desc and (err_name..": "..err_desc) or err_name; |
|
15 context = { oauth2_response = { error = err_name, error_description = err_desc } }; |
|
16 }); |
|
17 end |
|
18 |
|
19 local function new_access_token(username, host, scope, ttl) |
|
20 return { |
|
21 token_type = "bearer"; |
|
22 access_token = "test-token"; |
|
23 expires_in = ttl; |
|
24 -- TODO: include refresh_token when implemented |
|
25 }; |
|
26 end |
|
27 |
|
28 local grant_type_handlers = {}; |
|
29 |
|
30 function grant_type_handlers.password(params) |
|
31 local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); |
|
32 local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); |
|
33 local request_username, request_host = jid.prepped_split(request_jid); |
|
34 if params.scope then |
|
35 return oauth_error("invalid_scope", "unknown scope requested"); |
|
36 end |
|
37 if not (request_username and request_host) or not (hosts[request_host]) then |
|
38 return oauth_error("invalid_request", "invalid JID"); |
|
39 end |
|
40 if usermanager.test_password(request_username, request_host, request_password) then |
|
41 return json.encode(new_access_token(request_username, request_host, nil, nil)); |
|
42 end |
|
43 return oauth_error("invalid_grant", "incorrect credentials"); |
|
44 end |
|
45 |
|
46 function handle_token_grant(event) |
|
47 local params = http.formdecode(event.request.body); |
|
48 if not params then |
|
49 return oauth_error("invalid_request"); |
|
50 end |
|
51 local grant_type = params.grant_type |
|
52 local grant_handler = grant_type_handlers[grant_type]; |
|
53 if not grant_handler then |
|
54 return oauth_error("unsupported_grant_type"); |
|
55 end |
|
56 return grant_handler(params); |
|
57 end |
|
58 |
|
59 module:depends("http"); |
|
60 module:provides("http", { |
|
61 route = { |
|
62 ["POST /token"] = handle_token_grant; |
|
63 }; |
|
64 }); |
|
65 |
|
66 local http_server = require "net.http.server"; |
|
67 |
|
68 module:hook_object_event(http_server, "http-error", function (event) |
|
69 local oauth2_response = event.error and event.error.context and event.error.context.oauth2_response; |
|
70 if not oauth2_response then |
|
71 return; |
|
72 end |
|
73 event.response.headers.content_type = "application/json"; |
|
74 event.response.status_code = event.error.code or 400; |
|
75 return json.encode(oauth2_response); |
|
76 end, 5); |