Compare commits

..

6 Commits

Author SHA1 Message Date
0fca03a4d1 Improved Authentication module code.
Updated to match recent changes from cypress the OAuth Eiffel library.
2015-06-22 21:47:06 +02:00
642b901856 Make sure CMS_BLOCK knows about page variables values.
For now only for smarty template blocks.
2015-06-19 22:48:20 +02:00
4f3bcf290f Fixing issue with index. 2015-06-19 17:58:09 +02:00
6ca8a9ce82 Fixed parts of SQL statements handling (mostly for SQL script execution). 2015-06-19 17:42:02 +02:00
2c72fe6738 Renamed login module as auth (authentication) module 2015-06-19 11:48:42 +02:00
149de898c0 Updated location for cypress the OAuth Eiffel lib.
prepare login module renaming to auth module.
2015-06-19 11:44:41 +02:00
19 changed files with 235 additions and 197 deletions

View File

@@ -18,9 +18,11 @@
<library name="cms_blog_module" location="modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="cms_login_module" location="..\..\modules\login\login-safe.ecf" readonly="false"/>
<library name="cms_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
<!--
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-safe.ecf" readonly="false"/>
-->
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>

View File

@@ -1,7 +1,7 @@
-- Change the values `TO_COMPLETE` based on your API.
-- 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 ("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");
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');

View File

