Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
112be64095 | ||
|
|
aa1443cb8f | ||
|
|
6b2e256fa7 | ||
|
|
f8715d54a8 | ||
|
|
49b9ba3f86 | ||
|
|
84fe861cdc | ||
|
|
e8f024ede5 | ||
|
|
95d2306b1f | ||
|
|
60fbba5a70 | ||
|
|
be258c73e9 | ||
|
|
68ddd41fb7 | ||
|
|
72c35fd0f7 | ||
|
|
40855d73d3 | ||
|
|
1c149f9daf | ||
|
|
e445696698 | ||
|
|
375b53c677 | ||
|
|
ccf108a35e | ||
|
|
d00dd46187 | ||
|
|
7845240bf4 | ||
|
|
6b4b3f3539 | ||
|
|
92925169b4 | ||
|
|
3088468332 | ||
|
|
208a35cb73 | ||
|
|
bc561b1a48 | ||
|
|
9d7d43073d | ||
|
|
e04138c89e | ||
|
|
b83a050a1d | ||
|
|
6b4668ec6b | ||
|
|
5f7eb82def | ||
|
|
e9c028b94e | ||
|
|
f0180cc682 | ||
|
|
0c119b6b5a | ||
|
|
69894e8397 | ||
|
|
50a54ba519 | ||
|
|
2fcbcf1938 | ||
|
|
b6a5b4bc7f | ||
|
|
b732b20da8 | ||
|
|
c87b70a3ae | ||
|
|
dcf5132773 | ||
|
|
82bf9a4294 | ||
|
|
af3698ba5e | ||
|
|
71721ea00b | ||
|
|
ac9d29b971 | ||
|
|
34f0aa5844 |
19
.travis.yml
Normal file
19
.travis.yml
Normal file
@@ -0,0 +1,19 @@
|
||||
language: eiffel
|
||||
before_script:
|
||||
- export current_dir=$PWD ; echo current_dir=$current_dir ; cd ..
|
||||
- export ISE_VERSION=17.05; export ISE_BUILD=100416
|
||||
- curl -sSL http://downloads.sourceforge.net/eiffelstudio/Eiffel_${ISE_VERSION}_gpl_${ISE_BUILD}-linux-x86-64.tar.bz2 | tar -x --bzip2
|
||||
- export ISE_EIFFEL=$PWD/Eiffel_${ISE_VERSION} ; export ISE_PLATFORM=linux-x86-64
|
||||
- export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin:$PATH:$ISE_EIFFEL/tools/spec/$ISE_PLATFORM/bin
|
||||
- echo `ec -version`
|
||||
- cd $current_dir
|
||||
- echo Check projects compilation status...
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- v1
|
||||
|
||||
script: compile_all -ecb -melt -list_failures -log_verbose -clean -options dotnet=false
|
||||
group: stable
|
||||
os: linux
|
||||
5
cms.ecf
5
cms.ecf
@@ -3,12 +3,10 @@
|
||||
<target name="cms">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</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"/>
|
||||
@@ -19,6 +17,7 @@
|
||||
<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"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\web\authentication\http_authorization\http_authorization.ecf"/>
|
||||
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="kmp_matcher" location="$ISE_LIBRARY\library\text\regexp\kmp_matcher\kmp_matcher.ecf"/>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<target name="masquerade_auth">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
<target name="common" abstract="true">
|
||||
<root class="DEMO_CMS_SERVER" feature="make_and_launch"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option debug="true" warning="true">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
</option>
|
||||
<setting name="executable_name" value="demo"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
@@ -18,7 +19,6 @@
|
||||
</option>
|
||||
</library>
|
||||
<library name="cms_admin_module" location="..\..\modules\admin\admin.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
<library name="cms_auth_module" location="..\..\modules\auth\auth.ecf" readonly="false"/>
|
||||
<library name="cms_basic_auth_module" location="..\..\modules\basic_auth\basic_auth.ecf" readonly="false"/>
|
||||
<library name="cms_blog_module" location="..\..\modules\blog\cms_blog_module.ecf" readonly="false"/>
|
||||
@@ -28,16 +28,16 @@
|
||||
<library name="cms_demo_module" location="modules\demo\cms_demo_module.ecf" readonly="false"/>
|
||||
<library name="cms_feed_aggregator_module" location="..\..\modules\feed_aggregator\feed_aggregator.ecf" readonly="false"/>
|
||||
<library name="cms_files_module" location="..\..\modules\files\files.ecf" readonly="false"/>
|
||||
<library name="cms_google_search_20_module" location="..\..\modules\google_search_20\google_search_20"/>
|
||||
<library name="cms_messaging_module" location="..\..\modules\messaging\messaging.ecf"/>
|
||||
<library name="cms_google_search_20_module" location="..\..\modules\google_search_20\google_search_20.ecf" readonly="false" use_application_options="true"/>
|
||||
<library name="cms_messaging_module" location="..\..\modules\messaging\messaging.ecf" readonly="false"/>
|
||||
<library name="cms_node_module" location="..\..\modules\node\node.ecf" readonly="false"/>
|
||||
<library name="cms_oauth_20_module" location="..\..\modules\oauth20\oauth20.ecf" readonly="false"/>
|
||||
<library name="cms_openid_module" location="..\..\modules\openid\openid.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes.ecf" readonly="false"/>
|
||||
<library name="cms_seo_module" location="..\..\modules\seo\seo.ecf" readonly="false"/>
|
||||
<library name="cms_sitemap_module" location="..\..\modules\sitemap\sitemap.ecf" readonly="false"/>
|
||||
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth.ecf" readonly="false"/>
|
||||
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy.ecf" readonly="false"/>
|
||||
<library name="cms_sitemap_module" location="..\..\modules\sitemap\sitemap.ecf" readonly="false"/>
|
||||
<library name="cms_taxonomy_module" location="..\..\modules\taxonomy\taxonomy.ecf" readonly="false"/>
|
||||
<library name="cms_wikitext_module" location="..\..\modules\wikitext\wikitext.ecf" readonly="false"/>
|
||||
<library name="embedded_video_module" location="..\..\modules\embedded_video\embedded_video.ecf" readonly="false"/>
|
||||
<library name="masquerade_auth_module" location="..\..\dev_modules\masquerade_auth\masquerade_auth.ecf" readonly="false"/>
|
||||
@@ -46,7 +46,7 @@
|
||||
By default, commented, since it depends on specific environment settings.
|
||||
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc.ecf"/>
|
||||
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql.ecf" />
|
||||
-->
|
||||
-->
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
|
||||
</target>
|
||||
@@ -55,29 +55,28 @@
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo_standalone" extends="common">
|
||||
<option debug="true">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
</option>
|
||||
<variable name="httpd_ssl_disabled" value="true"/>
|
||||
<library name="standalone_launcher" location="..\..\launcher\standalone.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo_standalone_none" extends="demo_standalone">
|
||||
<capability>
|
||||
<concurrency support="none" use="none"/>
|
||||
<concurrency use="none"/>
|
||||
</capability>
|
||||
</target>
|
||||
<target name="demo_standalone_mt" extends="demo_standalone">
|
||||
<capability>
|
||||
<concurrency support="thread" use="thread"/>
|
||||
<concurrency use="thread"/>
|
||||
</capability>
|
||||
</target>
|
||||
<target name="demo_standalone_scoop" extends="demo_standalone">
|
||||
|
||||
<capability>
|
||||
<concurrency use="scoop"/>
|
||||
</capability>
|
||||
</target>
|
||||
<target name="demo_standalone_scoop_ssl" extends="demo_standalone_scoop">
|
||||
<capability>
|
||||
<concurrency support="scoop" use="scoop"/>
|
||||
<concurrency use="scoop"/>
|
||||
</capability>
|
||||
<variable name="httpd_ssl_enabled" value="true"/>
|
||||
<variable name="libcurl_http_client_disabled" value="true"/>
|
||||
@@ -86,14 +85,14 @@
|
||||
</target>
|
||||
<target name="demo_cgi" extends="common">
|
||||
<capability>
|
||||
<concurrency support="none" use="none"/>
|
||||
<concurrency use="none"/>
|
||||
</capability>
|
||||
<library name="cgi_launcher" location="..\..\launcher\cgi.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
<target name="demo_libfcgi" extends="common">
|
||||
<capability>
|
||||
<concurrency support="none" use="none"/>
|
||||
<concurrency use="none"/>
|
||||
</capability>
|
||||
<library name="libfcgi_launcher" location="..\..\launcher\libfcgi.ecf" readonly="false"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="cms_demo_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<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" location="..\..\..\..\cms.ecf" readonly="false"/>
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
"project": "demo-safe.ecf",
|
||||
"location": ".",
|
||||
"site_directory": "site",
|
||||
"themes": {
|
||||
"admin": { "location": "../../themes/admin", "mode": "link" }
|
||||
},
|
||||
"modules": {
|
||||
"demo": { "location": "modules/demo" },
|
||||
"core": { "location": "../../modules/core" },
|
||||
"admin": { "location": "../../modules/admin" },
|
||||
"auth": { "location": "../../modules/auth" },
|
||||
|
||||
@@ -57,13 +57,15 @@ output=site\db\mails
|
||||
#openid.token=
|
||||
#oauth.token=
|
||||
|
||||
[webapi]
|
||||
mode=on
|
||||
|
||||
[administration]
|
||||
base_path=/roc-admin
|
||||
#theme=admin
|
||||
theme=admin
|
||||
# CMS Installation, are accessible by "all", "none" or uppon "permission". (default is none)
|
||||
installation_access=all
|
||||
|
||||
[dev]
|
||||
# masquerade: all, none, permission. Default is none.
|
||||
masquerade=none
|
||||
masquerade=all
|
||||
|
||||
@@ -41,6 +41,18 @@ ul.cms-roles li.cms_role a::before {
|
||||
content: "[role] ";
|
||||
}
|
||||
|
||||
table.cms-roles {
|
||||
border: solid 1px black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.cms-roles th, table.cms-roles td {
|
||||
padding: 2px;
|
||||
border: solid 1px black;
|
||||
}
|
||||
table.cms-roles td.cms_role_permission {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul.cms-permissions {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
|
||||
@@ -45,6 +45,14 @@ ul.cms-roles {
|
||||
content: "[role] ";
|
||||
}
|
||||
}
|
||||
table.cms-roles {
|
||||
border: solid 1px black;
|
||||
border-collapse: collapse;
|
||||
th,td {padding: 2px; border: solid 1px black; }
|
||||
td.cms_role_permission {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-permissions {
|
||||
|
||||
6
examples/demo/site/modules/core/scripts/user_profile.sql
Normal file
6
examples/demo/site/modules/core/scripts/user_profile.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE user_profiles(
|
||||
`uid` INTEGER NOT NULL CHECK("uid">=0),
|
||||
`key` VARCHAR(255) NOT NULL,
|
||||
`value` TEXT,
|
||||
CONSTRAINT PK_uid_key PRIMARY KEY (uid,key)
|
||||
);
|
||||
@@ -1,3 +1,10 @@
|
||||
div.feed ul.nav {
|
||||
list-style: none;
|
||||
}
|
||||
div.feed ul.nav li {
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
}
|
||||
div.feed ul {
|
||||
list-style: none;
|
||||
position: relative;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
div.feed {
|
||||
ul.nav {
|
||||
list-style: none;
|
||||
li {
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
position: relative;
|
||||
|
||||
1
examples/demo/site/modules/files/files/js/basic.css
Normal file
1
examples/demo/site/modules/files/files/js/basic.css
Normal file
@@ -0,0 +1 @@
|
||||
.dropzone,.dropzone *{box-sizing:border-box}.dropzone{position:relative}.dropzone .dz-preview{position:relative;display:inline-block;width:120px;margin:0.5em}.dropzone .dz-preview .dz-progress{display:block;height:15px;border:1px solid #aaa}.dropzone .dz-preview .dz-progress .dz-upload{display:block;height:100%;width:0;background:green}.dropzone .dz-preview .dz-error-message{color:red;display:none}.dropzone .dz-preview.dz-error .dz-error-message,.dropzone .dz-preview.dz-error .dz-error-mark{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{display:block}.dropzone .dz-preview .dz-error-mark,.dropzone .dz-preview .dz-success-mark{position:absolute;display:none;left:30px;top:30px;width:54px;height:58px;left:50%;margin-left:-27px}
|
||||
@@ -12,4 +12,8 @@
|
||||
display: inline-block;
|
||||
padding: 0 2px 0 2px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-bottom: dotted 1px #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
display: inline-block;
|
||||
padding: 0 2px 0 2px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border-bottom: dotted 1px #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: #efefef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
examples/demo/site/themes/admin/assets/css/style.css
Normal file
107
examples/demo/site/themes/admin/assets/css/style.css
Normal file
@@ -0,0 +1,107 @@
|
||||
div {
|
||||
background-color: #ffdddd;
|
||||
}
|
||||
|
||||
ul.horizontal li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#header #primary.menu ul li {
|
||||
color: #555;
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
margin: 0;
|
||||
}
|
||||
#header #primary.menu ul li a {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
}
|
||||
#header #primary.menu ul li a:hover {
|
||||
color: black;
|
||||
}
|
||||
#header #primary.menu ul.horizontal {
|
||||
border-bottom: solid 1px #ddd;
|
||||
}
|
||||
#header #primary.menu ul.horizontal li {
|
||||
border-top: solid 3px #fff;
|
||||
}
|
||||
#header #primary.menu ul.horizontal li:hover {
|
||||
background-color: #ffe;
|
||||
border-top: solid 3px #999;
|
||||
}
|
||||
#header #primary.menu ul.horizontal li.active {
|
||||
font-weight: bold;
|
||||
border-top: solid 3px #ddd;
|
||||
background-color: #ddd;
|
||||
}
|
||||
#header #primary.menu ul.horizontal li.active:hover {
|
||||
border-top: solid 3px blue;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-left: 20px;
|
||||
}
|
||||
#content #highlighted {
|
||||
position: relative;
|
||||
border: solid 1px #ddd;
|
||||
background-color: #ffc;
|
||||
width: 70%;
|
||||
left: 15%;
|
||||
right: 15%;
|
||||
padding: 5px;
|
||||
font-style: italic;
|
||||
}
|
||||
#content .preview {
|
||||
border: solid 1px red;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
padding: 5px;
|
||||
margin: 3px;
|
||||
/* border: solid 1px #ccc; */
|
||||
}
|
||||
.sidebar#sidebar_first {
|
||||
width: 250px;
|
||||
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;
|
||||
}
|
||||
#primary-tabs ul.horizontal li {
|
||||
display: inline;
|
||||
padding: 2px 5px;
|
||||
border: solid 1px #ccf;
|
||||
}
|
||||
#primary-tabs ul.horizontal li.active {
|
||||
border-color: #99f #99f #ddd;
|
||||
border-style: solid solid none;
|
||||
border-width: 2px 1px 0;
|
||||
padding: 2px 7px 1px;
|
||||
}
|
||||
|
||||
#message li.error {
|
||||
background-color: #f99;
|
||||
border: solid 1px red;
|
||||
padding: 5px 2px 5px 2px;
|
||||
}
|
||||
|
||||
table.with_border thead td {
|
||||
font-weight: bold;
|
||||
}
|
||||
table.with_border td {
|
||||
border: solid 1px #ccc;
|
||||
padding: 2px 5px 2px 5px;
|
||||
}
|
||||
BIN
examples/demo/site/themes/admin/assets/favicon.ico
Normal file
BIN
examples/demo/site/themes/admin/assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 994 B |
6
examples/demo/site/themes/admin/assets/js/jquery-1.10.2.min.js
vendored
Normal file
6
examples/demo/site/themes/admin/assets/js/jquery-1.10.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
$(document).ready(function() {
|
||||
$('#gcse_search_form').submit(function() {
|
||||
window.open('', 'formpopup', 'width=600,height=600,resizeable,scrollbars');
|
||||
this.target = 'formpopup';
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
101
examples/demo/site/themes/admin/page.tpl
Normal file
101
examples/demo/site/themes/admin/page.tpl
Normal file
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- EWF CMS -->
|
||||
<link rel="stylesheet" href="{$theme_path/}css/style.css">
|
||||
|
||||
<!-- jQuery dep -->
|
||||
<script src="{$theme_path/}js/jquery-1.10.2.min.js"></script>
|
||||
<script src="{$theme_path/}js/popup_search.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 -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
|
||||
|
||||
<title>{$head_title/}</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Page Top -->
|
||||
{if isset="$region_top"}
|
||||
{$region_top/}
|
||||
{/if}
|
||||
<!-- Body -->
|
||||
<div class='container-fluid'>
|
||||
|
||||
<!-- Page Header -->
|
||||
<div id="header">
|
||||
{if isset="$page.primary_nav"}
|
||||
{$page.primary_nav/}
|
||||
{/if}
|
||||
</div>
|
||||
<!-- Page search -->
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-md-offset-9">
|
||||
<form action="{$site_url/}gcse" class="search-form" id="gcse_search_form">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="search" class="form-control" name="q" id="gcse_search" placeholder="search" value="{htmlentities}{$cms_search_query/}{/htmlentities}" >
|
||||
<span class="glyphicon glyphicon-search form-control-feedback"></span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<!-- General Page Content -->
|
||||
<div id='content' class='row-fluid'>
|
||||
<!-- Left Sidebar sidebar_first -->
|
||||
{unless isempty="$page.region_sidebar_first"}
|
||||
<div id="sidebar_first" class="sidebar">{$page.region_sidebar_first/}</div>
|
||||
{/unless}
|
||||
<!-- Right Sidebar sidebar_second-->
|
||||
{unless isempty="$page.region_sidebar_second"}
|
||||
<div id="sidebar_second" class="sidebar">{$page.region_sidebar_second/}</div>
|
||||
{/unless}
|
||||
|
||||
<!-- Highlighted, Help, Content -->
|
||||
<div id='main' class='span8 main'>
|
||||
<!-- Highlighted Section -->
|
||||
{unless isempty="$page.region_highlighted"}
|
||||
<div id="highlighted">{$page.region_highlighted/}</div>
|
||||
{/unless}
|
||||
<!-- Help Section -->
|
||||
{unless isempty="$page.region_help"}
|
||||
<div id="help">{$page.region_help/}</div>
|
||||
{/unless}
|
||||
|
||||
<!-- Main Content Section -->
|
||||
{unless isempty="$page_title"}<h1 class="page-title">{$page_title/}</h1>{/unless}
|
||||
{$page.region_content/}
|
||||
{if condition="$page.is_front"}
|
||||
{if isset="$page.region_feed_news"}
|
||||
<div class="column" style="width: 45%; float: left">{$page.region_feed_news/}</div>
|
||||
{/if}
|
||||
{if isset="$page.region_feed_forum"}
|
||||
<div class="column" style="width: 45%; float: left">{$page.region_feed_forum/}</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Page footer -->
|
||||
{$page.region_footer/}
|
||||
|
||||
<!-- Page Bottom -->
|
||||
{$page.region_bottom/}
|
||||
|
||||
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
|
||||
|
||||
{include file="debug.tpl"/}
|
||||
</body>
|
||||
</html>
|
||||
14
examples/demo/site/themes/admin/theme.info
Normal file
14
examples/demo/site/themes/admin/theme.info
Normal file
@@ -0,0 +1,14 @@
|
||||
name=admin
|
||||
engine=smarty
|
||||
author=jocelyn fiat
|
||||
version=0.1
|
||||
regions[page_top] = Top
|
||||
regions[header] = Header
|
||||
regions[content] = Content
|
||||
regions[highlighted] = Highlighted
|
||||
regions[help] = Help
|
||||
regions[footer] = Footer
|
||||
regions[sidebar_first] = first sidebar
|
||||
regions[sidebar_second] = second sidebar
|
||||
regions[page_bottom] = Bottom
|
||||
navigation=default_nav
|
||||
@@ -10,7 +10,6 @@
|
||||
<target name="launcher" extends="common">
|
||||
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi.ecf"/>
|
||||
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi.ecf"/>
|
||||
|
||||
<library name="standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\standalone.ecf"/>
|
||||
<cluster name="launcher" location=".\any\" recursive="true"/>
|
||||
<cluster name="src" location=".\"/>
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="cgi_launcher" uuid="0FE4F1D0-BB70-4C7F-A66E-B27F1D718109" library_target="cgi_launcher">
|
||||
<target name="common" abstract="true">
|
||||
<root all_classes="true"/>
|
||||
<capability>
|
||||
<concurrency support="none"/>
|
||||
</capability>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="libfcgi_launcher" uuid="04D7D1EA-059B-4024-B0DE-BBB57AB2D00C" library_target="libfcgi_launcher">
|
||||
<target name="common" abstract="true">
|
||||
<root all_classes="true"/>
|
||||
<option>
|
||||
</option>
|
||||
<capability>
|
||||
<concurrency support="none"/>
|
||||
</capability>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="standalone_launcher" uuid="F42660A9-26C2-466B-A63C-C7823C808BE7" library_target="standalone_launcher">
|
||||
<target name="common" abstract="true">
|
||||
<root all_classes="true"/>
|
||||
<option>
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
<description>Application Environment (layout, configuration, logger, database, ...)</description>
|
||||
<target name="app_env">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -38,14 +38,14 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
|
||||
make_with_path (p: PATH)
|
||||
-- Create a layour based on a path `p'.
|
||||
-- Create a layout based on a path `p'.
|
||||
do
|
||||
path := p.absolute_path.canonical_path
|
||||
initialize_name
|
||||
end
|
||||
|
||||
make_with_directory_name (a_dirname: READABLE_STRING_GENERAL)
|
||||
-- Create a layour based on a path `p'.
|
||||
-- Create a layout based on directory name `a_dirname'.
|
||||
do
|
||||
make_with_path (create {PATH}.make_from_string (a_dirname))
|
||||
end
|
||||
@@ -105,11 +105,18 @@ feature -- Access: internal
|
||||
application_config_path: PATH
|
||||
-- Database Configuration file path.
|
||||
local
|
||||
p: detachable PATH
|
||||
p,p_dft: detachable PATH
|
||||
fut: FILE_UTILITIES
|
||||
do
|
||||
p := internal_application_config_path
|
||||
if p = Void then
|
||||
p := config_path.extended (name + ".json")
|
||||
if not fut.file_path_exists (p) then
|
||||
p_dft := config_path.extended ("env.json")
|
||||
if fut.file_path_exists (p_dft) then
|
||||
p := p_dft
|
||||
end
|
||||
end
|
||||
internal_application_config_path := p
|
||||
end
|
||||
Result := p
|
||||
@@ -206,6 +213,6 @@ feature {NONE} -- Implementation
|
||||
-- Directory for templates (HTML, etc).
|
||||
|
||||
;note
|
||||
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
copyright: "2011-2017, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
<target name="config">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
<target name="config_tests">
|
||||
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<capability>
|
||||
<concurrency use="none"/>
|
||||
</capability>
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="email_service">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms_app_env" location="..\app_env\app_env.ecf"/>
|
||||
<library name="notification_mailer" location="$ISE_LIBRARY\contrib\library\runtime\process\notification_email\notification_email.ecf"/>
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
<target name="gcse">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="http_client_extension" location="..\http_client_extension\http_client_extension.ecf" readonly="false"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="gcse_tests" uuid="6E2183A4-28E0-4835-A9AA-BAB13696D873">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="gcse_tests" uuid="8E9CF931-93CE-4C5A-BF1A-6FD7D850C5FB">
|
||||
<target name="gcse_tests">
|
||||
<root class="APPLICATION" feature="make"/>
|
||||
<option warning="true">
|
||||
@@ -14,7 +14,7 @@
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<cluster name="test" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="http_client_extension" uuid="EA6A381D-2E78-448C-8A6D-B71759F1082E" library_target="http_client_extension">
|
||||
<target name="http_client_extension">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
|
||||
<file_rule>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<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="curl" location="$ISE_LIBRARY\library\cURL\cURL.ecf"/>
|
||||
@@ -14,13 +16,6 @@
|
||||
<library name="http_client" location="$ISE_LIBRARY\contrib\library\network\http_client\http_client.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||
<cluster name="http_client_extension" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="http_client_extension" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -2,18 +2,15 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
|
||||
<target name="cms_model">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<file_rule>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<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="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="cms_model" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="cms_model" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -23,12 +23,18 @@ feature -- Access
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_personal_information (a_personal_information: like personal_information)
|
||||
-- Assign `personal_information' with `a_personal_information'.
|
||||
set_personal_information (a_personal_information: detachable READABLE_STRING_GENERAL)
|
||||
-- Assign `personal_information` with `a_personal_information`.
|
||||
do
|
||||
personal_information := a_personal_information
|
||||
if a_personal_information = Void then
|
||||
personal_information := Void
|
||||
else
|
||||
personal_information := a_personal_information.as_string_32
|
||||
end
|
||||
ensure
|
||||
personal_information_assigned: personal_information = a_personal_information
|
||||
personal_information_assigned: a_personal_information /= Void
|
||||
implies (attached personal_information as inf and then
|
||||
a_personal_information.same_string (inf))
|
||||
end
|
||||
|
||||
set_salt (a_salt: like salt)
|
||||
|
||||
@@ -98,19 +98,6 @@ feature -- Roles
|
||||
roles: detachable LIST [CMS_USER_ROLE]
|
||||
-- If set, list of roles for current user.
|
||||
|
||||
feature -- Access: data
|
||||
|
||||
item (k: READABLE_STRING_GENERAL): detachable ANY assign put
|
||||
-- Additional item data associated with key `k'.
|
||||
do
|
||||
if attached items as tb then
|
||||
Result := tb.item (k)
|
||||
end
|
||||
end
|
||||
|
||||
items: detachable STRING_TABLE [detachable ANY]
|
||||
-- Additional data.
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_id: BOOLEAN
|
||||
@@ -223,29 +210,6 @@ feature -- Element change: roles
|
||||
roles := lst
|
||||
end
|
||||
|
||||
feature -- Change element: data
|
||||
|
||||
put (d: like item; k: READABLE_STRING_GENERAL)
|
||||
-- Associate data item `d' with key `k'.
|
||||
local
|
||||
tb: like items
|
||||
do
|
||||
tb := items
|
||||
if tb = Void then
|
||||
create tb.make (1)
|
||||
items := tb
|
||||
end
|
||||
tb.force (d, k)
|
||||
end
|
||||
|
||||
remove (k: READABLE_STRING_GENERAL)
|
||||
-- Remove data item associated with key `k'.
|
||||
do
|
||||
if attached items as tb then
|
||||
tb.remove (k)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status change
|
||||
|
||||
mark_not_active
|
||||
|
||||
72
library/model/src/user/cms_user_profile.e
Normal file
72
library/model/src/user/cms_user_profile.e
Normal file
@@ -0,0 +1,72 @@
|
||||
note
|
||||
description: "[
|
||||
User profile used to extend information associated with a {CMS_USER}.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_USER_PROFILE
|
||||
|
||||
inherit
|
||||
TABLE_ITERABLE [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create Current profile.
|
||||
do
|
||||
create items.make (0)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
item alias "[]" (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
|
||||
-- Profile item associated with key `k`.
|
||||
do
|
||||
Result := items.item (k)
|
||||
end
|
||||
|
||||
has_key (k: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Has a profile item associated with key `k`?
|
||||
do
|
||||
Result := items.has (k)
|
||||
end
|
||||
|
||||
count: INTEGER
|
||||
do
|
||||
Result := items.count
|
||||
end
|
||||
|
||||
is_empty: BOOLEAN
|
||||
do
|
||||
Result := items.is_empty
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
force (v: READABLE_STRING_GENERAL; k: READABLE_STRING_GENERAL)
|
||||
-- Associated value `v` with key `k`.
|
||||
do
|
||||
items.force (v.to_string_32, k)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
new_cursor: TABLE_ITERATION_CURSOR [READABLE_STRING_32, READABLE_STRING_GENERAL]
|
||||
-- Fresh cursor associated with current structure
|
||||
do
|
||||
Result := items.new_cursor
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
items: STRING_TABLE [READABLE_STRING_32]
|
||||
|
||||
;note
|
||||
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
@@ -110,6 +110,12 @@ feature -- Query
|
||||
sql_post_execution
|
||||
end
|
||||
|
||||
sql_delete (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
-- <Precursor>
|
||||
do
|
||||
sql_modify (a_sql_statement, a_params)
|
||||
end
|
||||
|
||||
sql_rows_count: INTEGER
|
||||
-- Number of rows for last sql execution.
|
||||
do
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="persistence_sqlite3" uuid="4E536C92-A09F-4305-8230-2EC5ABC51416" library_target="persistence_sqlite3">
|
||||
<target name="persistence_sqlite3">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<file_rule>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<library name="app_env" location="..\..\app_env\app_env.ecf"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf"/>
|
||||
@@ -13,15 +17,8 @@
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||
<library name="model" location="..\..\model\cms_model.ecf"/>
|
||||
<library name="sqlite3" location="$ISE_LIBRARY\unstable\library\persistency\database\sqlite3\sqlite.ecf"/>
|
||||
<library name="sqlite3" location="$ISE_LIBRARY\unstable\library\persistency\database\sqlite3\sqlite.ecf" readonly="false"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/old$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="persistence_sqlite" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -73,14 +73,25 @@ feature -- Execution
|
||||
|
||||
sql_begin_transaction
|
||||
-- Start a database transtaction.
|
||||
local
|
||||
retried: BOOLEAN
|
||||
do
|
||||
if transaction_depth = 0 then
|
||||
sqlite.begin_transaction (False)
|
||||
end
|
||||
transaction_depth := transaction_depth + 1
|
||||
debug ("roc_storage")
|
||||
print ("# sql_begin_transaction (depth="+ transaction_depth.out +").%N")
|
||||
if retried then
|
||||
-- Issue .. db locked?
|
||||
sql_rollback_transaction
|
||||
error_handler.add_custom_error (-1, "db error", "Unable to begin transaction..")
|
||||
else
|
||||
if transaction_depth = 0 then
|
||||
sqlite.begin_transaction (False)
|
||||
end
|
||||
transaction_depth := transaction_depth + 1
|
||||
debug ("roc_storage")
|
||||
print ("# sql_begin_transaction (depth="+ transaction_depth.out +").%N")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
sql_rollback_transaction
|
||||
@@ -230,6 +241,12 @@ feature -- Operation
|
||||
end
|
||||
end
|
||||
|
||||
sql_delete (a_sql_statement: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
-- <Precursor>
|
||||
do
|
||||
sql_modify (a_sql_statement, a_params)
|
||||
end
|
||||
|
||||
sqlite_arguments (a_params: STRING_TABLE [detachable ANY]): ARRAYED_LIST [SQLITE_BIND_ARG [ANY]]
|
||||
local
|
||||
k: READABLE_STRING_GENERAL
|
||||
@@ -440,12 +457,12 @@ feature -- Conversion
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
i := a_statement.substring_index ("AUTO_INCREMENT", i)
|
||||
i := a_statement.substring_index ("KEY AUTO_INCREMENT", i)
|
||||
if i > 0 then
|
||||
if Result = a_statement then
|
||||
create Result.make_from_string (a_statement)
|
||||
end
|
||||
Result.remove (i + 4)
|
||||
Result.remove (i + 8)
|
||||
i := i + 14
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
<description>CMS Eiffel Store MySQL persistence solution</description>
|
||||
<target name="store_mysql">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\app_env\app_env.ecf"/>
|
||||
@@ -24,7 +22,8 @@
|
||||
</cluster>
|
||||
<cluster name="persistence_store_mysql" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="tests" uuid="FCC2264E-784F-4ACF-9262-E348904FDBA5">
|
||||
<target name="tests">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="store_mysql_tests" uuid="FCC2264E-784F-4ACF-9262-E348904FDBA5">
|
||||
<target name="store_mysql_tests">
|
||||
<root class="APPLICATION" feature="make"/>
|
||||
<option warning="true">
|
||||
<assertions supplier_precondition="true"/>
|
||||
@@ -19,7 +19,7 @@
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<cluster name="tests" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/nodes$</exclude>
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
<description>CMS Eiffel Store MySQL persistence solution FAKE!!!</description>
|
||||
<target name="store_mysql_fake">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\app_env\app_env.ecf"/>
|
||||
@@ -17,7 +15,7 @@
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="persistence_store_mysql_fake" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
<target name="persistence_store_odbc">
|
||||
<description>CMS Eiffel Store ODBC persistence solution</description>
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\app_env\app_env.ecf"/>
|
||||
@@ -20,7 +18,7 @@
|
||||
<cluster name="common" location="..\implementation\store\" recursive="true"/>
|
||||
<cluster name="persistence_store_odbc" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<cluster name="tests" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/nodes$</exclude>
|
||||
|
||||
@@ -3,18 +3,15 @@
|
||||
<target name="recaptcha">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="http_client_extension" location="..\http_client_extension\http_client_extension.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<cluster name="recaptcha" location=".\src\" recursive="true"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf"/>
|
||||
<library name="uri" location="$ISE_LIBRARY\library\text\uri\uri.ecf"/>
|
||||
</cluster>
|
||||
<cluster name="recaptcha" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<cluster name="test" location=".\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="admin">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="false" syntax="transitional">
|
||||
<assertions/>
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -27,6 +27,7 @@ feature -- Security
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force (perm_view_system_info)
|
||||
Result.force ("access admin")
|
||||
Result.force ("admin users")
|
||||
Result.force ("admin roles")
|
||||
@@ -39,6 +40,8 @@ feature -- Security
|
||||
Result.force ("admin formats")
|
||||
end
|
||||
|
||||
perm_view_system_info: STRING = "view system info"
|
||||
|
||||
feature {NONE} -- Router/administration
|
||||
|
||||
setup_administration_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
@@ -46,6 +49,8 @@ feature {NONE} -- Router/administration
|
||||
local
|
||||
l_admin_handler: CMS_ADMIN_HANDLER
|
||||
|
||||
l_info_handler: CMS_ADMIN_INFO_HANDLER
|
||||
|
||||
l_modules_handler: CMS_ADMIN_MODULES_HANDLER
|
||||
l_users_handler: CMS_ADMIN_USERS_HANDLER
|
||||
l_roles_handler: CMS_ADMIN_ROLES_HANDLER
|
||||
@@ -67,6 +72,10 @@ feature {NONE} -- Router/administration
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("", l_admin_handler)
|
||||
a_router.map (l_uri_mapping, a_router.methods_get_post)
|
||||
|
||||
create l_info_handler.make (a_api)
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("/info", l_info_handler)
|
||||
a_router.map (l_uri_mapping, a_router.methods_get)
|
||||
|
||||
create l_modules_handler.make (a_api)
|
||||
create l_uri_mapping.make_trailing_slash_ignored ("/modules", l_modules_handler)
|
||||
a_router.map (l_uri_mapping, a_router.methods_get_post)
|
||||
@@ -146,27 +155,39 @@ feature -- Hooks
|
||||
if l_api.user_is_authenticated then
|
||||
admin_lnk := a_menu_system.management_menu.new_composite_item ("Admin", l_api.administration_path_location (""))
|
||||
|
||||
-- Global system information
|
||||
create lnk.make ("Info", l_api.administration_path_location ("info"))
|
||||
lnk.set_permission_arguments (<<"view system info">>)
|
||||
lnk.set_weight (-1)
|
||||
admin_lnk.extend (lnk)
|
||||
|
||||
create lnk.make ("Module", l_api.administration_path_location ("modules"))
|
||||
lnk.set_permission_arguments (<<"manage module">>)
|
||||
lnk.set_weight (1)
|
||||
admin_lnk.extend (lnk)
|
||||
|
||||
create lnk.make ("Formats", l_api.administration_path_location ("formats"))
|
||||
lnk.set_permission_arguments (<<"admin formats">>)
|
||||
lnk.set_weight (2)
|
||||
admin_lnk.extend (lnk)
|
||||
|
||||
-- Per module cache permission!
|
||||
create lnk.make ("Cache", l_api.administration_path_location ("cache"))
|
||||
lnk.set_permission_arguments (<<"admin cache">>)
|
||||
lnk.set_weight (3)
|
||||
admin_lnk.extend (lnk)
|
||||
|
||||
-- Per module export permission!
|
||||
create lnk.make ("Export", l_api.administration_path_location ("export"))
|
||||
lnk.set_permission_arguments (<<"admin export">>)
|
||||
lnk.set_weight (8)
|
||||
admin_lnk.extend (lnk)
|
||||
-- Per module import permission!
|
||||
create lnk.make ("Import", l_api.administration_path_location ("import"))
|
||||
lnk.set_permission_arguments (<<"admin import">>)
|
||||
lnk.set_weight (9)
|
||||
admin_lnk.extend (lnk)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
80
modules/admin/handler/cms_admin_info_handler.e
Normal file
80
modules/admin/handler/cms_admin_info_handler.e
Normal file
@@ -0,0 +1,80 @@
|
||||
note
|
||||
description: "Display information about ROC CMS installation."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_ADMIN_INFO_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute request handler
|
||||
local
|
||||
r: like new_generic_response
|
||||
s: STRING
|
||||
do
|
||||
if req.is_get_request_method then
|
||||
if api.has_permission ({CMS_ADMIN_MODULE_ADMINISTRATION}.perm_view_system_info) then
|
||||
r := new_generic_response (req, res)
|
||||
create s.make_empty
|
||||
r.set_title ("System Information")
|
||||
r.add_to_primary_tabs (api.administration_link ("Administration", ""))
|
||||
append_system_info_to (s)
|
||||
r.set_main_content (s)
|
||||
r.execute
|
||||
else
|
||||
send_access_denied (req, res)
|
||||
end
|
||||
else
|
||||
send_bad_request (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
append_system_info_to (s: STRING)
|
||||
local
|
||||
n: INTEGER
|
||||
do
|
||||
s.append ("<ul>")
|
||||
s.append ("<li><strong>Current direction:</strong> ")
|
||||
s.append (html_encoded ((create {EXECUTION_ENVIRONMENT}).current_working_path.name))
|
||||
s.append ("</li>")
|
||||
s.append ("<li><strong>Site:</strong> ")
|
||||
s.append (html_encoded (api.setup.site_location.name))
|
||||
s.append ("</li>")
|
||||
s.append ("<li><strong>Cache:</strong> ")
|
||||
s.append (html_encoded (api.setup.cache_location.name))
|
||||
s.append ("</li>")
|
||||
s.append ("<li><strong>Files:</strong> ")
|
||||
s.append (html_encoded (api.setup.files_location.name))
|
||||
s.append ("</li>")
|
||||
s.append ("<li><strong>Temp:</strong> ")
|
||||
s.append (html_encoded (api.setup.temp_location.name))
|
||||
s.append ("</li>")
|
||||
s.append ("<li><strong>Storage:</strong>")
|
||||
n := s.count
|
||||
across
|
||||
api.setup.storage_drivers as ic
|
||||
loop
|
||||
if s.count > n then
|
||||
s.append (", ")
|
||||
else
|
||||
s.append (" ")
|
||||
end
|
||||
s.append (html_encoded (ic.key))
|
||||
end
|
||||
s.append (" -> ")
|
||||
s.append (api.storage.generator)
|
||||
s.append ("</li>")
|
||||
s.append ("</ul>")
|
||||
end
|
||||
|
||||
end
|
||||
@@ -50,7 +50,7 @@ feature -- Execution
|
||||
attached {WSF_TABLE} req.query_parameter ("module_uninstallation") as tb
|
||||
then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if attached api.setup.string_8_item ("admin.installation_access") as l_access then
|
||||
if attached api.setup.string_8_item ("administration.installation_access") as l_access then
|
||||
if l_access.is_case_insensitive_equal ("none") then
|
||||
l_denied := True
|
||||
elseif l_access.is_case_insensitive_equal ("permission") then
|
||||
|
||||
@@ -7,7 +7,6 @@ class
|
||||
CMS_ADMIN_ROLES_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
@@ -29,6 +28,8 @@ inherit
|
||||
do_get
|
||||
end
|
||||
|
||||
CMS_SHARED_SORTING_UTILITIES
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
@@ -54,26 +55,30 @@ feature -- execute
|
||||
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_role: CMS_USER_ROLE
|
||||
l_perm: READABLE_STRING_8
|
||||
l_count: INTEGER
|
||||
user_api: CMS_USER_API
|
||||
l_full: BOOLEAN
|
||||
l_modname: STRING_8
|
||||
l_mods: ARRAYED_LIST [STRING_8]
|
||||
l_perms: LIST [READABLE_STRING_8]
|
||||
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
|
||||
|
||||
l_full := attached {WSF_STRING} req.query_parameter ("full") as p and then p.is_case_insensitive_equal ("yes")
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api)
|
||||
|
||||
create s.make_empty
|
||||
@@ -84,27 +89,93 @@ feature -- HTTP Methods
|
||||
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 (api.administration_path ("/role/") + u.id.out))
|
||||
s.append ("%">")
|
||||
s.append (html_encoded (u.name))
|
||||
s.append ("</a>")
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
l_response.add_to_primary_tabs (api.local_link ("Permissions", l_response.location + "?full=yes"))
|
||||
l_response.add_to_primary_tabs (api.local_link ("Roles", l_response.location))
|
||||
|
||||
if l_full then
|
||||
s.append ("<table class=%"cms-roles%"><tr><th>Permissions</th>")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
l_role := ic.item
|
||||
s.append ("<th class=%"cms_role%">")
|
||||
s.append ("<a href=%"")
|
||||
s.append (req.absolute_script_url (api.administration_path ("/role/") + l_role.id.out))
|
||||
s.append ("%">")
|
||||
s.append (html_encoded (l_role.name))
|
||||
s.append ("</a>")
|
||||
s.append ("</th>%N")
|
||||
end
|
||||
s.append ("</tr>")
|
||||
if attached user_api.role_permissions as l_role_permissions then
|
||||
create l_mods.make (l_role_permissions.count)
|
||||
across
|
||||
l_role_permissions as m_ic
|
||||
loop
|
||||
l_modname := m_ic.key
|
||||
l_mods.force (l_modname)
|
||||
end
|
||||
string_sorter.sort (l_mods)
|
||||
across
|
||||
l_mods as m_ic
|
||||
loop
|
||||
l_modname := m_ic.item
|
||||
l_perms := l_role_permissions.item (l_modname)
|
||||
s.append ("<tr><th colspan=%"" + (1 + lst.count).out + "%">")
|
||||
if l_modname.is_whitespace then
|
||||
s.append ("...")
|
||||
else
|
||||
s.append (html_encoded (l_modname))
|
||||
end
|
||||
s.append ("</th></tr>")
|
||||
if l_perms /= Void then
|
||||
across
|
||||
l_perms as p_ic
|
||||
loop
|
||||
l_perm := p_ic.item
|
||||
if not l_perm.is_whitespace then
|
||||
s.append ("<tr><td class=%"cms_role_permission%">")
|
||||
s.append (html_encoded (l_perm))
|
||||
s.append ("</td>")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
l_role := ic.item
|
||||
s.append ("<td>")
|
||||
if l_role.has_permission (l_perm) then
|
||||
s.append ("X")
|
||||
end
|
||||
s.append ("</td>")
|
||||
end
|
||||
s.append ("</tr>")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
s.append ("</table>")
|
||||
else
|
||||
s.append ("<ul class=%"cms-roles%">%N")
|
||||
across
|
||||
lst as ic
|
||||
loop
|
||||
l_role := ic.item
|
||||
s.append ("<li class=%"cms_role%">")
|
||||
s.append ("<a href=%"")
|
||||
s.append (req.absolute_script_url (api.administration_path ("/role/") + l_role.id.out))
|
||||
s.append ("%">")
|
||||
s.append (html_encoded (l_role.name))
|
||||
s.append ("</a>")
|
||||
s.append ("</li>%N")
|
||||
end
|
||||
s.append ("</ul>%N")
|
||||
end
|
||||
end
|
||||
s.append ("<br/>")
|
||||
if l_response.has_permission ("admin roles") then
|
||||
s.append (l_response.link ("Add Role", api.administration_path_location ("add/role"), Void))
|
||||
end
|
||||
|
||||
|
||||
l_response.set_main_content (s)
|
||||
l_response.execute
|
||||
end
|
||||
|
||||
@@ -37,11 +37,26 @@ feature -- Process
|
||||
b: STRING_8
|
||||
uid: INTEGER_64
|
||||
user_api: CMS_USER_API
|
||||
lnk: CMS_LINK
|
||||
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
|
||||
if l_role.has_id then
|
||||
lnk := api.administration_link (translation ("View", Void), "role/" + l_role.id.out)
|
||||
lnk.set_weight (1)
|
||||
add_to_primary_tabs (lnk)
|
||||
lnk := api.administration_link (translation ("Edit", Void), "role/" + l_role.id.out + "/edit")
|
||||
lnk.set_weight (2)
|
||||
add_to_primary_tabs (lnk)
|
||||
|
||||
lnk := api.administration_link (translation ("Delete", Void), "role/" + l_role.id.out + "/delete")
|
||||
lnk.set_weight (3)
|
||||
add_to_primary_tabs (lnk)
|
||||
|
||||
end
|
||||
|
||||
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
|
||||
@@ -52,6 +67,10 @@ feature -- Process
|
||||
else
|
||||
new_form
|
||||
end
|
||||
lnk := api.administration_link (translation ("<< Roles", Void), "roles")
|
||||
lnk.set_weight (10)
|
||||
add_to_primary_tabs (lnk)
|
||||
|
||||
end
|
||||
|
||||
feature -- Process Edit
|
||||
@@ -63,7 +82,7 @@ feature -- Process Edit
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_edit_form (a_role, request_url (Void), "edit-user")
|
||||
f := new_edit_form (a_role, request_url (Void), "edit-user-role")
|
||||
api.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))
|
||||
@@ -71,11 +90,7 @@ feature -- Process Edit
|
||||
f.process (Current)
|
||||
fd := f.last_data
|
||||
end
|
||||
if a_role.has_id then
|
||||
add_to_menu (api.administration_link (translation ("View", Void), "role/" + a_role.id.out), primary_tabs)
|
||||
add_to_menu (api.administration_link (translation ("Edit", Void), "role/" + a_role.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (api.administration_link (translation ("Delete", Void), "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)
|
||||
@@ -96,17 +111,13 @@ feature -- Process Delete
|
||||
fd: detachable WSF_FORM_DATA
|
||||
do
|
||||
create b.make_empty
|
||||
f := new_delete_form (a_role, request_url (Void), "edit-user")
|
||||
f := new_delete_form (a_role, request_url (Void), "delete-user-role")
|
||||
api.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 (api.administration_link (translation ("View", Void), "role/" + a_role.id.out), primary_tabs)
|
||||
add_to_menu (api.administration_link (translation ("Edit", Void), "role/" + a_role.id.out + "/edit"), primary_tabs)
|
||||
add_to_menu (api.administration_link (translation ("Delete", Void), "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)
|
||||
|
||||
@@ -45,7 +45,6 @@ feature -- Execution
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
append_html_to_output (a_role: CMS_USER_ROLE; a_response: CMS_RESPONSE )
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
@@ -66,6 +65,9 @@ feature -- Execution
|
||||
lnk.set_weight (3)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
end
|
||||
lnk := api.administration_link (translation ("<< Roles", Void), "roles")
|
||||
lnk.set_weight (10)
|
||||
add_to_primary_tabs (lnk)
|
||||
|
||||
create s.make_empty
|
||||
s.append ("<div class=%"info%"> ")
|
||||
|
||||
@@ -152,18 +152,30 @@ feature -- Process New
|
||||
set_main_content (b)
|
||||
end
|
||||
|
||||
feature -- Form
|
||||
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_update_password,
|
||||
l_update_roles,
|
||||
l_update_user,
|
||||
l_save_user: BOOLEAN
|
||||
l_user: detachable CMS_USER
|
||||
s: STRING
|
||||
lnk: CMS_LINK
|
||||
do
|
||||
|
||||
l_update_password := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update Password")
|
||||
if l_update_password then
|
||||
if a_user /= Void then
|
||||
l_user := a_user
|
||||
if l_user.has_id then
|
||||
lnk := api.administration_link (translation ("View", Void),"user/" + l_user.id.out)
|
||||
change_user (fd, a_user)
|
||||
s := "modified"
|
||||
set_redirection (lnk.location)
|
||||
end
|
||||
end
|
||||
end
|
||||
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")
|
||||
@@ -314,6 +326,7 @@ feature -- Form
|
||||
-- and apply this to content type `a_content_type'.
|
||||
local
|
||||
ti: WSF_FORM_TEXT_INPUT
|
||||
tp: WSF_FORM_PASSWORD_INPUT
|
||||
fe: WSF_FORM_EMAIL_INPUT
|
||||
fs: WSF_FORM_FIELD_SET
|
||||
cb: WSF_FORM_CHECKBOX_INPUT
|
||||
@@ -350,6 +363,19 @@ feature -- Form
|
||||
a_form.extend (ts)
|
||||
a_form.extend_html_text ("<hr>")
|
||||
|
||||
if api.has_permission ("admin users") then
|
||||
create fs.make
|
||||
fs.set_legend ("Change Password")
|
||||
create tp.make ("password")
|
||||
tp.set_label ("Password")
|
||||
tp.set_description ("Enter new password for the user.")
|
||||
tp.set_size (20)
|
||||
fs.extend (tp)
|
||||
create ts.make ("op")
|
||||
ts.set_default_value ("Update Password")
|
||||
fs.extend (ts)
|
||||
a_form.extend (fs)
|
||||
end
|
||||
|
||||
create fs.make
|
||||
fs.set_legend ("User Roles")
|
||||
@@ -463,6 +489,21 @@ feature -- Form
|
||||
else
|
||||
a_form_data.report_error ("Missing User")
|
||||
end
|
||||
elseif f_op.is_case_insensitive_equal_general ("Update Password") 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 ("password") as l_password and then not l_password.is_empty then
|
||||
l_user.set_password (l_password)
|
||||
api.user_api.update_user (l_user)
|
||||
if not api.user_api.has_error then
|
||||
add_success_message ("Updated user password")
|
||||
end
|
||||
else
|
||||
a_form_data.report_invalid_field ("password", "Missing password value!")
|
||||
end
|
||||
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
|
||||
@@ -516,13 +557,13 @@ feature -- Form
|
||||
create u.make (l_username)
|
||||
u.set_email (l_email.as_string_8)
|
||||
u.set_password (new_random_password (u))
|
||||
u.mark_active
|
||||
api.user_api.new_user (u)
|
||||
if api.user_api.has_error then
|
||||
-- handle error
|
||||
else
|
||||
add_success_message ("Created user")
|
||||
add_success_message ("Created user <a href=%"" + api.administration_path ("user/" + u.id.out) + "%">" + html_encoded (u.name) + "</a>")
|
||||
end
|
||||
|
||||
else
|
||||
a_form_data.report_invalid_field ("username", "Missing username!")
|
||||
a_form_data.report_invalid_field ("email", "Missing email address!")
|
||||
|
||||
@@ -61,12 +61,18 @@ feature -- Execution
|
||||
lnk.set_weight (2)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
|
||||
|
||||
if a_user /= Void and then a_user.id > 0 then
|
||||
lnk := api.administration_link (a_response.translation ("Delete", Void), "user/" + a_user.id.out + "/delete")
|
||||
lnk.set_weight (3)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
end
|
||||
|
||||
lnk := api.administration_link (a_response.translation ("<< Users", Void), "users")
|
||||
lnk.set_weight (10)
|
||||
a_response.add_to_primary_tabs (lnk)
|
||||
|
||||
|
||||
-- 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
|
||||
|
||||
@@ -7,7 +7,6 @@ class
|
||||
CMS_ADMIN_USERS_HANDLER
|
||||
|
||||
inherit
|
||||
|
||||
CMS_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
|
||||
@@ -41,6 +41,18 @@ ul.cms-roles li.cms_role a::before {
|
||||
content: "[role] ";
|
||||
}
|
||||
|
||||
table.cms-roles {
|
||||
border: solid 1px black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.cms-roles th, table.cms-roles td {
|
||||
padding: 2px;
|
||||
border: solid 1px black;
|
||||
}
|
||||
table.cms-roles td.cms_role_permission {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
ul.cms-permissions {
|
||||
list-style-type: none;
|
||||
padding: 3px 3px 3px 3px;
|
||||
|
||||
@@ -45,6 +45,14 @@ ul.cms-roles {
|
||||
content: "[role] ";
|
||||
}
|
||||
}
|
||||
table.cms-roles {
|
||||
border: solid 1px black;
|
||||
border-collapse: collapse;
|
||||
th,td {padding: 2px; border: solid 1px black; }
|
||||
td.cms_role_permission {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul.cms-permissions {
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="auth_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\authentication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
|
||||
29
modules/auth/cms_auth_strategy_filter.e
Normal file
29
modules/auth/cms_auth_strategy_filter.e
Normal file
@@ -0,0 +1,29 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTH_FILTER_WITH_LOGOUT}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_AUTH_STRATEGY_FILTER
|
||||
|
||||
inherit
|
||||
CMS_AUTH_FILTER
|
||||
redefine
|
||||
set_current_user
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
auth_strategy: STRING
|
||||
deferred
|
||||
end
|
||||
|
||||
set_current_user (u: CMS_USER)
|
||||
do
|
||||
Precursor (u)
|
||||
-- Record auth strategy:
|
||||
api.set_execution_variable ({CMS_AUTHENTICATION_MODULE}.auth_strategy_execution_variable_name, auth_strategy)
|
||||
end
|
||||
|
||||
end
|
||||
113
modules/auth/cms_authentication_api.e
Normal file
113
modules/auth/cms_authentication_api.e
Normal file
@@ -0,0 +1,113 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_API}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_API
|
||||
|
||||
inherit
|
||||
CMS_AUTH_API_I
|
||||
|
||||
create {CMS_AUTHENTICATION_MODULE}
|
||||
make
|
||||
|
||||
feature -- Token Generation
|
||||
|
||||
register_user (u: CMS_TEMP_USER; a_email: READABLE_STRING_8; a_personal_information: READABLE_STRING_GENERAL)
|
||||
local
|
||||
l_user_api: CMS_USER_API
|
||||
l_url_activate: STRING
|
||||
l_url_reject: STRING
|
||||
l_token: STRING
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
do
|
||||
l_user_api := cms_api.user_api
|
||||
|
||||
-- New temp user
|
||||
u.set_personal_information (a_personal_information)
|
||||
l_user_api.new_temp_user (u)
|
||||
|
||||
-- Create activation token
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, u.id)
|
||||
l_url_activate := cms_api.absolute_url ("/account/activate/" + l_token, Void)
|
||||
l_url_reject := cms_api.absolute_url ("/account/reject/" + l_token, Void)
|
||||
-- Send Email to webmaster
|
||||
cms_api.log_debug ("registration", "send_register_email", Void)
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (cms_api))
|
||||
es.send_account_evaluation (u, a_personal_information, l_url_activate, l_url_reject, cms_api.absolute_url ("", Void))
|
||||
|
||||
-- Send Email to user
|
||||
cms_api.log_debug ("registration", "send_contact_email", Void)
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (cms_api))
|
||||
es.send_contact_email (a_email, u, cms_api.absolute_url ("", Void))
|
||||
|
||||
cms_api.log ("registration", {STRING_32} "new user %"" + u.name + "%" <" + a_email + ">", {CMS_LOG}.level_info, Void)
|
||||
end
|
||||
|
||||
activate_user (a_temp_user: CMS_TEMP_USER; a_token: READABLE_STRING_GENERAL)
|
||||
require
|
||||
a_temp_user.has_id
|
||||
not a_temp_user.is_active
|
||||
local
|
||||
l_user_api: CMS_USER_API
|
||||
l_temp_id: INTEGER_64
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
do
|
||||
l_temp_id := a_temp_user.id
|
||||
|
||||
-- Valid user_id
|
||||
a_temp_user.set_id (0)
|
||||
a_temp_user.mark_active
|
||||
l_user_api := cms_api.user_api
|
||||
l_user_api.new_user_from_temp_user (a_temp_user)
|
||||
|
||||
if
|
||||
not l_user_api.has_error and then
|
||||
attached l_user_api.user_by_name (a_temp_user.name) as l_new_user
|
||||
then
|
||||
if attached a_temp_user.personal_information as l_perso_info then
|
||||
-- Keep personal information in profile item!
|
||||
l_user_api.save_user_profile_item (l_new_user, "personal_information", l_perso_info)
|
||||
end
|
||||
-- Delete temporal User
|
||||
a_temp_user.set_id (l_temp_id)
|
||||
l_user_api.delete_temp_user (a_temp_user)
|
||||
l_user_api.remove_activation (a_token)
|
||||
|
||||
-- Send Email
|
||||
if attached l_new_user.email as l_email then
|
||||
cms_api.log_debug ("activation", "send_contact_activation_confirmation_email", Void)
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (cms_api))
|
||||
es.send_contact_activation_confirmation_email (l_email, l_new_user, cms_api.site_url)
|
||||
end
|
||||
else
|
||||
error_handler.add_custom_error (-1, "activation error", "Activation failed!")
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
end
|
||||
@@ -8,12 +8,18 @@ class
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
rename
|
||||
module_api as auth_api
|
||||
redefine
|
||||
initialize,
|
||||
setup_hooks,
|
||||
permissions
|
||||
permissions,
|
||||
auth_api
|
||||
end
|
||||
|
||||
CMS_ADMINISTRABLE
|
||||
CMS_WITH_MODULE_ADMINISTRATION
|
||||
|
||||
CMS_WITH_WEBAPI
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
@@ -52,6 +58,15 @@ feature {NONE} -- Initialization
|
||||
enable -- Is enabled by default
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Initialization
|
||||
|
||||
initialize (api: CMS_API)
|
||||
-- <PRecursor>
|
||||
do
|
||||
create auth_api.make (api)
|
||||
Precursor (api)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "auth"
|
||||
@@ -64,10 +79,14 @@ feature -- Access
|
||||
Result.force ("account activate")
|
||||
Result.force ("account reject")
|
||||
Result.force ("account reactivate")
|
||||
Result.force ("edit own account")
|
||||
Result.force ("change own username")
|
||||
Result.force ("view user")
|
||||
Result.force ("change own password")
|
||||
Result.force ("view users")
|
||||
end
|
||||
|
||||
auth_api: detachable CMS_AUTHENTICATION_API
|
||||
|
||||
feature {CMS_EXECUTION} -- Administration
|
||||
|
||||
administration: CMS_AUTHENTICATION_MODULE_ADMINISTRATION
|
||||
@@ -75,6 +94,13 @@ feature {CMS_EXECUTION} -- Administration
|
||||
create Result.make (Current)
|
||||
end
|
||||
|
||||
feature -- Webapi
|
||||
|
||||
webapi: CMS_AUTHENTICATION_MODULE_WEBAPI
|
||||
do
|
||||
create Result.make (Current)
|
||||
end
|
||||
|
||||
feature -- Access: docs
|
||||
|
||||
root_dir: PATH
|
||||
@@ -99,10 +125,12 @@ feature -- Router
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
configure_web (a_api, a_router)
|
||||
if attached auth_api as l_auth_api then
|
||||
configure_web (l_auth_api, a_router)
|
||||
end
|
||||
end
|
||||
|
||||
configure_web (a_api: CMS_API; a_router: WSF_ROUTER)
|
||||
configure_web (a_api: CMS_AUTHENTICATION_API; a_router: WSF_ROUTER)
|
||||
local
|
||||
m: WSF_URI_MAPPING
|
||||
do
|
||||
@@ -124,8 +152,6 @@ feature -- Router
|
||||
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/change/{field}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_change_field (a_api, ?, ?)), a_router.methods_get_post)
|
||||
|
||||
a_router.handle ("/user/{uid}", create {CMS_USER_HANDLER}.make (a_api), a_router.methods_get)
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
@@ -206,25 +232,72 @@ feature -- Hooks configuration
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Handler / Constants
|
||||
|
||||
auth_strategy_execution_variable_name: STRING = "auth_strategy"
|
||||
-- Exevc
|
||||
|
||||
auth_strategy (req: WSF_REQUEST): detachable READABLE_STRING_8
|
||||
-- Strategy used by current authentication.
|
||||
-- note: if user is authenticated..
|
||||
do
|
||||
if
|
||||
attached {READABLE_STRING_GENERAL} req.execution_variable (auth_strategy_execution_variable_name) as s and then
|
||||
s.is_valid_as_string_8
|
||||
then
|
||||
Result := s.to_string_8
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Handler
|
||||
|
||||
handle_account (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
view_account_form_id: STRING = "roccms-user-view"
|
||||
edit_account_form_id: STRING = "roccms-user-edit"
|
||||
|
||||
handle_account (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user: detachable CMS_USER
|
||||
b: STRING
|
||||
lnk: CMS_LOCAL_LINK
|
||||
f: CMS_FORM
|
||||
tf: WSF_FORM_TEXT_INPUT
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
create b.make_empty
|
||||
l_user := r.user
|
||||
if attached smarty_template_block (Current, "account_info", api) as l_tpl_block then
|
||||
create f.make (r.location, view_account_form_id)
|
||||
if attached smarty_template_block (Current, "account_info", a_auth_api.cms_api) as l_tpl_block then
|
||||
l_tpl_block.set_weight (-10)
|
||||
r.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
r.add_warning_message ("Error with block [resources_page]")
|
||||
end
|
||||
if l_user /= Void then
|
||||
create tf.make_with_text ("username", l_user.name)
|
||||
tf.set_label ("Username")
|
||||
f.extend (tf)
|
||||
if attached l_user.email as l_email then
|
||||
create tf.make_with_text ("email", l_email.to_string_32)
|
||||
tf.set_label ("Email")
|
||||
f.extend (tf)
|
||||
end
|
||||
if attached l_user.profile_name as l_prof_name then
|
||||
create tf.make_with_text ("profile_name", l_prof_name)
|
||||
tf.set_label ("Profile name")
|
||||
f.extend (tf)
|
||||
end
|
||||
create tf.make_with_text ("creation", a_auth_api.cms_api.formatted_date_time_yyyy_mm_dd (l_user.creation_date))
|
||||
tf.set_label ("Creation date")
|
||||
f.extend (tf)
|
||||
|
||||
if attached l_user.last_login_date as dt then
|
||||
create tf.make_with_text ("last_login", a_auth_api.cms_api.formatted_date_time_ago (dt))
|
||||
tf.set_label ("Last login")
|
||||
f.extend (tf)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if r.is_authenticated then
|
||||
@@ -232,11 +305,16 @@ feature -- Handler
|
||||
lnk.set_weight (1)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
|
||||
create lnk.make ("Edit", "account/edit")
|
||||
lnk.set_weight (2)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
if r.has_permission ("edit own account") then
|
||||
create lnk.make ("Edit", "account/edit")
|
||||
lnk.set_weight (2)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
end
|
||||
end
|
||||
|
||||
a_auth_api.cms_api.hooks.invoke_form_alter (f, Void, r)
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
|
||||
r.set_main_content (b)
|
||||
|
||||
if l_user = Void then
|
||||
@@ -245,67 +323,80 @@ feature -- Handler
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_edit_account (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_edit_account (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user: detachable CMS_USER
|
||||
b: STRING
|
||||
lnk: CMS_LOCAL_LINK
|
||||
l_form: CMS_FORM
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create b.make_empty
|
||||
l_user := r.user
|
||||
if attached smarty_template_block (Current, "account_edit", api) as l_tpl_block then
|
||||
l_tpl_block.set_weight (-10)
|
||||
r.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
r.add_warning_message ("Error with block [resources_page]")
|
||||
if a_auth_api.cms_api.has_permission ("edit own account") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
create b.make_empty
|
||||
l_user := r.user
|
||||
create l_form.make (r.location, edit_account_form_id)
|
||||
if attached smarty_template_block (Current, "account_edit", a_auth_api.cms_api) as l_tpl_block then
|
||||
l_tpl_block.set_weight (-10)
|
||||
r.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
r.add_warning_message ("Error with block [resources_page]")
|
||||
end
|
||||
-- Build CMS form...
|
||||
end
|
||||
end
|
||||
create lnk.make ("View", "account/")
|
||||
lnk.set_weight (1)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
create lnk.make ("View", "account/")
|
||||
lnk.set_weight (1)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
|
||||
create lnk.make ("Edit", "account/edit")
|
||||
lnk.set_weight (2)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
create lnk.make ("Edit", "account/edit")
|
||||
lnk.set_weight (2)
|
||||
r.add_to_primary_tabs (lnk)
|
||||
|
||||
if
|
||||
r.has_permission ("change own username") and then
|
||||
attached new_change_username_form (r) as f
|
||||
then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if attached new_change_profile_name_form (r) as f then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if attached new_change_password_form (r) as f then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if attached new_change_email_form (r) as f then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if
|
||||
r.has_permission ("change own username") and then
|
||||
attached new_change_username_form (r) as f
|
||||
then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if attached new_change_profile_name_form (r) as f then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
|
||||
r.set_main_content (b)
|
||||
if
|
||||
r.has_permission ("change own password") and then
|
||||
attached new_change_password_form (r) as f
|
||||
then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
if attached new_change_email_form (r) as f then
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
|
||||
if l_user = Void then
|
||||
r.set_redirection ("account")
|
||||
l_form.append_to_html (r.wsf_theme, b)
|
||||
|
||||
r.set_main_content (b)
|
||||
|
||||
if l_user = Void then
|
||||
r.set_redirection ("account")
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
a_auth_api.cms_api.response_api.send_access_denied ("Can not edit your acocunt", req, res)
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_login (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_login (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
if api.user_is_authenticated then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if a_auth_api.cms_api.user_is_authenticated then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
r.set_redirection ("account")
|
||||
r.execute
|
||||
elseif attached api.module_by_name ("session_auth") then
|
||||
elseif attached a_auth_api.cms_api.module_by_name ("session_auth") then
|
||||
-- FIXME: find better solution to support a default login system.
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if attached {WSF_STRING} req.item ("destination") as l_destination then
|
||||
r.set_redirection ("account/auth/roc-session-login?destination=" + l_destination.url_encoded_value)
|
||||
else
|
||||
@@ -314,9 +405,9 @@ feature -- Handler
|
||||
|
||||
r.execute
|
||||
|
||||
elseif attached api.module_by_name ("basic_auth") then
|
||||
elseif attached a_auth_api.cms_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)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if attached {WSF_STRING} req.item ("destination") as l_destination then
|
||||
r.set_redirection ("account/auth/roc-basic-login?destination=" + l_destination.url_encoded_value)
|
||||
else
|
||||
@@ -325,18 +416,18 @@ feature -- Handler
|
||||
|
||||
r.execute
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
handle_logout (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_logout (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
loc: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if attached {READABLE_STRING_8} api.execution_variable ("auth_strategy") as l_auth_strategy then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if attached auth_strategy (req) as l_auth_strategy then
|
||||
loc := l_auth_strategy
|
||||
else
|
||||
loc := ""
|
||||
@@ -349,8 +440,9 @@ feature -- Handler
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_register (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_register (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
f: CMS_FORM
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
u: CMS_TEMP_USER
|
||||
@@ -362,125 +454,94 @@ feature -- Handler
|
||||
l_captcha_passed: BOOLEAN
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if r.has_permission ("account register") then
|
||||
if req.is_post_request_method then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("name") as l_name and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("email") as p_email and then
|
||||
attached {WSF_STRING} req.form_parameter ("personal_information") as l_personal_information
|
||||
then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
l_user_api := api.user_api
|
||||
if attached l_user_api.user_by_name (l_name.value) or else attached l_user_api.temp_user_by_name (l_name.value) then
|
||||
-- Username already exist.
|
||||
r.set_value ("User name already exists!", "error_name")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_email (l_email) or else attached l_user_api.temp_user_by_email (l_email) then
|
||||
-- Email already exists.
|
||||
r.set_value ("An account is already associated with that email address!", "error_email")
|
||||
l_exist := True
|
||||
end
|
||||
if attached recaptcha_secret_key (api) as l_recaptcha_key then
|
||||
if attached {WSF_STRING} req.form_parameter ("g-recaptcha-response") as l_recaptcha_response and then is_captcha_verified (l_recaptcha_key, l_recaptcha_response.url_encoded_value) then
|
||||
l_captcha_passed := True
|
||||
else
|
||||
--| Bad or missing captcha
|
||||
l_captcha_passed := False
|
||||
end
|
||||
else
|
||||
--| reCaptcha is not setup, so no verification
|
||||
if
|
||||
a_auth_api.cms_api.has_permission ("account register") and then
|
||||
req.is_post_request_method
|
||||
then
|
||||
create f.make (req.percent_encoded_path_info, "roccms-user-register")
|
||||
f.extend_text_field ("name", Void)
|
||||
f.extend_password_field ("password", Void)
|
||||
f.extend_text_field ("email", Void)
|
||||
f.extend_text_field ("personal_information", Void)
|
||||
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
f.process (r)
|
||||
if
|
||||
attached f.last_data as fd and then not fd.has_error and then
|
||||
attached fd.string_item ("name") as l_name and then
|
||||
attached fd.string_item ("password") as l_password and then
|
||||
attached fd.string_item ("email") as s_email and then
|
||||
attached fd.string_item ("personal_information") as l_personal_information
|
||||
then
|
||||
if s_email.is_valid_as_string_8 then
|
||||
l_email := s_email.to_string_8
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached l_user_api.user_by_name (l_name) or else attached l_user_api.temp_user_by_name (l_name) 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) or else attached l_user_api.temp_user_by_email (l_email) then
|
||||
-- Email already exists.
|
||||
r.set_value ("An account is already associated with that email address!", "error_email")
|
||||
l_exist := True
|
||||
end
|
||||
if attached recaptcha_secret_key (a_auth_api.cms_api) as l_recaptcha_key then
|
||||
if attached {WSF_STRING} req.form_parameter ("g-recaptcha-response") as l_recaptcha_response and then is_captcha_verified (l_recaptcha_key, l_recaptcha_response.url_encoded_value) then
|
||||
l_captcha_passed := True
|
||||
end
|
||||
if not l_exist then
|
||||
-- New temp user
|
||||
create u.make (l_name.value)
|
||||
u.set_email (l_email)
|
||||
u.set_password (l_password.value)
|
||||
u.set_personal_information (l_personal_information.value)
|
||||
l_user_api.new_temp_user (u)
|
||||
|
||||
-- Create activation token
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, u.id)
|
||||
l_url_activate := req.absolute_script_url ("/account/activate/" + l_token)
|
||||
l_url_reject := req.absolute_script_url ("/account/reject/" + l_token)
|
||||
|
||||
-- Send Email to webmaster
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_register_email")
|
||||
es.send_account_evaluation (u, l_personal_information.value, l_url_activate, l_url_reject, req.absolute_script_url (""))
|
||||
|
||||
-- Send Email to user
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_email")
|
||||
es.send_contact_email (l_email, u, req.absolute_script_url (""))
|
||||
else
|
||||
r.set_value (l_name.value, "name")
|
||||
r.set_value (l_email, "email")
|
||||
r.set_value (l_personal_information.value, "personal_information")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
--| Bad or missing captcha
|
||||
l_captcha_passed := False
|
||||
end
|
||||
else
|
||||
r.set_value (l_name.value, "name")
|
||||
r.set_value (p_email.value, "email")
|
||||
r.set_value (l_personal_information.value, "personal_information")
|
||||
--| reCaptcha is not setup, so no verification
|
||||
l_captcha_passed := True
|
||||
end
|
||||
if l_captcha_passed and then not l_exist then
|
||||
-- New temp user
|
||||
create u.make (l_name)
|
||||
u.set_email (l_email)
|
||||
u.set_password (l_password)
|
||||
u.set_personal_information (l_personal_information)
|
||||
a_auth_api.register_user (u, l_email, l_personal_information)
|
||||
else
|
||||
r.set_value (l_name, "name")
|
||||
r.set_value (l_email, "email")
|
||||
r.set_value (l_personal_information, "personal_information")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
else
|
||||
api.response_api.send_bad_request ("There were issue with your application, invalid or missing values.", req, res)
|
||||
r.set_value (l_name, "name")
|
||||
r.set_value (l_email, "email")
|
||||
r.set_value (l_personal_information, "personal_information")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
a_auth_api.cms_api.response_api.send_bad_request ("There were issue with your application, invalid or missing values.", req, res)
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
api.response_api.send_permissions_access_denied ("You can also contact the webmaster to ask for an account.", Void, req, res)
|
||||
a_auth_api.cms_api.response_api.send_permissions_access_denied ("You can also contact the webmaster to ask for an account.", Void, req, res)
|
||||
end
|
||||
end
|
||||
|
||||
handle_activation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_activation (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
l_temp_id: INTEGER_64
|
||||
do
|
||||
if api.has_permission ("account activate") then
|
||||
l_user_api := api.user_api
|
||||
if a_auth_api.cms_api.has_permission ("account activate") then
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached {WSF_STRING} req.path_parameter ("token") as l_token then
|
||||
if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_temp_user then
|
||||
|
||||
-- TODO copy the personal information
|
||||
--! to CMS_USER_PROFILE and persist data
|
||||
--! check also CMS_USER.data_items
|
||||
|
||||
l_temp_id := l_temp_user.id
|
||||
|
||||
-- Valid user_id
|
||||
l_temp_user.set_id (0)
|
||||
l_temp_user.mark_active
|
||||
l_user_api.new_user_from_temp_user (l_temp_user)
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
a_auth_api.activate_user (l_temp_user, l_token.value)
|
||||
if
|
||||
not l_user_api.has_error and then
|
||||
not a_auth_api.has_error and then
|
||||
attached l_user_api.user_by_name (l_temp_user.name) as l_new_user
|
||||
then
|
||||
-- Delete temporal User
|
||||
l_temp_user.set_id (l_temp_id)
|
||||
l_user_api.delete_temp_user (l_temp_user)
|
||||
l_user_api.remove_activation (l_token.value)
|
||||
|
||||
r.set_main_content ("<p> The account <i>" + html_encoded (l_new_user.name) + "</i> has been activated</p>")
|
||||
-- Send Email
|
||||
if attached l_new_user.email as l_email then
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_activation_confirmation_email")
|
||||
es.send_contact_activation_confirmation_email (l_email, l_new_user, req.absolute_script_url (""))
|
||||
end
|
||||
r.set_main_content ("<p> The account <i>" + a_auth_api.cms_api.user_html_link (l_new_user) + "</i> has been activated</p>")
|
||||
else
|
||||
-- Failure!!!
|
||||
r.set_status_code ({HTTP_CONSTANTS}.internal_server_error)
|
||||
@@ -490,38 +551,37 @@ feature -- Handler
|
||||
end
|
||||
end
|
||||
else -- the token does not exist, or it was already used.
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
r.set_main_content ("<p>The token <i>" + l_token.value + "</i> is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "</p>")
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
create l_ir.make (req, res, api)
|
||||
l_ir.execute
|
||||
(create {INTERNAL_SERVER_ERROR_CMS_RESPONSE}.make (req, res, a_auth_api.cms_api)).execute
|
||||
end
|
||||
else
|
||||
api.response_api.send_access_denied (Void, req, res)
|
||||
a_auth_api.cms_api.response_api.send_access_denied (Void, req, res)
|
||||
end
|
||||
end
|
||||
|
||||
handle_reject (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_reject (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if r.has_permission ("account reject") then
|
||||
if attached {WSF_STRING} req.path_parameter ("token") as l_token then
|
||||
l_user_api := api.user_api
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached {CMS_TEMP_USER} l_user_api.temp_user_by_activation_token (l_token.value) as l_user then
|
||||
l_user_api.delete_temp_user (l_user)
|
||||
r.set_main_content ("<p> The temporal account for <i>" + html_encoded (l_user.name) + "</i> has been removed</p>")
|
||||
-- Send Email
|
||||
if attached l_user.email as l_email then
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (a_auth_api.cms_api))
|
||||
write_debug_log (generator + ".handle register: send_contact_activation_reject_email")
|
||||
es.send_contact_activation_reject_email (l_email, l_user, req.absolute_script_url (""))
|
||||
end
|
||||
@@ -532,15 +592,15 @@ feature -- Handler
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
create l_ir.make (req, res, api)
|
||||
create l_ir.make (req, res, a_auth_api.cms_api)
|
||||
l_ir.execute
|
||||
end
|
||||
else
|
||||
api.response_api.send_access_denied (Void, req, res)
|
||||
a_auth_api.cms_api.response_api.send_access_denied (Void, req, res)
|
||||
end
|
||||
end
|
||||
|
||||
handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_reactivation (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
@@ -550,26 +610,26 @@ feature -- Handler
|
||||
l_url_reject: STRING
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
if api.has_permission ("account reactivate") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if a_auth_api.cms_api.has_permission ("account reactivate") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if req.is_post_request_method then
|
||||
if attached {WSF_STRING} req.form_parameter ("email") as p_email then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
l_user_api := api.user_api
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached {CMS_TEMP_USER} l_user_api.temp_user_by_email (l_email) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
if l_user.is_active then
|
||||
r.set_value ("The asociated user to the given email " + l_email + " , is already active", "is_active")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
else
|
||||
l_token := new_token
|
||||
l_token := a_auth_api.new_token
|
||||
l_user_api.new_activation (l_token, l_user.id)
|
||||
l_url_activate := req.absolute_script_url ("/account/activate/" + l_token)
|
||||
l_url_reject := req.absolute_script_url ("/account/reject/" + l_token)
|
||||
-- Send Email to webmaster
|
||||
if attached l_user.personal_information as l_personal_information then
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (a_auth_api.cms_api))
|
||||
write_debug_log (generator + ".handle register: send_register_email")
|
||||
es.send_account_evaluation (l_user, l_personal_information, l_url_activate, l_url_reject, req.absolute_script_url (""))
|
||||
end
|
||||
@@ -588,11 +648,11 @@ feature -- Handler
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
api.response_api.send_access_denied (Void, req, res)
|
||||
a_auth_api.cms_api.response_api.send_access_denied (Void, req, res)
|
||||
end
|
||||
end
|
||||
|
||||
handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_new_password (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATION_EMAIL_SERVICE
|
||||
@@ -601,20 +661,20 @@ feature -- Handler
|
||||
l_url: STRING
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
if req.is_post_request_method then
|
||||
l_user_api := api.user_api
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached {WSF_STRING} req.form_parameter ("email") as p_email then
|
||||
if p_email.value.is_valid_as_string_8 then
|
||||
l_email := p_email.value.to_string_8
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_token := a_auth_api.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))
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (a_auth_api.cms_api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email, l_user, l_url, req.absolute_script_url (""))
|
||||
else
|
||||
@@ -633,12 +693,12 @@ feature -- Handler
|
||||
attached l_user.email as l_user_email
|
||||
then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_token := a_auth_api.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))
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (a_auth_api.cms_api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_user_email, l_user, l_url, req.absolute_script_url (""))
|
||||
else
|
||||
@@ -651,13 +711,13 @@ feature -- Handler
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_reset_password (a_auth_api: CMS_AUTHENTICATION_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
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if attached {WSF_STRING} req.query_parameter ("token") as l_token then
|
||||
r.set_value (l_token.value, "token")
|
||||
if l_user_api.user_by_password_token (l_token.value) = Void then
|
||||
@@ -685,7 +745,7 @@ feature -- Handler
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_change_field (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_change_field (a_auth_api: CMS_AUTHENTICATION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
@@ -698,9 +758,9 @@ feature -- Handler
|
||||
l_fieldname := p_field.url_encoded_value
|
||||
end
|
||||
if l_fieldname = Void then
|
||||
api.response_api.send_bad_request (Void, req, res)
|
||||
a_auth_api.cms_api.response_api.send_bad_request (Void, req, res)
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_auth_api.cms_api)
|
||||
|
||||
if r.is_authenticated then
|
||||
create lnk.make ("View", "account/")
|
||||
@@ -712,7 +772,7 @@ feature -- Handler
|
||||
r.add_to_primary_tabs (lnk)
|
||||
end
|
||||
|
||||
l_user_api := api.user_api
|
||||
l_user_api := a_auth_api.cms_api.user_api
|
||||
if req.is_post_request_method then
|
||||
if attached r.user as l_user then
|
||||
if l_fieldname.is_case_insensitive_equal ("password") then
|
||||
@@ -759,7 +819,7 @@ feature -- Handler
|
||||
not fd.has_error and then
|
||||
attached fd.string_item ("new_profile_name") as l_new_profile_name
|
||||
then
|
||||
check api.user_api.is_valid_profile_name (l_new_profile_name) end
|
||||
check a_auth_api.cms_api.user_api.is_valid_profile_name (l_new_profile_name) end
|
||||
l_user.set_profile_name (l_new_profile_name)
|
||||
l_user_api.update_user (l_user)
|
||||
r.add_success_message ("Profile name updated.")
|
||||
@@ -770,7 +830,7 @@ feature -- Handler
|
||||
r.set_main_content (f.to_html (r.wsf_theme))
|
||||
end
|
||||
elseif l_fieldname.is_case_insensitive_equal ("username") then
|
||||
if api.has_permission ("change own username") then
|
||||
if a_auth_api.cms_api.has_permission ("change own username") then
|
||||
f := new_change_username_form (r)
|
||||
f.process (r)
|
||||
if
|
||||
@@ -778,8 +838,8 @@ feature -- Handler
|
||||
not fd.has_error and then
|
||||
attached fd.string_item ("new_username") as l_new_username
|
||||
then
|
||||
check api.user_api.is_valid_username (l_new_username) end
|
||||
check api.user_api.user_by_name (l_new_username) = Void end
|
||||
check a_auth_api.cms_api.user_api.is_valid_username (l_new_username) end
|
||||
check a_auth_api.cms_api.user_api.user_by_name (l_new_username) = Void end
|
||||
|
||||
l_user_api.update_username (l_user, l_new_username)
|
||||
r.add_success_message ("Username updated.")
|
||||
@@ -805,7 +865,7 @@ feature -- Handler
|
||||
f := new_change_email_form (r)
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
elseif l_fieldname.is_case_insensitive_equal_general ("new_username") then
|
||||
if api.has_permission ("change own username") then
|
||||
if a_auth_api.cms_api.has_permission ("change own username") then
|
||||
f := new_change_username_form (r)
|
||||
f.append_to_html (r.wsf_theme, b)
|
||||
end
|
||||
@@ -944,30 +1004,6 @@ feature -- Handler
|
||||
fs.extend_html_text ("<button type=%"submit%">Confirm</button>")
|
||||
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} -- Block views
|
||||
|
||||
get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
|
||||
38
modules/auth/cms_authentication_module_webapi.e
Normal file
38
modules/auth/cms_authentication_module_webapi.e
Normal file
@@ -0,0 +1,38 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_MODULE_WEBAPI}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_MODULE_WEBAPI
|
||||
|
||||
inherit
|
||||
CMS_MODULE_WEBAPI [CMS_AUTHENTICATION_MODULE]
|
||||
redefine
|
||||
permissions
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Security
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force ("account register")
|
||||
end
|
||||
|
||||
feature {NONE} -- Router/administration
|
||||
|
||||
setup_webapi_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached module.auth_api as l_auth_api then
|
||||
a_router.handle ("/account/register", create {CMS_USER_REGISTER_WEBAPI_HANDLER}.make_with_auth_api (l_auth_api), a_router.methods_post)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
114
modules/auth/cms_user_register_webapi_handler.e
Normal file
114
modules/auth/cms_user_register_webapi_handler.e
Normal file
@@ -0,0 +1,114 @@
|
||||
note
|
||||
description: "Summary description for {CMS_USER_REGISTER_WEBAPI_HANDLER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_USER_REGISTER_WEBAPI_HANDLER
|
||||
|
||||
inherit
|
||||
CMS_WEBAPI_HANDLER
|
||||
|
||||
WSF_URI_HANDLER
|
||||
|
||||
create
|
||||
make_with_auth_api
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_auth_api (a_auth_api: CMS_AUTHENTICATION_API)
|
||||
do
|
||||
auth_api := a_auth_api
|
||||
make (a_auth_api.cms_api)
|
||||
end
|
||||
|
||||
auth_api: CMS_AUTHENTICATION_API
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute handler for `req' and respond in `res'.
|
||||
do
|
||||
if req.is_post_request_method then
|
||||
register_user (req, res)
|
||||
else
|
||||
new_bad_request_error_response (Void, req, res).execute
|
||||
end
|
||||
end
|
||||
|
||||
register_user (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
f: CMS_FORM
|
||||
rep: like new_response
|
||||
l_user_api: CMS_USER_API
|
||||
u: CMS_TEMP_USER
|
||||
l_exist: BOOLEAN
|
||||
|
||||
l_url_activate: STRING
|
||||
l_url_reject: STRING
|
||||
l_token: STRING
|
||||
l_captcha_passed: BOOLEAN
|
||||
l_email: READABLE_STRING_8
|
||||
do
|
||||
if
|
||||
api.has_permission ("account register") and then
|
||||
req.is_post_request_method
|
||||
then
|
||||
create f.make (req.percent_encoded_path_info, "roccms-user-register")
|
||||
f.extend_text_field ("name", Void)
|
||||
f.extend_password_field ("password", Void)
|
||||
f.extend_text_field ("email", Void)
|
||||
f.extend_text_field ("personal_information", Void)
|
||||
|
||||
rep := new_response (req, res)
|
||||
f.process (rep)
|
||||
if
|
||||
attached f.last_data as fd and then not fd.has_error and then
|
||||
attached fd.string_item ("name") as l_name and then
|
||||
attached fd.string_item ("password") as l_password and then
|
||||
attached fd.string_item ("email") as s_email and then
|
||||
attached fd.string_item ("personal_information") as l_personal_information
|
||||
then
|
||||
if s_email.is_valid_as_string_8 then
|
||||
l_email := s_email.to_string_8
|
||||
l_user_api := api.user_api
|
||||
if attached l_user_api.user_by_name (l_name) or else attached l_user_api.temp_user_by_name (l_name) then
|
||||
-- Username already exists.
|
||||
fd.report_invalid_field ("name", "User name already exists!")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_email (l_email) or else attached l_user_api.temp_user_by_email (l_email) then
|
||||
-- Email already exists.
|
||||
fd.report_invalid_field ("email", "An account is already associated with that email address!")
|
||||
l_exist := True
|
||||
end
|
||||
if fd.has_error or l_exist then
|
||||
rep := new_bad_request_error_response ("User name or email is already taken!", req, res)
|
||||
else
|
||||
-- New temp user
|
||||
create u.make (l_name)
|
||||
u.set_email (l_email)
|
||||
u.set_password (l_password)
|
||||
u.set_personal_information (l_personal_information)
|
||||
|
||||
auth_api.register_user (u, l_email, l_personal_information)
|
||||
-- Until it is activated, this is not a real user.
|
||||
-- add_user_links_to (u, rep)
|
||||
rep.add_string_field ("status", "succeed")
|
||||
rep.add_string_field ("information", "Waiting for activation")
|
||||
rep.add_self (req.percent_encoded_path_info)
|
||||
end
|
||||
else
|
||||
rep := new_access_denied_error_response ("Invalid email", req, res)
|
||||
end
|
||||
else
|
||||
rep := new_access_denied_error_response ("There were issue with your application, invalid or missing values.", req, res)
|
||||
end
|
||||
else
|
||||
rep := new_permissions_access_denied_error_response (<<"account register">>, "You can also contact the webmaster to ask for an account.", req, res)
|
||||
end
|
||||
rep.execute
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
@@ -3,12 +3,10 @@
|
||||
<target name="basic_auth">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -16,9 +16,13 @@ inherit
|
||||
redefine
|
||||
make,
|
||||
filters,
|
||||
setup_hooks
|
||||
setup_hooks,
|
||||
install,
|
||||
permissions
|
||||
end
|
||||
|
||||
CMS_WITH_WEBAPI
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
create
|
||||
@@ -33,11 +37,38 @@ feature {NONE} -- Initialization
|
||||
description := "Service to manage basic authentication"
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
install (a_api: CMS_API)
|
||||
do
|
||||
Precursor (a_api)
|
||||
if attached a_api.user_api.anonymous_user_role as ano then
|
||||
ano.add_permission (perm_use_basic_auth)
|
||||
a_api.user_api.save_user_role (ano)
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_EXECUTION} -- Administration
|
||||
|
||||
webapi: CMS_BASIC_AUTH_MODULE_WEBAPI
|
||||
do
|
||||
create Result.make (Current)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "basic_auth"
|
||||
|
||||
feature -- Access: auth strategy
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force (perm_use_basic_auth)
|
||||
end
|
||||
|
||||
perm_use_basic_auth: STRING = "use basic_auth"
|
||||
|
||||
feature -- Access: auth strategy
|
||||
|
||||
login_title: STRING = "Basic Auth"
|
||||
-- Module specific login title.
|
||||
@@ -62,7 +93,7 @@ feature -- Access: auth strategy
|
||||
feature {CMS_API} -- Access: API
|
||||
|
||||
oauth20_api: detachable CMS_AUTH_API_I
|
||||
-- <Precursor>
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access: filter
|
||||
|
||||
|
||||
36
modules/basic_auth/cms_basic_auth_module_webapi.e
Normal file
36
modules/basic_auth/cms_basic_auth_module_webapi.e
Normal file
@@ -0,0 +1,36 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BASIC_AUTH_MODULE_WEBAPI}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_BASIC_AUTH_MODULE_WEBAPI
|
||||
|
||||
inherit
|
||||
CMS_MODULE_WEBAPI [CMS_BASIC_AUTH_MODULE]
|
||||
redefine
|
||||
filters
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Router/administration
|
||||
|
||||
setup_webapi_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
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 (1)
|
||||
Result.extend (create {CMS_BASIC_WEBAPI_AUTH_FILTER}.make (a_api))
|
||||
end
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
@@ -9,7 +9,7 @@ class
|
||||
CMS_BASIC_AUTH_FILTER
|
||||
|
||||
inherit
|
||||
CMS_AUTH_FILTER_I
|
||||
CMS_AUTH_STRATEGY_FILTER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
@@ -35,15 +35,16 @@ feature -- Basic operations
|
||||
attached l_auth.password as l_auth_password
|
||||
then
|
||||
if
|
||||
api.user_api.is_valid_credential (l_auth_login, l_auth_password) and then
|
||||
attached api.user_api.user_by_name (l_auth_login) as l_user
|
||||
attached api.user_api.user_with_credential (l_auth_login, l_auth_password) as l_user
|
||||
then
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Maybe we need to store in the credentials in a shared context SECURITY_CONTEXT")
|
||||
-- req.set_execution_variable ("security_content", create SECURITY_CONTEXT.make (l_user))
|
||||
-- other authentication filters (OpenID, etc) should implement the same approach.
|
||||
if api.user_has_permission (l_user, {CMS_BASIC_AUTH_MODULE}.perm_use_basic_auth) then
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Maybe we need to store in the credentials in a shared context SECURITY_CONTEXT")
|
||||
-- req.set_execution_variable ("security_content", create SECURITY_CONTEXT.make (l_user))
|
||||
-- other authentication filters (OpenID, etc) should implement the same approach.
|
||||
end
|
||||
set_current_user (l_user)
|
||||
end
|
||||
set_current_user (l_user)
|
||||
else
|
||||
api.logger.put_error (generator + ".execute login_valid failed for: " + l_auth_login, Void)
|
||||
end
|
||||
|
||||
44
modules/basic_auth/filter/cms_basic_webapi_auth_filter.e
Normal file
44
modules/basic_auth/filter/cms_basic_webapi_auth_filter.e
Normal file
@@ -0,0 +1,44 @@
|
||||
note
|
||||
description: "Summary description for {CMS_BASIC_WEBAPI_AUTH_FILTER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_BASIC_WEBAPI_AUTH_FILTER
|
||||
|
||||
inherit
|
||||
CMS_WEBAPI_AUTH_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
local
|
||||
l_auth: HTTP_AUTHORIZATION
|
||||
do
|
||||
create l_auth.make (req.http_authorization)
|
||||
if
|
||||
l_auth.is_basic and then
|
||||
attached l_auth.login as l_auth_login and then
|
||||
attached l_auth.password as l_auth_password
|
||||
then
|
||||
if
|
||||
attached api.user_api.user_with_credential (l_auth_login, l_auth_password) as l_user
|
||||
then
|
||||
if api.user_has_permission (l_user, {CMS_BASIC_AUTH_MODULE}.perm_use_basic_auth) then
|
||||
api.set_user (l_user)
|
||||
end
|
||||
else
|
||||
-- not authenticated due to bad login or password.
|
||||
end
|
||||
end
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
end
|
||||
@@ -15,9 +15,6 @@ inherit
|
||||
new_mapping as new_uri_mapping
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
|
||||
WSF_RESOURCE_HANDLER_HELPER
|
||||
redefine
|
||||
do_get
|
||||
@@ -34,7 +31,6 @@ feature -- execute
|
||||
-- Execute request handler.
|
||||
do
|
||||
execute_methods (req, res)
|
||||
execute_next (req, res)
|
||||
end
|
||||
|
||||
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
|
||||
@@ -17,6 +17,8 @@ inherit
|
||||
blog_api
|
||||
end
|
||||
|
||||
CMS_WITH_MODULE_ADMINISTRATION
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_RESPONSE_ALTER
|
||||
@@ -81,13 +83,21 @@ feature {CMS_API} -- Module management
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
feature {CMS_API, CMS_MODULE} -- Access: API
|
||||
|
||||
blog_api: detachable CMS_BLOG_API
|
||||
-- <Precursor>
|
||||
|
||||
node_api: detachable CMS_NODE_API
|
||||
|
||||
feature {NONE} -- Administration
|
||||
|
||||
administration: CMS_SELF_MODULE_ADMINISTRATION [CMS_BLOG_MODULE]
|
||||
-- Administration module.
|
||||
do
|
||||
create Result.make (Current)
|
||||
end
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
<target name="cms_blog_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<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" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_comments_module" location="..\..\modules\comments\comments.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_node_module" location="..\..\modules\node\node.ecf" readonly="false"/>
|
||||
<library name="cms_taxnomy_module" location="..\..\modules\taxonomy\taxonomy.ecf"/>
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
<target name="comments_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<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" location="..\..\cms.ecf" readonly="false"/>
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="contact" uuid="5F9BB4AA-FB62-4550-B314-DED374843DC0" library_target="contact">
|
||||
<target name="contact">
|
||||
<root all_classes="true"/>
|
||||
<option>
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
6
modules/core/site/scripts/user_profile.sql
Normal file
6
modules/core/site/scripts/user_profile.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
CREATE TABLE user_profiles(
|
||||
`uid` INTEGER NOT NULL CHECK("uid">=0),
|
||||
`key` VARCHAR(255) NOT NULL,
|
||||
`value` TEXT,
|
||||
CONSTRAINT PK_uid_key PRIMARY KEY (`uid`,`key`)
|
||||
);
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="custom_block_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf"/>
|
||||
|
||||
@@ -2,12 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="embedded_video" uuid="1469E34C-98EE-4E39-BC13-24A0D93A7EC0" library_target="embedded_video">
|
||||
<target name="embedded_video">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<capability>
|
||||
<concurrency support="scoop" use="scoop"/>
|
||||
<void_safety support="all"/>
|
||||
</capability>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
|
||||
|
||||
@@ -2,8 +2,8 @@ note
|
||||
description: "[
|
||||
Module that allows you to embed videos from YouTube and Vimeo in a web page.
|
||||
]"
|
||||
date: "$Date: 2015-07-16 15:57:08 +0200 (jeu., 16 juil. 2015) $"
|
||||
revision: "$Revision: 97722 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
EMBEDDED_VIDEO_MODULE
|
||||
|
||||
@@ -5,8 +5,8 @@ note
|
||||
Full syntax:
|
||||
[video:url width:X height:Y]
|
||||
]"
|
||||
date: "$Date: 2015-07-18 13:53:56 +0200 (sam., 18 juil. 2015) $"
|
||||
revision: "$Revision: 97737 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
VIDEO_CONTENT_FILTER
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
note
|
||||
description: "Summary description for {VIDEO_HTML_CONTENT_FORMAT}."
|
||||
author: ""
|
||||
date: "$Date: 2015-07-10 13:38:10 +0200 (ven., 10 juil. 2015) $"
|
||||
revision: "$Revision: 97687 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
VIDEO_HTML_CONTENT_FORMAT
|
||||
|
||||
@@ -3,8 +3,8 @@ note
|
||||
Eiffel tests that can be executed by testing tool.
|
||||
]"
|
||||
author: "EiffelStudio test wizard"
|
||||
date: "$Date: 2015-07-10 13:38:10 +0200 (ven., 10 juil. 2015) $"
|
||||
revision: "$Revision: 97687 $"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
testing: "type/manual"
|
||||
|
||||
class
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="embedded_video_testing" uuid="BD491995-C14C-4413-B09A-C1B4EDDA3116">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="embedded_video_testing" uuid="BD491995-C14C-4413-B09A-C1B4EDDA3116">
|
||||
<target name="embedded_video_testing">
|
||||
<root class="ANY" feature="default_create"/>
|
||||
<option warning="true" void_safety="all">
|
||||
</option>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.git$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="embedded_module" location="..\embedded_video-safe.ecf" readonly="false"/>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
|
||||
<capability>
|
||||
<concurrency support="none"/>
|
||||
</capability>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="embedded_module" location="..\embedded_video.ecf" readonly="false"/>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
|
||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
|
||||
<tests name="src" location=".\"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -52,14 +52,14 @@ feature -- Access
|
||||
feature -- Status report
|
||||
|
||||
has_category_filter: BOOLEAN
|
||||
-- Is there any category filtering?
|
||||
-- Is there any global category filtering?
|
||||
-- i.e via `included_categories'
|
||||
do
|
||||
Result := attached included_categories as cats and then not cats.is_empty
|
||||
end
|
||||
|
||||
has_category_filter_for_location (a_location: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is there any category filtering for `a_location'?
|
||||
-- Is there any specific category filtering for `a_location'?
|
||||
do
|
||||
Result := attached included_categories_per_feed as cats_per_location and then
|
||||
attached cats_per_location.item (a_location) as cats and then
|
||||
@@ -118,7 +118,7 @@ feature -- Element change
|
||||
end
|
||||
end
|
||||
|
||||
include_category_per_feed (a_cat: READABLE_STRING_GENERAL; a_feed_location: READABLE_STRING_8)
|
||||
include_category_per_feed (a_cat: READABLE_STRING_GENERAL; a_feed_location: READABLE_STRING_GENERAL)
|
||||
local
|
||||
tb: like included_categories_per_feed
|
||||
lst: like included_categories
|
||||
@@ -163,20 +163,22 @@ feature -- Status report
|
||||
|
||||
is_included_for_location (e: FEED_ITEM; a_location: READABLE_STRING_GENERAL): BOOLEAN
|
||||
-- Is `e' included in feed related to `a_location'?
|
||||
-- note that if `e' has no category, it is included by default,
|
||||
-- even if `included_categories_per_feed' is defined for `a_location'.
|
||||
-- notes:
|
||||
-- - it also check for `included_categories' condition.
|
||||
-- - if `e' has no category, it is included by default,
|
||||
-- even if `included_categories_per_feed' is defined for `a_location'.
|
||||
do
|
||||
Result := True
|
||||
if attached e.categories as e_cats then
|
||||
Result := is_included (e)
|
||||
if Result and attached e.categories as e_cats then
|
||||
if
|
||||
attached included_categories_per_feed as tb and then
|
||||
attached tb.item (a_location) as lst
|
||||
then
|
||||
Result := across lst as ic some
|
||||
across e_cats as e_ic some
|
||||
e_ic.item.same_string (ic.item)
|
||||
across e_cats as e_ic some
|
||||
e_ic.item.same_string (ic.item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="feed_aggregator" uuid="6A78AB37-9B07-4C42-9E24-0CA7D3C61E12" library_target="feed_aggregator">
|
||||
<target name="feed_aggregator">
|
||||
<root all_classes="true"/>
|
||||
<option>
|
||||
</option>
|
||||
|
||||
<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" location="..\..\cms.ecf"/>
|
||||
|
||||
@@ -35,6 +35,8 @@ feature -- Access
|
||||
l_feed_id: READABLE_STRING_32
|
||||
l_title: detachable READABLE_STRING_GENERAL
|
||||
l_locations: detachable STRING_TABLE [READABLE_STRING_8]
|
||||
loc_name: READABLE_STRING_GENERAL
|
||||
loc: READABLE_STRING_8
|
||||
l_table: like internal_aggregations
|
||||
do
|
||||
l_table := internal_aggregations
|
||||
@@ -102,6 +104,19 @@ feature -- Access
|
||||
agg.include_category (cats_ic.item)
|
||||
end
|
||||
end
|
||||
across
|
||||
l_locations as locs_ic
|
||||
loop
|
||||
loc_name := locs_ic.key
|
||||
loc := locs_ic.item
|
||||
if attached cfg.text_list_item ({STRING_32} "feeds." + l_feed_id + {STRING_32} ".categories." + loc_name.as_string_32) as l_loc_cats then
|
||||
across
|
||||
l_loc_cats as cats_ic
|
||||
loop
|
||||
agg.include_category_per_feed (cats_ic.item, loc)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -138,11 +153,42 @@ feature -- Operation
|
||||
|
||||
aggregation_feed (agg: FEED_AGGREGATION): detachable FEED
|
||||
-- Feed from aggregation `agg'.
|
||||
local
|
||||
loc: READABLE_STRING_8
|
||||
lst: LIST [FEED_ITEM]
|
||||
do
|
||||
across
|
||||
agg.locations as ic
|
||||
loop
|
||||
if attached feed (ic.item) as f then
|
||||
loc := ic.item
|
||||
if attached feed (loc) as f then
|
||||
lst := f.items
|
||||
if agg.has_category_filter_for_location (loc) then
|
||||
-- Note: it also check the global filter.
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
if agg.is_included_for_location (lst.item, loc) then
|
||||
lst.forth
|
||||
else
|
||||
lst.remove
|
||||
end
|
||||
end
|
||||
elseif agg.has_category_filter then
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
if agg.is_included (lst.item) then
|
||||
lst.forth
|
||||
else
|
||||
lst.remove
|
||||
end
|
||||
end
|
||||
end
|
||||
if Result /= Void then
|
||||
if f /= Void then
|
||||
Result := Result + f
|
||||
@@ -152,6 +198,9 @@ feature -- Operation
|
||||
end
|
||||
end
|
||||
end
|
||||
if Result /= Void then
|
||||
Result.set_date (create {DATE_TIME}.make_now_utc)
|
||||
end
|
||||
end
|
||||
|
||||
new_http_client_session (a_url: READABLE_STRING_8): HTTP_CLIENT_SESSION
|
||||
|
||||
@@ -57,7 +57,7 @@ feature {CMS_API} -- Module Initialization
|
||||
create feed_aggregator_api.make (api)
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
feature {CMS_API, CMS_MODULE} -- Access: API
|
||||
|
||||
feed_aggregator_api: detachable FEED_AGGREGATOR_API
|
||||
-- Eventual module api.
|
||||
@@ -90,16 +90,33 @@ feature -- Handle
|
||||
end
|
||||
if attached {WSF_STRING} req.path_parameter ("feed_id") as p_feed_id then
|
||||
if attached feed_aggregation (p_feed_id.value) as l_agg then
|
||||
if attached {WSF_STRING} req.query_parameter ("view") as p_view and then p_view.same_string ("embedded") then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_api)
|
||||
if attached feed_to_html (p_feed_id.value, nb, True, r) as l_html then
|
||||
r := Void
|
||||
if
|
||||
attached {WSF_STRING} req.query_parameter ("view") as p_view and then
|
||||
p_view.same_string ("embedded")
|
||||
then
|
||||
if attached feed_to_html (p_feed_id.value, nb, True, create {GENERIC_VIEW_CMS_RESPONSE}.make (req, res, a_api)) as l_html then
|
||||
create m.make_with_body (l_html)
|
||||
m.header.put_content_type_text_html
|
||||
res.send (m)
|
||||
else
|
||||
a_api.response_api.send_not_found (Void, req, res)
|
||||
end
|
||||
elseif
|
||||
attached {WSF_STRING} req.query_parameter ("view") as p_view and then
|
||||
(p_view.same_string ("feed") or p_view.same_string ("feed.atom")) and then
|
||||
attached feed_to_atom (p_feed_id.value, nb) as l_feed_content
|
||||
then
|
||||
create m.make_with_body (l_feed_content)
|
||||
m.header.put_content_type ("application/atom+xml")
|
||||
res.send (m)
|
||||
elseif
|
||||
attached {WSF_STRING} req.query_parameter ("view") as p_view and then
|
||||
(p_view.same_string ("feed.rss")) and then
|
||||
attached feed_to_rss (p_feed_id.value, nb) as l_feed_content
|
||||
then
|
||||
create m.make_with_body (l_feed_content)
|
||||
m.header.put_content_type ("application/rss+xml")
|
||||
res.send (m)
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, a_api)
|
||||
create s.make_empty
|
||||
@@ -130,13 +147,29 @@ feature -- Handle
|
||||
s.append (ic.item)
|
||||
s.append ("%">")
|
||||
s.append (ic.item)
|
||||
s.append ("</a></li>")
|
||||
s.append ("</a>")
|
||||
if
|
||||
attached l_agg.included_categories_per_feed as tb and then
|
||||
attached tb.item (ic.item) as l_cats
|
||||
then
|
||||
s.append ("<span class=%"category%">")
|
||||
across
|
||||
l_cats as cats_ic
|
||||
loop
|
||||
s.append (" [")
|
||||
s.append (r.html_encoded (cats_ic.item))
|
||||
s.append ("]")
|
||||
end
|
||||
s.append ("</span>")
|
||||
end
|
||||
s.append ("</li>")
|
||||
end
|
||||
s.append ("</ul>")
|
||||
|
||||
if attached feed_to_html (p_feed_id.value, nb, True, r) as l_html then
|
||||
s.append (l_html)
|
||||
end
|
||||
append_bottom_feed_links_to (s, p_feed_id.value, r)
|
||||
|
||||
r.set_main_content (s)
|
||||
r.execute
|
||||
@@ -252,6 +285,70 @@ feature -- Hook
|
||||
end
|
||||
end
|
||||
|
||||
to_adapted_feed (a_feed_api: FEED_AGGREGATOR_API; a_feed_agg: FEED_AGGREGATION; a_count: INTEGER): detachable FEED
|
||||
-- Feed aggregation `a_feed_agg` adapted according to filter and `a_count`.
|
||||
local
|
||||
nb: INTEGER
|
||||
do
|
||||
if a_count = 0 then
|
||||
nb := a_feed_agg.size
|
||||
else
|
||||
nb := a_count
|
||||
end
|
||||
if attached a_feed_api.aggregation_feed (a_feed_agg) as l_feed then
|
||||
if attached l_feed.items as lst then
|
||||
if a_feed_agg.has_category_filter then
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
if nb = 0 then
|
||||
lst.remove
|
||||
elseif a_feed_agg.is_included (lst.item_for_iteration) then
|
||||
nb := nb - 1
|
||||
lst.forth
|
||||
elseif a_feed_agg.is_included_for_location (lst.item_For_iteration, "") then
|
||||
|
||||
else
|
||||
lst.remove
|
||||
end
|
||||
end
|
||||
elseif nb > 0 then
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
if nb = 0 then
|
||||
lst.remove
|
||||
else
|
||||
nb := nb - 1
|
||||
lst.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Result := l_feed
|
||||
end
|
||||
end
|
||||
|
||||
append_bottom_feed_links_to (s: STRING; a_feed_id: READABLE_STRING_GENERAL; a_response: CMS_RESPONSE)
|
||||
do
|
||||
s.append_string ("<ul class=%"nav%">")
|
||||
s.append_string ("<li>")
|
||||
s.append_string (a_response.link ("Embedded", "feed_aggregation/" + a_response.url_encoded (a_feed_id) + "?view=embedded", Void))
|
||||
s.append_string ("</li>")
|
||||
s.append_string ("<li>")
|
||||
s.append_string (a_response.link ("ATOM", "feed_aggregation/" + a_response.url_encoded (a_feed_id) + "?view=feed.atom", Void))
|
||||
s.append_string ("</li>")
|
||||
s.append_string ("<li>")
|
||||
s.append_string (a_response.link ("RSS", "feed_aggregation/" + a_response.url_encoded (a_feed_id) + "?view=feed.rss", Void))
|
||||
s.append_string ("</li>")
|
||||
s.append_string ("</ul>")
|
||||
end
|
||||
|
||||
feed_to_html (a_feed_id: READABLE_STRING_GENERAL; a_count: INTEGER; with_feed_info: BOOLEAN; a_response: CMS_RESPONSE): detachable STRING
|
||||
local
|
||||
nb: INTEGER
|
||||
@@ -262,18 +359,21 @@ feature -- Hook
|
||||
vis: FEED_TO_XHTML_VISITOR
|
||||
s: STRING
|
||||
do
|
||||
if attached feed_aggregator_api as l_feed_api then
|
||||
if attached l_feed_api.aggregation (a_feed_id) as l_agg then
|
||||
create l_cache.make (l_feed_api.cms_api.cache_location.extended (name).extended ("feed__" + a_feed_id + "__" + a_count.out + "_" + with_feed_info.out))
|
||||
Result := l_cache.item
|
||||
if Result = Void or l_cache.expired (Void, l_agg.expiration) then
|
||||
|
||||
if
|
||||
attached feed_aggregator_api as l_feed_api and then
|
||||
attached l_feed_api.aggregation (a_feed_id) as l_agg
|
||||
then
|
||||
create l_cache.make (l_feed_api.cms_api.cache_location.extended (name).extended ("feed__" + a_feed_id + "__" + a_count.out + "_" + with_feed_info.out))
|
||||
Result := l_cache.item
|
||||
if Result = Void or l_cache.expired (Void, l_agg.expiration) then
|
||||
if attached to_adapted_feed (l_feed_api, l_agg, a_count) as l_feed then
|
||||
create Result.make (1024)
|
||||
Result.append ("<!-- ")
|
||||
Result.append ("Updated: " + l_cache.cache_date_time.out)
|
||||
Result.append (" -->")
|
||||
|
||||
create vis.make (Result)
|
||||
|
||||
if a_count = 0 then
|
||||
nb := l_agg.size
|
||||
else
|
||||
@@ -292,29 +392,72 @@ feature -- Hook
|
||||
vis.set_header (s)
|
||||
end
|
||||
create s.make_empty
|
||||
s.append_string ("<liv class=%"nav%">")
|
||||
s.append ("<li>")
|
||||
s.append_string (a_response.link ("See more ...", "feed_aggregation/" + a_response.url_encoded (a_feed_id), Void))
|
||||
s.append_string ("</li>")
|
||||
s.append ("</li>")
|
||||
vis.set_footer (s)
|
||||
|
||||
if attached l_feed_api.aggregation_feed (l_agg) as l_feed then
|
||||
if l_agg.has_category_filter and attached l_feed.items as lst then
|
||||
from
|
||||
lst.start
|
||||
until
|
||||
lst.after
|
||||
loop
|
||||
if not l_agg.is_included (lst.item_for_iteration) then
|
||||
lst.remove
|
||||
else
|
||||
lst.forth
|
||||
end
|
||||
end
|
||||
end
|
||||
l_feed.accept (vis)
|
||||
end
|
||||
l_feed.accept (vis)
|
||||
l_cache.put (Result)
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feed_to_atom (a_feed_id: READABLE_STRING_GENERAL; a_count: INTEGER): detachable STRING
|
||||
local
|
||||
nb: INTEGER
|
||||
i: INTEGER
|
||||
e: FEED_ITEM
|
||||
vis: ATOM_FEED_GENERATOR
|
||||
s: STRING
|
||||
l_cache: CMS_FILE_STRING_8_CACHE
|
||||
do
|
||||
if
|
||||
attached feed_aggregator_api as l_feed_api and then
|
||||
attached l_feed_api.aggregation (a_feed_id) as l_agg
|
||||
then
|
||||
create l_cache.make (l_feed_api.cms_api.cache_location.extended (name).extended ("feed__" + a_feed_id + "__" + a_count.out + ".atom"))
|
||||
Result := l_cache.item
|
||||
if Result = Void or l_cache.expired (Void, l_agg.expiration) then
|
||||
if attached to_adapted_feed (l_feed_api, l_agg, a_count) as l_feed then
|
||||
create Result.make (1024)
|
||||
create vis.make (Result)
|
||||
l_feed.accept (vis)
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feed_to_rss (a_feed_id: READABLE_STRING_GENERAL; a_count: INTEGER): detachable STRING
|
||||
local
|
||||
vis: RSS_2_FEED_GENERATOR
|
||||
l_cache: CMS_FILE_STRING_8_CACHE
|
||||
do
|
||||
if
|
||||
attached feed_aggregator_api as l_feed_api and then
|
||||
attached l_feed_api.aggregation (a_feed_id) as l_agg
|
||||
then
|
||||
create l_cache.make (l_feed_api.cms_api.cache_location.extended (name).extended ("feed__" + a_feed_id + "__" + a_count.out + ".rss"))
|
||||
Result := l_cache.item
|
||||
if Result = Void or l_cache.expired (Void, l_agg.expiration) then
|
||||
if attached to_adapted_feed (l_feed_api, l_agg, a_count) as l_feed then
|
||||
create Result.make (1024)
|
||||
create vis.make (Result)
|
||||
l_feed.accept (vis)
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
elseif l_cache /= Void then
|
||||
l_cache.delete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
div.feed ul.nav {
|
||||
list-style: none;
|
||||
}
|
||||
div.feed ul.nav li {
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
}
|
||||
div.feed ul {
|
||||
list-style: none;
|
||||
position: relative;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
div.feed {
|
||||
ul.nav {
|
||||
list-style: none;
|
||||
li {
|
||||
display: inline-block;
|
||||
padding-right: 1em;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
list-style: none;
|
||||
position: relative;
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
<target name="files_module">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf"/>
|
||||
|
||||
1
modules/files/site/files/js/basic.css
Normal file
1
modules/files/site/files/js/basic.css
Normal file
@@ -0,0 +1 @@
|
||||
.dropzone,.dropzone *{box-sizing:border-box}.dropzone{position:relative}.dropzone .dz-preview{position:relative;display:inline-block;width:120px;margin:0.5em}.dropzone .dz-preview .dz-progress{display:block;height:15px;border:1px solid #aaa}.dropzone .dz-preview .dz-progress .dz-upload{display:block;height:100%;width:0;background:green}.dropzone .dz-preview .dz-error-message{color:red;display:none}.dropzone .dz-preview.dz-error .dz-error-message,.dropzone .dz-preview.dz-error .dz-error-mark{display:block}.dropzone .dz-preview.dz-success .dz-success-mark{display:block}.dropzone .dz-preview .dz-error-mark,.dropzone .dz-preview .dz-success-mark{position:absolute;display:none;left:30px;top:30px;width:54px;height:58px;left:50%;margin-left:-27px}
|
||||
@@ -2,9 +2,6 @@
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="google_search" uuid="054E9C5C-ACCB-4A4D-B825-6C574AEC30A9" library_target="google_search">
|
||||
<target name="google_search">
|
||||
<root all_classes="true"/>
|
||||
<option>
|
||||
</option>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<root all_classes="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env.ecf" readonly="false"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
|
||||
@@ -161,7 +161,7 @@ feature -- Hooks
|
||||
if l_current_user.id = ic.item.id then
|
||||
else
|
||||
create f_user.make_with_value ("users[]", ic.item.id.out)
|
||||
l_name := api.user_api.user_display_name (ic.item)
|
||||
l_name := api.user_api.real_user_display_name (ic.item)
|
||||
if l_name.same_string (ic.item.name) then
|
||||
f_user.set_title (l_name)
|
||||
else
|
||||
@@ -227,10 +227,10 @@ $(document).ready(function() {
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.values.force ("messaging", "messaging")
|
||||
r.set_main_content (new_html_messaging_form (r, api))
|
||||
r.execute
|
||||
else
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make_with_permissions (req, res, api, <<"use messaging", "message any user">>)
|
||||
api.response_api.send_permissions_access_denied (Void, <<"use messaging", "message any user">>, req, res)
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_post_messaging (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
@@ -280,7 +280,7 @@ $(document).ready(function() {
|
||||
end
|
||||
s.append ("<li>")
|
||||
if l_user /= Void and then attached l_user.email as l_user_email then
|
||||
s.append (r.html_encoded (api.user_api.user_display_name (l_user)))
|
||||
s.append (r.html_encoded (api.user_api.real_user_display_name (l_user)))
|
||||
s.append (" <")
|
||||
s.append (r.html_encoded (l_user_email))
|
||||
s.append (">")
|
||||
@@ -313,10 +313,10 @@ $(document).ready(function() {
|
||||
end
|
||||
end
|
||||
r.set_main_content (s)
|
||||
r.execute
|
||||
else
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make_with_permissions (req, res, api, <<"message any user">>)
|
||||
api.response_api.send_permissions_access_denied (Void, <<"message any user">>, req, res)
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
feature {NONE} -- Helpers
|
||||
@@ -346,7 +346,7 @@ feature {NONE} -- Contact Message
|
||||
end
|
||||
if a_target_user /= Void then
|
||||
smt.set_value (a_target_user.name, "target_user_name")
|
||||
smt.set_value (api.user_api.user_display_name (a_target_user), "target_user_profile_name")
|
||||
smt.set_value (api.user_api.real_user_display_name (a_target_user), "target_user_profile_name")
|
||||
smt.set_value (a_target_user.id.out, "target_user_id")
|
||||
if attached a_target_user.email as l_email then
|
||||
smt.set_value (l_email, "target_user_email")
|
||||
|
||||
@@ -134,6 +134,8 @@ feature -- Access
|
||||
l_type_name := ic.item.name
|
||||
if not l_type_name.is_whitespace then
|
||||
Result.force ("create " + l_type_name)
|
||||
Result.force ("delete " + l_type_name)
|
||||
Result.force ("trash " + l_type_name)
|
||||
|
||||
Result.force ("view any " + l_type_name)
|
||||
Result.force ("edit any " + l_type_name)
|
||||
@@ -312,6 +314,7 @@ feature -- Hooks
|
||||
if l_node_api.has_permission_for_action_on_node ("view", n, a_current_user) then
|
||||
n := l_node_api.full_node (n)
|
||||
create ch.make (n.content_type, create {CMS_LOCAL_LINK}.make (n.title, "node/" + n.id.out), n.modification_date)
|
||||
ch.set_id (n.content_type + ":id" + n.id.out + "-rev" + n.revision.out)
|
||||
if n.creation_date ~ n.modification_date then
|
||||
l_info := "new"
|
||||
if not n.is_published then
|
||||
@@ -328,7 +331,11 @@ feature -- Hooks
|
||||
end
|
||||
end
|
||||
ch.set_information (l_info)
|
||||
ch.set_author (n.editor)
|
||||
if n.editor = Void then
|
||||
ch.set_author (n.author)
|
||||
else
|
||||
ch.set_author (n.editor)
|
||||
end
|
||||
ch.set_summary (n.summary)
|
||||
if attached {CMS_TAXONOMY_API} l_node_api.cms_api.module_api ({CMS_TAXONOMY_MODULE}) as l_taxonomy_api then
|
||||
if attached l_taxonomy_api.terms_of_content (n, Void) as l_terms then
|
||||
|
||||
@@ -122,6 +122,9 @@ feature -- Forms ...
|
||||
l_uri := lnk.location
|
||||
if l_uri.same_string (node_api.node_path (a_node)) then
|
||||
l_uri := ""
|
||||
else
|
||||
l_iri := percent_encoder.percent_decoded_string (l_uri)
|
||||
l_uri := l_iri.to_string_8
|
||||
end
|
||||
else
|
||||
l_iri := percent_encoder.percent_decoded_string (response.api.location_alias (response.node_api.node_path (a_node)))
|
||||
|
||||
@@ -80,8 +80,13 @@ feature -- HTTP Methods
|
||||
lnk: FEED_LINK
|
||||
mesg: CMS_CUSTOM_RESPONSE_MESSAGE
|
||||
l_payload: STRING
|
||||
l_feed_name: STRING_32
|
||||
do
|
||||
create l_feed.make (a_content_type.name)
|
||||
create l_feed_name.make_from_string (api.setup.site_name)
|
||||
l_feed_name.append_string ({STRING_32} " : ")
|
||||
l_feed_name.append_string_general (a_content_type.name)
|
||||
create l_feed.make (l_feed_name)
|
||||
l_feed.set_id (api.absolute_url (req.path_info, Void))
|
||||
l_feed.set_date (create {DATE_TIME}.make_now_utc)
|
||||
|
||||
if attached {WSF_STRING} req.query_parameter ("size") as p_size and then p_size.is_integer then
|
||||
@@ -109,9 +114,10 @@ feature -- HTTP Methods
|
||||
if n.is_published then
|
||||
create l_feed_item.make (n.title)
|
||||
if attached n.author as u then
|
||||
l_feed_item.set_author (create {FEED_AUTHOR}.make (api.user_api.user_display_name (u)))
|
||||
l_feed_item.set_author (create {FEED_AUTHOR}.make (api.user_api.real_user_display_name (u)))
|
||||
end
|
||||
l_feed_item.set_date (n.publication_date)
|
||||
l_feed_item.set_id (n.content_type + ":id" + n.id.out + "-rev" + n.revision.out)
|
||||
create lnk.make (req.absolute_script_url ("/" + node_api.node_link (n).location))
|
||||
l_feed_item.links.force (lnk, "")
|
||||
if attached n.summary as l_summary and then not l_summary.is_whitespace then
|
||||
|
||||
@@ -3,16 +3,14 @@
|
||||
<target name="node">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/\.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\cms.ecf"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_comments_module" location="..\..\modules\comments\comments.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_recent_changes_module" location="..\..\modules\recent_changes\recent_changes.ecf" readonly="false"/>
|
||||
<library name="cms_sitemap_module" location="..\..\modules\sitemap\sitemap.ecf" readonly="false"/>
|
||||
<library name="cms_taxonomy_module" location="..\..\modules\taxonomy\taxonomy.ecf" readonly="false"/>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {NODE_MODULE}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
NODE_MODULE
|
||||
|
||||
obsolete "Use {CMS_NODE_MODULE}"
|
||||
|
||||
inherit
|
||||
CMS_NODE_MODULE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
end
|
||||
@@ -214,7 +214,7 @@ feature -- Access
|
||||
end
|
||||
|
||||
recent_node_changes_before (a_lower: INTEGER; a_count: INTEGER; a_date: DATE_TIME): LIST [CMS_NODE]
|
||||
-- List of recent changes, before `a_date', according to `params' settings.
|
||||
-- List of recent changes on published nodes, before `a_date', according to `params' settings.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
@@ -224,10 +224,11 @@ feature -- Access
|
||||
write_information_log (generator + ".recent_node_changes_before")
|
||||
|
||||
from
|
||||
create l_parameters.make (3)
|
||||
create l_parameters.make (4)
|
||||
l_parameters.put (a_count, "size")
|
||||
l_parameters.put (a_lower, "offset")
|
||||
l_parameters.put (a_date, "date")
|
||||
l_parameters.put ({CMS_NODE_API}.published, "status")
|
||||
|
||||
sql_query (sql_select_recent_node_changes_before, l_parameters)
|
||||
sql_start
|
||||
@@ -613,9 +614,9 @@ feature {NONE} -- Queries nodes
|
||||
end
|
||||
|
||||
sql_select_recent_node_changes_before: STRING
|
||||
--
|
||||
--published nodes before ':date'.
|
||||
once
|
||||
Result := sql_select_all_from_nodes + " WHERE changed <= :date ORDER BY changed DESC, nid DESC LIMIT :size OFFSET :offset ;"
|
||||
Result := sql_select_all_from_nodes + " WHERE changed <= :date AND status=:status ORDER BY changed DESC, nid DESC LIMIT :size OFFSET :offset ;"
|
||||
end
|
||||
|
||||
feature {NONE} -- Queries node revisions
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user