diff --git a/sql/lite.sql b/sql/lite.sql index 1741ea950..aacea11e7 100644 --- a/sql/lite.sql +++ b/sql/lite.sql @@ -313,3 +313,10 @@ CREATE TABLE sm ( CREATE UNIQUE INDEX i_sm_sid ON sm(usec, pid); CREATE INDEX i_sm_node ON sm(node); CREATE INDEX i_sm_username ON sm(username); + +CREATE TABLE oauth_token ( + token text NOT NULL PRIMARY KEY, + jid text NOT NULL, + scope text NOT NULL, + expire bigint NOT NULL +); diff --git a/sql/mssql.sql b/sql/mssql.sql index 45378d246..0dfaa7161 100644 --- a/sql/mssql.sql +++ b/sql/mssql.sql @@ -480,3 +480,13 @@ ON DELETE CASCADE; ALTER TABLE [dbo].[pubsub_state] CHECK CONSTRAINT [pubsub_state_ibfk_1]; +CREATE TABLE [dbo].[oauth_token] ( + [token] [varchar] (250) NOT NULL, + [jid] [text] NOT NULL, + [scope] [text] NOT NULL, + [expire] [bigint] NOT NULL, + CONSTRAINT [oauth_token_PRIMARY] PRIMARY KEY CLUSTERED +( + [token] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) +) TEXTIMAGE_ON [PRIMARY]; diff --git a/sql/mysql.sql b/sql/mysql.sql index 5150fc45b..3d253c574 100644 --- a/sql/mysql.sql +++ b/sql/mysql.sql @@ -328,3 +328,10 @@ CREATE TABLE sm ( CREATE UNIQUE INDEX i_sid ON sm(usec, pid(75)); CREATE INDEX i_node ON sm(node(75)); CREATE INDEX i_username ON sm(username); + +CREATE TABLE oauth_token ( + token varchar(191) NOT NULL PRIMARY KEY, + jid text NOT NULL, + scope text NOT NULL, + expire bigint NOT NULL +) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/sql/pg.sql b/sql/pg.sql index 1bc4f397c..3d7de4285 100644 --- a/sql/pg.sql +++ b/sql/pg.sql @@ -330,3 +330,12 @@ CREATE TABLE sm ( CREATE UNIQUE INDEX i_sm_sid ON sm USING btree (usec, pid); CREATE INDEX i_sm_node ON sm USING btree (node); CREATE INDEX i_sm_username ON sm USING btree (username); + +CREATE TABLE oauth_token ( + token text NOT NULL, + jid text NOT NULL, + scope text NOT NULL, + expire bigint NOT NULL +); + +CREATE UNIQUE INDEX i_oauth_token_token ON oauth_token USING btree (token); diff --git a/src/ejabberd_oauth_sql.erl b/src/ejabberd_oauth_sql.erl new file mode 100644 index 000000000..9253335ff --- /dev/null +++ b/src/ejabberd_oauth_sql.erl @@ -0,0 +1,78 @@ +%%%------------------------------------------------------------------- +%%% File : ejabberd_oauth_sql.erl +%%% Author : Alexey Shchepin +%%% Purpose : OAUTH2 SQL backend +%%% Created : 27 Jul 2016 by Alexey Shchepin +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2016 ProcessOne +%%% +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the GNU General Public License as +%%% published by the Free Software Foundation; either version 2 of the +%%% License, or (at your option) any later version. +%%% +%%% This program is distributed in the hope that it will be useful, +%%% but WITHOUT ANY WARRANTY; without even the implied warranty of +%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +%%% General Public License for more details. +%%% +%%% You should have received a copy of the GNU General Public License +%%% along with this program; if not, write to the Free Software +%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +%%% 02111-1307 USA +%%% +%%%------------------------------------------------------------------- + +-module(ejabberd_oauth_sql). + +-compile([{parse_transform, ejabberd_sql_pt}]). + +-export([init/0, + store/1, + lookup/1, + clean/1]). + +-include("ejabberd_oauth.hrl"). +-include("ejabberd.hrl"). +-include("ejabberd_sql_pt.hrl"). +-include("jlib.hrl"). + +init() -> + ok. + +store(R) -> + Token = R#oauth_token.token, + {User, Server} = R#oauth_token.us, + SJID = jid:to_string({User, Server, <<"">>}), + Scope = str:join(R#oauth_token.scope, <<" ">>), + Expire = R#oauth_token.expire, + ?SQL_UPSERT( + ?MYNAME, + "oauth_token", + ["!token=%(Token)s", + "jid=%(SJID)s", + "scope=%(Scope)s", + "expire=%(Expire)d"]). + +lookup(Token) -> + case ejabberd_sql:sql_query( + ?MYNAME, + ?SQL("select @(jid)s, @(scope)s, @(expire)d" + " from oauth_token where token=%(Token)s")) of + {selected, [{SJID, Scope, Expire}]} -> + JID = jid:from_string(SJID), + US = {JID#jid.luser, JID#jid.lserver}, + #oauth_token{token = Token, + us = US, + scope = str:tokens(Scope, <<" ">>), + expire = Expire}; + _ -> + false + end. + +clean(TS) -> + ejabberd_sql:sql_query( + ?MYNAME, + ?SQL("delete from oauth_token where expire < %(TS)d")). +