@@ -30,19 +30,19 @@ CREATE TABLE `role_permissions`(
`module` VARCHAR(255)
);
CREATE TABLE "users_activations" (
"aid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK ("aid" >= 0),
"token" VARCHAR(255) NOT NULL,
"uid" INTEGER NOT NULL CHECK ("uid" >= 0),
"created" DATETIME NOT NULL,
CONSTRAINT "token" UNIQUE ("token")
CREATE TABLE `users_activations` (
`aid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK (`aid` >= 0),
`token` VARCHAR(255) NOT NULL,
`uid` INTEGER NOT NULL CHECK (`uid` >= 0),
`created` DATETIME NOT NULL,
CONSTRAINT `token` UNIQUE (`token`)
);
CREATE TABLE "users_password_recovery" (
"aid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK ("aid" >= 0),
"token" VARCHAR(255) NOT NULL,
"uid" INTEGER NOT NULL CHECK ("uid" >= 0),
"created" DATETIME NOT NULL,
CONSTRAINT "token" UNIQUE ("token")
CREATE TABLE `users_password_recovery` (
`aid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK (`aid` >= 0),
`token` VARCHAR(255) NOT NULL,
`uid` INTEGER NOT NULL CHECK (`uid` >= 0),
`created` DATETIME NOT NULL,
CONSTRAINT `token` UNIQUE (`token`)
);

View File

@@ -1,6 +1,6 @@
<div class="primary-tabs">
{unless isset="$user"}
<h3>Login or <a href="/account/roc-register">Register</a></h3>
<h3>Login or <a href="{$site_url/}account/roc-register">Register</a></h3>
<div>
<div>
<form action method="POST">
@@ -21,14 +21,14 @@
<div>
<div>
<p>
<a href="/account/new-password">Forgot password?</a>
<a href="{$site_url/}account/new-password">Forgot password?</a>
</p>
</div>
</div>
<div>
{foreach item="item" from="$oauth_consumers"}
<a href="/account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
<a href="{$site_url/}account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
{/foreach}
</div>
{/unless}
</div>
</div>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="login" uuid="AAB9EE7D-A671-4727-8658-D417A48B2B57" library_target="login">
<target name="login">
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="auth_module" uuid="AAB9EE7D-A671-4727-8658-D417A48B2B57" library_target="auth_module">
<target name="auth_module">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
@@ -20,8 +20,8 @@
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\communication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
<library name="cypress_consumer" location="$ISE_LIBRARY\contrib\library\web\communication\oauth\cypress\consumer\cypress_consumer-safe.ecf" readonly="false"/>
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
<library name="cypress_consumer" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>

View File

@@ -9,5 +9,7 @@ class
feature -- Access
oauth_session: STRING = "EWF_ROC_OAUTH_TOKEN_"
-- Name of Cookie used to keep the session info.
-- FIXME: make this configurable.
end

View File

@@ -104,57 +104,48 @@ feature -- Access
contact_subject_password: IMMUTABLE_STRING_8
contact_subject_oauth: IMMUTABLE_STRING_8
account_activation: STRING
-- Account activation template email message.
local
p: PATH
do
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_activation.html")
if attached read_template_file (p) as l_content then
Result := l_content
else
create Result.make_from_string (template_account_activation)
end
Result := template_string ("account_activation.html", default_template_account_activation)
end
account_re_activation: STRING
-- Account re_activation template email message.
local
p: PATH
do
p := setup.environment.config_path.extended ("modules").extended ("login").extended("accunt_re_activation.html")
if attached read_template_file (p) as l_content then
Result := l_content
else
create Result.make_from_string (template_account_re_activation)
end
Result := template_string ("accunt_re_activation.html", default_template_account_re_activation)
end
account_password: STRING
-- Account password template email message.
local
p: PATH
do
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_new_password.html")
if attached read_template_file (p) as l_content then
Result := l_content
else
create Result.make_from_string (template_account_new_password)
end
Result := template_string ("account_new_password.html", default_template_account_new_password)
end
account_welcome: STRING
-- Account welcome template email message.
do
Result := template_string ("account_welcome.html", default_template_account_welcome)
end
feature {NONE} -- Implementation: Template
template_path (a_name: READABLE_STRING_GENERAL): PATH
-- Location of template named `a_name'.
do
Result := setup.environment.config_path.extended ("modules").extended ("login").extended (a_name)
end
template_string (a_name: READABLE_STRING_GENERAL; a_default: STRING): STRING
-- Content of template named `a_name', or `a_default' if template is not found.
local
p: PATH
do
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_welcome.html")
p := template_path ("account_activation.html")
if attached read_template_file (p) as l_content then
Result := l_content
else
create Result.make_from_string (template_account_welcome)
create Result.make_from_string (a_default)
end
end
@@ -162,16 +153,17 @@ feature {NONE} -- Implementation
setup: CMS_SETUP
read_template_file (a_path: PATH): detachable STRING
-- Read the content of the file at path `a_path'.
local
l_file: FILE
n: INTEGER
do
create {PLAIN_TEXT_FILE} l_file.make_with_path (a_path)
if l_file.exists and then l_file.is_readable then
n := l_file.count
l_file.open_read
l_file.read_stream (l_file.count)
l_file.read_stream (n)
Result := l_file.last_string
l_file.close
else
@@ -182,7 +174,7 @@ feature {NONE} -- Implementation
feature {NONE} -- Message email
template_account_activation: STRING= "[
default_template_account_activation: STRING = "[
<!doctype html>
<html lang="en">
<head>
@@ -195,7 +187,7 @@ feature {NONE} -- Message email
<body>
<p>Thank you for registering at <a href="...">ROC CMS</a></p>
<p>To complete your registration, please click on this link to activate your account:<p>
<p>To complete your registration, please click on the following link to activate your account:<p>
<p><a href="$link">$link</a></p>
<p>Thank you for joining us.</p>
@@ -204,7 +196,7 @@ feature {NONE} -- Message email
]"
template_account_re_activation: STRING= "[
default_template_account_re_activation: STRING = "[
<!doctype html>
<html lang="en">
<head>
@@ -215,9 +207,9 @@ feature {NONE} -- Message email
</head>
<body>
<p>You have request a new activation token at<a href="...">ROC CMS</a></p>
<p>You have requested a new activation token at <a href="...">ROC CMS</a></p>
<p>To complete your registration, please click on this link to activate your account:<p>
<p>To complete your registration, please click on the following link to activate your account:<p>
<p><a href="$link">$link</a></p>
<p>Thank you for joining us.</p>
@@ -227,7 +219,7 @@ feature {NONE} -- Message email
template_account_new_password: STRING= "[
default_template_account_new_password: STRING = "[
<!doctype html>
<html lang="en">
<head>
@@ -240,7 +232,7 @@ feature {NONE} -- Message email
<body>
<p>You have required a new password at <a href="...">ROC CMS</a></p>
<p>To complete your request, please click on this link to genereate a new password:<p>
<p>To complete your request, please click on this link to generate a new password:<p>
<p><a href="$link">$link</a></p>
</body>
@@ -248,7 +240,7 @@ feature {NONE} -- Message email
]"
template_account_welcome: STRING= "[
default_template_account_welcome: STRING = "[
<!doctype html>
<html lang="en">
<head>

View File

@@ -50,8 +50,8 @@ feature {NONE} -- Initialization
do
name := "login"
version := "1.0"
description := "Eiffel login module"
package := "login"
description := "Authentication module"
package := "authentication"
create root_dir.make_current
cache_duration := 0
@@ -235,7 +235,7 @@ feature -- Hooks
local
l_string: STRING
do
Result := <<"login","register","reactivate","new_password", "reset_password">>
Result := <<"login", "register", "reactivate", "new_password", "reset_password">>
create l_string.make_empty
across Result as ic loop
l_string.append (ic.item)
@@ -248,27 +248,27 @@ feature -- Hooks
do
if
a_block_id.is_case_insensitive_equal_general ("login") and then
a_response.request.path_info.starts_with ("/account/roc-login")
a_response.location.starts_with ("account/roc-login")
then
get_block_view_login (a_block_id, a_response)
elseif
a_block_id.is_case_insensitive_equal_general ("register") and then
a_response.request.path_info.starts_with ("/account/roc-register")
a_response.location.starts_with ("account/roc-register")
then
get_block_view_register (a_block_id, a_response)
elseif
a_block_id.is_case_insensitive_equal_general ("reactivate") and then
a_response.request.path_info.starts_with ("/account/reactivate")
a_response.location.starts_with ("account/reactivate")
then
get_block_view_reactivate (a_block_id, a_response)
elseif
a_block_id.is_case_insensitive_equal_general ("new_password") and then
a_response.request.path_info.starts_with ("/account/new-password")
a_response.location.starts_with ("account/new-password")
then
get_block_view_new_password (a_block_id, a_response)
elseif
a_block_id.is_case_insensitive_equal_general ("reset_password") and then
a_response.request.path_info.starts_with ("/account/reset-password")
a_response.location.starts_with ("account/reset-password")
then
get_block_view_reset_password (a_block_id, a_response)
end
@@ -306,8 +306,7 @@ feature -- Hooks
else
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
r.set_status_code ({HTTP_CONSTANTS}.found)
l_url := req.absolute_script_url ("")
l_url.append ("/basic_auth_logoff")
l_url := req.absolute_script_url ("/basic_auth_logoff")
r.set_redirection (l_url)
r.execute
end
@@ -321,7 +320,7 @@ feature -- Hooks
l_roles: LIST [CMS_USER_ROLE]
l_exist: BOOLEAN
es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_link: STRING
l_url: STRING
l_token: STRING
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
@@ -359,15 +358,12 @@ feature -- Hooks
-- Create activation token
l_token := new_token
l_user_api.new_activation (l_token, u.id)
create l_link.make_from_string (req.server_url)
l_link.append ("/account/activate/")
l_link.append (l_token)
l_url := req.absolute_script_url ("/account/activate/" + l_token)
-- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_email")
es.send_contact_email (l_email.value, l_link)
es.send_contact_email (l_email.value, l_url)
else
r.values.force (l_name.value, "name")
@@ -401,8 +397,7 @@ feature -- Hooks
-- the token does not exist, or it was already used.
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
r.set_value ("Account not activated", "optional_content_type")
r.set_main_content ("<p>The token <i>"+ l_token.value +"</i> is not valid <a href=%"/account/reactivate%">Reactivate Account</a></p>" )
r.set_main_content ("<p>The token <i>" + l_token.value +"</i> is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "</p>")
end
r.execute
else
@@ -418,7 +413,7 @@ feature -- Hooks
es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_user_api: CMS_USER_API
l_token: STRING
l_link: STRING
l_url: STRING
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if req.is_post_request_method then
@@ -434,14 +429,12 @@ feature -- Hooks
else
l_token := new_token
l_user_api.new_activation (l_token, l_user.id)
create l_link.make_from_string (req.server_url)
l_link.append ("/account/activate/")
l_link.append (l_token)
l_url := req.absolute_script_url ("/account/activate/" + l_token)
-- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_activation_email")
es.send_contact_activation_email (l_email.value, l_link)
es.send_contact_activation_email (l_email.value, l_url)
end
else
r.values.force ("The email does not exist or !", "error_email")
@@ -460,7 +453,7 @@ feature -- Hooks
es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_user_api: CMS_USER_API
l_token: STRING
l_link: STRING
l_url: STRING
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if req.is_post_request_method then
@@ -470,14 +463,12 @@ feature -- Hooks
-- User exist create a new token and send a new email.
l_token := new_token
l_user_api.new_password (l_token, l_user.id)
create l_link.make_from_string (req.server_url)
l_link.append ("/account/reset-password?token=")
l_link.append (l_token)
l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token)
-- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_password_email")
es.send_contact_password_email (l_email.value, l_link)
es.send_contact_password_email (l_email.value, l_url)
else
r.values.force ("The email does not exist !", "error_email")
r.values.force (l_email.value, "email")
@@ -499,7 +490,7 @@ feature -- Hooks
if attached {WSF_STRING} req.query_parameter ("token") as l_token then
r.values.force (l_token.value, "token")
if l_user_api.user_by_password_token (l_token.value) = Void then
r.values.force ("The token " + l_token.value + " is not valid, click <a href=%"/account/new-password%">here</a> to generate a new token.", "error_token")
r.values.force ("The token " + l_token.value + " is not valid, " + r.link ("click here" , "account/new-password", Void) + " to generate a new token.", "error_token")
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
end
end
@@ -773,9 +764,9 @@ feature -- OAuth2 Login with google.
if
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
if attached 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_by_id (p_user.id, l_consumer.name) then
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
@@ -788,7 +779,7 @@ feature -- OAuth2 Login with google.
res.add_cookie (l_cookie)
else
create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1)
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
@@ -813,9 +804,8 @@ feature -- OAuth2 Login with google.
write_debug_log (generator + ".handle register: send_contact_welcome_email")
es.send_contact_welcome_email (l_email, "")
end
else
end
r.set_redirection (req.absolute_script_url (""))
r.set_redirection (r.front_page_url)
r.execute
end
@@ -844,8 +834,6 @@ feature {NONE} -- Token Generation
Result := l_token
end
feature {NONE} -- Implementation: date and time
http_date_format_to_date (s: READABLE_STRING_8): detachable DATE_TIME

View File

@@ -34,20 +34,20 @@ feature {CMS_MODULE} -- Access: User oauth storage.
feature -- Access: User Oauth20
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_32): detachable CMS_USER
-- Retrieve a user by id `a_uid' for the consumer `a_consumer', if aby.
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_32; a_consumer: READABLE_STRING_32): detachable CMS_USER
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_32 ): detachable CMS_USER
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
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
@@ -75,7 +75,7 @@ feature -- Access: Consumers OAuth20
feature -- Change: User OAuth20
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32)
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
@@ -84,7 +84,7 @@ feature -- Change: User OAuth20
end
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_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

