Compare commits

...

57 Commits

Author SHA1 Message Date
bd3fe63976 Fixed "destination" support when login.
(i.e when visitor click on signin from page A, one he is signed, he will be redirected to the initial page A.)
2016-04-13 10:56:28 +02:00
0c7d8af9d7 Added support for CMS_BLOCK.is_raw in custom block module. 2016-02-19 00:53:47 +01:00
f80268c1ac Updated CMS_HOOK_BLOCK, to provide a better block_identifiers (CMS_RESPONSE): detachable ITERABLE [READABLE_STRING_8] query, to be implemented by CMS_HOOK_RESPONSE_BLOCK descendants.
Added CONFIG_READER.table_keys: detachable LIST [READABLE_STRING_32].
2016-02-19 00:10:09 +01:00
77e2c28d18 Added logs admin viewer.
Added CMS_SETUP.is_debug: BOOLEAN  (see cms.ini   site.debug setting)
2016-02-19 00:03:15 +01:00
af137629e0 Restored previous template_block* function signatures and made them obsolete.
Added smarty_template_block* functions as new recommended functions.
2016-02-18 16:26:00 +01:00
a7f1f14b8a Added missing change to installed file for demo example. 2016-02-18 16:14:58 +01:00
fbda2c9eb2 Reuse improved CMS_HOOK_BLOCK_HELPER to help creation of block templates.
Fixed typo in basic auth login form.
2016-02-18 16:13:58 +01:00
ff58593bff Added functions to get link from menu or link composite.
Improved management menu, but using sub menu.
2016-02-18 12:47:21 +01:00
c65f5765d6 Removed unwanted auth.json file (wrong directory). 2016-02-17 16:11:50 +01:00
19565b9c98 Updated registration form. 2016-02-17 16:07:20 +01:00
6716cb5575 Protected cache, export and feeds menu link. 2016-02-17 15:20:38 +01:00
75332c148d Added protection/permissions. 2016-02-17 12:24:58 +01:00
b54fd85172 Added files module, with for now, a focus on upload files facility.
Contribution from Fabian Murer, as part of an ETH student project.
Supervised, refactorized and merged by Jocelyn Fiat.

Signed-off-by: Fabian Murer <fmurer@student.ethz.ch>
Signed-off-by: Jocelyn Fiat <git@djoce.net>
2016-02-17 12:03:24 +01:00
bc07aad01b Restored iron package name to "roc" 2016-02-12 09:03:56 +01:00
ce4bb551d2 Updated package.iron . 2016-02-04 00:01:32 +01:00
5ceb9d3dd3 Fixed new account admin message.
- the rejection url was badly formatted in the template.
2016-02-03 23:59:55 +01:00
c1a5838320 Fixed auth email messages code and template. 2016-02-03 23:51:20 +01:00
db697cec3e Fixed auth mail template text and code. 2016-02-03 23:33:52 +01:00
892f2331de Do not set destination query parameter to any account/auth url.
Set "site_sign_in_url" and "site_sign_out_url" as variables (so it could be used by template).
2016-02-03 23:16:05 +01:00
3496536751 Added CMS_API.request: WSF_REQUEST to ease dev of ROC CMS code.
- Removed CMS_REQUEST_UTIL
  - centralize a few request related code into CMS_API
Added CMS_API.user, CMS_API.set_user (CMS_USER), ... and user related routines.

Refactored Auth related code
  - added various abstractions to factorize implementation and harmonize solutions.
  - revisited the logout strategy.
  - updated the account info page, and remove info user should not care about.
  - simplified the process, and encourage auth module to follow same design.

Added CMS_LINK helper routines to modify the related query string.
Removed CMS_USER.profile (and related routines)
   - It was not used so far.
   - it will probably a specific module later, if needed.

Update various module to avoid fetching user from sql directly, and let this task to CMS_USER_API.

Removed CMS_NODE_API.node_author (a_node: CMS_NODE): detachable CMS_USER,
   - as the info is already in CMS_NODE.author

Added CMS_RESPONSE.redirection_delay, if ever one code want to redirect after a few seconds.
Added the request uri info to the not found cms response.
2016-01-29 21:58:49 +01:00
41ac45d07b Fixed various CMS_MODULE.install, by not marked module installed if an error occurred!
Improved Auth related module implementation by having a way to change settings like token, max age.
  - use CMS_SETUP.site_id and related "auth.$module.token" ... configuration values.
  - removed related CMS_..._CONSTANTS classes.

For auth session module, use auth_session as table name, and use VARCHAR(64).
Extracted sql from blog module, and store it under site/scripts/install.sql .
Renamed a few $modulename.sql as install.sql
2016-01-27 18:22:20 +01:00
d3b485f4d3 Removed unused local variable. 2016-01-22 22:19:24 +01:00
2b1d5f9693 Updated to new routine type. 2016-01-22 21:41:56 +01:00
59c03c5f4d Added CMS_STRING_EXPANDER.
For now with basic implementation.
  It will be improved later

Added SEO related attribute in CMS_RESPONSE.
Added improved Contact module.
Added basic SEO module.
2016-01-22 21:33:06 +01:00
39ab19d20e Eiffel code and ECFs update to support new agent notations.
Accepts /account and /account/ .
2016-01-19 16:15:13 +01:00
fd5e396b72 Code cleaning. 2016-01-15 18:35:53 +01:00
5bd28326c2 Added source for sql scripts. 2016-01-15 17:59:21 +01:00
eef2a52f48 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.
2016-01-15 17:46:56 +01:00
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
a013efd6f7 Cosmetic in DEMO_CMS_EXECUTION
Removed persistence/mysql which is not used.
2016-01-15 13:30:07 +01:00
jvelilla
2f95c66295 Removed unneeded template
Updated Sql sentence.
2016-01-14 08:39:35 -03:00
f6885ff581 remove roc.exe 2016-01-13 22:05:49 +01: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
a179ee3239 Reverted executable name to "demo" 2016-01-13 10:38:27 +01:00
ed0d9c8d07 Use {CMS_LOG}.level_notice and related constant when using api.log(..) 2016-01-12 16:14:54 +01:00
67fbee737d Keep only sqlite3 persistence as default.
To include mysql and other, uncomment related code in demo-safe.ecf and demo_cms_execution.
2016-01-12 16:14:18 +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
56b9355f3c Updated email messaging of Auth modules to use the CMS_API.process_email (..) system.
as a consequence, removed usage of email_service library.
Updated the meaning for site.email to be sender email addressed.
Added notification.email to set the email address that will received system email notification.
2016-01-08 22:24:52 +01: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
0813abe0bb Fixed ROC CMS library compilation. 2015-12-18 15:29:43 +01:00
1094acb3ec Removed unused local variable 2015-12-16 21:05:57 +01:00
e7c9a54f3f Removed unused local. 2015-12-16 21:03:15 +01:00
bbbdac12c8 Moved taxonomy html generation to CMS_TAXONOMY_API. 2015-12-16 21:03:03 +01:00
jvelilla
22528315cb Removed unneeded file. 2015-12-16 16:01:02 +01:00
jvelilla
090a48eb85 Updated class CMS_TOKEN_GENERATOR.
Remove once in sha1 feature.
Updated encoded_base_64 to base_64
2015-12-16 16:01:01 +01:00
jvelilla
e05c4dca3a Fixed typos
Renamed class CMS_SESSION_CONSTANT to CMS_SESSION_CONSTANTS
Removed unneeded classes and files.
Update SQL implementation.
2015-12-16 16:00:59 +01:00
jvelilla
2255fcc0f6 Added Module Session Authentication with Cookies.
Updated Demo example with the Module Session (Authentication with Cookies)
Fixed little issue with SQL query in OpenID module.
2015-12-16 16:00:58 +01:00
e50fb6959e Moved taxonomy integration for web form inside CMS_TAXONOMY_API.
Moved a few helpers routine from CMS_RESPONSE to CMS_API.
Added CMS_CONTENT.identifier: detachable READABLE_STRING_32 .
2015-12-16 15:59:22 +01:00
jvelilla
3b88c746a1 Removed unneeded file. 2015-12-16 10:43:21 -03:00
jvelilla
fa8ef44a4a Merge branch 'jvelilla-roc_login_session' 2015-12-16 10:11:55 -03:00
jvelilla
068943734f Updated class CMS_TOKEN_GENERATOR.
Remove once in sha1 feature.
Updated encoded_base_64 to base_64
2015-12-16 10:03:35 -03:00
jvelilla
089179e60e Fixed typos
Renamed class CMS_SESSION_CONSTANT to CMS_SESSION_CONSTANTS
Removed unneeded classes and files.
Update SQL implementation.
2015-12-15 15:32:31 -03:00
jvelilla
c25590c9cd Added Module Session Authentication with Cookies.
Updated Demo example with the Module Session (Authentication with Cookies)
Fixed little issue with SQL query in OpenID module.
2015-12-13 18:19:25 -03:00
234 changed files with 17509 additions and 3049 deletions

View File

@@ -1,11 +1,11 @@
<?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="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<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="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>

View File

@@ -1,12 +1,12 @@
<?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="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<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="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<description>ROC CMS library</description>
<target name="cms">
<root all_classes="true"/>
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true" full_class_checking="false" void_safety="none" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>

View File

@@ -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">
@@ -23,30 +24,32 @@
<library name="cms_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
<library name="cms_basic_auth_module" location="..\..\modules\basic_auth\basic_auth-safe.ecf" readonly="false"/>
<library name="cms_blog_module" location="..\..\modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
<library name="cms_contact_module" location="..\..\modules\contact\contact-safe.ecf" readonly="false"/>
<library name="cms_custom_block_module" location="..\..\modules\custom_block\custom_block-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/>
<library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator-safe.ecf" readonly="false"/>
<library name="cms_files_module" location="..\..\modules\files\files-safe.ecf" readonly="false"/>
<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_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="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3-safe.ecf" readonly="false">
<option>
<assertions/>
</option>
</library>
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf"/>
<library name="cms_seo_module" location="..\..\modules\seo\seo-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"/>
<!--
By default, commented, since it depends on specific environment settings.
<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>
<target name="demo_any" extends="common">
<setting name="concurrency" value="thread"/>
<setting name="concurrency" value="scoop"/>
<library name="any_launcher" location="..\..\launcher\any-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>

View File

@@ -1,2 +1,3 @@
port=9090
#port=12345
#verbose=true

View File

