Merge branch 'master' of https://github.com/EiffelWebFramework/EWF
Conflicts: draft/application/cms/cms.ecf draft/application/cms/example/src/web_cms.e draft/application/cms/src/cms_configuration.e draft/application/cms/src/cms_default_setup.e draft/application/cms/src/cms_service.e draft/application/cms/src/cms_setup.e draft/application/cms/src/handler/cms_file_system_handler.e draft/application/cms/src/kernel/content/format/filters/cms_html_filter.e draft/application/cms/src/modules/debug/debug_module.e draft/application/cms/src/notification/cms_email.e draft/application/cms/src/notification/cms_storage_mailer.e draft/application/cms/src/storage/cms_sed_storage.e draft/application/cms/src/storage/cms_storage.e library/runtime/process/notification_email/notification_external_mailer.e tools/bin/ecf_updater.exe
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
<library name="wsf" location="..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_html" location="..\..\..\library\server\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_session" location="..\..\..\library\server\wsf\wsf_session-safe.ecf" readonly="false"/>
|
||||
<library name="notification_email" location="..\..\..\library\runtime\process\notification_email\notification_email-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
31
draft/application/cms/cms.ecf
Normal file
31
draft/application/cms/cms.ecf
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-10-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-10-0 http://www.eiffel.com/developers/xml/configuration-1-10-0.xsd" name="cms" library_target="cms" uuid="0D24AE3C-61DA-4E81-8DCF-90C2E65FB669">
|
||||
<target name="cms">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" syntax="transitional">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<setting name="exception_trace" value="true"/>
|
||||
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="encoder" location="..\..\..\library\text\encoder\encoder.ecf" readonly="false"/>
|
||||
<library name="wsf_html" location="..\..\..\library\server\wsf_html\wsf_html.ecf" readonly="false"/>
|
||||
<library name="http" location="..\..\..\library\network\protocol\http\http.ecf" readonly="false"/>
|
||||
<library name="openid" location="..\..\..\library\security\openid\consumer\openid.ecf" />
|
||||
<library name="process" location="$ISE_LIBRARY\library\process\process.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="uuid" location="$ISE_LIBRARY\library\uuid\uuid.ecf"/>
|
||||
<library name="uri_template" location="..\..\..\library\text\parser\uri_template\uri_template.ecf"/>
|
||||
<library name="wsf" location="..\..\..\library\server\wsf\wsf.ecf" readonly="false"/>
|
||||
<library name="wsf_session" location="..\..\..\library\server\wsf\wsf_session.ecf" readonly="false"/>
|
||||
<library name="notification_email" location="..\..\..\library\runtime\process\notification_email\notification_email.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true">
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
135
draft/application/cms/example/src/web_cms.e
Normal file
135
draft/application/cms/example/src/web_cms.e
Normal file
@@ -0,0 +1,135 @@
|
||||
note
|
||||
description: "[
|
||||
This class implements the Demo of WEB CMS service
|
||||
|
||||
]"
|
||||
|
||||
class
|
||||
WEB_CMS
|
||||
|
||||
inherit
|
||||
WSF_DEFAULT_SERVICE
|
||||
redefine
|
||||
initialize
|
||||
end
|
||||
|
||||
create
|
||||
make_and_launch
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
local
|
||||
args: ARGUMENTS_32
|
||||
cfg: detachable READABLE_STRING_32
|
||||
i,n: INTEGER
|
||||
do
|
||||
--| Arguments
|
||||
create args
|
||||
from
|
||||
i := 1
|
||||
n := args.argument_count
|
||||
until
|
||||
i > n or cfg /= Void
|
||||
loop
|
||||
if attached args.argument (i) as s then
|
||||
if s.same_string_general ("--config") or s.same_string_general ("-c") then
|
||||
if i < n then
|
||||
cfg := args.argument (i + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if cfg = Void then
|
||||
if file_exists ("cms.ini") then
|
||||
cfg := {STRING_32} "cms.ini"
|
||||
end
|
||||
end
|
||||
|
||||
--| EWF settings
|
||||
service_options := create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI}.make_from_file ("ewf.ini")
|
||||
Precursor
|
||||
|
||||
--| CMS initialization
|
||||
launch_cms (cms_setup (cfg))
|
||||
end
|
||||
|
||||
cms_setup (a_cfg_fn: detachable READABLE_STRING_GENERAL): CMS_CUSTOM_SETUP
|
||||
do
|
||||
if a_cfg_fn /= Void then
|
||||
create Result.make_from_file (a_cfg_fn)
|
||||
else
|
||||
create Result -- Default
|
||||
end
|
||||
setup_modules (Result)
|
||||
setup_storage (Result)
|
||||
end
|
||||
|
||||
launch_cms (a_setup: CMS_SETUP)
|
||||
local
|
||||
cms: CMS_SERVICE
|
||||
do
|
||||
create cms.make (a_setup)
|
||||
on_launched (cms)
|
||||
cms_service := cms
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
cms_service: CMS_SERVICE
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
cms_service.execute (req, res)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
setup_modules (a_setup: CMS_SETUP)
|
||||
local
|
||||
m: CMS_MODULE
|
||||
do
|
||||
create {DEMO_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.add_module (m)
|
||||
|
||||
create {SHUTDOWN_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.add_module (m)
|
||||
|
||||
create {DEBUG_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.add_module (m)
|
||||
|
||||
create {OPENID_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.add_module (m)
|
||||
end
|
||||
|
||||
setup_storage (a_setup: CMS_SETUP)
|
||||
do
|
||||
|
||||
end
|
||||
|
||||
feature -- Event
|
||||
|
||||
on_launched (cms: CMS_SERVICE)
|
||||
local
|
||||
e: CMS_EMAIL
|
||||
do
|
||||
create e.make (cms.site_email, cms.site_email, "[" + cms.site_name + "] launched...", "The site [" + cms.site_name + "] was launched at " + (create {DATE_TIME}.make_now_utc).out + " UTC.")
|
||||
cms.mailer.safe_process_email (e)
|
||||
end
|
||||
|
||||
feature -- Helper
|
||||
|
||||
file_exists (fn: READABLE_STRING_GENERAL): BOOLEAN
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
create f.make_with_name (fn)
|
||||
Result := f.exists and then f.is_readable
|
||||
end
|
||||
|
||||
end
|
||||
311
draft/application/cms/src/cms_configuration.e
Normal file
311
draft/application/cms/src/cms_configuration.e
Normal file
@@ -0,0 +1,311 @@
|
||||
note
|
||||
description: "Summary description for {CMS_CONFIGURATION}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_CONFIGURATION
|
||||
|
||||
inherit
|
||||
ANY
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make,
|
||||
make_from_file
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
create options.make_equal (10)
|
||||
analyze
|
||||
end
|
||||
|
||||
make_from_file (a_filename: READABLE_STRING_GENERAL)
|
||||
-- Initialize `Current'.
|
||||
local
|
||||
p: PATH
|
||||
do
|
||||
make
|
||||
create p.make_from_string (a_filename)
|
||||
configuration_location := p
|
||||
import_from_path (p)
|
||||
analyze
|
||||
end
|
||||
|
||||
analyze
|
||||
do
|
||||
get_root_location
|
||||
get_var_location
|
||||
get_themes_location
|
||||
get_files_location
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
configuration_location: detachable PATH
|
||||
|
||||
option (a_name: READABLE_STRING_GENERAL): detachable ANY
|
||||
do
|
||||
Result := options.item (a_name)
|
||||
end
|
||||
|
||||
options: STRING_TABLE [STRING_32]
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
append_to_string (s: STRING)
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
s.append ("Options:%N")
|
||||
across
|
||||
options as c
|
||||
loop
|
||||
s.append (c.key.to_string_8)
|
||||
s.append_character ('=')
|
||||
utf.string_32_into_utf_8_string_8 (c.item, s)
|
||||
s.append_character ('%N')
|
||||
end
|
||||
|
||||
s.append ("Specific:%N")
|
||||
s.append ("root_location=" + root_location.utf_8_name + "%N")
|
||||
s.append ("var_location=" + var_location.utf_8_name + "%N")
|
||||
s.append ("files_location=" + files_location.utf_8_name + "%N")
|
||||
s.append ("themes_location=" + themes_location.utf_8_name + "%N")
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_option (a_name: READABLE_STRING_GENERAL; a_value: STRING_32)
|
||||
do
|
||||
options.force (a_value, a_name.as_string_8)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
var_location: PATH
|
||||
|
||||
root_location: PATH
|
||||
|
||||
files_location: PATH
|
||||
|
||||
themes_location: PATH
|
||||
|
||||
theme_name (dft: detachable like theme_name): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("theme") as s then
|
||||
Result := s
|
||||
elseif dft /= Void then
|
||||
Result := dft
|
||||
else
|
||||
Result := "default"
|
||||
end
|
||||
end
|
||||
|
||||
site_id: READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.id") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := "_EWF_CMS_NO_ID_"
|
||||
end
|
||||
end
|
||||
|
||||
site_name (dft: like site_name): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.name") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
site_url (dft: like site_url): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.url") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
if Result /= Void then
|
||||
if Result.is_empty then
|
||||
-- ok
|
||||
elseif not Result.ends_with ("/") then
|
||||
Result := Result + "/"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
site_script_url (dft: like site_script_url): detachable READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.script_url") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
if Result /= Void then
|
||||
if Result.is_empty then
|
||||
elseif not Result.ends_with ("/") then
|
||||
Result := Result + "/"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
site_email (dft: like site_email): READABLE_STRING_8
|
||||
do
|
||||
if attached options.item ("site.email") as s then
|
||||
Result := s
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
get_var_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("var-dir") as s then
|
||||
create var_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
var_location := execution_environment.current_working_path
|
||||
end
|
||||
end
|
||||
|
||||
get_root_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("root-dir") as s then
|
||||
create root_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
root_location := execution_environment.current_working_path
|
||||
end
|
||||
end
|
||||
|
||||
get_files_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("files-dir") as s then
|
||||
create files_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
create files_location.make_from_string ("files")
|
||||
end
|
||||
end
|
||||
|
||||
get_themes_location
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached options.item ("themes-dir") as s then
|
||||
create themes_location.make_from_string (utf.utf_8_string_8_to_escaped_string_32 (s))
|
||||
else
|
||||
themes_location := root_location.extended ("themes")
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
import_from_file (fn: READABLE_STRING_GENERAL)
|
||||
do
|
||||
import_from_path (create {PATH}.make_from_string (fn))
|
||||
end
|
||||
|
||||
import_from_path (a_filename: PATH)
|
||||
-- Import ini file content
|
||||
local
|
||||
f: PLAIN_TEXT_FILE
|
||||
l,v: STRING_8
|
||||
p: INTEGER
|
||||
do
|
||||
create f.make_with_path (a_filename)
|
||||
if f.exists and f.is_readable then
|
||||
f.open_read
|
||||
from
|
||||
f.read_line
|
||||
until
|
||||
f.exhausted
|
||||
loop
|
||||
l := f.last_string
|
||||
l.left_adjust
|
||||
if not l.is_empty then
|
||||
if l[1] = '#' then
|
||||
-- commented line
|
||||
else
|
||||
p := l.index_of ('=', 1)
|
||||
if p > 1 then
|
||||
v := l.substring (p + 1, l.count)
|
||||
l.keep_head (p - 1)
|
||||
v.left_adjust
|
||||
v.right_adjust
|
||||
l.right_adjust
|
||||
|
||||
if l.is_case_insensitive_equal ("@include") then
|
||||
import_from_file (resolved_string (v))
|
||||
else
|
||||
set_option (l.as_lower, resolved_string (v))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
f.read_line
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Environment
|
||||
|
||||
resolved_string (s: READABLE_STRING_8): STRING_32
|
||||
-- Resolved `s' using `options' or else environment variables.
|
||||
local
|
||||
i,n,b,e: INTEGER
|
||||
k: detachable READABLE_STRING_8
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
n := s.count
|
||||
create Result.make (s.count)
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if i + 1 < n and then s[i] = '$' and then s[i+1] = '{' then
|
||||
b := i + 2
|
||||
e := s.index_of ('}', b) - 1
|
||||
if e > 0 then
|
||||
k := s.substring (b, e)
|
||||
if attached option (k) as v then
|
||||
if attached {READABLE_STRING_32} v as s32 then
|
||||
Result.append (s32)
|
||||
else
|
||||
Result.append (v.out)
|
||||
end
|
||||
i := e + 1
|
||||
elseif attached execution_environment.item (k) as v then
|
||||
Result.append (v)
|
||||
i := e + 1
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
else
|
||||
Result.extend (s[i])
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
132
draft/application/cms/src/cms_default_setup.e
Normal file
132
draft/application/cms/src/cms_default_setup.e
Normal file
@@ -0,0 +1,132 @@
|
||||
note
|
||||
description: "Summary description for {CMS_DEFAULT_SETUP}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_DEFAULT_SETUP
|
||||
|
||||
inherit
|
||||
CMS_SETUP
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
make,
|
||||
make_from_file
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_cfg: CMS_CONFIGURATION)
|
||||
do
|
||||
configuration := a_cfg
|
||||
default_create
|
||||
end
|
||||
|
||||
make_from_file (fn: READABLE_STRING_GENERAL)
|
||||
local
|
||||
cfg: CMS_CONFIGURATION
|
||||
do
|
||||
create cfg.make_from_file (fn)
|
||||
make (cfg)
|
||||
end
|
||||
|
||||
default_create
|
||||
do
|
||||
Precursor
|
||||
build_modules
|
||||
build_storage
|
||||
build_session_manager
|
||||
build_auth_engine
|
||||
build_mailer
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
modules: ARRAYED_LIST [CMS_MODULE]
|
||||
|
||||
storage: CMS_STORAGE
|
||||
-- CMS persistent layer
|
||||
|
||||
session_manager: WSF_SESSION_MANAGER
|
||||
-- CMS Session manager
|
||||
|
||||
auth_engine: CMS_AUTH_ENGINE
|
||||
-- CMS Authentication engine
|
||||
|
||||
mailer: NOTIFICATION_MAILER
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
build_modules
|
||||
local
|
||||
m: CMS_MODULE
|
||||
do
|
||||
create modules.make (3)
|
||||
|
||||
-- Core
|
||||
create {USER_MODULE} m.make
|
||||
m.enable
|
||||
modules.extend (m)
|
||||
|
||||
create {ADMIN_MODULE} m.make
|
||||
m.enable
|
||||
modules.extend (m)
|
||||
|
||||
create {NODE_MODULE} m.make
|
||||
m.enable
|
||||
modules.extend (m)
|
||||
end
|
||||
|
||||
build_storage
|
||||
local
|
||||
dn: PATH
|
||||
do
|
||||
if attached configuration as cfg and then attached cfg.var_location as l_site_var_dir then
|
||||
dn := l_site_var_dir
|
||||
else
|
||||
create dn.make_current
|
||||
end
|
||||
create {CMS_SED_STORAGE} storage.make (dn.extended ("_storage_").name)
|
||||
end
|
||||
|
||||
build_session_manager
|
||||
local
|
||||
dn: PATH
|
||||
do
|
||||
if attached configuration as cfg and then attached cfg.var_location as l_site_var_dir then
|
||||
dn := l_site_var_dir
|
||||
else
|
||||
create dn.make_empty
|
||||
end
|
||||
dn := dn.extended ("_storage_").extended ("_sessions_")
|
||||
create {WSF_FS_SESSION_MANAGER} session_manager.make_with_folder (dn.name)
|
||||
end
|
||||
|
||||
build_auth_engine
|
||||
do
|
||||
create {CMS_STORAGE_AUTH_ENGINE} auth_engine.make (storage)
|
||||
end
|
||||
|
||||
build_mailer
|
||||
local
|
||||
ch_mailer: NOTIFICATION_CHAIN_MAILER
|
||||
st_mailer: CMS_STORAGE_MAILER
|
||||
do
|
||||
create st_mailer.make (storage)
|
||||
create ch_mailer.make (st_mailer)
|
||||
ch_mailer.set_next (create {NOTIFICATION_SENDMAIL_MAILER})
|
||||
mailer := ch_mailer
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
add_module (m: CMS_MODULE)
|
||||
do
|
||||
modules.force (m)
|
||||
end
|
||||
|
||||
end
|
||||
442
draft/application/cms/src/cms_service.e
Normal file
442
draft/application/cms/src/cms_service.e
Normal file
@@ -0,0 +1,442 @@
|
||||
note
|
||||
description: "[
|
||||
This class implements the CMS service
|
||||
|
||||
It could be used to implement the main EWF service, or
|
||||
even for a specific handler.
|
||||
]"
|
||||
|
||||
class
|
||||
CMS_SERVICE
|
||||
|
||||
inherit
|
||||
WSF_SERVICE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_setup: CMS_SETUP)
|
||||
local
|
||||
cfg: detachable CMS_CONFIGURATION
|
||||
do
|
||||
cfg := a_setup.configuration
|
||||
if cfg = Void then
|
||||
create cfg.make
|
||||
end
|
||||
|
||||
configuration := cfg
|
||||
base_url := a_setup.base_url
|
||||
|
||||
site_id := cfg.site_id
|
||||
site_url := cfg.site_url ("")
|
||||
site_name := cfg.site_name ("EWF::CMS")
|
||||
site_email := cfg.site_email ("webmaster")
|
||||
site_dir := cfg.root_location
|
||||
site_var_dir := cfg.var_location
|
||||
files_location := cfg.files_location
|
||||
themes_location := cfg.themes_location
|
||||
theme_name := cfg.theme_name ("default")
|
||||
|
||||
set_script_url (cfg.site_script_url (Void)) -- Temporary value
|
||||
|
||||
compute_theme_resource_location
|
||||
|
||||
create content_types.make (3)
|
||||
|
||||
modules := a_setup.modules
|
||||
storage := a_setup.storage
|
||||
session_manager := a_setup.session_manager
|
||||
auth_engine := a_setup.auth_engine
|
||||
mailer := a_setup.mailer
|
||||
|
||||
initialize_storage
|
||||
initialize_auth_engine
|
||||
initialize_session_manager
|
||||
initialize_mailer
|
||||
initialize_router
|
||||
initialize_modules
|
||||
end
|
||||
|
||||
initialize_session_manager
|
||||
-- local
|
||||
-- dn: DIRECTORY_NAME
|
||||
do
|
||||
-- create dn.make_from_string (site_var_dir)
|
||||
-- dn.extend ("_storage_")
|
||||
-- dn.extend ("_sessions_")
|
||||
-- create {WSF_FS_SESSION_MANAGER} session_manager.make_with_folder (dn.string)
|
||||
end
|
||||
|
||||
initialize_storage
|
||||
do
|
||||
if not storage.has_user then
|
||||
initialize_users
|
||||
end
|
||||
end
|
||||
|
||||
initialize_users
|
||||
require
|
||||
has_no_user: not storage.has_user
|
||||
local
|
||||
u: CMS_USER
|
||||
ur: CMS_USER_ROLE
|
||||
do
|
||||
create u.make_new ("admin")
|
||||
u.set_password ("istrator")
|
||||
storage.save_user (u)
|
||||
|
||||
create ur.make_with_id (1, "anonymous")
|
||||
storage.save_user_role (ur)
|
||||
create ur.make_with_id (2, "authenticated")
|
||||
ur.add_permission ("create page")
|
||||
ur.add_permission ("edit page")
|
||||
storage.save_user_role (ur)
|
||||
end
|
||||
|
||||
initialize_mailer
|
||||
local
|
||||
-- ch_mailer: CMS_CHAIN_MAILER
|
||||
-- st_mailer: CMS_STORAGE_MAILER
|
||||
do
|
||||
-- create st_mailer.make (storage)
|
||||
-- create ch_mailer.make (st_mailer)
|
||||
-- ch_mailer.set_next (create {CMS_SENDMAIL_MAILER})
|
||||
-- mailer := ch_mailer
|
||||
end
|
||||
|
||||
initialize_router
|
||||
local
|
||||
-- h: CMS_HANDLER
|
||||
file_hdl: CMS_FILE_SYSTEM_HANDLER
|
||||
do
|
||||
create router.make (10)
|
||||
router.set_base_url (base_url)
|
||||
|
||||
router.map (create {WSF_URI_MAPPING}.make ("/", create {CMS_HANDLER}.make (agent handle_home)))
|
||||
router.map (create {WSF_URI_MAPPING}.make ("/favicon.ico", create {CMS_HANDLER}.make (agent handle_favicon)))
|
||||
|
||||
create file_hdl.make_with_path (files_location)
|
||||
file_hdl.disable_index
|
||||
file_hdl.set_max_age (8*60*60)
|
||||
router.map (create {WSF_STARTS_WITH_MAPPING}.make ("/files/", file_hdl))
|
||||
|
||||
create file_hdl.make_with_path (theme_resource_location)
|
||||
file_hdl.set_max_age (8*60*60)
|
||||
router.map (create {WSF_STARTS_WITH_MAPPING}.make ("/theme/", file_hdl))
|
||||
end
|
||||
|
||||
initialize_modules
|
||||
do
|
||||
across
|
||||
modules as m
|
||||
loop
|
||||
if m.item.is_enabled then
|
||||
m.item.register (Current)
|
||||
if attached {CMS_HOOK_AUTO_REGISTER} m.item as h_auto then
|
||||
h_auto.hook_auto_register (Current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initialize_auth_engine
|
||||
do
|
||||
-- create {CMS_STORAGE_AUTH_ENGINE} auth_engine.make (storage)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
configuration: CMS_CONFIGURATION
|
||||
|
||||
auth_engine: CMS_AUTH_ENGINE
|
||||
|
||||
modules: LIST [CMS_MODULE]
|
||||
|
||||
feature -- Hook: menu_alter
|
||||
|
||||
add_menu_alter_hook (h: like menu_alter_hooks.item)
|
||||
local
|
||||
lst: like menu_alter_hooks
|
||||
do
|
||||
lst := menu_alter_hooks
|
||||
if lst = Void then
|
||||
create lst.make (1)
|
||||
menu_alter_hooks := lst
|
||||
end
|
||||
if not lst.has (h) then
|
||||
lst.force (h)
|
||||
end
|
||||
end
|
||||
|
||||
menu_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_MENU_ALTER]
|
||||
|
||||
call_menu_alter_hooks (m: CMS_MENU_SYSTEM; a_execution: CMS_EXECUTION)
|
||||
do
|
||||
if attached menu_alter_hooks as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
c.item.menu_alter (m, a_execution)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: form_alter
|
||||
|
||||
add_form_alter_hook (h: like form_alter_hooks.item)
|
||||
local
|
||||
lst: like form_alter_hooks
|
||||
do
|
||||
lst := form_alter_hooks
|
||||
if lst = Void then
|
||||
create lst.make (1)
|
||||
form_alter_hooks := lst
|
||||
end
|
||||
if not lst.has (h) then
|
||||
lst.force (h)
|
||||
end
|
||||
end
|
||||
|
||||
form_alter_hooks: detachable ARRAYED_LIST [CMS_HOOK_FORM_ALTER]
|
||||
|
||||
call_form_alter_hooks (f: CMS_FORM; a_form_data: detachable WSF_FORM_DATA; a_execution: CMS_EXECUTION)
|
||||
do
|
||||
if attached form_alter_hooks as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
c.item.form_alter (f, a_form_data, a_execution)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Hook: block
|
||||
|
||||
add_block_hook (h: like block_hooks.item)
|
||||
local
|
||||
lst: like block_hooks
|
||||
do
|
||||
lst := block_hooks
|
||||
if lst = Void then
|
||||
create lst.make (1)
|
||||
block_hooks := lst
|
||||
end
|
||||
if not lst.has (h) then
|
||||
lst.force (h)
|
||||
end
|
||||
end
|
||||
|
||||
block_hooks: detachable ARRAYED_LIST [CMS_HOOK_BLOCK]
|
||||
|
||||
hook_block_view (a_execution: CMS_EXECUTION)
|
||||
do
|
||||
if attached block_hooks as lst then
|
||||
across
|
||||
lst as c
|
||||
loop
|
||||
across
|
||||
c.item.block_list as blst
|
||||
loop
|
||||
c.item.get_block_view (blst.item, a_execution)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
site_id: READABLE_STRING_8
|
||||
|
||||
site_name: READABLE_STRING_32
|
||||
|
||||
site_email: READABLE_STRING_8
|
||||
|
||||
site_url: READABLE_STRING_8
|
||||
|
||||
site_dir: PATH
|
||||
|
||||
site_var_dir: PATH
|
||||
|
||||
files_location: PATH
|
||||
|
||||
themes_location: PATH
|
||||
|
||||
compute_theme_resource_location
|
||||
do
|
||||
theme_resource_location := themes_location.extended (theme_name).extended ("res")
|
||||
end
|
||||
|
||||
theme_resource_location: PATH
|
||||
|
||||
theme_name: READABLE_STRING_32
|
||||
|
||||
router: WSF_ROUTER
|
||||
|
||||
map_uri_template (tpl: STRING; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]])
|
||||
do
|
||||
router.map (create {WSF_URI_TEMPLATE_MAPPING}.make_from_template (tpl, create {CMS_HANDLER}.make (proc)))
|
||||
end
|
||||
|
||||
map_uri (a_uri: STRING; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]])
|
||||
do
|
||||
router.map (create {WSF_URI_MAPPING}.make (a_uri, create {CMS_HANDLER}.make (proc)))
|
||||
end
|
||||
|
||||
feature -- URL related
|
||||
|
||||
front_path: STRING
|
||||
do
|
||||
if attached base_url as l_base_url then
|
||||
Result := l_base_url + "/"
|
||||
else
|
||||
Result := "/"
|
||||
end
|
||||
end
|
||||
|
||||
urls_set: BOOLEAN
|
||||
|
||||
initialize_urls (req: WSF_REQUEST)
|
||||
local
|
||||
u: like base_url
|
||||
do
|
||||
if not urls_set then
|
||||
u := base_url
|
||||
if u = Void then
|
||||
u := ""
|
||||
end
|
||||
urls_set := True
|
||||
if site_url.is_empty then
|
||||
site_url := req.absolute_script_url (u)
|
||||
end
|
||||
set_script_url (req.script_url (u))
|
||||
end
|
||||
end
|
||||
|
||||
base_url: detachable READABLE_STRING_8
|
||||
-- Base url (related to the script path).
|
||||
|
||||
script_url: detachable READABLE_STRING_8
|
||||
|
||||
set_script_url (a_url: like script_url)
|
||||
local
|
||||
s: STRING_8
|
||||
do
|
||||
if a_url = Void then
|
||||
script_url := Void
|
||||
elseif not a_url.is_empty then
|
||||
if a_url.ends_with ("/") then
|
||||
create s.make_from_string (a_url)
|
||||
else
|
||||
create s.make (a_url.count + 1)
|
||||
s.append (a_url)
|
||||
s.append_character ('/')
|
||||
end
|
||||
script_url := s
|
||||
end
|
||||
ensure
|
||||
attached script_url as l_url implies l_url.ends_with ("/")
|
||||
end
|
||||
|
||||
feature -- Report
|
||||
|
||||
is_front_page (req: WSF_REQUEST): BOOLEAN
|
||||
do
|
||||
Result := req.path_info.same_string (front_path)
|
||||
end
|
||||
|
||||
feature {CMS_EXECUTION, CMS_MODULE} -- Security report
|
||||
|
||||
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
||||
-- Anonymous or user `u' has permission for `s' ?
|
||||
--| `s' could be "create page",
|
||||
do
|
||||
Result := storage.user_has_permission (u, s)
|
||||
end
|
||||
|
||||
feature -- Storage
|
||||
|
||||
session_controller (req: WSF_REQUEST): CMS_SESSION_CONTROLER
|
||||
-- New session controller for request `req'
|
||||
do
|
||||
create Result.make (req, session_manager, site_id)
|
||||
end
|
||||
|
||||
session_manager: WSF_SESSION_MANAGER
|
||||
-- CMS Session manager
|
||||
|
||||
storage: CMS_STORAGE
|
||||
|
||||
feature -- Logging
|
||||
|
||||
log (a_category: READABLE_STRING_8; a_message: READABLE_STRING_8; a_level: INTEGER; a_link: detachable CMS_LINK)
|
||||
local
|
||||
l_log: CMS_LOG
|
||||
do
|
||||
create l_log.make (a_category, a_message, a_level, Void)
|
||||
if a_link /= Void then
|
||||
l_log.set_link (a_link)
|
||||
end
|
||||
storage.save_log (l_log)
|
||||
end
|
||||
|
||||
feature -- Content type
|
||||
|
||||
content_types: ARRAYED_LIST [CMS_CONTENT_TYPE]
|
||||
-- Available content types
|
||||
|
||||
add_content_type (a_type: CMS_CONTENT_TYPE)
|
||||
do
|
||||
content_types.force (a_type)
|
||||
end
|
||||
|
||||
content_type (a_name: READABLE_STRING_8): detachable CMS_CONTENT_TYPE
|
||||
do
|
||||
across
|
||||
content_types as t
|
||||
until
|
||||
Result /= Void
|
||||
loop
|
||||
if t.item.name.same_string (a_name) then
|
||||
Result := t.item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Notification
|
||||
|
||||
mailer: NOTIFICATION_MAILER
|
||||
|
||||
feature -- Core Execution
|
||||
|
||||
handle_favicon (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
fres: WSF_FILE_RESPONSE
|
||||
do
|
||||
create fres.make_with_path (theme_resource_location.extended ("favicon.ico"))
|
||||
fres.set_expires_in_seconds (7 * 24 * 60 * 60) -- 7 jours
|
||||
res.send (fres)
|
||||
end
|
||||
|
||||
handle_home (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
(create {HOME_CMS_EXECUTION}.make (req, res, Current)).execute
|
||||
end
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Default request handler if no other are relevant
|
||||
local
|
||||
e: CMS_EXECUTION
|
||||
sess: WSF_ROUTER_SESSION
|
||||
do
|
||||
initialize_urls (req)
|
||||
create sess
|
||||
router.dispatch (req, res, sess)
|
||||
if not sess.dispatched then
|
||||
create {NOT_FOUND_CMS_EXECUTION} e.make (req, res, Current)
|
||||
e.execute
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
55
draft/application/cms/src/cms_setup.e
Normal file
55
draft/application/cms/src/cms_setup.e
Normal file
@@ -0,0 +1,55 @@
|
||||
note
|
||||
description: "Summary description for {CMS_SETUP}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_SETUP
|
||||
|
||||
feature -- Access
|
||||
|
||||
configuration: detachable CMS_CONFIGURATION
|
||||
|
||||
base_url: detachable READABLE_STRING_8
|
||||
|
||||
modules: LIST [CMS_MODULE]
|
||||
deferred
|
||||
end
|
||||
|
||||
storage: CMS_STORAGE
|
||||
-- CMS persistent layer
|
||||
deferred
|
||||
end
|
||||
|
||||
session_manager: WSF_SESSION_MANAGER
|
||||
-- CMS Session manager
|
||||
deferred
|
||||
end
|
||||
|
||||
auth_engine: CMS_AUTH_ENGINE
|
||||
-- CMS Authentication engine
|
||||
deferred
|
||||
end
|
||||
|
||||
mailer: NOTIFICATION_MAILER
|
||||
-- CMS email engine
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change
|
||||
|
||||
set_base_url (a_base_url: like base_url)
|
||||
do
|
||||
if a_base_url /= Void and then not a_base_url.is_empty then
|
||||
base_url := a_base_url
|
||||
else
|
||||
base_url := Void
|
||||
end
|
||||
end
|
||||
|
||||
add_module (m: CMS_MODULE)
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
17
draft/application/cms/src/handler/cms_file_system_handler.e
Normal file
17
draft/application/cms/src/handler/cms_file_system_handler.e
Normal file
@@ -0,0 +1,17 @@
|
||||
note
|
||||
description: "Summary description for {CMS_FILE_SYSTEM_HANDLER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_FILE_SYSTEM_HANDLER
|
||||
|
||||
inherit
|
||||
WSF_FILE_SYSTEM_HANDLER
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_path
|
||||
|
||||
end
|
||||
@@ -0,0 +1,128 @@
|
||||
note
|
||||
description: "Summary description for {CMS_HTML_FILTER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_HTML_FILTER
|
||||
|
||||
inherit
|
||||
CMS_FILTER
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
do
|
||||
Precursor
|
||||
allowed_html_tags := <<"a", "em", "strong", "cite", "blockquote", "code", "ul", "ol", "li", "dl">>
|
||||
description := "Allowed HTML tags: "
|
||||
across
|
||||
allowed_html_tags as c
|
||||
loop
|
||||
description.append ("<" + c.item + "> ")
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING_8 = "html_filter"
|
||||
|
||||
title: STRING_8 = "HTML filter"
|
||||
|
||||
description: STRING_8
|
||||
|
||||
allowed_html_tags: ITERABLE [READABLE_STRING_8]
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
filter (a_text: STRING_8)
|
||||
local
|
||||
l_new: STRING_8
|
||||
i: INTEGER
|
||||
n: INTEGER
|
||||
in_tag: BOOLEAN
|
||||
p1, p2: INTEGER
|
||||
do
|
||||
create l_new.make (a_text.count)
|
||||
from
|
||||
p1 := 1
|
||||
i := a_text.index_of ('<', 1)
|
||||
if i > 0 then
|
||||
l_new.append (a_text.substring (1, i - 1))
|
||||
end
|
||||
n := a_text.count
|
||||
until
|
||||
i = 0 or i > n
|
||||
loop
|
||||
if a_text[i] = '<' then
|
||||
in_tag := True
|
||||
p1 := i
|
||||
p2 := a_text.index_of ('>', i + 1)
|
||||
if p2 = 0 then
|
||||
-- next '<'
|
||||
i := a_text.index_of ('<', i + 1)
|
||||
if i > 0 then
|
||||
l_new.append (a_text.substring (p1, i - 1))
|
||||
end
|
||||
else
|
||||
if is_authorized (a_text.substring (p1, p2)) then
|
||||
l_new.append (a_text.substring (p1, p2))
|
||||
i := a_text.index_of ('<', p2 + 1)
|
||||
else
|
||||
i := a_text.index_of ('<', p2 + 1)
|
||||
end
|
||||
if i = 0 then
|
||||
p1 := p2 + 1
|
||||
else
|
||||
l_new.append (a_text.substring (p2 + 1, i - 1))
|
||||
end
|
||||
end
|
||||
else
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
l_new.append (a_text.substring (p1, n))
|
||||
a_text.wipe_out
|
||||
a_text.append (l_new)
|
||||
end
|
||||
|
||||
is_authorized (s: READABLE_STRING_8): BOOLEAN
|
||||
-- Is `s' authorized?
|
||||
--| `s' has either "<....>" or "<..../>" or "</.....>"
|
||||
local
|
||||
l_tagname: detachable STRING
|
||||
i,n,p1: INTEGER
|
||||
do
|
||||
-- create l_tagname.make_empty
|
||||
from
|
||||
i := 2 -- skip first '<'
|
||||
n := s.count
|
||||
until
|
||||
i > n or l_tagname /= Void
|
||||
loop
|
||||
if p1 > 0 then
|
||||
if s[i].is_space or s[i] = '/' or s[i] = '>' then
|
||||
l_tagname := s.substring (p1, i - 1)
|
||||
end
|
||||
else
|
||||
if s[i].is_space or s[i] = '/' then
|
||||
else
|
||||
p1 := i
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if l_tagname /= Void then
|
||||
l_tagname.to_lower
|
||||
Result := across allowed_html_tags as c some c.item.same_string (l_tagname) end
|
||||
else
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
128
draft/application/cms/src/modules/debug/debug_module.e
Normal file
128
draft/application/cms/src/modules/debug/debug_module.e
Normal file
@@ -0,0 +1,128 @@
|
||||
note
|
||||
description: "Summary description for {DEBUG_MODULE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
DEBUG_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
|
||||
-- CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
name := "debug"
|
||||
version := "1.0"
|
||||
description := "Debug"
|
||||
package := "cms"
|
||||
end
|
||||
|
||||
feature {CMS_SERVICE} -- Registration
|
||||
|
||||
service: detachable CMS_SERVICE
|
||||
|
||||
register (a_service: CMS_SERVICE)
|
||||
do
|
||||
service := a_service
|
||||
a_service.map_uri_template ("/debug/", agent handle_debug (a_service, ?, ?))
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
-- block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
-- do
|
||||
-- Result := <<"debug-info">>
|
||||
-- end
|
||||
|
||||
-- get_block_view (a_block_id: detachable READABLE_STRING_8; a_execution: CMS_EXECUTION)
|
||||
-- local
|
||||
-- b: CMS_CONTENT_BLOCK
|
||||
-- do
|
||||
-- create b.make ("debug-info", "Debug", "... ", a_execution.formats.plain_text)
|
||||
-- a_execution.add_block (b, Void)
|
||||
-- end
|
||||
|
||||
feature -- Handler
|
||||
|
||||
handle_debug (cms: CMS_SERVICE; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
e: CMS_EXECUTION
|
||||
s: STRING
|
||||
do
|
||||
if req.is_get_request_method then
|
||||
create {ANY_CMS_EXECUTION} e.make (req, res, cms)
|
||||
e.set_title ("DEBUG")
|
||||
|
||||
create s.make_empty
|
||||
append_info_to ("Name", cms.site_name, e, s)
|
||||
append_info_to ("Url", cms.site_url, e, s)
|
||||
|
||||
if attached cms.configuration as cfg and then attached cfg.configuration_location as l_loc then
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Configuration file", l_loc.name, e, s)
|
||||
end
|
||||
|
||||
s.append ("<hr/>")
|
||||
|
||||
append_info_to ("Current dir", execution_environment.current_working_path.utf_8_name, e, s)
|
||||
append_info_to ("Base url", cms.base_url, e, s)
|
||||
append_info_to ("Script url", cms.script_url, e, s)
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Dir", cms.site_dir.utf_8_name, e, s)
|
||||
append_info_to ("Var dir", cms.site_var_dir.utf_8_name, e, s)
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Theme", cms.theme_name, e, s)
|
||||
append_info_to ("Theme location", cms.theme_resource_location.utf_8_name, e, s)
|
||||
s.append ("<hr/>")
|
||||
append_info_to ("Files location", cms.files_location.utf_8_name, e, s)
|
||||
s.append ("<hr/>")
|
||||
|
||||
append_info_to ("Url", e.url ("/", Void), e, s)
|
||||
if attached e.user as u then
|
||||
append_info_to ("User", u.name, e, s)
|
||||
append_info_to ("User url", e.user_url (u), e, s)
|
||||
|
||||
end
|
||||
|
||||
e.set_main_content (s)
|
||||
else
|
||||
create {NOT_FOUND_CMS_EXECUTION} e.make (req, res, cms)
|
||||
end
|
||||
e.execute
|
||||
end
|
||||
|
||||
append_info_to (n: READABLE_STRING_8; v: detachable READABLE_STRING_GENERAL; e: CMS_EXECUTION; t: STRING)
|
||||
do
|
||||
t.append ("<li>")
|
||||
t.append ("<strong>" + n + "</strong>: ")
|
||||
if v /= Void then
|
||||
t.append (e.html_encoded (v))
|
||||
end
|
||||
t.append ("</li>")
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
18
draft/application/cms/src/notification/cms_email.e
Normal file
18
draft/application/cms/src/notification/cms_email.e
Normal file
@@ -0,0 +1,18 @@
|
||||
note
|
||||
description : "[
|
||||
Component representing an email
|
||||
]"
|
||||
author : "$Author$"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
CMS_EMAIL
|
||||
|
||||
inherit
|
||||
NOTIFICATION_EMAIL
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
end
|
||||
38
draft/application/cms/src/notification/cms_storage_mailer.e
Normal file
38
draft/application/cms/src/notification/cms_storage_mailer.e
Normal file
@@ -0,0 +1,38 @@
|
||||
note
|
||||
description: "Summary description for {CMS_CHAIN_MAILER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_STORAGE_MAILER
|
||||
|
||||
inherit
|
||||
NOTIFICATION_MAILER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_storage: like storage)
|
||||
do
|
||||
storage := a_storage
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
storage: CMS_STORAGE
|
||||
|
||||
feature -- Status
|
||||
|
||||
is_available: BOOLEAN = True
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
process_email (a_email: NOTIFICATION_EMAIL)
|
||||
do
|
||||
storage.save_email (a_email)
|
||||
end
|
||||
|
||||
end
|
||||
615
draft/application/cms/src/storage/cms_sed_storage.e
Normal file
615
draft/application/cms/src/storage/cms_sed_storage.e
Normal file
@@ -0,0 +1,615 @@
|
||||
note
|
||||
description : "[
|
||||
CMS Storage implemented using SED
|
||||
]"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
class
|
||||
CMS_SED_STORAGE
|
||||
|
||||
inherit
|
||||
CMS_STORAGE
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (dn: READABLE_STRING_GENERAL)
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
create directory_name.make_from_string (dn)
|
||||
ensure_directory_exists (directory_name)
|
||||
create sed
|
||||
initialize
|
||||
end
|
||||
|
||||
directory_name: PATH
|
||||
|
||||
sed: SED_STORABLE_FACILITIES
|
||||
|
||||
sed_file_retrieved (f: FILE): detachable ANY
|
||||
local
|
||||
r: SED_MEDIUM_READER_WRITER
|
||||
do
|
||||
create r.make (f)
|
||||
r.set_for_reading
|
||||
Result := sed.retrieved (r, True)
|
||||
end
|
||||
|
||||
sed_file_store (obj: ANY; f: FILE)
|
||||
local
|
||||
w: SED_MEDIUM_READER_WRITER
|
||||
do
|
||||
create w.make (f)
|
||||
w.set_for_writing
|
||||
sed.store (obj, w)
|
||||
end
|
||||
|
||||
save_object_with_id (obj: ANY; a_id: INTEGER; a_type: STRING)
|
||||
local
|
||||
fn: PATH
|
||||
f: RAW_FILE
|
||||
do
|
||||
fn := directory_name.extended (a_type)
|
||||
ensure_directory_exists (fn)
|
||||
fn := fn.extended (a_id.out)
|
||||
-- .appended_with_extension ("txt")
|
||||
create f.make_with_path (fn)
|
||||
-- check not f.exists end
|
||||
f.create_read_write
|
||||
sed_file_store (obj, f)
|
||||
f.close
|
||||
end
|
||||
|
||||
object_with_id (a_id: INTEGER; a_type: STRING): detachable ANY
|
||||
local
|
||||
fn: PATH
|
||||
f: RAW_FILE
|
||||
do
|
||||
fn := directory_name.extended (a_type)
|
||||
ensure_directory_exists (fn)
|
||||
fn := fn.extended (a_id.out)
|
||||
-- .append_with_extension ("txt")
|
||||
create f.make_with_path (fn)
|
||||
if f.exists and f.is_readable then
|
||||
f.open_read
|
||||
Result := sed_file_retrieved (f)
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: user
|
||||
|
||||
has_user: BOOLEAN
|
||||
-- Has any user?
|
||||
do
|
||||
Result := users_count > 0
|
||||
end
|
||||
|
||||
users_count: INTEGER
|
||||
do
|
||||
Result := last_sequence ("user")
|
||||
end
|
||||
|
||||
fill_user_profile (a_user: CMS_USER)
|
||||
do
|
||||
if a_user.profile = Void then
|
||||
if attached user_profile (a_user) as p then
|
||||
a_user.set_profile (p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
all_users: LIST [CMS_USER]
|
||||
local
|
||||
res: ARRAYED_LIST [like all_users.item]
|
||||
i, n: like last_sequence
|
||||
do
|
||||
n := last_sequence ("user")
|
||||
create res.make (n)
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if attached user_by_id (i) as u then
|
||||
res.force (u)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
Result := res
|
||||
end
|
||||
|
||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||
do
|
||||
if attached {like user_by_id} object_with_id (a_id, "user") as u then
|
||||
Result := u
|
||||
end
|
||||
end
|
||||
|
||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
||||
local
|
||||
uid: INTEGER
|
||||
do
|
||||
if attached users_index as t then
|
||||
uid := t.by_name.item (a_name)
|
||||
if uid > 0 then
|
||||
Result := user_by_id (uid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
||||
local
|
||||
uid: INTEGER
|
||||
do
|
||||
if attached users_index as t then
|
||||
uid := t.by_email.item (a_email)
|
||||
if uid > 0 then
|
||||
Result := user_by_id (uid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_valid_credential (u, p: READABLE_STRING_32): BOOLEAN
|
||||
do
|
||||
if attached user_by_name (u) as l_user then
|
||||
Result := attached l_user.encoded_password as l_pass and then l_pass.same_string (encoded_password (p))
|
||||
end
|
||||
end
|
||||
|
||||
encoded_password (a_raw_password: STRING_32): attached like {CMS_USER}.encoded_password
|
||||
do
|
||||
Result := a_raw_password.as_string_8 + "!123!"
|
||||
end
|
||||
|
||||
feature -- Change: user
|
||||
|
||||
save_user (a_user: CMS_USER)
|
||||
local
|
||||
uid: INTEGER
|
||||
prof: like {CMS_USER}.profile
|
||||
l_has_new_name: BOOLEAN
|
||||
l_has_new_email: BOOLEAN
|
||||
l_stored_user: like user_by_id
|
||||
do
|
||||
if a_user.has_id then
|
||||
uid := a_user.id
|
||||
l_stored_user := user_by_id (uid)
|
||||
if l_stored_user /= Void then
|
||||
l_has_new_name := not l_stored_user.name.same_string (a_user.name)
|
||||
l_has_new_email := not (l_stored_user.email ~ a_user.email)
|
||||
end
|
||||
else
|
||||
l_has_new_name := True
|
||||
l_has_new_email := True
|
||||
uid := next_sequence ("user")
|
||||
a_user.set_id (uid)
|
||||
end
|
||||
if attached a_user.password as p then
|
||||
a_user.set_encoded_password (encoded_password (p))
|
||||
a_user.set_password (Void)
|
||||
end
|
||||
|
||||
prof := a_user.profile
|
||||
a_user.set_profile (Void)
|
||||
if prof /= Void then
|
||||
save_user_profile (a_user, prof)
|
||||
end
|
||||
save_object_with_id (a_user, uid, "user")
|
||||
if l_has_new_name or l_has_new_email then
|
||||
if attached users_index as l_index then
|
||||
l_index.by_name.force (uid, a_user.name)
|
||||
l_index.by_email.force (uid, a_user.email)
|
||||
store_users_index (l_index)
|
||||
end
|
||||
end
|
||||
a_user.set_profile (prof)
|
||||
end
|
||||
|
||||
feature -- Access: user_role
|
||||
|
||||
user_role_by_id (a_id: INTEGER): detachable CMS_USER_ROLE
|
||||
do
|
||||
if attached {like user_role_by_id} object_with_id (a_id, "user_roles") as ur then
|
||||
Result := ur
|
||||
end
|
||||
end
|
||||
|
||||
user_roles: LIST [CMS_USER_ROLE]
|
||||
local
|
||||
i: INTEGER
|
||||
n: like last_sequence
|
||||
do
|
||||
n := last_sequence ("user_roles")
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (n)
|
||||
if n > 0 then
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > n
|
||||
loop
|
||||
if attached user_role_by_id (i) as ur then
|
||||
Result.force (ur)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: user_role
|
||||
|
||||
save_user_role (a_role: CMS_USER_ROLE)
|
||||
do
|
||||
if not a_role.has_id then
|
||||
a_role.set_id (next_sequence ("user_roles"))
|
||||
end
|
||||
save_object_with_id (a_role, a_role.id, "user_roles")
|
||||
end
|
||||
|
||||
feature -- Email
|
||||
|
||||
save_email (a_email: NOTIFICATION_EMAIL)
|
||||
local
|
||||
dn: PATH
|
||||
fn: PATH
|
||||
f: RAW_FILE
|
||||
ts: INTEGER_64
|
||||
i: INTEGER
|
||||
do
|
||||
dn := directory_name.extended ("emails")
|
||||
ensure_directory_exists (dn)
|
||||
ts := (create {HTTP_DATE_TIME_UTILITIES}).unix_time_stamp (a_email.date)
|
||||
from
|
||||
fn := dn.extended (ts.out).appended_with_extension ("txt")
|
||||
create f.make_with_path (fn)
|
||||
until
|
||||
not f.exists
|
||||
loop
|
||||
i := i + 1
|
||||
fn := dn.extended (ts.out + "-" + i.out).appended_with_extension ("txt")
|
||||
f.make_with_path (fn)
|
||||
end
|
||||
f.create_read_write
|
||||
f.put_string (a_email.message)
|
||||
f.close
|
||||
end
|
||||
|
||||
feature -- Log
|
||||
|
||||
log (a_id: like {CMS_LOG}.id): detachable CMS_LOG
|
||||
do
|
||||
if attached {CMS_LOG} object_with_id (a_id, "log") as l then
|
||||
Result := l
|
||||
end
|
||||
end
|
||||
|
||||
recent_logs (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
|
||||
local
|
||||
n: Like last_sequence
|
||||
i, p1, nb: INTEGER
|
||||
do
|
||||
n := last_sequence ("log")
|
||||
p1 := n - a_lower + 1
|
||||
|
||||
if p1 > 0 then
|
||||
create {ARRAYED_LIST [CMS_LOG]} Result.make (a_count)
|
||||
from
|
||||
i := p1
|
||||
until
|
||||
i < 1 or nb = a_count
|
||||
loop
|
||||
if attached log (i) as obj then
|
||||
Result.force (obj)
|
||||
nb := nb + 1
|
||||
end
|
||||
i := i - 1
|
||||
end
|
||||
else
|
||||
create {ARRAYED_LIST [CMS_LOG]} Result.make (0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
save_log (a_log: CMS_LOG)
|
||||
do
|
||||
if not a_log.has_id then
|
||||
a_log.set_id (next_sequence ("log"))
|
||||
end
|
||||
save_object_with_id (a_log, a_log.id, "log")
|
||||
end
|
||||
|
||||
feature -- Node
|
||||
|
||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||
local
|
||||
n: Like last_sequence
|
||||
i, p1, nb: INTEGER
|
||||
do
|
||||
n := last_sequence ("node")
|
||||
p1 := n - a_lower + 1
|
||||
|
||||
if p1 > 0 then
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (a_count)
|
||||
from
|
||||
i := p1
|
||||
until
|
||||
i < 1 or nb = a_count
|
||||
loop
|
||||
if attached node (i) as l_node then
|
||||
Result.force (l_node)
|
||||
nb := nb + 1
|
||||
end
|
||||
i := i - 1
|
||||
end
|
||||
else
|
||||
create {ARRAYED_LIST [CMS_NODE]} Result.make (0)
|
||||
end
|
||||
end
|
||||
|
||||
node (a_id: INTEGER): detachable CMS_NODE
|
||||
do
|
||||
if attached {like node} object_with_id (a_id, "node") as obj then
|
||||
Result := obj
|
||||
end
|
||||
end
|
||||
|
||||
save_node (a_node: CMS_NODE)
|
||||
local
|
||||
nid: INTEGER
|
||||
do
|
||||
if a_node.has_id then
|
||||
nid := a_node.id
|
||||
else
|
||||
nid := next_sequence ("node")
|
||||
a_node.set_id (nid)
|
||||
end
|
||||
|
||||
save_object_with_id (a_node, nid, "node")
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
last_sequence (a_type: STRING): INTEGER
|
||||
local
|
||||
fn: PATH
|
||||
f: RAW_FILE
|
||||
do
|
||||
fn := directory_name.extended (a_type).appended_with_extension ("last_id")
|
||||
create f.make_with_path (fn)
|
||||
if f.exists and then f.is_readable then
|
||||
f.open_read
|
||||
f.read_line
|
||||
if f.last_string.is_integer then
|
||||
Result := f.last_string.to_integer
|
||||
else
|
||||
check is_integer: False end
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
next_sequence (a_type: STRING): INTEGER
|
||||
local
|
||||
fn: PATH
|
||||
f: RAW_FILE
|
||||
do
|
||||
fn := directory_name.extended (a_type).appended_with_extension ("last_id")
|
||||
create f.make_with_path (fn)
|
||||
if f.exists and then f.is_readable then
|
||||
f.open_read
|
||||
f.read_line
|
||||
if f.last_string.is_integer then
|
||||
Result := f.last_string.to_integer
|
||||
else
|
||||
check is_integer: False end
|
||||
end
|
||||
f.close
|
||||
end
|
||||
Result := Result + 1
|
||||
f.open_write
|
||||
f.put_string (Result.out)
|
||||
f.put_new_line
|
||||
f.close
|
||||
end
|
||||
|
||||
users_index: TUPLE [
|
||||
by_name: HASH_TABLE [like {CMS_USER}.id, like {CMS_USER}.name];
|
||||
by_email: HASH_TABLE [like {CMS_USER}.id, like {CMS_USER}.email]
|
||||
]
|
||||
local
|
||||
f: RAW_FILE
|
||||
fn: PATH
|
||||
res: detachable like users_index
|
||||
retried: INTEGER
|
||||
do
|
||||
fn := directory_name.extended ("users.db")
|
||||
create f.make_with_path (fn)
|
||||
if retried = 0 then
|
||||
if f.exists and then f.is_readable then
|
||||
f.open_read
|
||||
if attached {like users_index} sed_file_retrieved (f) as r then
|
||||
res := r
|
||||
end
|
||||
f.close
|
||||
else
|
||||
end
|
||||
end
|
||||
if res = Void then
|
||||
res := [ create {HASH_TABLE [like {CMS_USER}.id, like {CMS_USER}.name]}.make (1),
|
||||
create {HASH_TABLE [like {CMS_USER}.id, like {CMS_USER}.email]}.make (1) ]
|
||||
end
|
||||
Result := res
|
||||
rescue
|
||||
retried := retried + 1
|
||||
retry
|
||||
end
|
||||
|
||||
store_users_index (a_users_index: like users_index)
|
||||
local
|
||||
f: RAW_FILE
|
||||
fn: PATH
|
||||
do
|
||||
fn := directory_name.extended ("users.db")
|
||||
create f.make_with_path (fn)
|
||||
if not f.exists or else f.is_writable then
|
||||
f.open_write
|
||||
sed_file_store (a_users_index, f)
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
user_profile (a_user: CMS_USER): detachable CMS_USER_PROFILE
|
||||
do
|
||||
if attached {like user_profile} object_with_id (a_user.id, "user_profile") as obj then
|
||||
Result := obj
|
||||
end
|
||||
end
|
||||
|
||||
save_user_profile (a_user: CMS_USER; a_prof: CMS_USER_PROFILE)
|
||||
local
|
||||
l_id: INTEGER
|
||||
do
|
||||
if a_user.has_id then
|
||||
l_id := a_user.id
|
||||
end
|
||||
|
||||
save_object_with_id (a_prof, l_id, "user_profile")
|
||||
end
|
||||
|
||||
feature -- Misc
|
||||
|
||||
custom_type (a_type: READABLE_STRING_8): STRING
|
||||
do
|
||||
Result := "custom__" + a_type
|
||||
end
|
||||
|
||||
custom_value_id (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): INTEGER
|
||||
-- Storage `id' for custom value named `a_name' if any.
|
||||
-- If no such data exists, return 0
|
||||
local
|
||||
i,
|
||||
l_id, l_last_id: INTEGER
|
||||
t: STRING
|
||||
do
|
||||
t := custom_type (a_type)
|
||||
l_last_id := last_sequence (t)
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > l_last_id or l_id > 0
|
||||
loop
|
||||
if
|
||||
attached {TUPLE [name: READABLE_STRING_8; value: attached like custom_value]} object_with_id (i, t) as obj and then
|
||||
obj.name.same_string (a_name)
|
||||
then
|
||||
l_id := i
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value ; a_type: READABLE_STRING_8)
|
||||
-- Save data `a_name:a_value' for type `a_type'
|
||||
local
|
||||
t: STRING
|
||||
l_id: INTEGER
|
||||
do
|
||||
t := custom_type (a_type)
|
||||
l_id := custom_value_id (a_name, a_type)
|
||||
if l_id = 0 then
|
||||
l_id := next_sequence (t)
|
||||
end
|
||||
save_object_with_id ([a_name, a_value], l_id, t)
|
||||
end
|
||||
|
||||
custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
|
||||
-- Data for name `a_name' and type `a_type'.
|
||||
local
|
||||
i,
|
||||
l_id, l_last_id: INTEGER
|
||||
t: STRING
|
||||
do
|
||||
t := custom_type (a_type)
|
||||
l_last_id := last_sequence (t)
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > l_last_id or l_id > 0
|
||||
loop
|
||||
if
|
||||
attached {TUPLE [name: READABLE_STRING_8; value: attached like custom_value]} object_with_id (i, t) as obj and then
|
||||
obj.name.same_string (a_name)
|
||||
then
|
||||
l_id := i
|
||||
Result := obj.value
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
|
||||
-- Name where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
|
||||
local
|
||||
i, l_last_id: INTEGER
|
||||
t: STRING
|
||||
l_key_found: BOOLEAN
|
||||
res: ARRAYED_LIST [READABLE_STRING_8]
|
||||
do
|
||||
create res.make (0)
|
||||
t := custom_type (a_type)
|
||||
l_last_id := last_sequence (t)
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > l_last_id
|
||||
loop
|
||||
if
|
||||
attached {TUPLE [name: READABLE_STRING_8; value: attached like custom_value]} object_with_id (i, t) as d
|
||||
then
|
||||
l_key_found := False
|
||||
across
|
||||
d.value as c
|
||||
until
|
||||
l_key_found or Result /= Void
|
||||
loop
|
||||
if c.key.same_string (a_where_key) then
|
||||
l_key_found := True
|
||||
if c.item.same_string (a_where_value) then
|
||||
res.force (d.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if not res.is_empty then
|
||||
Result := res
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
ensure_directory_exists (dn: PATH)
|
||||
local
|
||||
d: DIRECTORY
|
||||
do
|
||||
d := tmp_dir
|
||||
d.make_with_path (dn)
|
||||
if not d.exists then
|
||||
d.recursive_create_dir
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
tmp_dir: DIRECTORY
|
||||
once
|
||||
create Result.make_with_path (directory_name)
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
end
|
||||
186
draft/application/cms/src/storage/cms_storage.e
Normal file
186
draft/application/cms/src/storage/cms_storage.e
Normal file
@@ -0,0 +1,186 @@
|
||||
note
|
||||
description : "[
|
||||
CMS interface to storage
|
||||
]"
|
||||
date : "$Date$"
|
||||
revision : "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_STORAGE
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Access: user
|
||||
|
||||
has_user: BOOLEAN
|
||||
-- Has any user?
|
||||
deferred
|
||||
end
|
||||
|
||||
fill_user_profile (a_user: CMS_USER)
|
||||
deferred
|
||||
end
|
||||
|
||||
all_users: LIST [CMS_USER]
|
||||
deferred
|
||||
end
|
||||
|
||||
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
|
||||
require
|
||||
a_id > 0
|
||||
deferred
|
||||
ensure
|
||||
same_id: Result /= Void implies Result.id = a_id
|
||||
no_password: Result /= Void implies Result.password = Void
|
||||
end
|
||||
|
||||
user_by_name (a_name: like {CMS_USER}.name): detachable CMS_USER
|
||||
require
|
||||
a_name /= Void and then not a_name.is_empty
|
||||
deferred
|
||||
ensure
|
||||
no_password: Result /= Void implies Result.password = Void
|
||||
end
|
||||
|
||||
user_by_email (a_email: like {CMS_USER}.email): detachable CMS_USER
|
||||
deferred
|
||||
ensure
|
||||
no_password: Result /= Void implies Result.password = Void
|
||||
end
|
||||
|
||||
is_valid_credential (u, p: READABLE_STRING_32): BOOLEAN
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: user
|
||||
|
||||
save_user (a_user: CMS_USER)
|
||||
deferred
|
||||
ensure
|
||||
a_user_password_is_encoded: a_user.password = Void
|
||||
a_user.has_id
|
||||
end
|
||||
|
||||
feature -- Access: roles and permissions
|
||||
|
||||
user_has_permission (u: detachable CMS_USER; s: detachable READABLE_STRING_8): BOOLEAN
|
||||
-- Anonymous or user `u' has permission for `s' ?
|
||||
--| `s' could be "create page",
|
||||
do
|
||||
if s = Void then
|
||||
Result := True
|
||||
elseif u = Void then
|
||||
Result := user_role_has_permission (anonymous_user_role, s)
|
||||
else
|
||||
Result := user_role_has_permission (authenticated_user_role, s)
|
||||
if not Result and attached u.roles as l_roles then
|
||||
across
|
||||
l_roles as r
|
||||
until
|
||||
Result
|
||||
loop
|
||||
if attached user_role_by_id (r.item) as ur then
|
||||
Result := user_role_has_permission (ur, s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
anonymous_user_role: CMS_USER_ROLE
|
||||
do
|
||||
if attached user_role_by_id (1) as l_anonymous then
|
||||
Result := l_anonymous
|
||||
else
|
||||
create Result.make ("anonymous")
|
||||
end
|
||||
end
|
||||
|
||||
authenticated_user_role: CMS_USER_ROLE
|
||||
do
|
||||
if attached user_role_by_id (2) as l_authenticated then
|
||||
Result := l_authenticated
|
||||
else
|
||||
create Result.make ("authenticated")
|
||||
end
|
||||
end
|
||||
|
||||
user_role_has_permission (a_role: CMS_USER_ROLE; s: READABLE_STRING_8): BOOLEAN
|
||||
do
|
||||
Result := a_role.has_permission (s)
|
||||
end
|
||||
|
||||
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
|
||||
deferred
|
||||
end
|
||||
|
||||
user_roles: LIST [CMS_USER_ROLE]
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: roles and permissions
|
||||
|
||||
save_user_role (a_user_role: CMS_USER_ROLE)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Email
|
||||
|
||||
save_email (a_email: NOTIFICATION_EMAIL)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Log
|
||||
|
||||
recent_logs (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_LOG]
|
||||
deferred
|
||||
end
|
||||
|
||||
log (a_id: like {CMS_LOG}.id): detachable CMS_LOG
|
||||
require
|
||||
a_id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
save_log (a_log: CMS_LOG)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Node
|
||||
|
||||
recent_nodes (a_lower: INTEGER; a_count: INTEGER): LIST [CMS_NODE]
|
||||
deferred
|
||||
end
|
||||
|
||||
node (a_id: INTEGER): detachable CMS_NODE
|
||||
require
|
||||
a_id > 0
|
||||
deferred
|
||||
end
|
||||
|
||||
save_node (a_node: CMS_NODE)
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Misc
|
||||
|
||||
set_custom_value (a_name: READABLE_STRING_8; a_value: attached like custom_value; a_type: READABLE_STRING_8)
|
||||
-- Save data `a_name:a_value' for type `a_type'
|
||||
deferred
|
||||
end
|
||||
|
||||
custom_value (a_name: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable TABLE_ITERABLE [READABLE_STRING_8, STRING_8]
|
||||
-- Data for name `a_name' and type `a_type'.
|
||||
deferred
|
||||
end
|
||||
|
||||
custom_value_names_where (a_where_key, a_where_value: READABLE_STRING_8; a_type: READABLE_STRING_8): detachable LIST [READABLE_STRING_8]
|
||||
-- Names where custom value has item `a_where_key' same as `a_where_value' for type `a_type'.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user