View File

@@ -8,17 +8,23 @@ class
CMS_OAUTH_20_CONSUMER
inherit
ANY
redefine
default_create
end
create
default_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 ("")
@@ -34,29 +40,29 @@ feature {NONE} -- Initialization
feature -- Access
endpoint: READABLE_STRING_32
endpoint: READABLE_STRING_8
-- Url that receives the access token request.
authorize_url: READABLE_STRING_32
authorize_url: READABLE_STRING_8
--
extractor: READABLE_STRING_32
extractor: READABLE_STRING_8
-- text, json
callback_name: READABLE_STRING_32
callback_name: READABLE_STRING_8
-- consumer callback name
protected_resource_url: READABLE_STRING_32
protected_resource_url: READABLE_STRING_8
-- consumer resource url
scope: READABLE_STRING_32
scope: READABLE_STRING_8
-- consumer scope
api_key: READABLE_STRING_32
api_key: READABLE_STRING_8
-- consumer public key
api_secret: READABLE_STRING_32
api_secret: READABLE_STRING_8
-- consumer secret.
name: READABLE_STRING_32
@@ -65,8 +71,6 @@ feature -- Access
id: INTEGER_64
-- unique identifier.
feature -- Element change
set_extractor (a_extractor: like extractor)

View File

@@ -32,27 +32,21 @@ feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
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
-- A valid user
if
attached {WSF_STRING} req.cookie ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session) as l_roc_auth_session_token
then
if attached {CMS_USER} user_oauth_api.user_oauth2_without_consumer_by_token (l_roc_auth_session_token.value) as l_user 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)
execute_next (req, res)
else
api.logger.put_error (generator + ".execute login_valid failed for: " + l_roc_auth_session_token.value , Void)
execute_next (req, res)
end
else
api.logger.put_debug (generator + ".execute without authentication", Void)
execute_next (req, res)
end
execute_next (req, res)
end
end

