Skip to content

Commit

Permalink
Merge pull request #675 from Onlineberatung/OB-6984-improve-log-error…
Browse files Browse the repository at this point in the history
…-handling-for-rocketchat

feat: add handling for restricted consultant admin role and improve rocketchat logging
  • Loading branch information
tkuzynow authored Oct 31, 2023
2 parents 1b3f626 + f4385fe commit 634b61a
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,10 @@ public ResponseEntity<LoginResponseDTO> loginUserFirstTime(String username, Stri
var url = rocketChatConfig.getApiUrl(ENDPOINT_USER_LOGIN);
return restTemplate.postForEntity(url, request, LoginResponseDTO.class);
} catch (Exception ex) {
log.error(
"Rocket.Chat Error: Could not login user ({}) in Rocket.Chat for the first time. Reason",
username,
ex);
throw new RocketChatLoginException(
String.format("Could not login user (%s) in Rocket.Chat for the first time", username));
}
Expand Down Expand Up @@ -566,6 +570,11 @@ public void addUserToGroup(String rcUserId, String rcGroupId)
response = restTemplate.postForObject(url, request, GroupResponseDTO.class);

} catch (Exception ex) {
log.error(
"Rocket.Chat Error: Could not add user {} to Rocket.Chat group with id {}. Reason: ",
rcUserId,
rcGroupId,
ex);
throw new RocketChatAddUserToGroupException(
String.format(
"Could not add user %s to Rocket.Chat group with id %s", rcUserId, rcGroupId));
Expand Down Expand Up @@ -607,6 +616,10 @@ public void leaveFromGroupAsTechnicalUser(String rcGroupId)
response = restTemplate.postForObject(url, request, GroupResponseDTO.class);

} catch (Exception ex) {
log.error(
"Rocket.Chat Error: Could not leave as technical user from Rocket.Chat group with id {}. Reason: ",
rcGroupId,
ex);
throw new RocketChatLeaveFromGroupException(
String.format(
"Could not leave as technical user from Rocket.Chat group with id %s", rcGroupId));
Expand Down Expand Up @@ -639,6 +652,11 @@ public void removeUserFromGroup(String rcUserId, String rcGroupId)
response = restTemplate.postForObject(url, request, GroupResponseDTO.class);

} catch (Exception ex) {
log.error(
"Rocket.Chat Error: Could not remove user {} from Rocket.Chat group with id {}. Reason: ",
rcUserId,
rcGroupId,
ex);
throw new RocketChatRemoveUserFromGroupException(
String.format(
"Could not remove user %s from Rocket.Chat group with id %s", rcUserId, rcGroupId));
Expand Down Expand Up @@ -678,6 +696,7 @@ public List<GroupMemberDTO> getStandardMembersOfGroup(String rcGroupId)
try {
groupMemberList = getChatUsers(rcGroupId);
} catch (Exception exception) {
log.error("Could not get chat users. Reason: ", exception);
throw new RocketChatGetGroupMembersException(
String.format("Group member list from group with id %s is empty", rcGroupId));
}
Expand Down Expand Up @@ -783,6 +802,7 @@ public List<GroupMemberDTO> getMembersOfGroup(String rcGroupId)
GroupMemberResponseDTO.class);

} catch (Exception ex) {
log.error("Could not get chat users. Reason: ", ex);
throw new RocketChatGetGroupMembersException(
String.format("Could not get Rocket.Chat group" + " members for room id %s", rcGroupId),
ex);
Expand Down Expand Up @@ -851,6 +871,7 @@ private void removeMessages(
response = restTemplate.postForObject(url, request, StandardResponseDTO.class);

} catch (Exception ex) {
log.error("Could not clean history of Rocket.Chat group id {}. Reason: ", rcGroupId, ex);
throw new RocketChatRemoveSystemMessagesException(
String.format("Could not clean history of Rocket.Chat group id %s", rcGroupId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public RestrictedTenantDTO getRestrictedTenantData(String subdomain) {

@Cacheable(cacheNames = CacheManagerConfig.TENANT_CACHE, key = "#tenantId")
public RestrictedTenantDTO getRestrictedTenantData(Long tenantId) {
log.info("Calling tenant service to get tenant data for subdomain {}", tenantId);
log.info("Calling tenant service to get tenant data for tenantId {}", tenantId);

return tenantServiceApiControllerFactory
.createControllerApi()
.getRestrictedTenantDataByTenantId(tenantId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.ASSIGN_CONSULTANT_TO_ENQUIRY;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.ASSIGN_CONSULTANT_TO_PEER_SESSION;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.ASSIGN_CONSULTANT_TO_SESSION;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.CONSULTANT_CREATE_UPDATE;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.CONSULTANT_DEFAULT;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.CREATE_NEW_CHAT;
import static de.caritas.cob.userservice.api.config.auth.Authority.AuthorityValue.START_CHAT;
Expand Down Expand Up @@ -47,10 +48,15 @@ UserRole.NOTIFICATIONS_TECHNICAL, singletonList(AuthorityValue.NOTIFICATIONS_TEC
GROUP_CHAT_CONSULTANT(
UserRole.GROUP_CHAT_CONSULTANT,
List.of(CONSULTANT_DEFAULT, CREATE_NEW_CHAT, START_CHAT, STOP_CHAT, UPDATE_CHAT)),
USER_ADMIN(UserRole.USER_ADMIN, singletonList(AuthorityValue.USER_ADMIN)),
USER_ADMIN(
UserRole.USER_ADMIN,
List.of(AuthorityValue.USER_ADMIN, AuthorityValue.CONSULTANT_CREATE_UPDATE)),
SINGLE_TENANT_ADMIN(
UserRole.SINGLE_TENANT_ADMIN, singletonList(AuthorityValue.SINGLE_TENANT_ADMIN)),
TENANT_ADMIN(UserRole.TENANT_ADMIN, singletonList(AuthorityValue.TENANT_ADMIN)),

RESTRICTED_CONSULTANT_ADMIN(
UserRole.RESTRICTED_CONSULTANT_ADMIN, singletonList(CONSULTANT_CREATE_UPDATE)),
RESTRICTED_AGENCY_ADMIN(
UserRole.RESTRICTED_AGENCY_ADMIN, singletonList(AuthorityValue.RESTRICTED_AGENCY_ADMIN));

Expand Down Expand Up @@ -91,6 +97,7 @@ private AuthorityValue() {}
public static final String STOP_CHAT = PREFIX + "STOP_CHAT";
public static final String UPDATE_CHAT = PREFIX + "UPDATE_CHAT";
public static final String USER_ADMIN = PREFIX + "USER_ADMIN";
public static final String CONSULTANT_CREATE_UPDATE = PREFIX + "CONSULTANT_CREATE_UPDATE";
public static final String SINGLE_TENANT_ADMIN = PREFIX + "SINGLE_TENANT_ADMIN";
public static final String TENANT_ADMIN = PREFIX + "TENANT_ADMIN";
public static final String RESTRICTED_AGENCY_ADMIN = PREFIX + "RESTRICTED_AGENCY_ADMIN";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ protected void configure(HttpSecurity http) throws Exception {
.hasAuthority(TENANT_ADMIN)
.antMatchers("/useradmin/data/*")
.hasAnyAuthority(SINGLE_TENANT_ADMIN, RESTRICTED_AGENCY_ADMIN)
.antMatchers(HttpMethod.POST, "/useradmin/consultants/")
.hasAnyAuthority(USER_ADMIN, CONSULTANT_CREATE_UPDATE, TECHNICAL_DEFAULT)
.antMatchers(HttpMethod.PUT, "/useradmin/consultants/{consultantId:" + UUID_PATTERN + "}")
.hasAnyAuthority(USER_ADMIN, CONSULTANT_CREATE_UPDATE, TECHNICAL_DEFAULT)
.antMatchers("/useradmin", "/useradmin/**")
.hasAnyAuthority(USER_ADMIN, TECHNICAL_DEFAULT)
.antMatchers("/users/consultants/search")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public enum UserRole {
AGENCY_ADMIN("agency-admin"),
RESTRICTED_AGENCY_ADMIN("restricted-agency-admin"),
TOPIC_ADMIN("topic-admin"),
NOTIFICATIONS_TECHNICAL("notifications-technical");
NOTIFICATIONS_TECHNICAL("notifications-technical"),
RESTRICTED_CONSULTANT_ADMIN("restricted-consultant-admin");

private final String value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.AGENCY_CONSULTANT_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.CONSULTANT_AGENCIES_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.CONSULTANT_AGENCY_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.CONSULTANT_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.DELETE_ASKER_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.DELETE_CONSULTANT_AGENCY_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.DELETE_CONSULTANT_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.FILTERED_CONSULTANTS_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.GET_CONSULTANT_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.PAGE_PARAM;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.PER_PAGE_PARAM;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.REPORT_PATH;
Expand Down Expand Up @@ -228,7 +228,7 @@ public void getConsultants_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdm
getConsultant_Should_ReturnUnauthorizedAndCallNoMethods_When_noKeycloakAuthorizationIsPresent()
throws Exception {

mvc.perform(get(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(get(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isUnauthorized());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -251,7 +251,7 @@ public void getConsultants_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdm
public void getConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdminAuthority()
throws Exception {

mvc.perform(get(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(get(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isForbidden());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -264,7 +264,7 @@ public void getConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdmi
throws Exception {

mvc.perform(
get(GET_CONSULTANT_PATH + "consultantId")
get(CONSULTANT_PATH + "consultantId")
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isOk());
Expand Down Expand Up @@ -330,7 +330,7 @@ public void getConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdmi
public void
createConsultant_Should_ReturnUnauthorizedAndCallNoMethods_When_noKeycloakAuthorizationIsPresent()
throws Exception {
mvc.perform(post(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(post(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isUnauthorized());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -352,7 +352,7 @@ public void getConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdmi
})
public void createConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdminAuthority()
throws Exception {
mvc.perform(post(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(post(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isForbidden());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -366,7 +366,7 @@ public void createConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserA
CreateConsultantDTO createConsultantDTO = easyRandom.nextObject(CreateConsultantDTO.class);

mvc.perform(
post(GET_CONSULTANT_PATH)
post(CONSULTANT_PATH)
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.contentType(MediaType.APPLICATION_JSON)
Expand All @@ -380,7 +380,7 @@ public void createConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserA
public void
updateConsultant_Should_ReturnUnauthorizedAndCallNoMethods_When_noKeycloakAuthorizationIsPresent()
throws Exception {
mvc.perform(put(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(put(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isUnauthorized());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -402,7 +402,7 @@ public void createConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserA
})
public void updateConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserAdminAuthority()
throws Exception {
mvc.perform(put(GET_CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
mvc.perform(put(CONSULTANT_PATH).cookie(CSRF_COOKIE).header(CSRF_HEADER, CSRF_VALUE))
.andExpect(status().isForbidden());

verifyNoMoreInteractions(consultantAdminFacade);
Expand All @@ -417,7 +417,7 @@ public void updateConsultant_Should_ReturnForbiddenAndCallNoMethods_When_noUserA
easyRandom.nextObject(UpdateAdminConsultantDTO.class);

mvc.perform(
put(GET_CONSULTANT_PATH + "consultantId")
put(CONSULTANT_PATH + "consultantId")
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.contentType(MediaType.APPLICATION_JSON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.ADMIN_DATA_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.AGENCY_ADMIN_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.CONSULTANT_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.TENANT_ADMIN_PATH;
import static de.caritas.cob.userservice.api.adapters.web.controller.UserAdminControllerIT.TENANT_ADMIN_PATH_WITHOUT_SLASH;
import static org.assertj.core.api.Assertions.assertThat;
Expand All @@ -22,6 +23,7 @@
import de.caritas.cob.userservice.api.adapters.keycloak.dto.KeycloakCreateUserResponseDTO;
import de.caritas.cob.userservice.api.adapters.rocketchat.RocketChatCredentialsProvider;
import de.caritas.cob.userservice.api.adapters.web.dto.CreateAdminDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.CreateConsultantDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.PatchAdminDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.UpdateAgencyAdminDTO;
import de.caritas.cob.userservice.api.adapters.web.dto.UpdateTenantAdminDTO;
Expand Down Expand Up @@ -152,6 +154,60 @@ public void setUp() {
.thenReturn(keycloakResponse);
}

@Test
@WithMockUser(authorities = {AuthorityValue.USER_ADMIN})
void createNewConsultant_Should_returnOk_When_requiredConsultantIsGiven() throws Exception {
givenNewConsultantIsCreated();
}

@Test
@WithMockUser(authorities = {AuthorityValue.CREATE_NEW_CHAT})
void createNewConsultant_WithoutValidCredentials_Should_returnAccessDenied() throws Exception {
// given
CreateConsultantDTO createAdminDTO = new EasyRandom().nextObject(CreateConsultantDTO.class);
createAdminDTO.setEmail("[email protected]");

// when, then
this.mockMvc
.perform(
post(CONSULTANT_PATH)
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(createAdminDTO)))
.andExpect(status().isForbidden());
}

@Test
@WithMockUser(authorities = {AuthorityValue.CONSULTANT_CREATE_UPDATE})
void createNewConsultant_WithAuthorityConsultantCreateUpdate_Should_returnOK() throws Exception {
givenNewConsultantIsCreated();
}

private String givenNewConsultantIsCreated() throws Exception {
// given
CreateConsultantDTO createAdminDTO = new EasyRandom().nextObject(CreateConsultantDTO.class);
createAdminDTO.setEmail("[email protected]");

// when
MvcResult mvcResult =
this.mockMvc
.perform(
post(CONSULTANT_PATH)
.cookie(CSRF_COOKIE)
.header(CSRF_HEADER, CSRF_VALUE)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(createAdminDTO)))
.andExpect(status().isOk())
.andExpect(jsonPath("_embedded.id", notNullValue()))
.andExpect(jsonPath("_embedded.username", notNullValue()))
.andExpect(jsonPath("_embedded.lastname", notNullValue()))
.andExpect(jsonPath("_embedded.email", is("[email protected]")))
.andReturn();
String content = mvcResult.getResponse().getContentAsString();
return JsonPath.read(content, "_embedded.id");
}

@Test
@WithMockUser(authorities = {AuthorityValue.USER_ADMIN})
void createNewAgencyAdmin_Should_returnOk_When_requiredCreateAgencyAdminIsGiven()
Expand Down
Loading

0 comments on commit 634b61a

Please sign in to comment.