Skip to content

Commit

Permalink
Merge branch 'develop' into OB-5178-set-groupchat-role-based-on-flag
Browse files Browse the repository at this point in the history
  • Loading branch information
tkuzynow authored Sep 5, 2023
2 parents 2c173e6 + f8625b0 commit 8545118
Show file tree
Hide file tree
Showing 34 changed files with 482 additions and 163 deletions.
7 changes: 6 additions & 1 deletion api/useradminservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ paths:
required: true
schema:
type: string
- name: forceDeleteSessions
in: query
schema:
type: boolean
description: parameter specifying if consultant sessions need to be removed prior the deletion
responses:
200:
description: OK - consultant was marked for deletion successfully
Expand Down Expand Up @@ -568,7 +573,7 @@ paths:
parameters:
- name: query
in: query
description: URL-encoded infix to search for in first name, last name, or email.
description: URL-encoded infix to search for in id first name, last name, or email.
A non-encoded star symbol searches for all.
required: true
schema:
Expand Down
5 changes: 4 additions & 1 deletion api/userservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ paths:
parameters:
- name: query
in: query
description: URL-encoded infix to search for in first name, last name, or email.
description: URL-encoded infix to search for in id, first name, last name, or email.
A non-encoded star symbol searches for all.
required: true
schema:
Expand Down Expand Up @@ -2368,6 +2368,9 @@ components:
SessionUserDTO:
type: object
properties:
id:
type: string
example: 926b9777-4eef-443d-925a-4aa534797bd7
username:
type: string
example: max94
Expand Down
2 changes: 1 addition & 1 deletion services/statisticsservice.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ components:
description: The id of the session
example: 12345

