diff --git a/examples/demo/modules/demo/cms_demo_module.e b/examples/demo/modules/demo/cms_demo_module.e index 85cb11f..023e6e1 100644 --- a/examples/demo/modules/demo/cms_demo_module.e +++ b/examples/demo/modules/demo/cms_demo_module.e @@ -140,7 +140,7 @@ feature -- Handler r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE do create r.make (req, res, a_api) - r.set_main_content ("DEMO module does not yet implement %"" + req.path_info + "%" ...") + r.set_main_content ("DEMO module does not yet implement %"" + req.percent_encoded_path_info + "%" ...") r.add_error_message ("DEMO Module: not yet implemented") r.execute end diff --git a/examples/demo/site/config/cms.ini b/examples/demo/site/config/cms.ini index 439ddcb..1c611b5 100644 --- a/examples/demo/site/config/cms.ini +++ b/examples/demo/site/config/cms.ini @@ -21,6 +21,7 @@ smtp=localhost:25 # for each module, this can be overwritten with # module_name= on or off *=off +admin=on auth=on basic_auth=on blog=on diff --git a/library/model/src/link/cms_link.e b/library/model/src/link/cms_link.e index 7906d70..4f981a8 100644 --- a/library/model/src/link/cms_link.e +++ b/library/model/src/link/cms_link.e @@ -49,7 +49,7 @@ feature -- Comparison end end -feature -- status report +feature -- Status report is_active: BOOLEAN -- Is current link active? @@ -79,6 +79,14 @@ feature -- status report deferred end +feature -- Security + + is_forbidden: BOOLEAN + -- Is Current link forbidden? + -- Current link could be disabled for current CMS user. + deferred + end + feature -- Element change set_weight (a_weight: INTEGER) diff --git a/library/model/src/link/cms_local_link.e b/library/model/src/link/cms_local_link.e index 146d6f7..09fa2fc 100644 --- a/library/model/src/link/cms_local_link.e +++ b/library/model/src/link/cms_local_link.e @@ -71,6 +71,12 @@ feature -- Status report Result := attached children as l_children and then not l_children.is_empty end +feature -- Security + + is_forbidden: BOOLEAN + -- + -- Related to `permission_arguments' values. + feature -- Element change set_title (a_title: detachable READABLE_STRING_GENERAL) @@ -167,6 +173,16 @@ feature -- Status change is_expandable: is_expandable = b end +feature -- Security change + + set_is_forbidden (b: BOOLEAN) + -- Set `is_forbidden' to `b'. + do + is_forbidden := b + ensure + is_forbidden: is_forbidden = b + end + feature {NONE} -- Implementation internal_is_expandable: BOOLEAN diff --git a/modules/admin/cms_admin_module.e b/modules/admin/cms_admin_module.e index 0245b9f..552538e 100644 --- a/modules/admin/cms_admin_module.e +++ b/modules/admin/cms_admin_module.e @@ -1,5 +1,5 @@ note - description: "Summary description for {CMS_ADMIN_MODULE}." + description: "CMS module providing Administration support (back-end)." date: "$Date$" revision: "$Revision$" @@ -7,7 +7,6 @@ class CMS_ADMIN_MODULE inherit - CMS_MODULE redefine register_hooks @@ -17,9 +16,7 @@ inherit CMS_HOOK_RESPONSE_ALTER - CMS_HOOK_BLOCK - - CMS_REQUEST_UTIL +-- CMS_REQUEST_UTIL create make @@ -94,7 +91,6 @@ feature -- Hooks -- do a_response.subscribe_to_menu_system_alter_hook (Current) - a_response.subscribe_to_block_hook (Current) a_response.subscribe_to_response_alter_hook (Current) end @@ -104,29 +100,16 @@ feature -- Hooks a_response.add_style (a_response.url ("/module/" + name + "/files/css/admin.css", Void), Void) end - block_list: ITERABLE [like {CMS_BLOCK}.name] - -- - do - Result := <<"admin-info">> - end - - get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) - local --- b: CMS_CONTENT_BLOCK - do --- create b.make (a_block_id, "Block::node", "This is a block test", Void) --- a_response.add_block (b, "sidebar_second") - end - menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) local lnk: CMS_LOCAL_LINK do if - attached current_user (a_response.request) as l_user and then - a_response.api.user_api.is_admin_user (l_user) + a_response.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) -- Note: admin user has all permissions enabled by default. then + -- TODO: we should probably use more side menu and less primary_menu. create lnk.make ("Admin", "admin") + lnk.set_permission_arguments (<<"manage " + {CMS_ADMIN_MODULE}.name>>) a_menu_system.primary_menu.extend (lnk) end end diff --git a/modules/admin/handler/cms_admin_handler.e b/modules/admin/handler/cms_admin_handler.e index d6036f4..49d123b 100644 --- a/modules/admin/handler/cms_admin_handler.e +++ b/modules/admin/handler/cms_admin_handler.e @@ -3,7 +3,7 @@ note handler for CMS admin in the CMS interface. TODO: implement REST API. - ]" author: "" + ]" date: "$Date$" revision: "$Revision$" @@ -11,7 +11,6 @@ class CMS_ADMIN_HANDLER inherit - CMS_HANDLER WSF_URI_HANDLER @@ -59,7 +58,6 @@ feature -- execute execute (req, res) end - feature -- HTTP Methods do_get (req: WSF_REQUEST; res: WSF_RESPONSE) diff --git a/modules/admin/handler/cms_admin_response.e b/modules/admin/handler/cms_admin_response.e index cd77a2f..113ca54 100644 --- a/modules/admin/handler/cms_admin_response.e +++ b/modules/admin/handler/cms_admin_response.e @@ -7,12 +7,10 @@ class CMS_ADMIN_RESPONSE inherit - CMS_RESPONSE redefine make, - initialize, - custom_prepare + initialize end create @@ -56,186 +54,4 @@ feature -- Process set_main_content (b) end -feature -- Generation - - custom_prepare (page: CMS_HTML_PAGE) - do - if attached variables as l_variables then - across l_variables as c loop page.register_variable (c.item, c.key) end - end - end - -feature -- Admin: Add User Form - - handle_admin_user_form - local - s: STRING - f: CMS_FORM - t: WSF_FORM_TEXT_INPUT - fe: WSF_FORM_EMAIL_INPUT - fs: WSF_FORM_FIELD_SET - f_submit: WSF_FORM_SUBMIT_INPUT - do - - create f.make (request.percent_encoded_path_info, {CMS_ADMIN_MODULE}.name ) - create fs.make - fs.set_legend ("Create new user without password:") - create t.make_with_text ("username", "") - t.set_label ("User name") - t.enable_required - t.set_placeholder ("username") - fs.extend (t) - - create fe.make_with_text ("email", "") - fe.set_label ("Email") - fe.set_placeholder ("valid email") - fs.extend (fe) - create f_submit.make_with_text ("op", "Create user") - fs.extend (f_submit) - create f_submit.make_with_text ("op", "Update user") - fs.extend (f_submit) - f.extend (fs) - - if request.is_post_request_method then - create s.make_empty - f.validation_actions.extend (agent (fd: WSF_FORM_DATA; ia_api: CMS_API) - do - if attached fd.string_item ("op") as f_op then - if f_op.is_case_insensitive_equal_general ("Create user") then - if attached fd.string_item ("username") as l_username then - if attached ia_api.user_api.user_by_name (l_username) then - fd.report_invalid_field ("username", "Username already taken!") - end - else - fd.report_invalid_field ("username", "missing username") - end - if attached fd.string_item ("email") as l_email then - if attached ia_api.user_api.user_by_email (l_email) then - fd.report_invalid_field ("email", "Email address already associated with an existing account!") - end - else - fd.report_invalid_field ("email", "missing email address") - end - elseif f_op.is_case_insensitive_equal_general ("Update user") then - if attached fd.string_item ("username") as l_username then - if ia_api.user_api.user_by_name (l_username) = Void then - fd.report_invalid_field ("username", "Username does not exist!") - end - else - fd.report_invalid_field ("username", "missing username") - end - end - end - end(?, api) - ) - f.submit_actions.extend (agent (fd: WSF_FORM_DATA; ia_api: CMS_API; a_output: STRING) - local - u: CMS_USER - l_roles: detachable LIST [CMS_USER_ROLE] - l_trusted_user_role: detachable CMS_USER_ROLE - do - if attached fd.string_item ("op") as f_op then - if f_op.is_case_insensitive_equal_general ("Create user") then - if - attached fd.string_item ("username") as l_username and then - attached fd.string_item ("email") as l_email and then - l_email.is_valid_as_string_8 - then - create u.make (l_username) - u.set_email (l_email.as_string_8) - u.set_password (new_random_password (u)) - ia_api.user_api.new_user (u) - if ia_api.user_api.has_error then - - end - a_output.append ("
  • New user ["+ html_encoded (l_username) +"] created.
  • ") - else - fd.report_invalid_field ("username", "Missing username!") - fd.report_invalid_field ("email", "Missing email address!") - end - elseif f_op.is_case_insensitive_equal_general ("Update user") then - if - attached fd.string_item ("username") as l_username and then - attached ia_api.user_api.user_by_name (l_username) as l_user - then - l_trusted_user_role := ia_api.user_api.user_role_by_name ("trusted") - if l_trusted_user_role = Void then - create l_trusted_user_role.make ("trusted") - ia_api.user_api.save_user_role (l_trusted_user_role) - end - - l_trusted_user_role.add_permission ("admin wdocs") - l_trusted_user_role.add_permission ("edit wdocs page") - l_trusted_user_role.add_permission ("create wdocs page") - l_trusted_user_role.add_permission ("delete wdocs page") - l_trusted_user_role.add_permission ("edit any wdocs page") - l_trusted_user_role.add_permission ("delete any wdocs page") - l_trusted_user_role.add_permission ("clear wdocs cache") - - l_trusted_user_role.add_permission ("create page") - l_trusted_user_role.add_permission ("edit any page") - l_trusted_user_role.add_permission ("delete any page") - l_trusted_user_role.add_permission ("create blog") - l_trusted_user_role.add_permission ("edit any blog") - l_trusted_user_role.add_permission ("delete any blog") - - l_trusted_user_role.add_permission ("edit any node") - l_trusted_user_role.add_permission ("delete any node") - - - ia_api.user_api.save_user_role (l_trusted_user_role) - l_trusted_user_role := ia_api.user_api.user_role_by_name ("trusted") - if l_trusted_user_role /= Void then - u := l_user - ia_api.user_api.update_user (u) - l_roles := u.roles - if l_roles = Void then - create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (1) - end - l_roles.force (l_trusted_user_role) - u.set_roles (l_roles) - - ia_api.user_api.update_user (u) - a_output.append ("
  • User ["+ html_encoded (l_username) +"] updated.
  • ") - else - a_output.append ("
  • User ["+ html_encoded (l_username) +"] NOT updated! [ERROR].
  • ") - end - else - fd.report_invalid_field ("username", "User does not exist!") - end - end - end - end(?, api, s) - ) - - f.process (Current) - f.append_to_html (create {CMS_TO_WSF_THEME}.make (Current, Current.theme), s) - Current.set_main_content (s) - elseif request.is_get_head_request_method then - create s.make_empty - f.append_to_html (create {CMS_TO_WSF_THEME}.make (Current, Current.theme), s) - Current.set_main_content (s) - end - end - - - new_random_password (u: CMS_USER): STRING - -- Generate a new token activation token - local - l_token: STRING - l_security: SECURITY_PROVIDER - l_encode: URL_ENCODER - do - create l_security - l_token := l_security.token - create l_encode - from until l_token.same_string (l_encode.encoded_string (l_token)) loop - -- Loop ensure that we have a security token that does not contain characters that need encoding. - -- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token - -- but the user will need to use an unencoded token if activation has to be done manually. - l_token := l_security.token - end - Result := l_token + url_encoded (u.name) + u.creation_date.out - end - end diff --git a/modules/admin/handler/role/cms_admin_roles_handler.e b/modules/admin/handler/role/cms_admin_roles_handler.e index 0b05499..ed68867 100644 --- a/modules/admin/handler/role/cms_admin_roles_handler.e +++ b/modules/admin/handler/role/cms_admin_roles_handler.e @@ -83,7 +83,6 @@ feature -- HTTP Methods l_response.set_title ("Listing " + l_count.out + " Role") end - if attached user_api.roles as lst then s.append ("
      %N") across @@ -92,7 +91,7 @@ feature -- HTTP Methods u := ic.item s.append ("
    • ") s.append ("") s.append (u.name) s.append ("") diff --git a/modules/admin/handler/role/cms_role_form_response.e b/modules/admin/handler/role/cms_role_form_response.e index 2c7b562..9bebafa 100644 --- a/modules/admin/handler/role/cms_role_form_response.e +++ b/modules/admin/handler/role/cms_role_form_response.e @@ -7,12 +7,10 @@ class CMS_ROLE_FORM_RESPONSE inherit - CMS_RESPONSE redefine make, - initialize, - custom_prepare + initialize end create @@ -64,9 +62,9 @@ feature -- Process if uid > 0 and then attached user_api.user_role_by_id (uid.to_integer) as l_role then fixme ("Issues with WSD_FORM_DATA.apply_to_associated_form") -- if we have a WSF_FORM_CHECKBOK_INPUT, cheked inputs, are not preserverd in case of error. - if request.path_info.ends_with_general ("/edit") then + if location.ends_with_general ("/edit") then edit_form (l_role) - elseif request.path_info.ends_with_general ("/delete") then + elseif location.ends_with_general ("/delete") then delete_form (l_role) end else @@ -83,7 +81,7 @@ feature -- Process Edit fd: detachable WSF_FORM_DATA do create b.make_empty - f := new_edit_form (a_role, url (request.path_info, Void), "edit-user") + f := new_edit_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user") invoke_form_alter (f, fd) if request.is_post_request_method then f.validation_actions.extend (agent edit_form_validate(?,a_role, b)) @@ -116,7 +114,7 @@ feature -- Process Delete fd: detachable WSF_FORM_DATA do create b.make_empty - f := new_delete_form (a_role, url (request.path_info, Void), "edit-user") + f := new_delete_form (a_role, url (request.percent_encoded_path_info, Void), "edit-user") invoke_form_alter (f, fd) if request.is_post_request_method then f.process (Current) @@ -148,7 +146,7 @@ feature -- Process New l_role: detachable CMS_USER_ROLE do create b.make_empty - f := new_edit_form (l_role, url (request.path_info, Void), "create-role") + f := new_edit_form (l_role, url (request.percent_encoded_path_info, Void), "create-role") invoke_form_alter (f, fd) if request.is_post_request_method then f.validation_actions.extend (agent new_form_validate(?, b)) @@ -177,9 +175,6 @@ feature -- Form local l_save_role: BOOLEAN l_update_role: BOOLEAN - l_role: detachable CMS_USER_ROLE - s: STRING - lnk: CMS_LINK do l_save_role := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Create role") if l_save_role then @@ -195,24 +190,25 @@ feature -- Form end end create_role (fd) - end - l_update_role := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update role") - if l_update_role then - debug ("cms") - across - fd as c - loop - b.append ("
    • " + html_encoded (c.key) + "=") - if attached c.item as v then - b.append (html_encoded (v.string_representation)) + else + l_update_role := attached {WSF_STRING} fd.item ("op") as l_op and then l_op.same_string ("Update role") + if l_update_role then + debug ("cms") + across + fd as c + loop + b.append ("
    • " + html_encoded (c.key) + "=") + if attached c.item as v then + b.append (html_encoded (v.string_representation)) + end + b.append ("
    • ") end - b.append ("") end - end - if attached a_role as u_role then - update_role (fd, u_role) - else - fd.report_error ("Missing Role") + if a_role /= Void then + update_role (fd, a_role) + else + fd.report_error ("Missing Role") + end end end end @@ -233,19 +229,18 @@ feature -- Form fd.report_invalid_field ("role", "missing role") end end - if attached {WSF_TABLE} fd.item ("cms_perm[]") as l_perm then + if attached {WSF_TABLE} fd.item ("new_cms_permissions[]") as l_perm then a_role.permissions.compare_objects - from - l_perm.values.start - until - l_perm.values.after + across + l_perm.values as ic loop - if attached {WSF_STRING} l_perm.value (l_perm.values.key_for_iteration) as l_value then - if a_role.permissions.has (l_value.value) then - fd.report_invalid_field ("cms_perm[]", "Permission " + l_value.value + " already taken!") + if attached {WSF_STRING} ic.item as p then + if not p.value.is_valid_as_string_8 then + fd.report_invalid_field ("new_cms_permissions[]", "Permission " + p.value + " should not have any unicode character!") + elseif across a_role.permissions as p_ic some p_ic.item.is_case_insensitive_equal_general (p.value) end then + fd.report_invalid_field ("new_cms_permissions[]", "Permission " + p.value + " already exists!") end end - l_perm.values.forth end end end @@ -286,7 +281,7 @@ feature -- Form end new_delete_form (a_role: detachable CMS_USER_ROLE; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM - -- Create a web form named `a_name' for node `a_user' (if set), using form action url `a_url'. + -- Create a web form named `a_name' for role `a_role' (if set), using form action url `a_url'. local f: CMS_FORM ts: WSF_FORM_SUBMIT_INPUT @@ -317,11 +312,12 @@ feature -- Form -- and apply this to content type `a_content_type'. local ti: WSF_FORM_TEXT_INPUT - fe: WSF_FORM_EMAIL_INPUT +-- fe: WSF_FORM_EMAIL_INPUT fs: WSF_FORM_FIELD_SET cb: WSF_FORM_CHECKBOX_INPUT ts: WSF_FORM_SUBMIT_INPUT - tb: WSF_FORM_BUTTON_INPUT +-- tb: WSF_FORM_BUTTON_INPUT + l_role_permissions: detachable LIST [READABLE_STRING_8] do if attached a_role as l_role then create fs.make @@ -338,15 +334,19 @@ feature -- Form create fs.make fs.set_legend ("Permissions") - if not l_role.permissions.is_empty then - across l_role.permissions as ic loop + if + attached api.user_api.role_permissions as l_permissions + then + l_role_permissions := l_role.permissions + l_role_permissions.compare_objects + across l_permissions as ic loop create cb.make_with_value ("cms_permissions", ic.item) - cb.set_checked (True) - cb.set_label (ic.item) + cb.set_checked (l_role_permissions.has (ic.item)) + cb.set_title (ic.item) fs.extend (cb) end end - create ti.make ("cms_perm[]") + create ti.make ("new_cms_permissions[]") fs.extend (ti) fs.extend_html_text ("
      ") fs.extend_html_text ("") @@ -379,7 +379,7 @@ feature -- Form update_role (a_form_data: WSF_FORM_DATA; a_role: CMS_USER_ROLE) -- Update node `a_node' with form_data `a_form_data' for the given content type `a_content_type'. local - l_permissions: LIST [READABLE_STRING_8] + l_perm: READABLE_STRING_8 do if attached a_form_data.string_item ("op") as f_op then if f_op.is_case_insensitive_equal_general ("Update role") then @@ -388,45 +388,47 @@ feature -- Form attached a_form_data.string_item ("role-id") as l_role_id and then attached {CMS_USER_ROLE} api.user_api.user_role_by_id (l_role_id.to_integer) as l_role then - l_permissions := a_role.permissions - l_permissions.compare_objects if attached {WSF_STRING} a_form_data.item ("cms_permissions") as u_role then a_role.permissions.wipe_out a_role.add_permission (u_role.value) elseif attached {WSF_MULTIPLE_STRING} a_form_data.item ("cms_permissions") as u_permissions then + a_role.permissions.wipe_out + -- Enable checked permissions. across u_permissions as ic loop - if not l_permissions.has (ic.item.value) then - a_role.remove_permission (ic.item.value) + l_perm := ic.item.value.as_string_8 + if not l_perm.is_whitespace then + a_role.add_permission (l_perm) end end else a_role.permissions.wipe_out end - if attached {WSF_TABLE} a_form_data.item ("cms_perm[]") as l_perm then - a_role.permissions.compare_objects - from - l_perm.values.start - until - l_perm.values.after + if attached {WSF_TABLE} a_form_data.item ("new_cms_permissions[]") as l_cms_perms then + -- Add new permissions as checked. + across + l_cms_perms.values as ic loop - if - attached {WSF_STRING} l_perm.value (l_perm.values.key_for_iteration) as l_value and then - not l_value.value.is_whitespace - then - a_role.add_permission (l_value.value) + if attached {WSF_STRING} ic.item as p then + l_perm := p.value.as_string_8 + if not l_perm.is_whitespace then + a_role.add_permission (l_perm) + end end - l_perm.values.forth end end if not a_form_data.has_error then a_role.set_name (l_role_name) api.user_api.save_user_role (a_role) - add_success_message ("Permissions updated") + if not api.user_api.has_error then + add_success_message ("Permissions updated") + set_redirection (absolute_url ("admin/role/" + a_role.id.out, Void)) + else + add_error_message ("Error during permissions update operation.") + end end - else a_form_data.report_error ("Missing Role") end @@ -457,17 +459,6 @@ feature -- Form feature -- Generation - custom_prepare (page: CMS_HTML_PAGE) - do - if attached variables as l_variables then - across - l_variables as c - loop - page.register_variable (c.item, c.key) - end - end - end - script_add_remove_items: STRING = "[ $(document).ready(function() { var wrapper = $(".input_fields_wrap"); //Fields wrapper @@ -475,7 +466,7 @@ feature -- Generation $(add_button).click(function(e){ //on add input button click e.preventDefault(); - $(wrapper).append('
      Remove
      '); //add input box + $(wrapper).append('
      Remove
      '); //add input box }); $(wrapper).on("click",".remove_field", function(e){ //user click on remove text diff --git a/modules/admin/handler/role/cms_role_handler.e b/modules/admin/handler/role/cms_role_handler.e index d511590..527c555 100644 --- a/modules/admin/handler/role/cms_role_handler.e +++ b/modules/admin/handler/role/cms_role_handler.e @@ -85,12 +85,12 @@ feature -- HTTP Methods do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then - if req.path_info.ends_with_general ("/edit") then - check valid_url: req.path_info.starts_with_general ("/admin/role/") end + if req.percent_encoded_path_info.ends_with_general ("/edit") then + check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/role/") end create edit_response.make (req, res, api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then - check valid_url: req.path_info.starts_with_general ("/admin/role/") end + elseif req.percent_encoded_path_info.ends_with_general ("/delete") then + check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/role/") end create edit_response.make (req, res, api) edit_response.execute else @@ -123,17 +123,17 @@ feature -- HTTP Methods do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then - if req.path_info.ends_with_general ("/edit") then + if req.percent_encoded_path_info.ends_with_general ("/edit") then create edit_response.make (req, res, api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then + elseif req.percent_encoded_path_info.ends_with_general ("/delete") then if attached {WSF_STRING} req.form_parameter ("op") as l_op and then l_op.value.same_string ("Delete") then do_delete (req, res) end - elseif req.path_info.ends_with_general ("/add/role") then + elseif req.percent_encoded_path_info.ends_with_general ("/add/role") then create edit_response.make (req, res, api) edit_response.execute end @@ -150,14 +150,14 @@ feature -- Error l_page: CMS_RESPONSE do create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) - l_page.add_variable (req.absolute_script_url (req.path_info), "request") + l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request") if a_id /= Void and then a_id.is_integer then -- resource not found - l_page.add_variable ("404", "code") + l_page.set_value ("404", "code") l_page.set_status_code (404) else -- bad request - l_page.add_variable ("400", "code") + l_page.set_value ("400", "code") l_page.set_status_code (400) end l_page.execute @@ -192,7 +192,7 @@ feature {NONE} -- New User local edit_response: CMS_ROLE_FORM_RESPONSE do - if req.path_info.starts_with_general ("/admin/add/role") then + if req.percent_encoded_path_info.starts_with_general ("/admin/add/role") then create edit_response.make (req, res, api) edit_response.execute else diff --git a/modules/admin/handler/role/cms_role_view_response.e b/modules/admin/handler/role/cms_role_view_response.e index 5f443d6..53b9038 100644 --- a/modules/admin/handler/role/cms_role_view_response.e +++ b/modules/admin/handler/role/cms_role_view_response.e @@ -72,7 +72,7 @@ feature -- Execution lnk: CMS_LOCAL_LINK s: STRING do - a_response.add_variable (a_role, "role") + a_response.set_value (a_role, "role") create lnk.make (a_response.translation ("View", Void), "admin/role/" + a_role.id.out) lnk.set_is_active (True) lnk.set_weight (1) diff --git a/modules/admin/handler/user/cms_user_form_response.e b/modules/admin/handler/user/cms_user_form_response.e index 2c79de6..b5e85c6 100644 --- a/modules/admin/handler/user/cms_user_form_response.e +++ b/modules/admin/handler/user/cms_user_form_response.e @@ -11,8 +11,7 @@ inherit CMS_RESPONSE redefine make, - initialize, - custom_prepare + initialize end create @@ -66,10 +65,10 @@ feature -- Process attached user_api.user_by_id (uid) as l_user then if - request.path_info.ends_with_general ("/edit") + location.ends_with_general ("/edit") then edit_form (l_user) - elseif request.path_info.ends_with_general ("/delete") then + elseif location.ends_with_general ("/delete") then delete_form (l_user) end else @@ -86,7 +85,7 @@ feature -- Process Edit fd: detachable WSF_FORM_DATA do create b.make_empty - f := new_edit_form (a_user, url (request.path_info, Void), "edit-user") + f := new_edit_form (a_user, url (location, Void), "edit-user") invoke_form_alter (f, fd) if request.is_post_request_method then f.submit_actions.extend (agent edit_form_submit (?, a_user, b)) @@ -118,7 +117,7 @@ feature -- Process Delete fd: detachable WSF_FORM_DATA do create b.make_empty - f := new_delete_form (a_user, url (request.path_info, Void), "edit-user") + f := new_delete_form (a_user, url (location, Void), "edit-user") invoke_form_alter (f, fd) if request.is_post_request_method then f.process (Current) @@ -151,7 +150,7 @@ feature -- Process New l_user: detachable CMS_USER do create b.make_empty - f := new_edit_form (l_user, url (request.path_info, Void), "create-user") + f := new_edit_form (l_user, url (location, Void), "create-user") invoke_form_alter (f, fd) if request.is_post_request_method then f.validation_actions.extend (agent new_form_validate (?, b)) @@ -202,7 +201,7 @@ feature -- Form if a_user /= Void then l_user := a_user if l_user.has_id then - create {CMS_LOCAL_LINK}lnk.make (translation ("View", Void),"admin/user/" + l_user.id.out ) + create {CMS_LOCAL_LINK} lnk.make (translation ("View", Void),"admin/user/" + l_user.id.out ) change_user (fd, a_user) s := "modified" set_redirection (lnk.location) @@ -248,7 +247,7 @@ feature -- Form end - new_edit_form (a_user: detachable CMS_USER; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM + new_edit_form (a_user: detachable CMS_USER; a_url: READABLE_STRING_8; a_name: STRING): CMS_FORM -- Create a web form named `a_name' for uSER `a_YSER' (if set), using form action url `a_url'. local f: CMS_FORM @@ -279,25 +278,25 @@ feature -- Form end else fd.report_invalid_field ("username", "missing username") - end - if attached fd.string_item ("email") as l_email then - if attached api.user_api.user_by_email (l_email) then - fd.report_invalid_field ("email", "Email address already associated with an existing account!") - end - else - fd.report_invalid_field ("email", "missing email address") - end - elseif f_op.is_case_insensitive_equal_general ("Update user") then - if attached fd.string_item ("username") as l_username then - if api.user_api.user_by_name (l_username) = Void then - fd.report_invalid_field ("username", "Username does not exist!") - end - else - fd.report_invalid_field ("username", "missing username") - end - end - end + end + if attached fd.string_item ("email") as l_email then + if attached api.user_api.user_by_email (l_email) then + fd.report_invalid_field ("email", "Email address already associated with an existing account!") end + else + fd.report_invalid_field ("email", "missing email address") + end + elseif f_op.is_case_insensitive_equal_general ("Update user") then + if attached fd.string_item ("username") as l_username then + if api.user_api.user_by_name (l_username) = Void then + fd.report_invalid_field ("username", "Username does not exist!") + end + else + fd.report_invalid_field ("username", "missing username") + end + end + end + end new_delete_form (a_user: detachable CMS_USER; a_url: READABLE_STRING_8; a_name: STRING;): CMS_FORM -- Create a web form named `a_name' for node `a_user' (if set), using form action url `a_url'. @@ -342,13 +341,14 @@ feature -- Form fs: WSF_FORM_FIELD_SET cb: WSF_FORM_CHECKBOX_INPUT ts: WSF_FORM_SUBMIT_INPUT + l_user_roles: detachable LIST [CMS_USER_ROLE] do - if attached a_user as l_user then + if a_user /= Void then create fs.make fs.set_legend ("Basic User Account Information") fs.extend_html_text ("

      ") - fs.extend_html_text (l_user.name) - if attached l_user.email as l_email then + fs.extend_html_text (a_user.name) + if attached a_user.email as l_email then create fe.make_with_text ("email", l_email) else create fe.make_with_text ("email", "") @@ -367,30 +367,18 @@ feature -- Form create fs.make fs.set_legend ("User Roles") - - if attached {LIST[CMS_USER_ROLE]} api.user_api.user_roles (l_user) as u_roles and then - not u_roles.is_empty - then - u_roles.compare_objects - across api.user_api.roles as ic loop - if u_roles.has (ic.item) then - create cb.make_with_value ("cms_roles", ic.item.id.out) - cb.set_checked (True) - cb.set_label (ic.item.name) - fs.extend (cb) - else - create cb.make_with_value ("cms_roles", ic.item.id.out) - cb.set_label (ic.item.name) - fs.extend (cb) - end - end - else - across api.user_api.roles as ic loop - create cb.make_with_value ("cms_roles", ic.item.id.out) - cb.set_label (ic.item.name) - fs.extend (cb) - end + l_user_roles := api.user_api.user_roles (a_user) + if l_user_roles.is_empty then + l_user_roles := Void end + + across api.user_api.effective_roles as ic loop + create cb.make_with_value ("cms_roles", ic.item.id.out) + cb.set_checked (l_user_roles /= Void and then across l_user_roles as r_ic some r_ic.item.same_user_role (ic.item) end) + cb.set_title (ic.item.name) + fs.extend (cb) + end + a_form.extend (fs) create ts.make ("op") ts.set_default_value ("Update user role") @@ -512,13 +500,6 @@ feature -- Form feature -- Generation - custom_prepare (page: CMS_HTML_PAGE) - do - if attached variables as l_variables then - across l_variables as c loop page.register_variable (c.item, c.key) end - end - end - new_random_password (u: CMS_USER): STRING -- Generate a new token activation token local diff --git a/modules/admin/handler/user/cms_user_handler.e b/modules/admin/handler/user/cms_user_handler.e index b4d542a..541101c 100644 --- a/modules/admin/handler/user/cms_user_handler.e +++ b/modules/admin/handler/user/cms_user_handler.e @@ -85,12 +85,12 @@ feature -- HTTP Methods do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then - if req.path_info.ends_with_general ("/edit") then - check valid_url: req.path_info.starts_with_general ("/admin/user/") end + if req.percent_encoded_path_info.ends_with_general ("/edit") then + check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/user/") end create edit_response.make (req, res, api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then - check valid_url: req.path_info.starts_with_general ("/admin/user/") end + elseif req.percent_encoded_path_info.ends_with_general ("/delete") then + check valid_url: req.percent_encoded_path_info.starts_with_general ("/admin/user/") end create edit_response.make (req, res, api) edit_response.execute else @@ -123,17 +123,17 @@ feature -- HTTP Methods do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then - if req.path_info.ends_with_general ("/edit") then + if req.percent_encoded_path_info.ends_with_general ("/edit") then create edit_response.make (req, res, api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then + elseif req.percent_encoded_path_info.ends_with_general ("/delete") then if attached {WSF_STRING} req.form_parameter ("op") as l_op and then l_op.value.same_string ("Delete") then do_delete (req, res) end - elseif req.path_info.ends_with_general ("/add/user") then + elseif req.percent_encoded_path_info.ends_with_general ("/add/user") then create edit_response.make (req, res, api) edit_response.execute end @@ -150,14 +150,14 @@ feature -- Error l_page: CMS_RESPONSE do create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) - l_page.add_variable (req.absolute_script_url (req.path_info), "request") + l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request") if a_id /= Void and then a_id.is_integer then -- resource not found - l_page.add_variable ("404", "code") + l_page.set_value ("404", "code") l_page.set_status_code (404) else -- bad request - l_page.add_variable ("400", "code") + l_page.set_value ("400", "code") l_page.set_status_code (400) end l_page.execute @@ -192,7 +192,7 @@ feature {NONE} -- New User local edit_response: CMS_USER_FORM_RESPONSE do - if req.path_info.starts_with_general ("/admin/add/user") then + if req.percent_encoded_path_info.starts_with ("/admin/add/user") then create edit_response.make (req, res, api) edit_response.execute else diff --git a/modules/admin/handler/user/cms_user_view_response.e b/modules/admin/handler/user/cms_user_view_response.e index 751def2..0568fcc 100644 --- a/modules/admin/handler/user/cms_user_view_response.e +++ b/modules/admin/handler/user/cms_user_view_response.e @@ -66,18 +66,19 @@ feature -- Execution end end - - append_html_to_output (a_user: CMS_USER; a_response: CMS_RESPONSE ) + append_html_to_output (a_user: CMS_USER; a_response: CMS_RESPONSE) local lnk: CMS_LOCAL_LINK s: STRING + l_role: CMS_USER_ROLE do - a_response.add_variable (a_user, "user") + a_response.set_value (a_user, "user") create lnk.make (a_response.translation ("View", Void), "admin/user/" + a_user.id.out) lnk.set_is_active (True) lnk.set_weight (1) a_response.add_to_primary_tabs (lnk) create lnk.make (a_response.translation ("Edit", Void), "admin/user/" + a_user.id.out + "/edit") + lnk.set_permission_arguments (<<"manage admin", "manage users", "manage own user">>) lnk.set_weight (2) a_response.add_to_primary_tabs (lnk) @@ -87,32 +88,38 @@ feature -- Execution a_response.add_to_primary_tabs (lnk) end + -- FIXME: [04/aug/2015] use a CMS_FORM rather than hardcoded html. + -- So that other module may easily integrate them-selves to add information. create s.make_empty s.append ("
      ") s.append ("

      Account Information

      ") - s.append ("

      UserName:") + s.append ("

      Username: ") s.append (a_user.name) s.append ("

      ") if attached a_user.email as l_email then - s.append ("

      Email:") + s.append ("

      Email: ") s.append (l_email) s.append ("

      ") end - s.append ("

      User Role:

      ") - if attached {LIST[CMS_USER_ROLE]} api.user_api.user_roles (a_user) as l_roles and then - not l_roles.is_empty + if + attached {LIST [CMS_USER_ROLE]} api.user_api.user_roles (a_user) as l_roles and then + not l_roles.is_empty then + s.append ("

      Role(s):

      ") across l_roles as ic loop + l_role := ic.item s.append ("") - s.append (ic.item.name) + s.append (link (l_role.name, "admin/role/" + l_role.id.out, Void)) s.append ("") - s.append ("
      Permissions:
      ") - s.append ("
        %N") - across ic.item.permissions as c loop - s.append ("
      • "+ c.item + "
      • %N") + debug + s.append ("
        Permissions:
        ") + s.append ("
          %N") + across l_role.permissions as perms_ic loop + s.append ("
        • " + perms_ic.item + "
        • %N") + end + s.append ("
        %N") end - s.append ("
      %N") end end diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index 4338bed..d27138d 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -111,8 +111,11 @@ feature -- Hooks configuration local lnk: CMS_LOCAL_LINK do - if attached a_response.current_user (a_response.request) as u then - create lnk.make (u.name + " (Logout)", "account/roc-logout" ) + if attached a_response.user as u then + create lnk.make (u.name, "account" ) + lnk.set_weight (97) + a_menu_system.primary_menu.extend (lnk) + create lnk.make ("Logout", "account/roc-logout") lnk.set_weight (98) a_menu_system.primary_menu.extend (lnk) else @@ -398,7 +401,7 @@ feature -- Handler l_user_api := api.user_api if req.is_post_request_method then - if attached current_user (req) as l_user then + if attached r.user as l_user then r.set_value (api.user_api.user_roles (l_user), "roles") if attached {WSF_STRING} req.form_parameter ("password") as l_password and then diff --git a/modules/basic_auth/cms_basic_auth_module.e b/modules/basic_auth/cms_basic_auth_module.e index 62d91c0..f39e650 100644 --- a/modules/basic_auth/cms_basic_auth_module.e +++ b/modules/basic_auth/cms_basic_auth_module.e @@ -114,7 +114,7 @@ feature -- Hooks value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) -- do - if attached current_user (a_response.request) as l_user then + if a_response.is_authenticated then a_value.force ("basic_auth_logoff", "auth_login_strategy") end end @@ -126,13 +126,13 @@ feature -- Hooks lnk: CMS_LOCAL_LINK lnk2: detachable CMS_LINK do - if attached a_response.current_user (a_response.request) as u then + if attached a_response.user as u then across a_menu_system.primary_menu.items as ic until lnk2 /= Void loop - if ic.item.title.has_substring ("(Logout)") then + if ic.item.location.same_string ("account/roc-logout") then lnk2 := ic.item end end @@ -141,7 +141,7 @@ feature -- Hooks a_menu_system.primary_menu.remove (lnk2) end - create lnk.make (u.name + " (Logout)", "basic_auth_logoff" ) + create lnk.make ("Logout", "basic_auth_logoff") lnk.set_weight (98) a_menu_system.primary_menu.extend (lnk) else diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e index 4670058..3e4b098 100644 --- a/modules/node/cms_node_module.e +++ b/modules/node/cms_node_module.e @@ -1,5 +1,5 @@ note - description: "CMS module that bring support for NODE management." + description: "CMS module bringing support for NODE management." date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" revision: "$Revision: 96616 $" @@ -7,14 +7,14 @@ class CMS_NODE_MODULE inherit - CMS_MODULE redefine register_hooks, initialize, is_installed, install, - module_api + module_api, + permissions end CMS_HOOK_MENU_SYSTEM_ALTER @@ -136,6 +136,34 @@ feature {CMS_API} -- Access: API node_api: detachable CMS_NODE_API -- +feature -- Access + + permissions: LIST [READABLE_STRING_8] + -- . + do + Result := Precursor + Result.force ("create any") + Result.force ("view any") + Result.force ("edit any") + Result.force ("delete any") + Result.force ("view own") + Result.force ("edit own") + Result.force ("delete own") + if attached node_api as l_node_api then + across + l_node_api.content_types as ic + loop + Result.force ("create " + ic.item.name) + Result.force ("view " + ic.item.name) + Result.force ("edit " + ic.item.name) + Result.force ("delete " + ic.item.name) + Result.force ("view own " + ic.item.name) + Result.force ("edit own " + ic.item.name) + Result.force ("delete own " + ic.item.name) + end + end + end + feature -- Access: router setup_router (a_router: WSF_ROUTER; a_api: CMS_API) @@ -213,7 +241,7 @@ feature -- Hooks local lnk: CMS_LOCAL_LINK do - debug + debug create lnk.make ("List of nodes", "nodes") a_menu_system.primary_menu.extend (lnk) end diff --git a/modules/node/handler/cms_node_type_webform_manager.e b/modules/node/handler/cms_node_type_webform_manager.e index a278e46..cfa4e8f 100644 --- a/modules/node/handler/cms_node_type_webform_manager.e +++ b/modules/node/handler/cms_node_type_webform_manager.e @@ -264,7 +264,7 @@ feature -- Output do node_api := a_response.node_api - a_response.add_variable (a_node, "node") + a_response.set_value (a_node, "node") -- Show tabs only if a user is authenticated. if attached a_response.user as l_user then diff --git a/modules/node/handler/node_form_response.e b/modules/node/handler/node_form_response.e index 1b31e4b..d0dbf91 100644 --- a/modules/node/handler/node_form_response.e +++ b/modules/node/handler/node_form_response.e @@ -50,10 +50,10 @@ feature -- Execution if attached node_api.node_type_for (l_node) as l_type then fixme ("refactor: process_edit, process_create process edit") if - request.path_info.ends_with_general ("/edit") and then - node_api.has_permission_for_action_on_node ("edit", l_node, current_user (request)) + location.ends_with_general ("/edit") and then + node_api.has_permission_for_action_on_node ("edit", l_node, user) then - f := new_edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type) + f := new_edit_form (l_node, url (location, Void), "edit-" + l_type.name, l_type) invoke_form_alter (f, fd) if request.is_post_request_method then f.validation_actions.extend (agent edit_form_validate (?, b)) @@ -76,10 +76,10 @@ feature -- Execution f.append_to_html (wsf_theme, b) end elseif - request.path_info.ends_with_general ("/delete") and then - node_api.has_permission_for_action_on_node ("delete", l_node, current_user (request)) + location.ends_with_general ("/delete") and then + node_api.has_permission_for_action_on_node ("delete", l_node, user) then - f := new_delete_form (l_node, url (request.path_info, Void), "delete-" + l_type.name, l_type) + f := new_delete_form (l_node, url (location, Void), "delete-" + l_type.name, l_type) invoke_form_alter (f, fd) if request.is_post_request_method then f.process (Current) @@ -100,10 +100,10 @@ feature -- Execution f.append_to_html (wsf_theme, b) end elseif - request.path_info.ends_with_general ("/trash") and then - node_api.has_permission_for_action_on_node ("trash", l_node, current_user (request)) + location.ends_with_general ("/trash") and then + node_api.has_permission_for_action_on_node ("trash", l_node, user) then - f := new_trash_form (l_node, url (request.path_info, Void), "trash-" + l_type.name, l_type) + f := new_trash_form (l_node, url (location, Void), "trash-" + l_type.name, l_type) invoke_form_alter (f, fd) if request.is_post_request_method then f.process (Current) @@ -136,7 +136,7 @@ feature -- Execution then if has_permissions (<<"create any", "create " + l_type.name>>) then if attached l_type.new_node (Void) as l_node then - f := new_edit_form (l_node, url (request.path_info, Void), "edit-" + l_type.name, l_type) + f := new_edit_form (l_node, url (location, Void), "edit-" + l_type.name, l_type) invoke_form_alter (f, fd) if request.is_post_request_method then f.validation_actions.extend (agent edit_form_validate (?, b)) @@ -253,7 +253,7 @@ feature -- Form fixme ("for now, publishing is not implemented, so let's assume any node saved is published.") -- FIXME l_node.mark_published node_api.save_node (l_node) - if attached current_user (request) as u then + if attached user as u then api.log ("node", "User %"" + user_html_link (u) + "%" " + s + " node " + node_html_link (l_node, a_type.name + " #" + l_node.id.out), 0, node_local_link (l_node, Void) diff --git a/modules/node/handler/node_handler.e b/modules/node/handler/node_handler.e index 39baec7..4843dd9 100644 --- a/modules/node/handler/node_handler.e +++ b/modules/node/handler/node_handler.e @@ -85,16 +85,16 @@ feature -- HTTP Methods edit_response: NODE_FORM_RESPONSE view_response: NODE_VIEW_RESPONSE do - if req.path_info.ends_with_general ("/edit") then - check valid_url: req.path_info.starts_with_general ("/node/") end + if req.percent_encoded_path_info.ends_with ("/edit") then + check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end create edit_response.make (req, res, api, node_api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then - check valid_url: req.path_info.starts_with_general ("/node/") end + elseif req.percent_encoded_path_info.ends_with ("/delete") then + check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end create edit_response.make (req, res, api, node_api) edit_response.execute - elseif req.path_info.ends_with_general ("/trash") then - check valid_url: req.path_info.starts_with_general ("/node/") end + elseif req.percent_encoded_path_info.ends_with ("/trash") then + check valid_url: req.percent_encoded_path_info.starts_with ("/node/") end create edit_response.make (req, res, api, node_api) edit_response.execute else @@ -125,17 +125,17 @@ feature -- HTTP Methods edit_response: NODE_FORM_RESPONSE do fixme ("Refactor code: extract methods: edit_node and add_node") - if req.path_info.ends_with_general ("/edit") then + if req.percent_encoded_path_info.ends_with ("/edit") then create edit_response.make (req, res, api, node_api) edit_response.execute - elseif req.path_info.ends_with_general ("/delete") then + elseif req.percent_encoded_path_info.ends_with ("/delete") then if attached {WSF_STRING} req.form_parameter ("op") as l_op and then l_op.value.same_string ("Delete") then do_delete (req, res) end - elseif req.path_info.ends_with_general ("/trash") then + elseif req.percent_encoded_path_info.ends_with ("/trash") then if attached {WSF_STRING} req.form_parameter ("op") as l_op and then l_op.value.same_string ("Trash") @@ -147,7 +147,7 @@ feature -- HTTP Methods then do_restore (req, res) end - elseif req.path_info.starts_with_general ("/node/add/") then + elseif req.percent_encoded_path_info.starts_with ("/node/add/") then create edit_response.make (req, res, api, node_api) edit_response.execute else @@ -260,14 +260,14 @@ feature -- Error l_page: CMS_RESPONSE do create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) - l_page.add_variable (req.absolute_script_url (req.path_info), "request") + l_page.set_value (req.absolute_script_url (req.percent_encoded_path_info), "request") if a_id /= Void and then a_id.is_integer then -- resource not found - l_page.add_variable ("404", "code") + l_page.set_value ("404", "code") l_page.set_status_code (404) else -- bad request - l_page.add_variable ("400", "code") + l_page.set_value ("400", "code") l_page.set_status_code (400) end l_page.execute @@ -279,7 +279,7 @@ feature {NONE} -- Node local edit_response: NODE_FORM_RESPONSE do - if req.path_info.starts_with_general ("/node/") then + if req.percent_encoded_path_info.starts_with_general ("/node/") then create edit_response.make (req, res, api, node_api) edit_response.execute elseif req.is_get_request_method then diff --git a/modules/node/handler/node_response.e b/modules/node/handler/node_response.e index 6c444a5..8bc0e28 100644 --- a/modules/node/handler/node_response.e +++ b/modules/node/handler/node_response.e @@ -10,8 +10,6 @@ inherit CMS_RESPONSE rename make as make_response - redefine - custom_prepare end feature {NONE} -- Initialization @@ -27,15 +25,6 @@ feature -- Access node_api: CMS_NODE_API -- Associated node API. -feature -- Generation - - custom_prepare (page: CMS_HTML_PAGE) - do - if attached variables as l_variables then - across l_variables as c loop page.register_variable (c.item, c.key) end - end - end - feature -- Helpers node_id_path_parameter (req: WSF_REQUEST): INTEGER_64 diff --git a/modules/oauth20/cms_oauth_20_module.e b/modules/oauth20/cms_oauth_20_module.e index 7116dfd..99ff73f 100644 --- a/modules/oauth20/cms_oauth_20_module.e +++ b/modules/oauth20/cms_oauth_20_module.e @@ -202,7 +202,7 @@ feature -- Hooks -- do if - attached a_response.current_user (a_response.request) as u and then + attached a_response.user as u and then attached {WSF_STRING} a_response.request.cookie ({CMS_OAUTH_20_CONSTANTS}.oauth_session) then a_value.force ("account/roc-oauth-logout", "auth_login_strategy") @@ -217,7 +217,7 @@ feature -- Hooks lnk2: detachable CMS_LINK do if - attached a_response.current_user (a_response.request) as u and then + attached a_response.user as u and then attached {WSF_STRING} a_response.request.cookie ({CMS_OAUTH_20_CONSTANTS}.oauth_session) as l_roc_auth_session_token then across @@ -225,14 +225,14 @@ feature -- Hooks until lnk2 /= Void loop - if ic.item.title.has_substring ("(Logout)") then + if ic.item.location.same_string ("account/roc-logout") then lnk2 := ic.item end end if lnk2 /= Void then a_menu_system.primary_menu.remove (lnk2) end - create lnk.make (u.name + " (Logout)", "account/roc-oauth-logout" ) + create lnk.make ("Logout", "account/roc-oauth-logout" ) a_menu_system.primary_menu.extend (lnk) else if a_response.location.starts_with ("account/") then @@ -307,10 +307,13 @@ feature -- Hooks l_cookie.set_max_age (-1) res.add_cookie (l_cookie) unset_current_user (req) + 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 end @@ -322,8 +325,8 @@ feature {NONE} -- Associate l_not_associated: LIST [STRING] do if attached user_oauth_api as l_oauth_api then - create {ARRAYED_LIST [STRING]}l_associated.make (1) - create {ARRAYED_LIST [STRING]}l_not_associated.make (1) + create {ARRAYED_LIST [STRING]} l_associated.make (1) + create {ARRAYED_LIST [STRING]} l_not_associated.make (1) across l_oauth_api.oauth2_consumers as ic loop if attached l_oauth_api.user_oauth2_by_id (a_user.id, ic.item) then l_associated.force (ic.item) @@ -506,7 +509,7 @@ feature -- OAuth2 Login with Provider if attached {WSF_STRING} req.form_parameter ("consumer") as l_consumer and then attached {WSF_STRING} req.form_parameter ("email") as l_email and then - attached current_user (req) as l_user + attached r.user as l_user then l_user.set_email (l_email.value) a_oauth_api.new_user_oauth2 ("none", "none", l_user, l_consumer.value ) @@ -526,7 +529,7 @@ feature -- OAuth2 Login with Provider if req.is_post_request_method then if attached {WSF_STRING} req.form_parameter ("consumer") as l_consumer and then - attached current_user (req) as l_user + attached r.user as l_user then a_oauth_api.remove_user_oauth2 (l_user, l_consumer.value) -- TODO send email? diff --git a/modules/openid/cms_openid_module.e b/modules/openid/cms_openid_module.e index d9b8dd6..70fa7c8 100644 --- a/modules/openid/cms_openid_module.e +++ b/modules/openid/cms_openid_module.e @@ -180,8 +180,8 @@ feature -- Hooks -- do if - attached a_response.current_user (a_response.request) as u and then - attached {WSF_STRING} a_response.request.cookie ({CMS_OPENID_CONSTANTS}.openid_session) + attached a_response.user as u and then + attached {WSF_STRING} a_response.request.cookie ({CMS_OPENID_CONSTANTS}.openid_session) then a_value.force ("account/roc-openid-logout", "auth_login_strategy") end @@ -195,7 +195,7 @@ feature -- Hooks lnk2: detachable CMS_LINK do if - attached a_response.current_user (a_response.request) as u and then + attached a_response.user as u and then attached {WSF_STRING} a_response.request.cookie ({CMS_OPENID_CONSTANTS}.openid_session) as l_roc_auth_session_token then across @@ -203,14 +203,14 @@ feature -- Hooks until lnk2 /= Void loop - if ic.item.title.has_substring ("(Logout)") then + if ic.item.location.same_string ("account/roc-logout") then lnk2 := ic.item end end if lnk2 /= Void then a_menu_system.primary_menu.remove (lnk2) end - create lnk.make (u.name + " (Logout)", "account/roc-openid-logout" ) + create lnk.make ("Logout", "account/roc-openid-logout" ) a_menu_system.primary_menu.extend (lnk) else if a_response.location.starts_with ("account/") then @@ -296,6 +296,8 @@ feature -- Hooks r.set_status_code ({HTTP_CONSTANTS}.found) r.set_redirection (req.absolute_script_url ("")) r.execute + else + -- FIXME: missing implementation! end end diff --git a/src/persistence/user/cms_user_storage_i.e b/src/persistence/user/cms_user_storage_i.e index 6c77756..2692e1b 100644 --- a/src/persistence/user/cms_user_storage_i.e +++ b/src/persistence/user/cms_user_storage_i.e @@ -171,6 +171,13 @@ feature -- Access: roles and permissions deferred end + role_permissions: LIST [READABLE_STRING_8] + -- Possible known role permissions. + deferred + ensure + object_comparison: Result.object_comparison + end + feature -- Change: roles and permissions save_user_role (a_user_role: CMS_USER_ROLE) diff --git a/src/persistence/user/cms_user_storage_null.e b/src/persistence/user/cms_user_storage_null.e index f078f45..c899696 100644 --- a/src/persistence/user/cms_user_storage_null.e +++ b/src/persistence/user/cms_user_storage_null.e @@ -99,6 +99,12 @@ feature -- Access: roles and permissions create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (0) end + role_permissions: LIST [READABLE_STRING_8] + -- Possible known permissions. + do + create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0) + end + feature -- Change: roles and permissions save_user_role (a_user_role: CMS_USER_ROLE) diff --git a/src/persistence/user/cms_user_storage_sql_i.e b/src/persistence/user/cms_user_storage_sql_i.e index 5d8ef9b..1434d14 100644 --- a/src/persistence/user/cms_user_storage_sql_i.e +++ b/src/persistence/user/cms_user_storage_sql_i.e @@ -503,6 +503,27 @@ feature -- Access: roles and permissions end end + role_permissions: LIST [READABLE_STRING_8] + -- Possible known permissions. + do + error_handler.reset + write_information_log (generator + ".role_permissions") + + create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0) + Result.compare_objects + from + sql_query (select_role_permissions, Void) + sql_start + until + sql_after + loop + if attached sql_read_string (1) as l_permission then + Result.force (l_permission) + end + sql_forth + end + end + feature -- Change: roles and permissions save_user_role (a_user_role: CMS_USER_ROLE) @@ -553,18 +574,7 @@ feature -- Change: roles and permissions a_user_role.permissions as ic loop p := ic.item - from - l_found := False - l_permissions.start - until - l_found or l_permissions.after - loop - if p.is_case_insensitive_equal (l_permissions.item) then - l_found := True - else - l_permissions.forth - end - end + l_found := across l_permissions as p_ic some p.is_case_insensitive_equal_general (p_ic.item) end if l_found then -- Already there, skip else @@ -915,6 +925,9 @@ feature {NONE} -- Sql Queries: USER ROLE select_role_permissions_by_role_id: STRING = "SELECT permission, module FROM role_permissions WHERE rid=:rid;" -- User role permissions for role id :rid; + select_role_permissions: STRING = "SELECT DISTINCT permission FROM role_permissions;" + -- Used user role permissions + sql_delete_role_permissions_by_role_id: STRING = "DELETE FROM role_permissions WHERE rid=:rid;" sql_delete_role_by_id: STRING = "DELETE FROM roles WHERE rid=:rid;" diff --git a/src/service/cms_module.e b/src/service/cms_module.e index fcb3574..5dfb22f 100644 --- a/src/service/cms_module.e +++ b/src/service/cms_module.e @@ -32,6 +32,14 @@ feature -- Access dependencies: detachable LIST [TYPE [CMS_MODULE]] -- Optional dependencies. + permissions: LIST [READABLE_STRING_8] + -- List of permission ids, used by this module, and declared. + require + is_initialized: is_initialized + do + create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (0) + end + feature {CMS_API} -- Module Initialization initialize (api: CMS_API) diff --git a/src/service/misc/cms_request_util.e b/src/service/misc/cms_request_util.e index f49337a..bbf222d 100644 --- a/src/service/misc/cms_request_util.e +++ b/src/service/misc/cms_request_util.e @@ -25,6 +25,7 @@ feature -- User current_user (req: WSF_REQUEST): detachable CMS_USER -- Current user or Void in case of Guest user. + -- note: if a CMS_RESPONSE is available, always prefer {CMS_RESPONSE}.user if relevant. note EIS: "eiffel:?class=AUTHENTICATION_FILTER&feature=execute" do @@ -70,4 +71,7 @@ feature -- Media Type end end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/cms_response.e b/src/service/response/cms_response.e index 1c62728..8773268 100644 --- a/src/service/response/cms_response.e +++ b/src/service/response/cms_response.e @@ -194,9 +194,14 @@ feature -- Access: CMS values: CMS_VALUE_TABLE -- Associated values indexed by string name. - feature -- User access + is_authenticated: BOOLEAN + -- Is user authenticated? + do + Result := user /= Void + end + user: detachable CMS_USER do Result := current_user (request) @@ -204,16 +209,28 @@ feature -- User access feature -- Permission + has_permission_on_link (a_link: CMS_LINK): BOOLEAN + -- Does current user has permission to access link `a_link'? + do + Result := True + if + attached {CMS_LOCAL_LINK} a_link as lnk and then + attached lnk.permission_arguments as l_perms + then + Result := has_permissions (l_perms) + end + end + has_permission (a_permission: READABLE_STRING_GENERAL): BOOLEAN -- Does current user has permission `a_permission' ? do - Result := user_has_permission (current_user (request), a_permission) + Result := user_has_permission (user, a_permission) end has_permissions (a_permission_list: ITERABLE [READABLE_STRING_GENERAL]): BOOLEAN -- Does current user has any of the permissions `a_permission_list' ? do - Result := user_has_permissions (current_user (request), a_permission_list) + Result := user_has_permissions (user, a_permission_list) end user_has_permission (a_user: detachable CMS_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN @@ -296,6 +313,12 @@ feature -- Element change main_content := s end + add_variable (a_element: ANY; a_key:READABLE_STRING_32) + obsolete "Use `set_value' [Aug/2015]" + do + set_value (a_element, a_key) + end + set_value (v: detachable ANY; k: READABLE_STRING_GENERAL) -- Set value `v' associated with name `k'. do @@ -859,15 +882,16 @@ feature -- Generation prepare (page: CMS_HTML_PAGE) local lnk: CMS_LINK + l_menu_list_prepared: ARRAYED_LIST [CMS_LINK_COMPOSITE] do -- Menu create {CMS_LOCAL_LINK} lnk.make ("Home", "") lnk.set_weight (-10) add_to_primary_menu (lnk) invoke_menu_system_alter (menu_system) - prepare_menu_system (menu_system) -- Blocks + create l_menu_list_prepared.make (0) get_blocks across regions as reg_ic @@ -876,11 +900,23 @@ feature -- Generation reg_ic.item.blocks as ic loop if attached {CMS_MENU_BLOCK} ic.item as l_menu_block then - recursive_get_active (l_menu_block.menu, request) + l_menu_list_prepared.force (l_menu_block.menu) + prepare_links (l_menu_block.menu) end end end + -- Prepare menu not in a block. + across + menu_system as ic + loop + if not l_menu_list_prepared.has (ic.item) then + l_menu_list_prepared.force (ic.item) + prepare_links (ic.item) + end + end + l_menu_list_prepared.wipe_out -- Clear for memory purpose. + -- Sort items across menu_system as ic loop ic.item.sort @@ -951,7 +987,7 @@ feature -- Generation page.set_title (title) debug ("cms") if title = Void then - page.set_title ("CMS::" + request.path_info) --| FIXME: probably, should be removed and handled by theme. + page.set_title ({STRING_32} "CMS::" + request.path_info) --| FIXME: probably, should be removed and handled by theme. end end @@ -988,54 +1024,19 @@ feature -- Generation do end - prepare_menu_system (a_menu_system: CMS_MENU_SYSTEM) - do - across - a_menu_system as c - loop - prepare_links (c.item) - end - end - - prepare_links (a_menu: CMS_LINK_COMPOSITE) - local - to_remove: ARRAYED_LIST [CMS_LINK] - do - create to_remove.make (0) - across - a_menu as c - loop - if attached {CMS_LOCAL_LINK} c.item as lm then --- if attached lm.permission_arguments as perms and then not has_permissions (perms) then --- to_remove.force (lm) --- else - -- if lm.permission_arguments is Void , this is permitted - get_local_link_active_status (lm) - if attached {CMS_LINK_COMPOSITE} lm as comp then - prepare_links (comp) - end --- end - elseif attached {CMS_LINK_COMPOSITE} c.item as comp then - prepare_links (comp) - end - end - across - to_remove as c - loop - a_menu.remove (c.item) - end - end - - recursive_get_active (a_comp: CMS_LINK_COMPOSITE; req: WSF_REQUEST) + prepare_links (a_comp: CMS_LINK_COMPOSITE) -- Update the active status recursively on `a_comp'. local + to_remove: ARRAYED_LIST [CMS_LINK] ln: CMS_LINK l_comp_link: detachable CMS_LOCAL_LINK do if attached {CMS_LOCAL_LINK} a_comp as lnk then l_comp_link := lnk + get_local_link_active_status (lnk) end if attached a_comp.items as l_items then + create to_remove.make (0) across l_items as ic loop @@ -1043,15 +1044,27 @@ feature -- Generation if attached {CMS_LOCAL_LINK} ln as l_local then get_local_link_active_status (l_local) end - if (ln.is_expanded or ln.is_collapsed) and then attached {CMS_LINK_COMPOSITE} ln as l_comp then - recursive_get_active (l_comp, req) - end - if l_comp_link /= Void then - if ln.is_expanded or (not ln.is_expandable and ln.is_active) then - l_comp_link.set_expanded (True) + if ln.is_forbidden then + to_remove.force (ln) + else + if + (ln.is_expanded or ln.is_collapsed) and then + attached {CMS_LINK_COMPOSITE} ln as l_comp + then + prepare_links (l_comp) + end + if l_comp_link /= Void then + if ln.is_expanded or (not ln.is_expandable and ln.is_active) then + l_comp_link.set_expanded (True) + end end end end + across + to_remove as ic + loop + a_comp.remove (ic.item) + end end if l_comp_link /= Void and then l_comp_link.is_active then l_comp_link.set_expanded (True) @@ -1077,25 +1090,7 @@ feature -- Generation l_is_active := qs.same_string (a_lnk.location) end a_lnk.set_is_active (l_is_active) - end - -feature -- Custom Variables - - variables: detachable STRING_TABLE[ANY] - -- Custom variables to feed the templates. - -feature -- Element change: Add custom variables. - - add_variable (a_element: ANY; a_key:READABLE_STRING_32) - local - l_variables: like variables - do - l_variables := variables - if l_variables = Void then - create l_variables.make (5) - variables := l_variables - end - l_variables.force (a_element, a_key) + a_lnk.set_is_forbidden (not has_permission_on_link (a_lnk)) end feature -- Execution diff --git a/src/service/response/error/bad_request_error_cms_response.e b/src/service/response/error/bad_request_error_cms_response.e index 002a3c3..4c2cab1 100644 --- a/src/service/response/error/bad_request_error_cms_response.e +++ b/src/service/response/error/bad_request_error_cms_response.e @@ -20,7 +20,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do - page.register_variable (absolute_url (request.path_info, Void), "request") + page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request") page.set_status_code ({HTTP_STATUS_CODE}.bad_request) page.register_variable (page.status_code.out, "code") end @@ -35,4 +35,7 @@ feature -- Execution set_main_content ("Bad request.") end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/error/forbidden_error_cms_response.e b/src/service/response/error/forbidden_error_cms_response.e index 62518e5..0cc2982 100644 --- a/src/service/response/error/forbidden_error_cms_response.e +++ b/src/service/response/error/forbidden_error_cms_response.e @@ -20,7 +20,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do - page.register_variable (absolute_url (request.path_info, Void), "request") + page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request") page.set_status_code ({HTTP_STATUS_CODE}.forbidden) page.register_variable (page.status_code.out, "code") end @@ -34,5 +34,8 @@ feature -- Execution set_page_title ("Forbidden") set_main_content ("Access denied for resource " + request.request_uri + ".") end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/error/internal_server_error_cms_response.e b/src/service/response/error/internal_server_error_cms_response.e index f23a871..99aa752 100644 --- a/src/service/response/error/internal_server_error_cms_response.e +++ b/src/service/response/error/internal_server_error_cms_response.e @@ -20,7 +20,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do - page.register_variable (absolute_url (request.path_info, Void), "request") + page.register_variable (absolute_url (location, Void), "request") page.set_status_code ({HTTP_STATUS_CODE}.internal_server_error) page.register_variable (page.status_code.out, "code") end @@ -34,5 +34,8 @@ feature -- Execution set_page_title (Void) set_main_content ("Internal Server Error") end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/error/not_found_error_cms_response.e b/src/service/response/error/not_found_error_cms_response.e index 2c7d63c..0768a0b 100644 --- a/src/service/response/error/not_found_error_cms_response.e +++ b/src/service/response/error/not_found_error_cms_response.e @@ -20,7 +20,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do - page.register_variable (absolute_url (request.path_info, Void), "request") + page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request") page.set_status_code ({HTTP_STATUS_CODE}.not_found) page.register_variable (page.status_code.out, "code") end @@ -34,5 +34,8 @@ feature -- Execution set_page_title ("Not Found") set_main_content ("The requested page could not be found.") end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/error/not_implemented_error_cms_response.e b/src/service/response/error/not_implemented_error_cms_response.e index e46e9fd..5e6c18f 100644 --- a/src/service/response/error/not_implemented_error_cms_response.e +++ b/src/service/response/error/not_implemented_error_cms_response.e @@ -20,7 +20,7 @@ feature -- Generation custom_prepare (page: CMS_HTML_PAGE) do - page.register_variable (absolute_url (request.path_info, Void), "request") + page.register_variable (absolute_url (request.percent_encoded_path_info, Void), "request") page.set_status_code ({HTTP_STATUS_CODE}.not_implemented) page.register_variable (page.status_code.out, "code") end @@ -36,5 +36,8 @@ feature -- Execution set_main_content (request.percent_encoded_path_info + " is not implemented!") end end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/service/response/generic_view_cms_response.e b/src/service/response/generic_view_cms_response.e index 0a77a6a..f18d9d7 100644 --- a/src/service/response/generic_view_cms_response.e +++ b/src/service/response/generic_view_cms_response.e @@ -7,24 +7,11 @@ class GENERIC_VIEW_CMS_RESPONSE inherit - CMS_RESPONSE - redefine - custom_prepare - end create make -feature -- Generation - - custom_prepare (page: CMS_HTML_PAGE) - do - if attached variables as l_variables then - across l_variables as c loop page.register_variable (c.item, c.key) end - end - end - feature -- Execution process diff --git a/src/service/user/cms_user_api.e b/src/service/user/cms_user_api.e index 6ecc6fa..d1380f0 100644 --- a/src/service/user/cms_user_api.e +++ b/src/service/user/cms_user_api.e @@ -1,6 +1,5 @@ note - description: "Summary description for {CMS_USER_API}." - author: "" + description: "API providing user related features." date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $" revision: "$Revision: 96616 $" @@ -143,12 +142,52 @@ feature -- User roles. Result := storage.user_role_by_name (a_name) end + role_permissions: LIST [READABLE_STRING_8] + -- Possible known permissions. + local + perm: READABLE_STRING_8 + do + Result := storage.role_permissions + across + cms_api.enabled_modules as ic + loop + across + ic.item.permissions as perms_ic + loop + perm := perms_ic.item + if not Result.has (perm) then + Result.force (perm) + end + end + end + end + roles: LIST [CMS_USER_ROLE] -- List of possible roles. do Result := storage.user_roles end + effective_roles: LIST [CMS_USER_ROLE] + -- List of possible roles, apart from anonymous and authenticated roles that are special. + local + l_roles: like roles + r: CMS_USER_ROLE + do + l_roles := storage.user_roles + create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (l_roles.count) + across + l_roles as ic + loop + r := ic.item + if r.same_user_role (anonymous_user_role) or r.same_user_role (authenticated_user_role) then + -- Ignore + else + Result.force (r) + end + end + end + roles_count: INTEGER -- Number of roles do diff --git a/src/support/cms_pagination_generator.e b/src/support/cms_pagination_generator.e index 64ee463..8cd7414 100644 --- a/src/support/cms_pagination_generator.e +++ b/src/support/cms_pagination_generator.e @@ -266,19 +266,24 @@ feature -- Convertion pagination_links as ic loop lnk := ic.item - if lnk.is_active then - a_output.append ("
    • ") - elseif lnk.title.same_string (label_previous) then - a_output.append ("
    • ") - elseif lnk.title.same_string (label_next) then - a_output.append ("
    • ") - else - a_output.append ("
    • ") + if not lnk.is_forbidden then + if lnk.is_active then + a_output.append ("
    • ") + elseif lnk.title.same_string (label_previous) then + a_output.append ("
    • ") + elseif lnk.title.same_string (label_next) then + a_output.append ("
    • ") + else + a_output.append ("
    • ") + end + a_output.append (a_response.link (lnk.title, lnk.location, Void)) + a_output.append ("
    • ") end - a_output.append (a_response.link (lnk.title, lnk.location, Void)) - a_output.append ("") end a_output.append ("
    ") end +note + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/src/theme/cms_theme.e b/src/theme/cms_theme.e index 0bc2b69..c9090e5 100644 --- a/src/theme/cms_theme.e +++ b/src/theme/cms_theme.e @@ -148,46 +148,45 @@ feature {NONE} -- Implementation local cl: STRING do - debug ("refactor_fixme") - fixme ("Remove HTML from Eiffel") - end - create cl.make_empty - if lnk.is_active then - cl.append ("active ") - end - if lnk.is_expandable then - cl.append ("expandable ") - end - if lnk.is_expanded then - cl.append ("expanded ") - end - if cl.is_empty then - s.append ("
  • ") - else - s.append ("
  • ") - end - s.append ("") - s.append (html_encoded (lnk.title)) - s.append ("") - if - (lnk.is_expanded or lnk.is_collapsed) and then - attached lnk.children as l_children - then - s.append ("
      %N") - across - l_children as c - loop - append_cms_link_to (c.item, s) + if not lnk.is_forbidden then + create cl.make_empty + if lnk.is_active then + cl.append ("active ") end - s.append ("
    ") + if lnk.is_expandable then + cl.append ("expandable ") + end + if lnk.is_expanded then + cl.append ("expanded ") + end + if cl.is_empty then + s.append ("
  • ") + else + s.append ("
  • ") + end + s.append ("") + s.append (html_encoded (lnk.title)) + s.append ("") + if + (lnk.is_expanded or lnk.is_collapsed) and then + attached lnk.children as l_children + then + s.append ("
      %N") + across + l_children as c + loop + append_cms_link_to (c.item, s) + end + s.append ("
    ") + end + s.append ("
  • ") end - s.append ("") end note - copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others" + copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software