@@ -1,3 +1,4 @@
@echo off
setlocal
set ROC_CMD=call %~dp0..\..\tools\roc.bat
set ROC_CMS_DIR=%~dp0
@@ -6,10 +7,15 @@ set ROC_CMS_DIR=%~dp0
%ROC_CMD% install --module ..\..\modules\auth --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\basic_auth --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\blog --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\contact --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\google_search --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\node --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\oauth20 --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\openid --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\recent_changes --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\feed_aggregator --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\google_search --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\seo --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\session_auth --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\taxonomy --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\files --dir %ROC_CMS_DIR%
%ROC_CMD% install --module ..\..\modules\custom_block --dir %ROC_CMS_DIR%

View File

@@ -1,11 +1,11 @@
<?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="cms_demo_module" uuid="4BB59A54-2544-4C10-BFA6-01D12E541A30" library_target="cms_demo_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="cms_demo_module" uuid="4BB59A54-2544-4C10-BFA6-01D12E541A30" library_target="cms_demo_module">
<target name="cms_demo_module">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
@@ -21,4 +21,3 @@
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -70,8 +70,9 @@ CREATE TABLE tb_demo(
api.logger.put_error ("Could not initialize database for demo module", generating_type)
end
end
Precursor {CMS_MODULE}(api)
end
-- For this demo, be flexible, and do not required sql.
Precursor {CMS_MODULE}(api)
end
feature -- Access: router
@@ -151,7 +152,7 @@ feature -- Mapping helper: uri template
feature -- Mapping helper: uri template agent
map_uri_template_agent (a_router: WSF_ROUTER; a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_REQUEST_METHODS)
map_uri_template_agent (a_router: WSF_ROUTER; a_tpl: READABLE_STRING_8; proc: PROCEDURE [WSF_REQUEST, WSF_RESPONSE]; rqst_methods: detachable WSF_REQUEST_METHODS)
-- Map `proc' as handler for `a_tpl' for request methods `rqst_methods'.
require
a_tpl_attached: a_tpl /= Void

View File

@@ -2,8 +2,8 @@
#navigation.region=sidebar_first
#navigation.condition=is_front
management.conditions[]=path:admin*
management.conditions[]=is_front
#management.conditions[]=path:admin*
#management.conditions[]=is_front
#Feeds
feed.news.weight=3

View File

@@ -4,14 +4,37 @@ root-dir=site/www
#modules-dir=site/modules
[site]
# General token that could be use for cookies, and related.
id=_EIFFEL_CMS_
#debug=true
# Name of the site, for the title, and eventual message.
name=Eiffel CMS
email=your@email.com
# Properties used for SEO.
property[headline]=Eiffel CMS -- the demo
property[description]=Demo for Eiffel ROC CMS.
property[keywords]=eiffel,cms,demo
# 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
@@ -25,6 +48,14 @@ output=@stderr
[blocks]
@include=blocks.ini
[auth]
# token, default is $site.id or built-in.
#token=_ROC_AUTH_TOKEN_
#session.token=
#session.max_age=86400
#openid.token=
#oauth.token=
[admin]
# CMS Installation, are accessible by "all", "none" or uppon "permission". (default is none)
installation_access=all

View File

@@ -0,0 +1,12 @@
{
"subject": "Thank you for contacting us",
"forms": {
"registration": {
"application_description": "Present yourself in a few lines, otherwise your application is likely to be rejected."
}
},
"recaptcha": {
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
"secret_key":"6Lex9RMTAAAAAAkBczvX5DUiyg_xoM_EthVVgRRx"
}
}

View File

@@ -0,0 +1,28 @@
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] ";
}

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

@@ -4,15 +4,10 @@
<meta charset="utf-8">
<title>Activation</title>
<meta name="description" content="Activation">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>Thank you for registering at <a href="$host">ROC CMS</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>Thank you for joining us.</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>

View File

@@ -0,0 +1,13 @@
<!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 "$user ($email)" is confirmed at <a href="$host">$sitename</a>.</p>
<p>Thank you for joining us.</p>
</body>
</html>

View File

@@ -4,14 +4,12 @@
<meta charset="utf-8">
<title>New Password</title>
<meta name="description" content="New Password">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>You have required a new password at <a href="$host">ROC CMS</a></p>
<p>To complete your request, please click on this link to genereate 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>

View File

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

View File

@@ -0,0 +1,12 @@
<!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>Your account application is rejected, it was not respecting the requirements from <a href="$host">$sitename</a>.</p>
</body>
</html>

View File

@@ -4,10 +4,16 @@
<meta charset="utf-8">
<title>Welcome</title>
<meta name="description" content="Welcome">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>Welcome to<a href="$host">ROC CMS</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>

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 @@
{include file="block_account_info.tpl" /}

View File

@@ -1,62 +1,34 @@
<div class="primary-tabs">
{if isset="$user"}
<h3>Account Information</h3>
<div>
<div>
<div>
<label>Username:</label> {$user.name/}
</div>
<div>
<label>Email:</label> {$user.email/}
</div>
<div>
<label>Creation Date:</label> {$user.creation_date/}
</div>
<div>
<label>Last login:</label> {$user.last_login_date/}
</div>
<div>
<form method="get" action="{$site_url/}{$auth_login_strategy/}">
<button type="submit">Logout</button>
</form>
</div>
<ul class="user-information">
<div>
<label>Username:</label> {$user.name/}
</div>
</div>
<hr>
{include file="block_change_password.tpl" /}
<hr>
<h4>Roles</h4>
<div>
{foreach item="ic" from="$roles"}
<div>
<ul>
<li>
<strong>{$ic.name/}</strong>
<ul>
<li> <i>permissions</i>
<ul>
{foreach item="ip" from="$ic.permissions"}
<li>{$ip/}</li>
{/foreach}
</ul>
</li>
</ul>
</li>
</ul>
</div>
{/foreach}
</div>
<div>
<label>Email:</label> {$user.email/}
</div>
<div>
<label>Creation Date:</label> {$user.creation_date/} (UTC)
</div>
<div>
<label>Last login:</label> {$user.last_login_date/} (UTC)
</div>
<div>
<form method="get" action="{$site_url/}account/roc-logout">
<button type="submit">Logout</button>
</form>
</div>
</ul>
<hr>
<h4>Profile</h4>
<div>
<ul class="user-profile">
{foreach item="the_value" key="the_name" from="$user.profile"}
<div>
<label>{$the_name/}:</label> {$the_value/}
</div>
<li>
<label>{$the_name/}:</label><div>{$the_value/}</div>
</li>
{/foreach}
</div>
</ul>
{/if}
{unless isset="$user"}
<div>

View File

@@ -1,7 +1,7 @@
<div>
<form action="{$site_url/}account/change-password" method="post">
<fieldset>
<legend>Change Password Form</legend>
<legend>Change Password</legend>
<div>
<input type="password" id="password" name="password" value="" required/>
<label for="password">Password</label>

View File

@@ -1,29 +0,0 @@
<div class="primary-tabs">
{unless isset="$user"}
<h3>Login or <a href="{$site_url/}account/roc-register">Register</a></h3>
<div>
<div>
<form action method="POST">
<div>
<input type="text" name="username" required>
<label>Username</label>
</div>
<div>
<input type="password" name="password" required>
<label>Password</label>
</div>
<button type="button" onclick="ROC_AUTH.login();">Login</button>
</form>
</div>
</div>
<div>
<div>
<p>
<a href="{$site_url/}account/new-password">Forgot password?</a>
</p>
</div>
</div>
{/unless}
</div>

View File

@@ -1,3 +1,3 @@
<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>

View File

@@ -1,3 +1,3 @@
<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>

View File

@@ -1,28 +1,38 @@
<div>
<form action="{$site_url/}account/roc-register" method="post">
<fieldset>
<legend>Register Form</legend>
<div>
<input type="text" id="name" name="name" value="{$name/}" required autofocus />
<label for="name">Name</label>
{if isset="$error_name"}
<span><i>{$error_name/}</i></span> <br>
{/if}
</div>
<div>
<input type="password" id="password" name="password" value="" required/>
<label for="password">Password</label>
</div>
<div>
<input type="email" id="email" name="email" value="{$email/}" required/>
<label for="email">Email</label>
{if isset="$error_email"}
<span><i>{$error_email/}</i></span> <br>
{/if}
</div>
<button type="submit">Register</button>
</fieldset>
</form>
<div>
<form action="{$site_url/}account/roc-register" method="post">
<fieldset>
<legend>Registration</legend>
<div>
<input type="text" id="name" name="name" value="{$name/}" required autofocus />
<label for="name">Name</label>
{if isset="$error_name"}
<span><i>{$error_name/}</i></span> <br>
{/if}
</div>
<div>
<input type="password" id="password" name="password" value="" required/>
<label for="password">Password</label>
</div>
<div>
<input type="email" id="email" name="email" value="{$email/}" required/>
<label for="email">Email</label>
{if isset="$error_email"}
<span><i>{$error_email/}</i></span> <br/>
{/if}
</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}
{if isset="$application_description"}
<br/>
<p class="description">{$application_description/}</p>
{/if}
</div>
{unless isempty="$recaptcha_site_key"}<div class="g-recaptcha" data-sitekey="{$recaptcha_site_key/}"></div><br/>{/unless}
<button type="submit">Register</button>
</fieldset>
</form>
</div>

View File