View File

@@ -20,18 +20,18 @@ feature -- Error Handling
feature -- Access: Users
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
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_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
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_32 ): detachable CMS_USER
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
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
@@ -53,12 +53,12 @@ feature -- Access: Consumers
feature -- Change: User Oauth2
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
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_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
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

View File

@@ -22,17 +22,17 @@ feature -- Error handler
feature -- Access: Users
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
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_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
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_32 ): detachable CMS_USER
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_GENERAL ): detachable CMS_USER
do
end
@@ -40,7 +40,7 @@ feature -- Access: Consumers
oauth2_consumers: LIST [STRING]
do
create {ARRAYED_LIST[STRING]} Result.make (0)
create {ARRAYED_LIST [STRING]} Result.make (0)
end
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
@@ -55,12 +55,12 @@ feature -- Access: Consumers
feature -- Change: User Oauth2
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
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_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
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

View File

@@ -22,10 +22,10 @@ create
feature -- Access User Outh
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
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]
l_list: LIST [STRING]
do
error_handler.reset
write_information_log (generator + ".user_oauth2_without_consumer_by_token")
@@ -33,16 +33,14 @@ feature -- Access User Outh
from
l_list.start
until
l_list.after or attached Result
l_list.after or Result /= Void
loop
if attached {CMS_USER} user_oauth2_by_token (a_token, l_list.item) as l_user then
Result := l_user
end
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_32): detachable CMS_USER
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]
@@ -53,7 +51,7 @@ feature -- Access User Outh
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", sql_table_name (a_consumer))
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
@@ -62,7 +60,7 @@ feature -- Access User Outh
end
end
user_oauth2_by_token (a_token: READABLE_STRING_32; a_consumer: READABLE_STRING_32): detachable CMS_USER
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]
@@ -73,7 +71,7 @@ feature -- Access User Outh
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", sql_table_name (a_consumer))
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
@@ -85,11 +83,11 @@ feature -- Access User Outh
feature --Access: Consumers
oauth2_consumers: LIST[STRING]
oauth2_consumers: LIST [STRING]
-- Return a list of consumers, or empty
do
error_handler.reset
create {ARRAYED_LIST[STRING]}Result.make (0)
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
@@ -142,7 +140,7 @@ feature --Access: Consumers
feature -- Change: User OAuth
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32)
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
@@ -160,12 +158,12 @@ feature -- Change: User OAuth
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", sql_table_name (a_consumer))
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_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32 )
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
@@ -182,7 +180,7 @@ feature -- Change: User OAuth
l_parameters.put (a_user_profile, "profile")
create l_string.make_from_string (sql_update_oauth2_template)
l_string.replace_substring_all ("$table_name", sql_table_name (a_consumer))
l_string.replace_substring_all ("$table_name", oauth2_sql_table_name (a_consumer))
sql_change (l_string, l_parameters)
sql_commit_transaction
end
@@ -192,39 +190,38 @@ 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
Result.set_id (l_id)
end
if Result /= Void then
if attached sql_read_string_32 (2) as l_name 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_32 (3) as l_api_secret then
if attached sql_read_string (3) as l_api_secret then
Result.set_api_secret (l_api_secret)
end
if attached sql_read_string_32 (4) as l_api_key then
if attached sql_read_string (4) as l_api_key then
Result.set_api_key (l_api_key)
end
if attached sql_read_string_32 (5) as l_scope then
if attached sql_read_string (5) as l_scope then
Result.set_scope (l_scope)
end
if attached sql_read_string_32 (6) as l_resource_url then
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_32 (7) as l_callback_name then
if attached sql_read_string (7) as l_callback_name then
Result.set_callback_name (l_callback_name)
end
if attached sql_read_string_32 (8) as l_extractor then
if attached sql_read_string (8) as l_extractor then
Result.set_extractor (l_extractor)
end
if attached sql_read_string_32 (9) as l_authorize_url then
if attached sql_read_string (9) as l_authorize_url then
Result.set_authorize_url (l_authorize_url)
end
if attached sql_read_string_32 (10) as l_endpoint then
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
@@ -232,7 +229,7 @@ feature {NONE} -- Implementation: User
l_id: INTEGER_64
l_name: detachable READABLE_STRING_32
do
if attached sql_read_integer_32 (1) as i then
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
@@ -264,15 +261,36 @@ feature {NONE} -- Implementation: User
end
end
feature -- {NONE} User OAuth2
feature {NONE} -- User OAuth2
sql_table_name (a_consumer: READABLE_STRING_8): STRING_8
oauth2_sql_table_name (a_consumer: READABLE_STRING_GENERAL): STRING_8
local
i,n: INTEGER
do
Result := Sql_table_prefix.twin
Result.append (a_consumer)
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;"
@@ -282,12 +300,12 @@ feature -- {NONE} User OAuth2
Sql_oauth_consumers: STRING = "SELECT name FROM oauth2_consumers";
Sql_table_prefix: STRING = "oauth2_"
Sql_oauth2_table_prefix: STRING = "oauth2_"
feature -- {NONE} Consumer
feature {NONE} -- Consumer
Sql_oauth_consumer_callback: STRING ="SELECT * FROM oauth2_consumers where callback_name =:name;"
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;"
Sql_oauth_consumer_name: STRING = "SELECT * FROM oauth2_consumers where name =:name;"
end

