Compare commits

...

9 Commits

Author SHA1 Message Date
a6642e9f3e Fixed location of library "http_client_extension" in recaptcha library. 2016-01-15 14:11:51 +01:00
affe3beb27 Merge branch 'roc_register' of https://github.com/jvelilla/ROC into roc_register 2016-01-15 13:30:58 +01:00
jvelilla
2f95c66295 Removed unneeded template
Updated Sql sentence.
2016-01-14 08:39:35 -03:00
de443a2163 Do not use ODBC by default.
(bad for default, since it depends on odbc drivers to be installed)
2016-01-13 17:30:38 +01:00
jvelilla
f244e86f13 Updated user.sql added tabled auth_temp_users.
Added CMS_TEMP_USER as part of the core.
Moved the code from CMS_TEMP_USER_API and CMS_TEMP_USER_STORAGE_* to
CMS_USER_API and CMS_USER_STORAGE_*.
2016-01-12 09:34:39 -03:00
jvelilla
0cf6e59a76 Updated templates and fixed typos.
Renamed classes
2016-01-08 20:26:34 -03:00
jvelilla
0ca336d467 Updated templates
Replaced hardcoded name "ROC CMS" for placeholder $sitename, and
missing href's with $host.
Renamed database script and database table for temporal users.
Renamed CMS_AUTH_API AS CMS_USER_TEMP_API.
Revert design to use CMS_TEMPORAL_USER and clean CMS_USER.
Refactor rename cms_auth_storage_* classes to CMS_TEMPORAL_USER_STORAGE_*
Added Pending Registrations to the admin menu to show the list of pending registrarions
added CSS to display temporal users
2016-01-06 21:29:21 -03:00
jvelilla
5d8ea2065e Rename script name and table name for
temporary users.
Updated message, after account reactivation.
Updated message, post account application.
Updated Form name, Registration instead of Registration Form.
Updated CMS_USER to have two optional features used for temporary users.
Updated CMS_AUTH_API to user CMS_USER instead of CMS_TEMPORAL_USER
Removed CMS_TEMPORAL_USER
Updateed CMS_AUTHENTICATION_MODULE, with new permission to enable
activate, reject or reactivate a pending user registration.
Updated User Storage and API to create a new user from a temporal user.
2016-01-04 21:14:13 -03:00
jvelilla
682193d116 Updated Register Module.
Worlflow

1- Register
1.1 Create a new temporal user
1.2 Email to the new User
1.3 Email to Web Master
2 Web Master Review th Account Application
2.1 Accept and Send an confirmation email to the user and remove the temporal user
2.2 Reject the application send a rejection email to the user and remove the temporal

Added a new table to save temporal users to review their Application to the site.
Updated Register Form with an new input Application and Recaptcha validation.
Updated Emails templates and messages. (TODO improve messages)
Updated mails templates. Simple messages (Todo improve messages).
Added a new handler to reject a user
Updated existing hanlders to handler the new workflow.
2015-12-30 12:32:00 -03:00
54 changed files with 1922 additions and 311 deletions

View File

@@ -39,10 +39,10 @@
<assertions/> <assertions/>
</option> </option>
</library> </library>
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
<!-- <!--
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-safe.ecf" /> <library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
--> -->
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-safe.ecf" />
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <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"/> <library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target> </target>

View File

@@ -0,0 +1,8 @@
{
"email": "webmaster@eiffel.org",
"subject": "Thank you for contacting us",
"recaptcha": {
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
"secret_key":"6Lex9RMTAAAAAAkBczvX5DUiyg_xoM_EthVVgRRx"
}
}

View File

@@ -0,0 +1,22 @@
ul.cms-temp-users {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_information::before {
content: "[personal information] "; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_email::before {
content: "[email] "; }
/*# sourceMappingURL=auth.css.map */

View File

@@ -1,18 +1,14 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Activation</title> <title>Activation</title>
<meta name="description" content="Activation"> <meta name="description" content="Activation">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Thank you for registering at <a href="$host">ROC CMS</a></p> <p>Thank you for applying to <a href="$host">$sitename</a> $user</p>
<p>We will review your application and send you a resolution<p>
<p>To complete your registration, please click on this link to activate your account:<p>
<p><a href="$link">$link</a></p>
<p>Thank you for joining us.</p>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Activation Confirmation</title>
<meta name="description" content="Activation Confirmation">
<meta name="author" content="$sitename">
</head>
<body>
<p>Your account has been confirmed <a href="$host">$sitename</a> $email</p>
<p>Thank you for joining us.</p>
</body>
</html>

View File

@@ -4,13 +4,13 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Password</title> <title>New Password</title>
<meta name="description" content="New Password"> <meta name="description" content="New Password">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have required a new password at <a href="$host">ROC CMS</a></p> <p>You have required a new password at <a href="$host">$sitename</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> <p><a href="$link">$link</a></p>
</body> </body>

View File

@@ -4,11 +4,11 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Activation</title> <title>New Activation</title>
<meta name="description" content="New Activation token"> <meta name="description" content="New Activation token">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have request a new activation token at <a href="$host">ROC CMS</a></p> <p>You have request a new activation token at <a href="$host">$sitename</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 this link to activate your account:<p>

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Application Rejected</title>
<meta name="description" content="Application Rejected">
<meta name="author" content="$sitename">
</head>
<body>
<p>You requested has been rejected, your application does not conform our rules <a href="$host">$sitename</a></p>
</body>
</html>

View File

@@ -4,10 +4,10 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Welcome</title> <title>Welcome</title>
<meta name="description" content="Welcome"> <meta name="description" content="Welcome">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Welcome to<a href="$host">ROC CMS</a></p> <p>Welcome to <a href="$host">$sitename</a></p>
<p>Thank you for joining us.</p> <p>Thank you for joining us.</p>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,26 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Account Evaluation</title>
<meta name="description" content="Account Evaluation">
<meta name="author" content="$sitename">
</head>
<body>
<h2> Account Evaluation </h2>
<p>The user $user ($email) wants to register to the site <a href="$host">$sitename</a></p>
<blockquote><p>User application:</p>
<p>$application</p>
</blockquote>
<p>To complete the registration, please click on the following link to activate the user account:<p>
<p><a href="$activation_url">$activation_url</a></p>
<p>To reject the registration, please click on the following link <p>
<p><a href="$rejection_url<">$rejection_url</a></p>
</body>
</html>

View File

@@ -0,0 +1,13 @@
CREATE TABLE `auth_temp_users` (
`uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
`salt` VARCHAR(100) NOT NULL,
`email` VARCHAR(250) NOT NULL,
`application` TEXT NOT NULL,
CONSTRAINT `name`
UNIQUE(`name`)
);

View File

@@ -1,3 +1,3 @@
<div> <div>
<p>We have send you a new activation code, check your email to activate your account.</p> <p>Thanks for your application, we will review it to activate your account.</p>
</div> </div>

View File

@@ -1,3 +1,3 @@
<div> <div>
<p>Thanks for register, check your email to activate your account.</p> <p>Thanks for your application, we will review it to activate your account.</p>
</div> </div>

View File

@@ -1,7 +1,7 @@
<div> <div>
<form action="{$site_url/}account/roc-register" method="post"> <form action="{$site_url/}account/roc-register" method="post">
<fieldset> <fieldset>
<legend>Register Form</legend> <legend>Registration</legend>
<div> <div>
<input type="text" id="name" name="name" value="{$name/}" required autofocus /> <input type="text" id="name" name="name" value="{$name/}" required autofocus />
<label for="name">Name</label> <label for="name">Name</label>
@@ -20,8 +20,19 @@
<span><i>{$error_email/}</i></span> <br> <span><i>{$error_email/}</i></span> <br>
{/if} {/if}
</div> </div>
<div>
<textarea rows="4" cols="50" name="personal_information" id="personal_information" required>
{$personal_information/}
</textarea>
<label for="personal_information">Tell us why you want to register an account</label>
{if isset="$error_application"}
<span><i>{$error_application/}</i></span> <br>
{/if}
</div>
{unless isempty="$recaptcha_site_key"}
<div class="g-recaptcha" data-sitekey="{$recaptcha_site_key/}"></div>
<br/>
{/unless}
<button type="submit">Register</button> <button type="submit">Register</button>
</fieldset> </fieldset>
</form> </form>

View File

@@ -46,3 +46,18 @@ CREATE TABLE `users_password_recovery` (
CONSTRAINT `token` UNIQUE (`token`) CONSTRAINT `token` UNIQUE (`token`)
); );
CREATE TABLE `auth_temp_users` (
`uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
`salt` VARCHAR(100) NOT NULL,
`email` VARCHAR(250) NOT NULL,
`application` TEXT NOT NULL,
CONSTRAINT `name`
UNIQUE(`name`)
);

View File

@@ -34,8 +34,8 @@ feature -- CMS storage
setup_storage (a_setup: CMS_SETUP) setup_storage (a_setup: CMS_SETUP)
do do
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE3_BUILDER}.make, "sqlite3") a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE3_BUILDER}.make, "sqlite3")
-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql") a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql")
a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc") --a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc")
end end
feature -- CMS modules feature -- CMS modules

View File

@@ -35,12 +35,14 @@ feature {NONE} -- Initialization
parameters: EMAIL_SERVICE_PARAMETERS parameters: EMAIL_SERVICE_PARAMETERS
-- Associated parameters. -- Associated parameters.
admin_email: IMMUTABLE_STRING_8
-- Site admin's email.
mailer: NOTIFICATION_MAILER mailer: NOTIFICATION_MAILER
-- SMTP protocol. -- SMTP protocol.
feature -- Access
admin_email: IMMUTABLE_STRING_8
-- Site admin's email.
feature -- Basic Operations feature -- Basic Operations
send_internal_email (a_content: READABLE_STRING_GENERAL) send_internal_email (a_content: READABLE_STRING_GENERAL)

View File

@@ -0,0 +1,44 @@
note
description: "Summary description for {CMS_TEMP_USER}."
date: "$Date$"
revision: "$Revision$"
class
CMS_TEMP_USER
inherit
CMS_USER
create
make,
make_with_id
feature -- Access
personal_information: detachable STRING_32
-- User personal information.
salt: detachable STRING_32
-- User's password salt.
feature -- Element change
set_personal_information (an_personal_information: like personal_information)
-- Assign `personal_information' with `an_personal_information'.
do
personal_information := an_personal_information
ensure
personal_information_assigned: personal_information = an_personal_information
end
set_salt (a_salt: like salt)
-- Assign `salt' with `a_salt'.
do
salt := a_salt
ensure
salt_assigned: salt = a_salt
end
end

View File

