Mercurial > prosody-modules
diff mod_http_oauth2/mod_http_oauth2.lua @ 4340:7cd3b7ec59e9
mod_http_oauth2: Rudimentary support for scopes (but not really)
We don't support limiting access, but this change will inform the
client what permissions the created token has (e.g. is the user an
admin or not).
There is some work in progress on real scope support.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sat, 16 Jan 2021 19:47:22 +0000 |
parents | ec33b3b1136c |
children | dee6b5098278 |
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua Fri Jan 15 18:57:12 2021 +0000 +++ b/mod_http_oauth2/mod_http_oauth2.lua Sat Jan 16 19:47:22 2021 +0000 @@ -14,6 +14,15 @@ local clients = module:open_store("oauth2_clients", "map"); +local function filter_scopes(request_jid, requested_scope_string) --luacheck: ignore 212/requested_scope_string + -- We currently don't really support scopes, so override + -- to whatever real permissions the user has + if usermanager.is_admin(request_jid, module.host) then + return "prosody:scope:admin"; + end + return "prosody:scope:default"; +end + local function code_expired(code) return os.difftime(os.time(), code.issued) > 120; end @@ -47,6 +56,7 @@ token_type = "bearer"; access_token = token; expires_in = ttl; + scope = scope; -- TODO: include refresh_token when implemented }; end @@ -58,25 +68,22 @@ local request_jid = assert(params.username, oauth_error("invalid_request", "missing 'username' (JID)")); local request_password = assert(params.password, oauth_error("invalid_request", "missing 'password'")); local request_username, request_host, request_resource = jid.prepped_split(request_jid); - if params.scope and params.scope ~= "" then - return oauth_error("invalid_scope", "unknown scope requested"); - end + if not (request_username and request_host) or request_host ~= module.host then return oauth_error("invalid_request", "invalid JID"); end - if usermanager.test_password(request_username, request_host, request_password) then - local granted_jid = jid.join(request_username, request_host, request_resource); - return json.encode(new_access_token(granted_jid, nil, nil)); + if not usermanager.test_password(request_username, request_host, request_password) then + return oauth_error("invalid_grant", "incorrect credentials"); end - return oauth_error("invalid_grant", "incorrect credentials"); + + local granted_jid = jid.join(request_username, request_host, request_resource); + local granted_scopes = filter_scopes(granted_jid, params.scope); + return json.encode(new_access_token(granted_jid, granted_scopes, nil)); end function response_type_handlers.code(params, granted_jid) if not params.client_id then return oauth_error("invalid_request", "missing 'client_id'"); end if not params.redirect_uri then return oauth_error("invalid_request", "missing 'redirect_uri'"); end - if params.scope and params.scope ~= "" then - return oauth_error("invalid_scope", "unknown scope requested"); - end local client_owner, client_host, client_id = jid.prepped_split(params.client_id); if client_host ~= module.host then @@ -88,8 +95,14 @@ return oauth_error("invalid_client", "incorrect credentials"); end + local granted_scopes = filter_scopes(granted_jid, params.scope); + local code = uuid.generate(); - assert(codes:set(params.client_id .. "#" .. code, {issued = os.time(); granted_jid = granted_jid})); + assert(codes:set(params.client_id .. "#" .. code, { + issued = os.time(); + granted_jid = granted_jid; + granted_scopes = granted_scopes; + })); local redirect = url.parse(params.redirect_uri); local query = http.formdecode(redirect.query or ""); @@ -141,7 +154,7 @@ end assert(codes:set(client_owner, client_id .. "#" .. params.code, nil)); - return json.encode(new_access_token(code.granted_jid, nil, nil)); + return json.encode(new_access_token(code.granted_jid, code.granted_scopes, nil)); end local function check_credentials(request)