View File

@@ -76,7 +76,13 @@ feature -- Operation
i := a_sql_statement.index_of (':', i)
if i = 0 then
i := n -- exit
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
elseif
a_sql_statement [i-1] = '%''
or else a_sql_statement [i-1] = '%"'
or else a_sql_statement [i-1] = ' '
or else a_sql_statement [i-1] = '='
or else a_sql_statement [i-1] = '('
then
from
j := i + 1
until
@@ -177,6 +183,7 @@ feature -- Helper
local
i: INTEGER
err: BOOLEAN
cl: CELL [INTEGER]
do
reset_error
sql_begin_transaction
@@ -184,16 +191,17 @@ feature -- Helper
-- sql_change (a_sql_script, Void)
from
i := 1
create cl.put (0)
until
i > a_sql_script.count or err
loop
if attached next_sql_statement (a_sql_script, i) as s then
if attached next_sql_statement (a_sql_script, i, cl) as s then
if not s.is_whitespace then
sql_change (sql_statement (s), Void)
err := err or has_error
reset_error
end
i := i + s.count
i := i + cl.item
else
i := a_sql_script.count + 1
end
@@ -382,11 +390,12 @@ feature -- Conversion
feature {NONE} -- Implementation
next_sql_statement (a_script: STRING; a_start_index: INTEGER): detachable STRING
next_sql_statement (a_script: STRING; a_start_index: INTEGER; a_offset: CELL [INTEGER]): detachable STRING
local
i,j,n: INTEGER
c: CHARACTER
l_end: INTEGER
l_removals: detachable ARRAYED_LIST [TUPLE [start_index,end_index: INTEGER]]
do
from
i := a_start_index
@@ -400,21 +409,32 @@ feature {NONE} -- Implementation
if i < n and then a_script[i + 1] = '-' then
-- Commented line "--" until New Line
j := a_script.index_of ('%N', i)
if j > 0 then
i := j
if j = 0 then
j := n
else
i := n
-- j := j
end
if l_removals = Void then
create l_removals.make (1)
end
l_removals.force ([i,j])
i := j
end
when '/' then
if i < n and then a_script[i + 1] = '*' then
-- Commented text "/*" until closing "*/"
j := a_script.substring_index ("*/", i)
if j > 0 then
i := j
if j = 0 then
j := n
else
i := n
j := j + 1 -- Include '/'
end
if l_removals = Void then
create l_removals.make (1)
end
l_removals.force ([i,j])
i := j
end
when '`', '"', '%'' then
from
@@ -428,6 +448,8 @@ feature {NONE} -- Implementation
if a_script [j - 1] /= '\' then
l_end := j
end
else
l_end := i
end
end
if l_end > 0 then
@@ -440,9 +462,19 @@ feature {NONE} -- Implementation
end
i := i + 1
end
i := a_script.index_of (';', a_start_index)
if i > a_start_index then
if i <= n and i > a_start_index then
Result := a_script.substring (a_start_index, i)
a_offset.replace (Result.count)
if l_removals /= Void then
j := 0
across
l_removals as ic
loop
Result.remove_substring (ic.item.start_index - j, ic.item.end_index - j)
j := j + ic.item.end_index - ic.item.start_index + 1
end
-- a_offset.replace (a_offset.item j)
end
end
end

View File

@@ -921,13 +921,19 @@ feature -- Generation
across
reg_ic.item.blocks as ic
loop
-- if attached {CMS_SMARTY_CONTENT_BLOCK} ic.item as l_tpl_block then
-- across
-- page.variables as var_ic
-- loop
-- l_tpl_block.set_value (var_ic.item, var_ic.key)
-- end
-- end
if attached {CMS_SMARTY_TEMPLATE_BLOCK} ic.item as l_tpl_block then
-- Apply page variables to smarty block.
-- FIXME: maybe add notion of values at the CMS_BLOCK level
-- or consider a CMS_BLOCK_WITH_VALUES ...
across
page.variables as var_ic
loop
if not l_tpl_block.values.has (var_ic.key) then
-- Do not overwrite if has key.
l_tpl_block.set_value (var_ic.item, var_ic.key)
end
end
end
page.add_to_region (theme.block_html (ic.item), reg_ic.item.name)
end
end