@@ -80,7 +80,6 @@ feature -- Access
-- active -- active
-- trashed -- trashed
feature -- Access: helper feature -- Access: helper
utf_8_name: STRING_8 utf_8_name: STRING_8
@@ -302,6 +301,6 @@ invariant
id_or_name_set: id > 0 or else not name.is_whitespace id_or_name_set: id > 0 or else not name.is_whitespace
note note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" copyright: "2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -61,6 +61,16 @@ CREATE TABLE `users_password_recovery` (
UNIQUE KEY `token` (`token`) UNIQUE KEY `token` (`token`)
); );
CREATE TABLE `auth_temp_users` (
`uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
`salt` VARCHAR(100) NOT NULL,
`email` VARCHAR(250) NOT NULL,
`application` TEXT NOT NULL,
CONSTRAINT `name`
UNIQUE(`name`)
);
COMMIT; COMMIT;

View File

@@ -0,0 +1,4 @@
Recaptcha Eiffel Lbrary
Based on https://developers.google.com/recaptcha/

View File

@@ -0,0 +1,10 @@
${NOTE_KEYWORD}
copyright: "2011-${YEAR} Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="recaptcha" uuid="2A966489-284A-48A0-91BC-31E84EA9C3B1" library_target="recaptcha">
<target name="recaptcha">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" is_obsolete_routine_type="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="http_client_extension" location="..\http_client_extension\http_client_extension-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<cluster name="recaptcha" location=".\src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,22 @@
<?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="recaptcha" uuid="2A966489-284A-48A0-91BC-31E84EA9C3B1" library_target="recaptcha">
<target name="recaptcha">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
<library name="http_client_extension" location="..\http_client_extension\http_client_extension.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<cluster name="recaptcha" location=".\src\" recursive="true">
</cluster>
</target>
</system>

View File

@@ -0,0 +1,147 @@
note
description: "[
Simple API to call {RECAPTCHA} Google API.
Example call:
https://www.google.com/recaptcha/api/siteverify?secret=your_secret&response=response_string&remoteip=user_ip_address
]"
date: "$Date: 2015-01-28 11:44:15 -0300 (mi. 28 de ene. de 2015) $"
revision: "$Revision: 96551 $"
EIS: "name=RECAPTCHA", "src=https://developers.google.com/recaptcha/", "protocol=uri"
EIS: "name=RECAPTCHA API verify", "src=https://developers.google.com/recaptcha/docs/verify", "protocol=uri"
class
RECAPTCHA_API
create
make
feature {NONE} -- Initialization
make (a_secret_key, a_response: READABLE_STRING_8)
-- Create an object Recaptcha with secret key `a_secret_key' and response token `a_response'.
do
secret := a_secret_key
response := a_response
ensure
secret_set: secret.same_string (a_secret_key)
response_set: response.same_string (a_response)
end
feature -- Access
base_uri: STRING_8 = "https://www.google.com/recaptcha/api/siteverify"
-- Recaptcha base URI
secret: READABLE_STRING_8
-- Required. The shared key between your site and ReCAPTCHA.
response: READABLE_STRING_8
-- Required. The user response token provided by the reCAPTCHA to the user and provided to your site on.
remoteip: detachable READABLE_STRING_8
-- Optional. The user's IP address.
feature -- Status Reports
errors: detachable LIST [READABLE_STRING_8]
-- optional table of error codes
-- missing-input-secret The secret parameter is missing.
-- invalid-input-secret The secret parameter is invalid or malformed.
-- missing-input-response The response parameter is missing.
-- invalid-input-response The response parameter is invalid or malformed.
feature -- Change Element
set_remoteip (a_remoteip: READABLE_STRING_8)
-- Set `remoteip' with `a_remoteip'.
do
remoteip := a_remoteip
ensure
remoteip_set: remoteip = a_remoteip
end
feature -- API
verify: BOOLEAN
-- Verify the user's response
local
l_parser: JSON_PARSER
do
if attached get as l_response then
if attached l_response.body as l_body then
create l_parser.make_with_string (l_body)
l_parser.parse_content
if
l_parser.is_parsed and then attached {JSON_OBJECT} l_parser.parsed_json_object as jv and then
attached {JSON_BOOLEAN} jv.item ("success") as l_success
then
Result := l_success.item
if not Result and then attached {JSON_ARRAY} jv.item ("error-codes") as l_error_codes then
across
l_error_codes as c
loop
if attached {JSON_STRING} c.item as ji then
put_error (ji.unescaped_string_32)
end
end
end
end
else
put_error (l_response.status.out)
end
else
put_error ("unknown")
end
end
feature {NONE} -- REST API
get: detachable RESPONSE
-- Reading Data
local
l_request: REQUEST
do
create l_request.make ("GET", new_uri)
Result := l_request.execute
end
feature {NONE} -- Implementation
new_uri: STRING_8
-- new uri (BaseUri?secret=secret_value&response=response_value[&remoteip=remoteip_value]
do
create Result.make_from_string (base_uri)
Result.append ("?secret=")
Result.append (secret)
Result.append ("&response=")
Result.append (response)
if attached remoteip as l_remoteip then
Result.append ("&remoteip=" + l_remoteip)
end
end
put_error (a_code: READABLE_STRING_GENERAL)
local
l_errors: like errors
utf: UTF_CONVERTER
do
l_errors := errors
if l_errors = Void then
create {ARRAYED_LIST [STRING]} l_errors.make (1)
errors := l_errors
end
l_errors.force (utf.utf_32_string_to_utf_8_string_8 (a_code))
end
note
copyright: "2011-2015 Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,61 @@
note
description : "test application root class"
date : "$Date: 2015-01-14 15:37:57 -0300 (mi. 14 de ene. de 2015) $"
revision : "$Revision: 96458 $"
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
test_invalid_input
test_missing_input
test_missing_key_input
end
test_invalid_input
-- invalid-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("","234")
check
not_true:not l_captcha.verify
end
end
test_missing_input
-- missing-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("key","")
check
not_true:not l_captcha.verify
end
end
test_missing_key_input
-- missing-input-response
-- invalid-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("","")
l_captcha.set_remoteip("localhost")
check
not_true:not l_captcha.verify
end
end
end

View File

@@ -0,0 +1,69 @@
note
description: "[
Eiffel tests that can be executed by testing tool.
]"
author: "EiffelStudio test wizard"
date: "$Date: 2015-01-14 15:37:57 -0300 (mi. 14 de ene. de 2015) $"
revision: "$Revision: 96458 $"
testing: "type/manual"
class
RECAPTCHA_API_TEST_SET
inherit
EQA_TEST_SET
feature -- Test routines
test_invalid_input
-- invalid-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("","234")
check
not_true:not l_captcha.verify
end
assert ("Not true", not l_captcha.verify)
assert ("Has error invalid-input-response",has_error (l_captcha,"invalid-input-response"))
end
test_missing_input
-- missing-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("key","")
check
not_true:not l_captcha.verify
end
assert ("Not true", not l_captcha.verify)
assert ("Has error missing-input-response",has_error (l_captcha,"missing-input-response"))
end
test_missing_key_input
-- missing-input-response
-- invalid-input-response
local
l_captcha: RECAPTCHA_API
do
create l_captcha.make ("","")
l_captcha.set_remoteip("localhost")
assert ("Not true", not l_captcha.verify)
assert ("Has error missing-input-response",has_error (l_captcha,"missing-input-response"))
assert ("Has error invalid-input-response",has_error (l_captcha,"invalid-input-response"))
end
feature {NONE} -- Implementation
has_error (l_captcha: RECAPTCHA_API; a_error: READABLE_STRING_32): BOOLEAN
do
if attached l_captcha.errors as l_errors then
l_errors.compare_objects
Result := l_errors.has (a_error)
end
end
end

View File

@@ -0,0 +1,21 @@
<?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="test" uuid="CE9FCE69-EE0A-4028-AA02-BD9F8ABA7586">
<target name="test">
<root class="APPLICATION" feature="make"/>
<option warning="true" void_safety="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<precompile name="base_pre" location="$ISE_PRECOMP\base-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="recaptcha" location="..\recaptcha-safe.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<cluster name="test" location=".\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -1,34 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?> <?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="auth_module" uuid="AAB9EE7D-A671-4727-8658-D417A48B2B57" library_target="auth_module"> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="auth_module" uuid="AAB9EE7D-A671-4727-8658-D417A48B2B57" library_target="auth_module">
<target name="auth_module"> <target name="auth_module">
<root all_classes="true"/> <root all_classes="true"/>
<file_rule> <file_rule>
<exclude>/.git$</exclude> <exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude> <exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule> </file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard"> <option warning="true" full_class_checking="true" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="standard">
</option> </option>
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/> <library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/> <library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/> <library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/> <library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="config" location="..\..\library\configuration\config-safe.ecf"/> <library name="config" location="..\..\library\configuration\config-safe.ecf"/>
<library name="cypress_consumer" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer-safe.ecf" readonly="false"/>
<library name="email_service" location="..\..\library\email\email-safe.ecf"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/> <library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="recaptcha" location="..\..\library\recaptcha\recaptcha-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/> <library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <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"/> <library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/> <library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/> <cluster name="src" location=".\" recursive="true">
<file_rule>
<library name="email_service" location="..\..\library\email\email-safe.ecf"/> <exclude>^persistence$</exclude>
</file_rule>
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/> </cluster>
<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"/>
<cluster name="src" location=".\" recursive="true"/>
</target> </target>
</system> </system>

View File

@@ -17,18 +17,17 @@ feature {NONE} -- Initialization
make (a_cms_api: CMS_API) make (a_cms_api: CMS_API)
local local
utf: UTF_CONVERTER utf: UTF_CONVERTER
l_site_name: READABLE_STRING_8
s: detachable READABLE_STRING_32 s: detachable READABLE_STRING_32
l_contact_email, l_subject_register, l_subject_activate, l_subject_password, l_subject_oauth: detachable READABLE_STRING_8 l_contact_email, l_subject_register, l_subject_activate, l_subject_password, l_subject_oauth: detachable READABLE_STRING_8
do do
cms_api := a_cms_api cms_api := a_cms_api
-- Use global smtp setting if any, otherwise "localhost" -- Use global smtp setting if any, otherwise "localhost"
smtp_server := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.text_item_or_default ("smtp", "localhost")) smtp_server := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.text_item_or_default ("smtp", "localhost"))
l_site_name := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.site_name) site_name := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.site_name)
admin_email := a_cms_api.setup.site_email admin_email := a_cms_api.setup.site_email
if not admin_email.has ('<') then if not admin_email.has ('<') then
admin_email := l_site_name + " <" + admin_email +">" admin_email := site_name + " <" + admin_email +">"
end end
if attached {CONFIG_READER} a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then if attached {CONFIG_READER} a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then
@@ -60,7 +59,7 @@ feature {NONE} -- Initialization
end end
if l_contact_email /= Void then if l_contact_email /= Void then
if not l_contact_email.has ('<') then if not l_contact_email.has ('<') then
l_contact_email := l_site_name + " <" + l_contact_email + ">" l_contact_email := site_name + " <" + l_contact_email + ">"
end end
contact_email := l_contact_email contact_email := l_contact_email
else else
@@ -88,8 +87,15 @@ feature {NONE} -- Initialization
contact_subject_oauth := "Welcome." contact_subject_oauth := "Welcome."
end end
contact_subject_account_evaluation := "New register, account evalution"
contact_subject_rejected := "Your account was rejected"
contact_subject_activated := "Your account was activated"
end end
feature -- Access feature -- Access
cms_api: CMS_API cms_api: CMS_API
@@ -101,10 +107,23 @@ feature -- Access
contact_email: IMMUTABLE_STRING_8 contact_email: IMMUTABLE_STRING_8
-- Contact email. -- Contact email.
site_name: IMMUTABLE_STRING_8
-- UTF-8 encoded Site name.
contact_subject_account_evaluation: IMMUTABLE_STRING_8
contact_subject_register: IMMUTABLE_STRING_8 contact_subject_register: IMMUTABLE_STRING_8
contact_subject_activate: IMMUTABLE_STRING_8 contact_subject_activate: IMMUTABLE_STRING_8
contact_subject_password: IMMUTABLE_STRING_8 contact_subject_password: IMMUTABLE_STRING_8
contact_subject_oauth: IMMUTABLE_STRING_8 contact_subject_oauth: IMMUTABLE_STRING_8
contact_subject_rejected: IMMUTABLE_STRING_8
contact_subject_activated: IMMUTABLE_STRING_8
account_evaluation: STRING
-- Account evaluation template email message.
do
Result := template_string ("admin_account_evaluation.html", default_template_account_evaluation)
end
account_activation: STRING account_activation: STRING
-- Account activation template email message. -- Account activation template email message.
@@ -112,12 +131,24 @@ feature -- Access
Result := template_string ("account_activation.html", default_template_account_activation) Result := template_string ("account_activation.html", default_template_account_activation)
end end
account_activation_confirmation: STRING
-- Account activation confirmation template email message.
do
Result := template_string ("account_activation_confirmation.html", default_template_account_activation_confirmation)
end
account_re_activation: STRING account_re_activation: STRING
-- Account re_activation template email message. -- Account re_activation template email message.
do do
Result := template_string ("accunt_re_activation.html", default_template_account_re_activation) Result := template_string ("accunt_re_activation.html", default_template_account_re_activation)
end end
account_rejected: STRING
-- Account rejected template email message.
do
Result := template_string ("accunt_rejected.html", default_template_account_rejected)
end
account_password: STRING account_password: STRING
-- Account password template email message. -- Account password template email message.
do do
@@ -146,7 +177,7 @@ feature {NONE} -- Implementation: Template
local local
p: PATH p: PATH
do do
p := template_path ("account_activation.html") p := template_path (a_name)
if attached read_template_file (p) as l_content then if attached read_template_file (p) as l_content then
Result := l_content Result := l_content
else else
@@ -177,6 +208,36 @@ feature {NONE} -- Implementation
feature {NONE} -- Message email feature {NONE} -- Message email
default_template_account_evaluation: STRING = "[
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Account Evaluation</title>
<meta name="description" content="Account Evaluation">
<meta name="author" content="$sitename">
</head>
<body>
<h2> Account Evaluation </h2>
<p>The user $user ($email) wants to register to the site <a href="$host">$sitename</a></p>
<blockquote><p>This is his/her application.</p>
<p>$application</p>
</blockquote>
<p>To complete the registration, please click on the following link to activate the user account:<p>
<p><a href="$activation_url">$activation_url</a></p>
<p>To reject the registration, please click on the following link <p>
<p><a href="$rejection_url">$rejection_url</a></p>
</body>
</html>
]"
default_template_account_activation: STRING = "[ default_template_account_activation: STRING = "[
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
@@ -184,21 +245,53 @@ feature {NONE} -- Message email
<meta charset="utf-8"> <meta charset="utf-8">
<title>Activation</title> <title>Activation</title>
<meta name="description" content="Activation"> <meta name="description" content="Activation">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Thank you for registering at <a href="...">ROC CMS</a></p> <p>Thank you for applying to <a href="$host">$sitename</a> $user</p>
<p>To complete your registration, please click on the following link to activate your account:<p> <p>We will review your application and send you an email<p>
<p><a href="$link">$link</a></p>
<p>Thank you for joining us.</p> <p>Thank you for joining us.</p>
</body> </body>
</html> </html>
]" ]"
default_template_account_activation_confirmation: STRING = "[
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Activation</title>
<meta name="description" content="Activation Confirmation">
<meta name="author" content="$sitename">
</head>
<body>
<p>Your account has been confirmed <a href="$host">$sitename</a> $email</p>
<p>Thank you for joining us.</p>
</body>
</html>
]"
default_template_account_rejected: STRING = "[
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Application Rejected</title>
<meta name="description" content="Application Rejected">
<meta name="author" content="$sitename">
</head>
<body>
<p>You requested has been rejected, your application does not conform our rules <a href="$host">$sitename</a></p>
</body>
</html>
]"
default_template_account_re_activation: STRING = "[ default_template_account_re_activation: STRING = "[
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
@@ -206,11 +299,11 @@ feature {NONE} -- Message email
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Activation</title> <title>New Activation</title>
<meta name="description" content="New Activation token"> <meta name="description" content="New Activation token">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have requested a new activation token at <a href="...">ROC CMS</a></p> <p>You have requested a new activation token at <a href="$host">$sitename</a></p>
<p>To complete your registration, please click on the following link to activate your account:<p> <p>To complete your registration, please click on the following link to activate your account:<p>
@@ -229,11 +322,11 @@ feature {NONE} -- Message email
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Password</title> <title>New Password</title>
<meta name="description" content="New Password"> <meta name="description" content="New Password">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have required a new password at <a href="...">ROC CMS</a></p> <p>You have required a new password at <a href="$host">$sitename</a></p>
<p>To complete your request, please click on this link to generate a new password:<p> <p>To complete your request, please click on this link to generate a new password:<p>
@@ -250,11 +343,11 @@ feature {NONE} -- Message email
<meta charset="utf-8"> <meta charset="utf-8">
<title>Welcome</title> <title>Welcome</title>
<meta name="description" content="Welcome"> <meta name="description" content="Welcome">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Welcome to<a href="...">ROC CMS</a></p> <p>Welcome to<a href="...">$sitename</a></p>
<p>Thank you for joining us.</p> <p>Thank you for joining us.</p>
</body> </body>
</html> </html>

View File

@@ -7,6 +7,7 @@ class
CMS_AUTHENTICATION_MODULE CMS_AUTHENTICATION_MODULE
inherit inherit
CMS_MODULE CMS_MODULE
redefine redefine
setup_hooks, setup_hooks,
@@ -15,6 +16,8 @@ inherit
CMS_HOOK_AUTO_REGISTER CMS_HOOK_AUTO_REGISTER
CMS_HOOK_RESPONSE_ALTER
CMS_HOOK_VALUE_TABLE_ALTER CMS_HOOK_VALUE_TABLE_ALTER
CMS_HOOK_BLOCK CMS_HOOK_BLOCK
@@ -43,7 +46,6 @@ feature {NONE} -- Initialization
version := "1.0" version := "1.0"
description := "Authentication module" description := "Authentication module"
package := "authentication" package := "authentication"
create root_dir.make_current create root_dir.make_current
cache_duration := 0 cache_duration := 0
end end
@@ -57,6 +59,10 @@ feature -- Access
do do
Result := Precursor Result := Precursor
Result.force ("account register") Result.force ("account register")
Result.force ("account activate")
Result.force ("account reject")
Result.force ("account reactivate")
Result.force ("admin registration")
end end
feature -- Access: docs feature -- Access: docs
@@ -80,20 +86,29 @@ feature -- Router
-- <Precursor> -- <Precursor>
do do
configure_web (a_api, a_router) configure_web (a_api, a_router)
configure_web_admin (a_api, a_router)
end end
configure_web (a_api: CMS_API; a_router: WSF_ROUTER) configure_web (a_api: CMS_API; a_router: WSF_ROUTER)
do do
a_router.handle ("/account", create {WSF_URI_AGENT_HANDLER}.make (agent handle_account (a_api, ?, ?)), a_router.methods_head_get) a_router.handle ("/account", create {WSF_URI_AGENT_HANDLER}.make (agent handle_account(a_api, ?, ?)), a_router.methods_head_get)
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-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login(a_api, ?, ?)), a_router.methods_head_get)
a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_head_get) a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout(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) a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register(a_api, ?, ?)), a_router.methods_get_post)
a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation (a_api, ?, ?)), a_router.methods_head_get) a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation(a_api, ?, ?)), a_router.methods_head_get)
a_router.handle ("/account/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation (a_api, ?, ?)), a_router.methods_get_post) a_router.handle ("/account/reject/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_reject(a_api, ?, ?)), a_router.methods_head_get)
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/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation(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/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password(a_api, ?, ?)), a_router.methods_get_post)
a_router.handle ("/account/change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_change_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/post-change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_post_change_password (a_api, ?, ?)), a_router.methods_get) a_router.handle ("/account/change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_change_password(a_api, ?, ?)), a_router.methods_get_post)
a_router.handle ("/account/post-change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_post_change_password(a_api, ?, ?)), a_router.methods_get)
end
configure_web_admin (a_api: CMS_API; a_router: WSF_ROUTER)
-- Configure router mapping for admin web interface.
do
a_router.handle ("/admin/pending-registrations/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_admin_pending_registrations (?, ?, a_api)), a_router.methods_get)
end end
feature -- Hooks configuration feature -- Hooks configuration
@@ -104,6 +119,7 @@ feature -- Hooks configuration
auto_subscribe_to_hooks (a_hooks) auto_subscribe_to_hooks (a_hooks)
a_hooks.subscribe_to_block_hook (Current) a_hooks.subscribe_to_block_hook (Current)
a_hooks.subscribe_to_value_table_alter_hook (Current) a_hooks.subscribe_to_value_table_alter_hook (Current)
a_hooks.subscribe_to_menu_system_alter_hook (Current)
end end
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
@@ -119,7 +135,7 @@ feature -- Hooks configuration
lnk: CMS_LOCAL_LINK lnk: CMS_LOCAL_LINK
do do
if attached a_response.user as u then if attached a_response.user as u then
create lnk.make (u.name, "account" ) create lnk.make (u.name, "account")
lnk.set_weight (97) lnk.set_weight (97)
a_menu_system.primary_menu.extend (lnk) a_menu_system.primary_menu.extend (lnk)
create lnk.make ("Logout", "account/roc-logout") create lnk.make ("Logout", "account/roc-logout")
@@ -130,7 +146,11 @@ feature -- Hooks configuration
lnk.set_weight (98) lnk.set_weight (98)
a_menu_system.primary_menu.extend (lnk) a_menu_system.primary_menu.extend (lnk)
end end
-- Add the link to the taxonomy to the main menu
if a_response.has_permission ("admin registration") then
create lnk.make ("Registration", "admin/pending-registrations/")
a_menu_system.management_menu.extend (lnk)
end
end end
feature -- Handler feature -- Handler
@@ -140,7 +160,6 @@ feature -- Handler
r: CMS_RESPONSE r: CMS_RESPONSE
do do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if attached template_block ("account_info", r) as l_tpl_block then if attached template_block ("account_info", r) as l_tpl_block then
if attached r.user as l_user then if attached r.user as l_user then
r.set_value (api.user_api.user_roles (l_user), "roles") r.set_value (api.user_api.user_roles (l_user), "roles")
@@ -182,53 +201,68 @@ feature -- Handler
local local
r: CMS_RESPONSE r: CMS_RESPONSE
l_user_api: CMS_USER_API l_user_api: CMS_USER_API
u: CMS_USER u: CMS_TEMP_USER
l_exist: BOOLEAN l_exist: BOOLEAN
es: CMS_AUTHENTICATON_EMAIL_SERVICE es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_url: STRING l_url_activate: STRING
l_url_reject: STRING
l_token: STRING l_token: STRING
l_captcha_passed: BOOLEAN
do do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if r.has_permission ("account register") then if r.has_permission ("account register") then
if req.is_post_request_method then if req.is_post_request_method then
if if attached {WSF_STRING} req.form_parameter ("name") as l_name and then attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("email") as l_email and then attached {WSF_STRING} req.form_parameter ("personal_information") as l_personal_information then
attached {WSF_STRING} req.form_parameter ("name") as l_name and then
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
attached {WSF_STRING} req.form_parameter ("email") as l_email
then
l_user_api := api.user_api l_user_api := api.user_api
if attached l_user_api.user_by_name (l_name.value) or else attached l_user_api.temp_user_by_name (l_name.value) then
if attached l_user_api.user_by_name (l_name.value) then
-- Username already exist. -- Username already exist.
r.set_value ("User name already exists!", "error_name") r.set_value ("User name already exists!", "error_name")
l_exist := True l_exist := True
end end
if attached l_user_api.user_by_email (l_email.value) then if attached l_user_api.user_by_email (l_email.value) or else attached l_user_api.temp_user_by_email (l_email.value) then
-- Emails already exist. -- Emails already exist.
r.set_value ("An account is already associated with that email address!", "error_email") r.set_value ("An account is already associated with that email address!", "error_email")
l_exist := True l_exist := True
end end
if attached recaptcha_secret_key (api) as l_recaptcha_key then
if attached {WSF_STRING} req.form_parameter ("g-recaptcha-response") as l_recaptcha_response and then is_captcha_verified (l_recaptcha_key, l_recaptcha_response.value) then
l_captcha_passed := True
else
--| Bad or missing captcha
l_captcha_passed := False
end
else
--| reCaptcha is not setup, so no verification
l_captcha_passed := True
end
if not l_exist then if not l_exist then
-- New user
-- New temp user
create u.make (l_name.value) create u.make (l_name.value)
u.set_email (l_email.value) u.set_email (l_email.value)
u.set_password (l_password.value) u.set_password (l_password.value)
l_user_api.new_user (u) u.set_personal_information (l_personal_information.value)
l_user_api.new_temp_user (u)
-- Create activation token -- Create activation token
l_token := new_token l_token := new_token
l_user_api.new_activation (l_token, u.id) l_user_api.new_activation (l_token, u.id)
l_url := req.absolute_script_url ("/account/activate/" + l_token) l_url_activate := req.absolute_script_url ("/account/activate/" + l_token)
l_url_reject := req.absolute_script_url ("/account/reject/" + l_token)
-- Send Email -- Send Email to webmaster
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_register_email")
es.send_account_evaluation (u, l_personal_information.value, l_url_activate, l_url_reject, req.absolute_script_url (""))
-- Send Email to user
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_email") write_debug_log (generator + ".handle register: send_contact_email")
es.send_contact_email (l_email.value, l_url) es.send_contact_email (l_email.value, l_name.value, req.absolute_script_url (""))
else else
r.set_value (l_name.value, "name") r.set_value (l_name.value, "name")
r.set_value (l_email.value, "email") r.set_value (l_email.value, "email")
r.set_value (l_personal_information.value, "personal_information")
r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.set_status_code ({HTTP_CONSTANTS}.bad_request)
end end
end end
@@ -237,7 +271,6 @@ feature -- Handler
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.set_main_content ("You can also contact the webmaster to ask for an account.") r.set_main_content ("You can also contact the webmaster to ask for an account.")
end end
r.execute r.execute
end end
@@ -246,29 +279,84 @@ feature -- Handler
r: CMS_RESPONSE r: CMS_RESPONSE
l_user_api: CMS_USER_API l_user_api: CMS_USER_API
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
es: CMS_AUTHENTICATON_EMAIL_SERVICE
do do
l_user_api := api.user_api l_user_api := api.user_api
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if attached {WSF_STRING} req.path_parameter ("token") as l_token then if r.has_permission ("account activate") then
if attached {WSF_STRING} req.path_parameter ("token") as l_token then
if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_user then
if attached {CMS_USER} l_user_api.user_by_activation_token (l_token.value) as l_user then -- TODO copy the personal information
-- Valid user_id --! to CMS_USER_PROFILE and persist data
l_user.mark_active --! check also CMS_USER.data_items
l_user_api.update_user (l_user)
l_user_api.remove_activation (l_token.value) -- Delete temporal User
r.set_main_content ("<p> Your account <i>"+ l_user.name +"</i> has been activated</p>") l_user_api.delete_temp_user (l_user)
-- Valid user_id
l_user.set_id (0)
l_user.mark_active
l_user_api.new_user_from_temp_user (l_user)
l_user_api.remove_activation (l_token.value)
r.set_main_content ("<p> The account <i>" + l_user.name + "</i> has been activated</p>")
-- Send Email
if attached l_user.email as l_email then
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_activation_confirmation_email")
es.send_contact_activation_confirmation_email (l_email, "", req.absolute_script_url (""))
end
else
-- the token does not exist, or it was already used.
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
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 else
-- the token does not exist, or it was already used. create l_ir.make (req, res, api)
r.set_status_code ({HTTP_CONSTANTS}.bad_request) l_ir.execute
r.set_main_content ("<p>The token <i>" + l_token.value +"</i> is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "</p>")
end end
r.execute
else else
create l_ir.make (req, res, api) create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
l_ir.execute r.execute
end end
end end
handle_reject (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local
r: CMS_RESPONSE
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_user_api: CMS_USER_API
do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if r.has_permission ("account reject") then
if attached {WSF_STRING} req.path_parameter ("token") as l_token then
l_user_api := api.user_api
if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_user then
l_user_api.delete_temp_user (l_user)
r.set_main_content ("<p> The temporal account for <i>" + l_user.name + "</i> has been removed</p>")
-- Send Email
if attached l_user.email as l_email then
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_activation_reject_email")
es.send_contact_activation_reject_email (l_email, "", req.absolute_script_url (""))
end
else
-- the token does not exist, or it was already used.
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
r.set_main_content ("<p>The token <i>" + l_token.value + "</i> is not valid ")
end
r.execute
else
create l_ir.make (req, res, api)
l_ir.execute
end
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.execute
end
end
handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
@@ -276,37 +364,42 @@ feature -- Handler
es: CMS_AUTHENTICATON_EMAIL_SERVICE es: CMS_AUTHENTICATON_EMAIL_SERVICE
l_user_api: CMS_USER_API l_user_api: CMS_USER_API
l_token: STRING l_token: STRING
l_url: STRING l_url_activate: STRING
l_url_reject: STRING
do do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if req.is_post_request_method then if r.has_permission ("account reactivate") then
if if req.is_post_request_method then
attached {WSF_STRING} req.form_parameter ("email") as l_email if attached {WSF_STRING} req.form_parameter ("email") as l_email then
then l_user_api := api.user_api
l_user_api := api.user_api if attached {CMS_TEMP_USER} l_user_api.temp_user_by_email (l_email.value) as l_user then
if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then -- User exist create a new token and send a new email.
-- User exist create a new token and send a new email. if l_user.is_active then
if l_user.is_active then r.set_value ("The asociated user to the given email " + l_email.value + " , is already active", "is_active")
r.set_value ("The asociated user to the given email " + l_email.value + " , is already active", "is_active") r.set_status_code ({HTTP_CONSTANTS}.bad_request)
r.set_status_code ({HTTP_CONSTANTS}.bad_request) else
l_token := new_token
l_user_api.new_activation (l_token, l_user.id)
l_url_activate := req.absolute_script_url ("/account/activate/" + l_token)
l_url_reject := req.absolute_script_url ("/account/reject/" + l_token)
-- Send Email to webmaster
if attached l_user.personal_information as l_personal_information then
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_register_email")
es.send_account_evaluation (l_user, l_personal_information, l_url_activate, l_url_reject, req.absolute_script_url (""))
end
end
else else
l_token := new_token r.set_value ("The email does not exist or !", "error_email")
l_user_api.new_activation (l_token, l_user.id) r.set_value (l_email.value, "email")
l_url := req.absolute_script_url ("/account/activate/" + l_token) r.set_status_code ({HTTP_CONSTANTS}.bad_request)
-- 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_url)
end end
else
r.set_value ("The email does not exist or !", "error_email")
r.set_value (l_email.value, "email")
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
end end
end end
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
r.execute
end end
r.execute r.execute
end end
@@ -322,34 +415,32 @@ feature -- Handler
if req.is_post_request_method then if req.is_post_request_method then
l_user_api := api.user_api l_user_api := api.user_api
if attached {WSF_STRING} req.form_parameter ("email") as l_email then if attached {WSF_STRING} req.form_parameter ("email") as l_email then
if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then
-- User exist create a new token and send a new email. -- User exist create a new token and send a new email.
l_token := new_token l_token := new_token
l_user_api.new_password (l_token, l_user.id) l_user_api.new_password (l_token, l_user.id)
l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token) l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token)
-- Send Email -- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_password_email") write_debug_log (generator + ".handle register: send_contact_password_email")
es.send_contact_password_email (l_email.value, l_url) es.send_contact_password_email (l_email.value, l_url, req.absolute_script_url (""))
else else
r.set_value ("The email does not exist !", "error_email") r.set_value ("The email does not exist !", "error_email")
r.set_value (l_email.value, "email") r.set_value (l_email.value, "email")
r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.set_status_code ({HTTP_CONSTANTS}.bad_request)
end end
elseif attached {WSF_STRING} req.form_parameter ("username") as l_username then elseif attached {WSF_STRING} req.form_parameter ("username") as l_username then
if attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then if attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then attached l_user.email as l_email then
attached l_user.email as l_email -- User exist create a new token and send a new email.
then
-- User exist create a new token and send a new email.
l_token := new_token l_token := new_token
l_user_api.new_password (l_token, l_user.id) l_user_api.new_password (l_token, l_user.id)
l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token) l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token)
-- Send Email -- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle register: send_contact_password_email") write_debug_log (generator + ".handle register: send_contact_password_email")
es.send_contact_password_email (l_email, l_url) es.send_contact_password_email (l_email, l_url, req.absolute_script_url (""))
else else
r.set_value ("The username does not exist !", "error_username") r.set_value ("The username does not exist !", "error_username")
r.set_value (l_username.value, "username") r.set_value (l_username.value, "username")
@@ -360,7 +451,6 @@ feature -- Handler
r.execute r.execute
end end
handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
local local
r: CMS_RESPONSE r: CMS_RESPONSE
@@ -368,24 +458,18 @@ feature -- Handler
do do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
l_user_api := api.user_api l_user_api := api.user_api
if attached {WSF_STRING} req.query_parameter ("token") as l_token then if attached {WSF_STRING} req.query_parameter ("token") as l_token then
r.set_value (l_token.value, "token") r.set_value (l_token.value, "token")
if l_user_api.user_by_password_token (l_token.value) = Void then if l_user_api.user_by_password_token (l_token.value) = Void then
r.set_value ("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_value ("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) r.set_status_code ({HTTP_CONSTANTS}.bad_request)
end end
end end
if req.is_post_request_method then if req.is_post_request_method then
if attached {WSF_STRING} req.form_parameter ("token") as l_token and then attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password then
if -- Does the passwords match?
attached {WSF_STRING} req.form_parameter ("token") as l_token and then
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password
then
-- Does the passwords match?
if l_password.value.same_string (l_confirm_password.value) then if l_password.value.same_string (l_confirm_password.value) then
-- is the token valid? -- is the token valid?
if attached {CMS_USER} l_user_api.user_by_password_token (l_token.value) as l_user then if attached {CMS_USER} l_user_api.user_by_password_token (l_token.value) as l_user then
l_user.set_password (l_password.value) l_user.set_password (l_password.value)
l_user_api.update_user (l_user) l_user_api.update_user (l_user)
@@ -408,22 +492,17 @@ feature -- Handler
do do
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
l_user_api := api.user_api l_user_api := api.user_api
if req.is_post_request_method then if req.is_post_request_method then
if attached r.user as l_user then if attached r.user as l_user then
r.set_value (api.user_api.user_roles (l_user), "roles") r.set_value (api.user_api.user_roles (l_user), "roles")
if if attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password and then l_password.value.same_string (l_confirm_password.value) then
attached {WSF_STRING} req.form_parameter ("password") as l_password and then -- Does the passwords match?
attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password and then
l_password.value.same_string (l_confirm_password.value)
then
-- Does the passwords match?
l_user.set_password (l_password.value) l_user.set_password (l_password.value)
l_user_api.update_user (l_user) l_user_api.update_user (l_user)
r.set_redirection (req.absolute_script_url ("/account/post-change-password")) r.set_redirection (req.absolute_script_url ("/account/post-change-password"))
else else
if attached template_block ("account_info", r) as l_tpl_block then if attached template_block ("account_info", r) as l_tpl_block then
-- r.set_value (l_user, "user") -- r.set_value (l_user, "user")
r.set_value ("Passwords Don't Match", "error_password") r.set_value ("Passwords Don't Match", "error_password")
r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.set_status_code ({HTTP_CONSTANTS}.bad_request)
r.add_block (l_tpl_block, "content") r.add_block (l_tpl_block, "content")
@@ -445,11 +524,104 @@ feature -- Handler
r.execute r.execute
end end
handle_admin_pending_registrations (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
local
l_response: CMS_RESPONSE
s: STRING
u: CMS_TEMP_USER
l_page_helper: CMS_PAGINATION_GENERATOR
s_pager: STRING
l_count: INTEGER
l_user_api: CMS_USER_API
do
-- At the moment the template are hardcoded, but we can
-- get them from the configuration file and load them into
-- the setup class.
create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api)
if
l_response.has_permission ("admin registration")
then
l_user_api := api.user_api
l_count := l_user_api.temp_users_count
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
create s.make_empty
if l_count > 1 then
l_response.set_title ("Listing " + l_count.out + " Pending Registrations")
else
l_response.set_title ("Listing " + l_count.out + " Pending Registration")
end
create s_pager.make_empty
create l_page_helper.make ("admin/pending-registrations/?page={page}&size={size}", l_user_api.temp_users_count.as_natural_64, 25) -- FIXME: Make this default page size a global CMS settings
l_page_helper.get_setting_from_request (req)
if l_page_helper.has_upper_limit and then l_page_helper.pages_count > 1 then
l_page_helper.append_to_html (l_response, s_pager)
if l_page_helper.page_size > 25 then
s.append (s_pager)
end
end
if attached l_user_api.temp_recent_users (create {CMS_DATA_QUERY_PARAMETERS}.make (l_page_helper.current_page_offset, l_page_helper.page_size)) as lst then
s.append ("<ul class=%"cms-temp-users%">%N")
across
lst as ic
loop
u := ic.item
s.append ("<li class=%"cms_temp_user%">")
s.append ("User:" + u.name)
s.append ("<ul class=%"cms_temp_user_details%">")
if attached u.personal_information as l_information then
s.append ("<li class=%"cms_temp_user_detail_information%">")
s.append (l_information)
s.append ("</li>%N")
end
if attached u.email as l_email then
s.append ("<li class=%"cms_temp_user_detail_email%">")
s.append (l_email)
s.append ("</li>%N")
end
if attached l_user_api.token_by_temp_user_id (u.id) as l_token then
s.append ("<li>")
s.append ("<a href=%"")
s.append (req.absolute_script_url ("/account/activate/" + l_token))
s.append ("%">")
s.append (html_encoded ("Activate"))
s.append ("</a>")
s.append ("</li>%N")
s.append ("<li>")
s.append ("<a href=%"")
s.append (req.absolute_script_url ("/account/reject/" + l_token))
s.append ("%">")
s.append (html_encoded ("Reject"))
s.append ("</a>")
s.append ("</li>%N")
end
s.append ("</ul>%N")
s.append ("</li>%N")
end
s.append ("</ul>%N")
end
-- Again the pager at the bottom, if needed
s.append (s_pager)
l_response.set_main_content (s)
l_response.execute
else
l_response.execute
end
end
block_list: ITERABLE [like {CMS_BLOCK}.name] block_list: ITERABLE [like {CMS_BLOCK}.name]
local local
l_string: STRING l_string: STRING
do do
Result := <<"register", "reactivate", "new_password", "reset_password">> Result := <<"register", "reactivate", "new_password", "reset_password", "registration">>
debug ("roc") debug ("roc")
create l_string.make_empty create l_string.make_empty
across across
@@ -458,32 +630,22 @@ feature -- Handler
l_string.append (ic.item) l_string.append (ic.item)
l_string.append_character (' ') l_string.append_character (' ')
end end
write_debug_log (generator + ".block_list:" + l_string ) write_debug_log (generator + ".block_list:" + l_string)
end end
end end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
do do
if if a_block_id.is_case_insensitive_equal_general ("register") and then a_response.location.starts_with ("account/roc-register") then
a_block_id.is_case_insensitive_equal_general ("register") and then
a_response.location.starts_with ("account/roc-register")
then
get_block_view_register (a_block_id, a_response) get_block_view_register (a_block_id, a_response)
elseif elseif a_block_id.is_case_insensitive_equal_general ("reactivate") and then a_response.location.starts_with ("account/reactivate") then
a_block_id.is_case_insensitive_equal_general ("reactivate") and then
a_response.location.starts_with ("account/reactivate")
then
get_block_view_reactivate (a_block_id, a_response) get_block_view_reactivate (a_block_id, a_response)
elseif elseif a_block_id.is_case_insensitive_equal_general ("new_password") and then a_response.location.starts_with ("account/new-password") then
a_block_id.is_case_insensitive_equal_general ("new_password") and then
a_response.location.starts_with ("account/new-password")
then
get_block_view_new_password (a_block_id, a_response) get_block_view_new_password (a_block_id, a_response)
elseif elseif a_block_id.is_case_insensitive_equal_general ("reset_password") and then a_response.location.starts_with ("account/reset-password") then
a_block_id.is_case_insensitive_equal_general ("reset_password") and then
a_response.location.starts_with ("account/reset-password")
then
get_block_view_reset_password (a_block_id, a_response) get_block_view_reset_password (a_block_id, a_response)
elseif a_block_id.is_case_insensitive_equal_general ("registration") and then a_response.location.starts_with ("admin/pending-registrations") then
get_block_view_registration (a_block_id, a_response)
end end
end end
@@ -499,10 +661,13 @@ feature {NONE} -- Token Generation
create l_security create l_security
l_token := l_security.token l_token := l_security.token
create l_encode create l_encode
from until l_token.same_string (l_encode.encoded_string (l_token)) loop from
-- Loop ensure that we have a security token that does not contain characters that need encoding. until
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token l_token.same_string (l_encode.encoded_string (l_token))
-- but the user will need to use an unencoded token if activation has to be done manually. loop
-- Loop ensure that we have a security token that does not contain characters that need encoding.
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token
-- but the user will need to use an unencoded token if activation has to be done manually.
l_token := l_security.token l_token := l_security.token
end end
Result := l_token Result := l_token
@@ -517,7 +682,6 @@ feature {NONE} -- Helpers
do do
create p.make_from_string ("templates") create p.make_from_string ("templates")
p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl") p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl")
p := a_response.api.module_theme_resource_location (Current, p) p := a_response.api.module_theme_resource_location (Current, p)
if p /= Void then if p /= Void then
if attached p.entry as e then if attached p.entry as e then
@@ -530,32 +694,14 @@ feature {NONE} -- Helpers
feature {NONE} -- Block views feature {NONE} -- Block views
-- get_block_view_login (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
-- local
---- vals: CMS_VALUE_TABLE
-- do
-- if attached template_block (a_block_id, a_response) as l_tpl_block then
---- create vals.make (1)
---- -- add the variable to the block
---- value_table_alter (vals, a_response)
---- across
---- vals as ic
---- loop
---- l_tpl_block.set_value (ic.item, ic.key)
---- end
-- a_response.put_required_block (l_tpl_block, "content")
-- else
-- debug ("cms")
-- a_response.add_warning_message ("Error with block [" + a_block_id + "]")
-- end
-- end
-- end
get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
do do
if a_response.has_permission ("account register") then if a_response.has_permission ("account register") then
if a_response.request.is_get_request_method then if a_response.request.is_get_request_method then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
if attached recaptcha_site_key (a_response.api) as l_recaptcha_site_key then
l_tpl_block.set_value (l_recaptcha_site_key, "recaptcha_site_key")
end
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -565,10 +711,13 @@ feature {NONE} -- Block views
elseif a_response.request.is_post_request_method then elseif a_response.request.is_post_request_method then
if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
-- l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name") -- l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name")
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
-- l_tpl_block.set_value (a_response.values.item ("email"), "email") -- l_tpl_block.set_value (a_response.values.item ("email"), "email")
-- l_tpl_block.set_value (a_response.values.item ("name"), "name") -- l_tpl_block.set_value (a_response.values.item ("name"), "name")
if attached recaptcha_site_key (a_response.api) as l_recaptcha_site_key then
l_tpl_block.set_value (l_recaptcha_site_key, "recaptcha_site_key")
end
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -601,9 +750,9 @@ feature {NONE} -- Block views
elseif a_response.request.is_post_request_method then elseif a_response.request.is_post_request_method then
if a_response.values.has ("error_email") or else a_response.values.has ("is_active") then if a_response.values.has ("error_email") or else a_response.values.has ("is_active") then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
-- l_tpl_block.set_value (a_response.values.item ("email"), "email") -- l_tpl_block.set_value (a_response.values.item ("email"), "email")
-- l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active") -- l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active")
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -633,12 +782,12 @@ feature {NONE} -- Block views
end end
end end
elseif a_response.request.is_post_request_method then elseif a_response.request.is_post_request_method then
if a_response.values.has ("error_email") or else a_response.values.has ("error_username") then if a_response.values.has ("error_email") or else a_response.values.has ("error_username") then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
-- l_tpl_block.set_value (a_response.values.item ("email"), "email") -- l_tpl_block.set_value (a_response.values.item ("email"), "email")
-- l_tpl_block.set_value (a_response.values.item ("error_username"), "error_username") -- l_tpl_block.set_value (a_response.values.item ("error_username"), "error_username")
-- l_tpl_block.set_value (a_response.values.item ("username"), "username") -- l_tpl_block.set_value (a_response.values.item ("username"), "username")
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -661,8 +810,8 @@ feature {NONE} -- Block views
do do
if a_response.request.is_get_request_method then if a_response.request.is_get_request_method then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
-- l_tpl_block.set_value (a_response.values.item ("token"), "token") -- l_tpl_block.set_value (a_response.values.item ("token"), "token")
-- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") -- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -670,11 +819,11 @@ feature {NONE} -- Block views
end end
end end
elseif a_response.request.is_post_request_method then elseif a_response.request.is_post_request_method then
if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then
if attached template_block (a_block_id, a_response) as l_tpl_block then if attached template_block (a_block_id, a_response) as l_tpl_block then
-- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") -- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
-- l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password") -- l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password")
-- l_tpl_block.set_value (a_response.values.item ("token"), "token") -- l_tpl_block.set_value (a_response.values.item ("token"), "token")
a_response.add_block (l_tpl_block, "content") a_response.add_block (l_tpl_block, "content")
else else
debug ("cms") debug ("cms")
@@ -693,14 +842,75 @@ feature {NONE} -- Block views
end end
end end
get_block_view_registration (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
do
end
feature -- Recaptcha
recaptcha_secret_key (api: CMS_API): detachable READABLE_STRING_8
-- Get recaptcha security key.
local
utf: UTF_CONVERTER
do
if attached api.module_configuration (Current, Void) as cfg then
if attached cfg.text_item ("recaptcha.secret_key") as l_recaptcha_key and then not l_recaptcha_key.is_empty then
Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key)
end
end
end
recaptcha_site_key (api: CMS_API): detachable READABLE_STRING_8
-- Get recaptcha security key.
local
utf: UTF_CONVERTER
do
if attached api.module_configuration (Current, Void) as cfg then
if attached cfg.text_item ("recaptcha.site_key") as l_recaptcha_key and then not l_recaptcha_key.is_empty then
Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key)
end
end
end
feature -- Response Alter
response_alter (a_response: CMS_RESPONSE)
do
a_response.add_javascript_url ("https://www.google.com/recaptcha/api.js")
a_response.add_style (a_response.url ("/module/" + name + "/files/css/auth.css", Void), Void)
end
feature {NONE} -- Implementation
is_captcha_verified (a_secret, a_response: READABLE_STRING_8): BOOLEAN
local
api: RECAPTCHA_API
l_errors: STRING
do
write_debug_log (generator + ".is_captcha_verified with response: [" + a_response + "]")
create api.make (a_secret, a_response)
Result := api.verify
if not Result and then attached api.errors as l_api_errors then
create l_errors.make_empty
l_errors.append_character ('%N')
across
l_api_errors as ic
loop
l_errors.append (ic.item)
l_errors.append_character ('%N')
end
write_error_log (generator + ".is_captcha_verified api_errors [" + l_errors + "]")
end
end
note note
copyright: "Copyright (c) 1984-2013, Eiffel Software and others" copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA 5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869 Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com Website http://www.eiffel.com
Customer support http://support.eiffel.com Customer support http://support.eiffel.com
]" ]"
end end

