diff --git a/examples/demo/site/scripts/oauth2_consumers.sql b/examples/demo/site/scripts/oauth2_consumers.sql
new file mode 100644
index 0000000..6bf79d6
--- /dev/null
+++ b/examples/demo/site/scripts/oauth2_consumers.sql
@@ -0,0 +1,20 @@
+BEGIN;
+
+CREATE TABLE "oauth2_consumers"(
+ "cid" INTEGER PRIMARY KEY NOT NULL CHECK("cid">=0),
+ "name" VARCHAR(255) NOT NULL,
+ "api_secret" TEXT NOT NULL,
+ "api_key" TEXT NOT NULL,
+ "scope" VARCHAR (100) NOT NULL,
+ "protected_resource_url" VARCHAR (255) NOT NULL,
+ "callback_name" VARCHAR(255) NOT NULL,
+ "extractor" VARCHAR(50) NOT NULL,
+ "authorize_url" VARCHAR (255) NOT NULL,
+ "endpoint" VARCHAR (255) NOT NULL,
+ CONSTRAINT "cid"
+ UNIQUE("cid"),
+ CONSTRAINT "name"
+ UNIQUE("name")
+ );
+
+COMMIT;
\ No newline at end of file
diff --git a/examples/demo/site/scripts/oauth2_consumers_initialize.sql b/examples/demo/site/scripts/oauth2_consumers_initialize.sql
new file mode 100644
index 0000000..16766a7
--- /dev/null
+++ b/examples/demo/site/scripts/oauth2_consumers_initialize.sql
@@ -0,0 +1,11 @@
+BEGIN;
+
+ -- Change the values `TO_COMPLETE' based on your API.
+ -- API SECTET KEY AND API PUBLIC KEY
+
+INSERT INTO "oauth2_consumers" ("name", "api_secret", "api_key", "scope", "protected_resource_url", "callback_name", "extractor", "authorize_url", "endpoint")
+VALUES ("google", 'TO-COMPLETE', 'TO-COMPLETE', 'email', 'https://www.googleapis.com/plus/v1/people/me', "callback_google", "json","https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI","https://accounts.google.com/o/oauth2/token");
+INSERT INTO "oauth2_consumers" ("name", "api_secret", "api_key", "scope", "protected_resource_url", "callback_name", "extractor", "authorize_url", "endpoint" )
+VALUES ("facebook", 'TO-COMPLETE', 'TO-COMPLETE', 'email', 'https://graph.facebook.com/me', "callback_facebook","text","https://www.facebook.com/dialog/oauth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI","https://graph.facebook.com/oauth/access_token");
+
+COMMIT;
\ No newline at end of file
diff --git a/examples/demo/site/scripts/oauth2_gmail.sql b/examples/demo/site/scripts/oauth2_template.sql
similarity index 71%
rename from examples/demo/site/scripts/oauth2_gmail.sql
rename to examples/demo/site/scripts/oauth2_template.sql
index 3efbe55..6c1fa68 100644
--- a/examples/demo/site/scripts/oauth2_gmail.sql
+++ b/examples/demo/site/scripts/oauth2_template.sql
@@ -1,9 +1,9 @@
BEGIN;
-CREATE TABLE "oauth2_gmail"(
+CREATE TABLE :table_name (
"uid" INTEGER PRIMARY KEY NOT NULL CHECK("uid">=0),
- "access_token" VARCHAR(255) NOT NULL,
+ "access_token" TEXT NOT NULL,
"created" DATETIME NOT NULL,
"details" TEXT NOT NULL,
CONSTRAINT "uid"
diff --git a/examples/demo/site/themes/bootstrap/modules/login/templates/block_login.tpl b/examples/demo/site/themes/bootstrap/modules/login/templates/block_login.tpl
index 130aa76..dda41b5 100644
--- a/examples/demo/site/themes/bootstrap/modules/login/templates/block_login.tpl
+++ b/examples/demo/site/themes/bootstrap/modules/login/templates/block_login.tpl
@@ -1,4 +1,4 @@
-
+
{unless isset="$user"}
@@ -26,7 +26,9 @@
{/unless}
\ No newline at end of file
diff --git a/examples/demo/site/themes/bootstrap/page.tpl b/examples/demo/site/themes/bootstrap/page.tpl
index 9bf0155..a587c0f 100644
--- a/examples/demo/site/themes/bootstrap/page.tpl
+++ b/examples/demo/site/themes/bootstrap/page.tpl
@@ -57,7 +57,7 @@
{unless isempty="$page_title"}{$page_title/}
{/unless}
{$page.region_content/}
-
+
diff --git a/modules/login/cms_oauth_consumer.e b/modules/login/cms_oauth_consumer.e
new file mode 100644
index 0000000..fda8210
--- /dev/null
+++ b/modules/login/cms_oauth_consumer.e
@@ -0,0 +1,152 @@
+note
+ description: "Summary description for {CMS_OAUTH_CONSUMER}."
+ author: ""
+ date: "$Date$"
+ revision: "$Revision$"
+
+class
+ CMS_OAUTH_CONSUMER
+
+inherit
+
+ ANY
+ redefine
+ default_create
+ end
+
+create
+ default_create
+
+feature {NONE} -- Initialization
+
+ default_create
+ do
+ set_endpoint ("")
+ set_authorize_url ("")
+ set_extractor ("")
+ set_callback_name ("")
+ set_protected_resource_url ("")
+ set_scope ("")
+ set_api_key ("")
+ set_api_secret ("")
+ set_name ("")
+ end
+
+feature -- Access
+
+ endpoint: READABLE_STRING_32
+ -- Url that receives the access token request.
+
+ authorize_url: READABLE_STRING_32
+ --
+
+ extractor: READABLE_STRING_32
+ -- text, json
+
+
+ callback_name: READABLE_STRING_32
+ -- consumer callback name
+
+ protected_resource_url: READABLE_STRING_32
+ -- consumer resource url
+
+ scope: READABLE_STRING_32
+ -- consumer scope
+
+ api_key: READABLE_STRING_32
+ -- consumer public key
+
+ api_secret: READABLE_STRING_32
+ -- consumer secret.
+
+ name: READABLE_STRING_32
+ -- consumer name.
+
+ id: INTEGER_64
+ -- unique identifier.
+
+
+
+feature -- Element change
+
+ set_extractor (a_extractor: like extractor)
+ -- Assign `extractor' with `a_extractor'.
+ do
+ extractor := a_extractor
+ ensure
+ extractor_assigned: extractor = a_extractor
+ end
+
+ set_authorize_url (a_authorize_url: like authorize_url)
+ -- Assign `authorize_url' with `a_authorize_url'.
+ do
+ authorize_url := a_authorize_url
+ ensure
+ authorize_url_assigned: authorize_url = a_authorize_url
+ end
+
+ set_endpoint (a_endpoint: like endpoint)
+ -- Assign `endpoint' with `a_endpoint'.
+ do
+ endpoint := a_endpoint
+ ensure
+ endpoint_assigned: endpoint = a_endpoint
+ end
+
+ set_callback_name (a_callback_name: like callback_name)
+ -- Assign `callback_name' with `a_callback_name'.
+ do
+ callback_name := a_callback_name
+ ensure
+ callback_name_assigned: callback_name = a_callback_name
+ end
+
+ set_protected_resource_url (a_protected_resource_url: like protected_resource_url)
+ -- Assign `protected_resource_url' with `a_protected_resource_url'.
+ do
+ protected_resource_url := a_protected_resource_url
+ ensure
+ protected_resource_url_assigned: protected_resource_url = a_protected_resource_url
+ end
+
+ set_scope (a_scope: like scope)
+ -- Assign `scope' with `a_scope'.
+ do
+ scope := a_scope
+ ensure
+ scope_assigned: scope = a_scope
+ end
+
+ set_api_key (an_api_key: like api_key)
+ -- Assign `api_key' with `an_api_key'.
+ do
+ api_key := an_api_key
+ ensure
+ api_key_assigned: api_key = an_api_key
+ end
+
+ set_api_secret (an_api_secret: like api_secret)
+ -- Assign `api_secret' with `an_api_secret'.
+ do
+ api_secret := an_api_secret
+ ensure
+ api_secret_assigned: api_secret = an_api_secret
+ end
+
+ set_name (a_name: like name)
+ -- Assign `name' with `a_name'.
+ do
+ name := a_name
+ ensure
+ name_assigned: name = a_name
+ end
+
+ set_id (an_id: like id)
+ -- Assign `id' with `an_id'.
+ do
+ id := an_id
+ ensure
+ id_assigned: id = an_id
+ end
+
+end
diff --git a/modules/login/cms_user_oauth_api.e b/modules/login/cms_user_oauth_api.e
index a9a7bb6..4e2ed38 100644
--- a/modules/login/cms_user_oauth_api.e
+++ b/modules/login/cms_user_oauth_api.e
@@ -31,34 +31,70 @@ feature {CMS_MODULE} -- Access user oauth storage.
feature -- Access: OAuth2 Gmail
- user_oauth2_gmail_by_id (a_uid: like {CMS_USER}.id): detachable CMS_USER
+-- user_oauth2_gmail_by_id (a_uid: like {CMS_USER}.id): detachable CMS_USER
+-- do
+-- Result := user_oauth_storage.user_oauth2_gmail_by_id (a_uid)
+-- end
+
+-- user_by_oauth2_gmail_token (a_token: READABLE_STRING_32): detachable CMS_USER
+-- do
+-- Result := user_oauth_storage.user_by_oauth2_gmail_token (a_token)
+-- end
+
+ user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
do
- Result := user_oauth_storage.user_oauth2_gmail_by_id (a_uid)
+ Result := user_oauth_storage.user_oauth2_by_id (a_uid, a_consumer_table)
end
- user_by_oauth2_gmail_token (a_token: READABLE_STRING_32): detachable CMS_USER
+ user_by_oauth2_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
do
- Result := user_oauth_storage.user_by_oauth2_gmail_token (a_token)
+ Result := user_oauth_storage.user_by_oauth2_token (a_token, a_consumer_table)
end
+ user_by_oauth2_global_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
+ do
+ Result := user_oauth_storage.user_by_oauth2_global_token (a_token)
+ end
+
+ oauth2_consumers: LIST [STRING]
+ do
+ Result := user_oauth_storage.oauth2_consumers
+ end
feature -- Change: OAuth2 Gmail
- new_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
+-- new_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
+-- -- Add a new user with oauth2 gmail authentication.
+-- require
+-- has_id: a_user.has_id
+-- do
+-- user_oauth_storage.new_user_oauth2_gmail (a_token, a_user_profile, a_user)
+-- end
+
+
+-- update_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
+-- -- Updaate user `a_user' with oauth2 gmail authentication.
+-- require
+-- has_id: a_user.has_id
+-- do
+-- user_oauth_storage.update_user_oauth2_gmail (a_token, a_user_profile, a_user)
+-- end
+
+ new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
-- Add a new user with oauth2 gmail authentication.
require
has_id: a_user.has_id
do
- user_oauth_storage.new_user_oauth2_gmail (a_token, a_user_profile, a_user)
+ user_oauth_storage.new_user_oauth2 (a_token, a_user_profile, a_user, a_consumer_table)
end
- update_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
+ update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
-- Updaate user `a_user' with oauth2 gmail authentication.
require
has_id: a_user.has_id
do
- user_oauth_storage.update_user_oauth2_gmail (a_token, a_user_profile, a_user)
+ user_oauth_storage.update_user_oauth2 (a_token, a_user_profile, a_user, a_consumer_table)
end
end
diff --git a/modules/login/filter/oauth_gmail_filter.e b/modules/login/filter/oauth_filter.e
similarity index 66%
rename from modules/login/filter/oauth_gmail_filter.e
rename to modules/login/filter/oauth_filter.e
index c4f6310..d7c1f45 100644
--- a/modules/login/filter/oauth_gmail_filter.e
+++ b/modules/login/filter/oauth_filter.e
@@ -1,10 +1,10 @@
note
- description: "Summary description for {OAUTH_GMAIL_FILTER}."
+ description: "Summary description for {OAUTH_FILTER}."
date: "$Date$"
revision: "$Revision$"
class
- OAUTH_GMAIL_FILTER
+ OAUTH_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
@@ -36,14 +36,14 @@ feature -- Basic operations
utf: UTF_CONVERTER
do
api.logger.put_debug (generator + ".execute ", Void)
- if attached req.raw_header_data as l_raw_data then
- api.logger.put_debug (generator + ".execute " + utf.escaped_utf_32_string_to_utf_8_string_8 (l_raw_data), Void)
- end
+-- if attached req.raw_header_data as l_raw_data then
+-- api.logger.put_debug (generator + ".execute " + utf.escaped_utf_32_string_to_utf_8_string_8 (l_raw_data), Void)
+-- end
-- A valid user
if
- attached {WSF_STRING} req.cookie ({LOGIN_CONSTANTS}.oauth_gmail_session) as l_roc_auth_session_token
+ attached {WSF_STRING} req.cookie ({LOGIN_CONSTANTS}.oauth_session) as l_roc_auth_session_token
then
- if attached {CMS_USER} user_oauth_api.user_by_oauth2_gmail_token (l_roc_auth_session_token.value) as l_user then
+ if attached {CMS_USER} user_oauth_api.user_by_oauth2_global_token (l_roc_auth_session_token.value) as l_user then
set_current_user (req, l_user)
execute_next (req, res)
else
diff --git a/modules/login/login_constants.e b/modules/login/login_constants.e
index 39886dc..ffae849 100644
--- a/modules/login/login_constants.e
+++ b/modules/login/login_constants.e
@@ -8,6 +8,6 @@ class
feature -- Access
- oauth_gmail_session: STRING = "EWF_ROC_OAUTH_GMAIL_SESSION_"
-
+ oauth_session: STRING = "EWF_ROC_OAUTH_TOKEN_"
+
end
diff --git a/modules/login/login_module.e b/modules/login/login_module.e
index 4db73b7..e649c95 100644
--- a/modules/login/login_module.e
+++ b/modules/login/login_module.e
@@ -94,18 +94,47 @@ feature {CMS_API} -- Module management
local
sql: STRING
l_setup: CMS_SETUP
+ l_params: detachable STRING_TABLE [detachable ANY]
+ l_consumers: LIST [STRING]
do
l_setup := api.setup
-- Schema
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
- if not l_sql_storage.sql_table_exists ("oauth2_gmail") then
+ if not l_sql_storage.sql_table_exists ("oauth2_consumers") then
--| Schema
- l_sql_storage.sql_execute_file_script (l_setup.environment.path.extended ("scripts").extended ("oauth2_gmail.sql"))
+ l_sql_storage.sql_execute_file_script (l_setup.environment.path.extended ("scripts").extended ("oauth2_consumers.sql"))
if l_sql_storage.has_error then
api.logger.put_error ("Could not initialize database for blog module", generating_type)
end
+ -- TODO workaround.
+ l_sql_storage.sql_execute_file_script (l_setup.environment.path.extended ("scripts").extended ("oauth2_consumers_initialize.sql"))
+ end
+
+ -- TODO workaround, until we have an admin module
+ l_sql_storage.sql_query ("SELECT name FROM oauth2_consumers;", Void)
+ if l_sql_storage.has_error then
+ api.logger.put_error ("Could not initialize database for differnent consumerns", generating_type)
+ else
+ from
+ l_sql_storage.sql_start
+ create {ARRAYED_LIST[STRING]} l_consumers.make (2)
+ until
+ l_sql_storage.sql_after
+ loop
+ if attached l_sql_storage.sql_read_string (1) as l_name then
+ l_consumers.force ("oauth2_"+l_name)
+ end
+ l_sql_storage.sql_forth
+ end
+ across l_consumers as ic loop
+ if not l_sql_storage.sql_table_exists (ic.item) then
+ create l_params.make (1)
+ l_params.force (ic.item, "table_name")
+ l_sql_storage.sql_execute_file_script_with_params (l_setup.environment.path.extended ("scripts").extended ("oauth2_template.sql"), l_params)
+ end
+ end
end
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
end
@@ -116,7 +145,6 @@ feature {CMS_API} -- Access: API
user_oauth_api: detachable CMS_USER_OAUTH_API
--
-
feature -- Filters
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
@@ -124,7 +152,7 @@ feature -- Filters
do
create {ARRAYED_LIST [WSF_FILTER]} Result.make (1)
if attached user_oauth_api as l_user_oauth_api then
- Result.extend (create {OAUTH_GMAIL_FILTER}.make (a_api, l_user_oauth_api))
+ Result.extend (create {OAUTH_FILTER}.make (a_api, l_user_oauth_api))
end
end
@@ -164,8 +192,8 @@ feature -- Router
a_router.handle_with_request_methods ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password (a_api, ?, ?)), a_router.methods_get_post)
a_router.handle_with_request_methods ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password (a_api, ?, ?)), a_router.methods_get_post)
a_router.handle_with_request_methods ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_get_post)
- a_router.handle_with_request_methods ("/account/login-with-google", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_with_google (a_api, ?, ?)), a_router.methods_get_post)
- a_router.handle_with_request_methods ("/account/oauthgmail", create {WSF_URI_AGENT_HANDLER}.make (agent handle_callback_gmail (a_api, a_user_oauth_api, ?, ?)), a_router.methods_get_post)
+ a_router.handle_with_request_methods ("/account/login-with-oauth/{callback}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_login_with_oauth (a_api, ?, ?)), a_router.methods_get_post)
+ a_router.handle_with_request_methods ("/account/{callback}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_callback_oauth (a_api, a_user_oauth_api, ?, ?)), a_router.methods_get_post)
end
@@ -273,17 +301,15 @@ feature -- Hooks
local
r: CMS_RESPONSE
l_url: STRING
- l_oauth_gmail: OAUTH_LOGIN_GMAIL
+ l_oauth_gmail: OAUTH_LOGIN
l_cookie: WSF_COOKIE
do
if
- attached {WSF_STRING} req.cookie ({LOGIN_CONSTANTS}.oauth_gmail_session) as l_cookie_token and then
+ attached {WSF_STRING} req.cookie ({LOGIN_CONSTANTS}.oauth_session) as l_cookie_token and then
attached {CMS_USER} current_user (req) as l_user
then
-- Logout gmail
- create l_oauth_gmail.make (api, req.absolute_script_url (""))
- l_oauth_gmail.sign_out (l_cookie_token.value)
- create l_cookie.make ({LOGIN_CONSTANTS}.oauth_gmail_session, l_cookie_token.value)
+ create l_cookie.make ({LOGIN_CONSTANTS}.oauth_session, l_cookie_token.value)
l_cookie.set_path ("/")
l_cookie.set_max_age (-1)
res.add_cookie (l_cookie)
@@ -563,7 +589,14 @@ feature {NONE} -- Block views
loop
l_tpl_block.set_value (ic.item, ic.key)
end
- a_response.add_block (l_tpl_block, "content")
+ if
+ attached user_oauth_api as l_auth_api and then
+ attached l_auth_api.oauth2_consumers as l_list
+ then
+ l_tpl_block.set_value (l_list, "oauth_consumers")
+ end
+
+ a_response.add_block (l_tpl_block, "content")
else
debug ("cms")
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
@@ -720,16 +753,25 @@ feature {NONE} -- Block views
feature -- OAuth2 Login with google.
- handle_login_with_google (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
+ handle_login_with_oauth (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local
r: CMS_RESPONSE
- l_oauth_gmail: OAUTH_LOGIN_GMAIL
+ l_oauth: OAUTH_LOGIN
do
- create l_oauth_gmail.make (api, req.absolute_script_url (""))
- if attached l_oauth_gmail.authorization_url as l_authorization then
- create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
- r.set_redirection (l_authorization)
- r.execute
+ if
+ attached {WSF_STRING} req.path_parameter ("callback") as p_consumer and then
+ attached {CMS_OAUTH_CONSUMER} oauth_consumer_by_name (api, p_consumer.value) as l_consumer
+ then
+ create l_oauth.make (req.server_url, l_consumer)
+ if attached l_oauth.authorization_url as l_authorization_url then
+ create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
+ r.set_redirection (l_authorization_url)
+ r.execute
+ else
+ create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
+ r.set_main_content ("Bad request")
+ r.execute
+ end
else
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.set_main_content ("Bad request")
@@ -737,22 +779,25 @@ feature -- OAuth2 Login with google.
end
end
- handle_callback_gmail (api: CMS_API; a_user_oauth_api: CMS_USER_OAUTH_API; req: WSF_REQUEST; res: WSF_RESPONSE)
+ handle_callback_oauth (api: CMS_API; a_user_oauth_api: CMS_USER_OAUTH_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local
r: CMS_RESPONSE
- l_auth_gmail: OAUTH_LOGIN_GMAIL
+ l_auth: OAUTH_LOGIN
l_user_api: CMS_USER_API
l_user: CMS_USER
l_roles: LIST [CMS_USER_ROLE]
l_cookie: WSF_COOKIE
es: LOGIN_EMAIL_SERVICE
do
- if attached {WSF_STRING} req.query_parameter ("code") as l_code then
- create l_auth_gmail.make (api, req.server_url)
- l_auth_gmail.sign_request (l_code.value)
+ if attached {WSF_STRING} req.path_parameter ("callback") as l_callback and then
+ attached {CMS_OAUTH_CONSUMER} oauth_consumer_by_callback (api, l_callback.value) as l_consumer and then
+ attached {WSF_STRING} req.query_parameter ("code") as l_code
+ then
+ create l_auth.make (req.server_url, l_consumer)
+ l_auth.sign_request (l_code.value)
if
- attached l_auth_gmail.access_token as l_access_token and then
- attached l_auth_gmail.user_profile as l_user_profile
+ attached l_auth.access_token as l_access_token and then
+ attached l_auth.user_profile as l_user_profile
then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
-- extract user email
@@ -760,18 +805,18 @@ feature -- OAuth2 Login with google.
l_user_api := api.user_api
-- 1 if the user exit put it in the context
if
- attached l_auth_gmail.user_email as l_email
+ attached l_auth.user_email as l_email
then
if attached {CMS_USER} l_user_api.user_by_email (l_email) as p_user then
-- User with email exist
- if attached {CMS_USER} a_user_oauth_api.user_oauth2_gmail_by_id (p_user.id) then
+ if attached {CMS_USER} a_user_oauth_api.user_oauth2_by_id (p_user.id, "oauth2_" + l_consumer.name) then
-- Update oauth entry
- a_user_oauth_api.update_user_oauth2_gmail (l_access_token.token, l_user_profile, p_user )
+ a_user_oauth_api.update_user_oauth2 (l_access_token.token, l_user_profile, p_user, "oauth2_" + l_consumer.name )
else
-- create a oauth entry
- a_user_oauth_api.new_user_oauth2_gmail (l_access_token.token, l_user_profile, p_user )
+ a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, p_user, "oauth2_" + l_consumer.name )
end
- create l_cookie.make ({LOGIN_CONSTANTS}.oauth_gmail_session, l_access_token.token)
+ create l_cookie.make ({LOGIN_CONSTANTS}.oauth_session, l_access_token.token)
l_cookie.set_max_age (l_access_token.expires_in)
l_cookie.set_path ("/")
res.add_cookie (l_cookie)
@@ -789,8 +834,8 @@ feature -- OAuth2 Login with google.
l_user_api.new_user (l_user)
-- Add oauth entry
- a_user_oauth_api.new_user_oauth2_gmail (l_access_token.token, l_user_profile, l_user )
- create l_cookie.make ({LOGIN_CONSTANTS}.oauth_gmail_session, l_access_token.token)
+ a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, l_user, "oauth_" + l_consumer.name )
+ create l_cookie.make ({LOGIN_CONSTANTS}.oauth_session, l_access_token.token)
l_cookie.set_max_age (l_access_token.expires_in)
l_cookie.set_path ("/")
res.add_cookie (l_cookie)
@@ -865,6 +910,120 @@ feature {NONE} -- Implementation: date and time
Result := d.date_time
end
+feature --{NONE} -- Helper OAUTH Consumers.
+
+
+ oauth_consumer_by_name (a_api: CMS_API; a_name: READABLE_STRING_8): detachable CMS_OAUTH_CONSUMER
+ local
+ l_params: detachable STRING_TABLE [detachable ANY]
+ l_setup: CMS_SETUP
+ do
+ -- TODO workaround!!, move to the persistence layer
+ l_setup := a_api.setup
+
+ -- Schema
+ if attached {CMS_STORAGE_SQL_I} a_api.storage as l_sql_storage then
+
+ -- Todo workaround, move this to his own database layer.
+ create l_params.make (1)
+ l_params.force (a_name, "name")
+ l_sql_storage.sql_query ("SELECT * FROM oauth2_consumers where name =:name;", l_params)
+ if l_sql_storage.has_error then
+ a_api.logger.put_error ("Could not retrieve a consumer from the database", generating_type)
+ else
+ -- Fetch a Consumer
+ create Result
+ if attached l_sql_storage.sql_read_integer_64 (1) as l_id then
+ Result.set_id (l_id)
+ end
+ if attached l_sql_storage.sql_read_string_32 (2) as l_name then
+ Result.set_name (l_name)
+ end
+ if attached l_sql_storage.sql_read_string_32 (3) as l_api_secret then
+ Result.set_api_secret (l_api_secret)
+ end
+ if attached l_sql_storage.sql_read_string_32 (4) as l_api_key then
+ Result.set_api_key (l_api_key)
+ end
+ if attached l_sql_storage.sql_read_string_32 (5) as l_scope then
+ Result.set_scope (l_scope)
+ end
+ if attached l_sql_storage.sql_read_string_32 (6) as l_resource_url then
+ Result.set_protected_resource_url (l_resource_url)
+ end
+ if attached l_sql_storage.sql_read_string_32 (7) as l_callback_name then
+ Result.set_callback_name (l_callback_name)
+ end
+ if attached l_sql_storage.sql_read_string_32 (8) as l_extractor then
+ Result.set_extractor (l_extractor)
+ end
+ if attached l_sql_storage.sql_read_string_32 (9) as l_authorize_url then
+ Result.set_authorize_url (l_authorize_url)
+ end
+ if attached l_sql_storage.sql_read_string_32 (10) as l_endpoint then
+ Result.set_endpoint (l_endpoint)
+ end
+ end
+ end
+ end
+
+
+ oauth_consumer_by_callback (a_api: CMS_API; a_name: READABLE_STRING_8): detachable CMS_OAUTH_CONSUMER
+ local
+ l_params: detachable STRING_TABLE [detachable ANY]
+ l_setup: CMS_SETUP
+ do
+ -- TODO workaround !!! move to the persistence layer.
+ l_setup := a_api.setup
+
+
+ -- Schema
+ if attached {CMS_STORAGE_SQL_I} a_api.storage as l_sql_storage then
+
+ -- Todo workaround, move this to his own database layer.
+ create l_params.make (1)
+ l_params.force (a_name, "name")
+ l_sql_storage.sql_query ("SELECT * FROM oauth2_consumers where callback_name =:name;", l_params)
+ if l_sql_storage.has_error then
+ a_api.logger.put_error ("Could not retrieve a consumer from the database", generating_type)
+ else
+ -- Fetch a Consumer
+ create Result
+ if attached l_sql_storage.sql_read_integer_64 (1) as l_id then
+ Result.set_id (l_id)
+ end
+ if attached l_sql_storage.sql_read_string_32 (2) as l_name then
+ Result.set_name (l_name)
+ end
+ if attached l_sql_storage.sql_read_string_32 (3) as l_api_secret then
+ Result.set_api_secret (l_api_secret)
+ end
+ if attached l_sql_storage.sql_read_string_32 (4) as l_api_key then
+ Result.set_api_key (l_api_key)
+ end
+ if attached l_sql_storage.sql_read_string_32 (5) as l_scope then
+ Result.set_scope (l_scope)
+ end
+ if attached l_sql_storage.sql_read_string_32 (6) as l_resource_url then
+ Result.set_protected_resource_url (l_resource_url)
+ end
+ if attached l_sql_storage.sql_read_string_32 (7) as l_callback_name then
+ Result.set_callback_name (l_callback_name)
+ end
+ if attached l_sql_storage.sql_read_string_32 (8) as l_extractor then
+ Result.set_extractor (l_extractor)
+ end
+ if attached l_sql_storage.sql_read_string_32 (9) as l_authorize_url then
+ Result.set_authorize_url (l_authorize_url)
+ end
+ if attached l_sql_storage.sql_read_string_32 (10) as l_endpoint then
+ Result.set_endpoint (l_endpoint)
+ end
+ end
+ end
+ end
+
+
note
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
diff --git a/modules/login/oauth_login_gmail.e b/modules/login/oauth_login.e
similarity index 61%
rename from modules/login/oauth_login_gmail.e
rename to modules/login/oauth_login.e
index f84c622..6c100da 100644
--- a/modules/login/oauth_login_gmail.e
+++ b/modules/login/oauth_login.e
@@ -1,10 +1,10 @@
note
- description: "OAuth workflow for Gmails."
+ description: "OAuth workflow"
date: "$Date$"
revision: "$Revision$"
class
- OAUTH_LOGIN_GMAIL
+ OAUTH_LOGIN
inherit
@@ -15,51 +15,25 @@ create
feature {NONE} -- Initialization
- make (a_cms_api:CMS_API a_host: READABLE_STRING_32)
+ make (a_host: READABLE_STRING_32; a_consumer: CMS_OAUTH_CONSUMER)
-- Create an object with the host `a_host'.
do
- cms_api := a_cms_api
- initilize
+ initilize (a_consumer)
create config.make_default (api_key, api_secret)
- config.set_callback (a_host + "/account/oauthgmail")
+ config.set_callback (a_host + "/account/"+ a_consumer.callback_name)
config.set_scope (scope)
- create goauth
- api_service := goauth.create_service (config)
- ensure
- cms_api_set: cms_api = a_cms_api
+ --Todo create a generic OAUTH_20_GENERIC_API
+ create oauth_api.make (a_consumer.endpoint, a_consumer.authorize_url, a_consumer.extractor)
+ api_service := oauth_api.create_service (config)
end
- initilize
- local
- utf: UTF_CONVERTER
+ initilize (a_consumer: CMS_OAUTH_CONSUMER)
do
--Use configuration values if any if not defaul
- api_key := "KEY"
- api_secret := "SECRET"
- scope := "email"
-
- api_revoke := "[https://accounts.google.com/o/oauth2/revoke?token=$ACCESS_TOKEN]"
- protected_resource_url := "https://www.googleapis.com/plus/v1/people/me"
-
-
- if attached {CONFIG_READER} cms_api.module_configuration ("login", "oauth2_gmail") as cfg then
- if attached cfg.text_item ("api_secret") as l_api_secret then
- api_secret := utf.utf_32_string_to_utf_8_string_8 (l_api_secret)
- end
- if attached cfg.text_item ("api_key") as l_api_key then
- api_key := utf.utf_32_string_to_utf_8_string_8 (l_api_key)
- end
- if attached cfg.text_item ("scope") as l_scope then
- scope := utf.utf_32_string_to_utf_8_string_8 (l_scope)
- end
- if attached cfg.text_item ("api_revoke") as l_api_revoke then
- api_revoke := utf.utf_32_string_to_utf_8_string_8 (l_api_revoke)
- end
- if attached cfg.text_item ("protected_resource_url") as l_resource_url then
- protected_resource_url := utf.utf_32_string_to_utf_8_string_8 (l_resource_url)
- end
- end
-
+ api_key := a_consumer.api_key
+ api_secret := a_consumer.api_secret
+ scope := a_consumer.scope
+ protected_resource_url := a_consumer.protected_resource_url
end
feature -- Access
@@ -103,26 +77,11 @@ feature -- Access
end
end
- sign_out (a_code: READABLE_STRING_32)
- -- Invalidate the current OAuth access token `a_code'.
- local
- l_revoke: STRING
- request: OAUTH_REQUEST
- do
- create l_revoke.make_from_string (api_revoke)
- l_revoke.replace_substring_all ("$ACCESS_TOKEN", a_code)
- create request.make ("POST", l_revoke)
- if attached {OAUTH_RESPONSE} request.execute as l_response then
- -- do nothing
- write_debug_log (generator + ".sign_out response [" + l_response.status.out + "]")
- check invalidate_ok: l_response.status = {HTTP_CONSTANTS}.ok end
- end
- end
-
user_email: detachable READABLE_STRING_32
-- Retrieve user email if any.
local
l_json: JSON_CONFIG
+ utf: UTF_CONVERTER
do
if attached user_profile as l_profile then
create l_json.make_from_string (l_profile)
@@ -132,6 +91,8 @@ feature -- Access
attached {JSON_STRING} l_object.item ("value") as l_email
then
Result := l_email.item
+ elseif attached {JSON_STRING} l_json.item ("email") as l_email then
+ Result := l_email.unescaped_string_32
end
end
end
@@ -146,7 +107,7 @@ feature -- Access
feature {NONE} -- Implementation
- goauth: OAUTH_20_GOOGLE_API
+ oauth_api: CMS_OAUTH_20_GENERIC_API
-- OAuth 2.0 Google API.
config: OAUTH_CONFIG
@@ -164,16 +125,10 @@ feature {NONE} -- Implementation
scope: STRING
-- api scope to access protected resources.
- api_revoke: STRING
- -- Revoke url
-
protected_resource_url: STRING
-- Resource url.
empty_token: detachable OAUTH_TOKEN
-- fake token.
- cms_api: CMS_API
- -- CMS API.
-
end
diff --git a/modules/login/persistence/cms_oauth_20_generic_api.e b/modules/login/persistence/cms_oauth_20_generic_api.e
new file mode 100644
index 0000000..149c340
--- /dev/null
+++ b/modules/login/persistence/cms_oauth_20_generic_api.e
@@ -0,0 +1,94 @@
+note
+ description: "Generic OAUTH2 API"
+ date: "$Date$"
+ revision: "$Revision$"
+
+class
+ CMS_OAUTH_20_GENERIC_API
+
+inherit
+
+ OAUTH_20_API
+ redefine
+ access_token_extractor,
+ access_token_verb
+ end
+
+create
+ make
+
+feature {NONE} -- Initialize
+
+ make (a_endpoint: READABLE_STRING_32; a_authorize_url: READABLE_STRING_32; a_extractor: READABLE_STRING_32)
+ do
+ endpoint := a_endpoint
+ authorize_url := a_authorize_url
+ extractor := a_extractor
+ ensure
+ endpoint_set: endpoint = a_endpoint
+ authorize_url_set: authorize_url = a_authorize_url
+ extractor_set: extractor = a_authorize_url
+ end
+
+ endpoint: READABLE_STRING_32
+ -- Url that receives the access token request.
+
+ authorize_url: READABLE_STRING_32
+ --
+
+ extractor: READABLE_STRING_32
+ -- text, json
+
+feature -- Access
+
+ access_token_extractor: ACCESS_TOKEN_EXTRACTOR
+ -- Return token extractor, by default TOKEN_EXTRACTOR_20.
+ do
+ if extractor.is_case_insensitive_equal_general ("json") then
+ create {JSON_TOKEN_EXTRACTOR} Result
+ else
+ create {TOKEN_EXTRACTOR_20} Result
+ end
+ end
+
+ access_token_verb: READABLE_STRING_GENERAL
+ do
+ Result := "POST"
+ end
+
+ access_token_endpoint: READABLE_STRING_GENERAL
+ -- Url that receives the access token request
+ do
+ create {STRING_32} Result.make_from_string (endpoint)
+ end
+
+ authorization_url (config: OAUTH_CONFIG): detachable READABLE_STRING_GENERAL
+ -- Url where you should redirect your users to authneticate
+ local
+ l_result: STRING_32
+ do
+ if attached config.scope as l_scope then
+ create {STRING_32} l_result.make_from_string (authorize_url + SCOPED_AUTHORIZE_URL)
+ l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
+ if attached config.callback as l_callback then
+ l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_32))
+ end
+ if attached config.callback as l_callback then
+ l_result.replace_substring_all ("$SCOPE", (create {OAUTH_ENCODER}).encoded_string (l_scope.as_string_32))
+ Result := l_result
+ end
+ else
+ create {STRING_32} l_result.make_from_string (authorize_url + SCOPED_AUTHORIZE_URL)
+ l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
+ if attached config.callback as l_callback then
+ l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_32))
+ end
+ end
+ end
+
+feature -- Implementation
+
+ Scoped_authorize_url: STRING = "&scope=$SCOPE";
+
+
+end
diff --git a/modules/login/persistence/cms_user_oauth_storage_i.e b/modules/login/persistence/cms_user_oauth_storage_i.e
index 8932faf..6011ee7 100644
--- a/modules/login/persistence/cms_user_oauth_storage_i.e
+++ b/modules/login/persistence/cms_user_oauth_storage_i.e
@@ -18,27 +18,35 @@ feature -- Error Handling
feature -- Access
- user_oauth2_gmail_by_id (a_uid: like {CMS_USER}.id): detachable CMS_USER
- -- CMS User with Oauth gmail credential by id if any.
+ user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
+ -- CMS User with Oauth credential by id if any.
deferred
end
- user_by_oauth2_gmail_token (a_token: READABLE_STRING_32): detachable CMS_USER
- -- -- CMS User with Oauth gmail credential by access token `a_token' if any.
+ user_by_oauth2_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
+ -- -- CMS User with Oauth credential by access token `a_token' if any.
+ deferred
+ end
+
+ user_by_oauth2_global_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
+ --
+ deferred
+ end
+
+ oauth2_consumers: LIST [STRING]
deferred
end
feature -- Change: User Oauth2
- new_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
- -- Add a new user with oauth2 gmail authentication.
+ new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
+ -- Add a new user with oauth2 authentication.
deferred
end
- update_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
- -- Update user `a_user' with oauth2 gmail authentication.
+ update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
+ -- Update user `a_user' with oauth2 authentication.
deferred
end
-
end
diff --git a/modules/login/persistence/cms_user_oauth_storage_null.e b/modules/login/persistence/cms_user_oauth_storage_null.e
index e20e07f..a907093 100644
--- a/modules/login/persistence/cms_user_oauth_storage_null.e
+++ b/modules/login/persistence/cms_user_oauth_storage_null.e
@@ -22,25 +22,34 @@ feature -- Error handler
feature -- Access
- user_oauth2_gmail_by_id (a_uid: like {CMS_USER}.id): detachable CMS_USER
- -- CMS User with Oauth gmail credential by id if any.
+ user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
+ -- CMS User with Oauth credential by id if any.
do
end
- user_by_oauth2_gmail_token (a_token: READABLE_STRING_32): detachable CMS_USER
- -- -- CMS User with Oauth gmail credential by access token `a_token' if any.
+ user_by_oauth2_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
+ -- -- CMS User with Oauth credential by access token `a_token' if any.
do
end
+ user_by_oauth2_global_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
+ do
+ end
+
+ oauth2_consumers: LIST [STRING]
+ do
+ create {ARRAYED_LIST[STRING]} Result.make (0)
+ end
+
feature -- Change: User Oauth2
- new_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
- -- Add a new user with oauth2 gmail authentication.
+ new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
+ -- Add a new user with oauth2 authentication.
do
end
- update_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
- -- Update user `a_user' with oauth2 gmail authentication.
+ update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
+ -- Update user `a_user' with oauth2 authentication.
do
end
diff --git a/modules/login/persistence/cms_user_oauth_storage_sql.e b/modules/login/persistence/cms_user_oauth_storage_sql.e
index 9a9a692..c0585f6 100644
--- a/modules/login/persistence/cms_user_oauth_storage_sql.e
+++ b/modules/login/persistence/cms_user_oauth_storage_sql.e
@@ -22,16 +22,39 @@ create
feature -- Access User Outh Gmail
- user_oauth2_gmail_by_id (a_uid: like {CMS_USER}.id): detachable CMS_USER
+
+ user_by_oauth2_global_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
+ local
+ l_list: LIST[STRING]
+ do
+ error_handler.reset
+ write_information_log (generator + ".user_by_oauth2_global_token")
+ l_list := oauth2_consumers
+ from
+ l_list.start
+ until
+ l_list.after or attached Result
+ loop
+ if attached {CMS_USER} user_by_oauth2_token (a_token, "oauth2_"+l_list.item) as l_user then
+ Result := l_user
+ end
+ l_list.forth
+ end
+ end
+
+ user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
--
local
l_parameters: STRING_TABLE [detachable ANY]
+ l_string: STRING
do
error_handler.reset
- write_information_log (generator + ".user_oauth2_gmail_by_id")
+ write_information_log (generator + ".user_oauth2_by_id")
create l_parameters.make (1)
l_parameters.put (a_uid, "uid")
- sql_query (select_user_oauth2_gmail_by_id, l_parameters)
+ create l_string.make_from_string (select_user_oauth2_template_by_id)
+ l_string.replace_substring_all ("$table_name", a_consumer_table)
+ sql_query (l_string, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
else
@@ -39,16 +62,19 @@ feature -- Access User Outh Gmail
end
end
- user_by_oauth2_gmail_token (a_token: READABLE_STRING_32): detachable CMS_USER
+ user_by_oauth2_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
--
local
l_parameters: STRING_TABLE [detachable ANY]
+ l_string: STRING
do
error_handler.reset
- write_information_log (generator + ".user_by_oauth2_gmail_token")
+ write_information_log (generator + ".user_by_oauth2_token")
create l_parameters.make (1)
l_parameters.put (a_token, "token")
- sql_query (select_user_by_oauth2_gmail_token, l_parameters)
+ create l_string.make_from_string (select_user_by_oauth2_template_token)
+ l_string.replace_substring_all ("$table_name", a_consumer_table)
+ sql_query (l_string, l_parameters)
if sql_rows_count = 1 then
Result := fetch_user
else
@@ -56,43 +82,71 @@ feature -- Access User Outh Gmail
end
end
+ oauth2_consumers: LIST[STRING]
+ -- Return a list of consumers, or empty
+ do
+ error_handler.reset
+ create {ARRAYED_LIST[STRING]}Result.make (0)
+ write_information_log (generator + ".user_by_oauth2_token")
+ sql_query (Sql_oauth_consumers, Void)
+ if not has_error then
+ from
+ sql_start
+ until
+ sql_after
+ loop
+ if attached sql_read_string (1) as l_name then
+ Result.force (l_name)
+ end
+ sql_forth
+ end
+ end
+ end
+
feature -- Change: User Oauth2 Gmail
- new_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
- -- .
+ new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
+ -- Add a new user with oauth2 authentication.
+ -- .
local
l_parameters: STRING_TABLE [detachable ANY]
+ l_string: STRING
do
error_handler.reset
sql_begin_transaction
- write_information_log (generator + ".new_user_oauth2_gmail")
+ write_information_log (generator + ".new_user_oauth2")
create l_parameters.make (4)
l_parameters.put (a_user.id, "uid")
l_parameters.put (a_token, "token")
l_parameters.put (a_user_profile, "profile")
l_parameters.put (create {DATE_TIME}.make_now_utc, "utc_date")
- sql_change (sql_insert_oauth2_gmail, l_parameters)
+ create l_string.make_from_string (sql_insert_oauth2_template)
+ l_string.replace_substring_all ("$table_name", a_consumer_table)
+ sql_change (l_string, l_parameters)
sql_commit_transaction
end
-
- update_user_oauth2_gmail (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER)
+ update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
+ -- Update user `a_user' with oauth2 authentication.
--
local
l_parameters: STRING_TABLE [detachable ANY]
+ l_string: STRING
do
error_handler.reset
sql_begin_transaction
- write_information_log (generator + ".new_user_oauth2_gmail")
+ write_information_log (generator + ".new_user_oauth2")
create l_parameters.make (4)
l_parameters.put (a_user.id, "uid")
l_parameters.put (a_token, "token")
l_parameters.put (a_user_profile, "profile")
- sql_change (sql_update_oauth2_gmail, l_parameters)
+ create l_string.make_from_string (sql_update_oauth2_template)
+ l_string.replace_substring_all ("$table_name", a_consumer_table)
+ sql_change (l_string, l_parameters)
sql_commit_transaction
end
@@ -135,15 +189,17 @@ feature {NONE} -- Implementation: User
end
end
-feature {NONE}-- User Oauth2 Gmail.
+feature -- {NONE} User OAuth2
- Sql_insert_oauth2_gmail: STRING = "INSERT INTO oauth2_gmail (uid, access_token, details, created) VALUES (:uid, :token, :profile, :utc_date);"
+ Select_user_by_oauth2_template_token: STRING = "SELECT u.* FROM users as u JOIN $table_name as og ON og.uid = u.uid and og.access_token = :token;"
- Sql_update_oauth2_gmail: STRING = "UPDATE oauth2_gmail SET access_token = :token, details = :profile WHERE uid =:uid;"
+ Select_user_oauth2_template_by_id: STRING = "SELECT u.* FROM users as u JOIN $table_name as og ON og.uid = u.uid and og.uid = :uid;"
- Select_user_by_oauth2_gmail_token: STRING = "SELECT u.* FROM users as u JOIN oauth2_gmail as og ON og.uid = u.uid and og.access_token = :token;"
- Select_user_oauth2_gmail_by_id: STRING = "SELECT u.* FROM users as u JOIN oauth2_gmail as og ON og.uid = u.uid and og.uid = :uid;"
+ Sql_insert_oauth2_template: STRING = "INSERT INTO $table_name (uid, access_token, details, created) VALUES (:uid, :token, :profile, :utc_date);"
+ Sql_update_oauth2_template: STRING = "UPDATE $table_name SET access_token = :token, details = :profile WHERE uid =:uid;"
+
+ Sql_oauth_consumers: STRING = "SELECT name FROM oauth2_consumers";
end
diff --git a/src/persistence/sql/cms_storage_sql_i.e b/src/persistence/sql/cms_storage_sql_i.e
index 8f38ab0..fa9f91b 100644
--- a/src/persistence/sql/cms_storage_sql_i.e
+++ b/src/persistence/sql/cms_storage_sql_i.e
@@ -76,7 +76,7 @@ feature -- Operation
i := a_sql_statement.index_of (':', i)
if i = 0 then
i := n -- exit
- else
+ elseif a_sql_statement.at (i-1).is_equal ('%'') or else a_sql_statement.at (i-1).is_equal ('%"') or else a_sql_statement.at (i-1).is_equal (' ') or else a_sql_statement.at (i-1).is_equal ('=') then
from
j := i + 1
until
@@ -124,6 +124,30 @@ feature -- Operation
feature -- Helper
+ sql_execute_file_script_with_params (a_path: PATH; a_params: detachable STRING_TABLE [detachable ANY])
+ -- Execute SQL script from `a_path' and with params `a_params'.
+ local
+ f: PLAIN_TEXT_FILE
+ sql: STRING
+ do
+ create f.make_with_path (a_path)
+ if f.exists and then f.is_access_readable then
+ create sql.make (f.count)
+ f.open_read
+ from
+ f.start
+ until
+ f.exhausted or f.end_of_file
+ loop
+ f.read_stream_thread_aware (1_024)
+ sql.append (f.last_string)
+ end
+ f.close
+ sql_execute_script_with_params (sql, a_params)
+ end
+ end
+
+
sql_execute_file_script (a_path: PATH)
-- Execute SQL script from `a_path'.
local
@@ -157,6 +181,14 @@ feature -- Helper
-- sql_commit_transaction
end
+ sql_execute_script_with_params (a_sql_script: STRING; a_params: detachable STRING_TABLE [detachable ANY])
+ -- Execute SQL script.
+ -- i.e: multiple SQL statements.
+ do
+ reset_error
+ sql_change (a_sql_script, a_params)
+ end
+
sql_table_exists (a_table_name: READABLE_STRING_8): BOOLEAN
-- Does table `a_table_name' exists?
local