diff --git a/cms-safe.ecf b/cms-safe.ecf index e6424f7..2562261 100644 --- a/cms-safe.ecf +++ b/cms-safe.ecf @@ -12,6 +12,7 @@ + diff --git a/cms.ecf b/cms.ecf index 9260f23..2c92e6d 100644 --- a/cms.ecf +++ b/cms.ecf @@ -13,6 +13,7 @@ + diff --git a/modules/admin/cms_admin_module.e b/modules/admin/cms_admin_module.e index 08466e0..fc59d7d 100644 --- a/modules/admin/cms_admin_module.e +++ b/modules/admin/cms_admin_module.e @@ -9,7 +9,8 @@ class inherit CMS_MODULE redefine - register_hooks + register_hooks, + permissions end CMS_HOOK_MENU_SYSTEM_ALTER @@ -79,6 +80,18 @@ feature -- Access: router a_router.handle ("/admin/role/{id}/delete", l_role_handler, a_router.methods_get_post) end +feature -- Security + + permissions: LIST [READABLE_STRING_8] + -- List of permission ids, used by this module, and declared. + do + Result := Precursor + Result.force ("manage admin") + Result.force ("admin users") + Result.force ("admin roles") + Result.force ("admin modules") + end + feature -- Hooks register_hooks (a_response: CMS_RESPONSE) diff --git a/modules/admin/handler/cms_admin_response.e b/modules/admin/handler/cms_admin_response.e index 113ca54..3274fb5 100644 --- a/modules/admin/handler/cms_admin_response.e +++ b/modules/admin/handler/cms_admin_response.e @@ -42,10 +42,12 @@ feature -- Process set_title (translation ("Admin Page", Void)) b.append ("
    ") fixme ("Check how to make it configurable") - if has_permissions (<< "View any">>) then + if has_permissions (<< "admin users">>) then b.append ("
  • " + link ("Users", "admin/users", Void)) b.append ("
    View/Edit/Add Users
    ") b.append ("
  • ") + end + if has_permissions (<< "admin roles">>) then b.append ("
  • " + link ("Roles", "admin/roles", Void)) b.append ("
    View/Edit/Add Roles
    ") b.append ("
  • ") diff --git a/modules/admin/handler/role/cms_admin_roles_handler.e b/modules/admin/handler/role/cms_admin_roles_handler.e index ed68867..229473e 100644 --- a/modules/admin/handler/role/cms_admin_roles_handler.e +++ b/modules/admin/handler/role/cms_admin_roles_handler.e @@ -100,7 +100,7 @@ feature -- HTTP Methods s.append ("
%N") end - if l_response.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if l_response.has_permission ("admin roles") then s.append (l_response.link ("Add Role", "admin/add/role", Void)) end diff --git a/modules/admin/handler/role/cms_role_form_response.e b/modules/admin/handler/role/cms_role_form_response.e index 88cd418..8c3710d 100644 --- a/modules/admin/handler/role/cms_role_form_response.e +++ b/modules/admin/handler/role/cms_role_form_response.e @@ -13,6 +13,8 @@ inherit initialize end + CMS_SHARED_SORTING_UTILITIES + create make @@ -317,7 +319,10 @@ feature -- Form cb: WSF_FORM_CHECKBOX_INPUT ts: WSF_FORM_SUBMIT_INPUT -- tb: WSF_FORM_BUTTON_INPUT + lab: WSF_WIDGET_TEXT l_role_permissions: detachable LIST [READABLE_STRING_8] + l_module_names: ARRAYED_LIST [READABLE_STRING_8] + l_mod_name: READABLE_STRING_8 do if attached a_role as l_role then create fs.make @@ -330,20 +335,45 @@ feature -- Form a_form.extend_html_text ("
") - create fs.make fs.set_legend ("Permissions") if - attached api.user_api.role_permissions as l_permissions + attached api.user_api.role_permissions as l_permissions_by_module 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 (l_role_permissions.has (ic.item)) - cb.set_title (ic.item) - fs.extend (cb) + + create l_module_names.make (l_permissions_by_module.count) + across + l_permissions_by_module as mod_ic + loop + l_module_names.force (mod_ic.key) + end + string_sorter.sort (l_module_names) + across + l_module_names as mod_ic + loop + l_mod_name := mod_ic.item + if + attached l_permissions_by_module.item (l_mod_name) as l_permissions and then + not l_permissions.is_empty + then + if l_mod_name.is_whitespace then + l_mod_name := "... " + end + + create lab.make_with_text ("" + l_mod_name + " module") + + fs.extend (lab) + string_sorter.sort (l_permissions) + across l_permissions as ic loop + create cb.make_with_value ("cms_permissions", ic.item) + cb.set_checked (across l_role_permissions as rp_ic some rp_ic.item.is_case_insensitive_equal (ic.item) end) + cb.set_title (ic.item) + fs.extend (cb) + end + end end end create ti.make ("new_cms_permissions[]") @@ -475,4 +505,5 @@ feature -- Generation }) }); ]" + end diff --git a/modules/admin/handler/role/cms_role_handler.e b/modules/admin/handler/role/cms_role_handler.e index 527c555..0b9a852 100644 --- a/modules/admin/handler/role/cms_role_handler.e +++ b/modules/admin/handler/role/cms_role_handler.e @@ -84,7 +84,7 @@ feature -- HTTP Methods r: CMS_RESPONSE do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) - if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if r.has_permission ("admin roles") then 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) @@ -122,7 +122,7 @@ feature -- HTTP Methods r: CMS_RESPONSE do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) - if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if r.has_permission ("admin roles") then if req.percent_encoded_path_info.ends_with_general ("/edit") then create edit_response.make (req, res, api) edit_response.execute @@ -186,7 +186,7 @@ feature -- Error end -feature {NONE} -- New User +feature {NONE} -- New role create_new_role (req: WSF_REQUEST; res: WSF_RESPONSE) local diff --git a/modules/admin/handler/user/cms_admin_users_handler.e b/modules/admin/handler/user/cms_admin_users_handler.e index 3dc8a03..d087c6c 100644 --- a/modules/admin/handler/user/cms_admin_users_handler.e +++ b/modules/admin/handler/user/cms_admin_users_handler.e @@ -72,7 +72,7 @@ feature -- HTTP Methods -- the setup class. create {FORBIDDEN_ERROR_CMS_RESPONSE} l_response.make (req, res, api) - if l_response.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if l_response.has_permission ("admin users") then user_api := api.user_api l_count := user_api.users_count diff --git a/modules/admin/handler/user/cms_user_handler.e b/modules/admin/handler/user/cms_user_handler.e index 541101c..4bfd764 100644 --- a/modules/admin/handler/user/cms_user_handler.e +++ b/modules/admin/handler/user/cms_user_handler.e @@ -84,7 +84,7 @@ feature -- HTTP Methods r: CMS_RESPONSE do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) - if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if r.has_permission ("admin users") then 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) @@ -122,7 +122,7 @@ feature -- HTTP Methods r: CMS_RESPONSE do create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) - if r.has_permission ("manage " + {CMS_ADMIN_MODULE}.name) then + if r.has_permission ("admin users") then if req.percent_encoded_path_info.ends_with_general ("/edit") then create edit_response.make (req, res, api) edit_response.execute diff --git a/modules/node/cms_node_api.e b/modules/node/cms_node_api.e index 877d0c6..7b45350 100644 --- a/modules/node/cms_node_api.e +++ b/modules/node/cms_node_api.e @@ -299,16 +299,6 @@ feature -- Permission Scope: Node Result := cms_api.user_has_permission (a_user, a_action + " own " + l_type_name) end end - fixme ("when admin back end is ready, remove this, as too general.") -- FIXME - if not Result then - Result := cms_api.user_has_permission (a_user, a_action + " any node") - if not Result and a_user /= Void then - if is_author_of_node (a_user, a_node) then - Result := cms_api.user_has_permission (a_user, a_action + " own node") - end - end - - end end feature -- Change: Node diff --git a/modules/node/cms_node_module.e b/modules/node/cms_node_module.e index 3e4b098..c7cedd1 100644 --- a/modules/node/cms_node_module.e +++ b/modules/node/cms_node_module.e @@ -140,26 +140,28 @@ feature -- Access permissions: LIST [READABLE_STRING_8] -- . + local + l_type_name: 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") + Result.force ("create any node") + 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) + l_type_name := ic.item.name + if not l_type_name.is_whitespace then + Result.force ("create " + l_type_name) + + Result.force ("view any " + l_type_name) + Result.force ("edit any " + l_type_name) + Result.force ("delete any " + l_type_name) + + Result.force ("view own " + l_type_name) + Result.force ("edit own " + l_type_name) + Result.force ("delete own " + l_type_name) + end end end end diff --git a/src/service/misc/cms_shared_sorting_utilities.e b/src/service/misc/cms_shared_sorting_utilities.e new file mode 100644 index 0000000..36acac0 --- /dev/null +++ b/src/service/misc/cms_shared_sorting_utilities.e @@ -0,0 +1,20 @@ +note + description: "Collection of sorters to help CMS dev." + date: "$Date$" + revision: "$Revision$" + +deferred class + CMS_SHARED_SORTING_UTILITIES + +feature -- Helpers + + string_sorter: QUICK_SORTER [READABLE_STRING_GENERAL] + -- New string sorter. + once + create Result.make (create {COMPARABLE_COMPARATOR [READABLE_STRING_GENERAL]}) + 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/user/cms_user_api.e b/src/service/user/cms_user_api.e index d1380f0..53874a5 100644 --- a/src/service/user/cms_user_api.e +++ b/src/service/user/cms_user_api.e @@ -142,23 +142,40 @@ feature -- User roles. Result := storage.user_role_by_name (a_name) end - role_permissions: LIST [READABLE_STRING_8] - -- Possible known permissions. + role_permissions: HASH_TABLE [LIST [READABLE_STRING_8], STRING_8] + -- Possible known permissions indexed by modules. local perm: READABLE_STRING_8 + lst, l_used_permissions: LIST [READABLE_STRING_8] + l_found: BOOLEAN do - Result := storage.role_permissions + create Result.make (cms_api.enabled_modules.count + 1) + + l_used_permissions := storage.role_permissions across cms_api.enabled_modules as ic loop + lst := ic.item.permissions + Result.force (lst, ic.item.name) across - ic.item.permissions as perms_ic + lst as p_ic loop - perm := perms_ic.item - if not Result.has (perm) then - Result.force (perm) + from + l_used_permissions.start + until + l_used_permissions.after + loop + if l_used_permissions.item.is_case_insensitive_equal (p_ic.item) then + l_used_permissions.remove + l_used_permissions.finish + end + l_used_permissions.forth end end + + if not l_used_permissions.is_empty then + Result.force (l_used_permissions, "") + end end end