# HG changeset patch # User Matthew Wild # Date 1610826442 0 # Node ID 7cd3b7ec59e921f78a0aeb039608fa60e9891947 # Parent 3b7847c9bd2601349a4d7de3665bce3a70d45a37 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. diff -r 3b7847c9bd26 -r 7cd3b7ec59e9 mod_http_oauth2/mod_http_oauth2.lua --- 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)