@@ -1,307 +1,291 @@
var ROC_AUTH = ROC_AUTH || { };
var loginURL = "/basic_auth_login";
var logoutURL = "/basic_auth_logoff";
var loginURL = "/roc-basic-login";
var logoutURL = "/roc-basic-logoff";
var userAgent = navigator.userAgent.toLowerCase();
var firstLogIn = true;
ROC_AUTH.login = function() {
var form = document.forms['cms_basic_auth'];
var username = form.username.value;
var password = form.password.value;
//var host = form.host.value;
var form = document.forms['cms_basic_auth'];
var username = form.username.value;
var password = form.password.value;
//var host = form.host.value;
var origin = window.location.origin + window.location.pathname;
var _login = function(){
var _login = function(){
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".login-box").append(newdiv);
}
}else{
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", loginURL, true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status==200) {
delete form;
window.location=window.location.origin;
} else {
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
// .. ?
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".login-box").append(newdiv);
}
}
}
}
}
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".primary-tabs").append(newdiv);
}
}else{
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", loginURL, true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status==200) {
delete form;
window.location=window.location.origin;
}
else{
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".primary-tabs").append(newdiv);
}
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1) { //TODO: check version number
if (firstLogIn) {
_login();
} else {
ROC_AUTH.logoff(_login);
}
} else {
_login();
}
}
}
}
}
}
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
if (firstLogIn) _login();
else logoff(_login);
}
else{
_login();
}
if (firstLogIn) firstLogIn = false;
if (firstLogIn) {
firstLogIn = false;
}
};
ROC_AUTH.login_with_redirect = function() {
var form = document.forms[2];
var username = form.username.value;
var password = form.password.value;
var host = form.host.value;
var _login = function(){
var form = document.forms[2];
var username = form.username.value;
var password = form.password.value;
var host = form.host.value;
var _login = function(){
var redirectURL = form.redirect && form.redirect.value || "";
$("#imgProgressRedirect").show();
var redirectURL = form.redirect && form.redirect.value || "";
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".login-box").append(newdiv);
$("#imgProgressRedirect").hide();
}
} else {
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host + loginURL, true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status==200) {
if (redirectURL === "") {
window.location=host + "/";
} else {
window.location=host + redirectURL;
}
} else{
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".login-box").append(newdiv);
$("#imgProgressRedirect").hide();
}
}
}
}
}
}
$("#imgProgressRedirect").show();
if (document.getElementById('myModalFormId') !== null ) {
ROC_AUTH.remove ('myModalFormId');
}
if (username === "" || password === "") {
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".primary-tabs").append(newdiv);
$("#imgProgressRedirect").hide();
}
}else{
//Instantiate HTTP Request
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host.concat(loginURL), true, username, password);
request.send(null);
//Process Response
request.onreadystatechange = function(){
if (request.readyState == 4) {
if (request.status==200) {
if (redirectURL === "") {
window.location=host.concat("/");
} else {
window.location=host.concat(redirectURL);
}
}
else{
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
}
if (document.getElementById('myModalFormId') === null ) {
var newdiv = document.createElement('div');
newdiv.innerHTML = "<br>Invalid Credentials</br>";
newdiv.id = 'myModalFormId';
$(".primary-tabs").append(newdiv);
$("#imgProgressRedirect").hide();
}
}
}
}
}
}
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
if (firstLogIn) _login();
else logoff(_login);
}
else{
_login();
}
if (firstLogIn) firstLogIn = false;
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
if (firstLogIn) {
_login();
} else {
ROC_AUTH.logoff(_login);
}
} else{
_login();
}
if (firstLogIn) {
firstLogIn = false;
}
};
ROC_AUTH.getQueryParameterByName = function (name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? " " : decodeURIComponent(results[1].replace(/\+/g, " "));
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search);
return results === null ? " " : decodeURIComponent(results[1].replace(/\+/g, " "));
}
ROC_AUTH.logoff = function(callback){
var form = document.forms[0];
var host = form.host.value;
if (userAgent.indexOf("msie") != -1) {
document.execCommand("ClearAuthenticationCache");
}
else if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
var request1 = new XMLHttpRequest();
var request2 = new XMLHttpRequest();
//Logout. Tell the server not to return the "WWW-Authenticate" header
request1.open("GET", host.concat(logoutURL) + "?prompt=false", true);
request1.send("");
request1.onreadystatechange = function(){
if (request1.readyState == 4) {
//Sign in with dummy credentials to clear the auth cache
request2.open("GET", host.concat(logoutURL), true, "logout", "logout");
request2.send("");
request2.onreadystatechange = function(){
if (request2.readyState == 4) {
if (callback!=null) { callback.call(); } else { window.location=host.concat(logoutURL);}
}
}
}
}
}
else {
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host.concat(logoutURL), true, "logout", "logout");
request.send("");
request.onreadystatechange = function(){
if (request.status==401 || request.status==403 ) { window.location=host.concat(logoutURL);
}
}
}
var form = document.forms[0];
var host = form.host.value;
if (userAgent.indexOf("msie") != -1) {
document.execCommand("ClearAuthenticationCache");
} else if (userAgent.indexOf("firefox") != -1){ //TODO: check version number
var request1 = new XMLHttpRequest();
var request2 = new XMLHttpRequest();
//Logout. Tell the server not to return the "WWW-Authenticate" header
request1.open("GET", host + logoutURL + "?prompt=false", true);
request1.send("");
request1.onreadystatechange = function(){
if (request1.readyState == 4) {
//Sign in with dummy credentials to clear the auth cache
request2.open("GET", host + logoutURL, true, "logout", "logout");
request2.send("");
request2.onreadystatechange = function(){
if (request2.readyState == 4) {
if (callback!=null) {
callback.call();
} else {
window.location=host + logoutURL;
}
}
}
}
}
} else {
var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
request.open("GET", host + logoutURL, true, "logout", "logout");
request.send("");
request.onreadystatechange = function(){
if (request.status==401 || request.status==403 ) {
window.location=host + logoutURL;
}
}
}
};
ROC_AUTH.remove = function (id)
{
var element = document.getElementById(id);
element.outerHTML = "";
delete element;
return;
ROC_AUTH.remove = function (id) {
var element = document.getElementById(id);
element.outerHTML = "";
delete element;
return;
};
$(document).ready(function() {
if (typeof String.prototype.contains != 'function') {
String.prototype.contains = function (str){
return this.indexOf(str) != -1;
};
}
ROC_AUTH.progressive_loging();
if (typeof String.prototype.contains != 'function') {
String.prototype.contains = function (str){
return this.indexOf(str) != -1;
};
}
ROC_AUTH.progressive_loging();
});
ROC_AUTH.progressive_loging = function () {
ROC_AUTH.login_href();
ROC_AUTH.login_href();
};
$(document).keypress(function(e) {
if ((e.which === 13) && (e.target.localName === 'input' && e.target.id === 'password')) {
ROC_AUTH.login();
}
if ((e.which === 13) && (e.target.localName === 'input' && e.target.id === 'password')) {
ROC_AUTH.login();
}
});
ROC_AUTH.OnOneClick = function(event) {
event.preventDefault();
if ( document.forms[0] === undefined ) {
ROC_AUTH.create_form();
}
return false;
event.preventDefault();
if ( document.forms[0] === undefined ) {
ROC_AUTH.create_form();
}
return false;
};
ROC_AUTH.login_href = function() {
var els = document.getElementsByTagName("a");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
if (el.href.contains("/basic_auth_login?destination")) {
loginURL = el.href;
var OneClick = el;
OneClick.addEventListener('click', ROC_AUTH.OnOneClick, false);
}
}
var els = document.getElementsByTagName("a");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
if (el.href.contains(loginURL + "?destination")) {
// loginURL = el.href;
var OneClick = el;
OneClick.addEventListener('click', ROC_AUTH.OnOneClick, false);
}
}
};
ROC_AUTH.create_form = function() {
// Fetching HTML Elements in Variables by ID.
var createform = document.createElement('form'); // Create New Element Form
createform.setAttribute("action", ""); // Setting Action Attribute on Form
createform.setAttribute("method", "post"); // Setting Method Attribute on Form
$("body").append(createform);
// Fetching HTML Elements in Variables by ID.
var createform = document.createElement('form'); // Create New Element Form
createform.setAttribute("action", ""); // Setting Action Attribute on Form
createform.setAttribute("method", "post"); // Setting Method Attribute on Form
$("body").append(createform);
var heading = document.createElement('h2'); // Heading of Form
heading.innerHTML = "Login Form ";
createform.appendChild(heading);
var heading = document.createElement('h2'); // Heading of Form
heading.innerHTML = "Login Form ";
createform.appendChild(heading);
var line = document.createElement('hr'); // Giving Horizontal Row After Heading
createform.appendChild(line);
var line = document.createElement('hr'); // Giving Horizontal Row After Heading
createform.appendChild(line);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var namelabel = document.createElement('label'); // Create Label for Name Field
namelabel.innerHTML = "Username : "; // Set Field Labels
createform.appendChild(namelabel);
var namelabel = document.createElement('label'); // Create Label for Name Field
namelabel.innerHTML = "Username : "; // Set Field Labels
createform.appendChild(namelabel);
var inputelement = document.createElement('input'); // Create Input Field for UserName
inputelement.setAttribute("type", "text");
inputelement.setAttribute("name", "username");
inputelement.setAttribute("required","required");
createform.appendChild(inputelement);
var inputelement = document.createElement('input'); // Create Input Field for UserName
inputelement.setAttribute("type", "text");
inputelement.setAttribute("name", "username");
inputelement.setAttribute("required","required");
createform.appendChild(inputelement);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var linebreak = document.createElement('br');
createform.appendChild(linebreak);
var passwordlabel = document.createElement('label'); // Create Label for Password Field
passwordlabel.innerHTML = "Password : ";
createform.appendChild(passwordlabel);
var passwordlabel = document.createElement('label'); // Create Label for Password Field
passwordlabel.innerHTML = "Password : ";
createform.appendChild(passwordlabel);
var passwordelement = document.createElement('input'); // Create Input Field for Password.
passwordelement.setAttribute("type", "password");
passwordelement.setAttribute("name", "password");
passwordelement.setAttribute("id", "password");
passwordelement.setAttribute("required","required");
createform.appendChild(passwordelement);
var passwordelement = document.createElement('input'); // Create Input Field for Password.
passwordelement.setAttribute("type", "password");
passwordelement.setAttribute("name", "password");
passwordelement.setAttribute("id", "password");
passwordelement.setAttribute("required","required");
createform.appendChild(passwordelement);
var passwordbreak = document.createElement('br');
createform.appendChild(passwordbreak);
var passwordbreak = document.createElement('br');
createform.appendChild(passwordbreak);
var submitelement = document.createElement('button'); // Append Submit Button
submitelement.setAttribute("type", "button");
submitelement.setAttribute("onclick", "ROC_AUTH.login();");
submitelement.innerHTML = "Sign In ";
createform.appendChild(submitelement);
var submitelement = document.createElement('button'); // Append Submit Button
submitelement.setAttribute("type", "button");
submitelement.setAttribute("onclick", "ROC_AUTH.login();");
submitelement.innerHTML = "Sign In ";
createform.appendChild(submitelement);
};
@@ -310,16 +294,16 @@ var password = document.getElementById("password");
var confirm_password = document.getElementById("confirm_password");
ROC_AUTH.validatePassword =function(){
if ((password != null) && (confirm_password != null)) {
if(password.value != confirm_password.value) {
confirm_password.setCustomValidity("Passwords Don't Match");
} else {
confirm_password.setCustomValidity('');
}
}
if ((password != null) && (confirm_password != null)) {
if(password.value != confirm_password.value) {
confirm_password.setCustomValidity("Passwords Don't Match");
} else {
confirm_password.setCustomValidity('');
}
}
}
if ((password != null) && (confirm_password != null)) {
password.onchange = ROC_AUTH.validatePassword();
confirm_password.onkeyup = ROC_AUTH.validatePassword;
password.onchange = ROC_AUTH.validatePassword();
confirm_password.onkeyup = ROC_AUTH.validatePassword;
}

View File

