From 7dd24c104036bc663c2b7ad4dbad509d7a3fd867 Mon Sep 17 00:00:00 2001 From: Loetie Kruger Date: Thu, 19 Jun 2025 14:47:11 +0200 Subject: [PATCH] Fix OEI2-44 add user group for moderator role --- modules/mod_ginger_base/mod_ginger_base.erl | 54 ++++++++++----- .../support/ginger_user_group.erl | 65 +++++++++++++++++++ 2 files changed, 101 insertions(+), 18 deletions(-) create mode 100644 modules/mod_ginger_base/support/ginger_user_group.erl diff --git a/modules/mod_ginger_base/mod_ginger_base.erl b/modules/mod_ginger_base/mod_ginger_base.erl index afef5f453..848edd36e 100644 --- a/modules/mod_ginger_base/mod_ginger_base.erl +++ b/modules/mod_ginger_base/mod_ginger_base.erl @@ -9,7 +9,7 @@ -mod_prio(250). -mod_depends([mod_content_groups, mod_acl_user_groups]). --mod_schema(11). +-mod_schema(13). -export([ init/1, @@ -53,11 +53,19 @@ manage_schema(_Version, Context) -> % {uniquename, category, [ % {propname, propvalue} % ]}, + {acl_user_group_moderators, acl_user_group, [ + {title, {trans, [{en, "Moderators"}, {nl, "Moderatoren"}]}} + ]}, {editor_dev, person, [ {title, "Redacteur"}, {name_first, "Redacteur"}, {email, "redactie@ginger.nl"} ]}, + {moderator_dev, person, [ + {title, "Moderator"}, + {name_first, "Moderator"}, + {email, "moderator@ginger.nl"} + ]}, {fallback, image, [ {title, "Fallback image"} ]}, @@ -121,7 +129,8 @@ manage_schema(_Version, Context) -> ]} ], edges = [ - {editor_dev, hasusergroup, acl_user_group_editors} + {editor_dev, hasusergroup, acl_user_group_editors}, + {moderator_dev, hasusergroup, acl_user_group_moderators} ], data = [ {acl_rules, [ @@ -165,12 +174,21 @@ manage_schema(_Version, Context) -> {acl_user_group_id, acl_user_group_editors}, {actions, [use]}, {module, mod_menu} + ]}, + %% Moderators can do user management + {module, [ + {acl_user_group_id, acl_user_group_moderators}, + {actions, [use]}, + {module, mod_admin_identity} ]} ]} ] }, z_datamodel:manage(?MODULE, Datamodel, Context), - schema:create_identity_if_not_exists(editor_dev, "redacteur", "redacteur", Context). + ginger_user_group:move_moderator_user_group(Context), + ginger_user_group:move_manager_user_group(Context), + schema:create_identity_if_not_exists(editor_dev, "redacteur", z_ids:id(20), Context), + schema:create_identity_if_not_exists(moderator_dev, "moderator", z_ids:id(20), Context). %% @doc Users without access to the admin should not be able to view unpublished %% resources @@ -207,16 +225,16 @@ event(#submit{message={newcomment, Args}, form=FormId}, Context) -> Html = z_template:render(CommentTemplate, Props, Context), Context1 = z_render:insert_bottom(CommentsListElt, Html, Context), Context2 = case Is_visible of - true -> - AllActions = lists:merge([ - {set_value, [{selector, "#"++FormId++" textarea[name=\"message\"]"}, {value, ""}]}, - {set_value, [{selector, "#"++FormId++" input[name=\"message\"]"}, {value, ""}]}, - {fade_in, [{target, "comment-"++integer_to_list(CommentId)}]} - ], ExtraActions), - z_render:wire(AllActions, Context1); - false -> - Context1 - end, + true -> + AllActions = lists:merge([ + {set_value, [{selector, "#"++FormId++" textarea[name=\"message\"]"}, {value, ""}]}, + {set_value, [{selector, "#"++FormId++" input[name=\"message\"]"}, {value, ""}]}, + {fade_in, [{target, "comment-"++integer_to_list(CommentId)}]} + ], ExtraActions), + z_render:wire(AllActions, Context1); + false -> + Context1 + end, case z_convert:to_bool(proplists:get_value(do_redirect, Args, true)) of true -> z_render:wire({redirect, [{location, "#comment-"++integer_to_list(CommentId)}]}, Context2); false -> Context2 @@ -227,11 +245,11 @@ event(#submit{message={newcomment, Args}, form=FormId}, Context) -> event(#postback{message={map_infobox, _Args}}, Context) -> Ids = z_context:get_q(ids, Context), Render = case z_context:get_q(data, Context) of - [] -> - z_template:render("map/map-infobox.tpl", [{results, Ids}], Context); - Data -> - z_template:render("map/map-infobox-data-item.tpl", [{item, Data}], Context) - end, + [] -> + z_template:render("map/map-infobox.tpl", [{results, Ids}], Context); + Data -> + z_template:render("map/map-infobox-data-item.tpl", [{item, Data}], Context) + end, Element = z_context:get_q(element, Context), EscapedRender = z_utils:js_escape(iolist_to_binary(Render)), diff --git a/modules/mod_ginger_base/support/ginger_user_group.erl b/modules/mod_ginger_base/support/ginger_user_group.erl new file mode 100644 index 000000000..0b6856697 --- /dev/null +++ b/modules/mod_ginger_base/support/ginger_user_group.erl @@ -0,0 +1,65 @@ +%% @doc User Group util functions +%% Functions to move the new moderator user group between editor user group and manager user group + +-module(ginger_user_group). + +-export([ + move_moderator_user_group/1, + move_manager_user_group/1 +]). + +move_moderator_user_group(Context0) -> + Context = z_acl:sudo(Context0), + Moderators = m_rsc:name_to_id_check(acl_user_group_moderators, Context), + Editors = m_rsc:name_to_id_check(acl_user_group_editors, Context), + move_user_group(Moderators, Editors, Context). + +move_manager_user_group(Context0) -> + Context = z_acl:sudo(Context0), + Managers = m_rsc:name_to_id_check(acl_user_group_managers, Context), + Moderators = m_rsc:name_to_id_check(acl_user_group_moderators, Context), + move_user_group(Managers, Moderators, Context). + +% based of m_category move_below functionality for categories +move_user_group(UserGroupId, ParentUserGroupId, Context) -> + Tree = m_hierarchy:menu(acl_user_group, Context), + {ok, {Tree1, Node, PrevParentId}} = remove_node(Tree, UserGroupId, undefined), + case PrevParentId of + ParentUserGroupId -> + ok; + _ -> + Tree2 = insert_node(ParentUserGroupId, Node, Tree1, []), + m_hierarchy:save('acl_user_group', Tree2, Context), + flush(Context) + end. + +remove_node([], _Id, _ParentId) -> + notfound; +remove_node([{Id,_Cs}=Node|Ts], Id, ParentId) -> + {ok, {Ts, Node, ParentId}}; +remove_node([{TId,TCs}|Ts], Id, ParentId) -> + case remove_node(TCs, Id, ParentId) of + {ok, {TCs1,Node,PId}} -> + {ok, {[{TId,TCs1}|Ts], Node, PId}}; + notfound -> + case remove_node(Ts, Id, ParentId) of + {ok, {Ts1,Node,PId}} -> + {ok, {[{TId,TCs}|Ts1], Node, PId}}; + notfound -> + notfound + end + end. + +insert_node(undefined, Node, Tree, []) -> + Tree ++ [Node]; +insert_node(_ParentId, _Node, [], Acc) -> + lists:reverse(Acc); +insert_node(ParentId, Node, [{ParentId,TCs}|Tree], Acc) -> + lists:reverse(Acc, [{ParentId,TCs++[Node]} | Tree]); +insert_node(ParentId, Node, [{TId,TCs}|Tree], Acc) -> + T1 = {TId, insert_node(ParentId, Node, TCs, [])}, + insert_node(ParentId, Node, Tree, [T1|Acc]). + +flush(Context) -> + m_hierarchy:flush('acl_user_group', Context), + z_depcache:flush(acl_user_group, Context).