diff --git a/modules/admin/cms_admin_module.e b/modules/admin/cms_admin_module.e index 77bc140..fc0c808 100644 --- a/modules/admin/cms_admin_module.e +++ b/modules/admin/cms_admin_module.e @@ -60,6 +60,7 @@ feature -- Access: router l_admin_cache_handler: CMS_ADMIN_CACHE_HANDLER l_admin_export_handler: CMS_ADMIN_EXPORT_HANDLER l_admin_import_handler: CMS_ADMIN_IMPORT_HANDLER + l_admin_path_alias_handler: CMS_ADMIN_PATH_ALIAS_HANDLER l_uri_mapping: WSF_URI_MAPPING do @@ -83,6 +84,10 @@ feature -- Access: router create l_uri_mapping.make_trailing_slash_ignored ("/admin/logs", l_admin_logs_handler) a_router.map (l_uri_mapping, a_router.methods_get) + create l_admin_path_alias_handler.make (a_api) + create l_uri_mapping.make_trailing_slash_ignored ("/admin/path_alias", l_admin_path_alias_handler) + a_router.map (l_uri_mapping, a_router.methods_get_post) + create l_admin_cache_handler.make (a_api) create l_uri_mapping.make_trailing_slash_ignored ("/admin/cache", l_admin_cache_handler) @@ -119,14 +124,10 @@ feature -- Security Result.force ("admin users") Result.force ("admin roles") Result.force ("admin modules") - Result.force ("install modules") - Result.force ("view logs") Result.force ("admin core caches") Result.force ("clear blocks cache") Result.force ("admin export") Result.force ("admin import") - Result.force ("export core") - Result.force ("import core") end feature -- Hooks diff --git a/modules/admin/handler/cms_admin_path_alias_handler.e b/modules/admin/handler/cms_admin_path_alias_handler.e new file mode 100644 index 0000000..9d740f2 --- /dev/null +++ b/modules/admin/handler/cms_admin_path_alias_handler.e @@ -0,0 +1,124 @@ +note + description: "[ + Administrate path aliases. + ]" + date: "$Date$" + revision: "$Revision$" + +class + CMS_ADMIN_PATH_ALIAS_HANDLER + +inherit + CMS_HANDLER + + WSF_URI_HANDLER + rename + new_mapping as new_uri_mapping + end + + WSF_RESOURCE_HANDLER_HELPER + redefine + do_get, + do_post + end + + REFACTORING_HELPER + +create + make + +feature -- Execution + + execute (req: WSF_REQUEST; res: WSF_RESPONSE) + -- Execute request handler + do + execute_methods (req, res) + end + + do_get (req: WSF_REQUEST; res: WSF_RESPONSE) + local + l_response: CMS_RESPONSE + l_sources: ARRAYED_LIST [READABLE_STRING_8] + l_alias: detachable READABLE_STRING_8 + s: STRING + b: BOOLEAN + do + if api.has_permission ("admin path_alias") then + create {GENERIC_VIEW_CMS_RESPONSE} l_response.make (req, res, api) + if attached api.storage.path_aliases as tb then + create s.make_empty + s.append ("
Back to list of path aliases ...
") + s.append ("(in 3 seconds...)") + l_response.set_main_content (s) + + l_response.set_redirection (l_response.location) + l_response.set_redirection_delay (3) + else + create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api) + l_response.set_redirection (l_response.location) + end + l_response.execute + end + +end diff --git a/modules/admin/handler/cms_admin_response.e b/modules/admin/handler/cms_admin_response.e index ad4f6a9..b9dbbb1 100644 --- a/modules/admin/handler/cms_admin_response.e +++ b/modules/admin/handler/cms_admin_response.e @@ -27,9 +27,10 @@ feature -- Process l_admin_links.force (["core", <<"admin roles">>, local_link ("Roles", "admin/roles"), "View/Edit/Add Roles"]) l_admin_links.force (["core", <<"admin modules">>, local_link ("Modules", "admin/modules"), "(un)Install modules"]) l_admin_links.force (["core", <<"view logs">>, local_link ("Logs", "admin/logs"), "View logs"]) + l_admin_links.force (["core", <<"admin path_alias">>, local_link ("Path Alias", "admin/path_alias"), "Manage path aliases"]) l_admin_links.force (["support", <<"admin cache">>, local_link ("Cache", "admin/cache"), "Clear caches"]) l_admin_links.force (["support", <<"admin export">>, local_link ("Export", "admin/export"), "Export CMS contents, and modules contents."]) - l_admin_links.force (["support", <<"admin import">>, local_link ("Export", "admin/import"), "Import CMS contents, and modules contents."]) + l_admin_links.force (["support", <<"admin import">>, local_link ("Import", "admin/import"), "Import CMS contents, and modules contents."]) create categories.make_caseless (3) across l_admin_links as ic diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index a87dc08..fbcd551 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -151,6 +151,10 @@ feature -- Forms ... end end(?, response, a_node) ) + if not cms_api.has_permission ("edit path_alias") then + -- FIXME: should we have an input field or just a raw text? + ti.set_is_readonly (True) + end if attached f.fields_by_name ("title") as l_title_fields and then attached l_title_fields.first as l_title_field diff --git a/modules/node/handler/node_form_response.e b/modules/node/handler/node_form_response.e index 74b3601..e1c750c 100644 --- a/modules/node/handler/node_form_response.e +++ b/modules/node/handler/node_form_response.e @@ -253,7 +253,8 @@ feature -- Form l_preview: BOOLEAN l_node: detachable CMS_NODE s: STRING - l_path_alias: detachable READABLE_STRING_8 + l_node_path: READABLE_STRING_8 + l_path_alias, l_existing_path_alias: detachable READABLE_STRING_8 do fixme ("Refactor code per operacion: Preview, Save") l_preview := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Preview") @@ -301,14 +302,34 @@ feature -- Form add_success_message ("Node #" + l_node.id.out + " saved.") end - if - attached fd.string_item ("path_alias") as f_path_alias and then - not f_path_alias.is_empty - then + if attached fd.string_item ("path_alias") as f_path_alias then + l_node_path := node_api.node_path (l_node) l_path_alias := percent_encoder.partial_encoded_string (f_path_alias, <<'/'>>) - -- Path alias, are always from the root of the cms. - api.set_path_alias (node_api.node_path (l_node), l_path_alias, False) - l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_path_alias)) + l_existing_path_alias := api.location_alias (l_node_path) + if + l_existing_path_alias /= Void and then + l_path_alias.same_string (l_existing_path_alias) + then + -- Same path alias + l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_path_alias)) + elseif l_existing_path_alias /= Void and then l_path_alias.is_whitespace then + -- Reset to builtin alias. + if api.has_permission ("edit path_alias") then + api.set_path_alias (l_node_path, l_node_path, True) + else + add_error_message ("Permission denied to reset path alias on node #" + l_node.id.out + "!") + end + l_node.set_link (node_api.node_link (l_node)) + else + if api.has_permission ("edit path_alias") then + -- Path alias, are always from the root of the cms. + api.set_path_alias (l_node_path, l_path_alias, True) + l_node.set_link (create {CMS_LOCAL_LINK}.make (l_node.title, l_path_alias)) + else + add_error_message ("Permission denied to set path alias on node #" + l_node.id.out + "!") + l_node.set_link (node_api.node_link (l_node)) + end + end else l_node.set_link (node_api.node_link (l_node)) end diff --git a/src/modules/cms_core_module.e b/src/modules/cms_core_module.e index 1a6dafb..bd65886 100644 --- a/src/modules/cms_core_module.e +++ b/src/modules/cms_core_module.e @@ -10,7 +10,8 @@ inherit CMS_MODULE redefine initialize, - install + install, + permissions end create @@ -102,6 +103,20 @@ feature -- Router do end +feature -- Security + + permissions: LIST [READABLE_STRING_8] + -- List of permission ids, used by this module, and declared. + do + Result := Precursor + Result.force ("install modules") + Result.force ("view logs") + Result.force ("export core") + Result.force ("import core") + Result.force ("admin path_alias") + Result.force ("edit path_alias") + end + note copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" diff --git a/src/persistence/core/cms_core_storage_sql_i.e b/src/persistence/core/cms_core_storage_sql_i.e index f6a475f..1329cd3 100644 --- a/src/persistence/core/cms_core_storage_sql_i.e +++ b/src/persistence/core/cms_core_storage_sql_i.e @@ -153,7 +153,7 @@ feature -- URL aliases sql_finalize end - sql_select_all_path_alias: STRING = "SELECT source, alias, lang FROM path_aliases;" + sql_select_all_path_alias: STRING = "SELECT source, alias, lang FROM path_aliases ORDER BY pid DESC;" -- SQL select all path aliases. sql_select_path_alias: STRING = "SELECT source FROM path_aliases WHERE alias=:alias ;" @@ -411,6 +411,6 @@ feature -- Misc note - copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end