Merge branch 'master' into es17.01
# Conflicts: # examples/demo/demo.ecf
This commit is contained in:
87
dev_modules/masquerade_auth/masquerade_api.e
Normal file
87
dev_modules/masquerade_auth/masquerade_api.e
Normal file
@@ -0,0 +1,87 @@
|
||||
note
|
||||
description: "API to manage CMS User session authentication"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
MASQUERADE_API
|
||||
|
||||
inherit
|
||||
CMS_AUTH_API_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create {MASQUERADE_AUTH_MODULE}
|
||||
make_with_session_api
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_session_api (a_api: CMS_API; a_session_api: CMS_SESSION_API)
|
||||
do
|
||||
session_api := a_session_api
|
||||
make (a_api)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
session_api: CMS_SESSION_API
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_permission_to_masquerade (a_user: detachable CMS_USER): BOOLEAN
|
||||
local
|
||||
v: STRING
|
||||
do
|
||||
if attached cms_api.setup.string_8_item_or_default ("dev.masquerade", "permission") as s then
|
||||
v := s
|
||||
v.left_adjust
|
||||
v.right_adjust
|
||||
if v.is_case_insensitive_equal_general ("none") then
|
||||
elseif v.is_case_insensitive_equal_general ("all") then
|
||||
Result := True
|
||||
elseif v.is_case_insensitive_equal_general ("permission") then
|
||||
Result := cms_api.user_has_permission (a_user, "masquerade")
|
||||
else
|
||||
-- no!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_authenticating (a_response: CMS_RESPONSE): BOOLEAN
|
||||
do
|
||||
if
|
||||
a_response.is_authenticated and then
|
||||
attached a_response.request.cookie (session_api.session_token)
|
||||
then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
process_user_login (a_user: CMS_USER; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
session_api.process_user_login (a_user, req, res)
|
||||
end
|
||||
|
||||
process_user_logout (a_user: CMS_USER; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
do
|
||||
session_api.process_user_logout (a_user, req, res)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
-- user_by_session_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
-- -- Retrieve user by token `a_token', if any.
|
||||
-- do
|
||||
-- Result := session_auth_storage.user_by_session_token (a_token)
|
||||
-- end
|
||||
|
||||
-- has_user_token (a_user: CMS_USER): BOOLEAN
|
||||
-- -- Has the user `a_user' and associated session token?
|
||||
-- do
|
||||
-- Result := session_auth_storage.has_user_token (a_user)
|
||||
-- end
|
||||
|
||||
|
||||
end
|
||||
3
dev_modules/masquerade_auth/masquerade_auth-safe.ecf
Normal file
3
dev_modules/masquerade_auth/masquerade_auth-safe.ecf
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<redirection 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" uuid="73DA3649-BA18-426C-91CD-5892D52C811C" message="Obsolete: use masquerade_auth.ecf !" location="masquerade_auth.ecf">
|
||||
</redirection>
|
||||
26
dev_modules/masquerade_auth/masquerade_auth.ecf
Normal file
26
dev_modules/masquerade_auth/masquerade_auth.ecf
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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="masquerade_auth" uuid="73DA3649-BA18-426C-91CD-5892D52C811C" library_target="masquerade_auth">
|
||||
<target name="masquerade_auth">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.svn$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
</file_rule>
|
||||
<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"/>
|
||||
<library name="cms_auth_module" location="..\..\modules\auth\auth.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_session_auth_module" location="..\..\modules\session_auth\cms_session_auth.ecf" readonly="false"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<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" readonly="false"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.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"/>
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
268
dev_modules/masquerade_auth/masquerade_auth_module.e
Normal file
268
dev_modules/masquerade_auth/masquerade_auth_module.e
Normal file
@@ -0,0 +1,268 @@
|
||||
note
|
||||
description: "[
|
||||
This module allows the use Session Based Authentication using Cookies to restrict access
|
||||
by looking up users in the given providers.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
MASQUERADE_AUTH_MODULE
|
||||
|
||||
inherit
|
||||
CMS_AUTH_MODULE_I
|
||||
rename
|
||||
module_api as masquerade_api
|
||||
redefine
|
||||
make,
|
||||
setup_hooks,
|
||||
initialize,
|
||||
install,
|
||||
permissions,
|
||||
masquerade_api,
|
||||
menu_system_alter
|
||||
end
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
do
|
||||
Precursor
|
||||
version := "1.0"
|
||||
description := "Service to easily log as user at development time"
|
||||
package := "debug"
|
||||
disable -- Disabled by default
|
||||
add_dependency ({CMS_SESSION_AUTH_MODULE})
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "masquerade_auth"
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.extend ("masquerade")
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor (a_api)
|
||||
|
||||
if attached {CMS_SESSION_API} a_api.module_api ({CMS_SESSION_AUTH_MODULE}) as l_session_api then
|
||||
-- API initialization
|
||||
create masquerade_api.make_with_session_api (a_api, l_session_api)
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
install (api: CMS_API)
|
||||
do
|
||||
Precursor {CMS_AUTH_MODULE_I} (api) -- Mark it as installed.
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
|
||||
masquerade_api: detachable MASQUERADE_API
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Access: auth strategy
|
||||
|
||||
login_title: STRING = "Masquerade"
|
||||
-- Module specific login title.
|
||||
|
||||
login_location: STRING = "account/auth/roc-masquerade-login"
|
||||
|
||||
logout_location: STRING = "account/auth/roc-masquerade-logout"
|
||||
|
||||
is_authenticating (a_response: CMS_RESPONSE): BOOLEAN
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached masquerade_api as l_masquerade_api then
|
||||
Result := l_masquerade_api.is_authenticating (a_response)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached masquerade_api as l_masquerade_api then
|
||||
a_router.handle ("/" + login_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/" + logout_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, l_masquerade_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/" + login_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_with_masquerade (a_api, l_masquerade_api,?, ?)), a_router.methods_post)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: routes
|
||||
|
||||
handle_login (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if
|
||||
attached masquerade_api as l_masquerade_api and then
|
||||
l_masquerade_api.has_permission_to_masquerade (api.user)
|
||||
then
|
||||
if api.user_is_authenticated then
|
||||
r.add_warning_message ("You are signed.")
|
||||
end
|
||||
r.add_block (login_block ("login", Void, r), "content")
|
||||
else
|
||||
r.add_error_message ("You are not allowed to use masquerade authentication!")
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_logout (api: CMS_API; a_masquerade_api: MASQUERADE_API ; req: WSF_REQUEST; res: WSF_RESPONSE) local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
if attached api.user as l_user then
|
||||
a_masquerade_api.process_user_logout (l_user, req, res)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
else
|
||||
-- Not loggued in ... redirect to home
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
end
|
||||
if
|
||||
attached {WSF_STRING} req.item ("destination") as p_destination and then
|
||||
attached p_destination.value as v and then
|
||||
v.is_valid_as_string_8
|
||||
then
|
||||
r.set_redirection (v.to_string_8)
|
||||
else
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
end
|
||||
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_login_with_masquerade (api: CMS_API; a_masquerade_api: MASQUERADE_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
if a_masquerade_api.has_permission_to_masquerade (api.user) then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("username") as l_username
|
||||
then
|
||||
if
|
||||
attached api.user_api.user_by_name (l_username.value) as l_user
|
||||
then
|
||||
a_masquerade_api.process_user_login (l_user, req, res)
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if
|
||||
attached {WSF_STRING} req.item ("destination") as p_destination and then
|
||||
attached p_destination.value as v and then
|
||||
v.is_valid_as_string_8
|
||||
then
|
||||
r.set_redirection (v.to_string_8)
|
||||
else
|
||||
r.set_redirection ("")
|
||||
end
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.add_block (login_block ("login", Void, r), "content")
|
||||
end
|
||||
else
|
||||
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.add_block (login_block ("login", "Wrong username", r), "content")
|
||||
end
|
||||
else
|
||||
create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
Precursor (a_hooks)
|
||||
a_hooks.subscribe_to_block_hook (Current)
|
||||
a_hooks.subscribe_to_menu_system_alter_hook (Current)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
do
|
||||
Result := <<"?login">>
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_block_id.is_case_insensitive_equal_general ("login") then
|
||||
a_response.add_block (login_block (a_block_id, Void, a_response), "content")
|
||||
end
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on collection of menu contained by `a_menu_system'
|
||||
-- for related response `a_response'.
|
||||
local
|
||||
u: detachable CMS_USER
|
||||
do
|
||||
u := a_response.api.user
|
||||
if
|
||||
attached masquerade_api as l_masquerade_api and then
|
||||
l_masquerade_api.has_permission_to_masquerade (u)
|
||||
then
|
||||
Precursor (a_menu_system, a_response)
|
||||
if u /= Void then
|
||||
a_menu_system.navigation_menu.extend (a_response.local_link ("Masquerade", login_location))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Block views
|
||||
|
||||
login_block (a_block_id: READABLE_STRING_8; a_err: detachable READABLE_STRING_8; a_response: CMS_RESPONSE): CMS_CONTENT_BLOCK
|
||||
do
|
||||
create Result.make (a_block_id, Void, login_html (a_err, a_response), Void)
|
||||
end
|
||||
|
||||
login_html (a_err: detachable READABLE_STRING_8; a_response: CMS_RESPONSE): STRING
|
||||
local
|
||||
params: CMS_DATA_QUERY_PARAMETERS
|
||||
u: CMS_USER
|
||||
do
|
||||
create Result.make_from_string ("<div class=%"login-box%">")
|
||||
if a_err /= Void then
|
||||
Result.append ("<div class=%"error%">")
|
||||
Result.append (a_err)
|
||||
Result.append ("</div>")
|
||||
end
|
||||
Result.append ("<form name=%"masquerade_auth%" action=%"" + a_response.site_url + login_location + "%" method=%"POST%">%N")
|
||||
Result.append ("<div><input type=%"text%" name=%"username%" id=%"username%" required value=%"%"><label>Username</label></div>")
|
||||
Result.append ("<button type=%"submit%">Login</button>")
|
||||
|
||||
create params.make (0, a_response.api.user_api.users_count.as_natural_32)
|
||||
across
|
||||
a_response.api.user_api.recent_users (params) as ic
|
||||
loop
|
||||
u := ic.item
|
||||
Result.append ("<li>")
|
||||
Result.append (a_response.html_encoded (a_response.api.user_display_name (u)))
|
||||
Result.append ("</li>%N")
|
||||
end
|
||||
Result.append ("</form></div>")
|
||||
end
|
||||
|
||||
end
|
||||
@@ -29,7 +29,7 @@
|
||||
<library name="cms_email_service" location="..\..\library\email\email.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_module" location="..\..\modules\google_search\google_search.ecf" readonly="false" use_application_options="true"/>
|
||||
<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_model" location="..\..\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="cms_node_module" location="..\..\modules\node\node.ecf" readonly="false"/>
|
||||
@@ -40,8 +40,9 @@
|
||||
<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="embedded_video_module" location="..\..\modules\embedded_video\embedded_video.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"/>
|
||||
<library name="persistence_sqlite3" location="..\..\library\persistence\sqlite3\sqlite3.ecf" readonly="false"/>
|
||||
<!--
|
||||
By default, commented, since it depends on specific environment settings.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"contact": { "location": "../../modules/contact" },
|
||||
"feed_aggregator": { "location": "../../modules/feed_aggregator" },
|
||||
"google_search": { "location": "../../modules/google_search" },
|
||||
"google_search_20": { "location": "../../modules/google_search_20" },
|
||||
"node": { "location": "../../modules/node" },
|
||||
"oauth20": { "location": "../../modules/oauth20" },
|
||||
"openid": { "location": "../../modules/openid" },
|
||||
@@ -25,6 +26,7 @@
|
||||
"embedded_video": { "location": "../../modules/embedded_video" },
|
||||
"wikitext": { "location": "../../modules/wikitext" },
|
||||
"messaging": { "location": "../../modules/messaging" },
|
||||
"comments": { "location": "../../modules/comments" }
|
||||
"comments": { "location": "../../modules/comments" },
|
||||
"masquerade": { "location": "../../dev_modules/masquerade" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,3 +63,7 @@ base_path=/roc-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
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"gcse": {
|
||||
"search_engine_id":""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<form action="{$site_url/}gcse20" class="search-form" id="search-form">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="search" class="form-control" name="q" id="search-query" placeholder="search" value="{htmlentities}{$cms_search_query/}{/htmlentities}" >
|
||||
<span class="glyphicon glyphicon-search form-control-feedback"></span>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,7 @@
|
||||
<section>
|
||||
<header>
|
||||
<h2>Results for <kbd>{$cms_search_query/}</kbd></h2>
|
||||
</header>
|
||||
|
||||
<gcse:searchresults-only></gcse:searchresults-only>
|
||||
</section>
|
||||
@@ -37,17 +37,14 @@
|
||||
{$page.primary_nav/}
|
||||
{/if}
|
||||
</div>
|
||||
{if isset="$page.regions.search"}
|
||||
<!-- 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>
|
||||
{$page.regions.search/}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- General Page Content -->
|
||||
<div id='content' class='row-fluid'>
|
||||
<!-- Left Sidebar sidebar_first -->
|
||||
|
||||
6
examples/demo/site/themes/bootstrap/search.tpl
Normal file
6
examples/demo/site/themes/bootstrap/search.tpl
Normal file
@@ -0,0 +1,6 @@
|
||||
<form action="{$site_url/}search" class="search-form" id="search-form">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="search" class="form-control" name="q" id="search-query" placeholder="search" value="{htmlentities}{$cms_search_query/}{/htmlentities}" >
|
||||
<span class="glyphicon glyphicon-search form-control-feedback"></span>
|
||||
</div>
|
||||
</form>
|
||||
@@ -4,6 +4,7 @@ author=jvelilla
|
||||
version=0.1
|
||||
regions[page_top] = Top
|
||||
regions[header] = Header
|
||||
regions[search] = Search
|
||||
regions[content] = Content
|
||||
regions[highlighted] = Highlighted
|
||||
regions[help] = Help
|
||||
|
||||
@@ -86,11 +86,14 @@ feature -- CMS modules
|
||||
|
||||
-- Miscellanious
|
||||
a_setup.register_module (create {CMS_MESSAGING_MODULE}.make)
|
||||
a_setup.register_module (create {GOOGLE_CUSTOM_SEARCH_MODULE}.make)
|
||||
a_setup.register_module (create {GOOGLE_CUSTOM_SEARCH_MODULE_20}.make)
|
||||
a_setup.register_module (create {CMS_CUSTOM_BLOCK_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_DEBUG_MODULE}.make)
|
||||
a_setup.register_module (create {CMS_DEMO_MODULE}.make)
|
||||
|
||||
-- Dev
|
||||
a_setup.register_module (create {MASQUERADE_AUTH_MODULE}.make)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
13
modules/google_search_20/Readme.md
Normal file
13
modules/google_search_20/Readme.md
Normal file
@@ -0,0 +1,13 @@
|
||||
Google Custom Search Module 2.0.
|
||||
|
||||
# Based on Google Custom Search Engine (CSE)
|
||||
- https://developers.google.com/custom-search/docs/element
|
||||
- Search form provides a parameter `q` for the search query.
|
||||
- Results are displayed in associated page /gcse2 (using <gcse:searchresults-only> )
|
||||
|
||||
# Settings
|
||||
- edit the `site/modules/google_search_20/config/google_search_20.json` file, and set the value `gcse.search_engine_id`.
|
||||
|
||||
# How to get a Custom Search engine ID?
|
||||
- See https://support.google.com/customsearch/answer/2649143?hl=en
|
||||
- https://cse.google.com/all
|
||||
20
modules/google_search_20/google_search_20-safe.ecf
Normal file
20
modules/google_search_20/google_search_20-safe.ecf
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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="google_search_20" uuid="3FAAD593-3428-43B9-8CE1-BC6E5FE81F19" library_target="google_search_20">
|
||||
<target name="google_search_20">
|
||||
<root all_classes="true"/>
|
||||
<capability>
|
||||
<concurrency support="scoop" use="scoop"/>
|
||||
</capability>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="..\..\library\app_env\app_env-safe.ecf" readonly="false"/>
|
||||
<library name="cms_config" location="..\..\library\configuration\config-safe.ecf"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
19
modules/google_search_20/google_search_20.ecf
Normal file
19
modules/google_search_20/google_search_20.ecf
Normal file
@@ -0,0 +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="google_search" uuid="3FAAD593-3428-43B9-8CE1-BC6E5FE81F19" library_target="google_search_20">
|
||||
<target name="google_search_20">
|
||||
<root all_classes="true"/>
|
||||
<option is_attached_by_default="false" void_safety="none">
|
||||
</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"/>
|
||||
<library name="cms_config" location="..\..\library\configuration\config.ecf"/>
|
||||
<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="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<cluster name="src" location="src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"gcse": {
|
||||
"search_engine_id":""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<form action="{$site_url/}gcse20" class="search-form" id="search-form">
|
||||
<div class="form-group has-feedback">
|
||||
<input type="search" class="form-control" name="q" id="search-query" placeholder="search" value="{htmlentities}{$cms_search_query/}{/htmlentities}" >
|
||||
<span class="glyphicon glyphicon-search form-control-feedback"></span>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,7 @@
|
||||
<section>
|
||||
<header>
|
||||
<h2>Results for <kbd>{$cms_search_query/}</kbd></h2>
|
||||
</header>
|
||||
|
||||
<gcse:searchresults-only></gcse:searchresults-only>
|
||||
</section>
|
||||
156
modules/google_search_20/src/google_custom_search_module_20.e
Normal file
156
modules/google_search_20/src/google_custom_search_module_20.e
Normal file
@@ -0,0 +1,156 @@
|
||||
note
|
||||
description: "[
|
||||
Module providing Google Custom Search functionality.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
GOOGLE_CUSTOM_SEARCH_MODULE_20
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
redefine
|
||||
setup_hooks
|
||||
end
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_BLOCK_HELPER
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create current module
|
||||
do
|
||||
version := "2.0"
|
||||
description := "Google custome search module 2.0"
|
||||
package := "search"
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "google_search_20"
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Router
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- Router configuration.
|
||||
local
|
||||
m: WSF_URI_MAPPING
|
||||
do
|
||||
create m.make_trailing_slash_ignored ("/gcse20", create {WSF_URI_AGENT_HANDLER}.make (agent handle_search (a_api, ?, ?)))
|
||||
a_router.map (m, a_router.methods_head_get)
|
||||
end
|
||||
|
||||
feature -- GCSE Keys
|
||||
|
||||
gcse_cx_key (api: CMS_API): detachable READABLE_STRING_8
|
||||
-- Get google custom search engine id.
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
if attached api.module_configuration (Current, Void) as cfg then
|
||||
if
|
||||
attached cfg.text_item ("gcse.search_engine_id") as l_gcse_cx_key and then
|
||||
not l_gcse_cx_key.is_empty
|
||||
then
|
||||
Result := utf.utf_32_string_to_utf_8_string_8 (l_gcse_cx_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Handler
|
||||
|
||||
handle_search (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_script: STRING
|
||||
b: CMS_CONTENT_BLOCK
|
||||
do
|
||||
write_debug_log (generator + ".handle_search")
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if
|
||||
attached {WSF_STRING} req.query_parameter ("q") as l_query and then
|
||||
not l_query.value.is_empty
|
||||
then
|
||||
if
|
||||
attached gcse_cx_key (api) as l_cx
|
||||
then
|
||||
r.set_value (l_query.value, "cms_search_query")
|
||||
if
|
||||
attached smarty_template_block (Current, "gcse_search_results", api) as l_tpl_block
|
||||
then
|
||||
r.add_block (l_tpl_block, "content")
|
||||
|
||||
if attached gcse_cx_key (api) as l_ctx then
|
||||
create l_script.make_from_string (gcse_20_script)
|
||||
l_script.replace_substring_all ("#CX_VALUE", l_ctx)
|
||||
create b.make_raw ("gcse2_js", Void, "<script>%N" + l_script + "%N</script>", Void)
|
||||
r.add_block (b, "footer")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
r.add_message ("No query submitted", Void)
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
setup_hooks (a_hooks: CMS_HOOK_CORE_MANAGER)
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
auto_subscribe_to_hooks (a_hooks)
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
do
|
||||
Result := <<"gcse_search_form">>
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_block_id.is_case_insensitive_equal_general ("gcse_search_form") then
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached smarty_template_block (Current, a_block_id, a_response.api) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "search")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
gcse_20_script: STRING = "[
|
||||
(function() {
|
||||
var cx = '#CX_VALUE';
|
||||
var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;
|
||||
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//www.google.com/cse/cse.js?cx=' + cx;
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(gcse, s);
|
||||
})();
|
||||
]"
|
||||
end
|
||||
@@ -57,6 +57,18 @@ feature -- Settings
|
||||
session_max_age: INTEGER
|
||||
-- Value of the Max-Age, before the cookie expires.
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_authenticating (a_response: CMS_RESPONSE): BOOLEAN
|
||||
do
|
||||
if
|
||||
a_response.is_authenticated and then
|
||||
attached a_response.request.cookie (session_token)
|
||||
then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
user_by_session_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
@@ -71,6 +83,47 @@ feature -- Access
|
||||
Result := session_auth_storage.has_user_token (a_user)
|
||||
end
|
||||
|
||||
feature -- Basic operation
|
||||
|
||||
process_user_login (a_user: CMS_USER; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_token: STRING
|
||||
l_cookie: WSF_COOKIE
|
||||
do
|
||||
l_token := new_session_token
|
||||
if has_user_token (a_user) then
|
||||
update_user_session_auth (l_token, a_user)
|
||||
else
|
||||
new_user_session_auth (l_token, a_user)
|
||||
end
|
||||
create l_cookie.make (session_token, l_token)
|
||||
l_cookie.set_max_age (session_max_age)
|
||||
l_cookie.set_path ("/")
|
||||
res.add_cookie (l_cookie)
|
||||
cms_api.set_user (a_user)
|
||||
cms_api.record_user_login (a_user)
|
||||
end
|
||||
|
||||
process_user_logout (a_user: CMS_USER; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
l_cookie: WSF_COOKIE
|
||||
do
|
||||
if
|
||||
attached session_token as tok and then
|
||||
attached {WSF_STRING} req.cookie (tok) as l_cookie_token
|
||||
then
|
||||
-- Logout Session
|
||||
create l_cookie.make (tok, "") -- l_cookie_token.value) -- FIXME: unicode issue?
|
||||
l_cookie.set_path ("/")
|
||||
l_cookie.unset_max_age
|
||||
l_cookie.set_expiration_date (create {DATE_TIME}.make_from_epoch (0))
|
||||
res.add_cookie (l_cookie)
|
||||
else
|
||||
-- it seems the user was not login, as there is no associated cookie!
|
||||
end
|
||||
cms_api.unset_user
|
||||
end
|
||||
|
||||
feature -- Change User session
|
||||
|
||||
new_user_session_auth (a_token: READABLE_STRING_GENERAL; a_user: CMS_USER;)
|
||||
@@ -86,4 +139,26 @@ feature -- Change User session
|
||||
session_auth_storage.update_user_session_auth (a_token, a_user)
|
||||
end
|
||||
|
||||
feature -- Token
|
||||
|
||||
new_session_token: STRING
|
||||
-- Generate token to use in a Session.
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: CMS_TOKEN_GENERATOR
|
||||
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
|
||||
|
||||
@@ -100,11 +100,9 @@ feature -- Access: auth strategy
|
||||
-- <Precursor>
|
||||
do
|
||||
if
|
||||
a_response.is_authenticated and then
|
||||
attached session_api as l_session_api and then
|
||||
attached a_response.request.cookie (l_session_api.session_token)
|
||||
attached session_api as l_session_api
|
||||
then
|
||||
Result := True
|
||||
Result := l_session_api.is_authenticating (a_response)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -116,7 +114,7 @@ feature -- Access: router
|
||||
if attached session_api as l_session_api then
|
||||
a_router.handle ("/" + login_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/" + logout_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, l_session_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/" + login_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_with_session (a_api,session_api, ?, ?)), a_router.methods_post)
|
||||
a_router.handle ("/" + login_location, create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_with_session (a_api, l_session_api, ?, ?)), a_router.methods_post)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -164,39 +162,33 @@ feature {NONE} -- Implementation: routes
|
||||
handle_logout (api: CMS_API; a_session_api: CMS_SESSION_API ; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_cookie: WSF_COOKIE
|
||||
tok: STRING
|
||||
do
|
||||
tok := a_session_api.session_token
|
||||
if
|
||||
attached {WSF_STRING} req.cookie (tok) as l_cookie_token and then
|
||||
attached api.user as l_user
|
||||
then
|
||||
-- Logout Session
|
||||
create l_cookie.make (tok, "") -- l_cookie_token.value) -- FIXME: unicode issue?
|
||||
l_cookie.set_path ("/")
|
||||
l_cookie.unset_max_age
|
||||
l_cookie.set_expiration_date (create {DATE_TIME}.make_from_epoch (0))
|
||||
res.add_cookie (l_cookie)
|
||||
api.unset_user
|
||||
|
||||
if attached api.user as l_user then
|
||||
a_session_api.process_user_logout (l_user, req, res)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
else
|
||||
-- Not loggued in ... redirect to home
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
r.execute
|
||||
else
|
||||
fixme (generator + ": missing else implementation in handle_logout!")
|
||||
end
|
||||
if
|
||||
attached {WSF_STRING} req.item ("destination") as p_destination and then
|
||||
attached p_destination.value as v and then
|
||||
v.is_valid_as_string_8
|
||||
then
|
||||
r.set_redirection (v.to_string_8)
|
||||
else
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
end
|
||||
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_login_with_session (api: CMS_API; a_session_api: detachable CMS_SESSION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
handle_login_with_session (api: CMS_API; a_session_api: CMS_SESSION_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_token: STRING
|
||||
l_cookie: WSF_COOKIE
|
||||
do
|
||||
if
|
||||
attached a_session_api as l_session_api and then
|
||||
attached {WSF_STRING} req.form_parameter ("username") as l_username and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password
|
||||
then
|
||||
@@ -204,18 +196,7 @@ feature {NONE} -- Implementation: routes
|
||||
api.user_api.is_valid_credential (l_username.value, l_password.value) and then
|
||||
attached api.user_api.user_by_name (l_username.value) as l_user
|
||||
then
|
||||
l_token := generate_token
|
||||
if a_session_api.has_user_token (l_user) then
|
||||
l_session_api.update_user_session_auth (l_token, l_user)
|
||||
else
|
||||
l_session_api.new_user_session_auth (l_token, l_user)
|
||||
end
|
||||
create l_cookie.make (a_session_api.session_token, l_token)
|
||||
l_cookie.set_max_age (a_session_api.session_max_age)
|
||||
l_cookie.set_path ("/")
|
||||
res.add_cookie (l_cookie)
|
||||
api.set_user (l_user)
|
||||
api.record_user_login (l_user)
|
||||
a_session_api.process_user_login (l_user, req, res)
|
||||
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if
|
||||
@@ -295,23 +276,4 @@ feature {NONE} -- Block views
|
||||
end
|
||||
end
|
||||
|
||||
generate_token: STRING
|
||||
-- Generate token to use in a Session.
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: CMS_TOKEN_GENERATOR
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user