View File

@@ -34,52 +34,112 @@ feature -- Access
feature -- Basic Operations feature -- Basic Operations
send_contact_email (a_to, a_content: READABLE_STRING_8) send_account_evaluation (a_user: CMS_USER; a_application, a_url_activate, a_url_reject, a_host: READABLE_STRING_8)
-- Send successful contact message `a_token' to `a_to'. -- Send new user register to webmaster to confirm or reject itt.
local
l_message: STRING
do
create l_message.make_from_string (parameters.account_evaluation)
l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$user", a_user.name)
if attached a_user.email as l_email then
l_message.replace_substring_all ("$email", l_email)
else
l_message.replace_substring_all ("$email", "unknown email")
end
l_message.replace_substring_all ("$application", a_application)
l_message.replace_substring_all ("$activation_url", a_url_activate)
l_message.replace_substring_all ("$rejection_url", a_url_reject)
send_message (contact_email, contact_email, parameters.contact_subject_account_evaluation, l_message)
end
send_contact_email (a_to, a_user, a_host: READABLE_STRING_8)
-- Send successful contact message to `a_to'.
require require
attached_to: a_to /= Void attached_to: a_to /= Void
local local
l_message: STRING l_message: STRING
do do
create l_message.make_from_string (parameters.account_activation) create l_message.make_from_string (parameters.account_activation)
l_message.replace_substring_all ("$link", a_content) l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$user", a_user)
send_message (contact_email, a_to, parameters.contact_subject_register, l_message) send_message (contact_email, a_to, parameters.contact_subject_register, l_message)
end end
send_contact_activation_email (a_to, a_content: READABLE_STRING_8) send_contact_activation_email (a_to, a_content, a_host: READABLE_STRING_8)
-- Send successful contact message `a_token' to `a_to'. -- Send successful contact activation message to `a_to'.
require require
attached_to: a_to /= Void attached_to: a_to /= Void
local local
l_message: STRING l_message: STRING
do do
create l_message.make_from_string (parameters.account_re_activation) create l_message.make_from_string (parameters.account_re_activation)
l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$link", a_content) l_message.replace_substring_all ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_activate, l_message) send_message (contact_email, a_to, parameters.contact_subject_activate, l_message)
end end
send_contact_password_email (a_to, a_content: READABLE_STRING_8) send_contact_activation_confirmation_email (a_to, a_content, a_host: READABLE_STRING_8)
-- Send successful contact message `a_token' to `a_to'. -- Send successful message activation to a_to.
require
attached_to: a_to /= Void
local
l_message: STRING
do
create l_message.make_from_string (parameters.account_activation_confirmation)
l_message.replace_substring_all ("$hot", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$email", a_content)
send_message (contact_email, a_to, parameters.contact_subject_activated, l_message)
end
send_contact_activation_reject_email (a_to, a_content, a_host: READABLE_STRING_8)
-- Send successful contact activation reject message to `a_to'.
require
attached_to: a_to /= Void
local
l_message: STRING
do
create l_message.make_from_string (parameters.account_rejected)
l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_rejected, l_message)
end
send_contact_password_email (a_to, a_content, a_host: READABLE_STRING_8)
-- Send successful new account password message to `a_to'.
require require
attached_to: a_to /= Void attached_to: a_to /= Void
local local
l_message: STRING l_message: STRING
do do
create l_message.make_from_string (parameters.account_password) create l_message.make_from_string (parameters.account_password)
l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitename", parameters.site_name)
l_message.replace_substring_all ("$link", a_content) l_message.replace_substring_all ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_password, l_message) send_message (contact_email, a_to, parameters.contact_subject_password, l_message)
end end
send_contact_welcome_email (a_to, a_content: READABLE_STRING_8) send_contact_welcome_email (a_to, a_content, a_host: READABLE_STRING_8)
-- Send successful contact message `a_token' to `a_to'. -- Send successful welcome message to `a_to'.
require require
attached_to: a_to /= Void attached_to: a_to /= Void
local local
l_message: STRING l_message: STRING
do do
create l_message.make_from_string (parameters.account_welcome) create l_message.make_from_string (parameters.account_welcome)
l_message.replace_substring_all ("$host", a_host)
l_message.replace_substring_all ("$sitenme", parameters.site_name)
l_message.replace_substring_all ("$link", a_content) l_message.replace_substring_all ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message) send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message)
end end

