This is an automated email from the ASF dual-hosted git repository. solomax pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openmeetings.git
commit 478d4dca8cdb82434b81b7f0bfd6412bba156510 Author: Maxim Solodovnik <solomax...@gmail.com> AuthorDate: Fri Dec 16 18:03:47 2022 +0700 [OPENMEETINGS-2566] Group admin can send invitations to group --- .../apache/openmeetings/db/dao/user/GroupDao.java | 8 +++-- .../web/admin/AdminUserChoiceProvider.java | 2 +- .../web/common/GroupChoiceProvider.java | 21 +++++++----- .../web/room/menu/RoomInvitationForm.java | 2 +- .../web/user/calendar/AppointmentDialog.java | 2 +- .../apache/openmeetings/user/TestUserGroup.java | 38 +++++++++++++++++++++- 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/GroupDao.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/GroupDao.java index 6acb8fd8f..273672f77 100644 --- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/GroupDao.java +++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/GroupDao.java @@ -43,6 +43,7 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class GroupDao implements IGroupAdminDataProviderDao<Group> { private static final List<String> searchFields = List.of("name"); + private static final List<String> guSearchFields = List.copyOf(searchFields.stream().map(n -> "group." + n).toList()); @PersistenceContext private EntityManager em; @@ -82,14 +83,15 @@ public class GroupDao implements IGroupAdminDataProviderDao<Group> { private Predicate getAdminFilter(Long adminId, CriteriaBuilder builder, CriteriaQuery<?> query) { Root<GroupUser> root = getRoot(query, GroupUser.class); - return builder.and(builder.equal(root.get("user").get("id"), adminId), builder.isTrue(root.get("moderator"))); + return builder.and(builder.equal(root.get("user").get("id"), adminId) + , builder.isTrue(root.get("moderator"))); } @Override public List<Group> adminGet(String search, Long adminId, long start, long count, SortParam<String> sort) { return DaoHelper.get(em, GroupUser.class, Group.class , (builder, root) -> root.get("group") - , true, search, searchFields, true + , true, search, guSearchFields, true , (b, q) -> getAdminFilter(adminId, b, q) , sort, start, count); } @@ -108,7 +110,7 @@ public class GroupDao implements IGroupAdminDataProviderDao<Group> { public long adminCount(String search, Long adminId) { return DaoHelper.count(em, GroupUser.class , (builder, root) -> builder.countDistinct(root.get("group")) - , search, searchFields, false + , search, guSearchFields, false , (b, q) -> getAdminFilter(adminId, b, q.distinct(true))); } diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminUserChoiceProvider.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminUserChoiceProvider.java index d17449eba..6452dd050 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminUserChoiceProvider.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/AdminUserChoiceProvider.java @@ -48,7 +48,7 @@ public abstract class AdminUserChoiceProvider extends ChoiceProvider<User> { @Override public void query(String term, int page, Response<User> response) { response.addAll(userDao.get(term, true, page * PAGE_SIZE, PAGE_SIZE)); - response.setHasMore(PAGE_SIZE == response.getResults().size()); + response.setHasMore(page * PAGE_SIZE + response.getResults().size() < userDao.count(term, true, -1L)); } @Override diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/GroupChoiceProvider.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/GroupChoiceProvider.java index d4d4332f7..fb9abd995 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/GroupChoiceProvider.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/GroupChoiceProvider.java @@ -19,10 +19,10 @@ package org.apache.openmeetings.web.common; import static org.apache.openmeetings.web.app.WebSession.getUserId; +import static org.apache.openmeetings.web.app.WebSession.getRights; import java.util.ArrayList; import java.util.Collection; -import java.util.List; import java.util.Locale; import org.apache.openmeetings.db.dao.user.GroupDao; @@ -30,7 +30,7 @@ import org.apache.openmeetings.db.dao.user.UserDao; import org.apache.openmeetings.db.entity.user.Group; import org.apache.openmeetings.db.entity.user.GroupUser; import org.apache.openmeetings.db.entity.user.User; -import org.apache.openmeetings.web.app.WebSession; +import org.apache.openmeetings.db.util.AuthLevelUtil; import org.apache.wicket.injection.Injector; import org.apache.wicket.spring.injection.annot.SpringBean; import org.apache.wicket.util.string.Strings; @@ -39,6 +39,7 @@ import org.wicketstuff.select2.Response; public class GroupChoiceProvider extends ChoiceProvider<Group> { private static final long serialVersionUID = 1L; + public static final long PAGE_SIZE = 5; @SpringBean private GroupDao groupDao; @SpringBean @@ -50,13 +51,13 @@ public class GroupChoiceProvider extends ChoiceProvider<Group> { @Override public void query(String term, int page, Response<Group> response) { - if (WebSession.getRights().contains(User.Right.ADMIN)) { - List<Group> groups = groupDao.get(0, Integer.MAX_VALUE); - for (Group g : groups) { - if (Strings.isEmpty(term) || g.getName().toLowerCase(Locale.ROOT).contains(term.toLowerCase(Locale.ROOT))) { - response.add(g); - } - } + long count; + if (AuthLevelUtil.hasAdminLevel(getRights())) { + count = groupDao.count(term); + response.addAll(groupDao.get(term, page * PAGE_SIZE, PAGE_SIZE, null)); + } else if (AuthLevelUtil.hasGroupAdminLevel(getRights())) { + response.addAll(groupDao.adminGet(term, getUserId(), page * PAGE_SIZE, PAGE_SIZE, null)); + count = groupDao.adminCount(term, getUserId()); } else { User u = userDao.get(getUserId()); for (GroupUser ou : u.getGroupUsers()) { @@ -64,7 +65,9 @@ public class GroupChoiceProvider extends ChoiceProvider<Group> { response.add(ou.getGroup()); } } + count = u.getGroupUsers().size(); } + response.setHasMore(page * PAGE_SIZE + response.getResults().size() < count); } @Override diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomInvitationForm.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomInvitationForm.java index e06354d4b..65e11512d 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomInvitationForm.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomInvitationForm.java @@ -81,7 +81,7 @@ public class RoomInvitationForm extends InvitationForm { @Override protected void onInitialize() { groups.setLabel(new ResourceModel("126")); - boolean showGroups = AuthLevelUtil.hasAdminLevel(getRights()); + boolean showGroups = AuthLevelUtil.hasAdminLevel(getRights()) || AuthLevelUtil.hasGroupAdminLevel(getRights()); add(rdi.add(new AjaxFormChoiceComponentUpdatingBehavior() { private static final long serialVersionUID = 1L; diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java index 611338d88..c40359e35 100644 --- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java +++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/calendar/AppointmentDialog.java @@ -370,7 +370,7 @@ public class AppointmentDialog extends Modal<Appointment> { add(feedback.setOutputMarkupId(true)); //General add(ownerPanel.add(owner)); - boolean showGroups = AuthLevelUtil.hasAdminLevel(getRights()); + boolean showGroups = AuthLevelUtil.hasAdminLevel(getRights()) || AuthLevelUtil.hasGroupAdminLevel(getRights()); groups.getSettings().setDropdownParent(AppointmentDialog.this.getMarkupId()); add(rdi.add(new AjaxFormChoiceComponentUpdatingBehavior() { private static final long serialVersionUID = 1L; diff --git a/openmeetings-web/src/test/java/org/apache/openmeetings/user/TestUserGroup.java b/openmeetings-web/src/test/java/org/apache/openmeetings/user/TestUserGroup.java index 5233a9cbb..a0c3a6f8b 100644 --- a/openmeetings-web/src/test/java/org/apache/openmeetings/user/TestUserGroup.java +++ b/openmeetings-web/src/test/java/org/apache/openmeetings/user/TestUserGroup.java @@ -20,11 +20,15 @@ package org.apache.openmeetings.user; import static java.util.UUID.randomUUID; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import org.apache.openmeetings.AbstractOmServerTest; import org.apache.openmeetings.db.dao.user.GroupUserDao; @@ -66,7 +70,7 @@ class TestUserGroup extends AbstractOmServerTest { void addGroup() { Group g = new Group(); g.setName(GROUP_NAME); - Long groupId = groupDao.update(g, null).getId(); //inserted by not checked + Long groupId = groupDao.update(g, null).getId(); assertNotNull(groupId, "New Group have valid id"); List<GroupUser> ul = groupUserDao.get(groupId, 0, 9999); @@ -89,6 +93,38 @@ class TestUserGroup extends AbstractOmServerTest { checkEmptyGroup("dao.getByLogin(user)", userDao.getByLogin(u.getLogin(), u.getType(), u.getDomainId())); } + private Long addGroupUser(User u, String grpNameUq, boolean moderator) { + Group g = new Group(); + g.setName(grpNameUq + randomUUID().toString()); + g = groupDao.update(g, null); + GroupUser gu = new GroupUser(g, u); + gu.setModerator(moderator); + u.getGroupUsers().add(gu); + return g.getId(); + } + + @Test + void groupAdmin() throws Exception { + String uuid = randomUUID().toString(); + User u = getUser(uuid); + u.setGroupUsers(new ArrayList<>()); + + final String uniquePart = randomUUID().toString().replace('-', '_'); + Long idG1 = addGroupUser(u, uniquePart, true); + Long idG2 = addGroupUser(u, uniquePart, true); + Long idG3 = addGroupUser(u, uniquePart, false); + + u = userDao.update(u, null); + + assertEquals(2, groupDao.adminCount(uniquePart, u.getId()), "Count: There should be exatly 2 groups"); + + List<Group> groups = groupDao.adminGet(uniquePart, u.getId(), 0, 10, null); + assertEquals(2, groups.size(), "List: There should be exatly 2 groups"); + Set<Long> groupIds = groups.stream().map(Group::getId).collect(Collectors.toSet()); + assertTrue(groupIds.contains(idG1), "First group should be found"); + assertTrue(groupIds.contains(idG2), "Second group should be found"); + assertFalse(groupIds.contains(idG3), "Third group should NOT be found"); + } @Test void addLdapUserWithoutGroup() throws Exception {