comparison mod_http_oauth2/mod_http_oauth2.lua @ 5186:fa3059e653fa

mod_http_oauth2: Implement the Implicit flow Everyone says this is insecure and bad, but it's also the only thing that makes sense for e.g. pure JavaScript clients, but hey implement this even more complicated thing instead!
author Kim Alvefur <zash@zash.se>
date Thu, 02 Mar 2023 22:06:50 +0100
parents 09d6bbd6c8a4
children 6a3c1febd7be
comparison
equal deleted inserted replaced
5185:09d6bbd6c8a4 5186:fa3059e653fa
90 local granted_jid = jid.join(request_username, request_host, request_resource); 90 local granted_jid = jid.join(request_username, request_host, request_resource);
91 local granted_scopes = filter_scopes(request_username, request_host, params.scope); 91 local granted_scopes = filter_scopes(request_username, request_host, params.scope);
92 return json.encode(new_access_token(granted_jid, granted_scopes, nil)); 92 return json.encode(new_access_token(granted_jid, granted_scopes, nil));
93 end 93 end
94 94
95 -- TODO response_type_handlers have some common boilerplate code, refactor?
96
95 function response_type_handlers.code(params, granted_jid) 97 function response_type_handlers.code(params, granted_jid)
96 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end 98 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
97 99
98 local client_owner, client_host, client_id = jid.prepped_split(params.client_id); 100 local client_owner, client_host, client_id = jid.prepped_split(params.client_id);
99 if client_host ~= module.host then 101 if client_host ~= module.host then
123 table.insert(query, { name = "code", value = code }) 125 table.insert(query, { name = "code", value = code })
124 if params.state then 126 if params.state then
125 table.insert(query, { name = "state", value = params.state }); 127 table.insert(query, { name = "state", value = params.state });
126 end 128 end
127 redirect.query = http.formencode(query); 129 redirect.query = http.formencode(query);
130
131 return {
132 status_code = 302;
133 headers = {
134 location = url.build(redirect);
135 };
136 }
137 end
138
139 -- Implicit flow
140 function response_type_handlers.token(params, granted_jid)
141 if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end
142
143 local client_owner, client_host, client_id = jid.prepped_split(params.client_id);
144 if client_host ~= module.host then
145 return oauth_error("invalid_client", "incorrect credentials");
146 end
147 local client, err = clients:get(client_owner, client_id);
148 if err then error(err); end
149 if not client then
150 return oauth_error("invalid_client", "incorrect credentials");
151 end
152
153 local granted_scopes = filter_scopes(client_owner, client_host, params.scope);
154 local token_info = new_access_token(granted_jid, granted_scopes, nil);
155
156 local redirect = url.parse(client.redirect_uri);
157 token_info.state = params.state;
158 redirect.fragment = http.formencode(token_info);
128 159
129 return { 160 return {
130 status_code = 302; 161 status_code = 302;
131 headers = { 162 headers = {
132 location = url.build(redirect); 163 location = url.build(redirect);
215 end 246 end
216 247
217 -- TODO How would this make sense with components? 248 -- TODO How would this make sense with components?
218 -- Have an admin authenticate maybe? 249 -- Have an admin authenticate maybe?
219 response_type_handlers.code = nil; 250 response_type_handlers.code = nil;
251 response_type_handlers.token = nil;
220 grant_type_handlers.authorization_code = nil; 252 grant_type_handlers.authorization_code = nil;
221 check_credentials = function () return false end 253 check_credentials = function () return false end
222 end 254 end
223 255
224 function handle_token_grant(event) 256 function handle_token_grant(event)