View File

@@ -0,0 +1,8 @@
{
"email": "webmaster@eiffel.org",
"subject": "Thank you for contacting us",
"recaptcha": {
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
"secret_key":"6Lex9RMTAAAAAAkBczvX5DUiyg_xoM_EthVVgRRx"
}
}

View File

@@ -0,0 +1,22 @@
ul.cms-temp-users {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_information::before {
content: "[personal information] "; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_email::before {
content: "[email] "; }
/*# sourceMappingURL=auth.css.map */

View File

@@ -0,0 +1,22 @@
ul.cms-temp-users {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li {
border-top: dotted 1px #ccc; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li:first-child {
border-top: none; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_information::before {
content: "[personal information] "; }
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li.cms_temp_user_detail_email::before {
content: "[email] "; }
/*# sourceMappingURL=auth.css.map */

View File

@@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "AAAA,iBAAkB;EAEjB,eAAe,EAAE,IAAI;EACrB,OAAO,EAAE,eAAe;EACxB,MAAM,EAAE,cAAc;EAEtB,oBAAE;IACD,UAAU,EAAE,eAAe;IAC3B,gCAAc;MACb,UAAU,EAAE,IAAI;EAMjB,2DAAyB;IACxB,eAAe,EAAE,IAAI;IACrB,OAAO,EAAE,eAAe;IACxB,MAAM,EAAE,cAAc;IAEtB,8DAAE;MACD,UAAU,EAAE,eAAe;MAC3B,0EAAc;QACb,UAAU,EAAE,IAAI;IAGlB,uGAA2C;MAC1C,OAAO,EAAE,yBAAyB;IAEnC,iGAAqC;MACpC,OAAO,EAAE,UAAU",
"sources": ["auth.scss"],
"names": [],
"file": "auth.css"
}

View File

@@ -0,0 +1,37 @@
ul.cms-temp-users {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc;
li{
border-top: dotted 1px #ccc;
&:first-child {
border-top: none;
}
}
li.cms_temp_user {
ul.cms_temp_user_details {
list-style-type: none;
padding: 3px 3px 3px 3px;
border: solid 1px #ccc;
li{
border-top: dotted 1px #ccc;
&:first-child {
border-top: none;
}
}
li.cms_temp_user_detail_information::before{
content: "[personal information] "
}
li.cms_temp_user_detail_email::before{
content: "[email] "
}
}
}
}

View File

@@ -1,18 +1,14 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Activation</title> <title>Activation</title>
<meta name="description" content="Activation"> <meta name="description" content="Activation">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Thank you for registering at <a href="$host">ROC CMS</a></p> <p>Thank you for applying to <a href="$host">$sitename</a> $user</p>
<p>We will review your application and send you a resolution<p>
<p>To complete your registration, please click on this link to activate your account:<p>
<p><a href="$link">$link</a></p>
<p>Thank you for joining us.</p>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Activation Confirmation</title>
<meta name="description" content="Activation Confirmation">
<meta name="author" content="$sitename">
</head>
<body>
<p>Your account has been confirmed <a href="$host">$sitename</a> $email</p>
<p>Thank you for joining us.</p>
</body>
</html>

View File

@@ -4,13 +4,13 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Password</title> <title>New Password</title>
<meta name="description" content="New Password"> <meta name="description" content="New Password">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have required a new password at <a href="$host">ROC CMS</a></p> <p>You have required a new password at <a href="$host">$sitename</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> <p><a href="$link">$link</a></p>
</body> </body>

View File

@@ -4,11 +4,11 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>New Activation</title> <title>New Activation</title>
<meta name="description" content="New Activation token"> <meta name="description" content="New Activation token">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>You have request a new activation token at <a href="$host">ROC CMS</a></p> <p>You have request a new activation token at <a href="$host">$sitename</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 this link to activate your account:<p>

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Application Rejected</title>
<meta name="description" content="Application Rejected">
<meta name="author" content="$sitename">
</head>
<body>
<p>You requested has been rejected, your application does not conform our rules <a href="$host">$sitename</a></p>
</body>
</html>

View File

@@ -4,10 +4,10 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Welcome</title> <title>Welcome</title>
<meta name="description" content="Welcome"> <meta name="description" content="Welcome">
<meta name="author" content="ROC CMS"> <meta name="author" content="$sitename">
</head> </head>
<body> <body>
<p>Welcome to<a href="$host">ROC CMS</a></p> <p>Welcome to <a href="$host">$sitename</a></p>
<p>Thank you for joining us.</p> <p>Thank you for joining us.</p>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,26 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Account Evaluation</title>
<meta name="description" content="Account Evaluation">
<meta name="author" content="$sitename">
</head>
<body>
<h2> Account Evaluation </h2>
<p>The user $user ($email) wants to register to the site <a href="$host">$sitename</a></p>
<blockquote><p>User application:</p>
<p>$application</p>
</blockquote>
<p>To complete the registration, please click on the following link to activate the user account:<p>
<p><a href="$activation_url">$activation_url</a></p>
<p>To reject the registration, please click on the following link <p>
<p><a href="$rejection_url<">$rejection_url</a></p>
</body>
</html>

View File

@@ -0,0 +1,13 @@
CREATE TABLE `auth_temp_users` (
`uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
`name` VARCHAR(100) NOT NULL,
`password` VARCHAR(100) NOT NULL,
`salt` VARCHAR(100) NOT NULL,
`email` VARCHAR(250) NOT NULL,
`application` TEXT NOT NULL,
CONSTRAINT `name`
UNIQUE(`name`)
);

View File

@@ -1,3 +1,3 @@
<div> <div>
<p>We have send you a new activation code, check your email to activate your account.</p> <p>Thanks for your application, we will review it to activate your account.</p>
</div> </div>

View File

@@ -1,3 +1,3 @@
<div> <div>
<p>Thanks for register, check your email to activate your account.</p> <p>Thanks for your application, we will review it to activate your account.</p>
</div> </div>

View File

@@ -1,7 +1,7 @@
<div> <div>
<form action="{$site_url/}account/roc-register" method="post"> <form action="{$site_url/}account/roc-register" method="post">
<fieldset> <fieldset>
<legend>Register Form</legend> <legend>Registration</legend>
<div> <div>
<input type="text" id="name" name="name" value="{$name/}" required autofocus /> <input type="text" id="name" name="name" value="{$name/}" required autofocus />
<label for="name">Name</label> <label for="name">Name</label>
@@ -20,8 +20,19 @@
<span><i>{$error_email/}</i></span> <br> <span><i>{$error_email/}</i></span> <br>
{/if} {/if}
</div> </div>
<div>
<textarea rows="4" cols="50" name="personal_information" id="personal_information" required>
{$personal_information/}
</textarea>
<label for="personal_information">Tell us why you want to register an account</label>
{if isset="$error_application"}
<span><i>{$error_application/}</i></span> <br>
{/if}
</div>
{unless isempty="$recaptcha_site_key"}
<div class="g-recaptcha" data-sitekey="{$recaptcha_site_key/}"></div>
<br/>
{/unless}
<button type="submit">Register</button> <button type="submit">Register</button>
</fieldset> </fieldset>
</form> </form>

View File

@@ -493,7 +493,7 @@ feature -- OAuth2 Login with Provider
-- Send Email -- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle_callback_oauth: send_contact_welcome_email") write_debug_log (generator + ".handle_callback_oauth: send_contact_welcome_email")
es.send_contact_welcome_email (l_email, "") es.send_contact_welcome_email (l_email, "", req.absolute_script_url (""))
end end
end end
r.set_redirection (r.front_page_url) r.set_redirection (r.front_page_url)

View File

@@ -443,7 +443,7 @@ feature -- Openid Login
-- Send Email -- Send Email
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
write_debug_log (generator + ".handle_callback_openid: send_contact_welcome_email") write_debug_log (generator + ".handle_callback_openid: send_contact_welcome_email")
es.send_contact_welcome_email (l_email, "") es.send_contact_welcome_email (l_email, "", req.absolute_script_url (""))
end end
end end
r.set_redirection (r.front_page_url) r.set_redirection (r.front_page_url)

View File

@@ -216,11 +216,6 @@ feature -- Change: User activation
deferred deferred
end end
remove_activation (a_token: READABLE_STRING_32)
-- <Precursor>.
deferred
end
feature -- Change: User password recovery feature -- Change: User password recovery
save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64) save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
@@ -233,7 +228,87 @@ feature -- Change: User password recovery
deferred deferred
end end
feature -- Access: Temp Users
temp_users_count: INTEGER
-- Number of pending users
--! to be accepted or rejected
deferred
end
temp_user_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
-- Retrieve a temporal user by id `a_uid' for the consumer `a_consumer', if aby.
deferred
end
temp_user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
-- User with name `a_name', if any.
require
a_name /= Void and then not a_name.is_empty
deferred
ensure
same_name: Result /= Void implies a_name ~ Result.name
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
temp_user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
-- User with name `a_email', if any.
deferred
ensure
same_email: Result /= Void implies a_email ~ Result.email
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User with activation token `a_token', if any.
deferred
ensure
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
end
temp_recent_users (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_TEMP_USER]
-- List of recent `a_count' temporal users with an offset of `lower'.
deferred
end
token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING
-- Retrieve activation token for user identified with id `a_id', if any.
deferred
end
feature -- New Temp User
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
-- new user from temporal user `a_user'
require
no_id: not a_user.has_id
deferred
end
remove_activation (a_token: READABLE_STRING_32)
-- Remove activation by token `a_token'.
deferred
end
new_temp_user (a_user: CMS_TEMP_USER)
-- New temp user `a_user'.
require
no_id: not a_user.has_id
deferred
end
delete_temp_user (a_user: CMS_TEMP_USER)
-- Delete user `a_user'.
require
has_id: a_user.has_id
deferred
end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -131,10 +131,6 @@ feature -- Change: User activation
do do
end end
remove_activation (a_token: READABLE_STRING_32)
-- <Precursor>.
do
end
feature -- Change: User password recovery feature -- Change: User password recovery
@@ -148,7 +144,67 @@ feature -- Change: User password recovery
do do
end end
feature -- Access: Users
temp_users_count: INTEGER
-- <Precursor>
do
end
temp_user_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_GENERAL): detachable CMS_USER
-- <Precursor>
do
end
temp_user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
-- <Precursor>
do
end
temp_user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
-- <Precursor>
do
end
temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- <Precursor>
do
end
temp_recent_users (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_TEMP_USER]
-- List of recent `a_count' temporal users with an offset of `lower'.
do
create {ARRAYED_LIST[CMS_TEMP_USER]} Result.make (0)
end
token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING
-- <Precursor>
do
end
feature -- Temp Users
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
-- <Precursor>
do
end
remove_activation (a_token: READABLE_STRING_32)
-- <Precursor>.
do
end
new_temp_user (a_user: CMS_TEMP_USER)
-- <Precursor>
do
end
delete_temp_user (a_user: CMS_TEMP_USER)
-- <Precursor>
do
end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -196,6 +196,7 @@ feature -- Access: user
end end
sql_finalize sql_finalize
end end
feature -- Change: user feature -- Change: user
new_user (a_user: CMS_USER) new_user (a_user: CMS_USER)
@@ -755,21 +756,6 @@ feature -- Change: User activation
sql_finalize sql_finalize
end end
remove_activation (a_token: READABLE_STRING_32)
-- <Precursor>.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
sql_begin_transaction
write_information_log (generator + ".remove_activation")
create l_parameters.make (1)
l_parameters.put (a_token, "token")
sql_modify (sql_remove_activation, l_parameters)
sql_commit_transaction
sql_finalize
end
feature -- Change: User password recovery feature -- Change: User password recovery
save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64) save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
@@ -866,19 +852,6 @@ feature {NONE} -- Implementation: User
end end
end end
last_inserted_user_id: INTEGER_64
-- Last insert user id.
do
error_handler.reset
write_information_log (generator + ".last_inserted_user_id")
sql_query (Sql_last_insert_user_id, Void)
if not sql_after then
Result := sql_read_integer_64 (1)
sql_forth
check one_row: sql_after end
end
sql_finalize
end
feature {NONE} -- Implementation: User role feature {NONE} -- Implementation: User role
@@ -909,8 +882,6 @@ feature {NONE} -- Sql Queries: USER
Select_users_count: STRING = "SELECT count(*) FROM users;" Select_users_count: STRING = "SELECT count(*) FROM users;"
-- Number of users. -- Number of users.
Sql_last_insert_user_id: STRING = "SELECT MAX(uid) FROM users;"
Select_users: STRING = "SELECT * FROM users;" Select_users: STRING = "SELECT * FROM users;"
-- List of users. -- List of users.
@@ -920,7 +891,7 @@ feature {NONE} -- Sql Queries: USER
Select_user_by_name: STRING = "SELECT * FROM users WHERE name =:name;" Select_user_by_name: STRING = "SELECT * FROM users WHERE name =:name;"
-- Retrieve user by name if exists. -- Retrieve user by name if exists.
Sql_select_recent_users: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM users ORDER BY uid DESC, created DESC LIMIT :rows OFFSET :offset ;" Sql_select_recent_users: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM users ORDER BY uid DESC, created DESC LIMIT :rows OFFSET :offset;"
-- Retrieve recent users -- Retrieve recent users
Select_user_by_email: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM users WHERE email =:email;" Select_user_by_email: STRING = "SELECT uid, name, password, salt, email, status, created, signed FROM users WHERE email =:email;"
@@ -941,6 +912,8 @@ feature {NONE} -- Sql Queries: USER ROLE
sql_last_insert_user_role_id: STRING = "SELECT MAX(rid) FROM roles;" sql_last_insert_user_role_id: STRING = "SELECT MAX(rid) FROM roles;"
sql_last_insert_user_id: STRING = "SELECT MAX(uid) FROM users;"
select_user_roles: STRING = "SELECT rid, name FROM roles;" select_user_roles: STRING = "SELECT rid, name FROM roles;"
-- List of user roles. -- List of user roles.
@@ -1009,7 +982,367 @@ feature {NONE} -- User Password Recovery
Select_user_by_password_token: STRING = "SELECT u.* FROM users as u JOIN users_password_recovery as ua ON ua.uid = u.uid and ua.token = :token;" Select_user_by_password_token: STRING = "SELECT u.* FROM users as u JOIN users_password_recovery as ua ON ua.uid = u.uid and ua.token = :token;"
-- Retrieve user by password token if exist. -- Retrieve user by password token if exist.
feature -- Acess: Temp users
temp_users_count: INTEGER
-- Number of items users.
do
error_handler.reset
write_information_log (generator + ".temp_users_count")
sql_query (select_temp_users_count, Void)
if not has_error and then not sql_after then
Result := sql_read_integer_64 (1).to_integer_32
sql_forth
check one_row: sql_after end
end
sql_finalize
end
temp_user_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 + ".temp_user_by_id")
create l_parameters.make (1)
l_parameters.put (a_uid, "uid")
create l_string.make_from_string (select_user_auth_temp_by_id)
sql_query (l_string, l_parameters)
if not has_error and not sql_after then
Result := fetch_temp_user
sql_forth
if not sql_after then
check no_more_than_one: False end
Result := Void
end
end
sql_finalize
end
temp_user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
-- User for the given name `a_name', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
write_information_log (generator + ".temp_user_by_name")
create l_parameters.make (1)
l_parameters.put (a_name, "name")
sql_query (select_temp_user_by_name, l_parameters)
if not sql_after then
Result := fetch_temp_user
sql_forth
check one_row: sql_after end
end
sql_finalize
end
temp_user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
-- User for the given email `a_email', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
write_information_log (generator + ".temp_user_by_name")
create l_parameters.make (1)
l_parameters.put (a_email, "email")
sql_query (select_temp_user_by_email, l_parameters)
if not sql_after then
Result := fetch_temp_user
sql_forth
check one_row: sql_after end
end
sql_finalize
end
temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User for the given activation token `a_token', if any.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
write_information_log (generator + ".temp_user_by_activation_token")
create l_parameters.make (1)
l_parameters.put (a_token, "token")
sql_query (select_temp_user_by_activation_token, l_parameters)
if not sql_after then
Result := fetch_temp_user
sql_forth
check one_row: sql_after end
end
sql_finalize
end
temp_recent_users (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_TEMP_USER]
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
create {ARRAYED_LIST [CMS_TEMP_USER]} Result.make (0)
error_handler.reset
write_information_log (generator + ".temp_recent_users")
from
create l_parameters.make (2)
l_parameters.put (a_count, "rows")
l_parameters.put (a_lower, "offset")
sql_query (sql_select_temp_recent_users, l_parameters)
sql_start
until
sql_after
loop
if attached fetch_temp_user as l_user then
Result.force (l_user)
end
sql_forth
end
sql_finalize
end
token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING
-- Number of items users.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
write_information_log (generator + ".token_by_temp_user_id")
create l_parameters.make (1)
l_parameters.put (a_id, "uid")
sql_query (select_token_activation_by_user_id, l_parameters)
if not has_error and then not sql_after then
Result := sql_read_string (1)
sql_forth
check one_row: sql_after end
end
sql_finalize
end
feature {NONE} -- Implementation: User
fetch_temp_user: detachable CMS_TEMP_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
Result.set_hashed_password (l_password)
end
if attached sql_read_string (4) as l_salt then
Result.set_salt (l_salt)
end
if attached sql_read_string (5) as l_email then
Result.set_email (l_email)
end
if attached sql_read_string (6) as l_application then
Result.set_personal_information (l_application)
end
else
check expected_valid_user: False end
end
end
feature -- New Temp User
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
-- <Precursor>
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
if
attached a_user.hashed_password as l_password_hash and then
attached a_user.email as l_email and then
attached a_user.salt as l_password_salt
then
sql_begin_transaction
write_information_log (generator + ".new_user_from_temporal_user")
create l_parameters.make (4)
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (create {DATE_TIME}.make_now_utc, "created")
l_parameters.put (a_user.status, "status")
sql_insert (sql_insert_user, l_parameters)
if not error_handler.has_error then
a_user.set_id (last_inserted_user_id)
end
if not error_handler.has_error then
sql_commit_transaction
else
sql_rollback_transaction
end
sql_finalize
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
new_temp_user (a_user: CMS_TEMP_USER)
-- Add a new temp_user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
l_password_salt, l_password_hash: STRING
l_security: SECURITY_PROVIDER
do
error_handler.reset
if
attached a_user.password as l_password and then
attached a_user.email as l_email and then
attached a_user.personal_information as l_personal_information
then
create l_security
l_password_salt := l_security.salt
l_password_hash := l_security.password_hash (l_password, l_password_salt)
write_information_log (generator + ".new_temp_user")
create l_parameters.make (4)
l_parameters.put (a_user.name, "name")
l_parameters.put (l_password_hash, "password")
l_parameters.put (l_password_salt, "salt")
l_parameters.put (l_email, "email")
l_parameters.put (l_personal_information, "application")
sql_begin_transaction
sql_insert (sql_insert_temp_user, l_parameters)
if not error_handler.has_error then
a_user.set_id (last_inserted_temp_user_id)
sql_commit_transaction
else
sql_rollback_transaction
end
sql_finalize
else
-- set error
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
end
end
feature -- Remove Activation
remove_activation (a_token: READABLE_STRING_32)
-- <Precursor>.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
sql_begin_transaction
write_information_log (generator + ".remove_activation")
create l_parameters.make (1)
l_parameters.put (a_token, "token")
sql_modify (sql_remove_activation, l_parameters)
sql_commit_transaction
sql_finalize
end
delete_temp_user (a_user: CMS_TEMP_USER)
-- Delete user `a_user'.
local
l_parameters: STRING_TABLE [detachable ANY]
do
error_handler.reset
sql_begin_transaction
write_information_log (generator + ".delete_temp_user")
create l_parameters.make (1)
l_parameters.put (a_user.id, "uid")
sql_modify (sql_delete_temp_user, l_parameters)
sql_commit_transaction
sql_finalize
end
feature {NONE} -- Implementation
last_inserted_temp_user_id: INTEGER_64
-- Last insert user id.
do
error_handler.reset
write_information_log (generator + ".last_inserted_temp_user_id")
sql_query (sql_last_insert_temp_user_id, Void)
if not sql_after then
Result := sql_read_integer_64 (1)
sql_forth
check one_row: sql_after end
end
sql_finalize
end
last_inserted_user_id: INTEGER_64
-- Last insert user id.
do
error_handler.reset
write_information_log (generator + ".last_inserted_user_id")
sql_query (sql_last_insert_user_id, Void)
if not sql_after then
Result := sql_read_integer_64 (1)
sql_forth
check one_row: sql_after end
end
sql_finalize
end
feature {NONE} -- SQL select
sql_last_insert_temp_user_id: STRING = "SELECT MAX(uid) FROM auth_temp_users;"
Select_user_auth_temp_by_id: STRING = "SELECT uid, name, password, salt, email, application FROM auth_temp_users as u where uid=:uid;"
sql_insert_temp_user: STRING = "INSERT INTO auth_temp_users (name, password, salt, email, application) VALUES (:name, :password, :salt, :email, :application);"
-- SQL Insert to add a new user.
select_temp_user_by_name: STRING = "SELECT uid, name, password, salt, email, application FROM auth_temp_users WHERE name =:name;"
-- Retrieve user by name if exists.
select_temp_user_by_email: STRING = "SELECT uid, name, password, salt, email, application FROM auth_temp_users WHERE email =:email;"
-- Retrieve user by email if exists.
select_temp_user_by_activation_token: STRING = "SELECT u.uid, u.name, u.password, u.salt, u.email, u.application FROM auth_temp_users as u JOIN users_activations as ua ON ua.uid = u.uid and ua.token = :token;"
-- Retrieve user by activation token if exist.
sql_delete_temp_user: STRING = "DELETE FROM auth_temp_users WHERE uid=:uid;"
select_temp_users_count: STRING = "SELECT count(*) FROM auth_temp_users;"
-- Number of temporal users.
sql_select_temp_recent_users: STRING = "SELECT uid, name, password, salt, email, application FROM auth_temp_users ORDER BY uid DESC LIMIT :rows OFFSET :offset ;"
-- Retrieve recent users
select_token_activation_by_user_id: STRING = "SELECT token FROM users_activations WHERE uid = :uid;"
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end

View File

@@ -251,7 +251,6 @@ feature -- Change User
do do
reset_error reset_error
if if
attached a_user.password as l_password and then
attached a_user.email as l_email attached a_user.email as l_email
then then
storage.new_user (a_user) storage.new_user (a_user)
@@ -289,12 +288,6 @@ feature -- User Activation
storage.save_activation (a_token, a_id) storage.save_activation (a_token, a_id)
end end
remove_activation (a_token: READABLE_STRING_32)
-- Remove activation token `a_token', from the storage.
do
storage.remove_activation (a_token)
end
feature -- User Password Recovery feature -- User Password Recovery
new_password (a_token: READABLE_STRING_32; a_id: INTEGER_64) new_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
@@ -320,7 +313,101 @@ feature -- User status
Trashed: INTEGER = -1 Trashed: INTEGER = -1
-- The user is trashed (soft delete), ready to be deleted/destroyed from storage. -- The user is trashed (soft delete), ready to be deleted/destroyed from storage.
feature -- Access - Temp User
temp_users_count: INTEGER
-- Number of pending users.
--! to be accepted or rehected
do
Result := storage.temp_users_count
end
temp_user_by_name (a_username: READABLE_STRING_GENERAL): detachable CMS_USER
-- User by name `a_user_name', if any.
do
Result := storage.temp_user_by_name (a_username.as_string_32)
end
temp_user_by_email (a_email: READABLE_STRING_8): detachable CMS_USER
-- User by email `a_email', if any.
do
Result := storage.temp_user_by_email (a_email)
end
temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User by activation token `a_token'.
do
Result := storage.temp_user_by_activation_token (a_token)
end
temp_recent_users (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_TEMP_USER]
-- List of the `a_rows' most recent users starting from `a_offset'.
do
Result := storage.temp_recent_users (params.offset.to_integer_32, params.size.to_integer_32)
end
token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING
do
Result := storage.token_by_temp_user_id (a_id)
end
feature -- Change Temp User
new_user_from_temp_user (a_user: CMS_TEMP_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
has_hashed_password: a_user.hashed_password /= Void
has_sal: a_user.salt /= Void
do
reset_error
if
attached a_user.hashed_password as l_password and then
attached a_user.salt as l_salt and then
attached a_user.email as l_email
then
storage.new_user_from_temporal_user (a_user)
error_handler.append (storage.error_handler)
else
error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!")
end
end
new_temp_user (a_user: CMS_TEMP_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
no_hashed_password: a_user.hashed_password = Void
do
reset_error
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.new_temp_user (a_user)
error_handler.append (storage.error_handler)
else
error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!")
end
end
remove_activation (a_token: READABLE_STRING_32)
-- Remove activation token `a_token', from the storage.
do
storage.remove_activation (a_token)
end
delete_temp_user (a_user: CMS_TEMP_USER)
-- Delete user `a_user'.
require
has_id: a_user.has_id
do
reset_error
storage.delete_temp_user (a_user)
error_handler.append (storage.error_handler)
end
note note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end end