@@ -1,29 +1,23 @@
<div class="primary-tabs">
{unless isset="$user"}
<h3>Login or <a href="{$site_url/}account/roc-register">Register</a></h3>
{unless isset="$user"}
<div class="login-box">
<div class="description">The "Basic Auth" relies on the HTTP basic access authentication.<br/>(see also: <a href="https://en.wikipedia.org/wiki/Basic_access_authentication">https://en.wikipedia.org/wiki/Basic_access_authentication</a> )</div>
<h3>Login or <a href="{$site_url/}account/roc-register">Register</a></h3>
<div>
<div>
<form name="cms_basic_auth" action method="POST">
<div>
<input type="text" name="username" id="username" required>
<label>Username</label>
</div>
<div>
<input type="password" name="password" id="password" required>
<label>Password</label>
</div>
<button type="button" onclick="ROC_AUTH.login();">Login</button>
</form>
</div>
<form name="cms_basic_auth" action="{$site_url/}roc-basic-login" method="POST">
<input type="hidden" name="host" id="host" value="{$site_url/}">
<div>
<input type="text" name="username" id="username" required>
<label>Username</label>
</div>
<div>
<input type="password" name="password" id="password" required>
<label>Password</label>
</div>
<button type="button" onclick="ROC_AUTH.login();">Login</button>
</form>
</div>
<div>
<div>
<p>
<a href="{$site_url/}account/new-password">Forgot password?</a>
</p>
</div>
<a href="{$site_url/}account/new-password">Forgot password?</a>
</div>
{/unless}
</div>
{/unless}

View File

@@ -0,0 +1,6 @@
CREATE TABLE blog_post_nodes(
`nid` INTEGER NOT NULL CHECK("nid">=0),
`revision` INTEGER NOT NULL,
`tags` VARCHAR(255),
CONSTRAINT PK_nid_revision PRIMARY KEY (nid,revision)
);

View File

@@ -0,0 +1,8 @@
{
"--email": "webmaster@example.com",
"subjet": "Thank you for contacting us",
"recaptcha": {
"site_key":"",
"secret_key":""
}
}

View File

@@ -0,0 +1,124 @@
.contact-box {
background-color: #F2F7F9;
width: 465px;
padding: 20px;
border: 6px solid #8FB5C1;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
border-radius: 15px;
position: relative;
/* Remove box shadow firefox, chrome and opera put around required fields.
* It looks rubbish.
*/
/* Normalize placeholder styles */
/* chrome, safari */
/* mozilla */
/* ie (faux placeholder) */
}
.contact-box h1 {
font-size: 42px;
}
.contact-box h2 {
margin-bottom: 15px;
font-style: italic;
font-weight: normal;
}
.contact-box label {
font-size: 15px;
margin-bottom: 2px;
display: block;
}
.contact-box input, .contact-box select, .contact-box textarea {
width: 100%;
font-size: 15px;
border: 1px solid #CEE1E8;
margin-bottom: 20px;
padding: 4px;
}
.contact-box input:focus, .contact-box select:focus, .contact-box textarea:focus {
border: 1px solid #AFCDD8;
background-color: #EBF2F4;
}
.contact-box textarea {
height: 150px;
resize: none;
}
.contact-box span.required {
font-weight: bold;
color: #F00;
}
.contact-box input[type=submit] {
width: 100px;
background-color: #333;
color: #FFF;
border: none;
display: block;
float: right;
margin-bottom: 0px;
margin-right: 6px;
background-color: #8FB5C1;
-moz-border-radius: 8px;
}
.contact-box input[type=submit]:hover {
background-color: #A6CFDD;
}
.contact-box input[type=submit]:active {
position: relative;
top: 1px;
}
.contact-box .message {
width: 95%;
margin: 25px 0px;
padding: 10px;
display: block;
border: solid 1px #ccc;
border-radius: 8px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
}
.contact-box .message.hidden {
display: none;
}
.contact-box .message.error {
border-color: #E58E8E;
background-color: #FFE6E6;
}
.contact-box .message.error li {
padding: 2px;
list-style: none;
}
.contact-box .message.error li:before {
content: ' - ';
}
.contact-box .message.error #info {
font-weight: bold;
}
.contact-box .message.error #info:before {
content: '';
}
.contact-box .message.success {
border-color: #83D186;
padding-top: 25px;
background-color: #D3EDD3;
}
.contact-box .req-field-desc {
font-style: italic;
}
.contact-box input:required, .contact-box textarea:required {
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
box-shadow: none;
}
.contact-box ::-webkit-input-placeholder {
color: #CCC;
font-style: italic;
}
.contact-box input:-moz-placeholder, .contact-box textarea:-moz-placeholder {
color: #CCC;
font-style: italic;
}
.contact-box input.placeholder-text, .contact-box textarea.placeholder-text {
color: #CCC;
font-style: italic;
}

View File

@@ -0,0 +1,140 @@
.contact-box {
background-color:#F2F7F9;
width:465px;
padding:20px;
border: 6px solid #8FB5C1;
-moz-border-radius:15px;
-webkit-border-radius:15px;
border-radius:15px;
position:relative;
h1 {
font-size:42px;
}
h2 {
margin-bottom:15px;
font-style:italic;
font-weight:normal;
}
label {
font-size:15px;
margin-bottom:2px;
display:block;
}
input, select, textarea {
width:100%;
font-size:15px;
border: 1px solid #CEE1E8;
margin-bottom:20px;
padding:4px;
&:focus {
border: 1px solid #AFCDD8;
background-color: #EBF2F4;
}
}
textarea {
height:150px;
resize: none;
}
span.required {
font-weight:bold;
color:#F00;
}
input[type=submit] {
width: 100px;
background-color:#333;
color:#FFF;
border:none;
display:block;
float:right;
margin-bottom:0px;
margin-right:6px;
background-color:#8FB5C1;
-moz-border-radius:8px;
&:hover {
background-color: #A6CFDD;
}
&:active {
position:relative;
top:1px;
}
}
.message {
width:95%;
margin:25px 0px;
padding:10px;
display:block;
border:solid 1px #ccc;
border-radius:8px;
-webkit-border-radius:8px;
-moz-border-radius:8px;
&.hidden {
display: none;
}
&.error {
border-color: #E58E8E;
background-color:#FFE6E6;
li {
padding:2px;
list-style:none;
&:before { content: ' - '; }
}
#info {
font-weight:bold;
&:before { content: ''; }
}
}
&.success {
border-color: #83D186;
padding-top: 25px;
background-color:#D3EDD3;
}
}
.req-field-desc {
font-style:italic;
}
/* Remove box shadow firefox, chrome and opera put around required fields.
* It looks rubbish.
*/
input:required, textarea:required {
-moz-box-shadow:none;
-webkit-box-shadow:none;
-o-box-shadow:none;
box-shadow:none;
}
/* Normalize placeholder styles */
/* chrome, safari */
::-webkit-input-placeholder {
color:#CCC;
font-style:italic;
}
/* mozilla */
input:-moz-placeholder, textarea:-moz-placeholder {
color:#CCC;
font-style:italic;
}
/* ie (faux placeholder) */
input.placeholder-text, textarea.placeholder-text {
color:#CCC;
font-style:italic;
}
}

View File

@@ -0,0 +1,25 @@
<div class="contact-box clearfix">
<h1>Contact us!</h1>
<form method="post" action="{$site_url/}contact" id="contact-form">
<label for="name">Name: <span class="required">*</span></label>
<input type="text" id="name" name="name" value="{$name/}" required="required" autofocus="autofocus" />
<label for="email">Email Address: <span class="required">*</span></label>
<input type="email" id="email" name="email" value="{$email/}" required="required" />
<label for="message">Message: <span class="required">*</span></label>
<textarea id="message" name="message" required="required" data-minlength="20" minlength="20" >{$message/}</textarea>
{unless isempty="$recaptcha_site_key"}
<div class="g-recaptcha" data-sitekey="{$recaptcha_site_key/}"></div>
<br/>
{/unless}
<input type="submit" value="Send" class="submit-button" />
<p class="req-field-desc"><span class="required">*</span> indicates a required field</p>
</form>
{unless isempty="$error_response"}
<ul class="message error">
{foreach item="item" from="$error_response"}<li class="info">{$item/}</li>{/foreach}
</ul>
<div class="notice"> Try again later </div>
{/unless}
</div>

View File

@@ -0,0 +1,15 @@
<div class="contact-box">
{if condition="$has_error"}
<div class="message error">
<strong>Internal Server Error <small>Error 500</small></strong>
<p>The page you requested could not be served because the server is down,
either contact the webmaster or try again.
Use your browser's <strong>Back</strong> button to navigate to the page you came from.</p>
<p><strong>Or you could just press this link:</strong> <a href="{$site_url/}" itemprop="home" rel="home">Take Me Home</a></p>
</div>
{/if}
{unless condition="$has_error"}
<p class="message success">Thank you for contacting the Eiffel Programming Language community.<br/>
We will get back to you promptly on your contact request.</p>
{/unless}
</div>

View File

@@ -0,0 +1,10 @@
<p>
Thank you for contacting {$sitename/}.<br/>
We will get back to you promptly about your contact message.
</p>
<h2>Your contact information:</h2>
<div>
<strong>Name<strong>: {$name/} <br/>
<strong>Email<strong>: {$email/} <br/>
<strong>Message<strong>: {$message/} <br/>
</div>

View File

@@ -0,0 +1,6 @@
<h2>Contact information:</h2>
<div>
<strong>Name<strong>: {$name/}<br/>
<strong>Email<strong>: {$email/} <br/>
<strong>Message<strong>: {$message/} <br/>
</div>

View File

@@ -0,0 +1,10 @@
{
"blocks": {
"test": {
"title": "Custom block test",
"region": "footer",
"weight": 100,
"conditions": ["path:demo/*"]
}
}
}

View File

@@ -0,0 +1,3 @@
<div>
This is a nice custom block test for site {$sitename/}.
</div>

View File

