Compare commits
9 Commits
roc_regist
...
es_rev9839
| Author | SHA1 | Date | |
|---|---|---|---|
| fd5e396b72 | |||
| 5bd28326c2 | |||
| eef2a52f48 | |||
| a013efd6f7 | |||
| f6885ff581 | |||
| a179ee3239 | |||
| ed0d9c8d07 | |||
| 67fbee737d | |||
| 56b9355f3c |
@@ -1,16 +1,17 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
|
||||
<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="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
|
||||
<description>Example/demo for Eiffel ROC CMS library</description>
|
||||
<target name="common" abstract="true">
|
||||
<root class="DEMO_CMS_SERVER" feature="make_and_launch"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option debug="true" warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
|
||||
<option debug="true" warning="true" full_class_checking="false" is_attached_by_default="true" is_obsolete_routine_type="true" void_safety="all" syntax="transitional">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
</option>
|
||||
<setting name="executable_name" value="demo"/>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="..\..\cms-safe.ecf" readonly="false">
|
||||
@@ -29,11 +30,11 @@
|
||||
<library name="cms_google_search_module" location="..\..\modules\google_search\google_search-safe.ecf" readonly="false" use_application_options="true"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
|
||||
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
|
||||
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-safe.ecf" readonly="false"/>
|
||||
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/>
|
||||
<library name="cms_openid_module" location="..\..\modules\openid\openid-safe.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/>
|
||||
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth-safe.ecf" readonly="false"/>
|
||||
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy-safe.ecf" readonly="false"/>
|
||||
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false">
|
||||
<option>
|
||||
<assertions/>
|
||||
@@ -41,8 +42,8 @@
|
||||
</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="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"/>
|
||||
</target>
|
||||
|
||||
@@ -4,14 +4,28 @@ root-dir=site/www
|
||||
#modules-dir=site/modules
|
||||
|
||||
[site]
|
||||
# Name of the site, for the title, and eventual message.
|
||||
name=Eiffel CMS
|
||||
email=your@email.com
|
||||
|
||||
# Email used for notification
|
||||
email=noreply@example.com
|
||||
|
||||
# Name of website theme.
|
||||
theme=bootstrap
|
||||
|
||||
[notification]
|
||||
# By default, notification.email = site.email
|
||||
# you can change here the email that will receive internal messages.
|
||||
email=webmaster@example.com
|
||||
|
||||
[mailer]
|
||||
#smtp=localhost:25
|
||||
#sendmail=/usr/bin/sendmail
|
||||
output=@stderr
|
||||
#The mailer is used mostly used by the CMS to send email messages.
|
||||
# you can change the "From:" by setting mailer.from value"
|
||||
subject_prefix=[Eiffel CMS]
|
||||
#from=...
|
||||
smtp=localhost:25
|
||||
#sendmail=site\bin\roc_sendmail.bat
|
||||
output=site\db\mailer.log
|
||||
|
||||
[modules]
|
||||
# Module status
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"email": "webmaster@eiffel.org",
|
||||
"subject": "Thank you for contacting us",
|
||||
"recaptcha": {
|
||||
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
ul.cms-temp-users {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
border: solid 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
border-top: dotted 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li:first-child {
|
||||
border-top: none; }
|
||||
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; }
|
||||
border: solid 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
border-top: dotted 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li:first-child {
|
||||
border-top: none; }
|
||||
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] "; }
|
||||
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 */
|
||||
content: "[email] ";
|
||||
}
|
||||
|
||||
37
examples/demo/site/modules/auth/files/scss/auth.scss
Normal file
37
examples/demo/site/modules/auth/files/scss/auth.scss
Normal 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] "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
<meta name="description" content="Activation">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<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>"$user ($email)", thank you for applying to <a href="$host">$sitename</a>.</p>
|
||||
<p>We will review your application and send you a resolution.<p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,9 +6,8 @@
|
||||
<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>Your account "$user ($email)" is confirmed at <a href="$host">$sitename</a>.</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,12 +6,10 @@
|
||||
<meta name="description" content="New Password">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<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><a href="$link">$link</a></p>
|
||||
<p>You have requested a new password at <a href="$host">$sitename</a>.</p>
|
||||
<p>To complete your request, please click on the following link to generate a new password:
|
||||
<ul><a href="$link">$link</a></ul>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
<meta name="description" content="New Activation token">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have request a new activation token at <a href="$host">$sitename</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 this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>To complete your registration, please click on the following link to re-activate your account:
|
||||
<ul><a href="$link">$link</a></ul>
|
||||
</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
<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>
|
||||
<p>Your account application is rejected, it was not respecting the requirements from <a href="$host">$sitename</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,13 @@
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
<body>
|
||||
<p>Welcome to <a href="$host">$sitename</a></p>
|
||||
<p>Welcome to <a href="$host">$sitename</a>.</p>
|
||||
<p>Your account information:
|
||||
<ul>
|
||||
<li>Email address: "$email" .</li>
|
||||
<li>User name: "$user" .</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
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`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ feature -- CMS storage
|
||||
setup_storage (a_setup: CMS_SETUP)
|
||||
do
|
||||
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")
|
||||
end
|
||||
|
||||
@@ -42,56 +42,34 @@ feature -- CMS modules
|
||||
|
||||
setup_modules (a_setup: CMS_SETUP)
|
||||
-- Setup additional modules.
|
||||
local
|
||||
m: CMS_MODULE
|
||||
do
|
||||
create {CMS_ADMIN_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
-- Admin
|
||||
a_setup.register_module (create {CMS_ADMIN_MODULE}.make)
|
||||
|
||||
-- Auth
|
||||
create {CMS_AUTHENTICATION_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_BASIC_AUTH_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_OAUTH_20_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_OPENID_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
a_setup.register_module (create {CMS_AUTHENTICATION_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_BASIC_AUTH_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_OAUTH_20_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_OPENID_MODULE}.make)
|
||||
|
||||
-- Nodes
|
||||
create {CMS_NODE_MODULE} m.make (a_setup)
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_BLOG_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
a_setup.register_module (create {CMS_NODE_MODULE}.make (a_setup))
|
||||
a_setup.register_module (create {CMS_BLOG_MODULE}.make)
|
||||
|
||||
-- Taxonomy
|
||||
create {CMS_TAXONOMY_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
a_setup.register_module (create {CMS_TAXONOMY_MODULE}.make)
|
||||
|
||||
-- Recent changes
|
||||
create {CMS_RECENT_CHANGES_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
a_setup.register_module (create {CMS_RECENT_CHANGES_MODULE}.make)
|
||||
|
||||
-- Recent changes
|
||||
create {FEED_AGGREGATOR_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
-- Feed aggregator
|
||||
a_setup.register_module (create {FEED_AGGREGATOR_MODULE}.make)
|
||||
|
||||
-- Miscellanious
|
||||
create {CMS_DEBUG_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_DEMO_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {GOOGLE_CUSTOM_SEARCH_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_SESSION_AUTH_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
a_setup.register_module (create {CMS_DEBUG_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_DEMO_MODULE}.make)
|
||||
a_setup.register_module (create {GOOGLE_CUSTOM_SEARCH_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_SESSION_AUTH_MODULE}.make)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
note
|
||||
description: "Summary description for {CMS_TEMP_USER}."
|
||||
description: "User for temporary account."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
@@ -7,7 +7,6 @@ class
|
||||
CMS_TEMP_USER
|
||||
|
||||
inherit
|
||||
|
||||
CMS_USER
|
||||
|
||||
create
|
||||
@@ -22,15 +21,14 @@ feature -- Access
|
||||
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'.
|
||||
set_personal_information (a_personal_information: like personal_information)
|
||||
-- Assign `personal_information' with `a_personal_information'.
|
||||
do
|
||||
personal_information := an_personal_information
|
||||
personal_information := a_personal_information
|
||||
ensure
|
||||
personal_information_assigned: personal_information = an_personal_information
|
||||
personal_information_assigned: personal_information = a_personal_information
|
||||
end
|
||||
|
||||
set_salt (a_salt: like salt)
|
||||
@@ -41,4 +39,7 @@ feature -- Element change
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `logs` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`category` VARCHAR(255) NOT NULL,
|
||||
`level` int(11) NOT NULL,
|
||||
`uid` int(11) DEFAULT NULL,
|
||||
`message` text NOT NULL,
|
||||
`info` text,
|
||||
`link` text,
|
||||
`date` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `custom_values` (
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`value` VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE `path_aliases` (
|
||||
`pid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`source` varchar(255) NOT NULL,
|
||||
`alias` varchar(255) NOT NULL,
|
||||
`lang` varchar(12) DEFAULT NULL,
|
||||
PRIMARY KEY (`pid`)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE nodes (
|
||||
nid INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK( nid >=0),
|
||||
revision INTEGER,
|
||||
type TEXT NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
summary TEXT,
|
||||
content MEDIUMTEXT NOT NULL,
|
||||
format VARCHAR(255),
|
||||
author INTEGER,
|
||||
publish DATETIME,
|
||||
created DATETIME NOT NULL,
|
||||
changed DATETIME NOT NULL,
|
||||
status INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE page_nodes(
|
||||
nid INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK( nid >=0),
|
||||
revision INTEGER,
|
||||
parent INTEGER
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
@@ -1,76 +0,0 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`uid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`password` varchar(100) NOT NULL,
|
||||
`salt` varchar(100) NOT NULL,
|
||||
`email` varchar(250) NOT NULL,
|
||||
`status` int(11) DEFAULT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
`signed` datetime DEFAULT NULL,
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`uid`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `roles` (
|
||||
`rid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
CHECK (`rid` >= 0),
|
||||
PRIMARY KEY (`rid`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_roles` (
|
||||
`uid` int(11) NOT NULL,
|
||||
`rid` int(11) NOT NULL,
|
||||
CHECK (`uid` >= 0),
|
||||
CHECK (`rid` >= 0)
|
||||
);
|
||||
|
||||
CREATE TABLE `role_permissions` (
|
||||
`rid` int(11) NOT NULL,
|
||||
`permission` varchar(255) NOT NULL,
|
||||
`module` varchar(255) DEFAULT NULL,
|
||||
CHECK (`rid` >= 0)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_activations` (
|
||||
`aid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`uid` int(11) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
CHECK (`aid` >= 0),
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`aid`),
|
||||
UNIQUE KEY `token` (`token`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_password_recovery` (
|
||||
`aid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`uid` int(11) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
CHECK (`aid` >= 0),
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`aid`),
|
||||
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;
|
||||
@@ -73,7 +73,7 @@ feature -- Execution
|
||||
s.append ("<div class=%"info%"> ")
|
||||
s.append ("<h4>Account Information</h4>")
|
||||
s.append ("<p>Username: ")
|
||||
s.append (a_user.name)
|
||||
s.append (html_encoded (a_user.name))
|
||||
s.append ("</p>")
|
||||
if attached a_user.email as l_email then
|
||||
s.append ("<p>Email: ")
|
||||
|
||||
@@ -26,10 +26,6 @@
|
||||
<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_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>^persistence$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
209
modules/auth/cms_authentication_email_service.e
Normal file
209
modules/auth/cms_authentication_email_service.e
Normal file
@@ -0,0 +1,209 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_EMAIL_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_params: like parameters)
|
||||
-- Create instance of email service with `a_params' data.
|
||||
do
|
||||
parameters := a_params
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize service.
|
||||
do
|
||||
create error_handler.make
|
||||
reset_error
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
parameters: CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
|
||||
-- Associated parameters.
|
||||
|
||||
cms_api: CMS_API
|
||||
do
|
||||
Result := parameters.cms_api
|
||||
end
|
||||
|
||||
contact_email_address: IMMUTABLE_STRING_8
|
||||
-- contact email.
|
||||
do
|
||||
Result := parameters.contact_email_address
|
||||
end
|
||||
|
||||
notif_email_address: IMMUTABLE_STRING_8
|
||||
-- Site admin's email.
|
||||
do
|
||||
Result := parameters.notif_email_address
|
||||
end
|
||||
|
||||
sender_email_address: IMMUTABLE_STRING_8
|
||||
-- Site sender's email.
|
||||
do
|
||||
Result := parameters.sender_email_address
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
|
||||
has_error: BOOLEAN
|
||||
do
|
||||
Result := error_handler.has_error
|
||||
end
|
||||
|
||||
reset_error
|
||||
do
|
||||
error_handler.reset
|
||||
end
|
||||
|
||||
feature -- Basic Operations / Internal
|
||||
|
||||
send_internal_email (a_content: READABLE_STRING_GENERAL)
|
||||
do
|
||||
send_message (sender_email_address, notif_email_address, "Notification Contact", a_content)
|
||||
end
|
||||
|
||||
send_email_internal_server_error (a_content: READABLE_STRING_GENERAL)
|
||||
do
|
||||
send_message (sender_email_address, notif_email_address, "Internal Server Error", a_content)
|
||||
end
|
||||
|
||||
feature -- Basic Operations / Contact
|
||||
|
||||
send_account_evaluation (a_user: CMS_USER; a_application, a_url_activate, a_url_reject, a_host: READABLE_STRING_8)
|
||||
-- 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.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$user", a_user.utf_8_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_address, contact_email_address, parameters.contact_subject_account_evaluation, l_message)
|
||||
end
|
||||
|
||||
send_contact_email (a_to: READABLE_STRING_8; a_user: CMS_USER; a_host: READABLE_STRING_8)
|
||||
-- Send successful contact message for user `a_user' to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_activation)
|
||||
l_message.replace_substring_all ("$host", a_host)
|
||||
l_message.replace_substring_all ("$sitename", parameters.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$user", a_user.utf_8_name)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_register, l_message)
|
||||
end
|
||||
|
||||
send_contact_activation_email (a_to: READABLE_STRING_8; a_user: CMS_USER; a_link, a_host: READABLE_STRING_8)
|
||||
-- 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_re_activation)
|
||||
l_message.replace_substring_all ("$host", a_host)
|
||||
l_message.replace_substring_all ("$sitename", parameters.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$link", a_link)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_activate, l_message)
|
||||
end
|
||||
|
||||
send_contact_activation_confirmation_email (a_to: READABLE_STRING_8; a_user: CMS_USER; a_host: READABLE_STRING_8)
|
||||
-- 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.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$user", a_user.utf_8_name)
|
||||
l_message.replace_substring_all ("$email", a_to)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_activated, l_message)
|
||||
end
|
||||
|
||||
send_contact_activation_reject_email (a_to: READABLE_STRING_8; a_user: CMS_USER; 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.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$email", a_to)
|
||||
l_message.replace_substring_all ("$user", a_user.utf_8_name)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_rejected, l_message)
|
||||
end
|
||||
|
||||
send_contact_password_email (a_to: READABLE_STRING_8; a_user: CMS_USER; a_link, a_host: READABLE_STRING_8)
|
||||
-- Send successful new account password message to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_password)
|
||||
l_message.replace_substring_all ("$host", a_host)
|
||||
l_message.replace_substring_all ("$sitename", parameters.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$link", a_link)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_password, l_message)
|
||||
end
|
||||
|
||||
send_contact_welcome_email (a_to: READABLE_STRING_8; a_user: CMS_USER; a_host: READABLE_STRING_8)
|
||||
-- Send successful welcome message to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_welcome)
|
||||
l_message.replace_substring_all ("$host", a_host)
|
||||
l_message.replace_substring_all ("$sitename", parameters.utf_8_site_name)
|
||||
l_message.replace_substring_all ("$email", a_to)
|
||||
l_message.replace_substring_all ("$user", a_user.utf_8_name)
|
||||
send_message (contact_email_address, a_to, parameters.contact_subject_oauth, l_message)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
send_message (a_from_address, a_to_address: READABLE_STRING_8; a_subjet: READABLE_STRING_GENERAL; a_content: READABLE_STRING_GENERAL)
|
||||
local
|
||||
l_email: CMS_EMAIL
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
reset_error
|
||||
l_email := cms_api.new_email (a_to_address, utf.escaped_utf_32_string_to_utf_8_string_8 (a_subjet), utf.escaped_utf_32_string_to_utf_8_string_8 (a_content))
|
||||
l_email.set_from_address (a_from_address)
|
||||
l_email.add_header_line ("MIME-Version:1.0")
|
||||
l_email.add_header_line ("Content-Type: text/html; charset=utf-8")
|
||||
cms_api.process_email (l_email)
|
||||
if cms_api.has_error then
|
||||
error_handler.add_custom_error (-1, generator + "send_message failed", cms_api.string_representation_of_errors)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -6,9 +6,6 @@ note
|
||||
class
|
||||
CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
|
||||
|
||||
inherit
|
||||
EMAIL_SERVICE_PARAMETERS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
@@ -18,23 +15,20 @@ feature {NONE} -- Initialization
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
s: detachable READABLE_STRING_32
|
||||
l_utf8_site_name: IMMUTABLE_STRING_8
|
||||
l_contact_email, l_subject_register, l_subject_activate, l_subject_password, l_subject_oauth: detachable READABLE_STRING_8
|
||||
do
|
||||
cms_api := a_cms_api
|
||||
-- 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"))
|
||||
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
|
||||
create l_utf8_site_name.make_from_string (a_cms_api.setup.utf_8_site_name)
|
||||
utf_8_site_name := l_utf8_site_name
|
||||
notif_email_address := a_cms_api.setup.site_notification_email
|
||||
sender_email_address := a_cms_api.setup.site_email
|
||||
|
||||
if not admin_email.has ('<') then
|
||||
admin_email := site_name + " <" + admin_email +">"
|
||||
if not notif_email_address.has ('<') then
|
||||
notif_email_address := l_utf8_site_name + " <" + notif_email_address + ">"
|
||||
end
|
||||
|
||||
if attached {CONFIG_READER} a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then
|
||||
if attached cfg.text_item ("smtp") as l_smtp then
|
||||
-- Overwrite global smtp setting if any.
|
||||
smtp_server := utf.utf_32_string_to_utf_8_string_8 (l_smtp)
|
||||
end
|
||||
if attached a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then
|
||||
s := cfg.text_item ("email")
|
||||
if s /= Void then
|
||||
l_contact_email := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
@@ -55,16 +49,15 @@ feature {NONE} -- Initialization
|
||||
if s /= Void then
|
||||
l_subject_oauth := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
|
||||
end
|
||||
if l_contact_email /= Void then
|
||||
if l_contact_email = Void then
|
||||
l_contact_email := notif_email_address
|
||||
end
|
||||
if not l_contact_email.has ('<') then
|
||||
l_contact_email := site_name + " <" + l_contact_email + ">"
|
||||
end
|
||||
contact_email := l_contact_email
|
||||
else
|
||||
contact_email := admin_email
|
||||
l_contact_email := l_utf8_site_name + " <" + l_contact_email + ">"
|
||||
end
|
||||
contact_email_address := l_contact_email
|
||||
|
||||
if l_subject_register /= Void then
|
||||
contact_subject_register := l_subject_register
|
||||
else
|
||||
@@ -87,11 +80,9 @@ feature {NONE} -- Initialization
|
||||
contact_subject_oauth := "Welcome."
|
||||
end
|
||||
|
||||
contact_subject_account_evaluation := "New register, account evalution"
|
||||
|
||||
contact_subject_rejected := "Your account was rejected"
|
||||
|
||||
contact_subject_activated := "Your account was activated"
|
||||
contact_subject_account_evaluation := "New register, account evalution."
|
||||
contact_subject_rejected := "Your account was rejected."
|
||||
contact_subject_activated := "Your account was activated."
|
||||
end
|
||||
|
||||
|
||||
@@ -100,14 +91,14 @@ feature -- Access
|
||||
|
||||
cms_api: CMS_API
|
||||
|
||||
smtp_server: IMMUTABLE_STRING_8
|
||||
notif_email_address: IMMUTABLE_STRING_8
|
||||
|
||||
admin_email: IMMUTABLE_STRING_8
|
||||
sender_email_address: IMMUTABLE_STRING_8
|
||||
|
||||
contact_email: IMMUTABLE_STRING_8
|
||||
contact_email_address: IMMUTABLE_STRING_8
|
||||
-- Contact email.
|
||||
|
||||
site_name: IMMUTABLE_STRING_8
|
||||
utf_8_site_name: IMMUTABLE_STRING_8
|
||||
-- UTF-8 encoded Site name.
|
||||
|
||||
contact_subject_account_evaluation: IMMUTABLE_STRING_8
|
||||
@@ -118,7 +109,6 @@ feature -- Access
|
||||
contact_subject_rejected: IMMUTABLE_STRING_8
|
||||
contact_subject_activated: IMMUTABLE_STRING_8
|
||||
|
||||
|
||||
account_evaluation: STRING
|
||||
-- Account evaluation template email message.
|
||||
do
|
||||
|
||||
@@ -203,23 +203,31 @@ feature -- Handler
|
||||
l_user_api: CMS_USER_API
|
||||
u: CMS_TEMP_USER
|
||||
l_exist: BOOLEAN
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
l_url_activate: STRING
|
||||
l_url_reject: STRING
|
||||
l_token: STRING
|
||||
l_captcha_passed: BOOLEAN
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("account register") then
|
||||
if req.is_post_request_method then
|
||||
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
|
||||
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 p_email and then
|
||||
attached {WSF_STRING} req.form_parameter ("personal_information") as l_personal_information
|
||||
then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
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
|
||||
-- Username already exist.
|
||||
r.set_value ("User name already exists!", "error_name")
|
||||
l_exist := True
|
||||
end
|
||||
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
|
||||
if attached l_user_api.user_by_email (l_email) or else attached l_user_api.temp_user_by_email (l_email) then
|
||||
-- Emails already exist.
|
||||
r.set_value ("An account is already associated with that email address!", "error_email")
|
||||
l_exist := True
|
||||
@@ -236,10 +244,9 @@ feature -- Handler
|
||||
l_captcha_passed := True
|
||||
end
|
||||
if not l_exist then
|
||||
|
||||
-- New temp user
|
||||
create u.make (l_name.value)
|
||||
u.set_email (l_email.value)
|
||||
u.set_email (l_email)
|
||||
u.set_password (l_password.value)
|
||||
u.set_personal_information (l_personal_information.value)
|
||||
l_user_api.new_temp_user (u)
|
||||
@@ -258,13 +265,22 @@ feature -- Handler
|
||||
-- Send Email to user
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_email")
|
||||
es.send_contact_email (l_email.value, l_name.value, req.absolute_script_url (""))
|
||||
es.send_contact_email (l_email, u, req.absolute_script_url (""))
|
||||
else
|
||||
r.set_value (l_name.value, "name")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_value (l_email, "email")
|
||||
r.set_value (l_personal_information.value, "personal_information")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
else
|
||||
r.set_value (l_name.value, "name")
|
||||
r.set_value (p_email.value, "email")
|
||||
r.set_value (l_personal_information.value, "personal_information")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
else
|
||||
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_main_content ("There were issue with your application, invalid or missing values.")
|
||||
end
|
||||
end
|
||||
else
|
||||
@@ -279,7 +295,7 @@ feature -- Handler
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
do
|
||||
l_user_api := api.user_api
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
@@ -299,12 +315,12 @@ feature -- Handler
|
||||
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>")
|
||||
r.set_main_content ("<p> The account <i>" + html_encoded (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 (""))
|
||||
es.send_contact_activation_confirmation_email (l_email, l_user, req.absolute_script_url (""))
|
||||
end
|
||||
else
|
||||
-- the token does not exist, or it was already used.
|
||||
@@ -325,8 +341,8 @@ feature -- Handler
|
||||
handle_reject (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
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)
|
||||
@@ -335,12 +351,12 @@ feature -- Handler
|
||||
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>")
|
||||
r.set_main_content ("<p> The temporal account for <i>" + html_encoded (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 (""))
|
||||
es.send_contact_activation_reject_email (l_email, l_user, req.absolute_script_url (""))
|
||||
end
|
||||
else
|
||||
-- the token does not exist, or it was already used.
|
||||
@@ -361,21 +377,24 @@ feature -- Handler
|
||||
handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
l_user_api: CMS_USER_API
|
||||
l_token: STRING
|
||||
l_url_activate: STRING
|
||||
l_url_reject: STRING
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("account reactivate") then
|
||||
if req.is_post_request_method then
|
||||
if attached {WSF_STRING} req.form_parameter ("email") as l_email then
|
||||
if attached {WSF_STRING} req.form_parameter ("email") as p_email then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
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_TEMP_USER} l_user_api.temp_user_by_email (l_email) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
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 + " , is already active", "is_active")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
else
|
||||
l_token := new_token
|
||||
@@ -390,8 +409,13 @@ feature -- Handler
|
||||
end
|
||||
end
|
||||
else
|
||||
r.set_value ("The email does not exist or !", "error_email")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_value ("The email does not exist !", "error_email")
|
||||
r.set_value (l_email, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
else
|
||||
r.set_value ("The email is not valid!", "error_email")
|
||||
r.set_value (p_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
@@ -406,16 +430,19 @@ feature -- Handler
|
||||
handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
l_user_api: CMS_USER_API
|
||||
l_token: STRING
|
||||
l_url: STRING
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if req.is_post_request_method then
|
||||
l_user_api := api.user_api
|
||||
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 {WSF_STRING} req.form_parameter ("email") as p_email then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_user_api.new_password (l_token, l_user.id)
|
||||
@@ -424,14 +451,22 @@ feature -- Handler
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email.value, l_url, req.absolute_script_url (""))
|
||||
es.send_contact_password_email (l_email, l_user, l_url, req.absolute_script_url (""))
|
||||
else
|
||||
r.set_value ("The email does not exist !", "error_email")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_value (p_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
else
|
||||
r.set_value ("The email is not valid!", "error_email")
|
||||
r.set_value (p_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
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 attached l_user.email as l_email then
|
||||
if
|
||||
attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then
|
||||
attached l_user.email as l_user_email
|
||||
then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_user_api.new_password (l_token, l_user.id)
|
||||
@@ -440,7 +475,7 @@ feature -- Handler
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email, l_url, req.absolute_script_url (""))
|
||||
es.send_contact_password_email (l_user_email, l_user, l_url, req.absolute_script_url (""))
|
||||
else
|
||||
r.set_value ("The username does not exist !", "error_username")
|
||||
r.set_value (l_username.value, "username")
|
||||
@@ -524,7 +559,6 @@ feature -- Handler
|
||||
r.execute
|
||||
end
|
||||
|
||||
|
||||
handle_admin_pending_registrations (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API)
|
||||
local
|
||||
l_response: CMS_RESPONSE
|
||||
@@ -573,11 +607,11 @@ feature -- Handler
|
||||
loop
|
||||
u := ic.item
|
||||
s.append ("<li class=%"cms_temp_user%">")
|
||||
s.append ("User:" + u.name)
|
||||
s.append ("User:" + html_encoded (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 (html_encoded (l_information))
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
if attached u.email as l_email then
|
||||
@@ -616,7 +650,6 @@ feature -- Handler
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
local
|
||||
l_string: STRING
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATON_EMAIL_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
|
||||
inherit
|
||||
EMAIL_SERVICE
|
||||
redefine
|
||||
initialize,
|
||||
parameters
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
contact_email := parameters.contact_email
|
||||
end
|
||||
|
||||
parameters: CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
|
||||
-- Associated parameters.
|
||||
|
||||
feature -- Access
|
||||
|
||||
contact_email: IMMUTABLE_STRING_8
|
||||
-- contact email.
|
||||
|
||||
feature -- Basic Operations
|
||||
|
||||
send_account_evaluation (a_user: CMS_USER; a_application, a_url_activate, a_url_reject, a_host: READABLE_STRING_8)
|
||||
-- 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
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_activation)
|
||||
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)
|
||||
end
|
||||
|
||||
|
||||
send_contact_activation_email (a_to, a_content, a_host: READABLE_STRING_8)
|
||||
-- Send successful contact activation message to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
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)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_activate, l_message)
|
||||
end
|
||||
|
||||
|
||||
send_contact_activation_confirmation_email (a_to, a_content, a_host: READABLE_STRING_8)
|
||||
-- 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
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
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)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_password, l_message)
|
||||
end
|
||||
|
||||
send_contact_welcome_email (a_to, a_content, a_host: READABLE_STRING_8)
|
||||
-- Send successful welcome message to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
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)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"email": "webmaster@eiffel.org",
|
||||
"subject": "Thank you for contacting us",
|
||||
"recaptcha": {
|
||||
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
ul.cms-temp-users {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
border: solid 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
border-top: dotted 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li:first-child {
|
||||
border-top: none; }
|
||||
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; }
|
||||
border: solid 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
border-top: dotted 1px #ccc;
|
||||
}
|
||||
ul.cms-temp-users li.cms_temp_user ul.cms_temp_user_details li:first-child {
|
||||
border-top: none; }
|
||||
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] "; }
|
||||
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 */
|
||||
content: "[email] ";
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
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 */
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
@@ -6,9 +6,8 @@
|
||||
<meta name="description" content="Activation">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<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>"$user ($email)", thank you for applying to <a href="$host">$sitename</a>.</p>
|
||||
<p>We will review your application and send you a resolution.<p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,9 +6,8 @@
|
||||
<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>Your account "$user ($email)" is confirmed at <a href="$host">$sitename</a>.</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,12 +6,10 @@
|
||||
<meta name="description" content="New Password">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<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><a href="$link">$link</a></p>
|
||||
<p>You have requested a new password at <a href="$host">$sitename</a>.</p>
|
||||
<p>To complete your request, please click on the following link to generate a new password:
|
||||
<ul><a href="$link">$link</a></ul>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
<meta name="description" content="New Activation token">
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have request a new activation token at <a href="$host">$sitename</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 this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>To complete your registration, please click on the following link to re-activate your account:
|
||||
<ul><a href="$link">$link</a></ul>
|
||||
</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
<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>
|
||||
<p>Your account application is rejected, it was not respecting the requirements from <a href="$host">$sitename</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -7,7 +7,13 @@
|
||||
<meta name="author" content="$sitename">
|
||||
</head>
|
||||
<body>
|
||||
<p>Welcome to <a href="$host">$sitename</a></p>
|
||||
<p>Welcome to <a href="$host">$sitename</a>.</p>
|
||||
<p>Your account information:
|
||||
<ul>
|
||||
<li>Email address: "$email" .</li>
|
||||
<li>User name: "$user" .</li>
|
||||
</ul>
|
||||
</p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
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`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ feature -- HTML Output
|
||||
do
|
||||
if attached n.author as l_author then
|
||||
a_output.append ("by ")
|
||||
a_output.append ("<a class=%"blog_user_link%" href=%"/blogs/user/" + l_author.id.out + "%">" + l_author.name + "</a>")
|
||||
a_output.append ("<a class=%"blog_user_link%" href=%"/blogs/user/" + l_author.id.out + "%">" + html_encoded (l_author.name) + "</a>")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -278,10 +278,10 @@ feature -- Form
|
||||
if attached user as u then
|
||||
api.log ("node",
|
||||
"User %"" + user_html_link (u) + "%" " + s + " node " + node_html_link (l_node, a_type.name + " #" + l_node.id.out),
|
||||
0, node_local_link (l_node, Void)
|
||||
{CMS_LOG}.level_notice, node_local_link (l_node, Void)
|
||||
)
|
||||
else
|
||||
api.log ("node", "Anonymous " + s + " node " + a_type.name +" #" + l_node.id.out, 0, node_local_link (l_node, Void))
|
||||
api.log ("node", "Anonymous " + s + " node " + a_type.name +" #" + l_node.id.out, {CMS_LOG}.level_notice, node_local_link (l_node, Void))
|
||||
end
|
||||
if node_api.has_error then
|
||||
add_error_message ("Node #" + l_node.id.out + " failed to save.")
|
||||
|
||||
@@ -430,7 +430,7 @@ feature -- OAuth2 Login with Provider
|
||||
l_user: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_cookie: WSF_COOKIE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ({CMS_OAUTH_20_CONSTANTS}.oauth_callback) as l_callback and then
|
||||
attached {CMS_OAUTH_20_CONSUMER} a_user_oauth_api.oauth_consumer_by_callback (l_callback.value) as l_consumer and then
|
||||
@@ -493,7 +493,7 @@ feature -- OAuth2 Login with Provider
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle_callback_oauth: send_contact_welcome_email")
|
||||
es.send_contact_welcome_email (l_email, "", req.absolute_script_url (""))
|
||||
es.send_contact_welcome_email (l_email, l_user, req.absolute_script_url (""))
|
||||
end
|
||||
end
|
||||
r.set_redirection (r.front_page_url)
|
||||
|
||||
@@ -390,7 +390,7 @@ feature -- Openid Login
|
||||
l_user: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_cookie: WSF_COOKIE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
b: STRING
|
||||
o: OPENID_CONSUMER
|
||||
v: OPENID_CONSUMER_VALIDATION
|
||||
@@ -443,7 +443,7 @@ feature -- Openid Login
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle_callback_openid: send_contact_welcome_email")
|
||||
es.send_contact_welcome_email (l_email, "", req.absolute_script_url (""))
|
||||
es.send_contact_welcome_email (l_email, l_user, req.absolute_script_url (""))
|
||||
end
|
||||
end
|
||||
r.set_redirection (r.front_page_url)
|
||||
|
||||
@@ -179,6 +179,6 @@ feature -- Element change
|
||||
|
||||
|
||||
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)"
|
||||
end
|
||||
|
||||
@@ -16,11 +16,12 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
local
|
||||
l_url: like site_url
|
||||
s, l_email: detachable READABLE_STRING_8
|
||||
do
|
||||
site_location := environment.path
|
||||
|
||||
--| Site id, used to identified a site, this could be set to a uuid, or else
|
||||
site_id := text_item_or_default ("site.id", "_EWF_CMS_NO_ID_")
|
||||
site_id := string_8_item_or_default ("site.id", "_ROC_CMS_NO_ID_")
|
||||
|
||||
-- Site url: optional, but ending with a slash
|
||||
l_url := string_8_item ("site_url")
|
||||
@@ -32,30 +33,50 @@ feature {NONE} -- Initialization
|
||||
site_url := l_url
|
||||
|
||||
-- Site name
|
||||
site_name := text_item_or_default ("site.name", "EWF::CMS")
|
||||
site_name := text_item_or_default ("site.name", "Another Eiffel ROC Website")
|
||||
|
||||
-- Site email for any internal notification
|
||||
-- Can be also used to precise the "From:" value for email.
|
||||
site_email := text_item_or_default ("site.email", "webmaster")
|
||||
-- Website email used to send email.
|
||||
-- used as real "From:" email.
|
||||
-- Any "From:" header passed to the CMS email sender will appear as "Reply-To:"
|
||||
-- or ignored if a reply-to header is already set.
|
||||
l_email := string_8_item ("site.email")
|
||||
if l_email = Void then
|
||||
-- FIXME: find better default value!
|
||||
-- Or handler configuration error (missing value)!!!
|
||||
l_email := string_8_item_or_default ("mailer.from", "webmaster")
|
||||
end
|
||||
if l_email.has ('<') then
|
||||
l_email := site_name + " <" + l_email + ">"
|
||||
end
|
||||
site_email := l_email
|
||||
|
||||
-- Email address for current web site
|
||||
site_notification_email := string_8_item_or_default ("notification.email", site_email)
|
||||
-- Email subject tuning.
|
||||
s := string_8_item ("mailer.subject_prefix")
|
||||
if s /= Void and then not s.ends_with_general (" ") then
|
||||
s := s + " "
|
||||
end
|
||||
site_email_subject_prefix := s
|
||||
|
||||
|
||||
-- Location for public files
|
||||
if attached text_item ("files-dir") as s then
|
||||
create files_location.make_from_string (s)
|
||||
if attached text_item ("files-dir") as l_files_dir then
|
||||
create files_location.make_from_string (l_files_dir)
|
||||
else
|
||||
files_location := site_location.extended ("files")
|
||||
end
|
||||
|
||||
-- Location for modules folders.
|
||||
if attached text_item ("modules-dir") as s then
|
||||
create modules_location.make_from_string (s)
|
||||
if attached text_item ("modules-dir") as l_modules_dir then
|
||||
create modules_location.make_from_string (l_modules_dir)
|
||||
else
|
||||
modules_location := environment.modules_path
|
||||
end
|
||||
|
||||
-- Location for themes folders.
|
||||
if attached text_item ("themes-dir") as s then
|
||||
create themes_location.make_from_string (s)
|
||||
if attached text_item ("themes-dir") as l_themes_dir then
|
||||
create themes_location.make_from_string (l_themes_dir)
|
||||
else
|
||||
themes_location := environment.themes_path
|
||||
end
|
||||
@@ -180,9 +201,24 @@ feature -- Access: Site
|
||||
site_name: READABLE_STRING_32
|
||||
-- Name of the site.
|
||||
|
||||
utf_8_site_name: READABLE_STRING_8
|
||||
-- `site_name' encoded with UTF-8.
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
Result := utf.utf_32_string_to_utf_8_string_8 (site_name)
|
||||
end
|
||||
|
||||
site_email: READABLE_STRING_8
|
||||
-- Admin email address for the site.
|
||||
-- Mainly used for internal notification.
|
||||
-- Website email address.
|
||||
-- Used as "From:" address when the site is sending emails
|
||||
-- cf: `CMS_SETUP.mailer'.
|
||||
|
||||
site_notification_email: READABLE_STRING_8
|
||||
-- Email address receiving internal notification.
|
||||
|
||||
site_email_subject_prefix: detachable READABLE_STRING_8
|
||||
-- Optional prefix for any email sent by Current site.
|
||||
|
||||
site_url: detachable READABLE_STRING_8
|
||||
-- Optional url of current CMS site.
|
||||
@@ -223,6 +259,16 @@ feature -- Query
|
||||
deferred
|
||||
end
|
||||
|
||||
string_8_item_or_default (a_name: READABLE_STRING_GENERAL; a_default_value: READABLE_STRING_8): READABLE_STRING_8
|
||||
-- `string_8_item' associated with `a_name' or if none, `a_default_value'.
|
||||
do
|
||||
if attached string_8_item (a_name) as v then
|
||||
Result := v
|
||||
else
|
||||
Result := a_default_value
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: Theme
|
||||
|
||||
site_location: PATH
|
||||
@@ -333,6 +379,6 @@ feature -- Element change
|
||||
end
|
||||
|
||||
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)"
|
||||
end
|
||||
|
||||
@@ -281,7 +281,7 @@ feature -- Access: Temp Users
|
||||
|
||||
feature -- New Temp User
|
||||
|
||||
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
|
||||
new_user_from_temp_user (a_user: CMS_TEMP_USER)
|
||||
-- new user from temporal user `a_user'
|
||||
require
|
||||
no_id: not a_user.has_id
|
||||
|
||||
@@ -184,7 +184,7 @@ feature -- Access: Users
|
||||
|
||||
feature -- Temp Users
|
||||
|
||||
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
|
||||
new_user_from_temp_user (a_user: CMS_TEMP_USER)
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
@@ -669,7 +669,7 @@ feature -- Change: roles and permissions
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".last_inserted_user_role_id")
|
||||
sql_query (Sql_last_insert_user_role_id, Void)
|
||||
sql_query (sql_last_insert_user_role_id, Void)
|
||||
if not sql_after then
|
||||
Result := sql_read_integer_64 (1).to_integer_32
|
||||
sql_forth
|
||||
@@ -879,25 +879,25 @@ feature {NONE} -- Implementation: User role
|
||||
|
||||
feature {NONE} -- Sql Queries: USER
|
||||
|
||||
Select_users_count: STRING = "SELECT count(*) FROM users;"
|
||||
select_users_count: STRING = "SELECT count(*) FROM users;"
|
||||
-- Number of users.
|
||||
|
||||
Select_users: STRING = "SELECT * FROM users;"
|
||||
select_users: STRING = "SELECT * FROM users;"
|
||||
-- List of users.
|
||||
|
||||
Select_user_by_id: STRING = "SELECT * FROM users WHERE uid =:uid;"
|
||||
select_user_by_id: STRING = "SELECT * FROM users WHERE uid =:uid;"
|
||||
-- Retrieve user by id if exists.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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;"
|
||||
-- Retrieve user by email if exists.
|
||||
|
||||
Select_salt_by_username: STRING = "SELECT salt FROM users WHERE name =:name;"
|
||||
select_salt_by_username: STRING = "SELECT salt FROM users WHERE name =:name;"
|
||||
-- Retrieve salt by username if exists.
|
||||
|
||||
sql_insert_user: STRING = "INSERT INTO users (name, password, salt, email, created, status) VALUES (:name, :password, :salt, :email, :created, :status);"
|
||||
@@ -959,16 +959,16 @@ feature {NONE} -- Sql Queries: USER ACTIVATION
|
||||
sql_insert_activation: STRING = "INSERT INTO users_activations (token, uid, created) VALUES (:token, :uid, :utc_date);"
|
||||
-- SQL insert a new activation :token.
|
||||
|
||||
sql_select_activation_expiration: STRING = "SELECT DATEDIFF(day,created,UTC_DATE()) FROM users_activations where token = :token;"
|
||||
sql_select_activation_expiration: STRING = "SELECT DATEDIFF(day,created,UTC_DATE()) FROM users_activations WHERE token = :token;"
|
||||
-- elapsed time that has passed in days since the token `a_token' was saved.
|
||||
|
||||
sql_select_userid_activation: STRING = "SELECT uid FROM users_activations where token = :token;"
|
||||
sql_select_userid_activation: STRING = "SELECT uid FROM users_activations WHERE token = :token;"
|
||||
-- Retrieve userid given the activation token.
|
||||
|
||||
Select_user_by_activation_token: STRING = "SELECT u.* FROM users as u JOIN users_activations as ua ON ua.uid = u.uid and ua.token = :token;"
|
||||
select_user_by_activation_token: STRING = "SELECT u.* FROM 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_remove_activation: STRING = "DELETE FROM users_activations WHERE token = :token;"
|
||||
sql_remove_activation: STRING = "DELETE FROM users_activations WHERE token = :token;"
|
||||
-- Remove activation token.
|
||||
|
||||
feature {NONE} -- User Password Recovery
|
||||
@@ -976,14 +976,12 @@ feature {NONE} -- User Password Recovery
|
||||
sql_insert_password: STRING = "INSERT INTO users_password_recovery (token, uid, created) VALUES (:token, :uid, :utc_date);"
|
||||
-- SQL insert a new password recovery :token.
|
||||
|
||||
Sql_remove_password: STRING = "DELETE FROM users_password_recovery WHERE token = :token;"
|
||||
sql_remove_password: STRING = "DELETE FROM users_password_recovery WHERE token = :token;"
|
||||
-- Retrieve password if exist.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
|
||||
feature -- Acess: Temp users
|
||||
|
||||
temp_users_count: INTEGER
|
||||
@@ -1001,7 +999,6 @@ feature -- Acess: Temp users
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
|
||||
temp_user_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_GENERAL): detachable CMS_USER
|
||||
-- <Precursor>
|
||||
local
|
||||
@@ -1170,7 +1167,7 @@ feature {NONE} -- Implementation: User
|
||||
|
||||
feature -- New Temp User
|
||||
|
||||
new_user_from_temporal_user (a_user: CMS_TEMP_USER)
|
||||
new_user_from_temp_user (a_user: CMS_TEMP_USER)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
@@ -1181,9 +1178,10 @@ feature -- New Temp User
|
||||
attached a_user.email as l_email and then
|
||||
attached a_user.salt as l_password_salt
|
||||
then
|
||||
-- FIXME: store the personal_information in profile!
|
||||
sql_begin_transaction
|
||||
|
||||
write_information_log (generator + ".new_user_from_temporal_user")
|
||||
write_information_log (generator + ".new_user_from_temp_user")
|
||||
create l_parameters.make (4)
|
||||
l_parameters.put (a_user.name, "name")
|
||||
l_parameters.put (l_password_hash, "password")
|
||||
@@ -1245,11 +1243,10 @@ feature -- New Temp User
|
||||
sql_finalize
|
||||
else
|
||||
-- set error
|
||||
error_handler.add_custom_error (-1, "bad request" , "Missing password or email")
|
||||
error_handler.add_custom_error (-1, "bad request" , "Missing password or email or personal information")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Remove Activation
|
||||
|
||||
remove_activation (a_token: READABLE_STRING_32)
|
||||
@@ -1281,6 +1278,7 @@ feature -- Remove Activation
|
||||
sql_commit_transaction
|
||||
sql_finalize
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
last_inserted_temp_user_id: INTEGER_64
|
||||
@@ -1316,7 +1314,7 @@ 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;"
|
||||
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);"
|
||||
|
||||
@@ -316,14 +316,24 @@ feature -- Emails
|
||||
|
||||
new_email (a_to_address: READABLE_STRING_8; a_subject: READABLE_STRING_8; a_content: READABLE_STRING_8): CMS_EMAIL
|
||||
-- New email object.
|
||||
local
|
||||
l_subject: READABLE_STRING_8
|
||||
do
|
||||
create Result.make (setup.site_email, a_to_address, a_subject, a_content)
|
||||
l_subject := a_subject
|
||||
if attached setup.site_email_subject_prefix as l_prefix then
|
||||
if not l_subject.starts_with (l_prefix) then
|
||||
l_subject := l_prefix + l_subject
|
||||
end
|
||||
end
|
||||
create Result.make (setup.site_email, a_to_address, l_subject, a_content)
|
||||
end
|
||||
|
||||
process_email (e: CMS_EMAIL)
|
||||
-- Process email `e'.
|
||||
do
|
||||
log ("mailer", "Send email %"" + e.subject + "%"%N" + e.header, {CMS_LOG}.level_notice, Void)
|
||||
reset_error
|
||||
prepare_email (e)
|
||||
setup.mailer.safe_process_email (e)
|
||||
if setup.mailer.has_error then
|
||||
error_handler.add_custom_error (0, "Mailer error", "Error occurred while processing email.")
|
||||
@@ -333,10 +343,33 @@ feature -- Emails
|
||||
process_emails (lst: ITERABLE [CMS_EMAIL])
|
||||
-- Process collection of email `lst'.
|
||||
do
|
||||
reset_error
|
||||
setup.mailer.process_emails (lst)
|
||||
if setup.mailer.has_error then
|
||||
error_handler.add_custom_error (0, "Mailer error", "Error occurred while processing emails.")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
process_email (ic.item)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Emails implementation
|
||||
|
||||
prepare_email (e: CMS_EMAIL)
|
||||
-- Prepare email `e', and update parameters if needed.
|
||||
local
|
||||
l_sender, l_from: READABLE_STRING_8
|
||||
do
|
||||
l_sender := setup.site_email
|
||||
l_from := e.from_address
|
||||
if not l_sender.is_case_insensitive_equal_general (l_from) then
|
||||
e.set_from_address (l_sender)
|
||||
if not e.has_header ("Return-Path") then
|
||||
e.add_header_line ("Return-path: " + l_from)
|
||||
end
|
||||
if e.reply_to_address = Void then
|
||||
e.set_reply_to_address (l_from)
|
||||
else
|
||||
--| As a Reply-To address is already set,
|
||||
--| ignore previous from address.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -548,7 +581,7 @@ feature -- Element Change: Error
|
||||
error_handler.reset
|
||||
end
|
||||
|
||||
feature {NONE}-- Implemenation
|
||||
feature {NONE}-- Implementation
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
@@ -834,7 +867,7 @@ feature -- Hook
|
||||
end
|
||||
|
||||
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)"
|
||||
end
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@ feature -- Change Temp User
|
||||
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)
|
||||
storage.new_user_from_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!")
|
||||
|
||||
23
tpl/site/scripts/core.sql
Normal file
23
tpl/site/scripts/core.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
CREATE TABLE `logs`(
|
||||
`id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`category` VARCHAR(255) NOT NULL,
|
||||
`level` INTEGER NOT NULL,
|
||||
`uid` INTEGER,
|
||||
`message` TEXT NOT NULL,
|
||||
`info` TEXT,
|
||||
`link` TEXT,
|
||||
`date` DATETIME NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE `custom_values`(
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`value` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE `path_aliases`(
|
||||
`pid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`source` VARCHAR(255) NOT NULL,
|
||||
`alias` VARCHAR(255) NOT NULL,
|
||||
`lang` VARCHAR(12)
|
||||
);
|
||||
63
tpl/site/scripts/user.sql
Normal file
63
tpl/site/scripts/user.sql
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
CREATE TABLE `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,
|
||||
`status` INTEGER,
|
||||
`created` DATETIME NOT NULL,
|
||||
`signed` DATETIME,
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `roles`(
|
||||
`rid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `users_roles`(
|
||||
`uid` INTEGER NOT NULL CHECK(`uid`>=0),
|
||||
`rid` INTEGER NOT NULL CHECK(`rid`>=0)
|
||||
);
|
||||
|
||||
CREATE TABLE `role_permissions`(
|
||||
`rid` INTEGER NOT NULL,
|
||||
`permission` VARCHAR(255) NOT NULL,
|
||||
`module` VARCHAR(255)
|
||||
);
|
||||
|
||||
CREATE TABLE `users_activations` (
|
||||
`aid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK (`aid` >= 0),
|
||||
`token` VARCHAR(255) NOT NULL,
|
||||
`uid` INTEGER NOT NULL CHECK (`uid` >= 0),
|
||||
`created` DATETIME NOT NULL,
|
||||
CONSTRAINT `token` UNIQUE (`token`)
|
||||
);
|
||||
|
||||
CREATE TABLE `users_password_recovery` (
|
||||
`aid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK (`aid` >= 0),
|
||||
`token` VARCHAR(255) NOT NULL,
|
||||
`uid` INTEGER NOT NULL CHECK (`uid` >= 0),
|
||||
`created` DATETIME NOT NULL,
|
||||
CONSTRAINT `token` UNIQUE (`token`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `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`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user