Integrated new registration workflow.

Added optional "mailer.subject_prefix" configuration item.
Added CMS_SETUP.utf_8_site_name for convenience.
Fixed a few potential unicode issues.
Fixed various typos.
This commit is contained in:
2016-01-15 17:46:56 +01:00
55 changed files with 2030 additions and 364 deletions

View File

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

View File

@@ -0,0 +1,45 @@
note
description: "User for temporary account."
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 (a_personal_information: like personal_information)
-- Assign `personal_information' with `a_personal_information'.
do
personal_information := a_personal_information
ensure
personal_information_assigned: personal_information = a_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
note
copyright: "2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -62,7 +62,7 @@ feature -- Access
hashed_password: detachable READABLE_STRING_8
-- Hashed user password.
email: detachable READABLE_STRING_32
email: detachable READABLE_STRING_8
-- User email.
profile: detachable CMS_USER_PROFILE
@@ -80,7 +80,6 @@ feature -- Access
-- active
-- trashed
feature -- Access: helper
utf_8_name: STRING_8
@@ -302,6 +301,6 @@ invariant
id_or_name_set: id > 0 or else not name.is_whitespace
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)"
end

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>