mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Check redirect_uri for OAUTH implicit grant
This commit is contained in:
parent
949e71efb6
commit
5d549dca96
@ -26,8 +26,8 @@
|
|||||||
}).
|
}).
|
||||||
|
|
||||||
-record(oauth_client, {
|
-record(oauth_client, {
|
||||||
client = <<"">> :: binary() | '_',
|
client_id = <<"">> :: binary() | '_',
|
||||||
secret = <<"">> :: binary() | '_',
|
client_name = <<"">> :: binary() | '_',
|
||||||
grant_type = password :: password | '_',
|
grant_type :: password | implicit | '_',
|
||||||
options :: [any()] | '_'
|
options :: [any()] | '_'
|
||||||
}).
|
}).
|
||||||
|
@ -339,8 +339,8 @@ CREATE TABLE oauth_token (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE oauth_client (
|
CREATE TABLE oauth_client (
|
||||||
client text PRIMARY KEY,
|
client_id text PRIMARY KEY,
|
||||||
secret text NOT NULL,
|
client_name text NOT NULL,
|
||||||
grant_type text NOT NULL,
|
grant_type text NOT NULL,
|
||||||
options text NOT NULL
|
options text NOT NULL
|
||||||
);
|
);
|
||||||
|
@ -384,6 +384,13 @@ CREATE TABLE oauth_token (
|
|||||||
expire bigint NOT NULL
|
expire bigint NOT NULL
|
||||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
CREATE TABLE oauth_client (
|
||||||
|
client_id varchar(191) NOT NULL PRIMARY KEY,
|
||||||
|
client_name text NOT NULL,
|
||||||
|
grant_type text NOT NULL,
|
||||||
|
options text NOT NULL
|
||||||
|
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
CREATE TABLE route (
|
CREATE TABLE route (
|
||||||
domain text NOT NULL,
|
domain text NOT NULL,
|
||||||
server_host varchar(191) NOT NULL,
|
server_host varchar(191) NOT NULL,
|
||||||
|
@ -355,8 +355,8 @@ CREATE TABLE oauth_token (
|
|||||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
CREATE TABLE oauth_client (
|
CREATE TABLE oauth_client (
|
||||||
client varchar(191) NOT NULL PRIMARY KEY,
|
client_id varchar(191) NOT NULL PRIMARY KEY,
|
||||||
secret text NOT NULL,
|
client_name text NOT NULL,
|
||||||
grant_type text NOT NULL,
|
grant_type text NOT NULL,
|
||||||
options text NOT NULL
|
options text NOT NULL
|
||||||
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
@ -529,6 +529,13 @@ CREATE TABLE oauth_token (
|
|||||||
|
|
||||||
CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token);
|
CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token);
|
||||||
|
|
||||||
|
CREATE TABLE oauth_client (
|
||||||
|
client_id text PRIMARY KEY,
|
||||||
|
client_name text NOT NULL,
|
||||||
|
grant_type text NOT NULL,
|
||||||
|
options text NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE route (
|
CREATE TABLE route (
|
||||||
domain text NOT NULL,
|
domain text NOT NULL,
|
||||||
server_host text NOT NULL,
|
server_host text NOT NULL,
|
||||||
|
@ -359,8 +359,8 @@ CREATE TABLE oauth_token (
|
|||||||
CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token);
|
CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token);
|
||||||
|
|
||||||
CREATE TABLE oauth_client (
|
CREATE TABLE oauth_client (
|
||||||
client text PRIMARY KEY,
|
client_id text PRIMARY KEY,
|
||||||
secret text NOT NULL,
|
client_name text NOT NULL,
|
||||||
grant_type text NOT NULL,
|
grant_type text NOT NULL,
|
||||||
options text NOT NULL
|
options text NOT NULL
|
||||||
);
|
);
|
||||||
|
@ -50,7 +50,9 @@
|
|||||||
|
|
||||||
-export([get_commands_spec/0,
|
-export([get_commands_spec/0,
|
||||||
oauth_issue_token/3, oauth_list_tokens/0, oauth_revoke_token/1,
|
oauth_issue_token/3, oauth_list_tokens/0, oauth_revoke_token/1,
|
||||||
oauth_add_client/3, oauth_remove_client/1]).
|
oauth_add_client_password/3,
|
||||||
|
oauth_add_client_implicit/3,
|
||||||
|
oauth_remove_client/1]).
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -65,6 +67,11 @@
|
|||||||
-callback lookup(binary()) -> {ok, #oauth_token{}} | error.
|
-callback lookup(binary()) -> {ok, #oauth_token{}} | error.
|
||||||
-callback clean(non_neg_integer()) -> any().
|
-callback clean(non_neg_integer()) -> any().
|
||||||
|
|
||||||
|
-record(oauth_ctx, {
|
||||||
|
password :: binary() | admin_generated,
|
||||||
|
client :: #oauth_client{}
|
||||||
|
}).
|
||||||
|
|
||||||
%% There are two ways to obtain an oauth token:
|
%% There are two ways to obtain an oauth token:
|
||||||
%% * Using the web form/api results in the token being generated in behalf of the user providing the user/pass
|
%% * Using the web form/api results in the token being generated in behalf of the user providing the user/pass
|
||||||
%% * Using the command line and oauth_issue_token command, the token is generated in behalf of ejabberd' sysadmin
|
%% * Using the command line and oauth_issue_token command, the token is generated in behalf of ejabberd' sysadmin
|
||||||
@ -99,12 +106,21 @@ get_commands_spec() ->
|
|||||||
result = {tokens, {list, {token, {tuple, [{token, string}, {user, string}, {scope, string}, {expires_in, string}]}}}},
|
result = {tokens, {list, {token, {tuple, [{token, string}, {user, string}, {scope, string}, {expires_in, string}]}}}},
|
||||||
result_desc = "List of remaining tokens"
|
result_desc = "List of remaining tokens"
|
||||||
},
|
},
|
||||||
#ejabberd_commands{name = oauth_add_client, tags = [oauth],
|
#ejabberd_commands{name = oauth_add_client_password, tags = [oauth],
|
||||||
desc = "Add OAUTH client_id",
|
desc = "Add OAUTH client_id with password grant type",
|
||||||
module = ?MODULE, function = oauth_add_client,
|
module = ?MODULE, function = oauth_add_client_password,
|
||||||
args = [{client_id, binary},
|
args = [{client_id, binary},
|
||||||
{secret, binary},
|
{client_name, binary},
|
||||||
{grant_type, binary}],
|
{secret, binary}],
|
||||||
|
policy = restricted,
|
||||||
|
result = {res, restuple}
|
||||||
|
},
|
||||||
|
#ejabberd_commands{name = oauth_add_client_implicit, tags = [oauth],
|
||||||
|
desc = "Add OAUTH client_id with implicit grant type",
|
||||||
|
module = ?MODULE, function = oauth_add_client_implicit,
|
||||||
|
args = [{client_id, binary},
|
||||||
|
{client_name, binary},
|
||||||
|
{redirect_uri, binary}],
|
||||||
policy = restricted,
|
policy = restricted,
|
||||||
result = {res, restuple}
|
result = {res, restuple}
|
||||||
},
|
},
|
||||||
@ -146,18 +162,21 @@ oauth_revoke_token(Token) ->
|
|||||||
ok = mnesia:dirty_delete(oauth_token, list_to_binary(Token)),
|
ok = mnesia:dirty_delete(oauth_token, list_to_binary(Token)),
|
||||||
oauth_list_tokens().
|
oauth_list_tokens().
|
||||||
|
|
||||||
oauth_add_client(Client, Secret, SGrantType) ->
|
oauth_add_client_password(ClientID, ClientName, Secret) ->
|
||||||
case SGrantType of
|
DBMod = get_db_backend(),
|
||||||
<<"password">> ->
|
DBMod:store_client(#oauth_client{client_id = ClientID,
|
||||||
DBMod = get_db_backend(),
|
client_name = ClientName,
|
||||||
DBMod:store_client(#oauth_client{client = Client,
|
grant_type = password,
|
||||||
secret = Secret,
|
options = [{secret, Secret}]}),
|
||||||
grant_type = password,
|
{ok, []}.
|
||||||
options = []}),
|
|
||||||
{ok, []};
|
oauth_add_client_implicit(ClientID, ClientName, RedirectURI) ->
|
||||||
_ ->
|
DBMod = get_db_backend(),
|
||||||
{error, "Unsupported grant type"}
|
DBMod:store_client(#oauth_client{client_id = ClientID,
|
||||||
end.
|
client_name = ClientName,
|
||||||
|
grant_type = implicit,
|
||||||
|
options = [{redirect_uri, RedirectURI}]}),
|
||||||
|
{ok, []}.
|
||||||
|
|
||||||
oauth_remove_client(Client) ->
|
oauth_remove_client(Client) ->
|
||||||
DBMod = get_db_backend(),
|
DBMod = get_db_backend(),
|
||||||
@ -216,9 +235,23 @@ terminate(_Reason, _State) ->
|
|||||||
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||||
|
|
||||||
|
|
||||||
get_client_identity(Client, Ctx) -> {ok, {Ctx, {client, Client}}}.
|
get_client_identity({client, ClientID}, Ctx) ->
|
||||||
|
{ok, {Ctx, {client, ClientID}}}.
|
||||||
|
|
||||||
verify_redirection_uri(_, _, Ctx) -> {ok, Ctx}.
|
verify_redirection_uri(_ClientID, RedirectURI, Ctx) ->
|
||||||
|
case Ctx of
|
||||||
|
#oauth_ctx{client = #oauth_client{grant_type = implicit} = Client} ->
|
||||||
|
case get_redirect_uri(Client) of
|
||||||
|
RedirectURI ->
|
||||||
|
{ok, Ctx};
|
||||||
|
_ ->
|
||||||
|
{error, invalid_uri}
|
||||||
|
end;
|
||||||
|
#oauth_ctx{client = #oauth_client{}} ->
|
||||||
|
{error, invalid_client};
|
||||||
|
_ ->
|
||||||
|
{ok, Ctx}
|
||||||
|
end.
|
||||||
|
|
||||||
authenticate_user({User, Server}, Ctx) ->
|
authenticate_user({User, Server}, Ctx) ->
|
||||||
case jid:make(User, Server) of
|
case jid:make(User, Server) of
|
||||||
@ -228,15 +261,16 @@ authenticate_user({User, Server}, Ctx) ->
|
|||||||
case acl:match_rule(JID#jid.lserver, Access, JID) of
|
case acl:match_rule(JID#jid.lserver, Access, JID) of
|
||||||
allow ->
|
allow ->
|
||||||
case Ctx of
|
case Ctx of
|
||||||
{password, Password} ->
|
#oauth_ctx{password = admin_generated} ->
|
||||||
case ejabberd_auth:check_password(User, <<"">>, Server, Password) of
|
|
||||||
true ->
|
|
||||||
{ok, {Ctx, {user, User, Server}}};
|
{ok, {Ctx, {user, User, Server}}};
|
||||||
false ->
|
#oauth_ctx{password = Password}
|
||||||
{error, badpass}
|
when is_binary(Password) ->
|
||||||
end;
|
case ejabberd_auth:check_password(User, <<"">>, Server, Password) of
|
||||||
admin_generated ->
|
true ->
|
||||||
{ok, {Ctx, {user, User, Server}}}
|
{ok, {Ctx, {user, User, Server}}};
|
||||||
|
false ->
|
||||||
|
{error, badpass}
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
deny ->
|
deny ->
|
||||||
{error, badpass}
|
{error, badpass}
|
||||||
@ -245,7 +279,20 @@ authenticate_user({User, Server}, Ctx) ->
|
|||||||
{error, badpass}
|
{error, badpass}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
authenticate_client(Client, Ctx) -> {ok, {Ctx, {client, Client}}}.
|
authenticate_client(ClientID, Ctx) ->
|
||||||
|
case ejabberd_option:oauth_client_id_check() of
|
||||||
|
allow ->
|
||||||
|
{ok, {Ctx, {client, ClientID}}};
|
||||||
|
deny -> {error, not_allowed};
|
||||||
|
db ->
|
||||||
|
DBMod = get_db_backend(),
|
||||||
|
case DBMod:lookup_client(ClientID) of
|
||||||
|
{ok, #oauth_client{} = Client} ->
|
||||||
|
{ok, {Ctx#oauth_ctx{client = Client}, {client, ClientID}}};
|
||||||
|
_ ->
|
||||||
|
{error, not_allowed}
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
-spec verify_resowner_scope({user, binary(), binary()}, [binary()], any()) ->
|
-spec verify_resowner_scope({user, binary(), binary()}, [binary()], any()) ->
|
||||||
{ok, any(), [binary()]} | {error, any()}.
|
{ok, any(), [binary()]} | {error, any()}.
|
||||||
@ -525,7 +572,7 @@ process(_Handlers,
|
|||||||
ClientId,
|
ClientId,
|
||||||
RedirectURI,
|
RedirectURI,
|
||||||
Scope,
|
Scope,
|
||||||
{password, Password}) of
|
#oauth_ctx{password = Password}) of
|
||||||
{ok, {_AppContext, Authorization}} ->
|
{ok, {_AppContext, Authorization}} ->
|
||||||
{ok, {_AppContext2, Response}} =
|
{ok, {_AppContext2, Response}} =
|
||||||
oauth2:issue_token(Authorization, [{expiry_time, ExpiresIn} || ExpiresIn /= undefined ]),
|
oauth2:issue_token(Authorization, [{expiry_time, ExpiresIn} || ExpiresIn /= undefined ]),
|
||||||
@ -597,13 +644,18 @@ process(_Handlers,
|
|||||||
end,
|
end,
|
||||||
DBMod = get_db_backend(),
|
DBMod = get_db_backend(),
|
||||||
case DBMod:lookup_client(ClientID) of
|
case DBMod:lookup_client(ClientID) of
|
||||||
{ok, #oauth_client{secret = Secret} = Client} ->
|
{ok, #oauth_client{grant_type = password} = Client} ->
|
||||||
case proplists:get_value(<<"grant_type">>, Q, <<"">>) of
|
case get_client_secret(Client) of
|
||||||
<<"password">> when
|
Secret ->
|
||||||
Client#oauth_client.grant_type == password ->
|
case proplists:get_value(<<"grant_type">>, Q, <<"">>) of
|
||||||
password;
|
<<"password">> when
|
||||||
|
Client#oauth_client.grant_type == password ->
|
||||||
|
password;
|
||||||
|
_ ->
|
||||||
|
unsupported_grant_type
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
unsupported_grant_type
|
deny
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
deny
|
deny
|
||||||
@ -623,7 +675,7 @@ process(_Handlers,
|
|||||||
end,
|
end,
|
||||||
case oauth2:authorize_password({Username, Server},
|
case oauth2:authorize_password({Username, Server},
|
||||||
Scope,
|
Scope,
|
||||||
{password, Password}) of
|
#oauth_ctx{password = Password}) of
|
||||||
{ok, {_AppContext, Authorization}} ->
|
{ok, {_AppContext, Authorization}} ->
|
||||||
{ok, {_AppContext2, Response}} =
|
{ok, {_AppContext2, Response}} =
|
||||||
oauth2:issue_token(Authorization, [{expiry_time, ExpiresIn} || ExpiresIn /= undefined ]),
|
oauth2:issue_token(Authorization, [{expiry_time, ExpiresIn} || ExpiresIn /= undefined ]),
|
||||||
@ -663,6 +715,11 @@ get_db_backend() ->
|
|||||||
DBType = ejabberd_option:oauth_db_type(),
|
DBType = ejabberd_option:oauth_db_type(),
|
||||||
list_to_existing_atom("ejabberd_oauth_" ++ atom_to_list(DBType)).
|
list_to_existing_atom("ejabberd_oauth_" ++ atom_to_list(DBType)).
|
||||||
|
|
||||||
|
get_client_secret(#oauth_client{grant_type = password, options = Options}) ->
|
||||||
|
proplists:get_value(secret, Options, false).
|
||||||
|
|
||||||
|
get_redirect_uri(#oauth_client{grant_type = implicit, options = Options}) ->
|
||||||
|
proplists:get_value(redirect_uri, Options, false).
|
||||||
|
|
||||||
%% Headers as per RFC 6749
|
%% Headers as per RFC 6749
|
||||||
json_response(Code, Body) ->
|
json_response(Code, Body) ->
|
||||||
|
@ -91,22 +91,25 @@ path(Path) ->
|
|||||||
Base = ejabberd_option:ext_api_path_oauth(),
|
Base = ejabberd_option:ext_api_path_oauth(),
|
||||||
<<Base/binary, "/", Path/binary>>.
|
<<Base/binary, "/", Path/binary>>.
|
||||||
|
|
||||||
store_client(#oauth_client{client = Client,
|
store_client(#oauth_client{client_id = ClientID,
|
||||||
secret = Secret,
|
client_name = ClientName,
|
||||||
grant_type = GrantType} = R) ->
|
grant_type = GrantType,
|
||||||
|
options = Options} = R) ->
|
||||||
Path = path(<<"store_client">>),
|
Path = path(<<"store_client">>),
|
||||||
%% Retry 2 times, with a backoff of 500millisec
|
|
||||||
SGrantType =
|
SGrantType =
|
||||||
case GrantType of
|
case GrantType of
|
||||||
password -> <<"password">>
|
password -> <<"password">>;
|
||||||
|
implicit -> <<"implicit">>
|
||||||
end,
|
end,
|
||||||
|
SOptions = misc:term_to_base64(Options),
|
||||||
|
%% Retry 2 times, with a backoff of 500millisec
|
||||||
case rest:with_retry(
|
case rest:with_retry(
|
||||||
post,
|
post,
|
||||||
[ejabberd_config:get_myname(), Path, [],
|
[ejabberd_config:get_myname(), Path, [],
|
||||||
{[{<<"client">>, Client},
|
{[{<<"client_id">>, ClientID},
|
||||||
{<<"secret">>, Secret},
|
{<<"client_name">>, ClientName},
|
||||||
{<<"grant_type">>, SGrantType},
|
{<<"grant_type">>, SGrantType},
|
||||||
{<<"options">>, []}
|
{<<"options">>, SOptions}
|
||||||
]}], 2, 500) of
|
]}], 2, 500) of
|
||||||
{ok, Code, _} when Code == 200 orelse Code == 201 ->
|
{ok, Code, _} when Code == 200 orelse Code == 201 ->
|
||||||
ok;
|
ok;
|
||||||
@ -115,22 +118,29 @@ store_client(#oauth_client{client = Client,
|
|||||||
{error, db_failure}
|
{error, db_failure}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
lookup_client(Client) ->
|
lookup_client(ClientID) ->
|
||||||
Path = path(<<"lookup_client">>),
|
Path = path(<<"lookup_client">>),
|
||||||
case rest:with_retry(post, [ejabberd_config:get_myname(), Path, [],
|
case rest:with_retry(post, [ejabberd_config:get_myname(), Path, [],
|
||||||
{[{<<"client">>, Client}]}],
|
{[{<<"client_id">>, ClientID}]}],
|
||||||
2, 500) of
|
2, 500) of
|
||||||
{ok, 200, {Data}} ->
|
{ok, 200, {Data}} ->
|
||||||
Secret = proplists:get_value(<<"secret">>, Data, <<>>),
|
ClientName = proplists:get_value(<<"client_name">>, Data, <<>>),
|
||||||
SGrantType = proplists:get_value(<<"grant_type">>, Data, <<>>),
|
SGrantType = proplists:get_value(<<"grant_type">>, Data, <<>>),
|
||||||
GrantType =
|
GrantType =
|
||||||
case SGrantType of
|
case SGrantType of
|
||||||
<<"password">> -> password
|
<<"password">> -> password;
|
||||||
|
<<"implicit">> -> implicit
|
||||||
end,
|
end,
|
||||||
{ok, #oauth_client{client = Client,
|
SOptions = proplists:get_value(<<"options">>, Data, <<>>),
|
||||||
secret = Secret,
|
case misc:base64_to_term(SOptions) of
|
||||||
grant_type = GrantType,
|
{term, Options} ->
|
||||||
options = []}};
|
{ok, #oauth_client{client_id = ClientID,
|
||||||
|
client_name = ClientName,
|
||||||
|
grant_type = GrantType,
|
||||||
|
options = Options}};
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end;
|
||||||
{ok, 404, _Resp} ->
|
{ok, 404, _Resp} ->
|
||||||
error;
|
error;
|
||||||
Other ->
|
Other ->
|
||||||
|
@ -83,37 +83,45 @@ clean(TS) ->
|
|||||||
ejabberd_config:get_myname(),
|
ejabberd_config:get_myname(),
|
||||||
?SQL("delete from oauth_token where expire < %(TS)d")).
|
?SQL("delete from oauth_token where expire < %(TS)d")).
|
||||||
|
|
||||||
lookup_client(Client) ->
|
lookup_client(ClientID) ->
|
||||||
case ejabberd_sql:sql_query(
|
case ejabberd_sql:sql_query(
|
||||||
ejabberd_config:get_myname(),
|
ejabberd_config:get_myname(),
|
||||||
?SQL("select @(secret)s, @(grant_type)s"
|
?SQL("select @(client_name)s, @(grant_type)s, @(options)s"
|
||||||
" from oauth_client where client=%(Client)s")) of
|
" from oauth_client where client_id=%(ClientID)s")) of
|
||||||
{selected, [{Secret, SGrantType}]} ->
|
{selected, [{ClientName, SGrantType, SOptions}]} ->
|
||||||
GrantType =
|
GrantType =
|
||||||
case SGrantType of
|
case SGrantType of
|
||||||
<<"password">> -> password
|
<<"password">> -> password;
|
||||||
|
<<"implicit">> -> implicit
|
||||||
end,
|
end,
|
||||||
{ok, #oauth_client{client = Client,
|
case misc:base64_to_term(SOptions) of
|
||||||
secret = Secret,
|
{term, Options} ->
|
||||||
grant_type = GrantType,
|
{ok, #oauth_client{client_id = ClientID,
|
||||||
options = []}};
|
client_name = ClientName,
|
||||||
|
grant_type = GrantType,
|
||||||
|
options = Options}};
|
||||||
|
_ ->
|
||||||
|
error
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
error
|
error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
store_client(#oauth_client{client = Client,
|
store_client(#oauth_client{client_id = ClientID,
|
||||||
secret = Secret,
|
client_name = ClientName,
|
||||||
grant_type = GrantType}) ->
|
grant_type = GrantType,
|
||||||
|
options = Options}) ->
|
||||||
SGrantType =
|
SGrantType =
|
||||||
case GrantType of
|
case GrantType of
|
||||||
password -> <<"password">>
|
password -> <<"password">>;
|
||||||
|
implicit -> <<"implicit">>
|
||||||
end,
|
end,
|
||||||
SOptions = <<"">>,
|
SOptions = misc:term_to_base64(Options),
|
||||||
case ?SQL_UPSERT(
|
case ?SQL_UPSERT(
|
||||||
ejabberd_config:get_myname(),
|
ejabberd_config:get_myname(),
|
||||||
"oauth_client",
|
"oauth_client",
|
||||||
["!client=%(Client)s",
|
["!client_id=%(ClientID)s",
|
||||||
"secret=%(Secret)s",
|
"client_name=%(ClientName)s",
|
||||||
"grant_type=%(SGrantType)s",
|
"grant_type=%(SGrantType)s",
|
||||||
"options=%(SOptions)s"]) of
|
"options=%(SOptions)s"]) of
|
||||||
ok ->
|
ok ->
|
||||||
|
Loading…
Reference in New Issue
Block a user