]> granicus.if.org Git - ejabberd/commitdiff
Add support for sending back missing scope error to API ReST command calls
authorMickael Remond <mremond@process-one.net>
Sat, 30 Jul 2016 16:51:54 +0000 (18:51 +0200)
committerMickael Remond <mremond@process-one.net>
Sat, 30 Jul 2016 16:51:54 +0000 (18:51 +0200)
src/cyrsasl_oauth.erl
src/ejabberd_commands.erl
src/ejabberd_oauth.erl
src/mod_http_api.erl

index 16f1e3dfb775cbc45d016310175b2499aca2f073..80ba315ed5879ad4fd5c063ca4819d2644bd73aa 100644 (file)
@@ -51,7 +51,7 @@ mech_step(State, ClientIn) ->
                     {ok,
                      [{username, User}, {authzid, AuthzId},
                       {auth_module, ejabberd_oauth}]};
-                false ->
+                _ ->
                     {error, <<"not-authorized">>, User}
             end;
         _ -> {error, <<"bad-protocol">>}
index 2c095440f6f0e5243726860c25b60aa206bb94ef..d9497322f5b0bec2b32b3a831e4ae3b0be1268f7 100644 (file)
@@ -682,7 +682,7 @@ check_auth(Command, {User, Server, {oauth, Token}, _}) ->
     case ejabberd_oauth:check_token(User, Server, ScopeList, Token) of
         true ->
             {ok, User, Server};
-        false ->
+        _ ->
             throw({error, invalid_account_data})
     end;
 check_auth(_Command, {User, Server, Password, _}) when is_binary(Password) ->
index 0ac18b7ef08922aaf9954d3f7e7c666df9542f2a..531f277498869372395bef0f8831dcde738551f9 100644 (file)
@@ -321,12 +321,17 @@ check_token(User, Server, ScopeList, Token) ->
                       expire = Expire}] ->
             {MegaSecs, Secs, _} = os:timestamp(),
             TS = 1000000 * MegaSecs + Secs,
-            TokenScopeSet = oauth2_priv_set:new(TokenScope),
-            lists:any(fun(Scope) ->
-                oauth2_priv_set:is_member(Scope, TokenScopeSet) end,
-                ScopeList) andalso Expire > TS;
+            if
+                Expire > TS ->
+                    TokenScopeSet = oauth2_priv_set:new(TokenScope),
+                    lists:any(fun(Scope) ->
+                                      oauth2_priv_set:is_member(Scope, TokenScopeSet) end,
+                              ScopeList);
+                true ->
+                    {false, expired}
+            end;
         _ ->
-            false
+            {false, not_found}
     end.
 
 check_token(ScopeList, Token) ->
@@ -336,15 +341,20 @@ check_token(ScopeList, Token) ->
                       expire = Expire}] ->
             {MegaSecs, Secs, _} = os:timestamp(),
             TS = 1000000 * MegaSecs + Secs,
-            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
+            if
+                Expire > TS ->
+                    TokenScopeSet = oauth2_priv_set:new(TokenScope),
+                    case lists:any(fun(Scope) ->
+                                           oauth2_priv_set:is_member(Scope, TokenScopeSet) end,
+                                   ScopeList) of
+                        true -> {ok, user, US};
+                        false -> {false, no_matching_scope}
+                    end;
+                true ->
+                    {false, expired}
             end;
         _ ->
-            false
+            {false, not_found}
     end.
 
 
index 6f6d59cdaa45bdd2de64dda5135aff44f4376b20..cda4d6059eb8c97c2348a1a2f407bcdb07adf56f 100644 (file)
@@ -162,14 +162,15 @@ check_permissions2(#request{auth = HTTPAuth, headers = Headers}, Call, _, ScopeL
                 case oauth_check_token(ScopeList, Token) of
                     {ok, user, {User, Server}} ->
                         {ok, {User, Server, {oauth, Token}, Admin}};
-                    false ->
-                        false
+                    {false, Reason} ->
+                        {false, Reason}
                 end;
             _ ->
                 false
         end,
     case Auth of
         {ok, A} -> {allowed, Call, A};
+        {false, no_matching_scope} -> outofscope_response();
         _ -> unauthorized_response()
     end;
 check_permissions2(_Request, Call, open, _Scope) ->
@@ -189,7 +190,7 @@ check_permissions2(#request{ip={IP, _Port}}, Call, _Policy, _Scope) ->
         Commands when is_list(Commands) ->
             case lists:member(Call, Commands) of
                 true -> {allowed, Call, admin};
-                _ -> unauthorized_response()
+                _ -> outofscope_response()
             end;
         _E ->
             {allowed, Call, noauth}
@@ -495,6 +496,7 @@ format_result(Tuple, {Name, {tuple, Def}}) ->
 format_result(404, {_Name, _}) ->
     "not_found".
 
+
 format_error_result(conflict, Code, Msg) ->
     {409, Code, iolist_to_binary(Msg)};
 format_error_result(_ErrorAtom, Code, Msg) ->
@@ -503,6 +505,9 @@ format_error_result(_ErrorAtom, Code, Msg) ->
 unauthorized_response() ->
     json_error(401, 10, <<"Oauth Token is invalid or expired.">>).
 
+outofscope_response() ->
+    json_error(401, 11, <<"Token does not grant usage to command required scope.">>).
+
 badrequest_response() ->
     badrequest_response(<<"400 Bad Request">>).
 badrequest_response(Body) ->