@@ -0,0 +1,52 @@
.uploaded-files table {
width: 100%;
border-collapse: collapse;
border: 1px solid black;
}
.uploaded-files table th {
padding: 3px 0 3px 5px;
}
.uploaded-files table td {
padding: 3px 0 3px 5px;
}
.uploaded-files a.button {
color: black;
text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
}
.uploaded-files a.button:hover {
color: black;
border: solid 1px #06f;
background-color: #cff;
}
.upload-files .center {
text-align: center;
padding: 10px;
}
.upload-files a.button {
margin: auto;
width: 100px;
color: black;
text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
}
.upload-files a.button:hover {
color: black;
border: solid 1px #06f;
background-color: #cff;
}
/******************* Drop Zone *******************/
.dropzone {
width: 100%;
border: 2px dashed blue;
border-radius: 3px;
text-align: center;
padding-top: 15px;
padding-bottom: 15px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
position: relative;
.dz-preview {
position: relative;
display: inline-block;
width: 120px;
margin: 0.5em;
.dz-progress {
display: block;
height: 15px;
border: 1px solid #aaa;
.dz-upload {
display: block;
height: 100%;
width: 0;
background: green;
}
}
.dz-error-message {
color: red;
display: none;
}
&.dz-error {
.dz-error-message, .dz-error-mark {
display: block;
}
}
&.dz-success {
.dz-success-mark {
display: block;
}
}
.dz-error-mark, .dz-success-mark {
position: absolute;
display: none;
left: 30px;
top: 30px;
width: 54px;
height: 58px;
left: 50%;
margin-left: -(54px/2);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,413 @@
/*
* The MIT License
* Copyright (c) 2012 Matias Meno <m@tias.me>
*/
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
@mixin keyframes($name) {
@-webkit-keyframes #{$name} {
@content;
}
@-moz-keyframes #{$name} {
@content;
}
@keyframes #{$name} {
@content;
}
}
@mixin prefix($map, $vendors: webkit moz ms o) {
@each $prop, $value in $map {
@if $vendors {
@each $vendor in $vendors {
#{"-" + $vendor + "-" + $prop}: #{$value};
}
}
// Dump regular property anyway
#{$prop}: #{$value};
}
}
@include keyframes(passing-through) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30%, 70% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
100% {
opacity: 0;
@include prefix((transform: translateY(-40px)));
}
}
@include keyframes(slide-in) {
0% {
opacity: 0;
@include prefix((transform: translateY(40px)));
}
30% {
opacity: 1;
@include prefix((transform: translateY(0px)));
}
}
@include keyframes(pulse) {
0% { @include prefix((transform: scale(1))); }
10% { @include prefix((transform: scale(1.1))); }
20% { @include prefix((transform: scale(1))); }
}
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
$image-size: 120px;
$image-border-radius: 20px;
&.dz-clickable {
cursor: pointer;
* {
cursor: default;
}
.dz-message {
&, * {
cursor: pointer;
}
}
}
min-height: 150px;
border: 2px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 20px 20px;
&.dz-started {
.dz-message {
display: none;
}
}
&.dz-drag-hover {
border-style: solid;
.dz-message {
opacity: 0.5;
}
}
.dz-message {
text-align: center;
margin: 2em 0;
}
.dz-preview {
position: relative;
display: inline-block;
vertical-align: top;
margin: 16px;
min-height: 100px;
&:hover {
// Making sure that always the hovered preview element is on top
z-index: 1000;
.dz-details {
opacity: 1;
}
}
&.dz-file-preview {
.dz-image {
border-radius: $image-border-radius;
background: #999;
background: linear-gradient(to bottom, #eee, #ddd);
}
.dz-details {
opacity: 1;
}
}
&.dz-image-preview {
background: white;
.dz-details {
@include prefix((transition: opacity 0.2s linear));
}
}
.dz-remove {
font-size: 14px;
text-align: center;
display: block;
cursor: pointer;
border: none;
&:hover {
text-decoration: underline;
}
}
&:hover .dz-details {
opacity: 1;
}
.dz-details {
$background-color: #444;
z-index: 20;
position: absolute;
top: 0;
left: 0;
opacity: 0;
font-size: 13px;
min-width: 100%;
max-width: 100%;
padding: 2em 1em;
text-align: center;
color: rgba(0, 0, 0, 0.9);
$width: 120px;
line-height: 150%;
.dz-size {
margin-bottom: 1em;
font-size: 16px;
}
.dz-filename {
white-space: nowrap;
&:hover {
span {
border: 1px solid rgba(200, 200, 200, 0.8);
background-color: rgba(255, 255, 255, 0.8);
}
}
&:not(:hover) {
span {
border: 1px solid transparent;
}
overflow: hidden;
text-overflow: ellipsis;
}
}
.dz-filename, .dz-size {
span {
background-color: rgba(255, 255, 255, 0.4);
padding: 0 0.4em;
border-radius: 3px;
}
}
}
&:hover {
.dz-image {
// opacity: 0.8;
img {
@include prefix((transform: scale(1.05, 1.05))); // Getting rid of that white bleed-in
@include prefix((filter: blur(8px)), webkit); // Getting rid of that white bleed-in
}
}
}
.dz-image {
border-radius: $image-border-radius;
overflow: hidden;
width: $image-size;
height: $image-size;
position: relative;
display: block;
z-index: 10;
img {
display: block;
}
}
&.dz-success {
.dz-success-mark {
@include prefix((animation: passing-through 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
&.dz-error {
.dz-error-mark {
opacity: 1;
@include prefix((animation: slide-in 3s cubic-bezier(0.770, 0.000, 0.175, 1.000)));
}
}
.dz-success-mark, .dz-error-mark {
$image-height: 54px;
$image-width: 54px;
pointer-events: none;
opacity: 0;
z-index: 500;
position: absolute;
display: block;
top: 50%;
left: 50%;
margin-left: -($image-width/2);
margin-top: -($image-height/2);
svg {
display: block;
width: $image-width;
height: $image-height;
}
}
&.dz-processing .dz-progress {
opacity: 1;
@include prefix((transition: all 0.2s linear));
}
&.dz-complete .dz-progress {
opacity: 0;
@include prefix((transition: opacity 0.4s ease-in));
}
&:not(.dz-processing) {
.dz-progress {
@include prefix((animation: pulse 6s ease infinite));
}
}
.dz-progress {
opacity: 1;
z-index: 1000;
pointer-events: none;
position: absolute;
height: 16px;
left: 50%;
top: 50%;
margin-top: -8px;
width: 80px;
margin-left: -40px;
// border: 2px solid #333;
background: rgba(255, 255, 255, 0.9);
// Fix for chrome bug: https://code.google.com/p/chromium/issues/detail?id=157218
-webkit-transform: scale(1);
border-radius: 8px;
overflow: hidden;
.dz-upload {
background: #333;
background: linear-gradient(to bottom, #666, #444);
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 0;
@include prefix((transition: width 300ms ease-in-out));
}
}
&.dz-error {
.dz-error-message {
display: block;
}
&:hover .dz-error-message {
opacity: 1;
pointer-events: auto;
}
}
.dz-error-message {
$width: $image-size + 20px;
$color: rgb(190, 38, 38);
pointer-events: none;
z-index: 1000;
position: absolute;
display: block;
display: none;
opacity: 0;
@include prefix((transition: opacity 0.3s ease));
border-radius: 8px;
font-size: 13px;
top: $image-size + 10px;
left: -10px;
width: $width;
background: $color;
background: linear-gradient(to bottom, $color, darken($color, 5%));
padding: 0.5em 1.2em;
color: white;
// The triangle pointing up
&:after {
content: '';
position: absolute;
top: -6px;
left: $width / 2 - 6px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $color;
}
}
}
}

View File

@@ -0,0 +1,63 @@
.uploaded-files {
table {
width: 100%;
border-collapse: collapse;
border: 1px solid black;
th {
padding: 3px 0 3px 5px;
}
td {
padding: 3px 0 3px 5px;
}
}
a.button{
color: black;
text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover {
color: black;
border: solid 1px #06f;
background-color: #cff;
}
}
}
.upload-files {
.center {
text-align: center;
padding: 10px;
}
a.button{
margin: auto;
width: 100px;
color: black;
text-decoration: none;
border: solid 1px #999;
background-color: #ddd;
padding: 2px 4px 2px 4px;
&:hover {
color: black;
border: solid 1px #06f;
background-color: #cff;
}
}
}
/******************* Drop Zone *******************/
.dropzone {
width: 100%;
border: 2px dashed blue;
border-radius: 3px;
text-align: center;
padding-top: 15px;
padding-bottom: 15px;
}

View File

@@ -3,22 +3,17 @@ ul.cms-nodes {
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_type_page a::before {
content: "[page] ";
}
li.cms_type_blog a::before {
content: "[blog] ";
}
}

View File

@@ -0,0 +1,9 @@
CREATE TABLE auth_session (
`uid` INTEGER PRIMARY KEY NOT NULL CHECK(`uid`>=0),
`access_token` VARCHAR(64) NOT NULL,
`created` DATETIME NOT NULL,
CONSTRAINT `uid` UNIQUE(`uid`),
CONSTRAINT `access_token` UNIQUE(`access_token`)
);

View File

@@ -0,0 +1,23 @@
{unless isset="$user"}
<div class="login-box">
<div class="description">The "Session" is the standard authentication system. (based on cookie)</div>
<h3>Login or <a href="{$site_url/}account/roc-register">Register</a></h3>
<div>
<form name="cms_session_auth" action="{$site_url/}account/auth/roc-session-login" method="POST">
<div>
<input type="text" name="username" id="username" required value="{$username/}">
<label>Username</label>
</div>
<div>
<input type="password" name="password" id="password" required >
<label>Password</label>
</div>
<button type="submit">Login</button>
</form>
</div>
<div>
<a href="{$site_url/}account/new-password">Forgot password?</a>
</div>
{if isset="$error"}<div class="error">{$error/}</div>{/if}
</div>
{/unless}

View File

@@ -46,3 +46,18 @@ CREATE TABLE `users_password_recovery` (
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

@@ -35,60 +35,52 @@ feature -- CMS storage
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_ODBC_BUILDER}.make, "odbc")
-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc")
end
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)
a_setup.register_module (create {CMS_SESSION_AUTH_MODULE}.make)
-- Nodes
create {CMS_NODE_MODULE} m.make (a_setup)
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)
create {CMS_BLOG_MODULE} m.make
a_setup.register_module (m)
-- Files
a_setup.register_module (create {CMS_FILES_MODULE}.make)
-- Contact
a_setup.register_module (create {CMS_CONTACT_MODULE}.make)
-- Misc
a_setup.register_module (create {CMS_SEO_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)
a_setup.register_module (create {GOOGLE_CUSTOM_SEARCH_MODULE}.make)
a_setup.register_module (create {CMS_CUSTOM_BLOCK_MODULE}.make)
a_setup.register_module (create {CMS_DEBUG_MODULE}.make)
a_setup.register_module (create {CMS_DEMO_MODULE}.make)
create {CMS_DEMO_MODULE} m.make
a_setup.register_module (m)
create {GOOGLE_CUSTOM_SEARCH_MODULE} m.make
a_setup.register_module (m)
end
end

View File

@@ -34,7 +34,7 @@ feature -- Query
end
resolved_text_list_item (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32]
-- List of String item associated with key `k',
-- List of String items associated with key `k',
-- and expanded values to resolved variables ${varname}.
do
if attached text_list_item (k) as lst then
@@ -50,7 +50,7 @@ feature -- Query
end
resolved_text_table_item (k: READABLE_STRING_GENERAL): detachable STRING_TABLE [READABLE_STRING_32]
-- Table of String item associated with key `k',
-- Table of String items associated with key `k',
-- and expanded values to resolved variables ${varname}.
do
if attached text_table_item (k) as tb then
@@ -71,12 +71,17 @@ feature -- Query
end
text_list_item (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32]
-- List of String item associated with key `k'.
-- List of String items associated with key `k'.
deferred
end
text_table_item (k: READABLE_STRING_GENERAL): detachable STRING_TABLE [READABLE_STRING_32]
-- Table of String item associated with key `k'.
-- Table of String items associated with key `k'.
deferred
end
table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32]
-- Keys of table associated with key `k'.
deferred
end

View File

@@ -163,6 +163,20 @@ feature -- Access: Config Reader
end
end
table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32]
-- <Precursor>
do
if attached {STRING_TABLE [like item]} item (k) as l_list then
create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (l_list.count)
Result.compare_objects
across
l_list as ic
loop
Result.force (ic.key.as_string_32)
end
end
end
integer_item (k: READABLE_STRING_GENERAL): INTEGER
-- Integer item associated with key `k'.
do
@@ -442,12 +456,12 @@ feature {NONE} -- Implementation
j := k.index_of (']', i + 1)
if j = i + 1 then -- ends_with "[]"
k.keep_head (i - 1)
if
if
a_section_prefix /= Void and then
attached {LIST [STRING_8]} items.item (a_section_prefix + {STRING_32} "." + k) as l_list
then
lst := l_list
elseif
elseif
attached last_section_name as l_section_prefix and then
attached {LIST [STRING_8]} items.item (l_section_prefix + {STRING_32} "." + k) as l_list
then
@@ -466,12 +480,12 @@ feature {NONE} -- Implementation
sk.left_adjust
sk.right_adjust
k.keep_head (i - 1)
if
if
a_section_prefix /= Void and then
attached {STRING_TABLE [STRING_8]} items.item (a_section_prefix + {STRING_32} "." + k) as l_table
then
tb := l_table
elseif
elseif
attached last_section_name as l_section_prefix and then
attached {STRING_TABLE [STRING_8]} items.item (l_section_prefix + {STRING_32} "." + k) as l_table
then
@@ -522,7 +536,7 @@ feature {NONE} -- Implementation
invariant
note
copyright: "2011-2015, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2016, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software

View File

@@ -105,6 +105,20 @@ feature -- Access: Config Reader
end
end
end
table_keys (k: READABLE_STRING_GENERAL): detachable LIST [READABLE_STRING_32]
-- <Precursor>
do
if attached {JSON_OBJECT} item (k) as obj then
create {ARRAYED_LIST [READABLE_STRING_32]} Result.make (obj.count)
Result.compare_objects
across
obj as ic
loop
Result.force (ic.key.item)
end
end
end
integer_item (k: READABLE_STRING_GENERAL): INTEGER
-- Integer item associated with key `k'.

View File

@@ -75,13 +75,21 @@ feature -- Test
lst.has ("a") and lst.has ("b") and lst.has ("c") and lst.has ("1") and lst.has ("2") and lst.has ("3")
)
)
assert ("has_item (table)", cfg.has_item ("table"))
assert ("item (table)", attached cfg.text_table_item ("table") as tb and then (
tb.item ("a") ~ {STRING_32} "1" and
tb.item ("b") ~ {STRING_32} "2" and
tb.item ("c") ~ {STRING_32} "3" and
tb.item ("d") ~ {STRING_32} "test"
tb.item ("a") ~ {STRING_32} "1" and
tb.item ("b") ~ {STRING_32} "2" and
tb.item ("c") ~ {STRING_32} "3" and
tb.item ("d") ~ {STRING_32} "test"
)
)
assert ("keys of (table)", attached cfg.table_keys ("table") as tb and then (
tb.i_th (1) ~ {STRING_32} "a" and
tb.i_th (2) ~ {STRING_32} "b" and
tb.i_th (3) ~ {STRING_32} "c" and
tb.i_th (4) ~ {STRING_32} "d"
)
)
@@ -198,13 +206,21 @@ feature -- Test
lst.has ("a") and lst.has ("b") and lst.has ("c") and lst.has ("1") and lst.has ("2") and lst.has ("3")
)
)
assert ("has_item (table)", cfg.has_item ("table"))
assert ("item (table)", attached cfg.text_table_item ("table") as tb and then (
tb.item ("a") ~ {STRING_32} "1" and
tb.item ("b") ~ {STRING_32} "2" and
tb.item ("c") ~ {STRING_32} "3" and
tb.item ("d") ~ {STRING_32} "test"
tb.item ("a") ~ {STRING_32} "1" and
tb.item ("b") ~ {STRING_32} "2" and
tb.item ("c") ~ {STRING_32} "3" and
tb.item ("d") ~ {STRING_32} "test"
)
)
assert ("keys of (table)", attached cfg.table_keys ("table") as tb and then (
tb.i_th (1) ~ {STRING_32} "a" and
tb.i_th (2) ~ {STRING_32} "b" and
tb.i_th (3) ~ {STRING_32} "c" and
tb.i_th (4) ~ {STRING_32} "d"
)
)

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

@@ -37,6 +37,80 @@ feature -- Access
weight: INTEGER
-- Optional weight used for order.
query_string: detachable STRING
-- Query string from `location'.
local
i: INTEGER
loc: like location
do
loc := location
i := loc.index_of ('?', 1)
if i > 0 then
Result := loc.substring (i + 1, loc.count)
i := loc.last_index_of ('#', loc.count)
if i > 0 then
Result.keep_head (i - 1)
end
end
end
fragment_string: detachable STRING
-- Query string from `location'.
local
i: INTEGER
loc: like location
do
loc := location
i := loc.last_index_of ('#', loc.count)
if i > 0 then
Result := loc.substring (i + 1, loc.count)
end
end
feature -- Element change
add_query_parameter (a_encoded_name: READABLE_STRING_8; a_encoded_value: detachable READABLE_STRING_8)
-- Add query parameter "$a_encoded_name=$a_encoded_value" to `location'.
-- note: the argument must already be url encoded!
local
q: STRING_8
f: detachable READABLE_STRING_8
i,j: INTEGER
loc: STRING_8
do
create loc.make_from_string (location)
j := loc.last_index_of ('#', loc.count)
if j > 0 then
f := loc.substring (j, loc.count)
loc.keep_head (j - 1)
end
i := loc.index_of ('?', 1)
if i > 0 then
q := loc.substring (i + 1, loc.count)
loc.keep_head (i)
else
create q.make_empty
end
if not q.is_empty then
q.append_character ('&')
end
q.append (a_encoded_name)
if a_encoded_value /= Void then
q.append_character ('=')
q.append (a_encoded_value)
end
loc.append_character ('?')
loc.append (q)
if f /= Void then
loc.append (f)
end
location := loc
end
feature -- Comparison
is_less alias "<" (other: like Current): BOOLEAN
@@ -89,6 +163,22 @@ feature -- Security
feature -- Element change
set_title (a_title: detachable READABLE_STRING_GENERAL)
-- Set `title' to `a_title' or `location'.
do
if a_title /= Void then
title := a_title.as_string_32
else
title := location.as_string_32
end
end
set_location (a_loc: READABLE_STRING_8)
-- Set `location' to `a_loc'.
do
location := a_loc
end
set_weight (a_weight: INTEGER)
-- Set `weight' to `a_weight'.
do
@@ -134,6 +224,6 @@ feature -- Status report
end
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

@@ -18,13 +18,82 @@ feature -- Access
deferred
end
feature -- Element change
item_by_title (a_title: READABLE_STRING_GENERAL): detachable CMS_LINK
-- First link with title `a_title' if any.
do
if attached items as l_items then
across
l_items as ic
until
Result /= Void
loop
Result := ic.item
if not a_title.is_case_insensitive_equal (Result.title) then
Result := Void
end
end
end
ensure
coherent_result: Result /= Void implies Result.title.is_case_insensitive_equal_general (a_title)
end
item_by_location (a_loc: READABLE_STRING_8): detachable CMS_LINK
-- First link with location `a_loc' if any.
do
if attached items as l_items then
across
l_items as ic
until
Result /= Void
loop
Result := ic.item
if not a_loc.same_string (Result.location) then
Result := Void
end
end
end
ensure
coherent_result: Result /= Void implies Result.location.same_string (a_loc)
end
new_composite_item (a_title: detachable READABLE_STRING_GENERAL; a_location: READABLE_STRING_8): CMS_LINK_COMPOSITE
-- If exists, item with location `a_location' or title `a_title',
-- otherwise create new local link and extend to Current.
local
lnk: CMS_LOCAL_LINK
do
if attached {CMS_LINK_COMPOSITE} item_by_location (a_location) as l_parent then
Result := l_parent
elseif a_title /= Void and then attached {CMS_LINK_COMPOSITE} item_by_title (a_title) as l_parent then
Result := l_parent
else
create lnk.make (a_title, a_location)
extend (lnk)
Result := lnk
end
if attached {CMS_LOCAL_LINK} Result as l_local_lnk and then not l_local_lnk.is_expanded then
l_local_lnk.set_expandable (True)
l_local_lnk.set_collapsed (True)
end
end
feature -- Element change
extend (lnk: CMS_LINK)
-- Add `lnk' as a sub link.
deferred
end
extend_into (lnk: CMS_LINK; a_parent_title: detachable READABLE_STRING_GENERAL; a_parent_location: READABLE_STRING_8)
-- Extend `lnk' into local link with location `a_parent_location'.
-- If the parent is not found, create it with title `a_parent_title'.
local
l_parent: CMS_LINK_COMPOSITE
do
l_parent := new_composite_item (a_parent_title, a_parent_location)
l_parent.extend (lnk)
end
remove (lnk: CMS_LINK)
-- Remove link `lnk' from Current container.
deferred
@@ -68,6 +137,6 @@ feature -- status report
end
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

@@ -79,16 +79,6 @@ feature -- Security
feature -- Element change
set_title (a_title: detachable READABLE_STRING_GENERAL)
-- Set `title' to `a_title' or `location'.
do
if a_title /= Void then
title := a_title.as_string_32
else
title := location.as_string_32
end
end
add_link (lnk: CMS_LINK)
-- <Precursor>
local
@@ -194,6 +184,6 @@ feature {NONE} -- Implementation
invariant
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

@@ -73,7 +73,7 @@ feature -- Status report
end
end
feature -- Element change
feature -- Element change
extend (lnk: CMS_LINK)
-- <Precursor>
@@ -104,6 +104,6 @@ feature -- Access
invariant
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

@@ -31,7 +31,7 @@ feature {NONE} -- Initialization
feature -- Access
id: INTEGER
id: INTEGER_64
-- Unique identifier of Current.
category: READABLE_STRING_8
@@ -124,4 +124,7 @@ feature -- Constants
level_info: INTEGER = 7
level_debug: INTEGER = 8
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

@@ -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,12 +62,9 @@ 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
-- User profile.
creation_date: DATE_TIME
-- Creation date.
@@ -80,7 +77,6 @@ feature -- Access
-- active
-- trashed
feature -- Access: helper
utf_8_name: STRING_8
@@ -190,26 +186,6 @@ feature -- Change element
email_set: email = a_email
end
set_profile (prof: like profile)
-- Set `profile' with `prof'.
do
profile := prof
ensure
profile_set: profile = prof
end
set_profile_item (k: READABLE_STRING_8; v: READABLE_STRING_8)
local
prof: like profile
do
prof := profile
if prof = Void then
create prof.make
profile := prof
end
prof.force (v, k)
end
set_last_login_date (dt: like last_login_date)
do
last_login_date := dt
@@ -285,7 +261,6 @@ feature -- Status change
status_set: status = a_status
end
feature -- User status
not_active: INTEGER = 0
@@ -302,6 +277,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

@@ -1,56 +0,0 @@
note
description: "[
User profile used to extend information associated with a {CMS_USER}.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_USER_PROFILE
inherit
TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_GENERAL]
create
make
feature {NONE} -- Initialization
make
-- Create Current profile.
do
create items.make (0)
end
feature -- Access
item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_8
-- Profile item associated with key `k'.
do
Result := items.item (k)
end
feature -- Change
force (v: READABLE_STRING_8; k: READABLE_STRING_GENERAL)
-- Associated value `v' with key `k'.
do
items.force (v, k)
end
feature -- Access
new_cursor: TABLE_ITERATION_CURSOR [READABLE_STRING_8, READABLE_STRING_GENERAL]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature {NONE} -- Implementation
items: STRING_TABLE [READABLE_STRING_8]
;note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -80,7 +80,7 @@ feature -- Cursor
feature -- Action
action: FUNCTION [ANY, detachable TUPLE, G]
action: FUNCTION [DB_TUPLE, G]
-- Agent to create a new item of type G.
feature {NONE} -- Implementation

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,66 +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`)
);
COMMIT;

View File

@@ -1,8 +1,9 @@
<?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="store_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="store_mysql">
<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="store_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="store_mysql">
<description>CMS Eiffel Store MySQL persistence solution</description>
<target name="store_mysql">
<root all_classes="true"/>
<option warning="true" void_safety="all">
<option warning="true" is_obsolete_routine_type="false" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
@@ -26,9 +27,9 @@
</cluster>
<cluster name="persistence_store_mysql" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
</cluster>
</target>

View File

@@ -1,8 +1,9 @@
<?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="persistence_store_odbc" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_store_odbc">
<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="persistence_store_odbc" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_store_odbc">
<target name="persistence_store_odbc">
<description>CMS Eiffel Store ODBC persistence solution</description>
<root all_classes="true"/>
<option warning="true" void_safety="all">
<option warning="true" is_obsolete_routine_type="false" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
@@ -22,9 +23,9 @@
<cluster name="common" location="..\implementation\store\" recursive="true"/>
<cluster name="persistence_store_odbc" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/EIFGENs$</exclude>
</file_rule>
</cluster>
</target>

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

@@ -54,6 +54,7 @@ feature -- Access: router
l_user_handler: CMS_USER_HANDLER
l_role_handler: CMS_ROLE_HANDLER
l_admin_logs_handler: CMS_LOGS_HANDLER
l_admin_cache_handler: CMS_ADMIN_CACHE_HANDLER
l_admin_export_handler: CMS_ADMIN_EXPORT_HANDLER
@@ -76,6 +77,11 @@ feature -- Access: router
create l_uri_mapping.make_trailing_slash_ignored ("/admin/roles", l_roles_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post)
create l_admin_logs_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/admin/logs", l_admin_logs_handler)
a_router.map (l_uri_mapping, a_router.methods_get)
create l_admin_cache_handler.make (a_api)
create l_uri_mapping.make_trailing_slash_ignored ("/admin/cache", l_admin_cache_handler)
a_router.map (l_uri_mapping, a_router.methods_get_post)
@@ -103,11 +109,12 @@ feature -- Security
-- List of permission ids, used by this module, and declared.
do
Result := Precursor
Result.force ("manage admin")
Result.force ("access admin")
Result.force ("admin users")
Result.force ("admin roles")
Result.force ("admin modules")
Result.force ("install modules")
Result.force ("view logs")
Result.force ("admin core caches")
Result.force ("clear blocks cache")
Result.force ("admin export")
@@ -132,28 +139,23 @@ feature -- Hooks
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
admin_lnk: CMS_LINK_COMPOSITE
do
if
a_response.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) -- Note: admin user has all permissions enabled by default.
then
-- TODO: we should probably use more side menu and less primary_menu.
create lnk.make ("Admin", "admin")
lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>)
a_menu_system.management_menu.extend (lnk)
if a_response.api.user_is_authenticated then
admin_lnk := a_menu_system.management_menu.new_composite_item ("Admin", "admin")
create lnk.make ("Module", "admin/modules")
lnk.set_permission_arguments (<<"manage module">>)
admin_lnk.extend (lnk)
-- Per module cache permission!
create lnk.make ("Cache", "admin/cache")
admin_lnk.extend (lnk)
-- Per module export permission!
create lnk.make ("Export", "admin/export")
admin_lnk.extend (lnk)
end
create lnk.make ("Module", "admin/modules")
lnk.set_permission_arguments (<<"manage module">>)
a_menu_system.management_menu.extend (lnk)
-- Per module cache permission!
create lnk.make ("Cache", "admin/cache")
a_menu_system.management_menu.extend (lnk)
-- Per module export permission!
create lnk.make ("Export", "admin/export")
a_menu_system.management_menu.extend (lnk)
end
note

View File

@@ -17,22 +17,59 @@ feature -- Process
process
local
b: STRING
l_admin_links: ARRAYED_LIST [TUPLE [package: READABLE_STRING_8; permissions: ARRAY [READABLE_STRING_GENERAL]; link: CMS_LINK; help: READABLE_STRING_GENERAL]]
lst: detachable ARRAYED_LIST [TUPLE [permissions: ARRAY [READABLE_STRING_GENERAL]; link: CMS_LINK; help: READABLE_STRING_GENERAL]]
categories: STRING_TABLE [ARRAYED_LIST [TUPLE [permissions: ARRAY [READABLE_STRING_GENERAL]; link: CMS_LINK; help: READABLE_STRING_GENERAL]]]
l_package: READABLE_STRING_8
do
create l_admin_links.make (5)
l_admin_links.force (["core", <<"admin users">>, local_link ("Users", "admin/users"), "View/Edit/Add Users"])
l_admin_links.force (["core", <<"admin roles">>, local_link ("Roles", "admin/roles"), "View/Edit/Add Roles"])
l_admin_links.force (["core", <<"admin modules">>, local_link ("Modules", "admin/modules"), "(un)Install modules"])
l_admin_links.force (["core", <<"view logs">>, local_link ("Logs", "admin/logs"), "View logs"])
l_admin_links.force (["support", <<"admin cache">>, local_link ("Cache", "admin/cache"), "Clear caches"])
l_admin_links.force (["support", <<"admin export">>, local_link ("Export", "admin/export"), "Export CMS contents, and modules contents."])
create categories.make_caseless (3)
across
l_admin_links as ic
loop
l_package := ic.item.package
lst := categories.item (l_package)
if lst = Void then
create lst.make (1)
categories.force (lst, l_package)
end
lst.force ([ic.item.permissions, ic.item.link, ic.item.help])
end
create b.make_empty
set_title (translation ("Admin Page", Void))
b.append ("<ul id=%"content-types%">")
fixme ("Check how to make it configurable")
if has_permissions (<< "admin users">>) then
b.append ("<li>" + link ("Users", "admin/users", Void))
b.append ("<div class=%"description%">View/Edit/Add Users</div>")
b.append ("</li>")
across
categories as cats_ic
loop
lst := cats_ic.item
b.append ("<h3>")
b.append (html_encoded (cats_ic.key))
b.append ("</h3>")
b.append ("<ul>")
across
lst as ic
loop
if has_permissions (ic.item.permissions) then
b.append ("<li>")
if attached ic.item.link as lnk then
b.append (link (lnk.title, lnk.location, Void))
end
b.append ("<div class=%"description%">")
b.append (html_encoded (ic.item.help))
b.append ("</div>")
b.append ("</li>")
end
end
b.append ("</ul>")
end
if has_permissions (<< "admin roles">>) then
b.append ("<li>" + link ("Roles", "admin/roles", Void))
b.append ("<div class=%"description%">View/Edit/Add Roles</div>")
b.append ("</li>")
end
b.append ("</ul>")
set_main_content (b)
end

View File

@@ -0,0 +1,114 @@
note
description: "[
Handler for a CMS logs in the CMS interface.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_LOGS_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_URI_TEMPLATE_HANDLER
rename
execute as uri_template_execute,
new_mapping as new_uri_template_mapping
select
new_uri_template_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
uri_template_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler
do
execute (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_logs: LIST [CMS_LOG]
l_log: CMS_LOG
r: CMS_RESPONSE
l_cat: detachable READABLE_STRING_8
l_lower: INTEGER
l_count: INTEGER
b: STRING
do
if api.has_permission ("view logs") then
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
if attached {WSF_STRING} req.query_parameter ("category") as p_cat then
l_cat := p_cat.value
end
if attached {WSF_STRING} req.query_parameter ("lower") as p_lower and then p_lower.is_integer then
l_lower := p_lower.integer_value
end
if attached {WSF_STRING} req.query_parameter ("count") as p_count and then p_count.is_integer then
l_count := p_count.integer_value
end
l_logs := api.logs (l_cat, l_lower, l_count)
create b.make (100)
b.append ("<ul class=%"logs%">%N")
across
l_logs as ic
loop
l_log := ic.item
b.append ("<li class=%"log-level-"+ l_log.level.out +"%">")
b.append ("[" + l_log.category + "] ")
b.append (l_log.message)
b.append ("%N<p>(date: " + l_log.date.out + ")")
if attached l_log.link as lnk then
b.append (" <a href=%"" + req.script_url (lnk.location) + "%">" + html_encoded (lnk.title) + "</a>")
end
b.append ("</p>%N")
if attached l_log.info as l_info then
b.append ("<pre>" + l_info + "</pre>%N")
end
b.append ("</li>%N")
end
b.append ("</ul>%N")
r.set_main_content (b)
r.set_page_title ("Logs ...")
r.set_title ("Logs")
else
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
end
r.execute
end
end

View File

@@ -166,7 +166,7 @@ feature -- Error
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user (req) as l_user then
if attached api.user as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then

View File

@@ -166,7 +166,7 @@ feature -- Error
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
do
if attached current_user (req) as l_user then
if attached api.user as l_user then
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if
l_id.is_integer and then

View File

@@ -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: ")
@@ -86,12 +86,13 @@ feature -- Execution
not l_roles.is_empty
then
s.append ("<h4>Role(s):</h4>")
s.append ("<ul class=%"user-roles%">")
across l_roles as ic loop
l_role := ic.item
s.append ("<i>")
s.append ("<li>")
s.append (link (l_role.name, "admin/role/" + l_role.id.out, Void))
s.append ("</i>")
debug
s.append ("</li>")
if request.query_parameter ("debug") /= Void then
s.append ("<h5>Permissions:</h5>")
s.append ("<ul class=%"cms-permissions%">%N")
across l_role.permissions as perms_ic loop
@@ -100,6 +101,7 @@ feature -- Execution
s.append ("</ul>%N")
end
end
s.append ("</ul>%N")
end
s.append ("</div>")

View File

@@ -1,34 +1,31 @@
<?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">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
<exclude>/EIFGENs$</exclude>
</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>
<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="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_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<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="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="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="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"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="email_service" location="..\..\library\email\email-safe.ecf"/>
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
<library name="cypress_consumer" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,17 @@
note
description: "[
Common interface for Auth module API.
]"
date: "$Date$"
revision: "$Revision$"
class
CMS_AUTH_API_I
inherit
CMS_MODULE_API
create
make
end

View File

@@ -0,0 +1,44 @@
note
description: "[
Processes a HTTP request, and depending on header, authenticate a current user or not.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_AUTH_FILTER_I
inherit
WSF_FILTER
feature {NONE} -- Initialization
make (a_api: CMS_API)
-- Initialize Current handler with `a_api'.
do
api := a_api
end
feature -- API Service
api: CMS_API
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
deferred
end
auth_strategy: STRING
deferred
end
set_current_user (u: CMS_USER)
do
api.set_user (u)
-- Record auth strategy:
api.set_execution_variable ("auth_strategy", auth_strategy)
end
end

View File

@@ -0,0 +1,110 @@
note
description: "Common ancestor for Authentication modules."
date: "$Date$"
revision: "$Revision$"
deferred class
CMS_AUTH_MODULE_I
inherit
CMS_MODULE
redefine
setup_hooks
end
CMS_HOOK_AUTO_REGISTER
CMS_HOOK_MENU_SYSTEM_ALTER
CMS_HOOK_BLOCK_HELPER
SHARED_LOGGER
feature {NONE} -- Initialization
make
do
package := "authentication"
add_dependency ({CMS_AUTHENTICATION_MODULE})
end
feature -- Access: auth strategy
login_title: READABLE_STRING_GENERAL
-- Module specific login title.
deferred
end
login_location: STRING
-- Login cms location for Current module.
deferred
end
logout_location: STRING
-- Logout cms location for Current module.
deferred
end
is_authenticating (a_response: CMS_RESPONSE): BOOLEAN
-- Is Current module strategy currently authenticating active user?
deferred
ensure
Result implies a_response.is_authenticated
end
feature -- Hooks configuration
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
-- Module hooks configuration.
do
auto_subscribe_to_hooks (a_hooks)
a_hooks.subscribe_to_menu_system_alter_hook (Current)
end
feature -- Hooks
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
-- <Precursor>
local
lnk: CMS_LOCAL_LINK
l_destination: READABLE_STRING_8
do
if attached {WSF_STRING} a_response.request.item ("destination") as p_destination then
l_destination := p_destination.url_encoded_value
else
l_destination := a_response.location
end
if is_authenticating (a_response) then
else
if a_response.location.starts_with ("account/auth/") then
create lnk.make (login_title, login_location)
if not l_destination.starts_with ("account/auth/") then
lnk.add_query_parameter ("destination", l_destination)
end
lnk.set_expandable (True)
a_response.add_to_primary_tabs (lnk)
end
end
end
feature {NONE} -- Template
smarty_template_login_block (a_request: WSF_REQUEST; a_module: CMS_MODULE; a_block_id: READABLE_STRING_8; a_cms_api: CMS_API): like smarty_template_block
local
l_destination: detachable READABLE_STRING_32
do
Result := smarty_template_block (a_module, a_block_id, a_cms_api)
if Result /= Void then
if attached {WSF_STRING} a_request.query_parameter ("destination") as p_destination then
l_destination := p_destination.value
elseif attached {WSF_STRING} a_request.form_parameter ("destination") as p_destination then
l_destination := p_destination.value
end
if l_destination /= Void then
Result.set_value (l_destination, "site_destination")
end
end
end
end

View File

@@ -0,0 +1,211 @@
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)
l_message.replace_substring_all ("$email", a_to)
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)
l_message.replace_substring_all ("$email", a_to)
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 ("$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)
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

View File

@@ -6,9 +6,6 @@ note
class
CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
inherit
EMAIL_SERVICE_PARAMETERS
create
make
@@ -17,25 +14,21 @@ feature {NONE} -- Initialization
make (a_cms_api: CMS_API)
local
utf: UTF_CONVERTER
l_site_name: READABLE_STRING_8
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"))
l_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 := l_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)
@@ -56,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
l_contact_email := notif_email_address
end
if not l_contact_email.has ('<') then
l_contact_email := l_utf8_site_name + " <" + l_contact_email + ">"
end
contact_email_address := l_contact_email
end
if l_contact_email /= Void then
if not l_contact_email.has ('<') then
l_contact_email := l_site_name + " <" + l_contact_email + ">"
end
contact_email := l_contact_email
else
contact_email := admin_email
end
if l_subject_register /= Void then
contact_subject_register := l_subject_register
else
@@ -88,23 +80,40 @@ 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."
end
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.
utf_8_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_activate: IMMUTABLE_STRING_8
contact_subject_password: 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 template email message.
@@ -112,10 +121,22 @@ feature -- Access
Result := template_string ("account_activation.html", default_template_account_activation)
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 template email message.
do
Result := template_string ("accunt_re_activation.html", default_template_account_re_activation)
Result := template_string ("account_re_activation.html", default_template_account_re_activation)
end
account_rejected: STRING
-- Account rejected template email message.
do
Result := template_string ("account_rejected.html", default_template_account_rejected)
end
account_password: STRING
@@ -146,7 +167,7 @@ feature {NONE} -- Implementation: Template
local
p: PATH
do
p := template_path ("account_activation.html")
p := template_path (a_name)
if attached read_template_file (p) as l_content then
Result := l_content
else
@@ -177,6 +198,36 @@ feature {NONE} -- Implementation
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 = "[
<!doctype html>
<html lang="en">
@@ -184,21 +235,53 @@ feature {NONE} -- Message email
<meta charset="utf-8">
<title>Activation</title>
<meta name="description" content="Activation">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<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><a href="$link">$link</a></p>
<p>We will review your application and send you an email<p>
<p>Thank you for joining us.</p>
</body>
</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>Your account application is rejected, it does not conform our rules <a href="$host">$sitename</a></p>
</body>
</html>
]"
default_template_account_re_activation: STRING = "[
<!doctype html>
<html lang="en">
@@ -206,11 +289,11 @@ feature {NONE} -- Message email
<meta charset="utf-8">
<title>New Activation</title>
<meta name="description" content="New Activation token">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<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>
@@ -229,11 +312,11 @@ feature {NONE} -- Message email
<meta charset="utf-8">
<title>New Password</title>
<meta name="description" content="New Password">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>You have required a new password at <a href="...">ROC CMS</a></p>
<p>You have requested 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>
@@ -250,11 +333,11 @@ feature {NONE} -- Message email
<meta charset="utf-8">
<title>Welcome</title>
<meta name="description" content="Welcome">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>Welcome to<a href="...">ROC CMS</a></p>
<p>Welcome to <a href="$host">$sitename</a>.</p>
<p>Thank you for joining us.</p>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,88 +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_contact_email (a_to, a_content: READABLE_STRING_8)
-- Send successful contact message `a_token' 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 ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_register, l_message)
end
send_contact_activation_email (a_to, a_content: READABLE_STRING_8)
-- Send successful contact message `a_token' 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 ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_activate, l_message)
end
send_contact_password_email (a_to, a_content: READABLE_STRING_8)
-- Send successful contact message `a_token' 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 ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_password, l_message)
end
send_contact_welcome_email (a_to, a_content: READABLE_STRING_8)
-- Send successful contact message `a_token' 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 ("$link", a_content)
send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message)
end
end

