aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_oauth.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_oauth.erl')
-rw-r--r--src/ejabberd_oauth.erl52
1 files changed, 32 insertions, 20 deletions
diff --git a/src/ejabberd_oauth.erl b/src/ejabberd_oauth.erl
index 246bac127..0397571b2 100644
--- a/src/ejabberd_oauth.erl
+++ b/src/ejabberd_oauth.erl
@@ -90,7 +90,7 @@ start() ->
get_commands_spec() ->
[
#ejabberd_commands{name = oauth_issue_token, tags = [oauth],
- desc = "Issue an oauth token. Available scopes are the ones usable by ejabberd admins",
+ desc = "Issue an oauth token for the given jid",
module = ?MODULE, function = oauth_issue_token,
args = [{jid, string},{scopes, string}],
policy = restricted,
@@ -106,11 +106,11 @@ get_commands_spec() ->
result = {tokens, {list, {token, {tuple, [{token, string}, {user, string}, {scope, string}, {expires_in, string}]}}}}
},
#ejabberd_commands{name = oauth_list_scopes, tags = [oauth],
- desc = "List scopes that can be granted to tokens generated through the command line",
+ desc = "List scopes that can be granted to tokens generated through the command line, together with the commands they allow",
module = ?MODULE, function = oauth_list_scopes,
args = [],
policy = restricted,
- result = {scopes, {list, {scope, string}}}
+ result = {scopes, {list, {scope, {tuple, [{scope, string}, {commands, string}]}}}}
},
#ejabberd_commands{name = oauth_revoke_token, tags = [oauth],
desc = "Revoke authorization for a token",
@@ -153,7 +153,7 @@ oauth_revoke_token(Token) ->
oauth_list_tokens().
oauth_list_scopes() ->
- get_cmd_scopes().
+ [ {Scope, string:join([atom_to_list(Cmd) || Cmd <- Cmds], ",")} || {Scope, Cmds} <- dict:to_list(get_cmd_scopes())].
@@ -240,7 +240,7 @@ authenticate_client(Client, Ctx) -> {ok, {Ctx, {client, Client}}}.
verify_resowner_scope({user, _User, _Server}, Scope, Ctx) ->
Cmds = ejabberd_commands:get_commands(),
- Cmds1 = [sasl_auth | Cmds],
+ Cmds1 = ['ejabberd:user', 'ejabberd:admin', sasl_auth | Cmds],
RegisteredScope = [atom_to_binary(C, utf8) || C <- Cmds1],
case oauth2_priv_set:is_subset(oauth2_priv_set:new(Scope),
oauth2_priv_set:new(RegisteredScope)) of
@@ -254,17 +254,27 @@ verify_resowner_scope(_, _, _) ->
get_cmd_scopes() ->
- Cmds = lists:filter(fun(Cmd) -> case ejabberd_commands:get_command_policy(Cmd) of
- {ok, Policy} when Policy =/= restricted -> true;
- _ -> false
- end end,
- ejabberd_commands:get_commands()),
- [atom_to_binary(C, utf8) || C <- Cmds].
+ ScopeMap = lists:foldl(fun(Cmd, Accum) ->
+ case ejabberd_commands:get_command_policy_and_scope(Cmd) of
+ {ok, Policy, Scopes} when Policy =/= restricted ->
+ lists:foldl(fun(Scope, Accum2) ->
+ dict:append(Scope, Cmd, Accum2)
+ end, Accum, Scopes);
+ _ -> Accum
+ end end, dict:new(), ejabberd_commands:get_commands()),
+ ScopeMap.
+
+ %Scps = lists:flatmap(fun(Cmd) -> case ejabberd_commands:get_command_policy_and_scope(Cmd) of
+ % {ok, Policy, Scopes} when Policy =/= restricted -> Scopes;
+ % _ -> []
+ % end end,
+ % ejabberd_commands:get_commands()),
+ %lists:usort(Scps).
%% This is callback for oauth tokens generated through the command line. Only open and admin commands are
%% made available.
verify_client_scope({client, ejabberd_ctl}, Scope, Ctx) ->
- RegisteredScope = get_cmd_scopes(),
+ RegisteredScope = dict:fetch_keys(get_cmd_scopes()),
case oauth2_priv_set:is_subset(oauth2_priv_set:new(Scope),
oauth2_priv_set:new(RegisteredScope)) of
true ->
@@ -299,7 +309,7 @@ associate_refresh_token(_RefreshToken, _Context, AppContext) ->
{ok, AppContext}.
-check_token(User, Server, Scope, Token) ->
+check_token(User, Server, ScopeList, Token) ->
LUser = jid:nodeprep(User),
LServer = jid:nameprep(Server),
case catch mnesia:dirty_read(oauth_token, Token) of
@@ -308,23 +318,25 @@ check_token(User, Server, Scope, Token) ->
expire = Expire}] ->
{MegaSecs, Secs, _} = os:timestamp(),
TS = 1000000 * MegaSecs + Secs,
- oauth2_priv_set:is_member(
- Scope, oauth2_priv_set:new(TokenScope)) andalso
- Expire > TS;
+ TokenScopeSet = oauth2_priv_set:new(TokenScope),
+ lists:any(fun(Scope) ->
+ oauth2_priv_set:is_member(Scope, TokenScopeSet) end,
+ ScopeList) andalso Expire > TS;
_ ->
false
end.
-check_token(Scope, Token) ->
+check_token(ScopeList, Token) ->
case catch mnesia:dirty_read(oauth_token, Token) of
[#oauth_token{us = US,
scope = TokenScope,
expire = Expire}] ->
{MegaSecs, Secs, _} = os:timestamp(),
TS = 1000000 * MegaSecs + Secs,
- case oauth2_priv_set:is_member(
- Scope, oauth2_priv_set:new(TokenScope)) andalso
- Expire > TS of
+ TokenScopeSet = oauth2_priv_set:new(TokenScope),
+ case lists:any(fun(Scope) ->
+ oauth2_priv_set:is_member(Scope, TokenScopeSet) end,
+ ScopeList) andalso Expire > TS of
true -> {ok, user, US};
false -> false
end;