| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 1 | package de.ids_mannheim.korap.service; |
| 2 | |
| margaretha | ed053fb | 2019-04-11 15:15:13 +0200 | [diff] [blame] | 3 | import java.sql.SQLException; |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 4 | import java.time.ZonedDateTime; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 5 | import java.util.ArrayList; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 6 | import java.util.Collections; |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 7 | import java.util.HashSet; |
| 8 | import java.util.Iterator; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 9 | import java.util.List; |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 10 | import java.util.Set; |
| margaretha | da5a6ab | 2019-11-08 10:06:05 +0100 | [diff] [blame] | 11 | import java.util.regex.Pattern; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 12 | |
| margaretha | 49cb688 | 2018-07-04 04:19:54 +0200 | [diff] [blame] | 13 | import org.apache.logging.log4j.LogManager; |
| 14 | import org.apache.logging.log4j.Logger; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 15 | import org.springframework.beans.factory.annotation.Autowired; |
| 16 | import org.springframework.stereotype.Service; |
| 17 | |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 18 | import de.ids_mannheim.korap.config.FullConfiguration; |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 19 | import de.ids_mannheim.korap.constant.GroupMemberStatus; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 20 | import de.ids_mannheim.korap.constant.PredefinedRole; |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 21 | import de.ids_mannheim.korap.constant.PrivilegeType; |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 22 | import de.ids_mannheim.korap.constant.UserGroupStatus; |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 23 | import de.ids_mannheim.korap.dao.AdminDao; |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 24 | import de.ids_mannheim.korap.dao.RoleDao; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 25 | import de.ids_mannheim.korap.dao.UserGroupDao; |
| 26 | import de.ids_mannheim.korap.dao.UserGroupMemberDao; |
| 27 | import de.ids_mannheim.korap.dto.UserGroupDto; |
| 28 | import de.ids_mannheim.korap.dto.converter.UserGroupConverter; |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 29 | import de.ids_mannheim.korap.encryption.RandomCodeGenerator; |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 30 | import de.ids_mannheim.korap.entity.Role; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 31 | import de.ids_mannheim.korap.entity.UserGroup; |
| 32 | import de.ids_mannheim.korap.entity.UserGroupMember; |
| 33 | import de.ids_mannheim.korap.exceptions.KustvaktException; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 34 | import de.ids_mannheim.korap.exceptions.StatusCodes; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 35 | import de.ids_mannheim.korap.utils.ParameterChecker; |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 36 | import de.ids_mannheim.korap.web.controller.UserGroupController; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 37 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 38 | /** |
| 39 | * UserGroupService defines the logic behind user group web |
| 40 | * controller. |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 41 | * |
| 42 | * @see UserGroupController |
| 43 | * |
| 44 | * @author margaretha |
| 45 | * |
| 46 | */ |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 47 | @Service |
| 48 | public class UserGroupService { |
| 49 | |
| margaretha | dda4ef7 | 2018-12-06 14:20:51 +0100 | [diff] [blame] | 50 | public static Logger jlog = LogManager.getLogger(UserGroupService.class); |
| 51 | public static boolean DEBUG = false; |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 52 | |
| margaretha | 9645ab0 | 2022-03-31 11:33:03 +0200 | [diff] [blame] | 53 | public static Pattern groupNamePattern = Pattern |
| 54 | .compile("[a-zA-Z0-9]+[a-zA-Z_0-9-.]+"); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 55 | |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 56 | @Autowired |
| 57 | private UserGroupDao userGroupDao; |
| 58 | @Autowired |
| 59 | private UserGroupMemberDao groupMemberDao; |
| 60 | @Autowired |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 61 | private RoleDao roleDao; |
| 62 | @Autowired |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 63 | private AdminDao adminDao; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 64 | @Autowired |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 65 | private UserGroupConverter converter; |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 66 | @Autowired |
| 67 | private FullConfiguration config; |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 68 | @Autowired |
| 69 | private MailService mailService; |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 70 | @Autowired |
| 71 | private RandomCodeGenerator random; |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 72 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 73 | /** |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 74 | * Only users with {@link PredefinedRole#GROUP_ADMIN} |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 75 | * are allowed to see the members of the group. |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 76 | * |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 77 | * @param username |
| 78 | * username |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 79 | * @return a list of usergroups |
| 80 | * @throws KustvaktException |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 81 | * |
| 82 | * @see {@link PredefinedRole} |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 83 | */ |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 84 | public List<UserGroup> retrieveUserGroup (String username) |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 85 | throws KustvaktException { |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 86 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 87 | List<UserGroup> userGroups = userGroupDao |
| 88 | .retrieveGroupByUserId(username); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 89 | Collections.sort(userGroups); |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 90 | return userGroups; |
| 91 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 92 | |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 93 | public List<UserGroupDto> retrieveUserGroupDto (String username) |
| 94 | throws KustvaktException { |
| 95 | List<UserGroup> userGroups = retrieveUserGroup(username); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 96 | |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 97 | ArrayList<UserGroupDto> dtos = new ArrayList<>(userGroups.size()); |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 98 | UserGroupMember userAsMember; |
| 99 | List<UserGroupMember> members; |
| margaretha | 6f28837 | 2018-03-08 18:35:23 +0100 | [diff] [blame] | 100 | UserGroupDto groupDto; |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 101 | for (UserGroup group : userGroups) { |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 102 | members = retrieveMembers(group.getId(), username); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 103 | userAsMember = groupMemberDao.retrieveMemberById(username, |
| 104 | group.getId()); |
| margaretha | 6f28837 | 2018-03-08 18:35:23 +0100 | [diff] [blame] | 105 | groupDto = converter.createUserGroupDto(group, members, |
| 106 | userAsMember.getStatus(), userAsMember.getRoles()); |
| 107 | dtos.add(groupDto); |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | return dtos; |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 111 | |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 112 | } |
| margaretha | cfea1ae | 2018-01-15 20:27:26 +0100 | [diff] [blame] | 113 | |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 114 | private List<UserGroupMember> retrieveMembers (int groupId, String username) |
| 115 | throws KustvaktException { |
| 116 | List<UserGroupMember> groupAdmins = groupMemberDao.retrieveMemberByRole( |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 117 | groupId, PredefinedRole.GROUP_ADMIN); |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 118 | |
| 119 | List<UserGroupMember> members = null; |
| 120 | for (UserGroupMember admin : groupAdmins) { |
| 121 | if (admin.getUserId().equals(username)) { |
| 122 | members = groupMemberDao.retrieveMemberByGroupId(groupId); |
| 123 | break; |
| 124 | } |
| 125 | } |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 126 | |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 127 | return members; |
| 128 | } |
| 129 | |
| margaretha | 541b8cc | 2018-01-10 13:02:46 +0100 | [diff] [blame] | 130 | public UserGroup retrieveUserGroupById (int groupId) |
| 131 | throws KustvaktException { |
| 132 | return userGroupDao.retrieveGroupById(groupId); |
| 133 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 134 | |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 135 | public UserGroup retrieveUserGroupByName (String groupName) |
| 136 | throws KustvaktException { |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 137 | return userGroupDao.retrieveGroupByName(groupName, false); |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 138 | } |
| margaretha | cfea1ae | 2018-01-15 20:27:26 +0100 | [diff] [blame] | 139 | |
| margaretha | b097fb0 | 2021-02-22 19:28:33 +0100 | [diff] [blame] | 140 | public UserGroup retrieveHiddenUserGroupByQuery (int queryId) |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 141 | throws KustvaktException { |
| margaretha | b097fb0 | 2021-02-22 19:28:33 +0100 | [diff] [blame] | 142 | return userGroupDao.retrieveHiddenGroupByQuery(queryId); |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 143 | } |
| 144 | |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 145 | public List<UserGroupDto> retrieveUserGroupByStatus (String username, |
| margaretha | bdde7f4 | 2023-02-10 08:24:03 +0100 | [diff] [blame] | 146 | UserGroupStatus status) throws KustvaktException { |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 147 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 148 | List<UserGroup> userGroups = userGroupDao |
| 149 | .retrieveGroupByStatus(username, status); |
| margaretha | bdde7f4 | 2023-02-10 08:24:03 +0100 | [diff] [blame] | 150 | Collections.sort(userGroups); |
| 151 | ArrayList<UserGroupDto> dtos = new ArrayList<>(userGroups.size()); |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 152 | |
| margaretha | bdde7f4 | 2023-02-10 08:24:03 +0100 | [diff] [blame] | 153 | List<UserGroupMember> members; |
| 154 | UserGroupDto groupDto; |
| 155 | for (UserGroup group : userGroups) { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 156 | members = groupMemberDao.retrieveMemberByGroupId(group.getId(), |
| 157 | true); |
| margaretha | bdde7f4 | 2023-02-10 08:24:03 +0100 | [diff] [blame] | 158 | groupDto = converter.createUserGroupDto(group, members, null, null); |
| 159 | dtos.add(groupDto); |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 160 | } |
| margaretha | bdde7f4 | 2023-02-10 08:24:03 +0100 | [diff] [blame] | 161 | return dtos; |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 162 | } |
| 163 | |
| margaretha | b097fb0 | 2021-02-22 19:28:33 +0100 | [diff] [blame] | 164 | public List<UserGroupMember> retrieveQueryAccessAdmins (UserGroup userGroup) |
| margaretha | cfea1ae | 2018-01-15 20:27:26 +0100 | [diff] [blame] | 165 | throws KustvaktException { |
| 166 | List<UserGroupMember> groupAdmins = groupMemberDao.retrieveMemberByRole( |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 167 | userGroup.getId(), PredefinedRole.QUERY_ACCESS_ADMIN); |
| margaretha | cfea1ae | 2018-01-15 20:27:26 +0100 | [diff] [blame] | 168 | return groupAdmins; |
| 169 | } |
| margaretha | 71e6fca | 2018-01-18 18:11:48 +0100 | [diff] [blame] | 170 | |
| margaretha | 26c592e | 2024-07-18 11:19:00 +0200 | [diff] [blame] | 171 | private Set<Role> prepareMemberRoles (UserGroup userGroup) { |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 172 | Role r1 = new Role(PredefinedRole.GROUP_MEMBER, |
| 173 | PrivilegeType.DELETE_MEMBER, userGroup); |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 174 | roleDao.addRole(r1); |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 175 | Set<Role>memberRoles = new HashSet<Role>(1); |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 176 | memberRoles.add(r1); |
| margaretha | 26c592e | 2024-07-18 11:19:00 +0200 | [diff] [blame] | 177 | return memberRoles; |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 178 | } |
| margaretha | cfea1ae | 2018-01-15 20:27:26 +0100 | [diff] [blame] | 179 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 180 | /** |
| 181 | * Group owner is automatically added when creating a group. |
| 182 | * Do not include owners in group members. |
| 183 | * |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 184 | * {@link PredefinedRole#GROUP_MEMBER} and |
| margaretha | 4a1a18c | 2021-02-26 10:19:54 +0100 | [diff] [blame] | 185 | * {@link PredefinedRole#VC_ACCESS_MEMBER} roles are |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 186 | * automatically assigned to each group member. |
| 187 | * |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 188 | * {@link PredefinedRole#GROUP_MEMBER} restrict users |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 189 | * to see other group members and allow users to remove |
| 190 | * themselves from the groups. |
| 191 | * |
| margaretha | 4a1a18c | 2021-02-26 10:19:54 +0100 | [diff] [blame] | 192 | * {@link PredefinedRole#VC_ACCESS_MEMBER} allow user to |
| margaretha | b097fb0 | 2021-02-22 19:28:33 +0100 | [diff] [blame] | 193 | * read group query. |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 194 | * |
| 195 | * @see /full/src/main/resources/db/predefined/V3.2__insert_predefined_roles.sql |
| 196 | * |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 197 | * @param createdBy |
| 198 | * the user creating the group |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 199 | * @throws KustvaktException |
| 200 | * |
| 201 | * |
| 202 | */ |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 203 | public boolean createUpdateUserGroup (String groupName, String description, |
| 204 | String createdBy) throws KustvaktException { |
| margaretha | 21d3296 | 2019-11-14 17:08:15 +0100 | [diff] [blame] | 205 | ParameterChecker.checkNameValue(groupName, "groupName"); |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 206 | ParameterChecker.checkStringValue(createdBy, "createdBy"); |
| margaretha | d8aa135 | 2019-12-19 11:04:41 +0100 | [diff] [blame] | 207 | |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 208 | if (!groupNamePattern.matcher(groupName).matches()) { |
| margaretha | da5a6ab | 2019-11-08 10:06:05 +0100 | [diff] [blame] | 209 | throw new KustvaktException(StatusCodes.INVALID_ARGUMENT, |
| margaretha | 9645ab0 | 2022-03-31 11:33:03 +0200 | [diff] [blame] | 210 | "User-group name must consists of alphanumerical characters " |
| 211 | + "(limited to ASCII), underscores, dashes and periods. " |
| 212 | + "The name has to start with an alphanumerical character.", |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 213 | groupName); |
| margaretha | da5a6ab | 2019-11-08 10:06:05 +0100 | [diff] [blame] | 214 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 215 | |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 216 | UserGroup userGroup = null; |
| 217 | boolean groupExists = false; |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 218 | try { |
| 219 | userGroup = userGroupDao.retrieveGroupByName(groupName, false); |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 220 | groupExists = true; |
| margaretha | da5a6ab | 2019-11-08 10:06:05 +0100 | [diff] [blame] | 221 | } |
| 222 | catch (KustvaktException e) { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 223 | if (e.getStatusCode() != StatusCodes.NO_RESOURCE_FOUND) { |
| margaretha | da5a6ab | 2019-11-08 10:06:05 +0100 | [diff] [blame] | 224 | throw e; |
| 225 | } |
| 226 | } |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 227 | |
| 228 | if (!groupExists) { |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 229 | try { |
| margaretha | d8aa135 | 2019-12-19 11:04:41 +0100 | [diff] [blame] | 230 | userGroupDao.createGroup(groupName, description, createdBy, |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 231 | UserGroupStatus.ACTIVE); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 232 | userGroup = userGroupDao.retrieveGroupByName(groupName, false); |
| margaretha | ed053fb | 2019-04-11 15:15:13 +0200 | [diff] [blame] | 233 | } |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 234 | // handle DB exceptions, e.g. unique constraint |
| 235 | catch (Exception e) { |
| 236 | Throwable cause = e; |
| 237 | Throwable lastCause = null; |
| 238 | while ((cause = cause.getCause()) != null |
| 239 | && !cause.equals(lastCause)) { |
| 240 | if (cause instanceof SQLException) { |
| 241 | break; |
| 242 | } |
| 243 | lastCause = cause; |
| margaretha | 39cec60 | 2019-02-05 19:48:49 +0100 | [diff] [blame] | 244 | } |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 245 | throw new KustvaktException(StatusCodes.DB_INSERT_FAILED, |
| 246 | cause.getMessage()); |
| 247 | } |
| margaretha | d8aa135 | 2019-12-19 11:04:41 +0100 | [diff] [blame] | 248 | } |
| 249 | else if (description != null) { |
| 250 | userGroup.setDescription(description); |
| 251 | userGroupDao.updateGroup(userGroup); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 252 | } |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 253 | return groupExists; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 254 | } |
| 255 | |
| margaretha | 39cec60 | 2019-02-05 19:48:49 +0100 | [diff] [blame] | 256 | public void deleteGroup (String groupName, String username) |
| 257 | throws KustvaktException { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 258 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, |
| 259 | false); |
| margaretha | 39cec60 | 2019-02-05 19:48:49 +0100 | [diff] [blame] | 260 | if (userGroup.getStatus() == UserGroupStatus.DELETED) { |
| 261 | // EM: should this be "not found" instead? |
| 262 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| 263 | "Group " + userGroup.getName() + " has been deleted.", |
| 264 | userGroup.getName()); |
| 265 | } |
| 266 | else if (userGroup.getCreatedBy().equals(username) |
| 267 | || adminDao.isAdmin(username)) { |
| 268 | // soft delete |
| 269 | userGroupDao.deleteGroup(userGroup.getId(), username, |
| 270 | config.isSoftDeleteGroup()); |
| 271 | } |
| 272 | else { |
| 273 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| 274 | "Unauthorized operation for user: " + username, username); |
| 275 | } |
| 276 | } |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 277 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 278 | public int createAutoHiddenGroup () throws KustvaktException { |
| margaretha | 3ccaeb7 | 2019-02-28 18:40:22 +0100 | [diff] [blame] | 279 | String code = random.createRandomCode(); |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 280 | String groupName = "auto-" + code; |
| margaretha | d8aa135 | 2019-12-19 11:04:41 +0100 | [diff] [blame] | 281 | int groupId = userGroupDao.createGroup(groupName, "auto-hidden-group", |
| 282 | "system", UserGroupStatus.HIDDEN); |
| margaretha | 45dde68 | 2018-01-04 21:33:46 +0100 | [diff] [blame] | 283 | |
| 284 | return groupId; |
| 285 | } |
| margaretha | 71e6fca | 2018-01-18 18:11:48 +0100 | [diff] [blame] | 286 | |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 287 | public void deleteAutoHiddenGroup (int groupId, String deletedBy) |
| 288 | throws KustvaktException { |
| 289 | // default hard delete |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 290 | userGroupDao.deleteGroup(groupId, deletedBy, |
| 291 | config.isSoftDeleteAutoGroup()); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 292 | } |
| 293 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 294 | /** |
| 295 | * Adds a user to the specified usergroup. If the username with |
| 296 | * {@link GroupMemberStatus} DELETED exists as a member of the |
| 297 | * group, |
| 298 | * the entry will be deleted first, and a new entry will be added. |
| 299 | * |
| 300 | * If a username with other statuses exists, a KustvaktException |
| 301 | * will |
| 302 | * be thrown. |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 303 | * |
| 304 | * @see GroupMemberStatus |
| 305 | * |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 306 | * @param username |
| 307 | * a username |
| 308 | * @param userGroup |
| 309 | * a user group |
| 310 | * @param createdBy |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 311 | * the user (query-access admin/system) adding the user |
| 312 | * the user-group |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 313 | * @param status |
| 314 | * the status of the membership |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 315 | * @throws KustvaktException |
| 316 | */ |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 317 | public void inviteGroupMember (String username, UserGroup userGroup, |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 318 | String createdBy, GroupMemberStatus status) |
| margaretha | e8ab51d | 2018-01-16 19:27:40 +0100 | [diff] [blame] | 319 | throws KustvaktException { |
| margaretha | 71e6fca | 2018-01-18 18:11:48 +0100 | [diff] [blame] | 320 | |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 321 | addGroupMember(username, userGroup, createdBy, status); |
| 322 | |
| 323 | if (config.isMailEnabled() |
| 324 | && userGroup.getStatus() != UserGroupStatus.HIDDEN) { |
| 325 | mailService.sendMemberInvitationNotification(username, |
| 326 | userGroup.getName(), createdBy); |
| 327 | } |
| 328 | } |
| 329 | |
| 330 | public void addGroupMember (String username, UserGroup userGroup, |
| 331 | String createdBy, GroupMemberStatus status) |
| 332 | throws KustvaktException { |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 333 | int groupId = userGroup.getId(); |
| 334 | ParameterChecker.checkIntegerValue(groupId, "userGroupId"); |
| 335 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 336 | GroupMemberStatus existingStatus = memberExists(username, groupId, |
| 337 | status); |
| margaretha | 97bb3bd | 2018-03-14 18:41:14 +0100 | [diff] [blame] | 338 | if (existingStatus != null) { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 339 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_EXISTS, |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 340 | "Username " + username + " with status " + existingStatus |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 341 | + " exists in the user-group " |
| 342 | + userGroup.getName(), |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 343 | username, existingStatus.name(), userGroup.getName()); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 344 | } |
| 345 | |
| margaretha | e8ab51d | 2018-01-16 19:27:40 +0100 | [diff] [blame] | 346 | UserGroupMember member = new UserGroupMember(); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 347 | member.setCreatedBy(createdBy); |
| margaretha | e8ab51d | 2018-01-16 19:27:40 +0100 | [diff] [blame] | 348 | member.setGroup(userGroup); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 349 | member.setStatus(status); |
| margaretha | e8ab51d | 2018-01-16 19:27:40 +0100 | [diff] [blame] | 350 | member.setUserId(username); |
| margaretha | e8ab51d | 2018-01-16 19:27:40 +0100 | [diff] [blame] | 351 | groupMemberDao.addMember(member); |
| 352 | } |
| margaretha | 45dde68 | 2018-01-04 21:33:46 +0100 | [diff] [blame] | 353 | |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 354 | private GroupMemberStatus memberExists (String username, int groupId, |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 355 | GroupMemberStatus status) throws KustvaktException { |
| 356 | UserGroupMember existingMember; |
| 357 | try { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 358 | existingMember = groupMemberDao.retrieveMemberById(username, |
| 359 | groupId); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 360 | } |
| 361 | catch (KustvaktException e) { |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 362 | return null; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 363 | } |
| 364 | |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 365 | GroupMemberStatus existingStatus = existingMember.getStatus(); |
| 366 | if (existingStatus.equals(GroupMemberStatus.ACTIVE) |
| 367 | || existingStatus.equals(status)) { |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 368 | return existingStatus; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 369 | } |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 370 | else if (existingStatus.equals(GroupMemberStatus.DELETED)) { |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 371 | // hard delete, not customizable |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 372 | doDeleteMember(username, groupId, "system", false); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 373 | } |
| 374 | |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 375 | return null; |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 376 | } |
| 377 | |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 378 | public void inviteGroupMembers (String groupName, String groupMembers, |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 379 | String inviter) throws KustvaktException { |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 380 | String[] members = groupMembers.split(","); |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 381 | ParameterChecker.checkStringValue(groupName, "group name"); |
| margaretha | ca7cff8 | 2019-11-12 12:06:37 +0100 | [diff] [blame] | 382 | ParameterChecker.checkStringValue(groupMembers, "members"); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 383 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 384 | UserGroup userGroup = retrieveUserGroupByName(groupName); |
| margaretha | c1c3f1d | 2018-03-13 14:39:32 +0100 | [diff] [blame] | 385 | if (userGroup.getStatus() == UserGroupStatus.DELETED) { |
| 386 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| 387 | "Group " + userGroup.getName() + " has been deleted.", |
| 388 | userGroup.getName()); |
| 389 | } |
| 390 | |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 391 | if (isUserGroupAdmin(inviter, userGroup) || adminDao.isAdmin(inviter)) { |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 392 | for (String memberName : members) { |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 393 | inviteGroupMember(memberName, userGroup, inviter, |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 394 | GroupMemberStatus.PENDING); |
| 395 | } |
| 396 | } |
| 397 | else { |
| 398 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 399 | "Unauthorized operation for user: " + inviter, inviter); |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 400 | } |
| 401 | } |
| 402 | |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 403 | public boolean isUserGroupAdmin (String username, UserGroup userGroup) |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 404 | throws KustvaktException { |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 405 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 406 | List<UserGroupMember> userGroupAdmins = groupMemberDao |
| 407 | .retrieveMemberByRole(userGroup.getId(), |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 408 | PredefinedRole.GROUP_ADMIN); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 409 | |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 410 | for (UserGroupMember admin : userGroupAdmins) { |
| 411 | if (username.equals(admin.getUserId())) { |
| 412 | return true; |
| 413 | } |
| 414 | } |
| 415 | return false; |
| 416 | } |
| 417 | |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 418 | public boolean isUserGroupAdmin (UserGroupMember member) |
| 419 | throws KustvaktException { |
| 420 | |
| 421 | for (Role r : member.getRoles()) { |
| 422 | if (r.getName().equals(PredefinedRole.GROUP_ADMIN)) { |
| 423 | return true; |
| 424 | } |
| 425 | } |
| 426 | return false; |
| 427 | } |
| 428 | |
| 429 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 430 | /** |
| 431 | * Updates the {@link GroupMemberStatus} of a pending member |
| 432 | * to {@link GroupMemberStatus#ACTIVE} and add default member |
| 433 | * roles. |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 434 | * |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 435 | * @param groupId |
| 436 | * groupId |
| 437 | * @param username |
| 438 | * the username of the group member |
| margaretha | a0d4d3c | 2018-01-02 12:06:11 +0100 | [diff] [blame] | 439 | * @throws KustvaktException |
| 440 | */ |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 441 | public void acceptInvitation (String groupName, String username) |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 442 | throws KustvaktException { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 443 | |
| 444 | ParameterChecker.checkStringValue(username, "userId"); |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 445 | ParameterChecker.checkStringValue(groupName, "groupName"); |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 446 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 447 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, |
| 448 | false); |
| margaretha | 97bb3bd | 2018-03-14 18:41:14 +0100 | [diff] [blame] | 449 | if (userGroup.getStatus() == UserGroupStatus.DELETED) { |
| 450 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| 451 | "Group " + userGroup.getName() + " has been deleted.", |
| 452 | userGroup.getName()); |
| 453 | } |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 454 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 455 | UserGroupMember member = groupMemberDao.retrieveMemberById(username, |
| 456 | userGroup.getId()); |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 457 | GroupMemberStatus status = member.getStatus(); |
| 458 | if (status.equals(GroupMemberStatus.DELETED)) { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 459 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_DELETED, |
| 460 | username + " has already been deleted from the group " |
| margaretha | 97bb3bd | 2018-03-14 18:41:14 +0100 | [diff] [blame] | 461 | + userGroup.getName(), |
| 462 | username, userGroup.getName()); |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 463 | } |
| 464 | else if (member.getStatus().equals(GroupMemberStatus.ACTIVE)) { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 465 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_EXISTS, |
| 466 | "Username " + username + " with status " + status |
| margaretha | 97bb3bd | 2018-03-14 18:41:14 +0100 | [diff] [blame] | 467 | + " exists in the user-group " |
| 468 | + userGroup.getName(), |
| 469 | username, status.name(), userGroup.getName()); |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 470 | } |
| 471 | // status pending |
| 472 | else { |
| margaretha | dda4ef7 | 2018-12-06 14:20:51 +0100 | [diff] [blame] | 473 | if (DEBUG) { |
| 474 | jlog.debug("status: " + member.getStatusDate()); |
| 475 | } |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 476 | ZonedDateTime expiration = member.getStatusDate().plusMinutes(30); |
| 477 | ZonedDateTime now = ZonedDateTime.now(); |
| margaretha | dda4ef7 | 2018-12-06 14:20:51 +0100 | [diff] [blame] | 478 | if (DEBUG) { |
| 479 | jlog.debug("expiration: " + expiration + ", now: " + now); |
| 480 | } |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 481 | |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 482 | if (expiration.isAfter(now)) { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 483 | member.setStatus(GroupMemberStatus.ACTIVE); |
| margaretha | 26c592e | 2024-07-18 11:19:00 +0200 | [diff] [blame] | 484 | Set<Role> memberRoles = prepareMemberRoles(userGroup); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 485 | member.setRoles(memberRoles); |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 486 | groupMemberDao.updateMember(member); |
| 487 | } |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 488 | else { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 489 | throw new KustvaktException(StatusCodes.INVITATION_EXPIRED); |
| 490 | } |
| 491 | } |
| margaretha | 9d3eb04 | 2017-12-22 11:02:30 +0100 | [diff] [blame] | 492 | } |
| 493 | |
| margaretha | 2c24991 | 2018-01-17 20:07:20 +0100 | [diff] [blame] | 494 | public boolean isMember (String username, UserGroup userGroup) |
| 495 | throws KustvaktException { |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 496 | List<UserGroupMember> members = groupMemberDao |
| 497 | .retrieveMemberByGroupId(userGroup.getId()); |
| margaretha | 2c24991 | 2018-01-17 20:07:20 +0100 | [diff] [blame] | 498 | for (UserGroupMember member : members) { |
| 499 | if (member.getUserId().equals(username) |
| 500 | && member.getStatus().equals(GroupMemberStatus.ACTIVE)) { |
| 501 | return true; |
| 502 | } |
| 503 | } |
| 504 | return false; |
| 505 | } |
| margaretha | 71e6fca | 2018-01-18 18:11:48 +0100 | [diff] [blame] | 506 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 507 | public void deleteGroupMember (String memberId, String groupName, |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 508 | String deletedBy) throws KustvaktException { |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 509 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 510 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, |
| 511 | false); |
| margaretha | 97bb3bd | 2018-03-14 18:41:14 +0100 | [diff] [blame] | 512 | if (userGroup.getStatus() == UserGroupStatus.DELETED) { |
| 513 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| 514 | "Group " + userGroup.getName() + " has been deleted.", |
| 515 | userGroup.getName()); |
| 516 | } |
| 517 | else if (memberId.equals(userGroup.getCreatedBy())) { |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 518 | throw new KustvaktException(StatusCodes.NOT_ALLOWED, |
| 519 | "Operation " + "'delete group owner'" + "is not allowed.", |
| 520 | "delete group owner"); |
| 521 | } |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 522 | else if (memberId.equals(deletedBy) |
| 523 | || isUserGroupAdmin(deletedBy, userGroup) |
| margaretha | 4edc70e | 2018-03-14 22:34:29 +0100 | [diff] [blame] | 524 | || adminDao.isAdmin(deletedBy)) { |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 525 | // soft delete |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 526 | doDeleteMember(memberId, userGroup.getId(), deletedBy, |
| margaretha | 2c019fa | 2018-02-01 19:50:51 +0100 | [diff] [blame] | 527 | config.isSoftDeleteGroupMember()); |
| margaretha | 4566792 | 2018-01-25 21:23:03 +0100 | [diff] [blame] | 528 | } |
| 529 | else { |
| 530 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| 531 | "Unauthorized operation for user: " + deletedBy, deletedBy); |
| 532 | } |
| margaretha | 71e6fca | 2018-01-18 18:11:48 +0100 | [diff] [blame] | 533 | } |
| margaretha | b874ef5 | 2018-01-23 20:26:31 +0100 | [diff] [blame] | 534 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 535 | /** |
| 536 | * Updates the {@link GroupMemberStatus} of a member to |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 537 | * {@link GroupMemberStatus#DELETED} |
| 538 | * |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 539 | * @param userId |
| 540 | * user to be deleted |
| 541 | * @param groupId |
| 542 | * user-group id |
| 543 | * @param deletedBy |
| 544 | * user that issue the delete |
| 545 | * @param isSoftDelete |
| 546 | * true if database entry is to be deleted |
| 547 | * permanently, false otherwise |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 548 | * @throws KustvaktException |
| 549 | */ |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 550 | private void doDeleteMember (String username, int groupId, String deletedBy, |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 551 | boolean isSoftDelete) throws KustvaktException { |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 552 | |
| margaretha | c9f1dfa | 2018-02-07 17:50:33 +0100 | [diff] [blame] | 553 | UserGroup group = userGroupDao.retrieveGroupById(groupId); |
| margaretha | 58e1863 | 2018-02-15 13:04:42 +0100 | [diff] [blame] | 554 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 555 | UserGroupMember member = groupMemberDao.retrieveMemberById(username, |
| 556 | groupId); |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 557 | GroupMemberStatus status = member.getStatus(); |
| 558 | if (isSoftDelete && status.equals(GroupMemberStatus.DELETED)) { |
| margaretha | e6c711b | 2018-02-06 21:55:04 +0100 | [diff] [blame] | 559 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_DELETED, |
| 560 | username + " has already been deleted from the group " |
| 561 | + group.getName(), |
| 562 | username, group.getName()); |
| 563 | } |
| 564 | |
| 565 | groupMemberDao.deleteMember(member, deletedBy, isSoftDelete); |
| 566 | } |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 567 | |
| margaretha | b0eca9d | 2023-02-15 15:03:36 +0100 | [diff] [blame] | 568 | public UserGroupDto searchByName (String groupName) |
| margaretha | 4457383 | 2018-03-21 16:59:59 +0100 | [diff] [blame] | 569 | throws KustvaktException { |
| margaretha | b0eca9d | 2023-02-15 15:03:36 +0100 | [diff] [blame] | 570 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, true); |
| 571 | UserGroupDto groupDto = converter.createUserGroupDto(userGroup, |
| 572 | userGroup.getMembers(), null, null); |
| 573 | return groupDto; |
| margaretha | 4457383 | 2018-03-21 16:59:59 +0100 | [diff] [blame] | 574 | } |
| 575 | |
| margaretha | 26c592e | 2024-07-18 11:19:00 +0200 | [diff] [blame] | 576 | @Deprecated |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 577 | public void editMemberRoles (String username, String groupName, |
| margaretha | 99470ce | 2024-07-17 13:52:37 +0200 | [diff] [blame] | 578 | String memberUsername, List<PredefinedRole> roleList) |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 579 | throws KustvaktException { |
| margaretha | 293ee03 | 2018-03-20 20:11:52 +0100 | [diff] [blame] | 580 | |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 581 | ParameterChecker.checkStringValue(username, "username"); |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 582 | ParameterChecker.checkStringValue(groupName, "groupName"); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 583 | ParameterChecker.checkStringValue(memberUsername, "memberUsername"); |
| 584 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 585 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, true); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 586 | UserGroupStatus groupStatus = userGroup.getStatus(); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 587 | if (groupStatus == UserGroupStatus.DELETED) { |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 588 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 589 | "Usergroup has been deleted."); |
| 590 | } |
| 591 | else if (isUserGroupAdmin(username, userGroup) |
| 592 | || adminDao.isAdmin(username)) { |
| 593 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 594 | UserGroupMember member = groupMemberDao |
| 595 | .retrieveMemberById(memberUsername, userGroup.getId()); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 596 | |
| 597 | if (!member.getStatus().equals(GroupMemberStatus.ACTIVE)) { |
| 598 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_INACTIVE, |
| 599 | memberUsername + " has status " + member.getStatus(), |
| 600 | memberUsername, member.getStatus().name()); |
| 601 | } |
| 602 | |
| 603 | Set<Role> roles = new HashSet<>(); |
| margaretha | 99470ce | 2024-07-17 13:52:37 +0200 | [diff] [blame] | 604 | for (int i = 0; i < roleList.size(); i++) { |
| 605 | roles.add(roleDao.retrieveRoleByName(roleList.get(i))); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 606 | } |
| 607 | member.setRoles(roles); |
| 608 | groupMemberDao.updateMember(member); |
| 609 | |
| 610 | } |
| 611 | else { |
| 612 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| 613 | "Unauthorized operation for user: " + username, username); |
| 614 | } |
| 615 | } |
| 616 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 617 | public void addMemberRoles (String username, String groupName, |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 618 | String memberUsername, List<PredefinedRole> roleNames) |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 619 | throws KustvaktException { |
| 620 | |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 621 | ParameterChecker.checkStringValue(username, "username"); |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 622 | ParameterChecker.checkStringValue(groupName, "groupName"); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 623 | ParameterChecker.checkStringValue(memberUsername, "memberUsername"); |
| 624 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 625 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, true); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 626 | UserGroupStatus groupStatus = userGroup.getStatus(); |
| 627 | if (groupStatus == UserGroupStatus.DELETED) { |
| 628 | throw new KustvaktException(StatusCodes.GROUP_DELETED, |
| 629 | "Usergroup has been deleted."); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 630 | } |
| 631 | else if (isUserGroupAdmin(username, userGroup) |
| 632 | || adminDao.isAdmin(username)) { |
| 633 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 634 | UserGroupMember member = groupMemberDao |
| 635 | .retrieveMemberById(memberUsername, userGroup.getId()); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 636 | |
| 637 | if (!member.getStatus().equals(GroupMemberStatus.ACTIVE)) { |
| 638 | throw new KustvaktException(StatusCodes.GROUP_MEMBER_INACTIVE, |
| 639 | memberUsername + " has status " + member.getStatus(), |
| 640 | memberUsername, member.getStatus().name()); |
| 641 | } |
| 642 | |
| 643 | Set<Role> roles = member.getRoles(); |
| margaretha | 22d3a7c | 2024-07-17 12:57:09 +0200 | [diff] [blame] | 644 | for (PredefinedRole role : roleNames) { |
| margaretha | 777ef10 | 2024-07-22 10:10:50 +0200 | [diff] [blame] | 645 | if (role.equals(PredefinedRole.GROUP_ADMIN)) { |
| 646 | Role r1 = new Role(role,PrivilegeType.READ_MEMBER, userGroup); |
| 647 | roleDao.addRole(r1); |
| 648 | roles.add(r1); |
| 649 | |
| 650 | Role r2 = new Role(role,PrivilegeType.DELETE_MEMBER, userGroup); |
| 651 | roleDao.addRole(r2); |
| 652 | roles.add(r2); |
| 653 | |
| 654 | Role r3 = new Role(role,PrivilegeType.WRITE_MEMBER, userGroup); |
| 655 | roleDao.addRole(r3); |
| 656 | roles.add(r3); |
| 657 | |
| 658 | Role r4 = new Role(role,PrivilegeType.SHARE_QUERY, userGroup); |
| 659 | roleDao.addRole(r4); |
| 660 | roles.add(r4); |
| 661 | |
| 662 | Role r5 = new Role(role,PrivilegeType.DELETE_QUERY, userGroup); |
| 663 | roleDao.addRole(r5); |
| 664 | roles.add(r5); |
| 665 | } |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 666 | } |
| 667 | member.setRoles(roles); |
| 668 | groupMemberDao.updateMember(member); |
| 669 | |
| 670 | } |
| 671 | else { |
| 672 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| 673 | "Unauthorized operation for user: " + username, username); |
| 674 | } |
| 675 | } |
| 676 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 677 | public void deleteMemberRoles (String username, String groupName, |
| margaretha | 99470ce | 2024-07-17 13:52:37 +0200 | [diff] [blame] | 678 | String memberUsername, List<PredefinedRole> rolesToBeDeleted) |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 679 | throws KustvaktException { |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 680 | |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 681 | ParameterChecker.checkStringValue(username, "username"); |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 682 | ParameterChecker.checkStringValue(groupName, "groupName"); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 683 | ParameterChecker.checkStringValue(memberUsername, "memberUsername"); |
| 684 | |
| margaretha | a18ab2b | 2019-11-11 12:55:26 +0100 | [diff] [blame] | 685 | UserGroup userGroup = userGroupDao.retrieveGroupByName(groupName, true); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 686 | |
| 687 | if (isUserGroupAdmin(username, userGroup) |
| 688 | || adminDao.isAdmin(username)) { |
| 689 | |
| margaretha | 35e1ca2 | 2023-11-16 22:00:01 +0100 | [diff] [blame] | 690 | UserGroupMember member = groupMemberDao |
| 691 | .retrieveMemberById(memberUsername, userGroup.getId()); |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 692 | |
| 693 | Set<Role> roles = member.getRoles(); |
| 694 | Iterator<Role> i = roles.iterator(); |
| margaretha | f7abb36 | 2018-09-18 20:09:37 +0200 | [diff] [blame] | 695 | while (i.hasNext()) { |
| margaretha | 99470ce | 2024-07-17 13:52:37 +0200 | [diff] [blame] | 696 | if (rolesToBeDeleted.contains(i.next().getName())) { |
| margaretha | 18533fd | 2018-03-28 16:01:06 +0200 | [diff] [blame] | 697 | i.remove(); |
| 698 | } |
| 699 | } |
| 700 | |
| 701 | member.setRoles(roles); |
| 702 | groupMemberDao.updateMember(member); |
| 703 | |
| 704 | } |
| 705 | else { |
| 706 | throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED, |
| 707 | "Unauthorized operation for user: " + username, username); |
| 708 | } |
| 709 | } |
| margaretha | 0b63de4 | 2017-12-20 18:48:09 +0100 | [diff] [blame] | 710 | } |