View File

@@ -1,8 +0,0 @@
{
"email": "webmaster@example.com",
"subjet_register": "Thank you for regitering with us, activate account",
"subjet_activate": "New account ativation token",
"subjet_password": "Password Recovery!!!",
"subjet_oauth": "Welcome",
"smtp": "127.0.0.1"
}

View File

@@ -0,0 +1,12 @@
{
"subject": "Thank you for contacting us",
"forms": {
"registration": {
"application_description": "Present yourself in a few lines, otherwise your application is likely to be rejected."
}
},
"recaptcha": {
"site_key":"6Lex9RMTAAAAAKleC4x6TaRlFcpLbEWgH_U7MSiD",
"secret_key":"6Lex9RMTAAAAAAkBczvX5DUiyg_xoM_EthVVgRRx"
}
}

View File

@@ -0,0 +1,28 @@
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] ";
}

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

@@ -4,15 +4,10 @@
<meta charset="utf-8">
<title>Activation</title>
<meta name="description" content="Activation">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>Thank you for registering at <a href="$host">ROC CMS</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>Thank you for joining us.</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>

View File

@@ -0,0 +1,13 @@
<!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 "$user ($email)" is confirmed at <a href="$host">$sitename</a>.</p>
<p>Thank you for joining us.</p>
</body>
</html>

View File

@@ -4,14 +4,12 @@
<meta charset="utf-8">
<title>New Password</title>
<meta name="description" content="New Password">
<meta name="author" content="ROC CMS">
<meta name="author" content="$sitename">
</head>
<body>
<p>You have required a new password at <a href="$host">ROC CMS</a></p>
<p>To complete your request, please click on this link to genereate 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>

Some files were not shown because too many files have changed in this diff Show More