ArchiveSessionStatisticsEventMessage:
ArchiveOrDeleteSessionStatisticsEventMessage:
type: object
required:
- sessionId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/** Controller to handle all session admin requests. */
Expand Down Expand Up @@ -167,8 +168,11 @@ public ResponseEntity<Void> deleteConsultantAgency(String consultantId, Long age
* @param consultantId consultant id (required)
*/
@Override
public ResponseEntity<Void> markConsultantForDeletion(@PathVariable String consultantId) {
this.consultantAdminFacade.markConsultantForDeletion(consultantId);
public ResponseEntity<Void> markConsultantForDeletion(
@PathVariable String consultantId,
@Valid @RequestParam(value = "forceDeleteSessions", required = false)
Boolean forceDeleteSessions) {
this.consultantAdminFacade.markConsultantForDeletion(consultantId, forceDeleteSessions);
return new ResponseEntity<>(HttpStatus.OK);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import static org.apache.commons.lang3.BooleanUtils.isTrue;

import com.google.common.collect.Lists;
import de.caritas.cob.userservice.api.actions.registry.ActionsRegistry;
import de.caritas.cob.userservice.api.actions.user.DeactivateKeycloakUserActionCommand;
import de.caritas.cob.userservice.api.adapters.rocketchat.RocketChatCredentials;
import de.caritas.cob.userservice.api.adapters.web.dto.AbsenceDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.AgencyAdminResponseDTO;
Expand Down Expand Up @@ -95,12 +93,11 @@
import de.caritas.cob.userservice.api.service.LogService;
import de.caritas.cob.userservice.api.service.SessionDataService;
import de.caritas.cob.userservice.api.service.archive.SessionArchiveService;
import de.caritas.cob.userservice.api.service.archive.SessionDeleteService;
import de.caritas.cob.userservice.api.service.session.SessionFilter;
import de.caritas.cob.userservice.api.service.session.SessionService;
import de.caritas.cob.userservice.api.service.user.UserAccountService;
import de.caritas.cob.userservice.api.tenant.TenantContext;
import de.caritas.cob.userservice.api.workflow.delete.action.asker.DeleteSingleRoomAndSessionAction;
import de.caritas.cob.userservice.api.workflow.delete.model.SessionDeletionWorkflowDTO;
import de.caritas.cob.userservice.generated.api.adapters.web.controller.UsersApi;
import io.swagger.annotations.Api;
import java.net.URLDecoder;
Expand Down Expand Up @@ -162,7 +159,6 @@ public class UserController implements UsersApi {
private final @NonNull IdentityManaging identityManager;
private final @NonNull AccountManaging accountManager;
private final @NonNull Messaging messenger;
private final @NotNull ActionsRegistry actionsRegistry;
private final @NonNull ConsultantDtoMapper consultantDtoMapper;
private final @NonNull UserDtoMapper userDtoMapper;
private final @NonNull ConsultantService consultantService;
Expand All @@ -177,6 +173,8 @@ public class UserController implements UsersApi {

private final @NonNull EmailNotificationMapper emailNotificationMapper;

private final @NonNull SessionDeleteService sessionDeleteService;

@Override
public ResponseEntity<Void> userExists(String username) {
val usernameAvailable = identityClient.isUsernameAvailable(username);
Expand Down Expand Up @@ -295,26 +293,7 @@ public ResponseEntity<CreateEnquiryMessageResponseDTO> createEnquiryMessage(

@Override
public ResponseEntity<Void> deleteSessionAndInactiveUser(@PathVariable Long sessionId) {
var session =
sessionService
.getSession(sessionId)
.orElseThrow(
() -> new NotFoundException("A session with an id %s does not exist.", sessionId));

var user = session.getUser();
if (user.getSessions().size() == 1) {
actionsRegistry
.buildContainerForType(User.class)
.addActionToExecute(DeactivateKeycloakUserActionCommand.class)
.executeActions(user);
}

var deleteSession = new SessionDeletionWorkflowDTO(session, null);
actionsRegistry
.buildContainerForType(SessionDeletionWorkflowDTO.class)
.addActionToExecute(DeleteSingleRoomAndSessionAction.class)
.executeActions(deleteSession);

sessionDeleteService.deleteSession(sessionId);
return new ResponseEntity<>(HttpStatus.OK);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
Expand All @@ -43,18 +44,21 @@
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApiResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

private static final String BAD_REQUEST = "Bad Request: ";
private static final String USER_SERVICE_API_LOG_PLACEHOLDER = "UserService API: {}: {}";

@ExceptionHandler({DataIntegrityViolationException.class})
public ResponseEntity<Object> handleJPAConstraintViolationException(
final org.hibernate.exception.ConstraintViolationException ex, final WebRequest request) {
log.error("Bad Request: ", ex);
log.error(BAD_REQUEST, ex);

return handleExceptionInternal(ex, null, new HttpHeaders(), HttpStatus.CONFLICT, request);
}

@ExceptionHandler({CreateEnquiryMessageException.class})
public ResponseEntity<Object> handleCreateEnquiryMessageException(
final CreateEnquiryMessageException ex, final WebRequest request) {
log.error("Bad Request: ", ex);
log.error(BAD_REQUEST, ex);

return handleExceptionInternal(ex, null, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
Expand All @@ -68,7 +72,7 @@ public ResponseEntity<Object> handleCreateEnquiryMessageException(
@ExceptionHandler({BadRequestException.class})
public ResponseEntity<Object> handleCustomBadRequest(
final BadRequestException ex, final WebRequest request) {
log.warn("Bad Request: ", ex);
log.warn(BAD_REQUEST, ex);

return handleExceptionInternal(ex, null, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}
Expand Down Expand Up @@ -113,7 +117,7 @@ protected ResponseEntity<Object> handleHttpMessageNotReadable(
final HttpHeaders headers,
final HttpStatus status,
final WebRequest request) {
log.warn("UserService API: {}: {}", status.getReasonPhrase(), ex.getStackTrace());
log.warn(USER_SERVICE_API_LOG_PLACEHOLDER, status.getReasonPhrase(), ex.getStackTrace());

return handleExceptionInternal(null, null, headers, status, request);
}
Expand All @@ -130,7 +134,7 @@ protected ResponseEntity<Object> handleMethodArgumentNotValid(
final HttpHeaders headers,
final HttpStatus status,
final WebRequest request) {
log.warn("UserService API: {}: {}", status.getReasonPhrase(), ex.getStackTrace());
log.warn(USER_SERVICE_API_LOG_PLACEHOLDER, status.getReasonPhrase(), ex);

return handleExceptionInternal(null, null, headers, status, request);
}
Expand Down Expand Up @@ -159,7 +163,7 @@ public ResponseEntity<Object> handleUnauthorized(
@ExceptionHandler({InvalidDataAccessApiUsageException.class})
protected ResponseEntity<Object> handleConflict(
final RuntimeException ex, final WebRequest request) {
log.warn("UserService API: {}: {}", HttpStatus.CONFLICT, ex.getStackTrace());
log.warn(USER_SERVICE_API_LOG_PLACEHOLDER, HttpStatus.CONFLICT, ex.getStackTrace());

return handleExceptionInternal(null, null, new HttpHeaders(), HttpStatus.CONFLICT, request);
}
Expand Down Expand Up @@ -256,4 +260,18 @@ public ResponseEntity<Object> handleInternal(
final NoContentException ex, final WebRequest request) {
return handleExceptionInternal(null, null, new HttpHeaders(), HttpStatus.NO_CONTENT, request);
}

@Override
protected ResponseEntity<Object> handleExceptionInternal(
@Nullable Exception ex,
@Nullable Object body,
HttpHeaders headers,
HttpStatus status,
WebRequest request) {
if (HttpStatus.INTERNAL_SERVER_ERROR.equals(status)) {
request.setAttribute("javax.servlet.error.exception", ex, 0);
}

return new ResponseEntity<>(body, headers, status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
@ApiModel(value = "SessionUser")
public class SessionUserDTO {

@ApiModelProperty(example = "Username", position = 0)
@ApiModelProperty(example = "id", position = 0)
private String id;

@ApiModelProperty(example = "Username", position = 1)
private String username;

@ApiModelProperty(example = "isDeleted", position = 1)
@ApiModelProperty(example = "isDeleted", position = 2)
private boolean isDeleted;

private Map<String, Object> sessionData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public HalLink consultantLinkOf(String id, MethodEnum method) {
httpEntity = userAdminApi.updateConsultant(id, null);
break;
case DELETE:
httpEntity = userAdminApi.markConsultantForDeletion(id);
httpEntity = userAdminApi.markConsultantForDeletion(id, false);
break;
default:
httpEntity = userAdminApi.getConsultant(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ public void markConsultantAgenciesForDeletion(String consultantId, List<Long> ag
*
* @param consultantId the consultant id
*/
public void markConsultantForDeletion(String consultantId) {
this.consultantAdminService.markConsultantForDeletion(consultantId);
public void markConsultantForDeletion(String consultantId, Boolean forceDeleteSessions) {
this.consultantAdminService.markConsultantForDeletion(consultantId, forceDeleteSessions);
}

/**
Expand Down Expand Up @@ -292,7 +292,7 @@ public void checkPermissionsToAssignedAgencies(List<CreateConsultantAgencyDTO> a
adminUserFacade.findAdminUserAgencyIds(authenticatedUser.getUserId());
List<Long> agencyIdsFromTheRequest =
agencyList.stream()
.map(createConsultantAgencyDTO -> createConsultantAgencyDTO.getAgencyId())
.map(CreateConsultantAgencyDTO::getAgencyId)
.collect(Collectors.toList());

if (!adminUserAgencyIds.containsAll(agencyIdsFromTheRequest)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package de.caritas.cob.userservice.api.admin.service.consultant;

import static de.caritas.cob.userservice.api.helper.CustomLocalDateTime.nowInUtc;
import static de.caritas.cob.userservice.api.model.Session.SessionStatus.INITIAL;
import static de.caritas.cob.userservice.api.model.Session.SessionStatus.IN_ARCHIVE;
import static de.caritas.cob.userservice.api.model.Session.SessionStatus.IN_PROGRESS;
import static de.caritas.cob.userservice.api.model.Session.SessionStatus.NEW;

import com.google.common.collect.Lists;
import de.caritas.cob.userservice.api.adapters.web.dto.ConsultantAdminResponseDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.ConsultantResponseDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.CreateConsultantDTO;
Expand All @@ -12,17 +17,21 @@
import de.caritas.cob.userservice.api.admin.service.consultant.update.ConsultantUpdateService;
import de.caritas.cob.userservice.api.exception.httpresponses.NoContentException;
import de.caritas.cob.userservice.api.exception.httpresponses.NotFoundException;
import de.caritas.cob.userservice.api.helper.AuthenticatedUser;
import de.caritas.cob.userservice.api.model.Consultant;
import de.caritas.cob.userservice.api.model.ConsultantStatus;
import de.caritas.cob.userservice.api.port.out.ConsultantRepository;
import de.caritas.cob.userservice.api.port.out.SessionRepository;
import de.caritas.cob.userservice.api.service.appointment.AppointmentService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/** Service class for admin operations on {@link Consultant} objects. */
@Service
@RequiredArgsConstructor
@Slf4j
public class ConsultantAdminService {

private final @NonNull ConsultantRepository consultantRepository;
Expand All @@ -31,6 +40,10 @@ public class ConsultantAdminService {
private final @NonNull ConsultantPreDeletionService consultantPreDeletionService;
private final @NonNull AppointmentService appointmentService;

private final @NonNull SessionRepository sessionRepository;

private final @NonNull AuthenticatedUser authenticatedUser;

/**
* Finds a {@link Consultant} by the given consultant id and throws a {@link NoContentException}
* if no consultant for given id exists.
Expand Down Expand Up @@ -92,18 +105,49 @@ public ConsultantAdminResponseDTO updateConsultant(
* Marks the {@link Consultant} as deleted.
*
* @param consultantId the consultant id
* @param forceDeleteSessions
*/
public void markConsultantForDeletion(String consultantId) {
public void markConsultantForDeletion(String consultantId, Boolean forceDeleteSessions) {
var consultant =
this.consultantRepository
.findByIdAndDeleteDateIsNull(consultantId)
.orElseThrow(
() -> new NotFoundException("Consultant with id %s does not exist", consultantId));

this.consultantPreDeletionService.performPreDeletionSteps(consultant);
this.consultantPreDeletionService.performPreDeletionSteps(consultant, forceDeleteSessions);

if (Boolean.TRUE.equals(forceDeleteSessions)) {
deleteAndUnassignSessions(consultant);
log.info(
"User with id {}, who has roles {}, has deleted in-progress and archived sessions of consultant with id {}",
authenticatedUser.getUserId(),
authenticatedUser.getRoles(),
consultantId);
}

consultant.setDeleteDate(nowInUtc());
consultant.setStatus(ConsultantStatus.IN_DELETION);
this.consultantRepository.save(consultant);
}

private void deleteAndUnassignSessions(Consultant consultant) {
deleteSessionsInProgressOrArchived(consultant);
unassignNewOrInitialSessions(consultant);
}

private void unassignNewOrInitialSessions(Consultant consultant) {
sessionRepository
.findByConsultantAndStatusIn(consultant, Lists.newArrayList(NEW, INITIAL))
.forEach(
session -> {
session.setConsultant(null);
sessionRepository.save(session);
});
}

private void deleteSessionsInProgressOrArchived(Consultant consultant) {
sessionRepository
.findByConsultantAndStatusIn(consultant, Lists.newArrayList(IN_PROGRESS, IN_ARCHIVE))
.forEach(sessionRepository::delete);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private HalLink buildUpdateLink() {

private HalLink buildDeleteLink() {
return buildHalLink(
methodOn(UseradminApi.class).markConsultantForDeletion(this.consultant.getId()),
methodOn(UseradminApi.class).markConsultantForDeletion(this.consultant.getId(), false),
MethodEnum.DELETE);
}

Expand Down
Loading

0 comments on commit 8545118

Please sign in to comment.