Compare commits
87 Commits
BEFORE_RES
...
es_15_08
| Author | SHA1 | Date | |
|---|---|---|---|
| ad4f020d0e | |||
| 7a13b47131 | |||
| 923089baa1 | |||
| cfec9dc7f8 | |||
| b5e7d5d201 | |||
| e1bdcb965c | |||
| 0061afcbe8 | |||
| 6a9bc8aa42 | |||
| 1d7d79d69e | |||
| 46014da3d8 | |||
| 7cb4c0e9f4 | |||
| aff6b07c80 | |||
| 479194d6c5 | |||
| 3f123dd921 | |||
| cd0c2acd87 | |||
| 44ada4b6b1 | |||
| 8efbddc8cb | |||
| f26b81977c | |||
| bbf7456fa2 | |||
| 62ef07c86b | |||
| a422dea15d | |||
| 6fb7bf9a1d | |||
| bba1d57ce3 | |||
| c271f839e2 | |||
| 5d81f1d195 | |||
|
|
63f3ec12d0 | ||
|
|
863a1e7b98 | ||
|
|
0fe9018ce9 | ||
|
|
1ef4025caa | ||
|
|
3ebffad3d6 | ||
| 500f8f78a4 | |||
| 47573a1950 | |||
|
|
2d5f985037 | ||
|
|
eff3552ea1 | ||
| 43b8c52d34 | |||
| d8ac46f8b0 | |||
|
|
91f1a87b83 | ||
| 769c14caf8 | |||
| 3c0122d98f | |||
|
|
77487e90f3 | ||
|
|
5d498c0bf2 | ||
|
|
e42a7636ae | ||
| f55a52e4d0 | |||
| 2040a746dd | |||
|
|
d4fc9f9411 | ||
|
|
bba504df53 | ||
| 5688cffcf1 | |||
| 19e8607e54 | |||
| 2d77bf6de8 | |||
| 2d985ba05e | |||
| 1b0cc9dc07 | |||
|
|
0164c6ec6d | ||
|
|
2fe2a7f864 | ||
| 3dec559d58 | |||
|
|
dce3f71be9 | ||
| 3ea9e36e7c | |||
| 5da01fd576 | |||
| 7f4a7b3ab9 | |||
| 779064a505 | |||
| 5477bab83c | |||
| d24f124e42 | |||
| bace9657b4 | |||
| 6319d46f26 | |||
| 31095b1b66 | |||
| 16cae0047d | |||
| 85cff0b139 | |||
| cc94c59eed | |||
| 4c8af3ef66 | |||
| 37729f648a | |||
| 26dc018893 | |||
|
|
f0eff2cb98 | ||
| 011a6b7804 | |||
| 83e7f95425 | |||
|
|
4f7acc5dbd | ||
|
|
922fca80ad | ||
|
|
9d465b3d7e | ||
|
|
5288fe4d3c | ||
|
|
9722347736 | ||
|
|
a2598fff92 | ||
| 42e7763528 | |||
|
|
02fe3ba829 | ||
|
|
fe3274e29a | ||
|
|
96bae9f8fb | ||
|
|
1cef32a1fb | ||
|
|
f1e8e1da58 | ||
|
|
26276dad5d | ||
| eb9ac980e6 |
@@ -12,9 +12,10 @@
|
||||
</option>
|
||||
<mapping old_name="CMS_LAYOUT" new_name="CMS_ENVIRONMENT"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
|
||||
<library name="cms_app_env" location=".\library\app_env\app_env-safe.ecf"/>
|
||||
<library name="cms_model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="config" location=".\library\configuration\config-safe.ecf"/>
|
||||
<library name="cms_config" location=".\library\configuration\config-safe.ecf"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||
|
||||
3
cms.ecf
3
cms.ecf
@@ -13,9 +13,10 @@
|
||||
</option>
|
||||
<mapping old_name="CMS_LAYOUT" new_name="CMS_ENVIRONMENT"/>
|
||||
<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="cms_app_env" location=".\library\app_env\app_env.ecf"/>
|
||||
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="config" location=".\library\configuration\config.ecf"/>
|
||||
<library name="cms_config" location=".\library\configuration\config.ecf"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?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-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="demo" uuid="3643E657-BCBE-46AA-931B-71EAEA877A18" library_target="demo">
|
||||
<description>Example/demo for Eiffel ROC CMS library</description>
|
||||
<target name="common" abstract="true">
|
||||
<file_rule>
|
||||
@@ -15,16 +15,20 @@
|
||||
<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_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
|
||||
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20-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_blog_module" location="..\..\modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_email_service" location="..\..\library\email\email-safe.ecf" readonly="false"/>
|
||||
<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_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_admin_module" location="..\..\modules\admin\admin-safe.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes-safe.ecf" readonly="false"/>
|
||||
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf" readonly="false"/>
|
||||
<!--
|
||||
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-safe.ecf" readonly="false"/>
|
||||
-->
|
||||
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
|
||||
9
examples/demo/install_modules.bat
Normal file
9
examples/demo/install_modules.bat
Normal file
@@ -0,0 +1,9 @@
|
||||
setlocal
|
||||
set ROC_CMD=%~dp0..\..\tools\roc.exe
|
||||
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\node --dir %ROC_CMS_DIR%
|
||||
%ROC_CMD% install --module ..\..\modules\blog --dir %ROC_CMS_DIR%
|
||||
%ROC_CMD% install --module ..\..\modules\oauth20 --dir %ROC_CMS_DIR%
|
||||
@@ -1,115 +0,0 @@
|
||||
note
|
||||
description: "Storage extension for Blog nodes."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_NODE_STORAGE_SQL_BLOG_EXTENSION
|
||||
|
||||
inherit
|
||||
CMS_NODE_STORAGE_EXTENSION [CMS_BLOG]
|
||||
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
rename
|
||||
sql_storage as node_storage
|
||||
redefine
|
||||
node_storage
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
node_storage: CMS_NODE_STORAGE_SQL
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access
|
||||
|
||||
content_type: STRING
|
||||
once
|
||||
Result := {CMS_BLOG_NODE_TYPE}.name
|
||||
end
|
||||
|
||||
feature -- Persistence
|
||||
|
||||
store (a_node: CMS_BLOG)
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_new_tags: detachable STRING_32
|
||||
l_previous_tags: detachable STRING_32
|
||||
l_update: BOOLEAN
|
||||
do
|
||||
error_handler.reset
|
||||
if attached api as l_api then
|
||||
l_api.logger.put_information (generator + ".store", Void)
|
||||
end
|
||||
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
|
||||
sql_query (sql_select_blog_data, l_parameters)
|
||||
if not has_error then
|
||||
if sql_rows_count = 1 then
|
||||
l_previous_tags := sql_read_string_32 (3)
|
||||
l_update := True
|
||||
end
|
||||
if attached a_node.tags as l_tags and then not l_tags.is_empty then
|
||||
create l_new_tags.make (0)
|
||||
across
|
||||
l_tags as ic
|
||||
loop
|
||||
if not l_new_tags.is_empty then
|
||||
l_new_tags.append_character (',')
|
||||
end
|
||||
l_new_tags.append (ic.item)
|
||||
end
|
||||
else
|
||||
l_new_tags := Void
|
||||
end
|
||||
l_parameters.put (l_new_tags, "tags")
|
||||
if l_update and l_new_tags /~ l_previous_tags then
|
||||
sql_change (sql_update_blog_data, l_parameters)
|
||||
elseif l_new_tags /= Void then
|
||||
sql_change (sql_insert_blog_data, l_parameters)
|
||||
else
|
||||
-- no blog data, means everything is empty.
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
load (a_node: CMS_BLOG)
|
||||
local
|
||||
l_parameters: STRING_TABLE [ANY]
|
||||
n: INTEGER
|
||||
do
|
||||
error_handler.reset
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_node.id, "nid")
|
||||
l_parameters.put (a_node.revision, "revision")
|
||||
sql_query (sql_select_blog_data, l_parameters)
|
||||
if not has_error then
|
||||
n := sql_rows_count
|
||||
if n = 1 then
|
||||
-- nid, revision, parent
|
||||
if
|
||||
attached sql_read_string_32 (3) as l_tags and then
|
||||
not l_tags.is_whitespace
|
||||
then
|
||||
-- FIXME: find a simple way to access the declared content types.
|
||||
a_node.set_tags_from_string (l_tags)
|
||||
end
|
||||
else
|
||||
check unique_data: n = 0 end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- SQL
|
||||
|
||||
sql_select_blog_data: STRING = "SELECT nid, revision, tags FROM blog_post_nodes WHERE nid =:nid AND revision=:revision;"
|
||||
sql_insert_blog_data: STRING = "INSERT INTO blog_post_nodes (nid, revision, tags) VALUES (:nid, :revision, :tags);"
|
||||
sql_update_blog_data: STRING = "UPDATE blog_post_nodes SET nid=:nid, revision=:revision, tags=:tags WHERE nid=:nid AND revision=:revision;"
|
||||
|
||||
end
|
||||
@@ -12,7 +12,6 @@ inherit
|
||||
redefine
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install
|
||||
end
|
||||
|
||||
@@ -52,12 +51,6 @@ feature {CMS_API} -- Module Initialization
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
sql: STRING
|
||||
@@ -77,7 +70,7 @@ CREATE TABLE tb_demo(
|
||||
api.logger.put_error ("Could not initialize database for demo module", generating_type)
|
||||
end
|
||||
end
|
||||
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
|
||||
Precursor {CMS_MODULE}(api)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -94,8 +87,8 @@ feature -- Hooks
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
do
|
||||
a_response.subscribe_to_menu_system_alter_hook (Current)
|
||||
a_response.subscribe_to_block_hook (Current)
|
||||
a_response.hooks.subscribe_to_menu_system_alter_hook (Current)
|
||||
a_response.hooks.subscribe_to_block_hook (Current)
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
@@ -140,7 +133,7 @@ feature -- Handler
|
||||
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
|
||||
do
|
||||
create r.make (req, res, a_api)
|
||||
r.set_main_content ("DEMO module does not yet implement %"" + req.path_info + "%" ...")
|
||||
r.set_main_content ("DEMO module does not yet implement %"" + req.percent_encoded_path_info + "%" ...")
|
||||
r.add_error_message ("DEMO Module: not yet implemented")
|
||||
r.execute
|
||||
end
|
||||
|
||||
@@ -12,3 +12,28 @@ theme=bootstrap
|
||||
smtp=localhost:25
|
||||
#sendmail=/usr/bin/sendmail
|
||||
#output=@stderr
|
||||
|
||||
[modules]
|
||||
# Module status
|
||||
# *=on -> modules are enabled by default
|
||||
# *=off -> modules are disabled by default
|
||||
# Default is "on"
|
||||
# for each module, this can be overwritten with
|
||||
# module_name= on or off
|
||||
*=off
|
||||
admin=on
|
||||
auth=on
|
||||
basic_auth=on
|
||||
blog=on
|
||||
debug=on
|
||||
demo=on
|
||||
node=on
|
||||
oauth20=on
|
||||
openid=on
|
||||
|
||||
[blocks]
|
||||
#navigation.region=sidebar_first
|
||||
|
||||
[admin]
|
||||
# CMS Installation, are accessible by "all", "none" or uppon "permission". (default is none)
|
||||
installation_access=permission
|
||||
|
||||
34
examples/demo/site/modules/admin/files/css/admin.css
Normal file
34
examples/demo/site/modules/admin/files/css/admin.css
Normal file
@@ -0,0 +1,34 @@
|
||||
ul.cms-users {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-users li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-users li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-users li.cms_user a::before {
|
||||
content: "[users] "; }
|
||||
|
||||
ul.cms-roles {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-roles li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-roles li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-roles li.cms_role a::before {
|
||||
content: "[roles] "; }
|
||||
|
||||
ul.cms-permissions {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-permissions li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-permissions li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-permissions li.cms_permission a::before {
|
||||
content: "[permission] "; }
|
||||
|
||||
/*# sourceMappingURL=admin.css.map */
|
||||
59
examples/demo/site/modules/admin/files/scss/admin.scss
Normal file
59
examples/demo/site/modules/admin/files/scss/admin.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
ul.cms-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_user a::before {
|
||||
content: "[users] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-roles {
|
||||
|
||||
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_role a::before {
|
||||
content: "[roles] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-permissions {
|
||||
|
||||
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_permission a::before {
|
||||
content: "[permission] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"api_secret":"ADD_YOUR_SECRET_KEY",
|
||||
"api_key":"ADD_YOUR_PUBLIC_KEY",
|
||||
"scope": "email",
|
||||
"api_revoke":"https://accounts.google.com/o/oauth2/revoke?token=$ACCESS_TOKEN",
|
||||
"protected_resource_url":"https://www.googleapis.com/plus/v1/people/me"
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<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>
|
||||
</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>
|
||||
|
||||
|
||||
<hr>
|
||||
<h4>Profile</h4>
|
||||
<div>
|
||||
{foreach item="the_value" key="the_name" from="$user.profile"}
|
||||
<div>
|
||||
<label>{$the_name/}:</label> {$the_value/}
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
{unless isset="$user"}
|
||||
<div>
|
||||
<p> You are not logged in </p>
|
||||
<a href="{$site_url/}account/roc-login">Go to the login page</a>
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
<div>
|
||||
<form action="{$site_url/}account/change-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Change Password Form</legend>
|
||||
<div>
|
||||
<input type="password" id="password" name="password" value="" required/>
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" id="confirm_password" name="confirm_password" value="" required/>
|
||||
<label for="password">Confirm Password</label>
|
||||
</div>
|
||||
|
||||
<button type="submit">Confirm</button>
|
||||
{if isset="$error_password"}
|
||||
<span><i>{$error_password/}</i></span> <br>
|
||||
{/if}
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -25,10 +25,5 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{foreach item="item" from="$oauth_consumers"}
|
||||
<a href="{$site_url/}account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div>
|
||||
<form action="/account/new-password" method="post">
|
||||
<form action="{$site_url/}account/new-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Require new password</legend>
|
||||
<legend>Request new password by email</legend>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<label for="email">Email</label>
|
||||
@@ -13,4 +13,20 @@
|
||||
<button type="submit">Send</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<hr>
|
||||
<form action="{$site_url/}account/new-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Request new password by username</legend>
|
||||
<div>
|
||||
<input type="text" id="username" name="username" value="{$username/}" required/>
|
||||
<label for="username">Username</label>
|
||||
{if isset="$error_username"}
|
||||
<span><i>{$error_username/}</i></span> <br>
|
||||
{/if}
|
||||
<br>
|
||||
</div>
|
||||
<button type="submit">Send</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>You new password has been saved!, Login again</p>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/reactivate" method="post">
|
||||
<form action="{$site_url/}account/reactivate" method="post">
|
||||
<fieldset>
|
||||
<legend>Reactivate Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/roc-register" method="post">
|
||||
<form action="{$site_url/}account/roc-register" method="post">
|
||||
<fieldset>
|
||||
<legend>Register Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/reset-password" method="post">
|
||||
<form action="{$site_url/}account/reset-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Generate New Password Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -7,7 +7,7 @@ var userAgent = navigator.userAgent.toLowerCase();
|
||||
var firstLogIn = true;
|
||||
|
||||
ROC_AUTH.login = function() {
|
||||
var form = document.forms[0];
|
||||
var form = document.forms['cms_basic_auth'];
|
||||
var username = form.username.value;
|
||||
var password = form.password.value;
|
||||
//var host = form.host.value;
|
||||
@@ -39,7 +39,7 @@ ROC_AUTH.login = function() {
|
||||
if (request.readyState == 4) {
|
||||
if (request.status==200) {
|
||||
delete form;
|
||||
window.location=origin;
|
||||
window.location=window.location.origin;
|
||||
}
|
||||
else{
|
||||
if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){
|
||||
@@ -306,16 +306,20 @@ ROC_AUTH.create_form = function() {
|
||||
};
|
||||
|
||||
|
||||
var password = document.getElementById("password")
|
||||
, confirm_password = document.getElementById("confirm_password");
|
||||
var password = document.getElementById("password");
|
||||
var confirm_password = document.getElementById("confirm_password");
|
||||
|
||||
ROC_AUTH.validatePassword =function(){
|
||||
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('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
password.onchange = ROC_AUTH.validatePassword();
|
||||
confirm_password.onkeyup = ROC_AUTH.validatePassword;
|
||||
if ((password != null) && (confirm_password != null)) {
|
||||
password.onchange = ROC_AUTH.validatePassword();
|
||||
confirm_password.onkeyup = ROC_AUTH.validatePassword;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<div class="primary-tabs">
|
||||
{unless isset="$user"}
|
||||
<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" 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>
|
||||
<div>
|
||||
{foreach item="item" from="$oauth_consumers"}
|
||||
<a href="{$site_url/}account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
@@ -11,12 +11,27 @@ CREATE TABLE nodes (
|
||||
`publish` DATETIME,
|
||||
`created` DATETIME NOT NULL,
|
||||
`changed` DATETIME NOT NULL,
|
||||
`status` INTEGER
|
||||
`status` INTEGER,
|
||||
CONSTRAINT Unique_nid_revision UNIQUE (nid,revision)
|
||||
);
|
||||
|
||||
CREATE TABLE node_revisions (
|
||||
`nid` INTEGER NOT NULL,
|
||||
`revision` INTEGER NOT NULL,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`summary` TEXT,
|
||||
`content` TEXT,
|
||||
`format` VARCHAR(128),
|
||||
`author` INTEGER,
|
||||
`changed` DATETIME NOT NULL,
|
||||
`status` INTEGER,
|
||||
CONSTRAINT Unique_nid_revision PRIMARY KEY (nid,revision)
|
||||
);
|
||||
|
||||
CREATE TABLE page_nodes(
|
||||
`nid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`revision` INTEGER,
|
||||
`parent` INTEGER
|
||||
`nid` INTEGER NOT NULL,
|
||||
`revision` INTEGER NOT NULL,
|
||||
`parent` INTEGER,
|
||||
CONSTRAINT PK_nid_revision PRIMARY KEY (nid,revision)
|
||||
);
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ CREATE TABLE $table_name (
|
||||
`access_token` TEXT NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`details` TEXT NOT NULL,
|
||||
`email` TEXT NOT NULL,
|
||||
CONSTRAINT `uid`
|
||||
UNIQUE(`uid`)
|
||||
UNIQUE(`uid`),
|
||||
CONSTRAINT `email`
|
||||
UNIQUE(`email`)
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<hr>
|
||||
{unless isempty="$oauth_associated"}
|
||||
<h4>Un-Associate Account with Oauth Consumer</h4>
|
||||
<div>
|
||||
{foreach item="consumer" from="$oauth_associated"}
|
||||
<div>
|
||||
<form method="post" action="{$site_url/}account/oauth-un-associate">
|
||||
<input type="hidden" name="consumer" value="{$consumer/}"/>
|
||||
<div>
|
||||
<button type="submit">Unlink {$consumer/}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
{unless isempty="$oauth_not_associated"}
|
||||
<h4>Associate Account with Oauth Consumer</h4>
|
||||
<div>
|
||||
{foreach item="consumer" from="$oauth_not_associated"}
|
||||
<div>
|
||||
<form method="post" action="{$site_url/}account/oauth-associate">
|
||||
<input type="hidden" name="consumer" value="{$consumer/}"/>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<button type="submit">Link with {$consumer/}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
CREATE TABLE openid_consumers(
|
||||
`cid` INTEGER PRIMARY KEY NOT NULL CHECK(`cid`>=0),
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`endpoint` VARCHAR (255) NOT NULL,
|
||||
CONSTRAINT `cid`
|
||||
UNIQUE(`cid`),
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Change the values TO_COMPLETE based on your API.
|
||||
-- API SECTET KEY AND API PUBLIC KEY
|
||||
INSERT INTO openid_consumers (name, endpoint)
|
||||
VALUES ('yahoo', 'https://me.yahoo.com/');
|
||||
11
examples/demo/site/modules/openid/scripts/openid_items.sql
Normal file
11
examples/demo/site/modules/openid/scripts/openid_items.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
CREATE TABLE openid_items (
|
||||
`uid` INTEGER PRIMARY KEY NOT NULL CHECK(`uid`>=0),
|
||||
`identity` TEXT NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
CONSTRAINT `uid`
|
||||
UNIQUE(`uid`),
|
||||
CONSTRAINT `identity`
|
||||
UNIQUE(`identity`)
|
||||
);
|
||||
|
||||
18
examples/demo/site/modules/openid/templates/block_login.tpl
Normal file
18
examples/demo/site/modules/openid/templates/block_login.tpl
Normal file
@@ -0,0 +1,18 @@
|
||||
<div>
|
||||
<form action="{$site_url/}account/roc-openid-login" id="openid-login" method="POST">
|
||||
<div>
|
||||
<strong><label for="openid">OpenID identifier</label></strong><br/>
|
||||
<input type="text" name="openid" value="" size="50"/>
|
||||
</div>
|
||||
<div><input type="submit" name="op" value="Validate"/></div>
|
||||
<div hgv vtid="openid">Login with
|
||||
{foreach item="item" from="$openid_consumers"}
|
||||
<a href="{$site_url/}account/login-with-openid/{$item/}">{$item/}</a><br>
|
||||
{/foreach}
|
||||
</form>
|
||||
<div>
|
||||
{if isset="$error"}
|
||||
<span><i>{$error/}</i></span> <br>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,16 +51,24 @@ ul.horizontal li {
|
||||
.sidebar {
|
||||
padding: 5px;
|
||||
margin: 3px;
|
||||
border: solid 1px #ccc;
|
||||
/* border: solid 1px #ccc; */
|
||||
}
|
||||
.sidebar#sidebar_first {
|
||||
width: 250px;
|
||||
float: left;
|
||||
position: fixed;
|
||||
top: 45px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 200px;
|
||||
border-right: solid 1px #ddd;
|
||||
}
|
||||
.sidebar#sidebar_second {
|
||||
width: 250px;
|
||||
float: right;
|
||||
}
|
||||
.sidebar + .main {
|
||||
margin-left: 200px;
|
||||
}
|
||||
|
||||
#primary-tabs ul.horizontal {
|
||||
list-style-type: none;
|
||||
@@ -76,3 +84,9 @@ ul.horizontal li {
|
||||
border-width: 2px 1px 0;
|
||||
padding: 2px 7px 1px;
|
||||
}
|
||||
|
||||
#message li.error {
|
||||
background-color: #f99;
|
||||
border: solid 1px red;
|
||||
padding: 5px 2px 5px 2px;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -55,15 +55,24 @@ ul.horizontal {
|
||||
.sidebar {
|
||||
padding: 5px;
|
||||
margin: 3px;
|
||||
border: solid 1px #ccc;
|
||||
/* border: solid 1px #ccc; */
|
||||
&#sidebar_first {
|
||||
width: 250px;
|
||||
float: left;
|
||||
position: fixed;
|
||||
top: 45px;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 200px;
|
||||
border-right: solid 1px #ddd;
|
||||
}
|
||||
&#sidebar_second {
|
||||
width: 250px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
&+.main {
|
||||
margin-left: 200px;
|
||||
}
|
||||
}
|
||||
#primary-tabs {
|
||||
ul.horizontal {
|
||||
@@ -81,3 +90,8 @@ ul.horizontal {
|
||||
}
|
||||
}
|
||||
}
|
||||
#message li.error {
|
||||
background-color: #f99;
|
||||
border: solid 1px red;
|
||||
padding: 5px 2px 5px 2px;
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<div class='navbar navbar-inverse'>
|
||||
<div class='navbar-inner nav-collapse' style="height: auto;">
|
||||
<ul class="nav">
|
||||
{$header_block/}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -5,13 +5,14 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- EWF CMS -->
|
||||
<link rel="stylesheet" href="{$site_url/}theme/css/style.css">
|
||||
<link rel="stylesheet" href="{$site_url/}theme/css/node.css">
|
||||
|
||||
<!-- CMS Blog Module -->
|
||||
<link rel="stylesheet" href="{$site_url/}theme/css/blog.css">
|
||||
|
||||
<!-- jQuery dep -->
|
||||
<script src="{$site_url/}theme/js/jquery-1.10.2.min.js"></script>
|
||||
<script src="{$site_url/}theme/js/roc_auth.js"></script>
|
||||
|
||||
{if isset="$head"}{$head/}{/if}
|
||||
{if isset="$styles"}{$styles/}{/if}
|
||||
{if isset="$scripts"}{$scripts/}{/if}
|
||||
{if isset="$head_lines"}{$head_lines/}{/if}
|
||||
|
||||
<!-- bootstrap framework -->
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
@@ -48,7 +49,7 @@
|
||||
{/unless}
|
||||
|
||||
<!-- Highlighted, Help, Content -->
|
||||
<div class='span8 main'>
|
||||
<div id='main' class='span8 main'>
|
||||
<!-- Highlighted Section -->
|
||||
{unless isempty="$page.region_highlighted"}
|
||||
<div id="highlighted">{$page.region_highlighted/}</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ regions[content] = Content
|
||||
regions[highlighted] = Highlighted
|
||||
regions[help] = Help
|
||||
regions[footer] = Footer
|
||||
regions[first_sidebar] = first sidebar
|
||||
regions[second_sidebar] = second sidebar
|
||||
regions[sidebar_first] = first sidebar
|
||||
regions[sidebar_second] = second sidebar
|
||||
regions[page_bottom] = Bottom
|
||||
navigation=default_nav
|
||||
navigation=default_nav
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<h2>Help Section</h2>
|
||||
@@ -1 +0,0 @@
|
||||
<h1>Highlighted Section</h1>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div class='span2 sidebar'>
|
||||
<h3>Left Sidebar</h3>
|
||||
<ul class="nav nav-tabs nav-stacked">
|
||||
<li><a href='#'>Another Link 1</a></li>
|
||||
<li><a href='#'>Another Link 2</a></li>
|
||||
<li><a href='#'>Another Link 3</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1,4 +0,0 @@
|
||||
<h2>Main Content Section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.<p>
|
||||
|
||||
<p>Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
|
||||
@@ -1,9 +0,0 @@
|
||||
<div id="footer">
|
||||
<small>
|
||||
<center>
|
||||
<p class="text-muted"><a href="#" target="_blank" class="info">ROC Documentation </a>
|
||||
<a href="http://www.eiffel.com/company/contact/" target="_blank" class="info">Questions? Comments? Let us know! </a></p>
|
||||
<p>© Copyright 2014 Eiffel Software -- <a href="#" target="_blank" class="info">Privacy Policy</a>
|
||||
</center>
|
||||
</small>
|
||||
</div>
|
||||
@@ -1,34 +0,0 @@
|
||||
<div class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{$site_url/}" itemprop="home" rel="home">{unless isset="$site_name"}Eiffel CMS{/unless}{if isset="$site_name"}{$site_name/}{/if}</a>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse collapse">
|
||||
|
||||
{if isset="$primary_nav"}
|
||||
<ul class="nav navbar-nav navbar-left">
|
||||
{foreach item="item" from="$primary_nav.items"}
|
||||
<!-- TODO check if a menu item is active or not -->
|
||||
<li class="active"><a href="{$item.location/}">{$item.title/}</a></li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
{/if}
|
||||
|
||||
{if isset="$secondary_nav"}
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{foreach item="item" from="$secondary_nav.items"}
|
||||
<!-- TODO check if a menu item is active or not -->
|
||||
<li class="active"><a href="{$item.location/}">{$item.title/}</a></li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
{if isset="$default_nav"}
|
||||
<div class="navbar navbar-default" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="${site_url/}" itemprop="home" rel="home">{$page_title/}</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse collapse">
|
||||
{/if}
|
||||
|
||||
{if isset="$primary_nav"}
|
||||
{$primary_nav/}
|
||||
{/if}
|
||||
|
||||
{if isset="$secondary_nav"}
|
||||
{$secondary_nav/}
|
||||
{/if}
|
||||
|
||||
{if isset="$default_nav"}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -1,6 +0,0 @@
|
||||
<ul class="nav navbar-nav navbar-left">
|
||||
{foreach item="item" from="$menu.items"}
|
||||
<!-- TODO check if a menu item is active or not -->
|
||||
<li class="active"><a href="{$item.location/}">{$item.title/}</a></li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
@@ -1,8 +0,0 @@
|
||||
<div class='span2 sidebar'>
|
||||
<h3>Right Sidebar</h3>
|
||||
<ul class="nav nav-tabs nav-stacked">
|
||||
<li><a href='#'>Another Link 1</a></li>
|
||||
<li><a href='#'>Another Link 2</a></li>
|
||||
<li><a href='#'>Another Link 3</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1,7 +0,0 @@
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{foreach item="item" from="$menu.items"}
|
||||
<!-- TODO check if a menu item is active or not -->
|
||||
<li class="active"><a href="{$item.location/}">{$item.title/}</a></li>
|
||||
{/foreach}
|
||||
</ul>
|
||||
|
||||
5849
examples/demo/site/www/static/css/bootstrap.css
vendored
5849
examples/demo/site/www/static/css/bootstrap.css
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* Base structure
|
||||
*/
|
||||
|
||||
/* Move down content because we have a fixed navbar that is 36px tall on small screen */
|
||||
body {
|
||||
padding-top: 40px;
|
||||
}
|
||||
/* On large screen, we give it more space and the navbar is 30px tall. */
|
||||
@media (min-width: 768px) {
|
||||
body {
|
||||
padding-top: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Global add-ons
|
||||
*/
|
||||
|
||||
h1 {
|
||||
margin-top: initial;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
h2.sub-header{
|
||||
margin-top: 1px;
|
||||
margin-bottom: 1px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
|
||||
.container .jumbotron {
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
/* Hide for mobile, show later */
|
||||
.sidebar {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
display: block;
|
||||
padding: 70px 20px 20px;
|
||||
background-color: #f5f5f5;
|
||||
border-right: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar navigation */
|
||||
.nav-sidebar {
|
||||
margin-left: -20px;
|
||||
margin-right: -21px; /* 20px padding + 1px border */
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.nav-sidebar > li > a {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.nav-sidebar > .active > a {
|
||||
color: #fff;
|
||||
background-color: #428bca;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main content
|
||||
*/
|
||||
|
||||
.main {
|
||||
padding: 3px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.main {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
.main .page-header {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Placeholder dashboard ideas
|
||||
*/
|
||||
|
||||
.placeholders {
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
.placeholders h4 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.placeholder {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.placeholder img {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.navbar-default {
|
||||
background-color:#194573;
|
||||
border-color: #400040;
|
||||
}
|
||||
.navbar-default .navbar-brand {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-text {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav > li > a {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #400040;
|
||||
}
|
||||
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #400040;
|
||||
}
|
||||
.navbar-default .navbar-toggle {
|
||||
border-color: #400040;
|
||||
}
|
||||
.navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus {
|
||||
background-color: #400040;
|
||||
}
|
||||
.navbar-default .navbar-toggle .icon-bar {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-collapse,
|
||||
.navbar-default .navbar-form {
|
||||
border-color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-link {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-link:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
|
||||
color: #ffffff;
|
||||
}
|
||||
.navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {
|
||||
color: #ffffff;
|
||||
background-color: #400040;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-nav > li > a {padding-top:5px !important; padding-bottom:5px !important;}
|
||||
.navbar {min-height:30px !important}
|
||||
|
||||
.navbar-brand {
|
||||
float: left;
|
||||
padding: 15px;
|
||||
padding-top: 5px;
|
||||
padding-right: 15px;
|
||||
padding-bottom: 5px;
|
||||
padding-left: 15px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltips */
|
||||
.blue-tooltip + .tooltip > .tooltip-inner {background-color: #FF;}
|
||||
.blue-tooltip + .tooltip > .tooltip-arrow { border-bottom-color:#FF; }
|
||||
|
||||
|
||||
.tooltip.top .tooltip-arrow {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-top-color: #000000;
|
||||
border-width: 5px 5px 0;
|
||||
}
|
||||
.tooltip-inner {
|
||||
text-align: left;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
border: solid 1px #000000;
|
||||
max-width: 450px
|
||||
}
|
||||
|
||||
.tooltip.bottom .tooltip-arrow {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
margin-left: -5px;
|
||||
border-bottom-color: #000000;
|
||||
border-width: 0 5px 5px;
|
||||
}
|
||||
|
||||
/* pre */
|
||||
pre {
|
||||
word-wrap: code;
|
||||
white-space: pre-wrap;
|
||||
background-color:white;
|
||||
}
|
||||
|
||||
|
||||
/* Container -Fluid */
|
||||
.container-fluid {
|
||||
padding: 0 2px;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
.container-fluid {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.container-fluid .row {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.row-padding {
|
||||
margin-top: 25px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
/* Width for the text field to enter a bug report number in the reports page.
|
||||
* We put a maximum width to override the width value coming from `form-control'. */
|
||||
.form-bug-number-entry {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
/* Default width for the entries in a table like layout. */
|
||||
.form-inline .form-control {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.form-inline .checkbox {
|
||||
font-weight: initial;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* Note that there is also a class called label. */
|
||||
label {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.label {
|
||||
padding: 0px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.label-primary-api-default {
|
||||
display: inline-block;
|
||||
width: 105px;
|
||||
text-align: left;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
font-size: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
.label-primary-api-interactions {
|
||||
display: inline-block;
|
||||
padding-right: 5px;
|
||||
text-align: left;
|
||||
color: #000;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
|
||||
pre {
|
||||
padding: 1.5px;
|
||||
display: block;
|
||||
margin: 0 0 10px;
|
||||
font-size: 12px;
|
||||
font-family: monospace;
|
||||
line-height: 1.428571429;
|
||||
word-break: break-word;
|
||||
word-wrap: break-word;
|
||||
color: #333;
|
||||
border: 0px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
||||
/* No padding, so that nested columns are always properly aligned. */
|
||||
.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12 {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td {
|
||||
padding:2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.form-control{
|
||||
height:inherit;
|
||||
padding: 1px 2px;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 1px 12px;
|
||||
margin: 1px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.dropdown-toggle, .login {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pager {
|
||||
margin:10px 0;
|
||||
}
|
||||
|
||||
.pager li>a,.pager li>span {
|
||||
padding:1px 12px;
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
.well {
|
||||
padding: 9px;
|
||||
margin-bottom: 10px;
|
||||
min-height: 44px;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
background-color: #ddeaf2 !important;
|
||||
}
|
||||
|
||||
.private-panel-border {
|
||||
border: solid 1px #DBA458 !important;
|
||||
}
|
||||
|
||||
.private-panel {
|
||||
background-color: #f2eadd !important;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* EWF CMS javascript based on JQuery
|
||||
*/
|
||||
|
||||
/**
|
||||
* Override jQuery.fn.init to guard against XSS attacks.
|
||||
*
|
||||
* See http://bugs.jquery.com/ticket/9521
|
||||
*/
|
||||
|
||||
(function () {
|
||||
var jquery_init = jQuery.fn.init;
|
||||
jQuery.fn.init = function (selector, context, rootjQuery) {
|
||||
// If the string contains a "#" before a "<", treat it as invalid HTML.
|
||||
if (selector && typeof selector === 'string') {
|
||||
var hash_position = selector.indexOf('#');
|
||||
if (hash_position >= 0) {
|
||||
var bracket_position = selector.indexOf('<');
|
||||
if (bracket_position > hash_position) {
|
||||
throw 'Syntax error, unrecognized expression: ' + selector;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jquery_init.call(this, selector, context, rootjQuery);
|
||||
};
|
||||
jQuery.fn.init.prototype = jquery_init.prototype;
|
||||
})();
|
||||
|
||||
|
||||
var ROC = ROC || { };
|
||||
|
||||
$('body').on('click',"a[rel='node']",function(e){
|
||||
|
||||
e.preventDefault();
|
||||
/*
|
||||
if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content;
|
||||
if commented, html5 nonsupported browers will reload the page to the specified link.
|
||||
*/
|
||||
|
||||
//get the link location that was clicked
|
||||
pageurl = $(this).attr('href');
|
||||
|
||||
spinner = "<span class='loading'><h3>Loading content..</h3><img src='/static/images/ajax-loader.gif' alt='loading...' class='spinner'></span>";
|
||||
//to get the ajax content and display in div with class 'main'
|
||||
$.ajax({url:pageurl+'?rel=node',success: function(data){
|
||||
$('.main').html(data);
|
||||
}});
|
||||
|
||||
//to change the browser URL to the given link location
|
||||
//if(pageurl!=window.location){
|
||||
//window.history.pushState({path:pageurl},'',pageurl);
|
||||
//}
|
||||
//stop refreshing to the page given in
|
||||
return false;
|
||||
});
|
||||
|
||||
$('body').on('click',"a[rel='register']",function(e){
|
||||
|
||||
e.preventDefault();
|
||||
/*
|
||||
if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content;
|
||||
if commented, html5 nonsupported browers will reload the page to the specified link.
|
||||
*/
|
||||
|
||||
//get the link location that was clicked
|
||||
pageurl = $(this).attr('href');
|
||||
|
||||
spinner = "<span class='loading'><h3>Loading content..</h3><img src='/static/images/ajax-loader.gif' alt='loading...' class='spinner'></span>";
|
||||
//to get the ajax content and display in div with class 'main'
|
||||
$.ajax({url:pageurl+'?rel=node',success: function(data){
|
||||
$('.main').html(data);
|
||||
}});
|
||||
|
||||
//to change the browser URL to the given link location
|
||||
//if(pageurl!=window.location){
|
||||
//window.history.pushState({path:pageurl},'',pageurl);
|
||||
//}
|
||||
//stop refreshing to the page given in
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
|
||||
$("a[rel='node']").click(function(e){
|
||||
e.preventDefault();
|
||||
/*
|
||||
if uncomment the above line, html5 nonsupported browers won't change the url but will display the ajax content;
|
||||
if commented, html5 nonsupported browers will reload the page to the specified link.
|
||||
*/
|
||||
|
||||
//get the link location that was clicked
|
||||
pageurl = $(this).attr('href');
|
||||
|
||||
spinner = "<span class='loading'><h3>Loading content..</h3><img src='/static/images/ajax-loader.gif' alt='loading...' class='spinner'></span>";
|
||||
//to get the ajax content and display in div with class 'main'
|
||||
$.ajax({url:pageurl+'?rel=node',success: function(data){
|
||||
$('.main').html(data);
|
||||
}});
|
||||
|
||||
//to change the browser URL to the given link location
|
||||
//if(pageurl!=window.location){
|
||||
//window.history.pushState({path:pageurl},'',pageurl);
|
||||
//}
|
||||
//stop refreshing to the page given in
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
@@ -55,34 +55,39 @@ feature -- CMS setup
|
||||
local
|
||||
m: CMS_MODULE
|
||||
do
|
||||
create {NODE_MODULE} m.make (a_setup)
|
||||
m.enable
|
||||
create {CMS_ADMIN_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
-- Auth
|
||||
create {CMS_AUTHENTICATION_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {BASIC_AUTH_MODULE} m.make
|
||||
if not a_setup.module_with_same_type_registered (m) then
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
end
|
||||
create {CMS_BASIC_AUTH_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_OAUTH_20_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_DEBUG_MODULE} m.make
|
||||
m.enable
|
||||
create {CMS_OPENID_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_DEMO_MODULE} m.make
|
||||
m.enable
|
||||
-- Nodes
|
||||
create {CMS_NODE_MODULE} m.make (a_setup)
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_BLOG_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
-- Recent changes
|
||||
create {CMS_RECENT_CHANGES_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
|
||||
-- Miscellanious
|
||||
create {CMS_DEBUG_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_DEMO_MODULE} m.make
|
||||
a_setup.register_module (m)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?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="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
|
||||
<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="config_tests" library_target="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
|
||||
<target name="config_tests">
|
||||
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
|
||||
<file_rule>
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms_app_env" location="..\app_env\app_env-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="notification_mailer" location="$ISE_LIBRARY\contrib\library\runtime\process\notification_email\notification_email-safe.ecf"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -26,8 +26,6 @@ feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
-- Initialize service.
|
||||
local
|
||||
l_address_factory: INET_ADDRESS_FACTORY
|
||||
do
|
||||
admin_email := parameters.admin_email
|
||||
|
||||
|
||||
@@ -41,6 +41,11 @@ feature -- Status report
|
||||
has_children: BOOLEAN = False
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Security
|
||||
|
||||
is_forbidden: BOOLEAN = False
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access
|
||||
|
||||
children: detachable LIST [CMS_LINK]
|
||||
@@ -48,6 +53,6 @@ feature -- Access
|
||||
|
||||
invariant
|
||||
note
|
||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -49,7 +49,7 @@ feature -- Comparison
|
||||
end
|
||||
end
|
||||
|
||||
feature -- status report
|
||||
feature -- Status report
|
||||
|
||||
is_active: BOOLEAN
|
||||
-- Is current link active?
|
||||
@@ -79,6 +79,14 @@ feature -- status report
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Security
|
||||
|
||||
is_forbidden: BOOLEAN
|
||||
-- Is Current link forbidden?
|
||||
-- Current link could be disabled for current CMS user.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_weight (a_weight: INTEGER)
|
||||
|
||||
@@ -71,6 +71,12 @@ feature -- Status report
|
||||
Result := attached children as l_children and then not l_children.is_empty
|
||||
end
|
||||
|
||||
feature -- Security
|
||||
|
||||
is_forbidden: BOOLEAN
|
||||
-- <Precursor>
|
||||
-- Related to `permission_arguments' values.
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_title (a_title: detachable READABLE_STRING_GENERAL)
|
||||
@@ -167,6 +173,16 @@ feature -- Status change
|
||||
is_expandable: is_expandable = b
|
||||
end
|
||||
|
||||
feature -- Security change
|
||||
|
||||
set_is_forbidden (b: BOOLEAN)
|
||||
-- Set `is_forbidden' to `b'.
|
||||
do
|
||||
is_forbidden := b
|
||||
ensure
|
||||
is_forbidden: is_forbidden = b
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_is_expandable: BOOLEAN
|
||||
|
||||
@@ -81,6 +81,16 @@ feature -- Access
|
||||
-- trashed
|
||||
|
||||
|
||||
feature -- Access: helper
|
||||
|
||||
utf_8_name: STRING_8
|
||||
-- UTF-8 version of `name'.
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
Result := utf.utf_32_string_to_utf_8_string_8 (name)
|
||||
end
|
||||
|
||||
feature -- Roles
|
||||
|
||||
roles: detachable LIST [CMS_USER_ROLE]
|
||||
|
||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Factory
|
||||
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_MYSQL
|
||||
storage (a_setup: CMS_SETUP; a_error_handler: ERROR_HANDLER): detachable CMS_STORAGE_STORE_MYSQL
|
||||
local
|
||||
conn: DATABASE_CONNECTION
|
||||
do
|
||||
@@ -40,6 +40,8 @@ feature -- Factory
|
||||
initialize (a_setup, Result)
|
||||
end
|
||||
end
|
||||
else
|
||||
a_error_handler.add_custom_error (0, "Could not connect to the MySQL storage", Void)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Factory
|
||||
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_ODBC
|
||||
storage (a_setup: CMS_SETUP; a_error_handler: ERROR_HANDLER): detachable CMS_STORAGE_STORE_ODBC
|
||||
local
|
||||
s: detachable STRING
|
||||
conn: detachable DATABASE_CONNECTION
|
||||
@@ -53,6 +53,8 @@ feature -- Factory
|
||||
initialize (a_setup, Result)
|
||||
end
|
||||
end
|
||||
else
|
||||
a_error_handler.add_custom_error (0, "Could not connect to the ODBC storage", Void)
|
||||
end
|
||||
else
|
||||
-- Wrong mapping between storage name and storage builder!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="tests" uuid="FE27C81D-3F7D-4E46-992B-55F4BBDA4F8B">
|
||||
<target name="tests">
|
||||
<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="tests_store_odbc" library_target="tests_store_odbc" uuid="FE27C81D-3F7D-4E46-992B-55F4BBDA4F8B">
|
||||
<target name="tests_store_odbc">
|
||||
<root class="APPLICATION" feature="make"/>
|
||||
<option warning="true" void_safety="conformance">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
|
||||
28
modules/admin/admin-safe.ecf
Normal file
28
modules/admin/admin-safe.ecf
Normal file
@@ -0,0 +1,28 @@
|
||||
<?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="admin" uuid="7195898D-7ACB-40D1-B85A-EE83E0DC695A" library_target="admin">
|
||||
<target name="admin">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</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"/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="..\..\cms-safe.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
|
||||
<library name="cms_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
||||
<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"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
128
modules/admin/cms_admin_module.e
Normal file
128
modules/admin/cms_admin_module.e
Normal file
@@ -0,0 +1,128 @@
|
||||
note
|
||||
description: "CMS module providing Administration support (back-end)."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
register_hooks,
|
||||
permissions
|
||||
end
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_RESPONSE_ALTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create Current module, disabled by default.
|
||||
do
|
||||
version := "1.0"
|
||||
description := "Service to Administrate CMS (users, modules, etc)"
|
||||
package := "core"
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "admin"
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
configure_web (a_api, a_router)
|
||||
end
|
||||
|
||||
configure_web (a_api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_admin_handler: CMS_ADMIN_HANDLER
|
||||
l_users_handler: CMS_ADMIN_USERS_HANDLER
|
||||
l_roles_handler: CMS_ADMIN_ROLES_HANDLER
|
||||
|
||||
l_user_handler: CMS_USER_HANDLER
|
||||
l_role_handler: CMS_ROLE_HANDLER
|
||||
|
||||
l_uri_mapping: WSF_URI_MAPPING
|
||||
do
|
||||
create l_admin_handler.make (a_api)
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("/admin", l_admin_handler)
|
||||
a_router.map (l_uri_mapping, a_router.methods_get_post)
|
||||
|
||||
create l_users_handler.make (a_api)
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("/admin/users", l_users_handler)
|
||||
a_router.map (l_uri_mapping, a_router.methods_get_post)
|
||||
|
||||
create l_roles_handler.make (a_api)
|
||||
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_user_handler.make (a_api)
|
||||
a_router.handle ("/admin/add/user", l_user_handler, a_router.methods_get_post)
|
||||
a_router.handle ("/admin/user/{id}", l_user_handler, a_router.methods_get)
|
||||
a_router.handle ("/admin/user/{id}/edit", l_user_handler, a_router.methods_get_post)
|
||||
a_router.handle ("/admin/user/{id}/delete", l_user_handler, a_router.methods_get_post)
|
||||
|
||||
create l_role_handler.make (a_api)
|
||||
a_router.handle ("/admin/add/role", l_role_handler, a_router.methods_get_post)
|
||||
a_router.handle ("/admin/role/{id}", l_role_handler, a_router.methods_get)
|
||||
a_router.handle ("/admin/role/{id}/edit", l_role_handler, a_router.methods_get_post)
|
||||
a_router.handle ("/admin/role/{id}/delete", l_role_handler, a_router.methods_get_post)
|
||||
end
|
||||
|
||||
feature -- Security
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force ("manage admin")
|
||||
Result.force ("admin users")
|
||||
Result.force ("admin roles")
|
||||
Result.force ("admin modules")
|
||||
Result.force ("install modules")
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
a_response.hooks.subscribe_to_menu_system_alter_hook (Current)
|
||||
a_response.hooks.subscribe_to_response_alter_hook (Current)
|
||||
end
|
||||
|
||||
response_alter (a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
a_response.add_style (a_response.url ("/module/" + name + "/files/css/admin.css", Void), Void)
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
89
modules/admin/handler/cms_admin_handler.e
Normal file
89
modules/admin/handler/cms_admin_handler.e
Normal file
@@ -0,0 +1,89 @@
|
||||
note
|
||||
description: "[
|
||||
handler for CMS admin in the CMS interface.
|
||||
|
||||
TODO: implement REST API.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_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,
|
||||
do_post
|
||||
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)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then
|
||||
create {CMS_ADMIN_RESPONSE} r.make (req, res, api)
|
||||
r.execute
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then
|
||||
create {CMS_ADMIN_RESPONSE} r.make (req, res, api)
|
||||
r.execute
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
59
modules/admin/handler/cms_admin_response.e
Normal file
59
modules/admin/handler/cms_admin_response.e
Normal file
@@ -0,0 +1,59 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ADMIN_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Process
|
||||
|
||||
process
|
||||
local
|
||||
b: STRING
|
||||
do
|
||||
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>")
|
||||
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
|
||||
|
||||
end
|
||||
112
modules/admin/handler/role/cms_admin_roles_handler.e
Normal file
112
modules/admin/handler/role/cms_admin_roles_handler.e
Normal file
@@ -0,0 +1,112 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ADMIN_ROLE_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_ROLES_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)
|
||||
local
|
||||
l_response: CMS_RESPONSE
|
||||
s: STRING
|
||||
u: CMS_USER_ROLE
|
||||
l_count: INTEGER
|
||||
user_api: CMS_USER_API
|
||||
do
|
||||
-- At the moment the template are hardcoded, but we can
|
||||
-- get them from the configuration file and load them into
|
||||
-- the setup class.
|
||||
|
||||
|
||||
user_api := api.user_api
|
||||
|
||||
l_count := user_api.roles_count
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
|
||||
|
||||
create s.make_empty
|
||||
if l_count > 1 then
|
||||
l_response.set_title ("Listing " + l_count.out + " Roles")
|
||||
else
|
||||
l_response.set_title ("Listing " + l_count.out + " Role")
|
||||
end
|
||||
|
||||
if attached user_api.roles as lst then
|
||||
s.append ("<ul class=%"cms-roles%">%N")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
u := ic.item
|
||||
s.append ("<li class=%"cms_role%">")
|
||||
s.append ("<a href=%"")
|
||||
s.append (req.absolute_script_url ("/admin/role/" + u.id.out))
|
||||
s.append ("%">")
|
||||
s.append (u.name)
|
||||
s.append ("</a>")
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
|
||||
if l_response.has_permission ("admin roles") then
|
||||
s.append (l_response.link ("Add Role", "admin/add/role", Void))
|
||||
end
|
||||
|
||||
|
||||
l_response.set_main_content (s)
|
||||
l_response.execute
|
||||
end
|
||||
end
|
||||
|
||||
509
modules/admin/handler/role/cms_role_form_response.e
Normal file
509
modules/admin/handler/role/cms_role_form_response.e
Normal file
@@ -0,0 +1,509 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ROLE_FORM_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ROLE_FORM_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
CMS_SHARED_SORTING_UTILITIES
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Query
|
||||
|
||||
role_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- Role id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Process
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
b: STRING_8
|
||||
uid: INTEGER_64
|
||||
user_api: CMS_USER_API
|
||||
do
|
||||
user_api := api.user_api
|
||||
create b.make_empty
|
||||
uid := role_id_path_parameter (request)
|
||||
if uid > 0 and then attached user_api.user_role_by_id (uid.to_integer) as l_role then
|
||||
fixme ("Issues with WSD_FORM_DATA.apply_to_associated_form")
|
||||
-- if we have a WSF_FORM_CHECKBOK_INPUT, cheked inputs, are not preserverd in case of error.
|
||||
if location.ends_with_general ("/edit") then
|
||||
edit_form (l_role)
|
||||
elseif location.ends_with_general ("/delete") then
|
||||
delete_form (l_role)
|
||||
end
|
||||
else
|
||||
new_form
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Process Edit
|
||||
|
||||
edit_form (a_role: CMS_USER_ROLE)
|
||||
local
|
||||
f: like new_edit_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_edit_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent edit_form_validate(?,a_role, b))
|
||||
f.submit_actions.extend (agent edit_form_submit(?, a_role, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if a_role.has_id then
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void), "admin/role/" + a_role.id.out), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void), "admin/role/" + a_role.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Delete", Void), "admin/role/" + a_role.id.out + "/delete"), primary_tabs)
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (a_role.name)
|
||||
b.append (html_encoded (a_role.name) + " saved")
|
||||
else
|
||||
set_title (formatted_string (translation ("Edit $1 #$2", Void), [a_role.name, a_role.id]))
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Process Delete
|
||||
|
||||
delete_form (a_role: CMS_USER_ROLE)
|
||||
local
|
||||
f: like new_delete_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_delete_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if a_role.has_id then
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void), "admin/role/" + a_role.id.out), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void), "admin/role/" + a_role.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Delete", Void), "admin/role/" + a_role.id.out + "/delete"), primary_tabs)
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (a_role.name)
|
||||
b.append (html_encoded (a_role.name) + " deleted")
|
||||
else
|
||||
set_title (formatted_string (translation ("Delete $1 #$2", Void), [a_role.name, a_role.id]))
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Process New
|
||||
|
||||
new_form
|
||||
local
|
||||
f: like new_edit_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
l_role: detachable CMS_USER_ROLE
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_edit_form (l_role, url (request.percent_encoded_path_info, Void), "create-role")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent new_form_validate(?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit(?, l_role, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
if attached l_role then
|
||||
set_title (l_role.name)
|
||||
b.append (html_encoded (l_role.name) + " Saved")
|
||||
end
|
||||
else
|
||||
if attached l_role then
|
||||
set_title (formatted_string (translation ("Saved $1 #$2", Void), [l_role.name, l_role.id]))
|
||||
end
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Form
|
||||
|
||||
edit_form_submit (fd: WSF_FORM_DATA; a_role: detachable CMS_USER_ROLE; b: STRING)
|
||||
local
|
||||
l_save_role: BOOLEAN
|
||||
l_update_role: BOOLEAN
|
||||
do
|
||||
l_save_role := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Create role")
|
||||
if l_save_role then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
create_role (fd)
|
||||
else
|
||||
l_update_role := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update role")
|
||||
if l_update_role then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
if a_role /= Void then
|
||||
update_role (fd, a_role)
|
||||
else
|
||||
fd.report_error ("Missing Role")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
edit_form_validate (fd: WSF_FORM_DATA; a_role: CMS_USER_ROLE; b: STRING)
|
||||
do
|
||||
if attached fd.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Update role") then
|
||||
if
|
||||
attached fd.string_item ("role") as l_role and then
|
||||
not a_role.name.is_case_insensitive_equal (l_role)
|
||||
then
|
||||
if attached api.user_api.user_role_by_name (l_role) then
|
||||
fd.report_invalid_field ("role", "Role already taken!")
|
||||
end
|
||||
else
|
||||
if fd.string_item ("role") = Void then
|
||||
fd.report_invalid_field ("role", "missing role")
|
||||
end
|
||||
end
|
||||
if attached {WSF_TABLE} fd.item ("new_cms_permissions[]") as l_perm then
|
||||
a_role.permissions.compare_objects
|
||||
across
|
||||
l_perm.values as ic
|
||||
loop
|
||||
if attached {WSF_STRING} ic.item as p then
|
||||
if not p.value.is_valid_as_string_8 then
|
||||
fd.report_invalid_field ("new_cms_permissions[]", "Permission " + p.value + " should not have any unicode character!")
|
||||
elseif across a_role.permissions as p_ic some p_ic.item.is_case_insensitive_equal_general (p.value) end then
|
||||
fd.report_invalid_field ("new_cms_permissions[]", "Permission " + p.value + " already exists!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_edit_form (a_role: detachable CMS_USER_ROLE; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM
|
||||
-- Create a web form named `a_name' for uSER `a_YSER' (if set), using form action url `a_url'.
|
||||
local
|
||||
f: CMS_FORM
|
||||
th: WSF_FORM_HIDDEN_INPUT
|
||||
do
|
||||
create f.make (a_url, a_name)
|
||||
create th.make ("role-id")
|
||||
if a_role /= Void then
|
||||
th.set_text_value (a_role.id.out)
|
||||
else
|
||||
th.set_text_value ("0")
|
||||
end
|
||||
f.extend (th)
|
||||
populate_form (f, a_role)
|
||||
Result := f
|
||||
end
|
||||
|
||||
new_form_validate (fd: WSF_FORM_DATA; b: STRING)
|
||||
do
|
||||
if attached fd.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Create role") then
|
||||
if attached fd.string_item ("role") as l_role then
|
||||
if attached api.user_api.user_role_by_name (l_role) then
|
||||
fd.report_invalid_field ("role", "Role already taken!")
|
||||
end
|
||||
else
|
||||
fd.report_invalid_field ("role", "missing role")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_delete_form (a_role: detachable CMS_USER_ROLE; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM
|
||||
-- Create a web form named `a_name' for role `a_role' (if set), using form action url `a_url'.
|
||||
local
|
||||
f: CMS_FORM
|
||||
ts: WSF_FORM_SUBMIT_INPUT
|
||||
do
|
||||
create f.make (a_url, a_name)
|
||||
f.extend_html_text ("<br/>")
|
||||
f.extend_html_text ("<legend>Are you sure you want to delete?</legend>")
|
||||
|
||||
-- TODO check if we need to check for has_permissions!!
|
||||
if a_role /= Void and then a_role.has_id then
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Delete")
|
||||
fixme ("[
|
||||
ts.set_default_value (translation ("Delete"))
|
||||
]")
|
||||
f.extend (ts)
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Cancel")
|
||||
ts.set_formmethod ("GET")
|
||||
ts.set_formaction ("/admin/role/" + a_role.id.out)
|
||||
f.extend (ts)
|
||||
end
|
||||
Result := f
|
||||
end
|
||||
|
||||
populate_form (a_form: WSF_FORM; a_role: detachable CMS_USER_ROLE)
|
||||
-- Fill the web form `a_form' with data from `a_node' if set,
|
||||
-- and apply this to content type `a_content_type'.
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
-- fe: WSF_FORM_EMAIL_INPUT
|
||||
fs: WSF_FORM_FIELD_SET
|
||||
cb: WSF_FORM_CHECKBOX_INPUT
|
||||
ts: WSF_FORM_SUBMIT_INPUT
|
||||
-- tb: WSF_FORM_BUTTON_INPUT
|
||||
lab: WSF_WIDGET_TEXT
|
||||
l_role_permissions: detachable LIST [READABLE_STRING_8]
|
||||
l_module_names: ARRAYED_LIST [READABLE_STRING_8]
|
||||
l_mod_name: READABLE_STRING_8
|
||||
do
|
||||
if attached a_role as l_role then
|
||||
create fs.make
|
||||
fs.set_legend ("User Role")
|
||||
create ti.make_with_text ("role", a_role.name)
|
||||
ti.set_label ("Role")
|
||||
ti.enable_required
|
||||
fs.extend (ti)
|
||||
a_form.extend (fs)
|
||||
|
||||
a_form.extend_html_text ("<br/>")
|
||||
|
||||
create fs.make
|
||||
fs.set_legend ("Permissions")
|
||||
|
||||
if
|
||||
attached api.user_api.role_permissions as l_permissions_by_module
|
||||
then
|
||||
l_role_permissions := l_role.permissions
|
||||
l_role_permissions.compare_objects
|
||||
|
||||
create l_module_names.make (l_permissions_by_module.count)
|
||||
across
|
||||
l_permissions_by_module as mod_ic
|
||||
loop
|
||||
l_module_names.force (mod_ic.key)
|
||||
end
|
||||
string_sorter.sort (l_module_names)
|
||||
across
|
||||
l_module_names as mod_ic
|
||||
loop
|
||||
l_mod_name := mod_ic.item
|
||||
if
|
||||
attached l_permissions_by_module.item (l_mod_name) as l_permissions and then
|
||||
not l_permissions.is_empty
|
||||
then
|
||||
if l_mod_name.is_whitespace then
|
||||
l_mod_name := "... "
|
||||
end
|
||||
|
||||
create lab.make_with_text ("<strong>" + l_mod_name + " module</strong>")
|
||||
|
||||
fs.extend (lab)
|
||||
string_sorter.sort (l_permissions)
|
||||
across l_permissions as ic loop
|
||||
create cb.make_with_value ("cms_permissions", ic.item)
|
||||
cb.set_checked (across l_role_permissions as rp_ic some rp_ic.item.is_case_insensitive_equal (ic.item) end)
|
||||
cb.set_title (ic.item)
|
||||
fs.extend (cb)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
create ti.make ("new_cms_permissions[]")
|
||||
fs.extend (ti)
|
||||
fs.extend_html_text ("<div class=%"input_fields_wrap%"></div>")
|
||||
fs.extend_html_text ("<button class=%"add_field_button%">Add More Permissions</button>")
|
||||
|
||||
|
||||
a_form.extend (fs)
|
||||
add_javascript_content (script_add_remove_items)
|
||||
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Update role")
|
||||
a_form.extend (ts)
|
||||
a_form.extend_html_text ("<hr>")
|
||||
|
||||
else
|
||||
create fs.make
|
||||
fs.set_legend ("User Role")
|
||||
create ti.make ("role")
|
||||
ti.set_label ("Role")
|
||||
ti.enable_required
|
||||
fs.extend (ti)
|
||||
a_form.extend (fs)
|
||||
a_form.extend_html_text ("<br/>")
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Create role")
|
||||
a_form.extend (ts)
|
||||
a_form.extend_html_text ("<hr>")
|
||||
end
|
||||
end
|
||||
|
||||
update_role (a_form_data: WSF_FORM_DATA; a_role: CMS_USER_ROLE)
|
||||
-- Update node `a_node' with form_data `a_form_data' for the given content type `a_content_type'.
|
||||
local
|
||||
l_perm: READABLE_STRING_8
|
||||
do
|
||||
if attached a_form_data.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Update role") then
|
||||
if
|
||||
attached a_form_data.string_item("role") as l_role_name and then
|
||||
attached a_form_data.string_item ("role-id") as l_role_id
|
||||
and then attached {CMS_USER_ROLE} api.user_api.user_role_by_id (l_role_id.to_integer) as l_role
|
||||
then
|
||||
if attached {WSF_STRING} a_form_data.item ("cms_permissions") as u_role then
|
||||
a_role.permissions.wipe_out
|
||||
a_role.add_permission (u_role.value)
|
||||
elseif attached {WSF_MULTIPLE_STRING} a_form_data.item ("cms_permissions") as u_permissions then
|
||||
a_role.permissions.wipe_out
|
||||
-- Enable checked permissions.
|
||||
across
|
||||
u_permissions as ic
|
||||
loop
|
||||
l_perm := ic.item.value.as_string_8
|
||||
if not l_perm.is_whitespace then
|
||||
a_role.add_permission (l_perm)
|
||||
end
|
||||
end
|
||||
else
|
||||
a_role.permissions.wipe_out
|
||||
end
|
||||
if attached {WSF_TABLE} a_form_data.item ("new_cms_permissions[]") as l_cms_perms then
|
||||
-- Add new permissions as checked.
|
||||
across
|
||||
l_cms_perms.values as ic
|
||||
loop
|
||||
if attached {WSF_STRING} ic.item as p then
|
||||
l_perm := p.value.as_string_8
|
||||
if not l_perm.is_whitespace then
|
||||
a_role.add_permission (l_perm)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not a_form_data.has_error then
|
||||
a_role.set_name (l_role_name)
|
||||
api.user_api.save_user_role (a_role)
|
||||
if not api.user_api.has_error then
|
||||
add_success_message ("Permissions updated")
|
||||
set_redirection (absolute_url ("admin/role/" + a_role.id.out, Void))
|
||||
else
|
||||
add_error_message ("Error during permissions update operation.")
|
||||
end
|
||||
end
|
||||
else
|
||||
a_form_data.report_error ("Missing Role")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
create_role (a_form_data: WSF_FORM_DATA)
|
||||
local
|
||||
u: CMS_USER_ROLE
|
||||
do
|
||||
if attached a_form_data.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Create role") then
|
||||
if attached a_form_data.string_item ("role") as l_role then
|
||||
create u.make (l_role)
|
||||
api.user_api.save_user_role (u)
|
||||
if api.user_api.has_error then
|
||||
-- handle error
|
||||
else
|
||||
add_success_message ("Created Role " + link (l_role, "admin/role/" + u.id.out, Void))
|
||||
set_redirection (absolute_url ("admin/role/" + u.id.out, Void))
|
||||
end
|
||||
else
|
||||
a_form_data.report_invalid_field ("username", "Missing role!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Generation
|
||||
|
||||
script_add_remove_items: STRING = "[
|
||||
$(document).ready(function() {
|
||||
var wrapper = $(".input_fields_wrap"); //Fields wrapper
|
||||
var add_button = $(".add_field_button"); //Add button ID
|
||||
|
||||
$(add_button).click(function(e){ //on add input button click
|
||||
e.preventDefault();
|
||||
$(wrapper).append('<div><input type="text" name="new_cms_permissions[]"/><a href="#" class="remove_field">Remove</a></div>'); //add input box
|
||||
});
|
||||
|
||||
$(wrapper).on("click",".remove_field", function(e){ //user click on remove text
|
||||
e.preventDefault(); $(this).parent('div').remove(); x--;
|
||||
})
|
||||
});
|
||||
]"
|
||||
|
||||
end
|
||||
203
modules/admin/handler/role/cms_role_handler.e
Normal file
203
modules/admin/handler/role/cms_role_handler.e
Normal file
@@ -0,0 +1,203 @@
|
||||
note
|
||||
description: "[
|
||||
Handler for a CMS user in the CMS interface
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ROLE_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,
|
||||
do_post,
|
||||
do_delete
|
||||
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 -- Query
|
||||
|
||||
role_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- User id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_role: detachable CMS_USER_ROLE
|
||||
l_uid: INTEGER_64
|
||||
edit_response: CMS_ROLE_FORM_RESPONSE
|
||||
view_response: CMS_ROLE_VIEW_RESPONSE
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("admin roles") then
|
||||
if req.percent_encoded_path_info.ends_with_general ("/edit") then
|
||||
check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/role/") end
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/delete") then
|
||||
check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/role/") end
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
else
|
||||
-- Display existing node
|
||||
l_uid := role_id_path_parameter (req)
|
||||
if l_uid > 0 then
|
||||
l_role := api.user_api.user_role_by_id (l_uid.to_integer)
|
||||
if
|
||||
l_role /= Void
|
||||
then
|
||||
create view_response.make (req, res, api)
|
||||
view_response.execute
|
||||
else
|
||||
send_not_found (req, res)
|
||||
end
|
||||
else
|
||||
create_new_role (req, res)
|
||||
end
|
||||
end
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
edit_response: CMS_ROLE_FORM_RESPONSE
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("admin roles") then
|
||||
if req.percent_encoded_path_info.ends_with_general ("/edit") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/delete") then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("op") as l_op and then
|
||||
l_op.value.same_string ("Delete")
|
||||
then
|
||||
do_delete (req, res)
|
||||
end
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/add/role") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
end
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: detachable WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request")
|
||||
if a_id /= Void and then a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.set_value ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.set_value ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user (req) as l_user then
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||
if
|
||||
l_id.is_integer and then
|
||||
attached api.user_api.user_role_by_id (l_id.integer_value) as l_role
|
||||
then
|
||||
api.user_api.delete_role (l_role)
|
||||
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
send_access_denied (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- New role
|
||||
|
||||
create_new_role (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
edit_response: CMS_ROLE_FORM_RESPONSE
|
||||
do
|
||||
if req.percent_encoded_path_info.starts_with_general ("/admin/add/role") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
else
|
||||
send_bad_request (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
114
modules/admin/handler/role/cms_role_view_response.e
Normal file
114
modules/admin/handler/role/cms_role_view_response.e
Normal file
@@ -0,0 +1,114 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ROLE_VIEW_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ROLE_VIEW_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api;)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Query
|
||||
|
||||
role_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- Role id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
uid: INTEGER_64
|
||||
user_api : CMS_USER_API
|
||||
do
|
||||
user_api := api.user_api
|
||||
uid := role_id_path_parameter (request)
|
||||
if uid > 0 and then attached user_api.user_role_by_id (uid.to_integer) as l_role then
|
||||
append_html_to_output (l_role, Current)
|
||||
else
|
||||
set_main_content ("Missing Role")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
append_html_to_output (a_role: CMS_USER_ROLE; a_response: CMS_RESPONSE )
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
s: STRING
|
||||
do
|
||||
a_response.set_value (a_role, "role")
|
||||
create lnk.make (a_response.translation ("View", Void), "admin/role/" + a_role.id.out)
|
||||
lnk.set_is_active (True)
|
||||
lnk.set_weight (1)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
create lnk.make (a_response.translation ("Edit", Void), "admin/role/" + a_role.id.out + "/edit")
|
||||
lnk.set_weight (2)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
|
||||
if a_role /= Void and then a_role.id > 0 then
|
||||
create lnk.make (a_response.translation ("Delete", Void), "admin/role/" + a_role.id.out + "/delete")
|
||||
lnk.set_weight (3)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
end
|
||||
|
||||
create s.make_empty
|
||||
s.append ("<div class=%"info%"> ")
|
||||
s.append ("<h4>Role Information</h4>")
|
||||
s.append ("<p>Role:")
|
||||
s.append (a_role.name)
|
||||
s.append ("</p>")
|
||||
|
||||
s.append ("<h4>Permissions:</h4>")
|
||||
if
|
||||
not a_role.permissions.is_empty
|
||||
then
|
||||
s.append ("<ul class=%"cms-permissions%">%N")
|
||||
across a_role.permissions as ic loop
|
||||
s.append ("<li class=%"cms-permission%">"+ ic.item + "</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
|
||||
end
|
||||
|
||||
s.append ("</div>")
|
||||
a_response.set_title (a_role.name)
|
||||
a_response.set_main_content (s)
|
||||
end
|
||||
|
||||
end
|
||||
128
modules/admin/handler/user/cms_admin_users_handler.e
Normal file
128
modules/admin/handler/user/cms_admin_users_handler.e
Normal file
@@ -0,0 +1,128 @@
|
||||
note
|
||||
description: "Summary description for {CMS_ADMIN_USER_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_USERS_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)
|
||||
local
|
||||
l_response: CMS_RESPONSE
|
||||
s: STRING
|
||||
u: CMS_USER
|
||||
l_page_helper: CMS_PAGINATION_GENERATOR
|
||||
s_pager: STRING
|
||||
l_count: INTEGER
|
||||
user_api: CMS_USER_API
|
||||
do
|
||||
-- At the moment the template are hardcoded, but we can
|
||||
-- get them from the configuration file and load them into
|
||||
-- the setup class.
|
||||
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api)
|
||||
if l_response.has_permission ("admin users") then
|
||||
user_api := api.user_api
|
||||
|
||||
l_count := user_api.users_count
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
|
||||
|
||||
create s.make_empty
|
||||
if l_count > 1 then
|
||||
l_response.set_title ("Listing " + l_count.out + " Users")
|
||||
else
|
||||
l_response.set_title ("Listing " + l_count.out + " User")
|
||||
end
|
||||
|
||||
create s_pager.make_empty
|
||||
create l_page_helper.make ("admin/users/?page={page}&size={size}", user_api.users_count.as_natural_64, 25) -- FIXME: Make this default page size a global CMS settings
|
||||
l_page_helper.get_setting_from_request (req)
|
||||
if l_page_helper.has_upper_limit and then l_page_helper.pages_count > 1 then
|
||||
l_page_helper.append_to_html (l_response, s_pager)
|
||||
if l_page_helper.page_size > 25 then
|
||||
s.append (s_pager)
|
||||
end
|
||||
end
|
||||
|
||||
if attached user_api.recent_users (create {CMS_DATA_QUERY_PARAMETERS}.make (l_page_helper.current_page_offset, l_page_helper.page_size)) as lst then
|
||||
s.append ("<ul class=%"cms-users%">%N")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
u := ic.item
|
||||
s.append ("<li class=%"cms_user%">")
|
||||
s.append ("<a href=%"")
|
||||
s.append (req.absolute_script_url ("/admin/user/"+u.id.out))
|
||||
s.append ("%">")
|
||||
s.append (u.name)
|
||||
s.append ("</a>")
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
-- Again the pager at the bottom, if needed
|
||||
s.append (s_pager)
|
||||
|
||||
if l_response.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then
|
||||
s.append (l_response.link ("Add User", "admin/add/user", Void))
|
||||
end
|
||||
|
||||
l_response.set_main_content (s)
|
||||
l_response.execute
|
||||
else
|
||||
l_response.execute
|
||||
end
|
||||
end
|
||||
end
|
||||
523
modules/admin/handler/user/cms_user_form_response.e
Normal file
523
modules/admin/handler/user/cms_user_form_response.e
Normal file
@@ -0,0 +1,523 @@
|
||||
note
|
||||
description: "Summary description for {CMS_USER_FORM_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_USER_FORM_RESPONSE
|
||||
|
||||
inherit
|
||||
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Query
|
||||
|
||||
user_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- User id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Process
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
b: STRING_8
|
||||
uid: INTEGER_64
|
||||
user_api: CMS_USER_API
|
||||
do
|
||||
user_api := api.user_api
|
||||
create b.make_empty
|
||||
uid := user_id_path_parameter (request)
|
||||
if
|
||||
uid > 0 and then
|
||||
attached user_api.user_by_id (uid) as l_user
|
||||
then
|
||||
if
|
||||
location.ends_with_general ("/edit")
|
||||
then
|
||||
edit_form (l_user)
|
||||
elseif location.ends_with_general ("/delete") then
|
||||
delete_form (l_user)
|
||||
end
|
||||
else
|
||||
new_form
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Process Edit
|
||||
|
||||
edit_form (a_user: CMS_USER)
|
||||
local
|
||||
f: like new_edit_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_edit_form (a_user, url (location, Void), "edit-user")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.submit_actions.extend (agent edit_form_submit (?, a_user, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if a_user.has_id then
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void),"admin/user/" + a_user.id.out), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void),"admin/user/" + a_user.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Delete", Void),"admin/user/" + a_user.id.out + "/delete"), primary_tabs)
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (a_user.name)
|
||||
b.append (html_encoded (a_user.name) + " saved")
|
||||
else
|
||||
set_title (formatted_string (translation ("Edit $1 #$2", Void), [a_user.name, a_user.id]))
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Process Delete
|
||||
|
||||
delete_form (a_user: CMS_USER)
|
||||
local
|
||||
f: like new_delete_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_delete_form (a_user, url (location, Void), "edit-user")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if a_user.has_id then
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("View", Void),"admin/user/" + a_user.id.out ), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Edit", Void),"admin/user/" + a_user.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (create {CMS_LOCAL_LINK}.make (translation ("Delete", Void),"admin/user/" + a_user.id.out + "/delete"), primary_tabs)
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
set_title (a_user.name)
|
||||
b.append (html_encoded (a_user.name) + " deleted")
|
||||
else
|
||||
set_title (formatted_string (translation ("Delete $1 #$2", Void), [a_user.name, a_user.id]))
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
|
||||
feature -- Process New
|
||||
|
||||
new_form
|
||||
local
|
||||
f: like new_edit_form
|
||||
b: STRING
|
||||
fd: detachable WSF_FORM_DATA
|
||||
l_user: detachable CMS_USER
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_edit_form (l_user, url (location, Void), "create-user")
|
||||
hooks.invoke_form_alter (f, fd, Current)
|
||||
if request.is_post_request_method then
|
||||
f.validation_actions.extend (agent new_form_validate (?, b))
|
||||
f.submit_actions.extend (agent edit_form_submit (?, l_user, b))
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if attached redirection as l_location then
|
||||
-- FIXME: Hack for now
|
||||
if attached l_user then
|
||||
set_title (l_user.name)
|
||||
b.append (html_encoded (l_user.name) + " Saved")
|
||||
end
|
||||
else
|
||||
if attached l_user then
|
||||
set_title (formatted_string (translation ("Saved $1 #$2", Void), [l_user.name, l_user.id]))
|
||||
end
|
||||
f.append_to_html (wsf_theme, b)
|
||||
end
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Form
|
||||
|
||||
edit_form_submit (fd: WSF_FORM_DATA; a_user: detachable CMS_USER; b: STRING)
|
||||
local
|
||||
l_update_roles: BOOLEAN
|
||||
l_update_user: BOOLEAN
|
||||
l_save_user: BOOLEAN
|
||||
l_user: detachable CMS_USER
|
||||
s: STRING
|
||||
lnk: CMS_LINK
|
||||
do
|
||||
|
||||
l_update_roles := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update user role")
|
||||
if l_update_roles then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
if a_user /= Void then
|
||||
l_user := a_user
|
||||
if l_user.has_id then
|
||||
create {CMS_LOCAL_LINK} lnk.make (translation ("View", Void),"admin/user/" + l_user.id.out )
|
||||
change_user (fd, a_user)
|
||||
s := "modified"
|
||||
set_redirection (lnk.location)
|
||||
end
|
||||
end
|
||||
end
|
||||
l_update_user := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update user")
|
||||
if l_update_user then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
if a_user /= Void then
|
||||
l_user := a_user
|
||||
if l_user.has_id then
|
||||
change_user (fd, a_user)
|
||||
s := "modified"
|
||||
end
|
||||
end
|
||||
end
|
||||
l_save_user := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Create user")
|
||||
if l_save_user then
|
||||
debug ("cms")
|
||||
across
|
||||
fd as c
|
||||
loop
|
||||
b.append ("<li>" + html_encoded (c.key) + "=")
|
||||
if attached c.item as v then
|
||||
b.append (html_encoded (v.string_representation))
|
||||
end
|
||||
b.append ("</li>")
|
||||
end
|
||||
end
|
||||
create_user (fd)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
new_edit_form (a_user: detachable CMS_USER; a_url: READABLE_STRING_8; a_name: STRING): CMS_FORM
|
||||
-- Create a web form named `a_name' for uSER `a_YSER' (if set), using form action url `a_url'.
|
||||
local
|
||||
f: CMS_FORM
|
||||
th: WSF_FORM_HIDDEN_INPUT
|
||||
do
|
||||
create f.make (a_url, a_name)
|
||||
|
||||
create th.make ("user-id")
|
||||
if a_user /= Void then
|
||||
th.set_text_value (a_user.id.out)
|
||||
else
|
||||
th.set_text_value ("0")
|
||||
end
|
||||
f.extend (th)
|
||||
|
||||
populate_form (f, a_user)
|
||||
|
||||
Result := f
|
||||
end
|
||||
|
||||
new_form_validate (fd: WSF_FORM_DATA; b: STRING)
|
||||
do
|
||||
if attached fd.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Create user") then
|
||||
if attached fd.string_item ("username") as l_username then
|
||||
if attached api.user_api.user_by_name (l_username) then
|
||||
fd.report_invalid_field ("username", "Username already taken!")
|
||||
end
|
||||
else
|
||||
fd.report_invalid_field ("username", "missing username")
|
||||
end
|
||||
if attached fd.string_item ("email") as l_email then
|
||||
if attached api.user_api.user_by_email (l_email) then
|
||||
fd.report_invalid_field ("email", "Email address already associated with an existing account!")
|
||||
end
|
||||
else
|
||||
fd.report_invalid_field ("email", "missing email address")
|
||||
end
|
||||
elseif f_op.is_case_insensitive_equal_general ("Update user") then
|
||||
if attached fd.string_item ("username") as l_username then
|
||||
if api.user_api.user_by_name (l_username) = Void then
|
||||
fd.report_invalid_field ("username", "Username does not exist!")
|
||||
end
|
||||
else
|
||||
fd.report_invalid_field ("username", "missing username")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
new_delete_form (a_user: detachable CMS_USER; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM
|
||||
-- Create a web form named `a_name' for node `a_user' (if set), using form action url `a_url'.
|
||||
local
|
||||
f: CMS_FORM
|
||||
ts: WSF_FORM_SUBMIT_INPUT
|
||||
do
|
||||
create f.make (a_url, a_name)
|
||||
f.extend_html_text ("<br/>")
|
||||
f.extend_html_text ("<legend>Are you sure you want to delete?</legend>")
|
||||
|
||||
-- TODO check if we need to check for has_permissions!!
|
||||
if
|
||||
a_user /= Void and then
|
||||
a_user.has_id
|
||||
then
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Delete")
|
||||
fixme ("[
|
||||
ts.set_default_value (translation ("Delete"))
|
||||
]")
|
||||
|
||||
f.extend (ts)
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Cancel")
|
||||
ts.set_formmethod ("GET")
|
||||
ts.set_formaction ("/admin/user/" + a_user.id.out)
|
||||
f.extend (ts)
|
||||
end
|
||||
|
||||
Result := f
|
||||
end
|
||||
|
||||
|
||||
|
||||
populate_form (a_form: WSF_FORM; a_user: detachable CMS_USER)
|
||||
-- Fill the web form `a_form' with data from `a_node' if set,
|
||||
-- and apply this to content type `a_content_type'.
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
fe: WSF_FORM_EMAIL_INPUT
|
||||
fs: WSF_FORM_FIELD_SET
|
||||
cb: WSF_FORM_CHECKBOX_INPUT
|
||||
ts: WSF_FORM_SUBMIT_INPUT
|
||||
l_user_roles: detachable LIST [CMS_USER_ROLE]
|
||||
do
|
||||
if a_user /= Void then
|
||||
create fs.make
|
||||
fs.set_legend ("Basic User Account Information")
|
||||
fs.extend_html_text ("<div><string><label>User name </label></strong><br></div>")
|
||||
fs.extend_html_text (a_user.name)
|
||||
if attached a_user.email as l_email then
|
||||
create fe.make_with_text ("email", l_email)
|
||||
else
|
||||
create fe.make_with_text ("email", "")
|
||||
end
|
||||
fe.set_label ("Email")
|
||||
fe.enable_required
|
||||
fs.extend (fe)
|
||||
a_form.extend (fs)
|
||||
a_form.extend_html_text ("<br/>")
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Update user")
|
||||
a_form.extend (ts)
|
||||
a_form.extend_html_text ("<hr>")
|
||||
|
||||
|
||||
create fs.make
|
||||
fs.set_legend ("User Roles")
|
||||
|
||||
l_user_roles := api.user_api.user_roles (a_user)
|
||||
if l_user_roles.is_empty then
|
||||
l_user_roles := Void
|
||||
end
|
||||
|
||||
across api.user_api.effective_roles as ic loop
|
||||
create cb.make_with_value ("cms_roles", ic.item.id.out)
|
||||
cb.set_checked (l_user_roles /= Void and then across l_user_roles as r_ic some r_ic.item.same_user_role (ic.item) end)
|
||||
cb.set_title (ic.item.name)
|
||||
fs.extend (cb)
|
||||
end
|
||||
|
||||
a_form.extend (fs)
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Update user role")
|
||||
a_form.extend (ts)
|
||||
else
|
||||
create fs.make
|
||||
fs.set_legend ("Basic User Account Information")
|
||||
create ti.make ("username")
|
||||
ti.set_label ("Username")
|
||||
ti.enable_required
|
||||
fs.extend (ti)
|
||||
create fe.make_with_text ("email", "")
|
||||
fe.set_label ("Email")
|
||||
fe.enable_required
|
||||
fs.extend (fe)
|
||||
a_form.extend (fs)
|
||||
a_form.extend_html_text ("<br/>")
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Create user")
|
||||
a_form.extend (ts)
|
||||
a_form.extend_html_text ("<hr>")
|
||||
end
|
||||
end
|
||||
|
||||
change_user (a_form_data: WSF_FORM_DATA; a_user: CMS_USER)
|
||||
-- Update node `a_node' with form_data `a_form_data' for the given content type `a_content_type'.
|
||||
local
|
||||
l_uroles: LIST [CMS_USER_ROLE]
|
||||
do
|
||||
if attached a_form_data.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Update user role") then
|
||||
if attached a_form_data.string_item ("user-id") as l_user_id and then
|
||||
attached {CMS_USER} api.user_api.user_by_id (l_user_id.to_integer) as l_user
|
||||
then
|
||||
l_uroles := api.user_api.user_roles (l_user)
|
||||
l_uroles.compare_objects
|
||||
if attached {WSF_STRING} a_form_data.item ("cms_roles") as l_role then
|
||||
if attached api.user_api.user_role_by_id (l_role.integer_value) as role then
|
||||
if not l_uroles.has (role) then
|
||||
api.user_api.assign_role_to_user (role, a_user)
|
||||
end
|
||||
end
|
||||
elseif attached {WSF_MULTIPLE_STRING} a_form_data.item ("cms_roles") as l_roles then
|
||||
across l_roles as ic loop
|
||||
if attached api.user_api.user_role_by_id (ic.item.integer_value) as role then
|
||||
if not l_uroles.has (role) then
|
||||
api.user_api.assign_role_to_user (role, a_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
across api.user_api.roles as ic loop
|
||||
api.user_api.unassign_role_from_user (ic.item, a_user)
|
||||
end
|
||||
end
|
||||
add_success_message ("Roles updated")
|
||||
else
|
||||
a_form_data.report_error ("Missing User")
|
||||
end
|
||||
elseif f_op.is_case_insensitive_equal_general ("Update user") then
|
||||
if
|
||||
attached a_form_data.string_item ("user-id") as l_user_id and then
|
||||
attached {CMS_USER} api.user_api.user_by_id (l_user_id.to_integer) as l_user
|
||||
then
|
||||
if
|
||||
attached a_form_data.string_item ("email") as l_email
|
||||
then
|
||||
if
|
||||
attached l_user.email as u_email and then
|
||||
not u_email.is_case_insensitive_equal_general (l_email) and then
|
||||
api.user_api.user_by_email (l_email) = Void
|
||||
then
|
||||
-- Valid email
|
||||
a_user.set_email (l_email)
|
||||
else
|
||||
if attached l_user.email as u_email and then not u_email.is_case_insensitive_equal_general (l_email) then
|
||||
a_form_data.report_invalid_field ("email", "Email already exist!")
|
||||
end
|
||||
end
|
||||
if not a_form_data.has_error then
|
||||
api.user_api.update_user (a_user)
|
||||
add_success_message ("Updated basic info")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
create_user (a_form_data: WSF_FORM_DATA)
|
||||
local
|
||||
u: CMS_USER
|
||||
do
|
||||
if attached a_form_data.string_item ("op") as f_op then
|
||||
if f_op.is_case_insensitive_equal_general ("Create user") then
|
||||
if
|
||||
attached a_form_data.string_item ("username") as l_username and then
|
||||
attached a_form_data.string_item ("email") as l_email and then
|
||||
l_email.is_valid_as_string_8
|
||||
then
|
||||
create u.make (l_username)
|
||||
u.set_email (l_email.as_string_8)
|
||||
u.set_password (new_random_password (u))
|
||||
api.user_api.new_user (u)
|
||||
if api.user_api.has_error then
|
||||
-- handle error
|
||||
else
|
||||
add_success_message ("Created user")
|
||||
end
|
||||
|
||||
else
|
||||
a_form_data.report_invalid_field ("username", "Missing username!")
|
||||
a_form_data.report_invalid_field ("email", "Missing email address!")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Generation
|
||||
|
||||
new_random_password (u: CMS_USER): STRING
|
||||
-- Generate a new token activation token
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: SECURITY_PROVIDER
|
||||
l_encode: URL_ENCODER
|
||||
do
|
||||
create l_security
|
||||
l_token := l_security.token
|
||||
create l_encode
|
||||
from until l_token.same_string (l_encode.encoded_string (l_token)) loop
|
||||
-- Loop ensure that we have a security token that does not contain characters that need encoding.
|
||||
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token
|
||||
-- but the user will need to use an unencoded token if activation has to be done manually.
|
||||
l_token := l_security.token
|
||||
end
|
||||
Result := l_token + url_encoded (u.name) + u.creation_date.out
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
203
modules/admin/handler/user/cms_user_handler.e
Normal file
203
modules/admin/handler/user/cms_user_handler.e
Normal file
@@ -0,0 +1,203 @@
|
||||
note
|
||||
description: "[
|
||||
Handler for a CMS user in the CMS interface
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_USER_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,
|
||||
do_post,
|
||||
do_delete
|
||||
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 -- Query
|
||||
|
||||
user_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- User id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- HTTP Methods
|
||||
|
||||
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_user: detachable CMS_USER
|
||||
l_uid: INTEGER_64
|
||||
edit_response: CMS_USER_FORM_RESPONSE
|
||||
view_response: CMS_USER_VIEW_RESPONSE
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("admin users") then
|
||||
if req.percent_encoded_path_info.ends_with_general ("/edit") then
|
||||
check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/user/") end
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/delete") then
|
||||
check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/user/") end
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
else
|
||||
-- Display existing node
|
||||
l_uid := user_id_path_parameter (req)
|
||||
if l_uid > 0 then
|
||||
l_user := api.user_api.user_by_id (l_uid)
|
||||
if
|
||||
l_user /= Void
|
||||
then
|
||||
create view_response.make (req, res, api)
|
||||
view_response.execute
|
||||
else
|
||||
send_not_found (req, res)
|
||||
end
|
||||
else
|
||||
create_new_user (req, res)
|
||||
end
|
||||
end
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
do_post (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
edit_response: CMS_USER_FORM_RESPONSE
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("admin users") then
|
||||
if req.percent_encoded_path_info.ends_with_general ("/edit") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/delete") then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("op") as l_op and then
|
||||
l_op.value.same_string ("Delete")
|
||||
then
|
||||
do_delete (req, res)
|
||||
end
|
||||
elseif req.percent_encoded_path_info.ends_with_general ("/add/user") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
end
|
||||
else
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Error
|
||||
|
||||
do_error (req: WSF_REQUEST; res: WSF_RESPONSE; a_id: detachable WSF_STRING)
|
||||
-- Handling error.
|
||||
local
|
||||
l_page: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request")
|
||||
if a_id /= Void and then a_id.is_integer then
|
||||
-- resource not found
|
||||
l_page.set_value ("404", "code")
|
||||
l_page.set_status_code (404)
|
||||
else
|
||||
-- bad request
|
||||
l_page.set_value ("400", "code")
|
||||
l_page.set_status_code (400)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
|
||||
do_delete (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user (req) as l_user then
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as l_id then
|
||||
if
|
||||
l_id.is_integer and then
|
||||
attached api.user_api.user_by_id (l_id.integer_value) as u_user
|
||||
then
|
||||
api.user_api.delete_user(u_user)
|
||||
res.send (create {CMS_REDIRECTION_RESPONSE_MESSAGE}.make (req.absolute_script_url ("")))
|
||||
else
|
||||
do_error (req, res, l_id)
|
||||
end
|
||||
else
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, api)).execute
|
||||
end
|
||||
else
|
||||
send_access_denied (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- New User
|
||||
|
||||
create_new_user (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
edit_response: CMS_USER_FORM_RESPONSE
|
||||
do
|
||||
if req.percent_encoded_path_info.starts_with ("/admin/add/user") then
|
||||
create edit_response.make (req, res, api)
|
||||
edit_response.execute
|
||||
else
|
||||
send_bad_request (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
131
modules/admin/handler/user/cms_user_view_response.e
Normal file
131
modules/admin/handler/user/cms_user_view_response.e
Normal file
@@ -0,0 +1,131 @@
|
||||
note
|
||||
description: "Summary description for {CMS_USER_VIEW_RESPONSE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_USER_VIEW_RESPONSE
|
||||
|
||||
inherit
|
||||
CMS_RESPONSE
|
||||
redefine
|
||||
make,
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: like api;)
|
||||
do
|
||||
create {WSF_NULL_THEME} wsf_theme.make
|
||||
Precursor (req, res, a_api)
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
create {CMS_TO_WSF_THEME} wsf_theme.make (Current, theme)
|
||||
end
|
||||
|
||||
wsf_theme: WSF_THEME
|
||||
|
||||
feature -- Query
|
||||
|
||||
user_id_path_parameter (req: WSF_REQUEST): INTEGER_64
|
||||
-- User id passed as path parameter for request `req'.
|
||||
local
|
||||
s: STRING
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("id") as p_nid then
|
||||
s := p_nid.value
|
||||
if s.is_integer_64 then
|
||||
Result := s.to_integer_64
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Execution
|
||||
|
||||
process
|
||||
-- Computed response message.
|
||||
local
|
||||
uid: INTEGER_64
|
||||
user_api : CMS_USER_API
|
||||
do
|
||||
user_api := api.user_api
|
||||
uid := user_id_path_parameter (request)
|
||||
if uid > 0 and then attached user_api.user_by_id (uid) as l_user then
|
||||
append_html_to_output (l_user, Current)
|
||||
else
|
||||
set_main_content ("Missing User")
|
||||
end
|
||||
end
|
||||
|
||||
append_html_to_output (a_user: CMS_USER; a_response: CMS_RESPONSE)
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
s: STRING
|
||||
l_role: CMS_USER_ROLE
|
||||
do
|
||||
a_response.set_value (a_user, "user")
|
||||
create lnk.make (a_response.translation ("View", Void), "admin/user/" + a_user.id.out)
|
||||
lnk.set_is_active (True)
|
||||
lnk.set_weight (1)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
create lnk.make (a_response.translation ("Edit", Void), "admin/user/" + a_user.id.out + "/edit")
|
||||
lnk.set_permission_arguments (<<"manage admin", "manage users", "manage own user">>)
|
||||
lnk.set_weight (2)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
|
||||
if a_user /= Void and then a_user.id > 0 then
|
||||
create lnk.make (a_response.translation ("Delete", Void), "admin/user/" + a_user.id.out + "/delete")
|
||||
lnk.set_weight (3)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
end
|
||||
|
||||
-- FIXME: [04/aug/2015] use a CMS_FORM rather than hardcoded html.
|
||||
-- So that other module may easily integrate them-selves to add information.
|
||||
create s.make_empty
|
||||
s.append ("<div class=%"info%"> ")
|
||||
s.append ("<h4>Account Information</h4>")
|
||||
s.append ("<p>Username: ")
|
||||
s.append (a_user.name)
|
||||
s.append ("</p>")
|
||||
if attached a_user.email as l_email then
|
||||
s.append ("<p>Email: ")
|
||||
s.append (l_email)
|
||||
s.append ("</p>")
|
||||
end
|
||||
|
||||
if
|
||||
attached {LIST [CMS_USER_ROLE]} api.user_api.user_roles (a_user) as l_roles and then
|
||||
not l_roles.is_empty
|
||||
then
|
||||
s.append ("<h4>Role(s):</h4>")
|
||||
across l_roles as ic loop
|
||||
l_role := ic.item
|
||||
s.append ("<i>")
|
||||
s.append (link (l_role.name, "admin/role/" + l_role.id.out, Void))
|
||||
s.append ("</i>")
|
||||
debug
|
||||
s.append ("<h5>Permissions:</h5>")
|
||||
s.append ("<ul class=%"cms-permissions%">%N")
|
||||
across l_role.permissions as perms_ic loop
|
||||
s.append ("<li class=%"cms-permission%">" + perms_ic.item + "</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
s.append ("</div>")
|
||||
a_response.set_title (a_user.name)
|
||||
a_response.set_main_content (s)
|
||||
end
|
||||
|
||||
end
|
||||
34
modules/admin/site/files/css/admin.css
Normal file
34
modules/admin/site/files/css/admin.css
Normal file
@@ -0,0 +1,34 @@
|
||||
ul.cms-users {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-users li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-users li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-users li.cms_user a::before {
|
||||
content: "[users] "; }
|
||||
|
||||
ul.cms-roles {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-roles li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-roles li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-roles li.cms_role a::before {
|
||||
content: "[roles] "; }
|
||||
|
||||
ul.cms-permissions {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
border: solid 1px #ccc; }
|
||||
ul.cms-permissions li {
|
||||
border-top: dotted 1px #ccc; }
|
||||
ul.cms-permissions li:first-child {
|
||||
border-top: none; }
|
||||
ul.cms-permissions li.cms_permission a::before {
|
||||
content: "[permission] "; }
|
||||
|
||||
/*# sourceMappingURL=admin.css.map */
|
||||
59
modules/admin/site/files/scss/admin.scss
Normal file
59
modules/admin/site/files/scss/admin.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
ul.cms-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_user a::before {
|
||||
content: "[users] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-roles {
|
||||
|
||||
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_role a::before {
|
||||
content: "[roles] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-permissions {
|
||||
|
||||
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_permission a::before {
|
||||
content: "[permission] ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,14 +12,15 @@ inherit
|
||||
register_hooks
|
||||
end
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_VALUE_TABLE_ALTER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
@@ -76,14 +77,16 @@ feature -- Router
|
||||
|
||||
configure_web (a_api: CMS_API; a_router: WSF_ROUTER)
|
||||
do
|
||||
a_router.handle ("/account", create {WSF_URI_AGENT_HANDLER}.make (agent handle_account (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-basic-auth", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_basic_auth (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_change_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/post-change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_post_change_password (a_api, ?, ?)), a_router.methods_get)
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
@@ -92,18 +95,14 @@ feature -- Hooks configuration
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
auto_subscribe_to_hooks (a_response)
|
||||
a_response.subscribe_to_block_hook (Current)
|
||||
a_response.subscribe_to_value_table_alter_hook (Current)
|
||||
a_response.hooks.subscribe_to_block_hook (Current)
|
||||
a_response.hooks.subscribe_to_value_table_alter_hook (Current)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user (a_response.request) as l_user then
|
||||
a_value.force (l_user, "user")
|
||||
end
|
||||
a_value.force (a_response.user, "user")
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
@@ -112,94 +111,62 @@ feature -- Hooks
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
do
|
||||
if attached a_response.current_user (a_response.request) as u then
|
||||
create lnk.make (u.name + " (Logout)", "account/roc-logout" )
|
||||
if attached a_response.user as u then
|
||||
create lnk.make (u.name, "account" )
|
||||
lnk.set_weight (97)
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
create lnk.make ("Logout", "account/roc-logout")
|
||||
lnk.set_weight (98)
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
else
|
||||
create lnk.make ("Login", "account/roc-login")
|
||||
end
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
lnk.set_weight (98)
|
||||
if a_response.location.starts_with ("account/roc-login") then
|
||||
create lnk.make ("Basic Auth", "account/roc-basic-auth")
|
||||
lnk.set_expandable (True)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
lnk.set_weight (98)
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
end
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
feature -- Handler
|
||||
|
||||
handle_account (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_string: STRING
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
Result := <<"login", "register", "reactivate", "new_password", "reset_password">>
|
||||
debug ("roc")
|
||||
create l_string.make_empty
|
||||
across
|
||||
Result as ic
|
||||
loop
|
||||
l_string.append (ic.item)
|
||||
l_string.append_character (' ')
|
||||
end
|
||||
write_debug_log (generator + ".block_list:" + l_string )
|
||||
end
|
||||
end
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if
|
||||
a_block_id.is_case_insensitive_equal_general ("login") and then
|
||||
a_response.location.starts_with ("account/roc-basic-auth")
|
||||
then
|
||||
get_block_view_login (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("register") and then
|
||||
a_response.location.starts_with ("account/roc-register")
|
||||
then
|
||||
get_block_view_register (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reactivate") and then
|
||||
a_response.location.starts_with ("account/reactivate")
|
||||
then
|
||||
get_block_view_reactivate (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("new_password") and then
|
||||
a_response.location.starts_with ("account/new-password")
|
||||
then
|
||||
get_block_view_new_password (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reset_password") and then
|
||||
a_response.location.starts_with ("account/reset-password")
|
||||
then
|
||||
get_block_view_reset_password (a_block_id, a_response)
|
||||
if attached template_block ("account_info", r) as l_tpl_block then
|
||||
if attached r.user as l_user then
|
||||
r.set_value (api.user_api.user_roles (l_user), "roles")
|
||||
end
|
||||
r.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
r.add_warning_message ("Error with block [resources_page]")
|
||||
end
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_login (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Login", "optional_content_type")
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_login_basic_auth (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Basic Auth", "optional_content_type")
|
||||
r.execute
|
||||
if attached api.module_by_name ("basic_auth") then
|
||||
-- FIXME: find better solution to support a default login system.
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_redirection (r.absolute_url ("/account/roc-basic-auth", Void))
|
||||
r.execute
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
handle_logout (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_url: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
l_url := req.absolute_script_url ("/basic_auth_logoff")
|
||||
r.set_redirection (l_url)
|
||||
r.set_redirection (r.absolute_url ("", Void))
|
||||
r.execute
|
||||
end
|
||||
|
||||
@@ -208,60 +175,58 @@ feature -- Hooks
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
u: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_exist: BOOLEAN
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
l_url: STRING
|
||||
l_token: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Register", "optional_content_type")
|
||||
if req.is_post_request_method then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("name") as l_name and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("email") as l_email
|
||||
then
|
||||
l_user_api := api.user_api
|
||||
if r.has_permission ("account register") then
|
||||
if req.is_post_request_method then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("name") as l_name and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("email") as l_email
|
||||
then
|
||||
l_user_api := api.user_api
|
||||
|
||||
if attached l_user_api.user_by_name (l_name.value) then
|
||||
-- Username already exist.
|
||||
r.values.force ("The user name exist!", "error_name")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_email (l_email.value) then
|
||||
-- Emails already exist.
|
||||
r.values.force ("The email exist!", "error_email")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_name (l_name.value) then
|
||||
-- Username already exist.
|
||||
r.set_value ("User name already exists!", "error_name")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_email (l_email.value) then
|
||||
-- Emails already exist.
|
||||
r.set_value ("An account is already associated with that email address!", "error_email")
|
||||
l_exist := True
|
||||
end
|
||||
|
||||
if not l_exist then
|
||||
-- New user
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1)
|
||||
l_roles.force (l_user_api.authenticated_user_role)
|
||||
if not l_exist then
|
||||
-- New user
|
||||
create u.make (l_name.value)
|
||||
u.set_email (l_email.value)
|
||||
u.set_password (l_password.value)
|
||||
l_user_api.new_user (u)
|
||||
|
||||
create u.make (l_name.value)
|
||||
u.set_email (l_email.value)
|
||||
u.set_password (l_password.value)
|
||||
u.set_roles (l_roles)
|
||||
l_user_api.new_user (u)
|
||||
-- Create activation token
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, u.id)
|
||||
l_url := req.absolute_script_url ("/account/activate/" + l_token)
|
||||
|
||||
-- Create activation token
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, u.id)
|
||||
l_url := req.absolute_script_url ("/account/activate/" + l_token)
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_email")
|
||||
es.send_contact_email (l_email.value, l_url)
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_email")
|
||||
es.send_contact_email (l_email.value, l_url)
|
||||
|
||||
else
|
||||
r.values.force (l_name.value, "name")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
else
|
||||
r.set_value (l_name.value, "name")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
end
|
||||
|
||||
r.execute
|
||||
@@ -282,12 +247,10 @@ feature -- Hooks
|
||||
l_user.mark_active
|
||||
l_user_api.update_user (l_user)
|
||||
l_user_api.remove_activation (l_token.value)
|
||||
r.set_value ("Account activated", "optional_content_type")
|
||||
r.set_main_content ("<p> Your account <i>"+ l_user.name +"</i> has been activated</p>")
|
||||
else
|
||||
-- the token does not exist, or it was already used.
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
r.set_value ("Account not activated", "optional_content_type")
|
||||
r.set_main_content ("<p>The token <i>" + l_token.value +"</i> is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "</p>")
|
||||
end
|
||||
r.execute
|
||||
@@ -315,7 +278,7 @@ feature -- Hooks
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
if l_user.is_active then
|
||||
r.values.force ("The asociated user to the given email " + l_email.value + " , is already active", "is_active")
|
||||
r.set_value ("The asociated user to the given email " + l_email.value + " , is already active", "is_active")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
else
|
||||
l_token := new_token
|
||||
@@ -328,8 +291,8 @@ feature -- Hooks
|
||||
es.send_contact_activation_email (l_email.value, l_url)
|
||||
end
|
||||
else
|
||||
r.values.force ("The email does not exist or !", "error_email")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_value ("The email does not exist or !", "error_email")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
@@ -361,8 +324,26 @@ feature -- Hooks
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email.value, l_url)
|
||||
else
|
||||
r.values.force ("The email does not exist !", "error_email")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_value ("The email does not exist !", "error_email")
|
||||
r.set_value (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
elseif attached {WSF_STRING} req.form_parameter ("username") as l_username then
|
||||
if attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then
|
||||
attached l_user.email as l_email
|
||||
then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_user_api.new_password (l_token, l_user.id)
|
||||
l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token)
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email, l_url)
|
||||
else
|
||||
r.set_value ("The username does not exist !", "error_username")
|
||||
r.set_value (l_username.value, "username")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
@@ -379,9 +360,9 @@ feature -- Hooks
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
l_user_api := api.user_api
|
||||
if attached {WSF_STRING} req.query_parameter ("token") as l_token then
|
||||
r.values.force (l_token.value, "token")
|
||||
r.set_value (l_token.value, "token")
|
||||
if l_user_api.user_by_password_token (l_token.value) = Void then
|
||||
r.values.force ("The token " + l_token.value + " is not valid, " + r.link ("click here" , "account/new-password", Void) + " to generate a new token.", "error_token")
|
||||
r.set_value ("The token " + l_token.value + " is not valid, " + r.link ("click here" , "account/new-password", Void) + " to generate a new token.", "error_token")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
@@ -402,8 +383,8 @@ feature -- Hooks
|
||||
l_user_api.remove_password (l_token.value)
|
||||
end
|
||||
else
|
||||
r.values.force ("Passwords Don't Match", "error_password")
|
||||
r.values.force (l_token.value, "token")
|
||||
r.set_value ("Passwords Don't Match", "error_password")
|
||||
r.set_value (l_token.value, "token")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
@@ -411,6 +392,113 @@ feature -- Hooks
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_change_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
l_user_api := api.user_api
|
||||
|
||||
if req.is_post_request_method then
|
||||
if attached r.user as l_user then
|
||||
r.set_value (api.user_api.user_roles (l_user), "roles")
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password and then
|
||||
l_password.value.same_string (l_confirm_password.value)
|
||||
then
|
||||
-- Does the passwords match?
|
||||
l_user.set_password (l_password.value)
|
||||
l_user_api.update_user (l_user)
|
||||
r.set_redirection (req.absolute_script_url ("/account/post-change-password"))
|
||||
else
|
||||
if attached template_block ("account_info", r) as l_tpl_block then
|
||||
-- r.set_value (l_user, "user")
|
||||
r.set_value ("Passwords Don't Match", "error_password")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
r.add_block (l_tpl_block, "content")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_post_change_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if attached template_block ("post_change", r) as l_tpl_block then
|
||||
r.add_block (l_tpl_block, "content")
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
local
|
||||
l_string: STRING
|
||||
do
|
||||
Result := <<"register", "reactivate", "new_password", "reset_password">>
|
||||
debug ("roc")
|
||||
create l_string.make_empty
|
||||
across
|
||||
Result as ic
|
||||
loop
|
||||
l_string.append (ic.item)
|
||||
l_string.append_character (' ')
|
||||
end
|
||||
write_debug_log (generator + ".block_list:" + l_string )
|
||||
end
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if
|
||||
a_block_id.is_case_insensitive_equal_general ("register") and then
|
||||
a_response.location.starts_with ("account/roc-register")
|
||||
then
|
||||
get_block_view_register (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reactivate") and then
|
||||
a_response.location.starts_with ("account/reactivate")
|
||||
then
|
||||
get_block_view_reactivate (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("new_password") and then
|
||||
a_response.location.starts_with ("account/new-password")
|
||||
then
|
||||
get_block_view_new_password (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reset_password") and then
|
||||
a_response.location.starts_with ("account/reset-password")
|
||||
then
|
||||
get_block_view_reset_password (a_block_id, a_response)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Token Generation
|
||||
|
||||
new_token: STRING
|
||||
-- Generate a new token activation token
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: SECURITY_PROVIDER
|
||||
l_encode: URL_ENCODER
|
||||
do
|
||||
create l_security
|
||||
l_token := l_security.token
|
||||
create l_encode
|
||||
from until l_token.same_string (l_encode.encoded_string (l_token)) loop
|
||||
-- Loop ensure that we have a security token that does not contain characters that need encoding.
|
||||
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token
|
||||
-- but the user will need to use an unencoded token if activation has to be done manually.
|
||||
l_token := l_security.token
|
||||
end
|
||||
Result := l_token
|
||||
end
|
||||
|
||||
feature {NONE} -- Helpers
|
||||
|
||||
template_block (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK
|
||||
@@ -435,17 +523,17 @@ feature {NONE} -- Block views
|
||||
|
||||
get_block_view_login (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
local
|
||||
vals: CMS_VALUE_TABLE
|
||||
-- vals: CMS_VALUE_TABLE
|
||||
do
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
create vals.make (1)
|
||||
-- add the variable to the block
|
||||
value_table_alter (vals, a_response)
|
||||
across
|
||||
vals as ic
|
||||
loop
|
||||
l_tpl_block.set_value (ic.item, ic.key)
|
||||
end
|
||||
-- create vals.make (1)
|
||||
-- -- add the variable to the block
|
||||
-- value_table_alter (vals, a_response)
|
||||
-- across
|
||||
-- vals as ic
|
||||
-- loop
|
||||
-- l_tpl_block.set_value (ic.item, ic.key)
|
||||
-- end
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
@@ -456,33 +544,35 @@ feature {NONE} -- Block views
|
||||
|
||||
get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then
|
||||
if a_response.has_permission ("account register") then
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
l_tpl_block.set_value (a_response.values.item ("name"), "name")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
if attached template_block ("post_register", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("name"), "name")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
if attached template_block ("post_register", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -503,9 +593,9 @@ feature {NONE} -- Block views
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_email") or else a_response.values.has ("is_active") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
@@ -535,10 +625,12 @@ feature {NONE} -- Block views
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_email") then
|
||||
if a_response.values.has ("error_email") or else a_response.values.has ("error_username") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_username"), "error_username")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("username"), "username")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
@@ -561,8 +653,8 @@ feature {NONE} -- Block views
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
@@ -572,9 +664,9 @@ feature {NONE} -- Block views
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password")
|
||||
l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password")
|
||||
-- l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
@@ -593,60 +685,6 @@ feature {NONE} -- Block views
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Token Generation
|
||||
|
||||
new_token: STRING
|
||||
-- Generate a new token activation token
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: SECURITY_PROVIDER
|
||||
l_encode: URL_ENCODER
|
||||
do
|
||||
create l_security
|
||||
l_token := l_security.token
|
||||
create l_encode
|
||||
from until l_token.same_string (l_encode.encoded_string (l_token)) loop
|
||||
-- Loop ensure that we have a security token that does not contain characters that need encoding.
|
||||
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token
|
||||
-- but the user will need to use an unencoded token if activation has to be done manually.
|
||||
l_token := l_security.token
|
||||
end
|
||||
Result := l_token
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Implementation: date and time
|
||||
|
||||
http_date_format_to_date (s: READABLE_STRING_8): detachable DATE_TIME
|
||||
local
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create d.make_from_string (s)
|
||||
if not d.has_error then
|
||||
Result := d.date_time
|
||||
end
|
||||
end
|
||||
|
||||
file_date (p: PATH): DATE_TIME
|
||||
require
|
||||
path_exists: (create {FILE_UTILITIES}).file_path_exists (p)
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
create f.make_with_path (p)
|
||||
Result := timestamp_to_date (f.date)
|
||||
end
|
||||
|
||||
timestamp_to_date (n: INTEGER): DATE_TIME
|
||||
local
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create d.make_from_timestamp (n)
|
||||
Result := d.date_time
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_LOGIN_FORM}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_LOGIN_FORM
|
||||
|
||||
end
|
||||
@@ -8,10 +8,10 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have required a new password at <a href="...">ROC CMS</a></p>
|
||||
<p>You have required a new password at <a href="$host">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>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have request a new activation token at<a href="...">ROC CMS</a></p>
|
||||
<p>You have request a new activation token 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>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
<body>
|
||||
<p>Welcome to<a href="...">ROC CMS</a></p>
|
||||
<p>Welcome to<a href="$host">ROC CMS</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"api_secret":"ADD_YOUR_SECRET_KEY",
|
||||
"api_key":"ADD_YOUR_PUBLIC_KEY",
|
||||
"scope": "email",
|
||||
"api_revoke":"https://accounts.google.com/o/oauth2/revoke?token=$ACCESS_TOKEN",
|
||||
"protected_resource_url":"https://www.googleapis.com/plus/v1/people/me"
|
||||
}
|
||||
67
modules/auth/site/templates/block_account_info.tpl
Normal file
67
modules/auth/site/templates/block_account_info.tpl
Normal file
@@ -0,0 +1,67 @@
|
||||
<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>
|
||||
</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>
|
||||
|
||||
|
||||
<hr>
|
||||
<h4>Profile</h4>
|
||||
<div>
|
||||
{foreach item="the_value" key="the_name" from="$user.profile"}
|
||||
<div>
|
||||
<label>{$the_name/}:</label> {$the_value/}
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/if}
|
||||
{unless isset="$user"}
|
||||
<div>
|
||||
<p> You are not logged in </p>
|
||||
<a href="{$site_url/}account/roc-login">Go to the login page</a>
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
21
modules/auth/site/templates/block_change_password.tpl
Normal file
21
modules/auth/site/templates/block_change_password.tpl
Normal file
@@ -0,0 +1,21 @@
|
||||
<div>
|
||||
<form action="{$site_url/}account/change-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Change Password Form</legend>
|
||||
<div>
|
||||
<input type="password" id="password" name="password" value="" required/>
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" id="confirm_password" name="confirm_password" value="" required/>
|
||||
<label for="password">Confirm Password</label>
|
||||
</div>
|
||||
|
||||
<button type="submit">Confirm</button>
|
||||
{if isset="$error_password"}
|
||||
<span><i>{$error_password/}</i></span> <br>
|
||||
{/if}
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -25,10 +25,5 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{foreach item="item" from="$oauth_consumers"}
|
||||
<a href="{$site_url/}account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div>
|
||||
<form action="/account/new-password" method="post">
|
||||
<form action="{$site_url/}account/new-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Require new password</legend>
|
||||
<legend>Request new password by email</legend>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<label for="email">Email</label>
|
||||
@@ -13,4 +13,20 @@
|
||||
<button type="submit">Send</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
<hr>
|
||||
<form action="{$site_url/}account/new-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Request new password by username</legend>
|
||||
<div>
|
||||
<input type="text" id="username" name="username" value="{$username/}" required/>
|
||||
<label for="username">Username</label>
|
||||
{if isset="$error_username"}
|
||||
<span><i>{$error_username/}</i></span> <br>
|
||||
{/if}
|
||||
<br>
|
||||
</div>
|
||||
<button type="submit">Send</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
3
modules/auth/site/templates/block_post_change.tpl
Normal file
3
modules/auth/site/templates/block_post_change.tpl
Normal file
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>You new password has been saved!, Login again</p>
|
||||
</div>
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/reactivate" method="post">
|
||||
<form action="{$site_url/}account/reactivate" method="post">
|
||||
<fieldset>
|
||||
<legend>Reactivate Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/roc-register" method="post">
|
||||
<form action="{$site_url/}account/roc-register" method="post">
|
||||
<fieldset>
|
||||
<legend>Register Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<form action="/account/reset-password" method="post">
|
||||
<form action="{$site_url/}account/reset-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Generate New Password Form</legend>
|
||||
<div>
|
||||
|
||||
@@ -12,9 +12,12 @@
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="..\..\cms-safe.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
|
||||
<library name="cms_auth_module" location="..\..\modules\auth\auth-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
This module allows the use of HTTP Basic Authentication to restrict access
|
||||
by looking up users in the given providers.
|
||||
]"
|
||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||
revision: "$Revision: 96596 $"
|
||||
|
||||
class
|
||||
BASIC_AUTH_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
filters,
|
||||
register_hooks
|
||||
end
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
version := "1.0"
|
||||
description := "Service to manage basic authentication"
|
||||
package := "core"
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "basic_auth"
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
configure_api_login (a_api, a_router)
|
||||
configure_api_logoff (a_api, a_router)
|
||||
end
|
||||
|
||||
feature -- Access: filter
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Possibly list of Filter's module.
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (2)
|
||||
Result.extend (create {CORS_FILTER})
|
||||
Result.extend (create {BASIC_AUTH_FILTER}.make (a_api))
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: routes
|
||||
|
||||
configure_api_login (api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_bal_handler: BASIC_AUTH_LOGIN_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_bal_handler.make (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
a_router.handle ("/basic_auth_login", l_bal_handler, l_methods)
|
||||
end
|
||||
|
||||
configure_api_logoff (api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_bal_handler: BASIC_AUTH_LOGOFF_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_bal_handler.make (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
a_router.handle ("/basic_auth_logoff", l_bal_handler, l_methods)
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
-- a_response.subscribe_to_block_hook (Current)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
-- List of block names, managed by current object.
|
||||
do
|
||||
Result := <<"basic_auth_login_form">>
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
-- Get block object identified by `a_block_id' and associate with `a_response'.
|
||||
do
|
||||
if a_block_id.same_string ("basic_auth_login_form") then
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on collection of menu contained by `a_menu_system'
|
||||
-- for related response `a_response'.
|
||||
local
|
||||
-- lnk: CMS_LOCAL_LINK
|
||||
do
|
||||
-- if attached a_response.current_user (a_response.request) as u then
|
||||
-- create lnk.make (u.name + " (Logout)", "basic_auth_logoff?destination=" + a_response.request.request_uri)
|
||||
-- else
|
||||
-- create lnk.make ("Login", "basic_auth_login?destination=" + a_response.request.request_uri)
|
||||
-- end
|
||||
-- if not a_menu_system.primary_menu.has (lnk) then
|
||||
-- lnk.set_weight (99)
|
||||
-- a_menu_system.primary_menu.extend (lnk)
|
||||
-- end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
227
modules/basic_auth/cms_basic_auth_module.e
Normal file
227
modules/basic_auth/cms_basic_auth_module.e
Normal file
@@ -0,0 +1,227 @@
|
||||
note
|
||||
description: "[
|
||||
This module allows the use of HTTP Basic Authentication to restrict access
|
||||
by looking up users in the given providers.
|
||||
]"
|
||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||
revision: "$Revision: 96596 $"
|
||||
|
||||
class
|
||||
CMS_BASIC_AUTH_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
filters,
|
||||
register_hooks
|
||||
end
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_VALUE_TABLE_ALTER
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
CMS_REQUEST_UTIL
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
version := "1.0"
|
||||
description := "Service to manage basic authentication"
|
||||
package := "authentication"
|
||||
add_dependency ({CMS_AUTHENTICATION_MODULE})
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "basic_auth"
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
configure_api_login (a_api, a_router)
|
||||
configure_api_logoff (a_api, a_router)
|
||||
a_router.handle ("/account/roc-basic-auth", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_basic_auth (a_api, ?, ?)), a_router.methods_head_get)
|
||||
end
|
||||
|
||||
feature -- Access: filter
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Possibly list of Filter's module.
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (2)
|
||||
Result.extend (create {CMS_CORS_FILTER})
|
||||
Result.extend (create {CMS_BASIC_AUTH_FILTER}.make (a_api))
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: routes
|
||||
|
||||
configure_api_login (api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_bal_handler: CMS_BASIC_AUTH_LOGIN_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_bal_handler.make (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
a_router.handle ("/basic_auth_login", l_bal_handler, l_methods)
|
||||
end
|
||||
|
||||
configure_api_logoff (api: CMS_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
l_bal_handler: CMS_BASIC_AUTH_LOGOFF_HANDLER
|
||||
l_methods: WSF_REQUEST_METHODS
|
||||
do
|
||||
create l_bal_handler.make (api)
|
||||
create l_methods
|
||||
l_methods.enable_get
|
||||
a_router.handle ("/basic_auth_logoff", l_bal_handler, l_methods)
|
||||
end
|
||||
|
||||
|
||||
handle_login_basic_auth (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Basic Auth", "optional_content_type")
|
||||
r.execute
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
auto_subscribe_to_hooks (a_response)
|
||||
a_response.hooks.subscribe_to_block_hook (Current)
|
||||
a_response.hooks.subscribe_to_value_table_alter_hook (Current)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if a_response.is_authenticated then
|
||||
a_value.force ("basic_auth_logoff", "auth_login_strategy")
|
||||
end
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on collection of menu contained by `a_menu_system'
|
||||
-- for related response `a_response'.
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
lnk2: detachable CMS_LINK
|
||||
do
|
||||
if attached a_response.user as u then
|
||||
across
|
||||
a_menu_system.primary_menu.items as ic
|
||||
until
|
||||
lnk2 /= Void
|
||||
loop
|
||||
if ic.item.location.same_string ("account/roc-logout") then
|
||||
lnk2 := ic.item
|
||||
end
|
||||
end
|
||||
|
||||
if lnk2 /= Void then
|
||||
a_menu_system.primary_menu.remove (lnk2)
|
||||
end
|
||||
|
||||
create lnk.make ("Logout", "basic_auth_logoff")
|
||||
lnk.set_weight (98)
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
else
|
||||
if a_response.location.starts_with ("account/") then
|
||||
create lnk.make ("Basic Auth", "account/roc-basic-auth")
|
||||
lnk.set_expandable (True)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
local
|
||||
l_string: STRING
|
||||
do
|
||||
Result := <<"login">>
|
||||
debug ("roc")
|
||||
create l_string.make_empty
|
||||
across
|
||||
Result as ic
|
||||
loop
|
||||
l_string.append (ic.item)
|
||||
l_string.append_character (' ')
|
||||
end
|
||||
write_debug_log (generator + ".block_list:" + l_string )
|
||||
end
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if
|
||||
a_block_id.is_case_insensitive_equal_general ("login") and then
|
||||
a_response.location.starts_with ("account/roc-basic-auth")
|
||||
then
|
||||
a_response.add_javascript_url (a_response.url ("module/" + name + "/files/js/roc_basic_auth.js", Void))
|
||||
get_block_view_login (a_block_id, a_response)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Helpers
|
||||
|
||||
template_block (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK
|
||||
-- Smarty content block for `a_block_id'
|
||||
local
|
||||
p: detachable PATH
|
||||
do
|
||||
create p.make_from_string ("templates")
|
||||
p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl")
|
||||
|
||||
p := a_response.api.module_theme_resource_location (Current, p)
|
||||
if p /= Void then
|
||||
if attached p.entry as e then
|
||||
create Result.make (a_block_id, Void, p.parent, e)
|
||||
else
|
||||
create Result.make (a_block_id, Void, p.parent, p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Block views
|
||||
|
||||
get_block_view_login (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
local
|
||||
vals: CMS_VALUE_TABLE
|
||||
do
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
create vals.make (1)
|
||||
-- add the variable to the block
|
||||
value_table_alter (vals, a_response)
|
||||
across
|
||||
vals as ic
|
||||
loop
|
||||
l_tpl_block.set_value (ic.item, ic.key)
|
||||
end
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -6,7 +6,7 @@ note
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
BASIC_AUTH_FILTER
|
||||
CMS_BASIC_AUTH_FILTER
|
||||
|
||||
inherit
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
@@ -4,7 +4,7 @@ note
|
||||
revision: "$Revision: 96085 $"
|
||||
|
||||
class
|
||||
CORS_FILTER
|
||||
CMS_CORS_FILTER
|
||||
|
||||
inherit
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
note
|
||||
description: "Summary description for {BASIC_AUTH_LOGIN_HANDLER}."
|
||||
description: "Summary description for {CMS_BASIC_AUTH_LOGIN_HANDLER}."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
BASIC_AUTH_LOGIN_HANDLER
|
||||
CMS_BASIC_AUTH_LOGIN_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
@@ -1,10 +1,10 @@
|
||||
note
|
||||
description: "Summary description for {BASIC_AUTH_LOGOFF_HANDLER}."
|
||||
description: "Summary description for {CMS_BASIC_AUTH_LOGOFF_HANDLER}."
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
BASIC_AUTH_LOGOFF_HANDLER
|
||||
CMS_BASIC_AUTH_LOGOFF_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user