# HG changeset patch # User Kim Alvefur # Date 1684345227 -7200 # Node ID 1c78a97a1091a45fa978960f8260d70bf1f44969 # Parent 398d936e77fbd05c6ad2379070f195f9ff9272d2 mod_http_oauth2: Add a special "xmpp" scope that grants the users' default role This will be the first step towards defining a standard set of XMPP scopes. "xmpp" behaves as an alias for the user's default role, so that the client does not need to know about the various prosody:* roles. diff -r 398d936e77fb -r 1c78a97a1091 mod_http_oauth2/README.markdown --- a/mod_http_oauth2/README.markdown Wed May 17 18:49:22 2023 +0200 +++ b/mod_http_oauth2/README.markdown Wed May 17 19:40:27 2023 +0200 @@ -165,12 +165,22 @@ OAuth supports "scopes" as a way to grant clients limited access. -There are currently no standard scopes defined for XMPP. This is something -that we intend to change, e.g. by definitions provided in a future XEP. This -means that clients you authorize currently have unrestricted access to your -account (including the ability to change your password and lock you out!). So, -for now, while using OAuth clients can prevent leaking your password to them, -it is not currently suitable for connecting untrusted clients to your account. +There are currently no standard scopes defined for XMPP. This is +something that we intend to change, e.g. by definitions provided in a +future XEP. This means that clients you authorize currently have to +choose between unrestricted access to your account (including the +ability to change your password and lock you out!) and zero access. So, +for now, while using OAuth clients can prevent leaking your password to +them, it is not currently suitable for connecting untrusted clients to +your account. + +As a first step, the `xmpp` scope is supported, and corresponds to +whatever permissions the user would have when logged in over XMPP. + +Further, known Prosody roles can be used as scopes. + +OpenID scopes such as `openid` and `profile` can be used for "Login +with XMPP" without granting access to more than limited profile details. ## Compatibility diff -r 398d936e77fb -r 1c78a97a1091 mod_http_oauth2/mod_http_oauth2.lua --- a/mod_http_oauth2/mod_http_oauth2.lua Wed May 17 18:49:22 2023 +0200 +++ b/mod_http_oauth2/mod_http_oauth2.lua Wed May 17 19:40:27 2023 +0200 @@ -102,7 +102,7 @@ return array(scope_string:gmatch("%S+")); end -local openid_claims = set.new({ "openid", "profile"; "email"; "address"; "phone" }); +local openid_claims = set.new({ "openid"; "profile"; "email"; "address"; "phone" }); -- array -> array, array, array local function split_scopes(scope_list) @@ -111,7 +111,7 @@ for _, scope in ipairs(scope_list) do if openid_claims:contains(scope) then claims:push(scope); - elseif all_roles[scope] then + elseif scope == "xmpp" or all_roles[scope] then roles:push(scope); else unknown:push(scope); @@ -121,7 +121,7 @@ end local function can_assume_role(username, requested_role) - return usermanager.user_can_assume_role(username, module.host, requested_role); + return requested_role == "xmpp" or usermanager.user_can_assume_role(username, module.host, requested_role); end -- function (string) : function(string) : boolean @@ -223,6 +223,12 @@ refresh_token = refresh_token_info.token; end + if role == "xmpp" then + -- Special scope meaning the users default role. + local user_default_role = usermanager.get_user_role(jid.node(token_jid), module.host); + role = user_default_role and user_default_role.name; + end + local access_token, access_token_info = tokens.create_token(token_jid, grant.id, role, default_access_ttl, "oauth2"); local expires_at = access_token_info.expires; @@ -1080,7 +1086,8 @@ authorization_endpoint = handle_authorization_request and module:http_url() .. "/authorize" or nil; token_endpoint = handle_token_grant and module:http_url() .. "/token" or nil; registration_endpoint = handle_register_request and module:http_url() .. "/register" or nil; - scopes_supported = usermanager.get_all_roles and array(it.keys(usermanager.get_all_roles(module.host))):append(array(openid_claims:items())); + scopes_supported = usermanager.get_all_roles + and array(it.keys(usermanager.get_all_roles(module.host))):push("xmpp"):append(array(openid_claims:items())); response_types_supported = array(it.keys(response_type_handlers)); token_endpoint_auth_methods_supported = array({ "client_secret_post"; "client_secret_basic" }); op_policy_uri = module:get_option_string("oauth2_policy_url", nil);