Initial commit, added new module oauth20.
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_CONSTANTS}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_CONSTANTS
|
||||
|
||||
feature -- Access
|
||||
|
||||
oauth_session: STRING = "EWF_ROC_OAUTH_TOKEN_"
|
||||
-- Name of Cookie used to keep the session info.
|
||||
-- FIXME: make this configurable.
|
||||
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
note
|
||||
description: "Module Logging supporting different authentication strategies"
|
||||
description: "Module Auth"
|
||||
date: "$Date: 2015-05-20 06:50:50 -0300 (mi. 20 de may. de 2015) $"
|
||||
revision: "$Revision: 97328 $"
|
||||
|
||||
@@ -8,15 +8,9 @@ class
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
rename
|
||||
module_api as user_oauth_api
|
||||
|
||||
redefine
|
||||
filters,
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install,
|
||||
user_oauth_api
|
||||
register_hooks
|
||||
end
|
||||
|
||||
|
||||
@@ -57,103 +51,6 @@ feature {NONE} -- Initialization
|
||||
cache_duration := 0
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_user_auth_api: like user_oauth_api
|
||||
l_user_auth_storage: CMS_OAUTH_20_STORAGE_I
|
||||
do
|
||||
Precursor (a_api)
|
||||
|
||||
-- Storage initialization
|
||||
if attached {CMS_STORAGE_SQL_I} a_api.storage as l_storage_sql then
|
||||
create {CMS_OAUTH_20_STORAGE_SQL} l_user_auth_storage.make (l_storage_sql)
|
||||
else
|
||||
-- FIXME: in case of NULL storage, should Current be disabled?
|
||||
create {CMS_OAUTH_20_STORAGE_NULL} l_user_auth_storage
|
||||
end
|
||||
|
||||
-- Node API initialization
|
||||
create l_user_auth_api.make_with_storage (a_api, l_user_auth_storage)
|
||||
user_oauth_api := l_user_auth_api
|
||||
ensure then
|
||||
user_oauth_api_set: user_oauth_api /= Void
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
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_consumers") then
|
||||
--| Schema
|
||||
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
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
|
||||
user_oauth_api: detachable CMS_OAUTH_20_API
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Filters
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Possibly list of Filter's module.
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (1)
|
||||
if attached user_oauth_api as l_user_oauth_api then
|
||||
Result.extend (create {CMS_OAUTH_20_FILTER}.make (a_api, l_user_oauth_api))
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: docs
|
||||
|
||||
@@ -176,13 +73,11 @@ feature -- Router
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached user_oauth_api as l_user_oauth_api then
|
||||
configure_web (a_api, l_user_oauth_api, a_router)
|
||||
end
|
||||
configure_web (a_api, a_router)
|
||||
end
|
||||
|
||||
|
||||
configure_web (a_api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API; a_router: WSF_ROUTER)
|
||||
configure_web (a_api: CMS_API; a_router: WSF_ROUTER)
|
||||
do
|
||||
a_router.handle ("/account/roc-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register (a_api, ?, ?)), a_router.methods_get_post)
|
||||
@@ -191,8 +86,6 @@ feature -- Router
|
||||
a_router.handle ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/login-with-oauth/{callback}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_login_with_oauth (a_api,a_user_oauth_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/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
|
||||
|
||||
|
||||
@@ -289,27 +182,11 @@ feature -- Hooks
|
||||
l_url: STRING
|
||||
l_cookie: WSF_COOKIE
|
||||
do
|
||||
if
|
||||
attached {WSF_STRING} req.cookie ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session) as l_cookie_token and then
|
||||
attached {CMS_USER} current_user (req) as l_user
|
||||
then
|
||||
-- Logout gmail
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session, l_cookie_token.value)
|
||||
l_cookie.set_path ("/")
|
||||
l_cookie.set_max_age (-1)
|
||||
res.add_cookie (l_cookie)
|
||||
unset_current_user (req)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
r.execute
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
l_url := req.absolute_script_url ("/basic_auth_logoff")
|
||||
r.set_redirection (l_url)
|
||||
r.execute
|
||||
end
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
l_url := req.absolute_script_url ("/basic_auth_logoff")
|
||||
r.set_redirection (l_url)
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_register (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
@@ -554,13 +431,6 @@ feature {NONE} -- Block views
|
||||
loop
|
||||
l_tpl_block.set_value (ic.item, ic.key)
|
||||
end
|
||||
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")
|
||||
@@ -708,110 +578,6 @@ feature {NONE} -- Block views
|
||||
end
|
||||
end
|
||||
|
||||
feature -- OAuth2 Login with google.
|
||||
|
||||
handle_login_with_oauth (api: CMS_API; a_oauth_api: CMS_OAUTH_20_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_oauth: CMS_OAUTH_20_WORKFLOW
|
||||
do
|
||||
if
|
||||
attached {WSF_STRING} req.path_parameter ("callback") as p_consumer and then
|
||||
attached {CMS_OAUTH_20_CONSUMER} a_oauth_api.oauth_consumer_by_name (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")
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
handle_callback_oauth (api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_auth: CMS_OAUTH_20_WORKFLOW
|
||||
l_user_api: CMS_USER_API
|
||||
l_user: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_cookie: WSF_COOKIE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("callback") as l_callback and then
|
||||
attached {CMS_OAUTH_20_CONSUMER} a_user_oauth_api.oauth_consumer_by_callback (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.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
|
||||
-- check if the user exist
|
||||
l_user_api := api.user_api
|
||||
-- 1 if the user exit put it in the context
|
||||
if
|
||||
attached l_auth.user_email as l_email
|
||||
then
|
||||
if attached l_user_api.user_by_email (l_email) as p_user then
|
||||
-- User with email exist
|
||||
if attached a_user_oauth_api.user_oauth2_by_id (p_user.id, l_consumer.name) then
|
||||
-- Update oauth entry
|
||||
a_user_oauth_api.update_user_oauth2 (l_access_token.token, l_user_profile, p_user, l_consumer.name )
|
||||
else
|
||||
-- create a oauth entry
|
||||
a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, p_user, l_consumer.name )
|
||||
end
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_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)
|
||||
else
|
||||
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (1)
|
||||
l_roles.force (l_user_api.authenticated_user_role)
|
||||
|
||||
-- Create a new user and oauth entry
|
||||
create l_user.make (l_email)
|
||||
l_user.set_email (l_email)
|
||||
l_user.set_password (new_token) -- generate a random password.
|
||||
l_user.set_roles (l_roles)
|
||||
l_user.mark_active
|
||||
l_user_api.new_user (l_user)
|
||||
|
||||
-- Add oauth entry
|
||||
a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, l_user, l_consumer.name )
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_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)
|
||||
set_current_user (req, l_user)
|
||||
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_welcome_email")
|
||||
es.send_contact_welcome_email (l_email, "")
|
||||
end
|
||||
end
|
||||
r.set_redirection (r.front_page_url)
|
||||
r.execute
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
feature {NONE} -- Token Generation
|
||||
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
API to manage CMS User OAuth authentication.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_API
|
||||
|
||||
inherit
|
||||
CMS_MODULE_API
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create {CMS_AUTHENTICATION_MODULE}
|
||||
make_with_storage
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_storage (a_api: CMS_API; a_oauth_storage: CMS_OAUTH_20_STORAGE_I)
|
||||
-- Create an object with api `a_api' and storage `a_oauth_storage'.
|
||||
do
|
||||
oauth_20_storage := a_oauth_storage
|
||||
make (a_api)
|
||||
ensure
|
||||
oauht_20_storage_set: oauth_20_storage = a_oauth_storage
|
||||
end
|
||||
|
||||
feature {CMS_MODULE} -- Access: User oauth storage.
|
||||
|
||||
oauth_20_storage: CMS_OAUTH_20_STORAGE_I
|
||||
-- storage interface.
|
||||
|
||||
feature -- Access: User Oauth20
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve a user by id `a_uid' for the consumer `a_consumer', if any.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_by_id (a_uid, a_consumer)
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_GENERAL; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' for the consumer `a_consumer'.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_by_token (a_token, a_consumer)
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve user by token `a_token' searching in all the registered consumers in the system.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_without_consumer_by_token (a_token)
|
||||
end
|
||||
|
||||
feature -- Access: Consumers OAuth20
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
-- List of Oauth_20 consumers, if any, empty in other case.
|
||||
do
|
||||
Result := oauth_20_storage.oauth2_consumers
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
do
|
||||
Result := oauth_20_storage.oauth_consumer_by_name (a_name)
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
do
|
||||
Result := oauth_20_storage.oauth_consumer_by_callback (a_callback)
|
||||
end
|
||||
|
||||
feature -- Change: User OAuth20
|
||||
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_GENERAL)
|
||||
-- Add a new user with oauth20 using the consumer `a_consumer'.
|
||||
require
|
||||
has_id: a_user.has_id
|
||||
do
|
||||
oauth_20_storage.new_user_oauth2 (a_token, a_user_profile, a_user, a_consumer)
|
||||
end
|
||||
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_GENERAL)
|
||||
-- Updaate user `a_user' with oauth2 for the consumer `a_consumer'.
|
||||
require
|
||||
has_id: a_user.has_id
|
||||
do
|
||||
oauth_20_storage.update_user_oauth2 (a_token, a_user_profile, a_user, a_consumer_table)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,156 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_CONSUMER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_CONSUMER
|
||||
|
||||
inherit
|
||||
ANY
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
make_with_id
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_id (a_id: like id)
|
||||
do
|
||||
id := a_id
|
||||
default_create
|
||||
end
|
||||
|
||||
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_8
|
||||
-- Url that receives the access token request.
|
||||
|
||||
authorize_url: READABLE_STRING_8
|
||||
--
|
||||
|
||||
extractor: READABLE_STRING_8
|
||||
-- text, json
|
||||
|
||||
|
||||
callback_name: READABLE_STRING_8
|
||||
-- consumer callback name
|
||||
|
||||
protected_resource_url: READABLE_STRING_8
|
||||
-- consumer resource url
|
||||
|
||||
scope: READABLE_STRING_8
|
||||
-- consumer scope
|
||||
|
||||
api_key: READABLE_STRING_8
|
||||
-- consumer public key
|
||||
|
||||
api_secret: READABLE_STRING_8
|
||||
-- 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
|
||||
@@ -1,133 +0,0 @@
|
||||
note
|
||||
description: "OAuth workflow"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_WORKFLOW
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_host: READABLE_STRING_32; a_consumer: CMS_OAUTH_20_CONSUMER)
|
||||
-- Create an object with the host `a_host'.
|
||||
do
|
||||
initilize (a_consumer)
|
||||
create config.make_default (a_consumer.api_key, a_consumer.api_secret)
|
||||
config.set_callback (a_host + "/account/"+ a_consumer.callback_name)
|
||||
config.set_scope (a_consumer.scope)
|
||||
--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 (a_consumer: CMS_OAUTH_20_CONSUMER)
|
||||
do
|
||||
--Use configuration values if any if not defaul
|
||||
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
|
||||
|
||||
authorization_url: detachable READABLE_STRING_32
|
||||
-- Obtain the Authorization URL.
|
||||
do
|
||||
-- Obtain the Authorization URL
|
||||
write_debug_log (generator + ".authorization_url Fetching the Authorization URL..!")
|
||||
if attached api_service.authorization_url (empty_token) as l_authorization_url then
|
||||
write_debug_log (generator + ".authorization_url: Got the Authorization URL!")
|
||||
write_debug_log (generator + ".authorization_url:" + l_authorization_url)
|
||||
Result := l_authorization_url.as_string_32
|
||||
end
|
||||
end
|
||||
|
||||
sign_request (a_code: READABLE_STRING_32)
|
||||
-- Sign request with code `a_code'.
|
||||
--! To get the code `a_code' you need to do a request
|
||||
--! using the authorization_url
|
||||
local
|
||||
request: OAUTH_REQUEST
|
||||
do
|
||||
-- Get the access token.
|
||||
write_debug_log (generator + ".sign_request Fetching the access token with code [" + a_code + "]")
|
||||
access_token := api_service.access_token_post (empty_token, create {OAUTH_VERIFIER}.make (a_code))
|
||||
if attached access_token as l_access_token then
|
||||
write_debug_log (generator + ".sign_request Got the Access Token [" + l_access_token.debug_output + "]")
|
||||
-- Get the user email
|
||||
--! at the moment the scope is mail, but we can change it to get more information.
|
||||
create request.make ("GET", protected_resource_url)
|
||||
request.add_header ("Authorization", "Bearer " + l_access_token.token)
|
||||
api_service.sign_request (l_access_token, request)
|
||||
if attached {OAUTH_RESPONSE} request.execute as l_response then
|
||||
write_debug_log (generator + ".sign_request Sign_request response [" + l_response.status.out + "]")
|
||||
if attached l_response.body as l_body then
|
||||
user_profile := l_body
|
||||
write_debug_log (generator + ".sign_request User profile [" + l_body + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
user_email: detachable READABLE_STRING_32
|
||||
-- Retrieve user email if any.
|
||||
local
|
||||
l_json: JSON_CONFIG
|
||||
do
|
||||
if attached user_profile as l_profile then
|
||||
create l_json.make_from_string (l_profile)
|
||||
if
|
||||
attached {JSON_ARRAY} l_json.item ("emails") as l_array and then
|
||||
attached {JSON_OBJECT} l_array.i_th (1) as l_object and then
|
||||
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
|
||||
|
||||
feature -- Access
|
||||
|
||||
access_token: detachable OAUTH_TOKEN
|
||||
-- JSON representing the access token.
|
||||
|
||||
user_profile: detachable READABLE_STRING_32
|
||||
-- JSON representing the user profiles.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
oauth_api: CMS_OAUTH_20_GENERIC_API
|
||||
-- OAuth 2.0 Google API.
|
||||
|
||||
config: OAUTH_CONFIG
|
||||
-- configuration.
|
||||
|
||||
api_service: OAUTH_SERVICE_I
|
||||
-- Service.
|
||||
|
||||
api_key: STRING
|
||||
-- public key.
|
||||
|
||||
api_secret: STRING
|
||||
-- secret key.
|
||||
|
||||
scope: STRING
|
||||
-- api scope to access protected resources.
|
||||
|
||||
protected_resource_url: STRING
|
||||
-- Resource url.
|
||||
|
||||
empty_token: detachable OAUTH_TOKEN
|
||||
-- fake token.
|
||||
|
||||
end
|
||||
@@ -1,52 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_FILTER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_FILTER
|
||||
|
||||
inherit
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
CMS_HANDLER
|
||||
rename
|
||||
make as make_handler
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API)
|
||||
do
|
||||
make_handler (a_api)
|
||||
user_oauth_api := a_user_oauth_api
|
||||
end
|
||||
|
||||
user_oauth_api: CMS_OAUTH_20_API
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
do
|
||||
api.logger.put_debug (generator + ".execute ", Void)
|
||||
-- A valid user
|
||||
if
|
||||
attached {WSF_STRING} req.cookie ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session) as l_roc_auth_session_token
|
||||
then
|
||||
if attached user_oauth_api.user_oauth2_without_consumer_by_token (l_roc_auth_session_token.value) as l_user then
|
||||
set_current_user (req, l_user)
|
||||
else
|
||||
api.logger.put_error (generator + ".execute login_valid failed for: " + l_roc_auth_session_token.value , Void)
|
||||
end
|
||||
else
|
||||
api.logger.put_debug (generator + ".execute without authentication", Void)
|
||||
end
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,94 +0,0 @@
|
||||
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_8; a_authorize_url: READABLE_STRING_8; a_extractor: READABLE_STRING_8)
|
||||
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_8
|
||||
-- Url that receives the access token request.
|
||||
|
||||
authorize_url: READABLE_STRING_8
|
||||
--
|
||||
|
||||
extractor: READABLE_STRING_8
|
||||
-- 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: STRING_8
|
||||
do
|
||||
Result := "POST"
|
||||
end
|
||||
|
||||
access_token_endpoint: STRING_8
|
||||
-- Url that receives the access token request
|
||||
do
|
||||
create Result.make_from_string (endpoint)
|
||||
end
|
||||
|
||||
authorization_url (config: OAUTH_CONFIG): detachable STRING_8
|
||||
-- Url where you should redirect your users to authneticate
|
||||
local
|
||||
l_result: STRING_8
|
||||
do
|
||||
if attached config.scope as l_scope then
|
||||
create 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_8))
|
||||
end
|
||||
if attached config.callback as l_callback then
|
||||
l_result.replace_substring_all ("$SCOPE", (create {OAUTH_ENCODER}).encoded_string (l_scope.as_STRING_8))
|
||||
Result := l_result
|
||||
end
|
||||
else
|
||||
create 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_8))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
Scoped_authorize_url: STRING = "&scope=$SCOPE";
|
||||
|
||||
|
||||
end
|
||||
@@ -1,66 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
API to handle OAUTH storage
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
inherit
|
||||
SHARED_LOGGER
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: Users
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve a user by id `a_uid' for the consumer `a_consumer', if aby.
|
||||
deferred
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_GENERAL; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' for the consumer `a_consumer'.
|
||||
deferred
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve user by token `a_token' searching in all the registered consumers in the system.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: Consumers
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
deferred
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
deferred
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: User Oauth2
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_GENERAL)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
deferred
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_GENERAL )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,69 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_STORAGE_NULL}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_STORAGE_NULL
|
||||
|
||||
inherit
|
||||
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
|
||||
feature -- Error handler
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
do
|
||||
create Result.make
|
||||
end
|
||||
|
||||
feature -- Access: Users
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- CMS User with Oauth credential by id if any.
|
||||
do
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_GENERAL; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- -- CMS User with Oauth credential by access token `a_token' if any.
|
||||
do
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_GENERAL ): detachable CMS_USER
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Access: Consumers
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
do
|
||||
create {ARRAYED_LIST [STRING]} Result.make (0)
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
do
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Change: User Oauth2
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_GENERAL)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
do
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_GENERAL )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
do
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -1,311 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_STORAGE_SQL}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_STORAGE_SQL
|
||||
|
||||
inherit
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
CMS_STORAGE_SQL_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access User Outh
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- Retrieve user by token `a_token' searching in all the registered consumers in the system.
|
||||
local
|
||||
l_list: LIST [STRING]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_oauth2_without_consumer_by_token")
|
||||
l_list := oauth2_consumers
|
||||
from
|
||||
l_list.start
|
||||
until
|
||||
l_list.after or Result /= Void
|
||||
loop
|
||||
Result := user_oauth2_by_token (a_token, l_list.item)
|
||||
l_list.forth
|
||||
end
|
||||
end
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_oauth2_by_id")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_uid, "uid")
|
||||
create l_string.make_from_string (select_user_oauth2_template_by_id)
|
||||
l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer))
|
||||
sql_query (l_string, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_GENERAL; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_by_oauth2_token")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
create l_string.make_from_string (select_user_by_oauth2_template_token)
|
||||
l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer))
|
||||
sql_query (l_string, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature --Access: Consumers
|
||||
|
||||
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
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".oauth_consumer_by_name")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_name, "name")
|
||||
sql_query (sql_oauth_consumer_name, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_consumer
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".oauth_consumer_by_callback")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_callback, "name")
|
||||
sql_query (sql_oauth_consumer_callback, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_consumer
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: User OAuth
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_GENERAL)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
-- <Precursor>.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
|
||||
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")
|
||||
|
||||
create l_string.make_from_string (sql_insert_oauth2_template)
|
||||
l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer))
|
||||
sql_change (l_string, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_GENERAL; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_GENERAL )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
|
||||
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")
|
||||
|
||||
create l_string.make_from_string (sql_update_oauth2_template)
|
||||
l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer))
|
||||
sql_change (l_string, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation OAuth Consumer
|
||||
|
||||
fetch_consumer: detachable CMS_OAUTH_20_CONSUMER
|
||||
do
|
||||
if attached sql_read_integer_64 (1) as l_id then
|
||||
create Result.make_with_id (l_id)
|
||||
|
||||
if attached sql_read_string (2) as l_name then
|
||||
Result.set_name (l_name)
|
||||
end
|
||||
if attached sql_read_string (3) as l_api_secret then
|
||||
Result.set_api_secret (l_api_secret)
|
||||
end
|
||||
if attached sql_read_string (4) as l_api_key then
|
||||
Result.set_api_key (l_api_key)
|
||||
end
|
||||
if attached sql_read_string (5) as l_scope then
|
||||
Result.set_scope (l_scope)
|
||||
end
|
||||
if attached sql_read_string (6) as l_resource_url then
|
||||
Result.set_protected_resource_url (l_resource_url)
|
||||
end
|
||||
if attached sql_read_string (7) as l_callback_name then
|
||||
Result.set_callback_name (l_callback_name)
|
||||
end
|
||||
if attached sql_read_string (8) as l_extractor then
|
||||
Result.set_extractor (l_extractor)
|
||||
end
|
||||
if attached sql_read_string (9) as l_authorize_url then
|
||||
Result.set_authorize_url (l_authorize_url)
|
||||
end
|
||||
if attached sql_read_string (10) as l_endpoint then
|
||||
Result.set_endpoint (l_endpoint)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: User
|
||||
|
||||
fetch_user: detachable CMS_USER
|
||||
local
|
||||
l_id: INTEGER_64
|
||||
l_name: detachable READABLE_STRING_32
|
||||
do
|
||||
if attached sql_read_integer_64 (1) as i then
|
||||
l_id := i
|
||||
end
|
||||
if attached sql_read_string_32 (2) as s and then not s.is_whitespace then
|
||||
l_name := s
|
||||
end
|
||||
|
||||
if l_name /= Void then
|
||||
create Result.make (l_name)
|
||||
if l_id > 0 then
|
||||
Result.set_id (l_id)
|
||||
end
|
||||
elseif l_id > 0 then
|
||||
create Result.make_with_id (l_id)
|
||||
end
|
||||
|
||||
if Result /= Void then
|
||||
if attached sql_read_string (3) as l_password then
|
||||
-- FIXME: should we return the password here ???
|
||||
Result.set_hashed_password (l_password)
|
||||
end
|
||||
if attached sql_read_string (5) as l_email then
|
||||
Result.set_email (l_email)
|
||||
end
|
||||
if attached sql_read_integer_32 (6) as l_status then
|
||||
Result.set_status (l_status)
|
||||
end
|
||||
else
|
||||
check expected_valid_user: False end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- User OAuth2
|
||||
|
||||
oauth2_sql_table_name (a_consumer: READABLE_STRING_GENERAL): STRING_8
|
||||
local
|
||||
i,n: INTEGER
|
||||
do
|
||||
create Result.make_from_string (Sql_oauth2_table_prefix)
|
||||
if a_consumer.is_valid_as_string_8 then
|
||||
Result.append (a_consumer.to_string_8)
|
||||
else
|
||||
check only_ascii: False end
|
||||
-- Replace non ascii char by '-'
|
||||
from
|
||||
i := 1
|
||||
n := a_consumer.count
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if a_consumer [i].is_character_8 then
|
||||
Result.append_code (a_consumer.code (i))
|
||||
else
|
||||
Result.append_character ('-')
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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;"
|
||||
--| FIXME: replace the u.* by a list of field names, to avoid breaking `featch_user' if two fieds are swiped.
|
||||
|
||||
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;"
|
||||
|
||||
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";
|
||||
|
||||
Sql_oauth2_table_prefix: STRING = "oauth2_"
|
||||
|
||||
feature {NONE} -- Consumer
|
||||
|
||||
Sql_oauth_consumer_callback: STRING = "SELECT * FROM oauth2_consumers where callback_name =:name;"
|
||||
|
||||
Sql_oauth_consumer_name: STRING = "SELECT * FROM oauth2_consumers where name =:name;"
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user