8 local encodings = require "util.encodings"; |
8 local encodings = require "util.encodings"; |
9 local base64 = encodings.base64; |
9 local base64 = encodings.base64; |
10 |
10 |
11 local tokens = module:depends("tokenauth"); |
11 local tokens = module:depends("tokenauth"); |
12 |
12 |
13 local clients = module:open_store("oauth2_clients"); |
13 local clients = module:open_store("oauth2_clients", "map"); |
14 local codes = module:open_store("oauth2_codes", "map"); |
14 local codes = module:open_store("oauth2_codes", "map"); |
15 |
15 |
16 local function oauth_error(err_name, err_desc) |
16 local function oauth_error(err_name, err_desc) |
17 return errors.new({ |
17 return errors.new({ |
18 type = "modify"; |
18 type = "modify"; |
58 if not params.redirect_uri then return oauth_error("invalid_request", "missing 'redirect_uri'"); end |
58 if not params.redirect_uri then return oauth_error("invalid_request", "missing 'redirect_uri'"); end |
59 if params.scope and params.scope ~= "" then |
59 if params.scope and params.scope ~= "" then |
60 return oauth_error("invalid_scope", "unknown scope requested"); |
60 return oauth_error("invalid_scope", "unknown scope requested"); |
61 end |
61 end |
62 |
62 |
63 local client, err = clients:get(params.client_id); |
63 local client_owner, client_host, client_id = jid.prepped_split(params.client_id); |
64 module:log("debug", "clients:get(%q) --> %q, %q", params.client_id, client, err); |
64 if client_host ~= module.host then |
|
65 return oauth_error("invalid_client", "incorrect credentials"); |
|
66 end |
|
67 local client, err = clients:get(client_owner, client_id); |
65 if err then error(err); end |
68 if err then error(err); end |
66 if not client then |
69 if not client then |
67 return oauth_error("invalid_client", "incorrect credentials"); |
70 return oauth_error("invalid_client", "incorrect credentials"); |
68 end |
71 end |
69 |
72 |
70 local code = uuid.generate(); |
73 local code = uuid.generate(); |
71 assert(codes:set(params.client_id, code, { issued = os.time(), granted_jid = granted_jid, })); |
74 assert(codes:set(client_owner, client_id .. "#" .. code, {issued = os.time(); granted_jid = granted_jid})); |
72 |
75 |
73 local redirect = url.parse(params.redirect_uri); |
76 local redirect = url.parse(params.redirect_uri); |
74 local query = http.formdecode(redirect.query or ""); |
77 local query = http.formdecode(redirect.query or ""); |
75 if type(query) ~= "table" then query = {}; end |
78 if type(query) ~= "table" then query = {}; end |
76 table.insert(query, { name = "code", value = code }) |
79 table.insert(query, { name = "code", value = code }) |
93 if not params.code then return oauth_error("invalid_request", "missing 'code'"); end |
96 if not params.code then return oauth_error("invalid_request", "missing 'code'"); end |
94 if params.scope and params.scope ~= "" then |
97 if params.scope and params.scope ~= "" then |
95 return oauth_error("invalid_scope", "unknown scope requested"); |
98 return oauth_error("invalid_scope", "unknown scope requested"); |
96 end |
99 end |
97 |
100 |
98 local client, err = clients:get(params.client_id); |
101 local client_owner, client_host, client_id = jid.prepped_split(params.client_id); |
|
102 if client_host ~= module.host then |
|
103 module:log("debug", "%q ~= %q", client_host, module.host); |
|
104 return oauth_error("invalid_client", "incorrect credentials"); |
|
105 end |
|
106 local client, err = clients:get(client_owner, client_id); |
99 if err then error(err); end |
107 if err then error(err); end |
100 if not client or client.secret ~= params.client_secret then |
108 if not client or client.client_secret ~= params.client_secret then |
101 return oauth_error("invalid_client", "incorrect credentials"); |
109 module:log("debug", "client_secret mismatch"); |
102 end |
110 return oauth_error("invalid_client", "incorrect credentials"); |
103 local code, err = codes:get(params.client_id, params.code); |
111 end |
|
112 local code, err = codes:get(client_owner, client_id .. "#" .. params.code); |
104 if err then error(err); end |
113 if err then error(err); end |
105 if not code or type(code) ~= "table" or os.difftime(os.time(), code.issued) > 900 then |
114 if not code or type(code) ~= "table" or os.difftime(os.time(), code.issued) > 900 then |
106 return oauth_error("invalid_client", "incorrect credentials"); |
115 module:log("debug", "authorization_code invalid or expired: %q", code); |
107 end |
116 return oauth_error("invalid_client", "incorrect credentials"); |
108 assert(codes:set(params.client_id, params.code, nil)); |
117 end |
109 |
118 assert(codes:set(client_owner, client_id .. "#" .. params.code, nil)); |
110 |
119 |
111 return json.encode(new_access_token(code.granted_jid, nil, nil)); |
120 return json.encode(new_access_token(code.granted_jid, nil, nil)); |
112 end |
121 end |
113 |
122 |
114 local function check_credentials(request) |
123 local function check_credentials(request) |