From bcdd5b4d9fc12fddc5354f13ac6b79aab34ba3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Thu, 5 Oct 2023 15:39:29 +0200 Subject: [PATCH 01/37] feat(member-permissions): Add permission annotation to members endpoints --- .../MemberProfileController.java | 4 + .../MemberProfileControllerTest.java | 146 ++++++++++++++---- 2 files changed, 121 insertions(+), 29 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java index f93be953e3..44885afc58 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java @@ -1,5 +1,7 @@ package com.objectcomputing.checkins.services.memberprofile; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; +import com.objectcomputing.checkins.security.permissions.Permissions; import io.micronaut.core.annotation.Nullable; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -127,6 +129,7 @@ public Mono>> findByValue(@Nullable * @return {@link MemberProfileResponseDTO} The created member profile */ @Post() + @RequiredPermission(Permissions.CAN_CREATE_ORGANIZATION_MEMBERS) public Mono> save(@Body @Valid MemberProfileCreateDTO memberProfile) { return Mono.fromCallable(() -> memberProfileServices.saveProfile(fromDTO(memberProfile))) @@ -165,6 +168,7 @@ public Mono> update(@Body @Valid MemberPr * @return */ @Delete("/{id}") + @RequiredPermission(Permissions.CAN_DELETE_ORGANIZATION_MEMBERS) public Mono delete(@NotNull UUID id) { return Mono.fromCallable(() -> memberProfileServices.deleteProfile(id)) .publishOn(Schedulers.fromExecutor(eventLoopGroup)) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java index 5f4933a110..466d52c45f 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java @@ -1,8 +1,24 @@ package com.objectcomputing.checkins.services.memberprofile; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.assertProfilesEqual; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkCreateMemberProfileDTO; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkUpdateMemberProfileDTO; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.fasterxml.jackson.databind.JsonNode; import com.objectcomputing.checkins.services.TestContainersSuite; -import com.objectcomputing.checkins.services.fixture.*; +import com.objectcomputing.checkins.services.fixture.CheckInFixture; +import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; +import com.objectcomputing.checkins.services.fixture.MemberSkillFixture; +import com.objectcomputing.checkins.services.fixture.RoleFixture; +import com.objectcomputing.checkins.services.fixture.SkillFixture; +import com.objectcomputing.checkins.services.fixture.TeamFixture; +import com.objectcomputing.checkins.services.fixture.TeamMemberFixture; import com.objectcomputing.checkins.services.role.RoleType; import com.objectcomputing.checkins.services.skills.Skill; import com.objectcomputing.checkins.services.team.Team; @@ -14,21 +30,18 @@ import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; import io.micronaut.http.hateoas.Resource; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; -import java.util.*; - -import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.*; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class MemberProfileControllerTest extends TestContainersSuite implements MemberProfileFixture, CheckInFixture, SkillFixture, MemberSkillFixture, TeamFixture, TeamMemberFixture, RoleFixture { @@ -49,6 +62,11 @@ private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + @Test public void testGETNonExistingEndpointReturns404() { @@ -65,7 +83,8 @@ public void testGETNonExistingEndpointReturns404() { public void testDeleteThrowsExceptionWhenUserDoesNotExist() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -90,7 +109,8 @@ public void testDeleteThrowsExceptionIfCheckinDataExists() { createADefaultCheckIn(memberProfileOfMember, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -115,7 +135,8 @@ public void testDeleteThrowsExceptionIfMemberSkillExists() { createMemberSkill(memberProfileOfMember, testSkill, "Pro", LocalDate.now()); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -140,7 +161,8 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { createDefaultTeamMember(testTeam, memberProfileOfMember); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -159,11 +181,12 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { public void testDeleteThrowsExceptionIfMemberHasPDLRole() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); - - createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + assignPdlRole(memberProfileOfPDL); +// createAndAssignRole(RoleType.PDL, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfPDL.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -185,7 +208,8 @@ public void testDeleteHappyPath() { MemberProfile memberProfileOfMember = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -211,11 +235,23 @@ public void testDeleteHappyPath() { @Test public void testDeleteNotAuthorized() { + final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); + } + + @Test + public void testDeleteNoPermission() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); } @@ -321,12 +357,15 @@ void testFindBySupervisorId() { } @Test - public void testPOSTCreateAMemberProfile() { + public void testPOSTCreateAMemberProfileAdmin() { + + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); final HttpRequest request = HttpRequest. - POST("/", dto).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + POST("/", dto).basicAuth(admin.getWorkEmail(), RoleType.Constants.ADMIN_ROLE); final HttpResponse response = client.toBlocking().exchange(request, MemberProfile.class); assertNotNull(response); @@ -335,13 +374,52 @@ public void testPOSTCreateAMemberProfile() { assertEquals(String.format("%s/%s", request.getPath(), response.body().getId()), "/services" + response.getHeaders().get("location")); } + @Test + public void testPOSTCreateAMemberProfileMemberUnauthorized() { + + MemberProfile member = createADefaultMemberProfile(); + assignMemberRole(member); + + MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); + + final HttpRequest request = HttpRequest. + POST("/", dto).basicAuth(member.getWorkEmail(), MEMBER_ROLE); + final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertUnauthorized(exception); + } + + @Test + public void testPOSTCreateAMemberProfilePdlUnauthorized() { + + MemberProfile pdl = createADefaultMemberProfile(); + assignPdlRole(pdl); + + MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); + + final HttpRequest request = HttpRequest. + POST("/", dto).basicAuth(pdl.getWorkEmail(), PDL_ROLE); + final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertUnauthorized(exception); + } + + public void assertUnauthorized(HttpClientResponseException exception) { + assertEquals("Forbidden", exception.getMessage()); + assertEquals(HttpStatus.FORBIDDEN, exception.getStatus()); + } + @Test public void testPOSTCreateANullMemberProfile() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileCreateDTO memberProfileCreateDTO = new MemberProfileCreateDTO(); final HttpRequest request = HttpRequest. - POST("/", memberProfileCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + POST("/", memberProfileCreateDTO).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -352,9 +430,11 @@ public void testPOSTCreateANullMemberProfile() { // Find By id - when no user data exists for POST @Test public void testPostValidationFailures() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); final HttpRequest request = HttpRequest.POST("", new MemberProfileCreateDTO()) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -367,10 +447,13 @@ public void testPostValidationFailures() { @Test public void testPOSTSaveMemberSameEmailThrowsException() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); + // create a user MemberProfileUpdateDTO firstUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); final HttpResponse responseFirstUser = client.toBlocking().exchange(requestFirstUser, MemberProfile.class); assertNotNull(responseFirstUser); @@ -378,7 +461,7 @@ public void testPOSTSaveMemberSameEmailThrowsException() { // create another user with same email address MemberProfileUpdateDTO secondUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(requestSecondUser, Map.class)); @@ -436,13 +519,16 @@ public void testPUTUpdateNullMemberProfile() { // POST - Future Start Date @Test public void testPostForFutureStartDate() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); + MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setStartDate(maxDate); final HttpResponse response = client .toBlocking() .exchange(HttpRequest.POST("", requestBody) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE), MemberProfileResponseDTO.class); + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE), MemberProfileResponseDTO.class); assertEquals(HttpStatus.CREATED, response.getStatus()); assertNotNull(response.body()); @@ -453,12 +539,14 @@ public void testPostForFutureStartDate() { // POST - NotBlank MemberProfile first name (and last name) @Test public void testPostWithNullName() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setFirstName(null); final HttpRequest request = HttpRequest.POST("", requestBody) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); From f328a661f7a9152c55a87ca676258fb440506f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Thu, 5 Oct 2023 15:40:39 +0200 Subject: [PATCH 02/37] Revert "feat(member-permissions): Add permission annotation to members endpoints" This reverts commit bcdd5b4d9fc12fddc5354f13ac6b79aab34ba3ab. --- .../MemberProfileController.java | 4 - .../MemberProfileControllerTest.java | 146 ++++-------------- 2 files changed, 29 insertions(+), 121 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java index 44885afc58..f93be953e3 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java @@ -1,7 +1,5 @@ package com.objectcomputing.checkins.services.memberprofile; -import com.objectcomputing.checkins.services.permissions.RequiredPermission; -import com.objectcomputing.checkins.security.permissions.Permissions; import io.micronaut.core.annotation.Nullable; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -129,7 +127,6 @@ public Mono>> findByValue(@Nullable * @return {@link MemberProfileResponseDTO} The created member profile */ @Post() - @RequiredPermission(Permissions.CAN_CREATE_ORGANIZATION_MEMBERS) public Mono> save(@Body @Valid MemberProfileCreateDTO memberProfile) { return Mono.fromCallable(() -> memberProfileServices.saveProfile(fromDTO(memberProfile))) @@ -168,7 +165,6 @@ public Mono> update(@Body @Valid MemberPr * @return */ @Delete("/{id}") - @RequiredPermission(Permissions.CAN_DELETE_ORGANIZATION_MEMBERS) public Mono delete(@NotNull UUID id) { return Mono.fromCallable(() -> memberProfileServices.deleteProfile(id)) .publishOn(Schedulers.fromExecutor(eventLoopGroup)) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java index 466d52c45f..5f4933a110 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java @@ -1,24 +1,8 @@ package com.objectcomputing.checkins.services.memberprofile; -import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.assertProfilesEqual; -import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkCreateMemberProfileDTO; -import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkUpdateMemberProfileDTO; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import com.fasterxml.jackson.databind.JsonNode; import com.objectcomputing.checkins.services.TestContainersSuite; -import com.objectcomputing.checkins.services.fixture.CheckInFixture; -import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; -import com.objectcomputing.checkins.services.fixture.MemberSkillFixture; -import com.objectcomputing.checkins.services.fixture.RoleFixture; -import com.objectcomputing.checkins.services.fixture.SkillFixture; -import com.objectcomputing.checkins.services.fixture.TeamFixture; -import com.objectcomputing.checkins.services.fixture.TeamMemberFixture; +import com.objectcomputing.checkins.services.fixture.*; import com.objectcomputing.checkins.services.role.RoleType; import com.objectcomputing.checkins.services.skills.Skill; import com.objectcomputing.checkins.services.team.Team; @@ -30,18 +14,21 @@ import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; import io.micronaut.http.hateoas.Resource; +import org.junit.jupiter.api.Test; + import jakarta.inject.Inject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import java.util.*; + +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.*; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class MemberProfileControllerTest extends TestContainersSuite implements MemberProfileFixture, CheckInFixture, SkillFixture, MemberSkillFixture, TeamFixture, TeamMemberFixture, RoleFixture { @@ -62,11 +49,6 @@ private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } - @BeforeEach - void createRolesAndPermissions() { - createAndAssignRoles(); - } - @Test public void testGETNonExistingEndpointReturns404() { @@ -83,8 +65,7 @@ public void testGETNonExistingEndpointReturns404() { public void testDeleteThrowsExceptionWhenUserDoesNotExist() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -109,8 +90,7 @@ public void testDeleteThrowsExceptionIfCheckinDataExists() { createADefaultCheckIn(memberProfileOfMember, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -135,8 +115,7 @@ public void testDeleteThrowsExceptionIfMemberSkillExists() { createMemberSkill(memberProfileOfMember, testSkill, "Pro", LocalDate.now()); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -161,8 +140,7 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { createDefaultTeamMember(testTeam, memberProfileOfMember); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -181,12 +159,11 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { public void testDeleteThrowsExceptionIfMemberHasPDLRole() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); - assignPdlRole(memberProfileOfPDL); -// createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + + createAndAssignRole(RoleType.PDL, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfPDL.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -208,8 +185,7 @@ public void testDeleteHappyPath() { MemberProfile memberProfileOfMember = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - assignAdminRole(memberProfileOfAdmin); -// createAndAssignAdminRole(memberProfileOfAdmin); + createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -235,23 +211,11 @@ public void testDeleteHappyPath() { @Test public void testDeleteNotAuthorized() { - final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); - HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); - - assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); - } - - @Test - public void testDeleteNoPermission() { - MemberProfile pdlMember = createAnUnrelatedUser(); - assignPdlRole(pdlMember); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") - .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); } @@ -357,15 +321,12 @@ void testFindBySupervisorId() { } @Test - public void testPOSTCreateAMemberProfileAdmin() { - - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); + public void testPOSTCreateAMemberProfile() { MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); final HttpRequest request = HttpRequest. - POST("/", dto).basicAuth(admin.getWorkEmail(), RoleType.Constants.ADMIN_ROLE); + POST("/", dto).basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse response = client.toBlocking().exchange(request, MemberProfile.class); assertNotNull(response); @@ -374,52 +335,13 @@ public void testPOSTCreateAMemberProfileAdmin() { assertEquals(String.format("%s/%s", request.getPath(), response.body().getId()), "/services" + response.getHeaders().get("location")); } - @Test - public void testPOSTCreateAMemberProfileMemberUnauthorized() { - - MemberProfile member = createADefaultMemberProfile(); - assignMemberRole(member); - - MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); - - final HttpRequest request = HttpRequest. - POST("/", dto).basicAuth(member.getWorkEmail(), MEMBER_ROLE); - final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); - - assertUnauthorized(exception); - } - - @Test - public void testPOSTCreateAMemberProfilePdlUnauthorized() { - - MemberProfile pdl = createADefaultMemberProfile(); - assignPdlRole(pdl); - - MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); - - final HttpRequest request = HttpRequest. - POST("/", dto).basicAuth(pdl.getWorkEmail(), PDL_ROLE); - final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); - - assertUnauthorized(exception); - } - - public void assertUnauthorized(HttpClientResponseException exception) { - assertEquals("Forbidden", exception.getMessage()); - assertEquals(HttpStatus.FORBIDDEN, exception.getStatus()); - } - @Test public void testPOSTCreateANullMemberProfile() { - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); MemberProfileCreateDTO memberProfileCreateDTO = new MemberProfileCreateDTO(); final HttpRequest request = HttpRequest. - POST("/", memberProfileCreateDTO).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); + POST("/", memberProfileCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -430,11 +352,9 @@ public void testPOSTCreateANullMemberProfile() { // Find By id - when no user data exists for POST @Test public void testPostValidationFailures() { - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); final HttpRequest request = HttpRequest.POST("", new MemberProfileCreateDTO()) - .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -447,13 +367,10 @@ public void testPostValidationFailures() { @Test public void testPOSTSaveMemberSameEmailThrowsException() { - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); - // create a user MemberProfileUpdateDTO firstUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); + final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse responseFirstUser = client.toBlocking().exchange(requestFirstUser, MemberProfile.class); assertNotNull(responseFirstUser); @@ -461,7 +378,7 @@ public void testPOSTSaveMemberSameEmailThrowsException() { // create another user with same email address MemberProfileUpdateDTO secondUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); + final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(requestSecondUser, Map.class)); @@ -519,16 +436,13 @@ public void testPUTUpdateNullMemberProfile() { // POST - Future Start Date @Test public void testPostForFutureStartDate() { - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); - MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setStartDate(maxDate); final HttpResponse response = client .toBlocking() .exchange(HttpRequest.POST("", requestBody) - .basicAuth(admin.getWorkEmail(), ADMIN_ROLE), MemberProfileResponseDTO.class); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE), MemberProfileResponseDTO.class); assertEquals(HttpStatus.CREATED, response.getStatus()); assertNotNull(response.body()); @@ -539,14 +453,12 @@ public void testPostForFutureStartDate() { // POST - NotBlank MemberProfile first name (and last name) @Test public void testPostWithNullName() { - MemberProfile admin = createADefaultMemberProfile(); - assignAdminRole(admin); MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setFirstName(null); final HttpRequest request = HttpRequest.POST("", requestBody) - .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); From fd19db3d40f98dd4b1f1cbc14024c07a38523603 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Thu, 5 Oct 2023 15:43:05 +0200 Subject: [PATCH 03/37] feat(member-permissions): Add permission annotation to members endpoints --- .../MemberProfileController.java | 4 + .../MemberProfileControllerTest.java | 254 ++++++++++++------ 2 files changed, 175 insertions(+), 83 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java index f93be953e3..44885afc58 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java @@ -1,5 +1,7 @@ package com.objectcomputing.checkins.services.memberprofile; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; +import com.objectcomputing.checkins.security.permissions.Permissions; import io.micronaut.core.annotation.Nullable; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -127,6 +129,7 @@ public Mono>> findByValue(@Nullable * @return {@link MemberProfileResponseDTO} The created member profile */ @Post() + @RequiredPermission(Permissions.CAN_CREATE_ORGANIZATION_MEMBERS) public Mono> save(@Body @Valid MemberProfileCreateDTO memberProfile) { return Mono.fromCallable(() -> memberProfileServices.saveProfile(fromDTO(memberProfile))) @@ -165,6 +168,7 @@ public Mono> update(@Body @Valid MemberPr * @return */ @Delete("/{id}") + @RequiredPermission(Permissions.CAN_DELETE_ORGANIZATION_MEMBERS) public Mono delete(@NotNull UUID id) { return Mono.fromCallable(() -> memberProfileServices.deleteProfile(id)) .publishOn(Schedulers.fromExecutor(eventLoopGroup)) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java index 5f4933a110..cc194ea4d0 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileControllerTest.java @@ -1,8 +1,24 @@ package com.objectcomputing.checkins.services.memberprofile; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.assertProfilesEqual; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkCreateMemberProfileDTO; +import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.mkUpdateMemberProfileDTO; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.fasterxml.jackson.databind.JsonNode; import com.objectcomputing.checkins.services.TestContainersSuite; -import com.objectcomputing.checkins.services.fixture.*; +import com.objectcomputing.checkins.services.fixture.CheckInFixture; +import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; +import com.objectcomputing.checkins.services.fixture.MemberSkillFixture; +import com.objectcomputing.checkins.services.fixture.RoleFixture; +import com.objectcomputing.checkins.services.fixture.SkillFixture; +import com.objectcomputing.checkins.services.fixture.TeamFixture; +import com.objectcomputing.checkins.services.fixture.TeamMemberFixture; import com.objectcomputing.checkins.services.role.RoleType; import com.objectcomputing.checkins.services.skills.Skill; import com.objectcomputing.checkins.services.team.Team; @@ -14,24 +30,21 @@ import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; import io.micronaut.http.hateoas.Resource; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; -import java.util.*; - -import static com.objectcomputing.checkins.services.memberprofile.MemberProfileTestUtil.*; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class MemberProfileControllerTest extends TestContainersSuite implements MemberProfileFixture, CheckInFixture, - SkillFixture, MemberSkillFixture, TeamFixture, TeamMemberFixture, RoleFixture { + SkillFixture, MemberSkillFixture, TeamFixture, TeamMemberFixture, RoleFixture { @Inject @Client("/services/member-profiles") @@ -49,12 +62,17 @@ private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + @Test public void testGETNonExistingEndpointReturns404() { HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { client.toBlocking().exchange(HttpRequest.GET(String.valueOf(UUID.randomUUID())) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); }); assertNotNull(thrown.getResponse()); @@ -65,13 +83,14 @@ public void testGETNonExistingEndpointReturns404() { public void testDeleteThrowsExceptionWhenUserDoesNotExist() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); JsonNode body = responseException.getResponse().getBody(JsonNode.class).orElse(null); String error = Objects.requireNonNull(body).get("message").asText(); @@ -90,18 +109,19 @@ public void testDeleteThrowsExceptionIfCheckinDataExists() { createADefaultCheckIn(memberProfileOfMember, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request)); + () -> client.toBlocking().exchange(request)); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); assertEquals( - String.format("User %s cannot be deleted since Checkin record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), - responseException.getMessage() + String.format("User %s cannot be deleted since Checkin record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), + responseException.getMessage() ); } @@ -115,18 +135,19 @@ public void testDeleteThrowsExceptionIfMemberSkillExists() { createMemberSkill(memberProfileOfMember, testSkill, "Pro", LocalDate.now()); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request)); + () -> client.toBlocking().exchange(request)); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); assertEquals( - String.format("User %s cannot be deleted since MemberSkill record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), - responseException.getMessage() + String.format("User %s cannot be deleted since MemberSkill record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), + responseException.getMessage() ); } @@ -140,18 +161,19 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { createDefaultTeamMember(testTeam, memberProfileOfMember); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request)); + () -> client.toBlocking().exchange(request)); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); assertEquals( - String.format("User %s cannot be deleted since TeamMember record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), - responseException.getMessage() + String.format("User %s cannot be deleted since TeamMember record(s) exist", MemberProfileUtils.getFullName(memberProfileOfMember)), + responseException.getMessage() ); } @@ -159,22 +181,23 @@ public void testDeleteThrowsExceptionIfMemberIsPartOfATeam() { public void testDeleteThrowsExceptionIfMemberHasPDLRole() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); - - createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + assignPdlRole(memberProfileOfPDL); +// createAndAssignRole(RoleType.PDL, memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfPDL.getId().toString()) - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request)); + () -> client.toBlocking().exchange(request)); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); assertEquals( - String.format("User %s cannot be deleted since user has PDL role", MemberProfileUtils.getFullName(memberProfileOfPDL)), - responseException.getMessage() + String.format("User %s cannot be deleted since user has PDL role", MemberProfileUtils.getFullName(memberProfileOfPDL)), + responseException.getMessage() ); } @@ -185,20 +208,21 @@ public void testDeleteHappyPath() { MemberProfile memberProfileOfMember = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); +// createAndAssignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.DELETE(memberProfileOfMember.getId().toString()) - .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); final HttpResponse response = client.toBlocking().exchange(request); assertEquals(HttpStatus.OK, response.getStatus()); // Ensure profile is Deleted and not Terminated final HttpRequest requestForAssertingDeletion = HttpRequest.GET(String.format("/%s", memberProfileOfMember.getId())) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(requestForAssertingDeletion, Map.class)); + () -> client.toBlocking().exchange(requestForAssertingDeletion, Map.class)); JsonNode body = responseException.getResponse().getBody(JsonNode.class).orElse(null); String error = Objects.requireNonNull(body).get("message").asText(); @@ -211,11 +235,23 @@ public void testDeleteHappyPath() { @Test public void testDeleteNotAuthorized() { + final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); + } + + @Test + public void testDeleteNoPermission() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); final HttpRequest request = HttpRequest.DELETE("/01b7d769-9fa2-43ff-95c7-f3b950a27bf9") - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); } @@ -225,7 +261,7 @@ public void testDeleteNotAuthorized() { public void testGETFindByNameReturnsEmptyBody() throws UnsupportedEncodingException { final HttpRequest request = HttpRequest. - GET(String.format("/?name=%s", encodeValue("dnc"))).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + GET(String.format("/?name=%s", encodeValue("dnc"))).basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(MemberProfile.class)); @@ -237,7 +273,7 @@ public void testGETFindByValueName() throws UnsupportedEncodingException { MemberProfile memberProfile = createADefaultMemberProfile(); final HttpRequest request = HttpRequest. - GET(String.format("/?firstName=%s", encodeValue(memberProfile.getFirstName()))).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + GET(String.format("/?firstName=%s", encodeValue(memberProfile.getFirstName()))).basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(MemberProfile.class)); @@ -251,7 +287,7 @@ public void testGETGetByIdHappyPath() { MemberProfile memberProfile = createADefaultMemberProfile(); final HttpRequest request = HttpRequest. - GET(String.format("/%s", memberProfile.getId())).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + GET(String.format("/%s", memberProfile.getId())).basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse response = client.toBlocking().exchange(request, MemberProfile.class); @@ -263,10 +299,10 @@ public void testGETGetByIdHappyPath() { public void testGETGetByIdNotFound() { final HttpRequest request = HttpRequest. - GET(String.format("/%s", UUID.randomUUID().toString())).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + GET(String.format("/%s", UUID.randomUUID().toString())).basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertNotNull(responseException.getResponse()); assertEquals(HttpStatus.NOT_FOUND, responseException.getStatus()); @@ -277,7 +313,7 @@ void testFindByMemberName() throws UnsupportedEncodingException { MemberProfile memberProfile = createADefaultMemberProfile(); final HttpRequest request = HttpRequest.GET(String.format("/?firstName=%s", encodeValue(memberProfile.getFirstName()))) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(MemberProfile.class)); assertEquals(Set.of(memberProfile), response.body()); @@ -313,7 +349,7 @@ void testFindBySupervisorId() { MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPdl); final HttpRequest request = HttpRequest.GET(String.format("/?supervisorId=%s", memberProfileOfUser.getSupervisorid())) - .basicAuth(memberProfileOfUser.getWorkEmail(), MEMBER_ROLE); + .basicAuth(memberProfileOfUser.getWorkEmail(), MEMBER_ROLE); final HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(MemberProfile.class)); assertEquals(Set.of(memberProfileOfUser), response.body()); @@ -321,12 +357,15 @@ void testFindBySupervisorId() { } @Test - public void testPOSTCreateAMemberProfile() { + public void testPOSTCreateAMemberProfileAdmin() { + + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); final HttpRequest request = HttpRequest. - POST("/", dto).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + POST("/", dto).basicAuth(admin.getWorkEmail(), RoleType.Constants.ADMIN_ROLE); final HttpResponse response = client.toBlocking().exchange(request, MemberProfile.class); assertNotNull(response); @@ -335,15 +374,54 @@ public void testPOSTCreateAMemberProfile() { assertEquals(String.format("%s/%s", request.getPath(), response.body().getId()), "/services" + response.getHeaders().get("location")); } + @Test + public void testPOSTCreateAMemberProfileMemberUnauthorized() { + + MemberProfile member = createADefaultMemberProfile(); + assignMemberRole(member); + + MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); + + final HttpRequest request = HttpRequest. + POST("/", dto).basicAuth(member.getWorkEmail(), MEMBER_ROLE); + final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertUnauthorized(exception); + } + + @Test + public void testPOSTCreateAMemberProfilePdlUnauthorized() { + + MemberProfile pdl = createADefaultMemberProfile(); + assignPdlRole(pdl); + + MemberProfileUpdateDTO dto = mkUpdateMemberProfileDTO(); + + final HttpRequest request = HttpRequest. + POST("/", dto).basicAuth(pdl.getWorkEmail(), PDL_ROLE); + final HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertUnauthorized(exception); + } + + public void assertUnauthorized(HttpClientResponseException exception) { + assertEquals("Forbidden", exception.getMessage()); + assertEquals(HttpStatus.FORBIDDEN, exception.getStatus()); + } + @Test public void testPOSTCreateANullMemberProfile() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileCreateDTO memberProfileCreateDTO = new MemberProfileCreateDTO(); final HttpRequest request = HttpRequest. - POST("/", memberProfileCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + POST("/", memberProfileCreateDTO).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertNotNull(responseException.getResponse()); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); @@ -352,11 +430,13 @@ public void testPOSTCreateANullMemberProfile() { // Find By id - when no user data exists for POST @Test public void testPostValidationFailures() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); final HttpRequest request = HttpRequest.POST("", new MemberProfileCreateDTO()) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); JsonNode body = thrown.getResponse().getBody(JsonNode.class).orElse(null); JsonNode errors = Objects.requireNonNull(body).get(Resource.EMBEDDED).get("errors"); @@ -367,10 +447,13 @@ public void testPostValidationFailures() { @Test public void testPOSTSaveMemberSameEmailThrowsException() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); + // create a user MemberProfileUpdateDTO firstUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + final HttpRequest requestFirstUser = HttpRequest.POST("/", firstUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); final HttpResponse responseFirstUser = client.toBlocking().exchange(requestFirstUser, MemberProfile.class); assertNotNull(responseFirstUser); @@ -378,10 +461,10 @@ public void testPOSTSaveMemberSameEmailThrowsException() { // create another user with same email address MemberProfileUpdateDTO secondUser = mkUpdateMemberProfileDTO(); - final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + final HttpRequest requestSecondUser = HttpRequest.POST("/", secondUser).basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(requestSecondUser, Map.class)); + () -> client.toBlocking().exchange(requestSecondUser, Map.class)); JsonNode body = responseException.getResponse().getBody(JsonNode.class).orElse(null); String error = Objects.requireNonNull(body).get("message").asText(); @@ -398,7 +481,7 @@ public void testPUTUpdateMemberProfile() { MemberProfileUpdateDTO profileUpdateDTO = mkUpdateMemberProfileDTO(); final HttpRequest request = HttpRequest.PUT("/", profileUpdateDTO) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); final HttpResponse response = client.toBlocking().exchange(request, MemberProfileResponseDTO.class); assertProfilesEqual(profileUpdateDTO, response.body()); @@ -414,9 +497,9 @@ public void testPUTUpdateNonexistentMemberProfile() { memberProfileCreateDTO.setLastName("gentleman"); final HttpRequest request = HttpRequest. - PUT("/", memberProfileCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + PUT("/", memberProfileCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertNotNull(responseException.getResponse()); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); @@ -427,7 +510,7 @@ public void testPUTUpdateNullMemberProfile() { final HttpRequest request = HttpRequest.PUT("", "").basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertNotNull(responseException.getResponse()); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); @@ -436,13 +519,16 @@ public void testPUTUpdateNullMemberProfile() { // POST - Future Start Date @Test public void testPostForFutureStartDate() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); + MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setStartDate(maxDate); final HttpResponse response = client - .toBlocking() - .exchange(HttpRequest.POST("", requestBody) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE), MemberProfileResponseDTO.class); + .toBlocking() + .exchange(HttpRequest.POST("", requestBody) + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE), MemberProfileResponseDTO.class); assertEquals(HttpStatus.CREATED, response.getStatus()); assertNotNull(response.body()); @@ -453,14 +539,16 @@ public void testPostForFutureStartDate() { // POST - NotBlank MemberProfile first name (and last name) @Test public void testPostWithNullName() { + MemberProfile admin = createADefaultMemberProfile(); + assignAdminRole(admin); MemberProfileCreateDTO requestBody = mkCreateMemberProfileDTO(); requestBody.setFirstName(null); final HttpRequest request = HttpRequest.POST("", requestBody) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(admin.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException exception = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); assertEquals(HttpStatus.BAD_REQUEST, exception.getStatus()); } @@ -470,9 +558,9 @@ public void testPostWithNullName() { public void testPutValidationFailures() { final HttpRequest request = HttpRequest.PUT("", new MemberProfileUpdateDTO()) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, - () -> client.toBlocking().exchange(request, Map.class)); + () -> client.toBlocking().exchange(request, Map.class)); JsonNode body = thrown.getResponse().getBody(JsonNode.class).orElse(null); JsonNode errors = Objects.requireNonNull(body).get(Resource.EMBEDDED).get("errors"); @@ -489,9 +577,9 @@ public void testPutFutureStartDate() { requestBody.setStartDate(maxDate); final HttpResponse response = client - .toBlocking() - .exchange(HttpRequest.PUT("", requestBody) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE), MemberProfileResponseDTO.class); + .toBlocking() + .exchange(HttpRequest.PUT("", requestBody) + .basicAuth(MEMBER_ROLE, MEMBER_ROLE), MemberProfileResponseDTO.class); assertEquals(HttpStatus.OK, response.getStatus()); assertProfilesEqual(requestBody, Objects.requireNonNull(response.body())); @@ -503,7 +591,7 @@ public void testPutUpdateForEmptyInput() { MemberProfileUpdateDTO testMemberProfile = mkUpdateMemberProfileDTO(); testMemberProfile.setId(null); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(HttpRequest.PUT("", testMemberProfile) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE))); + .basicAuth(MEMBER_ROLE, MEMBER_ROLE))); JsonNode body = thrown.getResponse().getBody(JsonNode.class).orElse(null); JsonNode error = Objects.requireNonNull(body).get("_embedded").get("errors").get(0).get("message"); assertEquals("memberProfile.id: must not be null", error.asText()); @@ -514,8 +602,8 @@ public void testPutUpdateForEmptyInput() { public void testMemberProfileWithNullTerminationDate() { MemberProfile memberProfile = createADefaultMemberProfile(); final HttpResponse> response = client - .toBlocking() - .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); + .toBlocking() + .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(1, response.body().size()); @@ -527,8 +615,8 @@ public void testMemberProfileWithUpcomingTerminationDate() { MemberProfile memberProfile = createAFutureTerminatedMemberProfile(); final HttpResponse> response = client - .toBlocking() - .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); + .toBlocking() + .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(1, response.body().size()); @@ -540,8 +628,8 @@ public void testMemberProfileWithPreviousTerminationDate() { MemberProfile memberProfile = createAPastTerminatedMemberProfile(); final HttpResponse> response = client - .toBlocking() - .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); + .toBlocking() + .exchange(HttpRequest.GET("").basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(0, response.body().size()); @@ -552,8 +640,8 @@ public void testMemberProfileWithPreviousTerminationDateReturnsWhenTerminatedTru MemberProfile memberProfile = createAPastTerminatedMemberProfile(); final HttpResponse> response = client - .toBlocking() - .exchange(HttpRequest.GET("/?terminated=true").basicAuth(ADMIN_ROLE, ADMIN_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); + .toBlocking() + .exchange(HttpRequest.GET("/?terminated=true").basicAuth(ADMIN_ROLE, ADMIN_ROLE), Argument.listOf(MemberProfileResponseDTO.class)); assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(1, response.body().size()); From 25645763f7f9bcb8c6a79770d5686395653bd53c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Mon, 20 Nov 2023 15:31:43 +0100 Subject: [PATCH 04/37] feat(member-permissions): Add permission annotation to members endpoints --- .../src/main/resources/db/dev/R__Load_testing_data.sql | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 59e379c594..14b37bd683 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -10,7 +10,9 @@ delete from guild; delete from member_skills; delete from pulse_response; delete from questions; +delete from member_roles; delete from role_permissions; +delete from permissions; delete from role; delete from team_member; delete from team; @@ -589,10 +591,10 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -insert into role_permissions - (roleid, permissionid) -values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); +-- insert into role_permissions +-- (roleid, permissionid) +-- values +-- ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); insert into role_permissions (roleid, permissionid) From 7e6a588bdb8016d6f490c7f1320145f200adf7ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Tue, 21 Nov 2023 10:58:39 +0100 Subject: [PATCH 05/37] feat(member-permissions): Add permission annotation to members endpoints - add permissions to reports --- server/TODO | 5 ++ .../security/permissions/Permissions.java | 4 +- .../skillsreport/SkillsReportController.java | 3 + .../AnniversaryReportController.java | 3 + .../birthday/BirthDayController.java | 3 + .../MemberProfileReportController.java | 3 + .../RetentionReportController.java | 3 + .../src/main/resources/application-local.yml | 4 +- .../resources/db/dev/R__Load_testing_data.sql | 34 ++++++-- .../services/fixture/PermissionFixture.java | 7 +- .../SkillsReportControllerTest.java | 72 ++++++++++++++--- .../AnniversaryReportControllerTest.java | 26 ++++--- .../birthday/BirthDayControllerTest.java | 26 ++++--- .../MemberProfileReportControllerTest.java | 51 ++++++++---- .../RetentionReportControllerTest.java | 78 ++++++++++++++----- 15 files changed, 240 insertions(+), 82 deletions(-) create mode 100644 server/TODO diff --git a/server/TODO b/server/TODO new file mode 100644 index 0000000000..8c97c1c5d1 --- /dev/null +++ b/server/TODO @@ -0,0 +1,5 @@ +com.objectcomputing.checkins.services.member_skill.skillsreport.SkillsReportController +com.objectcomputing.checkins.services.memberprofile.retentionreport.RetentionReportController +com.objectcomputing.checkins.services.memberprofile.anniversaryreport.AnniversaryReportController +com.objectcomputing.checkins.services.memberprofile.birthday.BirthDayController +com.objectcomputing.checkins.services.memberprofile.csvreport.MemberProfileReportController \ No newline at end of file diff --git a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java index 0733a45497..0f752d205f 100644 --- a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java +++ b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java @@ -8,5 +8,7 @@ public enum Permissions { CAN_DELETE_ORGANIZATION_MEMBERS, CAN_CREATE_ORGANIZATION_MEMBERS, CAN_VIEW_ROLE_PERMISSIONS, - CAN_VIEW_PERMISSIONS + CAN_VIEW_PERMISSIONS, + CAN_VIEW_ADMIN_REPORT, + CAN_VIEW_PDL_REPORT } \ No newline at end of file diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java index c85b326080..da37e1065b 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java @@ -1,5 +1,6 @@ package com.objectcomputing.checkins.services.member_skill.skillsreport; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -18,6 +19,7 @@ import javax.validation.constraints.NotNull; import java.net.URI; import java.util.concurrent.ExecutorService; +import com.objectcomputing.checkins.security.permissions.Permissions; @Controller("/reports/skills") @Secured(SecurityRule.IS_AUTHENTICATED) @@ -44,6 +46,7 @@ public SkillsReportController(SkillsReportServices skillsReportServices, * @return {@link SkillsReportResponseDTO} Returned skills report */ @Post() + @RequiredPermission(Permissions.CAN_VIEW_PDL_REPORT) public Mono> reportSkills(@Body @Valid @NotNull SkillsReportRequestDTO requestBody, HttpRequest request) { return Mono.fromCallable(() -> skillsReportServices.report(requestBody)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java index a63406ab84..50f1b48b10 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java @@ -1,5 +1,7 @@ package com.objectcomputing.checkins.services.memberprofile.anniversaryreport; +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Consumes; @@ -49,6 +51,7 @@ public AnniversaryReportController(AnniversaryServices anniversaryServices, */ @Get("/{?month}") + @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) public Mono>> findByValue(@Nullable String[] month) { return Mono.fromCallable(() -> anniversaryServices.findByValue(month)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java index 58de204f11..cb0fdaa518 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java @@ -1,6 +1,8 @@ package com.objectcomputing.checkins.services.memberprofile.birthday; +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Consumes; @@ -51,6 +53,7 @@ public BirthDayController(BirthDayServices birthDayServices, */ @Get("/{?month,dayOfMonth}") + @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) public Mono>> findByValue(@Nullable String[] month, @Nullable Integer[] dayOfMonth) { return Mono.fromCallable(() -> birthDayServices.findByValue(month, dayOfMonth)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java index 30bed21706..5d3ae2de5d 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java @@ -1,8 +1,10 @@ package com.objectcomputing.checkins.services.memberprofile.csvreport; +import com.objectcomputing.checkins.security.permissions.Permissions; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices; import com.objectcomputing.checkins.services.memberprofile.MemberProfileUtils; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; import io.micronaut.http.HttpResponse; import io.micronaut.http.MutableHttpResponse; import io.micronaut.scheduling.TaskExecutors; @@ -44,6 +46,7 @@ public MemberProfileReportController(MemberProfileServices memberProfileServices } @Get(uri = "/csv", produces = MediaType.TEXT_CSV) + @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) public Mono> generateCsv() { return Flux.defer(() -> Flux.fromIterable(memberProfileServices.findByValues(null, null, null, null, null, null, false))) .subscribeOn(ioScheduler) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java index 9b66ea004e..c35b7f04d9 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java @@ -1,6 +1,8 @@ package com.objectcomputing.checkins.services.memberprofile.retentionreport; import com.objectcomputing.checkins.exceptions.BadArgException; +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -46,6 +48,7 @@ public RetentionReportController(RetentionReportServices retentionReportServices * @return {@link RetentionReportResponseDTO} Returned retention report */ @Post() + @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) public Mono> reportRetention(@Body @Valid @NotNull RetentionReportRequestDTO requestBody, HttpRequest request) { if (requestBody.getStartDate().isAfter(requestBody.getEndDate()) || diff --git a/server/src/main/resources/application-local.yml b/server/src/main/resources/application-local.yml index 4a4cf8c206..24b840a6be 100755 --- a/server/src/main/resources/application-local.yml +++ b/server/src/main/resources/application-local.yml @@ -30,8 +30,8 @@ micronaut: datasources: default: url: ${JDBC_URL:`jdbc:postgresql://localhost:5432/checkinsdb`} - username: postgres - password: "postgres" + username: armm + password: armm --- credentials: roles: diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 14b37bd683..92cdde0456 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -532,10 +532,20 @@ values ('1fd790d9-df9a-4201-818b-3a9ac5e5be3b', 'CAN_VIEW_ROLE_PERMISSIONS'); insert into permissions - (id, permission) +(id, permission) values ('f6961946-a792-4a16-b675-d8cf7980c17a', 'CAN_VIEW_PERMISSIONS'); +insert into permissions +(id, permission) +values + ('f7e815de-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_ADMIN_REPORT'); + +insert into permissions +(id, permission) +values + ('f7e81958-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_PDL_REPORT'); + insert into role_permissions (roleid, permissionid) values @@ -572,10 +582,20 @@ values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1fd790d9-df9a-4201-818b-3a9ac5e5be3b'); insert into role_permissions - (roleid, permissionid) +(roleid, permissionid) values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f6961946-a792-4a16-b675-d8cf7980c17a'); +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e815de-8849-11ee-b9d1-0242ac120002'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e81958-8849-11ee-b9d1-0242ac120002'); + insert into role_permissions (roleid, permissionid) values @@ -587,14 +607,14 @@ values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '1bf32dfe-a204-4c80-889e-829ca66c999b'); insert into role_permissions - (roleid, permissionid) +(roleid, permissionid) values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); --- insert into role_permissions --- (roleid, permissionid) --- values --- ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e81958-8849-11ee-b9d1-0242ac120002'); insert into role_permissions (roleid, permissionid) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 44c6e19a01..02675b9048 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -23,7 +23,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_CREATE_FEEDBACK_REQUEST, Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_PDL_REPORT ); // Add ADMIN Permissions here @@ -35,7 +36,9 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_DELETE_ORGANIZATION_MEMBERS, Permissions.CAN_CREATE_ORGANIZATION_MEMBERS, Permissions.CAN_VIEW_ROLE_PERMISSIONS, - Permissions.CAN_VIEW_PERMISSIONS + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_ADMIN_REPORT, + Permissions.CAN_VIEW_PDL_REPORT ); default Permission createACustomPermission(Permissions perm) { diff --git a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java index cdf50e1dde..b4e8423a61 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java @@ -1,8 +1,15 @@ package com.objectcomputing.checkins.services.member_skill.skillsreport; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.MemberSkillFixture; +import com.objectcomputing.checkins.services.fixture.RoleFixture; import com.objectcomputing.checkins.services.fixture.SkillFixture; import com.objectcomputing.checkins.services.member_skill.MemberSkill; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; @@ -13,24 +20,34 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; import java.time.LocalDate; -import java.util.*; - -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.jupiter.api.Assertions.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class SkillsReportControllerTest extends TestContainersSuite - implements MemberSkillFixture, MemberProfileFixture, SkillFixture { + implements MemberSkillFixture, MemberProfileFixture, SkillFixture, RoleFixture { @Inject @Client("/reports/skills") HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + @Test void testValidRequestNonEmptyResponse() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); + final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); final MemberSkill memberSkill = createMemberSkill(memberProfile, skill, SkillLevel.ADVANCED_LEVEL, LocalDate.now()); @@ -44,7 +61,7 @@ void testValidRequestNonEmptyResponse() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); final HttpResponse response = client.toBlocking() .exchange(request, SkillsReportResponseDTO.class); @@ -62,6 +79,9 @@ void testValidRequestNonEmptyResponse() { @Test void testValidRequestEmptyResponse() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); + final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); createMemberSkill(memberProfile, skill, SkillLevel.INTERMEDIATE_LEVEL, null); @@ -75,7 +95,7 @@ void testValidRequestEmptyResponse() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); final HttpResponse response = client.toBlocking() .exchange(request, SkillsReportResponseDTO.class); @@ -88,6 +108,9 @@ void testValidRequestEmptyResponse() { @Test void testInvalidRequestSkillNotExist() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); + final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); final List skillLevelDTOList = new ArrayList<>(); final SkillLevelDTO skillLevelDTO = new SkillLevelDTO(); @@ -98,7 +121,7 @@ void testInvalidRequestSkillNotExist() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -107,6 +130,9 @@ void testInvalidRequestSkillNotExist() { @Test void testInvalidRequestMemberProfileNotExist() { + MemberProfile pdlMember = createAnUnrelatedUser(); + assignPdlRole(pdlMember); + final Skill skill = createADefaultSkill(); final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); @@ -121,10 +147,34 @@ void testInvalidRequestMemberProfileNotExist() { skillsReportRequestDTO.setMembers(members); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); assertEquals(HttpStatus.BAD_REQUEST, responseException.getStatus()); } + + @Test + void testInvalidRequestMemberDoesntHavePermissions() { + final Skill skill = createADefaultSkill(); + + final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); + final List skillLevelDTOList = new ArrayList<>(); + final SkillLevelDTO skillLevelDTO = new SkillLevelDTO(); + skillLevelDTO.setId(skill.getId()); + skillLevelDTOList.add(skillLevelDTO); + skillsReportRequestDTO.setSkills(skillLevelDTOList); + final Set members = new HashSet<>(); + final UUID memberId = UUID.randomUUID(); + members.add(memberId); + skillsReportRequestDTO.setMembers(members); + + final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) + .basicAuth(MEMBER_ROLE, MEMBER_ROLE); + HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().exchange(request, Map.class)); + + assertEquals(HttpStatus.FORBIDDEN, responseException.getStatus()); + } + } diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportControllerTest.java index 187eb24f2f..d70244818e 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportControllerTest.java @@ -1,10 +1,14 @@ package com.objectcomputing.checkins.services.memberprofile.anniversaryreport; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.RoleFixture; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; -import com.objectcomputing.checkins.services.role.RoleType; import io.micronaut.core.type.Argument; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; @@ -12,19 +16,14 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Objects; - -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class AnniversaryReportControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture { @@ -32,6 +31,11 @@ public class AnniversaryReportControllerTest extends TestContainersSuite impleme @Client("/services/reports/anniversaries") private HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } @@ -39,7 +43,7 @@ private String encodeValue(String value) throws UnsupportedEncodingException { @Test public void testGETFindByMonthReturnsEmptyBody() throws UnsupportedEncodingException { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest. GET(String.format("/?month=%s", encodeValue(memberProfileOfAdmin.getStartDate().getMonth().toString()))).basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -53,7 +57,7 @@ public void testGETFindByMonthReturnsEmptyBody() throws UnsupportedEncodingExcep @Test public void testGETFindByMonthNotAuthorized() throws UnsupportedEncodingException { MemberProfile memberProfile = createAnUnrelatedUser(); - createAndAssignRole(RoleType.MEMBER, memberProfile); + assignMemberRole(memberProfile); final HttpRequest request = HttpRequest. GET(String.format("/?month=%s", encodeValue("dnc"))).basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE); @@ -71,7 +75,7 @@ public void testGETFindByMonthNotAuthorized() throws UnsupportedEncodingExceptio public void testGETFindByNoValue() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.GET("").basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayControllerTest.java index 2a8f29f1e5..a90dd9dff1 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayControllerTest.java @@ -1,29 +1,26 @@ package com.objectcomputing.checkins.services.memberprofile.birthday; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.RoleFixture; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; -import com.objectcomputing.checkins.services.memberprofile.anniversaryreport.AnniversaryReportResponseDTO; import io.micronaut.core.type.Argument; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; -import io.micronaut.http.annotation.Controller; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; -import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; - -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class BirthDayControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture { @@ -31,11 +28,16 @@ public class BirthDayControllerTest extends TestContainersSuite implements Membe @Client("/services/reports/birthdays") private HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + @Test public void testGETFindByValueNameOfTheMonth() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); MemberProfile memberProfile = createADefaultMemberProfileWithBirthDay(); final HttpRequest request = HttpRequest. @@ -52,7 +54,7 @@ public void testGETFindByValueNameOfTheMonth() { public void testGETFindByValueNameOfTheMonthAndDay() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); MemberProfile memberProfile = createADefaultMemberProfileWithBirthDayToday(); createADefaultMemberProfileWithBirthDayNotToday(); diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportControllerTest.java index 5983c079d9..592bb6f4cc 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportControllerTest.java @@ -1,13 +1,15 @@ package com.objectcomputing.checkins.services.memberprofile.csvreport; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.RoleFixture; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; -import com.objectcomputing.checkins.services.memberprofile.birthday.BirthDayResponseDTO; -import com.objectcomputing.checkins.services.memberprofile.retentionreport.RetentionReportRequestDTO; -import com.objectcomputing.checkins.services.memberprofile.retentionreport.RetentionReportResponseDTO; -import io.micronaut.core.type.Argument; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.HttpStatus; @@ -15,27 +17,23 @@ import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; import jakarta.inject.Inject; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.time.LocalDate; -import java.util.List; - -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class MemberProfileReportControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture { @Inject @Client("/services/reports/member") private HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } @@ -44,12 +42,12 @@ private String encodeValue(String value) throws UnsupportedEncodingException { public void testGETReportSucceeds() { MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); MemberProfile memberProfile = createADefaultMemberProfile(); final HttpRequest request = HttpRequest. - GET("/csv").basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + GET("/csv").basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); HttpResponse response = client.toBlocking().exchange(request, File.class); assertNotNull(response); @@ -59,4 +57,23 @@ public void testGETReportSucceeds() { assertNotNull(responseBody); } + @Test + public void testGETReportNoPermissions() { + + MemberProfile memberProfileOfPdl = createAnUnrelatedUser(); + assignPdlRole(memberProfileOfPdl); + + MemberProfile memberProfile = createADefaultMemberProfile(); + + final HttpRequest request = HttpRequest. + GET("/csv").basicAuth(memberProfileOfPdl.getWorkEmail(), PDL_ROLE); + + HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { + client.toBlocking().exchange(request, File.class); + }); + + assertNotNull(thrown.getResponse()); + assertEquals(HttpStatus.FORBIDDEN, thrown.getStatus()); + } + } diff --git a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportControllerTest.java index 27d5f66723..f23825fc8e 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportControllerTest.java @@ -1,6 +1,11 @@ package com.objectcomputing.checkins.services.memberprofile.retentionreport; -import com.fasterxml.jackson.databind.JsonNode; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.RoleFixture; @@ -11,38 +16,39 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - import jakarta.inject.Inject; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDate; -import java.util.Objects; - -import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static org.junit.Assert.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class RetentionReportControllerTest extends TestContainersSuite implements MemberProfileFixture, RoleFixture { @Inject @Client("/reports/retention") private HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } + private String encodeValue(String value) throws UnsupportedEncodingException { return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); } @Test public void testPOSTEmptyRequestReturns400() { + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); + RetentionReportRequestDTO dto = new RetentionReportRequestDTO(); HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { client.toBlocking().exchange(HttpRequest.POST("", dto) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE)); }); assertNotNull(thrown.getResponse()); @@ -51,6 +57,9 @@ public void testPOSTEmptyRequestReturns400() { @Test public void testPOSTNullStartDateReturns400() { + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); + RetentionReportRequestDTO dto = new RetentionReportRequestDTO(); dto.setStartDate(null); dto.setEndDate(LocalDate.now()); @@ -58,7 +67,7 @@ public void testPOSTNullStartDateReturns400() { HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { client.toBlocking().exchange(HttpRequest.POST("", dto) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE)); }); assertNotNull(thrown.getResponse()); @@ -67,6 +76,9 @@ public void testPOSTNullStartDateReturns400() { @Test public void testPOSTNullEndDateReturns400() { + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); + RetentionReportRequestDTO dto = new RetentionReportRequestDTO(); dto.setStartDate(LocalDate.now()); dto.setEndDate(null); @@ -74,7 +86,7 @@ public void testPOSTNullEndDateReturns400() { HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { client.toBlocking().exchange(HttpRequest.POST("", dto) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE)); }); assertNotNull(thrown.getResponse()); @@ -83,6 +95,9 @@ public void testPOSTNullEndDateReturns400() { @Test public void testPOSTEndDateBeforeStartDateReturns400() { + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); + RetentionReportRequestDTO dto = new RetentionReportRequestDTO(); dto.setStartDate(LocalDate.now()); dto.setEndDate(LocalDate.now().minusMonths(1)); @@ -90,7 +105,7 @@ public void testPOSTEndDateBeforeStartDateReturns400() { HttpClientResponseException thrown = assertThrows(HttpClientResponseException.class, () -> { client.toBlocking().exchange(HttpRequest.POST("", dto) - .basicAuth(MEMBER_ROLE, MEMBER_ROLE)); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE)); }); assertNotNull(thrown.getResponse()); @@ -105,7 +120,7 @@ void testValidRequestEmptyResponse() { dto.setFrequency("WEEKLY"); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.POST("", dto) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -127,7 +142,7 @@ void testValidEmptyFrequencyResponse() { dto.setFrequency(""); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.POST("", dto) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -149,7 +164,7 @@ void testValidCaseIgnoreFrequencyResponse() { dto.setFrequency("MoNtHlY"); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.POST("", dto) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -176,7 +191,7 @@ void testCorrectRetentionResponse() { final MemberProfile memberProfile4 = createATerminatedNewHireProfile(); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfAdmin); + assignAdminRole(memberProfileOfAdmin); final HttpRequest request = HttpRequest.POST("", dto) .basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); @@ -190,4 +205,29 @@ void testCorrectRetentionResponse() { assertEquals(String.format("%s", request.getPath()), response.getHeaders().get("Location")); } + @Test + void testCorrectRetentionNoPermission() { + RetentionReportRequestDTO dto = new RetentionReportRequestDTO(); + dto.setStartDate(LocalDate.now().minusMonths(2)); + dto.setEndDate(LocalDate.now()); + dto.setFrequency("MONTHLY"); + + final MemberProfile memberProfile1 = createAPastMemberProfile(); + final MemberProfile memberProfile2 = createAPastTerminatedMemberProfile(); + final MemberProfile memberProfile3 = createANewHireProfile(); + final MemberProfile memberProfile4 = createATerminatedNewHireProfile(); + + MemberProfile memberProfile = createAnUnrelatedUser(); + assignMemberRole(memberProfile); + + final HttpRequest request = HttpRequest.POST("", dto) + .basicAuth(memberProfile.getWorkEmail(), MEMBER_ROLE); + HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> { + client.toBlocking().exchange(request, RetentionReportResponseDTO.class); + }); + assertEquals(HttpStatus.FORBIDDEN, responseException.getStatus()); + + } + + } From 7299e8c8dd895522fa88287d96f8f663e1c3ce4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Nagli=C4=8D?= Date: Mon, 27 Nov 2023 10:51:11 +0100 Subject: [PATCH 06/37] feat(member-permissions): Add permission annotation to members endpoints - each report has now its own permission --- .../security/permissions/Permissions.java | 7 ++- .../skillsreport/SkillsReportController.java | 2 +- .../AnniversaryReportController.java | 2 +- .../birthday/BirthDayController.java | 2 +- .../MemberProfileReportController.java | 2 +- .../RetentionReportController.java | 2 +- .../resources/db/dev/R__Load_testing_data.sql | 58 +++++++++++++++++-- .../services/fixture/PermissionFixture.java | 38 +++++++----- 8 files changed, 86 insertions(+), 27 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java index 0f752d205f..cd2aa45ed7 100644 --- a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java +++ b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java @@ -9,6 +9,9 @@ public enum Permissions { CAN_CREATE_ORGANIZATION_MEMBERS, CAN_VIEW_ROLE_PERMISSIONS, CAN_VIEW_PERMISSIONS, - CAN_VIEW_ADMIN_REPORT, - CAN_VIEW_PDL_REPORT + CAN_VIEW_SKILLS_REPORT, + CAN_VIEW_RETENTION_REPORT, + CAN_VIEW_ANNIVERSARY_REPORT, + CAN_VIEW_BIRTHDAY_REPORT, + CAN_VIEW_PROFILE_REPORT, } \ No newline at end of file diff --git a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java index da37e1065b..ce4c98e01f 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportController.java @@ -46,7 +46,7 @@ public SkillsReportController(SkillsReportServices skillsReportServices, * @return {@link SkillsReportResponseDTO} Returned skills report */ @Post() - @RequiredPermission(Permissions.CAN_VIEW_PDL_REPORT) + @RequiredPermission(Permissions.CAN_VIEW_SKILLS_REPORT) public Mono> reportSkills(@Body @Valid @NotNull SkillsReportRequestDTO requestBody, HttpRequest request) { return Mono.fromCallable(() -> skillsReportServices.report(requestBody)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java index 50f1b48b10..c71267555b 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/anniversaryreport/AnniversaryReportController.java @@ -51,7 +51,7 @@ public AnniversaryReportController(AnniversaryServices anniversaryServices, */ @Get("/{?month}") - @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) + @RequiredPermission(Permissions.CAN_VIEW_ANNIVERSARY_REPORT) public Mono>> findByValue(@Nullable String[] month) { return Mono.fromCallable(() -> anniversaryServices.findByValue(month)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java index cb0fdaa518..b3d3c91124 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/birthday/BirthDayController.java @@ -53,7 +53,7 @@ public BirthDayController(BirthDayServices birthDayServices, */ @Get("/{?month,dayOfMonth}") - @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) + @RequiredPermission(Permissions.CAN_VIEW_BIRTHDAY_REPORT) public Mono>> findByValue(@Nullable String[] month, @Nullable Integer[] dayOfMonth) { return Mono.fromCallable(() -> birthDayServices.findByValue(month, dayOfMonth)) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java index 5d3ae2de5d..5b7d515610 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/csvreport/MemberProfileReportController.java @@ -46,7 +46,7 @@ public MemberProfileReportController(MemberProfileServices memberProfileServices } @Get(uri = "/csv", produces = MediaType.TEXT_CSV) - @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) + @RequiredPermission(Permissions.CAN_VIEW_PROFILE_REPORT) public Mono> generateCsv() { return Flux.defer(() -> Flux.fromIterable(memberProfileServices.findByValues(null, null, null, null, null, null, false))) .subscribeOn(ioScheduler) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java index c35b7f04d9..12bcbd7c84 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/memberprofile/retentionreport/RetentionReportController.java @@ -48,7 +48,7 @@ public RetentionReportController(RetentionReportServices retentionReportServices * @return {@link RetentionReportResponseDTO} Returned retention report */ @Post() - @RequiredPermission(Permissions.CAN_VIEW_ADMIN_REPORT) + @RequiredPermission(Permissions.CAN_VIEW_RETENTION_REPORT) public Mono> reportRetention(@Body @Valid @NotNull RetentionReportRequestDTO requestBody, HttpRequest request) { if (requestBody.getStartDate().isAfter(requestBody.getEndDate()) || diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 92cdde0456..107c94a537 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -539,12 +539,27 @@ values insert into permissions (id, permission) values - ('f7e815de-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_ADMIN_REPORT'); + ('f7e815de-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_SKILLS_REPORT'); insert into permissions (id, permission) values - ('f7e81958-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_PDL_REPORT'); + ('f7e81958-8849-11ee-b9d1-0242ac120002', 'CAN_VIEW_RETENTION_REPORT'); + +insert into permissions +(id, permission) +values + ('056e32b2-8d07-11ee-b9d1-0242ac120002', 'CAN_VIEW_ANNIVERSARY_REPORT'); + +insert into permissions +(id, permission) +values + ('2d765f78-8d07-11ee-b9d1-0242ac120002', 'CAN_VIEW_BIRTHDAY_REPORT'); + +insert into permissions +(id, permission) +values + ('2d765d5c-8d07-11ee-b9d1-0242ac120002', 'CAN_VIEW_PROFILE_REPORT'); insert into role_permissions (roleid, permissionid) @@ -582,7 +597,7 @@ values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1fd790d9-df9a-4201-818b-3a9ac5e5be3b'); insert into role_permissions -(roleid, permissionid) + (roleid, permissionid) values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f6961946-a792-4a16-b675-d8cf7980c17a'); @@ -596,6 +611,21 @@ insert into role_permissions values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e81958-8849-11ee-b9d1-0242ac120002'); +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '056e32b2-8d07-11ee-b9d1-0242ac120002'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765f78-8d07-11ee-b9d1-0242ac120002'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765d5c-8d07-11ee-b9d1-0242ac120002'); + insert into role_permissions (roleid, permissionid) values @@ -607,15 +637,35 @@ values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '1bf32dfe-a204-4c80-889e-829ca66c999b'); insert into role_permissions -(roleid, permissionid) + (roleid, permissionid) values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e815de-8849-11ee-b9d1-0242ac120002'); + insert into role_permissions (roleid, permissionid) values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e81958-8849-11ee-b9d1-0242ac120002'); +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '056e32b2-8d07-11ee-b9d1-0242ac120002'); + +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2d765f78-8d07-11ee-b9d1-0242ac120002'); + +insert into role_permissions + (roleid, permissionid) +values + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); + insert into role_permissions (roleid, permissionid) values diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 02675b9048..9a65b03aad 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -19,26 +19,32 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt // Add PDL Permissions here List pdlPermissions = List.of( - Permissions.CAN_VIEW_FEEDBACK_REQUEST, - Permissions.CAN_CREATE_FEEDBACK_REQUEST, - Permissions.CAN_DELETE_FEEDBACK_REQUEST, - Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS, - Permissions.CAN_VIEW_PDL_REPORT + Permissions.CAN_VIEW_FEEDBACK_REQUEST, + Permissions.CAN_CREATE_FEEDBACK_REQUEST, + Permissions.CAN_DELETE_FEEDBACK_REQUEST, + Permissions.CAN_VIEW_FEEDBACK_ANSWER, + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_SKILLS_REPORT, + Permissions.CAN_VIEW_RETENTION_REPORT, + Permissions.CAN_VIEW_ANNIVERSARY_REPORT, + Permissions.CAN_VIEW_BIRTHDAY_REPORT ); // Add ADMIN Permissions here List adminPermissions = List.of( - Permissions.CAN_VIEW_FEEDBACK_REQUEST, - Permissions.CAN_CREATE_FEEDBACK_REQUEST, - Permissions.CAN_DELETE_FEEDBACK_REQUEST, - Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_DELETE_ORGANIZATION_MEMBERS, - Permissions.CAN_CREATE_ORGANIZATION_MEMBERS, - Permissions.CAN_VIEW_ROLE_PERMISSIONS, - Permissions.CAN_VIEW_PERMISSIONS, - Permissions.CAN_VIEW_ADMIN_REPORT, - Permissions.CAN_VIEW_PDL_REPORT + Permissions.CAN_VIEW_FEEDBACK_REQUEST, + Permissions.CAN_CREATE_FEEDBACK_REQUEST, + Permissions.CAN_DELETE_FEEDBACK_REQUEST, + Permissions.CAN_VIEW_FEEDBACK_ANSWER, + Permissions.CAN_DELETE_ORGANIZATION_MEMBERS, + Permissions.CAN_CREATE_ORGANIZATION_MEMBERS, + Permissions.CAN_VIEW_ROLE_PERMISSIONS, + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_SKILLS_REPORT, + Permissions.CAN_VIEW_RETENTION_REPORT, + Permissions.CAN_VIEW_ANNIVERSARY_REPORT, + Permissions.CAN_VIEW_BIRTHDAY_REPORT, + Permissions.CAN_VIEW_PROFILE_REPORT ); default Permission createACustomPermission(Permissions perm) { From 36f59b891fd2d569501e9a7d6bc0d2b0971fa807 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 21:45:01 +0000 Subject: [PATCH 07/37] Bump tinymce from 6.2.0 to 6.8.1 in /web-ui Bumps [tinymce](https://github.com/tinymce/tinymce/tree/HEAD/modules/tinymce) from 6.2.0 to 6.8.1. - [Changelog](https://github.com/tinymce/tinymce/blob/develop/modules/tinymce/CHANGELOG.md) - [Commits](https://github.com/tinymce/tinymce/commits/6.8.1/modules/tinymce) --- updated-dependencies: - dependency-name: tinymce dependency-type: indirect ... Signed-off-by: dependabot[bot] --- web-ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web-ui/yarn.lock b/web-ui/yarn.lock index 8cd4e903f9..a77fe9c242 100644 --- a/web-ui/yarn.lock +++ b/web-ui/yarn.lock @@ -15929,9 +15929,9 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== "tinymce@^6.0.0 || ^5.5.1": - version "6.2.0" - resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.2.0.tgz#473aa38af03bf772916f3e1730e6b8d3471203f0" - integrity sha512-zLjbFrg0hbtJ6PxmZUjQY6zyIOM/mLrWGTvhBec7XwYwoW1E0xXMQzy2tgMTh3OvJpsclgqf2ZMjmwcv4Cludw== + version "6.8.1" + resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-6.8.1.tgz#840f514b4a175f55042cbe2fce548b10fc38208b" + integrity sha512-WYPvMXIjBrXM/oBiqGCbT2a8ptiO3TWXm/xxPWDCl8SxRKMW7Rfp0Lk190E9fXmX6uh9lJMRCnmKHzvryz0ftA== tmp@^0.0.33: version "0.0.33" From b67de77dbfa0dc1beb6efa67f043c3120baadbb6 Mon Sep 17 00:00:00 2001 From: S78901 <39834839+S78901@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:34:45 -0600 Subject: [PATCH 08/37] Member Permissions Adjustment --- .../checkins/services/demographics/DemographicsCreateDTO.java | 1 - .../checkins/services/permissions/PermissionController.java | 4 ++-- server/src/main/resources/application-local.yml | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/demographics/DemographicsCreateDTO.java b/server/src/main/java/com/objectcomputing/checkins/services/demographics/DemographicsCreateDTO.java index b0a51ecabb..c613dcdffd 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/demographics/DemographicsCreateDTO.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/demographics/DemographicsCreateDTO.java @@ -3,7 +3,6 @@ import io.micronaut.core.annotation.Nullable; import io.micronaut.core.annotation.Introspected; import io.swagger.v3.oas.annotations.media.Schema; -import io.micronaut.core.annotation.Nullable; import javax.validation.constraints.NotNull; import java.util.UUID; diff --git a/server/src/main/java/com/objectcomputing/checkins/services/permissions/PermissionController.java b/server/src/main/java/com/objectcomputing/checkins/services/permissions/PermissionController.java index bd610425d7..e525aa6853 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/permissions/PermissionController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/permissions/PermissionController.java @@ -42,7 +42,7 @@ public PermissionController(PermissionServices permissionServices, /** * Get all permissions (orders by permission name) * - * @return {@link List < Permission > list of Permissions} + * @return {@link List < Permission > list order by Permissions} */ @RequiredPermission(Permissions.CAN_VIEW_PERMISSIONS) @Get("/OrderByPermission") @@ -57,7 +57,7 @@ public Mono>> listOrderByPermission() { /** * Get all permissions * - * @return {@link List < Permission > list of Permissions} + * @return {@link List < Permission > list of all Permissions} */ @RequiredPermission(Permissions.CAN_VIEW_PERMISSIONS) @Get diff --git a/server/src/main/resources/application-local.yml b/server/src/main/resources/application-local.yml index 24b840a6be..4a4cf8c206 100755 --- a/server/src/main/resources/application-local.yml +++ b/server/src/main/resources/application-local.yml @@ -30,8 +30,8 @@ micronaut: datasources: default: url: ${JDBC_URL:`jdbc:postgresql://localhost:5432/checkinsdb`} - username: armm - password: armm + username: postgres + password: "postgres" --- credentials: roles: From 37933d580fa98005f5c360aa29e5262060564b7b Mon Sep 17 00:00:00 2001 From: S78901 <39834839+S78901@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:47:02 -0600 Subject: [PATCH 09/37] Delete extra TODO file --- server/TODO | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 server/TODO diff --git a/server/TODO b/server/TODO deleted file mode 100644 index 8c97c1c5d1..0000000000 --- a/server/TODO +++ /dev/null @@ -1,5 +0,0 @@ -com.objectcomputing.checkins.services.member_skill.skillsreport.SkillsReportController -com.objectcomputing.checkins.services.memberprofile.retentionreport.RetentionReportController -com.objectcomputing.checkins.services.memberprofile.anniversaryreport.AnniversaryReportController -com.objectcomputing.checkins.services.memberprofile.birthday.BirthDayController -com.objectcomputing.checkins.services.memberprofile.csvreport.MemberProfileReportController \ No newline at end of file From 9a6b7a8377cd11eb9eb694be4305dd8135cd9ed5 Mon Sep 17 00:00:00 2001 From: S78901 <39834839+S78901@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:57:33 -0600 Subject: [PATCH 10/37] Fix Role in fixture --- .../services/fixture/PermissionFixture.java | 14 ++++------ .../SkillsReportControllerTest.java | 26 +++++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 9a65b03aad..65105bea6b 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -11,10 +11,10 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt // Add MEMBER Permissions here List memberPermissions = List.of( - Permissions.CAN_VIEW_FEEDBACK_REQUEST, - Permissions.CAN_DELETE_FEEDBACK_REQUEST, - Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS + Permissions.CAN_VIEW_FEEDBACK_REQUEST, + Permissions.CAN_DELETE_FEEDBACK_REQUEST, + Permissions.CAN_VIEW_FEEDBACK_ANSWER, + Permissions.CAN_VIEW_PERMISSIONS ); // Add PDL Permissions here @@ -23,11 +23,7 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_CREATE_FEEDBACK_REQUEST, Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS, - Permissions.CAN_VIEW_SKILLS_REPORT, - Permissions.CAN_VIEW_RETENTION_REPORT, - Permissions.CAN_VIEW_ANNIVERSARY_REPORT, - Permissions.CAN_VIEW_BIRTHDAY_REPORT + Permissions.CAN_VIEW_PERMISSIONS ); // Add ADMIN Permissions here diff --git a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java index b4e8423a61..667c4bb572 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/member_skill/skillsreport/SkillsReportControllerTest.java @@ -1,7 +1,7 @@ package com.objectcomputing.checkins.services.member_skill.skillsreport; import static com.objectcomputing.checkins.services.role.RoleType.Constants.MEMBER_ROLE; -import static com.objectcomputing.checkins.services.role.RoleType.Constants.PDL_ROLE; +import static com.objectcomputing.checkins.services.role.RoleType.Constants.ADMIN_ROLE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -45,8 +45,8 @@ void createRolesAndPermissions() { @Test void testValidRequestNonEmptyResponse() { - MemberProfile pdlMember = createAnUnrelatedUser(); - assignPdlRole(pdlMember); + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); @@ -61,7 +61,7 @@ void testValidRequestNonEmptyResponse() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE); final HttpResponse response = client.toBlocking() .exchange(request, SkillsReportResponseDTO.class); @@ -79,8 +79,8 @@ void testValidRequestNonEmptyResponse() { @Test void testValidRequestEmptyResponse() { - MemberProfile pdlMember = createAnUnrelatedUser(); - assignPdlRole(pdlMember); + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); final MemberProfile memberProfile = createADefaultMemberProfile(); final Skill skill = createADefaultSkill(); @@ -95,7 +95,7 @@ void testValidRequestEmptyResponse() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE); final HttpResponse response = client.toBlocking() .exchange(request, SkillsReportResponseDTO.class); @@ -108,8 +108,8 @@ void testValidRequestEmptyResponse() { @Test void testInvalidRequestSkillNotExist() { - MemberProfile pdlMember = createAnUnrelatedUser(); - assignPdlRole(pdlMember); + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); final SkillsReportRequestDTO skillsReportRequestDTO = new SkillsReportRequestDTO(); final List skillLevelDTOList = new ArrayList<>(); @@ -121,7 +121,7 @@ void testInvalidRequestSkillNotExist() { skillsReportRequestDTO.setSkills(skillLevelDTOList); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -130,8 +130,8 @@ void testInvalidRequestSkillNotExist() { @Test void testInvalidRequestMemberProfileNotExist() { - MemberProfile pdlMember = createAnUnrelatedUser(); - assignPdlRole(pdlMember); + MemberProfile adminMember = createAnUnrelatedUser(); + assignAdminRole(adminMember); final Skill skill = createADefaultSkill(); @@ -147,7 +147,7 @@ void testInvalidRequestMemberProfileNotExist() { skillsReportRequestDTO.setMembers(members); final HttpRequest request = HttpRequest.POST("", skillsReportRequestDTO) - .basicAuth(pdlMember.getWorkEmail(), PDL_ROLE); + .basicAuth(adminMember.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); From 77bc22180789208f3438039da4c9f9b6ec0945c5 Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Tue, 5 Dec 2023 16:24:40 -0600 Subject: [PATCH 11/37] Attempt to fix dev build --- .github/workflows/gradle-build-development.yml | 1 + server/src/main/resources/application-dev.yml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/gradle-build-development.yml b/.github/workflows/gradle-build-development.yml index 88787f557f..c22670470c 100644 --- a/.github/workflows/gradle-build-development.yml +++ b/.github/workflows/gradle-build-development.yml @@ -114,6 +114,7 @@ jobs: --set-env-vars "WEB_ADDRESS=https://checkins-develop-tuvcfzotpq-uc.a.run.app" \ --set-env-vars "FROM_ADDRESS=kimberlinm@objectcomputing.com" \ --set-env-vars "FROM_NAME=Check-Ins - DEVELOP" \ + --set-env-vars "MICRONAUT_ENVIRONMENTS=dev" \ --platform "managed" \ --max-instances 4 \ --allow-unauthenticated diff --git a/server/src/main/resources/application-dev.yml b/server/src/main/resources/application-dev.yml index b3f36f5001..efbd4cabc1 100644 --- a/server/src/main/resources/application-dev.yml +++ b/server/src/main/resources/application-dev.yml @@ -1,3 +1,7 @@ +datasources: + default: + maximum-pool-size: 10 +--- flyway: enabled: enabled datasources: From 5a7a58607f4c5abddf1ab8f57edd7fc11f214c1b Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Tue, 5 Dec 2023 16:30:05 -0600 Subject: [PATCH 12/37] Adjust develop database connections --- .github/workflows/gradle-build-development.yml | 2 +- server/src/main/resources/application-dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gradle-build-development.yml b/.github/workflows/gradle-build-development.yml index c22670470c..4c111d6fb0 100644 --- a/.github/workflows/gradle-build-development.yml +++ b/.github/workflows/gradle-build-development.yml @@ -116,5 +116,5 @@ jobs: --set-env-vars "FROM_NAME=Check-Ins - DEVELOP" \ --set-env-vars "MICRONAUT_ENVIRONMENTS=dev" \ --platform "managed" \ - --max-instances 4 \ + --max-instances 2 \ --allow-unauthenticated diff --git a/server/src/main/resources/application-dev.yml b/server/src/main/resources/application-dev.yml index efbd4cabc1..4864659573 100644 --- a/server/src/main/resources/application-dev.yml +++ b/server/src/main/resources/application-dev.yml @@ -1,6 +1,6 @@ datasources: default: - maximum-pool-size: 10 + maximum-pool-size: 8 --- flyway: enabled: enabled From ec4798d487d3e949185caa806da60fd04aaa77a8 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Tue, 5 Dec 2023 17:50:52 -0600 Subject: [PATCH 13/37] add comments to make mock data more readable --- .../resources/db/dev/R__Load_testing_data.sql | 273 ++++++++++-------- 1 file changed, 160 insertions(+), 113 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 107c94a537..fddc2962d7 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -23,102 +23,102 @@ delete from feedback_templates; delete from member_profile; delete from skills; -INSERT INTO member_profile +INSERT INTO member_profile -- Gina Bremehr (id, firstName, lastName, title, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('01b7d769-9fa2-43ff-95c7-f3b950a27bf9', PGP_SYM_ENCRYPT('Gina','${aeskey}'), PGP_SYM_ENCRYPT('Bremehr','${aeskey}'), PGP_SYM_ENCRYPT('COO','${aeskey}'), PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('bremehrg@objectcomputing.com','${aeskey}'), '12312345', '2012-09-20', PGP_SYM_ENCRYPT('Epitome of Strong Woman','${aeskey}'), null, '1988-09-21'); -INSERT INTO member_profile +INSERT INTO member_profile -- Ron Steinkamp (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('2559a257-ae84-4076-9ed4-3820c427beeb', PGP_SYM_ENCRYPT('Ron','${aeskey}'), PGP_SYM_ENCRYPT('Steinkamp','${aeskey}'), PGP_SYM_ENCRYPT('Senior Project Manager','${aeskey}'), '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('steinkampr@objectcomputing.com','${aeskey}'), '12312346', '2012-09-29', PGP_SYM_ENCRYPT('Managing projects well','${aeskey}'), null, '1988-09-02'); -INSERT INTO member_profile +INSERT INTO member_profile -- John Meyerin (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('802cb1f5-a255-4236-8719-773fa53d79d9', PGP_SYM_ENCRYPT('John','${aeskey}'), PGP_SYM_ENCRYPT('Meyerin','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '2559a257-ae84-4076-9ed4-3820c427beeb', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('meyerinj@objectcomputing.com','${aeskey}'), '12312347', '2012-09-29', PGP_SYM_ENCRYPT('Outstanding Engineer','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Geetika Sharma (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('Geetika','${aeskey}'), PGP_SYM_ENCRYPT('Sharma','${aeskey}'), PGP_SYM_ENCRYPT('PMO Administrator','${aeskey}'), '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('sharmag@objectcomputing.com','${aeskey}'), '12312348', '2012-09-29', PGP_SYM_ENCRYPT('Engineer Wrangler Extrodinaire','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Holly Williams (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Holly','${aeskey}'), PGP_SYM_ENCRYPT('Williams','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '802cb1f5-a255-4236-8719-773fa53d79d9', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('williamsh@objectcomputing.com','${aeskey}'), '12312349', '2012-09-29', PGP_SYM_ENCRYPT('Software Engineer Remarkable','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Michael Kimberlin (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('6207b3fd-042d-49aa-9e28-dcc04f537c2d', PGP_SYM_ENCRYPT('Michael','${aeskey}'), PGP_SYM_ENCRYPT('Kimberlin','${aeskey}'), PGP_SYM_ENCRYPT('Director of Organizational Development','${aeskey}'), '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('kimberlinm@objectcomputing.com','${aeskey}'), '12312342', '2012-09-29', PGP_SYM_ENCRYPT('Developer of developers and others','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Mark Volkmann (id, firstName, lastName, title, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', PGP_SYM_ENCRYPT('Mark','${aeskey}'), PGP_SYM_ENCRYPT('Volkmann','${aeskey}'), PGP_SYM_ENCRYPT('Partner and Distinguished Engineer','${aeskey}'), PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('volkmannm@objectcomputing.com','${aeskey}'), '12312343', '2012-09-29', PGP_SYM_ENCRYPT('Software Engineer Spectacular','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Pramukh Bagur (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('6884ab96-2275-4af9-89d8-ad84254d8759', PGP_SYM_ENCRYPT('Pramukh','${aeskey}'), PGP_SYM_ENCRYPT('Bagur','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '802cb1f5-a255-4236-8719-773fa53d79d9', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('bagurp@objectcomputing.com','${aeskey}'), '12312344', '2012-09-29', PGP_SYM_ENCRYPT('Top notch Engineer','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Jesse Hanner (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Jesse','${aeskey}'), PGP_SYM_ENCRYPT('Hanner','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '6884ab96-2275-4af9-89d8-ad84254d8759', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('hannerj@objectcomputing.com','${aeskey}'), '123123450', '2012-09-29', PGP_SYM_ENCRYPT('Amazing Engineer','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Suman Maroju (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('1b4f99da-ef70-4a76-9b37-8bb783b749ad', PGP_SYM_ENCRYPT('Suman','${aeskey}'), PGP_SYM_ENCRYPT('Maroju','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('marojus@objectcomputing.com','${aeskey}'), '123123410', '2012-09-29', PGP_SYM_ENCRYPT('Superior Engineer','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Mohit Bhatia (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('b2d35288-7f1e-4549-aa2b-68396b162490', PGP_SYM_ENCRYPT('Mohit','${aeskey}'), PGP_SYM_ENCRYPT('Bhatia','${aeskey}'), PGP_SYM_ENCRYPT('Principal Software Engineer','${aeskey}'), '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('bhatiam@objectcomputing.com','${aeskey}'), '123123411', '2012-09-29', PGP_SYM_ENCRYPT('Engineer Extraordinaire','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Zack Brown (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Zack','${aeskey}'), PGP_SYM_ENCRYPT('Brown','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '2559a257-ae84-4076-9ed4-3820c427beeb', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('brownz@objectcomputing.com','${aeskey}'), '123123412', '2012-09-29', PGP_SYM_ENCRYPT('Engineer Phenomenal','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Joe Warner (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES ('066b186f-1425-45de-89f2-4ddcc6ebe237', PGP_SYM_ENCRYPT('Joe','${aeskey}'), PGP_SYM_ENCRYPT('Warner','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('warnerj@objectcomputing.com','${aeskey}'), '123123413', '2012-09-29', PGP_SYM_ENCRYPT('Engineer of Supreme Ability','${aeskey}'), null); -INSERT INTO member_profile +INSERT INTO member_profile -- Julia Smith (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Julia','${aeskey}'), PGP_SYM_ENCRYPT('Smith','${aeskey}'), PGP_SYM_ENCRYPT('Intern','${aeskey}'), '6207b3fd-042d-49aa-9e28-dcc04f537c2d', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('smithj@objectcomputing.com','${aeskey}'), '010101010', '2021-05-22', PGP_SYM_ENCRYPT('Local creature in discovery room','${aeskey}'), '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '1998-07-07'); -INSERT INTO member_profile +INSERT INTO member_profile -- Faux Freddy (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('2dee821c-de32-4d9c-9ecb-f73e5903d17a', PGP_SYM_ENCRYPT('Faux','${aeskey}'), PGP_SYM_ENCRYPT('Freddy','${aeskey}'), PGP_SYM_ENCRYPT('Test Engineer','${aeskey}'), '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('testing@objectcomputing.com','${aeskey}'), '010101011', '2021-05-22', PGP_SYM_ENCRYPT('Test user 1','${aeskey}'), '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '1950-01-01'); -INSERT INTO member_profile +INSERT INTO member_profile -- Unreal Ulysses (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('dfe2f986-fac0-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Unreal','${aeskey}'), PGP_SYM_ENCRYPT('Ulysses','${aeskey}'), PGP_SYM_ENCRYPT('Test Engineer 2','${aeskey}'), '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('testing2@objectcomputing.com','${aeskey}'), '010101012', '2021-05-22', PGP_SYM_ENCRYPT('Test user 2','${aeskey}'), '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '1950-01-01'); -INSERT INTO member_profile +INSERT INTO member_profile -- Kazuhira Miller (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('a90be358-aa3d-49c8-945a-879a93646e45', PGP_SYM_ENCRYPT('Kazuhira','${aeskey}'), PGP_SYM_ENCRYPT('Miller','${aeskey}'), PGP_SYM_ENCRYPT('Unit Coordinator','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Mother Base','${aeskey}'), PGP_SYM_ENCRYPT('millerkaz@objectcomputing.com','${aeskey}'), '012345678', '2022-03-29', PGP_SYM_ENCRYPT('Bff with Big Boss','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', '1943-07-04'); -INSERT INTO member_profile +INSERT INTO member_profile -- Big Boss (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', PGP_SYM_ENCRYPT('Big','${aeskey}'), PGP_SYM_ENCRYPT('Boss','${aeskey}'), PGP_SYM_ENCRYPT('Sneaky Snake','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Mother Base','${aeskey}'), PGP_SYM_ENCRYPT('bossb@objectcomputing.com','${aeskey}'), '351242153', '2022-03-29', PGP_SYM_ENCRYPT('The Legendary Big Boss','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', '1943-07-04'); -INSERT INTO member_profile +INSERT INTO member_profile -- Revolver Ocelot (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('105f2968-a182-45a3-892c-eeff76383fe0', PGP_SYM_ENCRYPT('Revolver','${aeskey}'), PGP_SYM_ENCRYPT('Ocelot','${aeskey}'), PGP_SYM_ENCRYPT('Shalashaska','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Mother Base','${aeskey}'), PGP_SYM_ENCRYPT('ocelotr@objectcomputing.com','${aeskey}'), '489102361', '2022-03-29', PGP_SYM_ENCRYPT('Loves to reload during battle','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', '1943-07-04'); -INSERT INTO member_profile +INSERT INTO member_profile -- Huey Emmerich (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES ('8d75c07e-6adc-437a-8659-7dd953ce6600', PGP_SYM_ENCRYPT('Huey','${aeskey}'), PGP_SYM_ENCRYPT('Emmerich','${aeskey}'), PGP_SYM_ENCRYPT('Head of R&D','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Mother Base','${aeskey}'), PGP_SYM_ENCRYPT('emmerichh@objectcomputing.com','${aeskey}'), '657483498', '2022-03-29', PGP_SYM_ENCRYPT('Waiting for love to bloom on the battlefield','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', '1943-07-04'); @@ -139,218 +139,235 @@ VALUES ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', PGP_SYM_ENCRYPT('is a pdl','${aeskey}'), 'PDL'); - +-- Admin Role Assigning INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); -- Michael Kimberlin INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2559a257-ae84-4076-9ed4-3820c427beeb'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2559a257-ae84-4076-9ed4-3820c427beeb'); -- Ron Steinkamp INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); -- Geetika Sharma INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '43ee8e79-b33d-44cd-b23c-e183894ebfef'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '43ee8e79-b33d-44cd-b23c-e183894ebfef'); -- Zack Brown INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '6884ab96-2275-4af9-89d8-ad84254d8759'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '6884ab96-2275-4af9-89d8-ad84254d8759'); -- Pramukh Bagur INSERT INTO member_roles (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); -- Holly Williams -INSERT INTO member_roles - (roleid, memberid) +INSERT INTO member_roles( + roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '066b186f-1425-45de-89f2-4ddcc6ebe237'); -- Joe Warner + +-- PDL Role Assigning INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2559a257-ae84-4076-9ed4-3820c427beeb'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); -- Michael Kimberlin INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2559a257-ae84-4076-9ed4-3820c427beeb'); -- Ron Steinkamp INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); -- Geetika Sharma INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d'); -- Mark Volkmann INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '802cb1f5-a255-4236-8719-773fa53d79d9'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9'); -- Gina Bremehr INSERT INTO member_roles (roleid, memberid) VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '6884ab96-2275-4af9-89d8-ad84254d8759'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '802cb1f5-a255-4236-8719-773fa53d79d9'); -- John Meyerin INSERT INTO member_roles -(roleid, memberid) + (roleid, memberid) VALUES -('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '6884ab96-2275-4af9-89d8-ad84254d8759'); -- Pramukh Bagur INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); -- Holly Williams + +INSERT INTO member_roles( + roleid, memberid) +VALUES + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '066b186f-1425-45de-89f2-4ddcc6ebe237'); -- Joe Warner + +-- Member Role Assigning INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '2559a257-ae84-4076-9ed4-3820c427beeb'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9'); -- Gina Bremehr INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '802cb1f5-a255-4236-8719-773fa53d79d9'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '2559a257-ae84-4076-9ed4-3820c427beeb'); -- Ron Steinkamp INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '802cb1f5-a255-4236-8719-773fa53d79d9'); -- John Meyerin INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498'); -- Geetika Sharma INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); -- Michael Kimberlin INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d'); -- Mark Volkmann INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '6884ab96-2275-4af9-89d8-ad84254d8759'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3'); -- Jesse Hanner INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1b4f99da-ef70-4a76-9b37-8bb783b749ad'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '6884ab96-2275-4af9-89d8-ad84254d8759'); -- Pramukh Bagur INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'b2d35288-7f1e-4549-aa2b-68396b162490'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1b4f99da-ef70-4a76-9b37-8bb783b749ad'); -- Suman Maroju INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '43ee8e79-b33d-44cd-b23c-e183894ebfef'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'b2d35288-7f1e-4549-aa2b-68396b162490'); -- Mohit Bhatia INSERT INTO member_roles (roleid, memberid) VALUES - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '43ee8e79-b33d-44cd-b23c-e183894ebfef'); -- Zack Brown -INSERT INTO member_roles( - roleid, memberid) +INSERT INTO member_roles + (roleid, memberid) VALUES - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '066b186f-1425-45de-89f2-4ddcc6ebe237'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); -- Holly Williams -INSERT INTO member_roles( - roleid, memberid) -VALUES - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '066b186f-1425-45de-89f2-4ddcc6ebe237'); -INSERT INTO team +-- Teams +INSERT INTO team -- Checkins Experts (id, name, description) VALUES ('a8733740-cf4c-4c16-a8cf-4f928c409acc', PGP_SYM_ENCRYPT('Checkins Experts','${aeskey}'), PGP_SYM_ENCRYPT('Checkins Engineers of superior knowledge','${aeskey}')); -INSERT INTO team +INSERT INTO team -- JavaScript Gurus (id, name, description) VALUES ('e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', PGP_SYM_ENCRYPT('JavaScript Gurus','${aeskey}'), PGP_SYM_ENCRYPT('JavaScript Engineers of Outstanding Skill','${aeskey}')); -INSERT INTO team +INSERT INTO team -- Micronaut Genii (id, name, description) VALUES ('036b95a5-357c-45bd-b60e-e8e2e1afec83', PGP_SYM_ENCRYPT('Micronaut Genii','${aeskey}'), PGP_SYM_ENCRYPT('Micronaut Engineers of Genius Caliber','${aeskey}')); -INSERT INTO team +INSERT INTO team -- PMO Superness (id, name, description) VALUES ('e545dfa1-a07d-4099-9a5b-ed14f07b87cc', PGP_SYM_ENCRYPT('PMO Superness','${aeskey}'), PGP_SYM_ENCRYPT('Excellent PMO Artists','${aeskey}')); + +-- Checkins Experts Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('d2ee49cb-9479-49fb-80d7-43c3c1b50f91', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '802cb1f5-a255-4236-8719-773fa53d79d9', true); +('d2ee49cb-9479-49fb-80d7-43c3c1b50f91', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '802cb1f5-a255-4236-8719-773fa53d79d9', true); -- John Meyerin INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('0f299d11-df47-406f-a426-8e3160eaeb21', '036b95a5-357c-45bd-b60e-e8e2e1afec83', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); +('c7b4d5e0-09ba-479a-8c40-ca9bbd8f217a', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '6884ab96-2275-4af9-89d8-ad84254d8759', false); -- Pramukh Bagur INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('9e7e9577-a36b-4238-84cc-4f160ac60b40', 'e545dfa1-a07d-4099-9a5b-ed14f07b87cc', '2559a257-ae84-4076-9ed4-3820c427beeb', true); +('20bf1ddb-53a0-436e-99dc-802c1199e282', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', false); -- Jesse Hanner INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('439ad8a8-500f-4f3f-963b-a86437d5820a', 'e545dfa1-a07d-4099-9a5b-ed14f07b87cc', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', false); +('122ca588-bf61-4aea-bb6e-39838328bf85', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', 'b2d35288-7f1e-4549-aa2b-68396b162490', true); -- Mohit Bhatia INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('8eea2f65-160c-4db7-9f6d-f367acd333fb', 'e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', '43ee8e79-b33d-44cd-b23c-e183894ebfef', false); +('adff5631-d4dc-4c61-b3d4-232d1cce8ce0', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', false); -- Suman Maroju + +-- JavaScript Gurus Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('c7b4d5e0-09ba-479a-8c40-ca9bbd8f217a', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '6884ab96-2275-4af9-89d8-ad84254d8759', false); +('8eea2f65-160c-4db7-9f6d-f367acd333fb', 'e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', '43ee8e79-b33d-44cd-b23c-e183894ebfef', false); -- Zack Brown INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('20bf1ddb-53a0-436e-99dc-802c1199e282', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', false); +('f84a21ca-1579-4c6a-8148-6a355518797a', 'e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', true); -- Mark Volkmann + +-- Micronaut Genii Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('f84a21ca-1579-4c6a-8148-6a355518797a', 'e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', true); +('7cf7820a-b099-48e5-b630-4f921ee17d16', '036b95a5-357c-45bd-b60e-e8e2e1afec83', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); -- Holly Williams + +-- PMO Superness Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('122ca588-bf61-4aea-bb6e-39838328bf85', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', 'b2d35288-7f1e-4549-aa2b-68396b162490', true); +('9e7e9577-a36b-4238-84cc-4f160ac60b40', 'e545dfa1-a07d-4099-9a5b-ed14f07b87cc', '2559a257-ae84-4076-9ed4-3820c427beeb', true); -- Ron Steinkamp INSERT INTO team_member (id, teamid, memberid, lead) VALUES -('adff5631-d4dc-4c61-b3d4-232d1cce8ce0', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', false); +('97f3a251-0ed2-449b-a756-07226e6e6522', 'e545dfa1-a07d-4099-9a5b-ed14f07b87cc', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', false); -- Geetika Sharma + + +-- Checkins INSERT INTO checkins (id, teammemberid, pdlid, checkindate, completed) VALUES @@ -406,6 +423,9 @@ INSERT INTO checkins VALUES ('553aa528-d5f6-4d15-bfb6-b53738dc7954', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2022-01-16 11:32:29.04', true); + + +-- Checkins Notes/Private Notes/Action Items INSERT INTO checkin_notes (id, checkinid, createdbyid, description) VALUES @@ -462,40 +482,48 @@ INSERT INTO action_items (id, checkinid, createdbyid, description) Values('0ead3434-82e7-47b4-a0ef-d1f44d01732b', '1343411e-26bf-4274-81ca-1b46ba3f0cb0', '6884ab96-2275-4af9-89d8-ad84254d8759', PGP_SYM_ENCRYPT('Action Item for Pramukh Bagur','${aeskey}')); -insert into guild (id, name, description) + +-- Guilds +insert into guild (id, name, description) -- Software Engineering values('ba42d181-3c5b-4ee3-938d-be122c314bee', PGP_SYM_ENCRYPT('Software Engineering','${aeskey}'), PGP_SYM_ENCRYPT('Resource for Software Engineering Topics','${aeskey}')); -insert into guild (id, name, description) +insert into guild (id, name, description) -- Micronaut values('06cd3202-a209-4ae1-a49a-10395fbe3548', PGP_SYM_ENCRYPT('Micronaut','${aeskey}'), PGP_SYM_ENCRYPT('For Micronaut Lovers and Learners','${aeskey}')); -insert into guild (id, name, description) +insert into guild (id, name, description) -- Fullstack Development values('d1d4af0e-b1a5-47eb-be49-f3581271f1e3', PGP_SYM_ENCRYPT('Fullstack Development','${aeskey}'), PGP_SYM_ENCRYPT('Full Stack Development Interests','${aeskey}')); + +-- Software Engineering Guild Members insert into guild_member (id, guildId, memberId, lead) -values('fd976615-6a8b-4cd1-8aea-cb7751c8ee1a','ba42d181-3c5b-4ee3-938d-be122c314bee', 'b2d35288-7f1e-4549-aa2b-68396b162490', true); +values('fd976615-6a8b-4cd1-8aea-cb7751c8ee1a','ba42d181-3c5b-4ee3-938d-be122c314bee', 'b2d35288-7f1e-4549-aa2b-68396b162490', true); -- Mohit Bhatia insert into guild_member (id, guildId, memberId, lead) -values('86dc52b9-5b2a-4241-9c54-0fde07600c58','ba42d181-3c5b-4ee3-938d-be122c314bee', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', false); +values('86dc52b9-5b2a-4241-9c54-0fde07600c58','ba42d181-3c5b-4ee3-938d-be122c314bee', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', false); -- Suman Maroju insert into guild_member (id, guildId, memberId, lead) -values('7cd12bb9-6aa4-4edc-831f-f4ebe8f22f62','ba42d181-3c5b-4ee3-938d-be122c314bee', '6884ab96-2275-4af9-89d8-ad84254d8759', false); +values('7cd12bb9-6aa4-4edc-831f-f4ebe8f22f62','ba42d181-3c5b-4ee3-938d-be122c314bee', '6884ab96-2275-4af9-89d8-ad84254d8759', false); -- Pramukh Bagur insert into guild_member (id, guildId, memberId, lead) -values('8a20e99f-c326-4529-8024-26724a8586b1','ba42d181-3c5b-4ee3-938d-be122c314bee', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); +values('8a20e99f-c326-4529-8024-26724a8586b1','ba42d181-3c5b-4ee3-938d-be122c314bee', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); -- Holly Williams + +-- Micronaut Guild Members insert into guild_member (id, guildId, memberId, lead) -values('7ffe3937-bdce-4ebb-a03d-8a8b7d4703ef','06cd3202-a209-4ae1-a49a-10395fbe3548', '802cb1f5-a255-4236-8719-773fa53d79d9', true); +values('7ffe3937-bdce-4ebb-a03d-8a8b7d4703ef','06cd3202-a209-4ae1-a49a-10395fbe3548', '802cb1f5-a255-4236-8719-773fa53d79d9', true); -- John Meyerin insert into guild_member (id, guildId, memberId, lead) -values('dd694cf2-c0f9-4470-b897-00c564c1252b','06cd3202-a209-4ae1-a49a-10395fbe3548', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); +values('dd694cf2-c0f9-4470-b897-00c564c1252b','06cd3202-a209-4ae1-a49a-10395fbe3548', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); -- Holly Williams + +-- Pulse INSERT INTO pulse_response (id, submissiondate, updateddate, teammemberid, internalfeelings, externalfeelings) VALUES ('cda41eed-70ea-4d3f-a9d7-cd0c5158eb5f', '2021-01-29', '2021-02-02', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Feeling pretty happy','${aeskey}'), PGP_SYM_ENCRYPT('Feeling really good','${aeskey}')); - +-- Permissions insert into permissions (id, permission) values @@ -561,126 +589,136 @@ insert into permissions values ('2d765d5c-8d07-11ee-b9d1-0242ac120002', 'CAN_VIEW_PROFILE_REPORT'); + +-- Admin Permissions insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '439ad8a8-500f-4f3f-963b-a86437d5820a'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '439ad8a8-500f-4f3f-963b-a86437d5820a'); -- CAN_CREATE_ORGANIZATION_MEMBERS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '0f299d11-df47-406f-a426-8e3160eaeb21'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '0f299d11-df47-406f-a426-8e3160eaeb21'); -- CAN_DELETE_ORGANIZATION_MEMBERS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '008f6641-0b0a-4e89-84f0-c580f912b80d'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1bf32dfe-a204-4c80-889e-829ca66c999b'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1bf32dfe-a204-4c80-889e-829ca66c999b'); -- CAN_CREATE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '26a2f861-3f7d-4dc3-8762-716b184a3a47'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '26a2f861-3f7d-4dc3-8762-716b184a3a47'); -- CAN_VIEW_FEEDBACK_ANSWER insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1fd790d9-df9a-4201-818b-3a9ac5e5be3b'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '1fd790d9-df9a-4201-818b-3a9ac5e5be3b'); -- CAN_VIEW_ROLE_PERMISSIONS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f6961946-a792-4a16-b675-d8cf7980c17a'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f6961946-a792-4a16-b675-d8cf7980c17a'); -- CAN_VIEW_PERMISSIONS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e815de-8849-11ee-b9d1-0242ac120002'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e815de-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_SKILLS_REPORT insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e81958-8849-11ee-b9d1-0242ac120002'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'f7e81958-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_RETENTION_REPORT insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '056e32b2-8d07-11ee-b9d1-0242ac120002'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '056e32b2-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_ANNIVERSARY_REPORT insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765f78-8d07-11ee-b9d1-0242ac120002'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765f78-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_BIRTHDAY_REPORT insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765d5c-8d07-11ee-b9d1-0242ac120002'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765d5c-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_PROFILE_REPORT + + +-- PDL Permissions insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '008f6641-0b0a-4e89-84f0-c580f912b80d'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '1bf32dfe-a204-4c80-889e-829ca66c999b'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '1bf32dfe-a204-4c80-889e-829ca66c999b'); -- CAN_CREATE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e815de-8849-11ee-b9d1-0242ac120002'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e815de-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_SKILLS_REPORT insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e81958-8849-11ee-b9d1-0242ac120002'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e81958-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_RETENTION_REPORT insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '056e32b2-8d07-11ee-b9d1-0242ac120002'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '056e32b2-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_ANNIVERSARY_REPORT insert into role_permissions (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2d765f78-8d07-11ee-b9d1-0242ac120002'); + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2d765f78-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_BIRTHDAY_REPORT + + +-- Member Permissions insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); -- CAN_CREATE_ORGANIZATION_MEMBERS insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '008f6641-0b0a-4e89-84f0-c580f912b80d'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1bf32dfe-a204-4c80-889e-829ca66c999b'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1bf32dfe-a204-4c80-889e-829ca66c999b'); -- CAN_CREATE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST + +-- Feedback Templates/Template Questions INSERT INTO feedback_templates (id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) VALUES @@ -891,6 +929,9 @@ INSERT INTO template_questions VALUES ('174e5851-cb24-4a0f-890c-e6f041db4127', PGP_SYM_ENCRYPT('Please provide any additional context or reasoning relevant to your assessment of this team member.', '${aeskey}'), 'd1e94b60-47c4-4945-87d1-4dc88f088e57', 15, 'TEXT'); + + +-- Feedback Requests INSERT INTO feedback_requests (id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) VALUES @@ -1001,7 +1042,6 @@ INSERT INTO feedback_requests VALUES ('7ca4d402-0bb9-4989-9087-8a52a63ee5d0', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); - INSERT INTO feedback_requests (id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) VALUES @@ -1027,6 +1067,9 @@ INSERT INTO feedback_requests VALUES ('4240735d-15fd-4eea-8bca-8c642a433036', '59b790d2-fabc-11eb-9a03-0242ac130003', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '066b186f-1425-45de-89f2-4ddcc6ebe237', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2021-03-22', '2021-04-01', '2021-04-01', 'submitted'); + + +-- Feedback Answers INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) VALUES @@ -1062,37 +1105,41 @@ INSERT INTO feedback_answers VALUES ('a223135a-742b-45c6-b9a4-2bb990d956b2', PGP_SYM_ENCRYPT('They are always punctual, and work well with the other members of the team. Although they have a few technical skills they could brush up on, our team is lucky to have them.', '${aeskey}'), 'afa7e2cb-366a-4c16-a205-c0d493b80d85', '4240735d-15fd-4eea-8bca-8c642a433036', 0.7); -INSERT INTO skills + +-- Skills +INSERT INTO skills -- React (id, name, pending, description, extraneous) VALUES ('f057af45-e627-499c-8a71-1e6b4ab2fcd2', 'React', false, 'Component-based JavaScript framework', false); -INSERT INTO skills +INSERT INTO skills -- Micronaut (id, name, pending, description, extraneous) VALUES ('689bb262-10af-40ef-bbf6-d8ad062e1470', 'Micronaut', false, 'JVM framework for microservices and serverless apps', false); -INSERT INTO skills +INSERT INTO skills -- CSS (id, name, pending, description, extraneous) VALUES ('6b56f0aa-09aa-4b09-bb81-03481af7e49f', 'CSS', true, 'Style sheet language', false); -INSERT INTO skills +INSERT INTO skills -- Git (id, name, pending, description, extraneous) VALUES ('84682de9-85a7-4bf7-b74b-e9054311a61a', 'Git', true, 'Version control system', false); -INSERT INTO member_skills + +-- Member Skills +INSERT INTO member_skills -- Big Boss, React (id, memberid, skillid, skilllevel, lastuseddate) VALUES ('99b7b700-bba3-440b-8df5-c1b668e9e7e0', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', 'f057af45-e627-499c-8a71-1e6b4ab2fcd2', '5', '2022-06-01'); -INSERT INTO member_skills +INSERT INTO member_skills -- Big Boss, (id, memberid, skillid, skilllevel, lastuseddate) VALUES ('daad16fa-2268-4e72-a2ad-e13aa8b8665b', '72655c4f-1fb8-4514-b31e-7f7e19fa9bd7', '6b56f0aa-09aa-4b09-bb81-03481af7e49f', '4', '2022-06-01'); -INSERT INTO member_skills +INSERT INTO member_skills -- Revolver Ocelot, React (id, memberid, skillid, skilllevel, lastuseddate) VALUES ('e2de59a8-71be-4972-86be-608538503195', '105f2968-a182-45a3-892c-eeff76383fe0', 'f057af45-e627-499c-8a71-1e6b4ab2fcd2', '3', '2022-05-01'); \ No newline at end of file From 93aefba05a16800761148b293d51c9b19e123653 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Tue, 5 Dec 2023 14:06:38 -0600 Subject: [PATCH 14/37] application onboarding changes --- gradle/wrapper/gradle-wrapper.jar | Bin 59203 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 257 ++++++++++++++--------- web-ui/.java-version | 1 + 4 files changed, 155 insertions(+), 105 deletions(-) create mode 100644 web-ui/.java-version diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e708b1c023ec8b20f512888fe07c5bd3ff77bb8f..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 20926 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 i_W%EDg1>@4`_NK(#)z|gdCiK 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 05679dc3c1..aa991fceae 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 4f906e0c81..1b6c787337 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,67 +17,101 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -106,80 +140,95 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/web-ui/.java-version b/web-ui/.java-version new file mode 100644 index 0000000000..ed9d00f9a5 --- /dev/null +++ b/web-ui/.java-version @@ -0,0 +1 @@ +14.0 From 397811fe7f293b2a172bfa28d7f3b7c6ec470b65 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Tue, 5 Dec 2023 15:51:52 -0600 Subject: [PATCH 15/37] add checkins crud permissions and assign to admin role --- .../security/permissions/Permissions.java | 4 ++ .../resources/db/dev/R__Load_testing_data.sql | 41 +++++++++++++++++++ .../services/fixture/PermissionFixture.java | 6 ++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java index cd2aa45ed7..c583fb7ed6 100644 --- a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java +++ b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java @@ -14,4 +14,8 @@ public enum Permissions { CAN_VIEW_ANNIVERSARY_REPORT, CAN_VIEW_BIRTHDAY_REPORT, CAN_VIEW_PROFILE_REPORT, + CAN_CREATE_CHECKINS, + CAN_VIEW_CHECKINS, + CAN_UPDATE_CHECKINS, + CAN_DELETE_CHECKINS, } \ No newline at end of file diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index fddc2962d7..a2d7055d92 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -589,6 +589,27 @@ insert into permissions values ('2d765d5c-8d07-11ee-b9d1-0242ac120002', 'CAN_VIEW_PROFILE_REPORT'); +insert into permissions +(id, permission) +values + ('d84772ac-85c5-4030-9a86-7db41770fbf3', 'CAN_CREATE_CHECKINS'); + +insert into permissions +(id, permission) +values + ('d04bd772-4a37-4cc3-91da-8fc7de08f3be', 'CAN_VIEW_CHECKINS'); + +insert into permissions +(id, permission) +values + ('ecd952a1-c7c8-47a9-b4ee-762b99276a6f', 'CAN_UPDATE_CHECKINS'); + +insert into permissions +(id, permission) +values + ('39adca8f-0f72-49ff-8c59-e39bb9d794dd', 'CAN_DELETE_CHECKINS'); + + -- Admin Permissions insert into role_permissions @@ -664,6 +685,26 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); + +insert into role_permissions +(roleid, permissionid) +values + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '39adca8f-0f72-49ff-8c59-e39bb9d794dd'); + insert into role_permissions (roleid, permissionid) values diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 65105bea6b..e0d8388d51 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -40,7 +40,11 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_VIEW_RETENTION_REPORT, Permissions.CAN_VIEW_ANNIVERSARY_REPORT, Permissions.CAN_VIEW_BIRTHDAY_REPORT, - Permissions.CAN_VIEW_PROFILE_REPORT + Permissions.CAN_VIEW_PROFILE_REPORT, + Permissions.CAN_CREATE_CHECKINS, + Permissions.CAN_VIEW_CHECKINS, + Permissions.CAN_UPDATE_CHECKINS, + Permissions.CAN_DELETE_CHECKINS ); default Permission createACustomPermission(Permissions perm) { From 20e38fb6bd4de2f83c5a0a0233c7cdae4063575e Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Wed, 6 Dec 2023 10:12:06 -0600 Subject: [PATCH 16/37] add comments to make mock data more readable --- .../resources/db/dev/R__Load_testing_data.sql | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index a2d7055d92..a9b25b057c 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -592,22 +592,22 @@ values insert into permissions (id, permission) values - ('d84772ac-85c5-4030-9a86-7db41770fbf3', 'CAN_CREATE_CHECKINS'); + ('d84772ac-85c5-4030-9a86-7db41770fbf3', 'CAN_CREATE_CHECKINS'); insert into permissions (id, permission) values - ('d04bd772-4a37-4cc3-91da-8fc7de08f3be', 'CAN_VIEW_CHECKINS'); + ('d04bd772-4a37-4cc3-91da-8fc7de08f3be', 'CAN_VIEW_CHECKINS'); insert into permissions (id, permission) values - ('ecd952a1-c7c8-47a9-b4ee-762b99276a6f', 'CAN_UPDATE_CHECKINS'); + ('ecd952a1-c7c8-47a9-b4ee-762b99276a6f', 'CAN_UPDATE_CHECKINS'); insert into permissions (id, permission) values - ('39adca8f-0f72-49ff-8c59-e39bb9d794dd', 'CAN_DELETE_CHECKINS'); + ('39adca8f-0f72-49ff-8c59-e39bb9d794dd', 'CAN_DELETE_CHECKINS'); @@ -688,22 +688,22 @@ values insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); -- CAN_CREATE_CHECKINS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS insert into role_permissions (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '39adca8f-0f72-49ff-8c59-e39bb9d794dd'); + ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '39adca8f-0f72-49ff-8c59-e39bb9d794dd'); -- CAN_DELETE_CHECKINS insert into role_permissions (roleid, permissionid) From 5973de833eafb20fdf588a163728a968e8dc7343 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Wed, 6 Dec 2023 14:19:17 -0600 Subject: [PATCH 17/37] remove delete permission for Checkins --- .../security/permissions/Permissions.java | 1 - .../resources/db/dev/R__Load_testing_data.sql | 20 +++++-------------- .../services/fixture/PermissionFixture.java | 3 +-- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java index c583fb7ed6..da2c72eae4 100644 --- a/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java +++ b/server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java @@ -17,5 +17,4 @@ public enum Permissions { CAN_CREATE_CHECKINS, CAN_VIEW_CHECKINS, CAN_UPDATE_CHECKINS, - CAN_DELETE_CHECKINS, } \ No newline at end of file diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index a9b25b057c..9179173b9b 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -604,11 +604,6 @@ insert into permissions values ('ecd952a1-c7c8-47a9-b4ee-762b99276a6f', 'CAN_UPDATE_CHECKINS'); -insert into permissions -(id, permission) -values - ('39adca8f-0f72-49ff-8c59-e39bb9d794dd', 'CAN_DELETE_CHECKINS'); - -- Admin Permissions @@ -677,14 +672,6 @@ insert into role_permissions values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '2d765d5c-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_PROFILE_REPORT - - --- PDL Permissions -insert into role_permissions - (roleid, permissionid) -values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST - insert into role_permissions (roleid, permissionid) values @@ -700,10 +687,13 @@ insert into role_permissions values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS + + +-- PDL Permissions insert into role_permissions -(roleid, permissionid) + (roleid, permissionid) values - ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', '39adca8f-0f72-49ff-8c59-e39bb9d794dd'); -- CAN_DELETE_CHECKINS + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index e0d8388d51..6a83b9f993 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -43,8 +43,7 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_VIEW_PROFILE_REPORT, Permissions.CAN_CREATE_CHECKINS, Permissions.CAN_VIEW_CHECKINS, - Permissions.CAN_UPDATE_CHECKINS, - Permissions.CAN_DELETE_CHECKINS + Permissions.CAN_UPDATE_CHECKINS ); default Permission createACustomPermission(Permissions perm) { From 0543a9e82dee1fef658e321e55ee0f7f3a745a4c Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Thu, 7 Dec 2023 14:37:03 -0600 Subject: [PATCH 18/37] add view permission to action item services --- .../services/action_item/ActionItemController.java | 6 ++++++ .../src/main/resources/db/dev/R__Load_testing_data.sql | 9 +++++++++ .../services/action_item/ActionItemControllerTest.java | 10 +++++++--- .../checkins/services/fixture/PermissionFixture.java | 6 ++++-- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java index 0036031809..a14a5d0207 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java @@ -10,6 +10,10 @@ import io.micronaut.core.annotation.Nullable; import javax.validation.Valid; + +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; + import java.net.URI; import java.util.List; import java.util.Set; @@ -78,6 +82,7 @@ public HttpResponse deleteActionItem(UUID id) { * @return {@link ActionItem} */ @Get("/{id}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public ActionItem readActionItem(UUID id) { return actionItemServices.read(id); } @@ -90,6 +95,7 @@ public ActionItem readActionItem(UUID id) { * @return {@link List < CheckIn > list of checkins} */ @Get("/{?checkinid,createdbyid}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Set findActionItems(@Nullable UUID checkinid, @Nullable UUID createdbyid) { return actionItemServices.findByFields(checkinid, createdbyid); diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 9179173b9b..1a60b34a0f 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -725,6 +725,10 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2d765f78-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_BIRTHDAY_REPORT +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS -- Member Permissions @@ -748,6 +752,11 @@ insert into role_permissions values ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST +insert into role_permissions +(roleid, permissionid) +values + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS + -- Feedback Templates/Template Questions INSERT INTO feedback_templates diff --git a/server/src/test/java/com/objectcomputing/checkins/services/action_item/ActionItemControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/action_item/ActionItemControllerTest.java index d86497f168..0c9c8b8c95 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/action_item/ActionItemControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/action_item/ActionItemControllerTest.java @@ -16,6 +16,8 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.inject.Inject; @@ -34,6 +36,10 @@ class ActionItemControllerTest extends TestContainersSuite implements MemberProf @Client("/services/action-items") HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } @Test void testCreateAnActionItemByAdmin() { @@ -315,7 +321,6 @@ void testDeleteActionItemByMember() { void testDeleteAnActionItemByADMINIdWhenCompleted() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - createAndAssignAdminRole(memberProfileOfUser); CheckIn checkIn = createACompletedCheckIn(memberProfileOfPDL, memberProfileOfUser); @@ -481,7 +486,6 @@ void testFindActionItemsByAdmin() { void testFindAllActionItemsByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForAdmin = createADefaultMemberProfileForPdl(memberProfile); - createAndAssignAdminRole(memberProfileForAdmin); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForAdmin); @@ -503,7 +507,7 @@ void testFindAllActionItemByNonAdmin() { CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); - ActionItem actionItem = createADefaultActionItem(checkIn, memberProfile); + createADefaultActionItem(checkIn, memberProfile); final HttpRequest request = HttpRequest.GET("/") .basicAuth(memberProfileForPDL.getWorkEmail(), MEMBER_ROLE); diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 6a83b9f993..85210cd258 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -14,7 +14,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_VIEW_FEEDBACK_REQUEST, Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_CHECKINS ); // Add PDL Permissions here @@ -23,7 +24,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_CREATE_FEEDBACK_REQUEST, Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, - Permissions.CAN_VIEW_PERMISSIONS + Permissions.CAN_VIEW_PERMISSIONS, + Permissions.CAN_VIEW_CHECKINS ); // Add ADMIN Permissions here From b8ac1b619c5c1e27ecf8925cff6a1fac8aee4387 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Thu, 7 Dec 2023 14:38:11 -0600 Subject: [PATCH 19/37] add view permission to agenda item services --- .../services/agenda_item/AgendaItemController.java | 5 +++++ .../agenda_item/AgendaItemControllerTest.java | 14 ++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java index 38c63df3db..de90a1fbb2 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java @@ -1,6 +1,9 @@ package com.objectcomputing.checkins.services.agenda_item; import com.objectcomputing.checkins.exceptions.NotFoundException; +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; + import io.micronaut.core.annotation.Nullable; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; @@ -93,6 +96,7 @@ public Mono> updateAgendaItem(@Body @Valid AgendaItem a * @return {@link List list of checkins */ @Get("/{?checkinid,createdbyid}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Mono>> findAgendaItems(@Nullable UUID checkinid, @Nullable UUID createdbyid) { return Mono.fromCallable(() -> agendaItemServices.findByFields(checkinid, createdbyid)) @@ -109,6 +113,7 @@ public Mono>> findAgendaItems(@Nullable UUID checki * @return {@link AgendaItem} */ @Get("/{id}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Mono> readAgendaItem(UUID id) { return Mono.fromCallable(() -> agendaItemServices.read(id)) .switchIfEmpty(Mono.error(new NotFoundException("No agennda item for UUID"))) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemControllerTest.java index 65a4a2ac2a..58c58b7650 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemControllerTest.java @@ -8,7 +8,6 @@ import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.RoleFixture; import com.objectcomputing.checkins.services.memberprofile.MemberProfile; -import com.objectcomputing.checkins.services.role.RoleType; import io.micronaut.core.type.Argument; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; @@ -16,11 +15,11 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.inject.Inject; -import org.reactivestreams.Publisher; -import reactor.test.StepVerifier; import java.util.*; import java.util.stream.Collectors; @@ -37,6 +36,10 @@ public class AgendaItemControllerTest extends TestContainersSuite implements Mem @Client("/services/agenda-items") HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } @Test void testCreateAgendaItemByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); @@ -311,7 +314,6 @@ void testReadAgendaItemNotFoundByUnrelatedUser() { void testFindAllAgendaItemByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfile); - createAndAssignAdminRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileOfUser); @@ -372,7 +374,6 @@ void testFindAgendaItemByMemberIdForAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileForUnrelatedUser = createAnUnrelatedUser(); - createAndAssignRole(RoleType.ADMIN, memberProfileForUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -392,7 +393,6 @@ void testFindAgendaItemByCheckinIdForAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileForUnrelatedUser = createAnUnrelatedUser(); - createAndAssignRole(RoleType.ADMIN, memberProfileForUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -690,7 +690,6 @@ void testUpdateAgendaItemForUnrelatedUserByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - createAndAssignAdminRole(memberProfileOfMrNobody); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -754,7 +753,6 @@ void testDeleteAgendaItemByMember() { void testDeleteAAgendaItemByADMINIdWhenCompleted() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - createAndAssignAdminRole(memberProfileOfUser); CheckIn checkIn = createACompletedCheckIn(memberProfileOfPDL, memberProfileOfUser); From 62161870d7c73f7e1a86a9f9ade0c9b60105a878 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Thu, 7 Dec 2023 14:38:49 -0600 Subject: [PATCH 20/37] add view permission to checkin notes services --- .../checkin_notes/CheckinNoteController.java | 6 ++ .../CheckinNoteControllerTest.java | 81 ++++++++++--------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java index 2ef10f9c0a..18d5e1827d 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java @@ -11,6 +11,10 @@ import io.micronaut.core.annotation.Nullable; import javax.validation.Valid; import javax.validation.constraints.NotNull; + +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; + import java.net.URI; import java.util.Set; import java.util.UUID; @@ -66,6 +70,7 @@ public HttpResponse updateCheckinNote(@Body @Valid CheckinNote chec * @return */ @Get("/{?checkinid,createdbyid}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Set findCheckinNote(@Nullable UUID checkinid, @Nullable UUID createdbyid) { return checkinNoteServices.findByFields(checkinid, createdbyid); @@ -78,6 +83,7 @@ public Set findCheckinNote(@Nullable UUID checkinid, * @return */ @Get("/{id}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public CheckinNote readCheckinNote(@NotNull UUID id) { return checkinNoteServices.read(id); } diff --git a/server/src/test/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteControllerTest.java index 7b5ad4be9f..7f7caaeaeb 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteControllerTest.java @@ -17,6 +17,8 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.inject.Inject; @@ -36,11 +38,15 @@ public class CheckinNoteControllerTest extends TestContainersSuite implements Me @Client("/services/checkin-notes") HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } @Test void testCreateCheckinNoteByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignAdminRole(memberProfileOfUser); + Role role = assignAdminRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfPDL, memberProfileOfUser); @@ -67,7 +73,7 @@ void testCreateCheckinNoteByAdmin() { void testCreateCheckinNoteByPdl() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfUser); + Role role = assignPdlRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfPDL, memberProfileOfUser); @@ -93,7 +99,7 @@ void testCreateCheckinNoteByPdl() { void testCreateCheckinNoteByMember() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfile); + Role role = assignMemberRole(memberProfile); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -157,7 +163,7 @@ void testCreateNullCheckinNote() { void testCreateACheckInNoteForNonExistingCheckInId() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfile); + Role role = assignPdlRole(memberProfile); CheckinNoteCreateDTO checkinNoteCreateDTO = new CheckinNoteCreateDTO(); checkinNoteCreateDTO.setCheckinid(UUID.randomUUID()); @@ -182,7 +188,7 @@ void testCreateACheckInNoteForNonExistingCheckInId() { void testCreateACheckInNoteForNonExistingMemberId() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfile); + Role role = assignPdlRole(memberProfile); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -209,7 +215,7 @@ void testCreateACheckInNoteForNonExistingMemberId() { void testCreateACheckInNoteByPLDIdWhenCompleted() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createACompletedCheckIn(memberProfileOfPDL, memberProfileOfUser); @@ -235,7 +241,7 @@ void testCreateACheckInNoteByPLDIdWhenCompleted() { void testCreateThrowsPermissionException() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createACompletedCheckIn(memberProfileOfPDL, memberProfileOfUser); @@ -262,7 +268,7 @@ void testCreateCheckinNoteByUnrelatedPDL() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileOfMrNobody); + Role pdlRole = assignPdlRole(memberProfileOfMrNobody); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -288,9 +294,8 @@ void testCreateCheckinNoteByUnrelatedPDL() { @Test void testCreateCheckinNoteByPDLWhoCreatedIt() { MemberProfile memberProfile = createADefaultMemberProfile(); - MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfFormerPDL = createAnUnrelatedUser(); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileOfFormerPDL); + Role pdlRole = assignPdlRole(memberProfileOfFormerPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileOfFormerPDL); @@ -317,7 +322,7 @@ void testCreateCheckinNoteByPDLWhoCreatedIt() { void testReadCheckinNoteByPDL() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -335,7 +340,7 @@ void testReadCheckinNoteByPDL() { void testReadCheckinNoteByMEMBER() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileForPDL); + Role role = assignMemberRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -353,7 +358,7 @@ void testReadCheckinNoteByMEMBER() { void testReadCheckinNoteByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileForPDL); + Role role = assignAdminRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -372,7 +377,7 @@ void testReadCheckinNoteByPDLNotOnCheckin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileForFormerPDL = createASecondDefaultMemberProfileForPdl(memberProfile); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role pdlRole = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForFormerPDL); @@ -394,7 +399,7 @@ void testReadCheckinNoteByPDLNotOnCheckin() { @Test void testReadCheckinNoteNotFound() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role pdlRole = assignPdlRole(memberProfileOfPDL); UUID randomCheckinID = UUID.randomUUID(); @@ -416,7 +421,7 @@ void testReadCheckinNoteNotFoundByUnrelatedPDL() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileOfMrNobody); + Role pdlRole = assignPdlRole(memberProfileOfMrNobody); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -439,7 +444,7 @@ void testReadCheckinNoteNotFoundByUnrelatedPDL() { void testReadCheckinNoteByFormerPDLWhoCreatedIt() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileOfFormerPDL = createAnUnrelatedUser(); - Role pdlRole = createAndAssignRole(RoleType.PDL, memberProfileOfFormerPDL); + Role pdlRole = assignPdlRole(memberProfileOfFormerPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileOfFormerPDL); @@ -458,7 +463,7 @@ void testReadCheckinNoteByFormerPDLWhoCreatedIt() { void testFindAllCheckinNoteByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role pdlRole = createAndAssignRole(RoleType.ADMIN, memberProfileForPDL); + Role pdlRole = assignAdminRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -477,11 +482,11 @@ void testFindAllCheckinNoteByAdmin() { void testFindAllCheckinNoteByNonAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileForPDL); + Role role = assignMemberRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); - CheckinNote checkinNote = createADefaultCheckInNote(checkIn, memberProfile); + createADefaultCheckInNote(checkIn, memberProfile); final HttpRequest request = HttpRequest.GET("/") .basicAuth(memberProfileForPDL.getWorkEmail(), role.getRole()); @@ -500,7 +505,7 @@ void testFindAllCheckinNoteByNonAdmin() { void testFindCheckinNoteByBothCheckinIdAndCreateByid() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfile); + Role role = assignPdlRole(memberProfile); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -521,7 +526,7 @@ void testFindCheckinNoteByMemberIdForAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileForUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileForUnrelatedUser); + Role role = assignAdminRole(memberProfileForUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -541,7 +546,7 @@ void testFindCheckinNoteByCheckinIdForAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileForUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileForUnrelatedUser); + Role role = assignAdminRole(memberProfileForUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -560,7 +565,7 @@ void testFindCheckinNoteByCheckinIdForAdmin() { void testFindCheckinNoteByCheckinIdForPDL() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -580,7 +585,7 @@ void testFindCheckinNoteByCheckinIdForUnrelatedUser() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile unrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, unrelatedUser); + Role role = assignPdlRole(unrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -601,7 +606,7 @@ void testFindCheckinNoteByCheckinIdForUnrelatedUser() { void testFindCheckinNoteByCreatedByIdByMember() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -621,7 +626,7 @@ void testFindCheckinNoteByCreatedByIdByUnrelatedUser() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile anUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, anUnrelatedUser); + Role role = assignPdlRole(anUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -642,7 +647,7 @@ void testFindCheckinNoteByCreatedByIdByUnrelatedUser() { void testUpdateCheckinNoteByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileForPDL); + Role role = assignAdminRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -661,7 +666,7 @@ void testUpdateCheckinNoteByAdmin() { void testUpdateCheckinNoteByPDL() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -679,7 +684,7 @@ void testUpdateCheckinNoteByPDL() { void testUpdateCheckinNoteByMEMBER() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfile); + Role role = assignMemberRole(memberProfile); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -697,7 +702,7 @@ void testUpdateCheckinNoteByMEMBER() { void testUpdateInvalidCheckinNote() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -726,7 +731,7 @@ void testUpdateInvalidCheckinNote() { @Test void testUpdateNullCheckinNote() { MemberProfile memberProfile = createADefaultMemberProfile(); - Role role = createAndAssignRole(RoleType.PDL, memberProfile); + Role role = assignPdlRole(memberProfile); final HttpRequest request = HttpRequest.PUT("", "") .basicAuth("test@test.com", role.getRole()); @@ -759,7 +764,7 @@ void testUpdateUnAuthorized() { void testUpdateNonExistingCheckInNote() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -784,7 +789,7 @@ void testUpdateNonExistingCheckInNote() { void testUpdateNonExistingCheckInNoteForCheckInId() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -809,7 +814,7 @@ void testUpdateNonExistingCheckInNoteForCheckInId() { void testUpdateNonExistingCheckInNoteForMemberId() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); - Role role = createAndAssignRole(RoleType.PDL, memberProfileForPDL); + Role role = assignPdlRole(memberProfileForPDL); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -835,7 +840,7 @@ void testUpdateCheckInNoteForUnrelatedUserByPdlWhenCompleted() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfMrNobody); + Role role = assignPdlRole(memberProfileOfMrNobody); CheckIn checkIn = createACompletedCheckIn(memberProfile, memberProfileForPDL); @@ -860,7 +865,7 @@ void testUpdateCheckInNoteForUnrelatedUserByAdmin() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileOfMrNobody); + Role role = assignAdminRole(memberProfileOfMrNobody); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); @@ -879,7 +884,7 @@ void testUpdateCheckInNoteForUnrelatedUserByAdmin() { void testUpdateThrowsPermissionException() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileForUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileForUser); + Role role = assignPdlRole(memberProfileForUser); CheckIn checkIn = createACompletedCheckIn(memberProfileForUser, memberProfileOfPDL); CheckinNote checkinNote = createADefaultCheckInNote(checkIn, memberProfileForUser); From 250c095a51d82646b87c3eee4c52e7097f4ad7fd Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Thu, 7 Dec 2023 14:39:01 -0600 Subject: [PATCH 21/37] add view permission to checkin services --- .../services/checkins/CheckInController.java | 5 + .../checkins/CheckInControllerTest.java | 108 +++++++++++------- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java index 3195184f10..40f9ee6eae 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java @@ -1,6 +1,9 @@ package com.objectcomputing.checkins.services.checkins; import com.objectcomputing.checkins.exceptions.NotFoundException; +import com.objectcomputing.checkins.security.permissions.Permissions; +import com.objectcomputing.checkins.services.permissions.RequiredPermission; + import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; @@ -50,6 +53,7 @@ public CheckInController(CheckInServices checkInServices, * @return */ @Get("/{?teamMemberId,pdlId,completed}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Mono>> findCheckIns(@Nullable UUID teamMemberId, @Nullable UUID pdlId, @Nullable Boolean completed) { return Mono.fromCallable(() -> checkInServices.findByFields(teamMemberId, pdlId, completed)) .publishOn(Schedulers.fromExecutor(eventLoopGroup)) @@ -100,6 +104,7 @@ public Mono> update(@Body @Valid @NotNull CheckIn checkIn, * @return */ @Get("/{id}") + @RequiredPermission(Permissions.CAN_VIEW_CHECKINS) public Mono> readCheckIn(@NotNull UUID id) { return Mono.fromCallable(() -> checkInServices.read(id)) .switchIfEmpty(Mono.error(new NotFoundException("No checkin for UUID"))) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/checkins/CheckInControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/checkins/CheckInControllerTest.java index 686c053f00..eb99df396e 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/checkins/CheckInControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/checkins/CheckInControllerTest.java @@ -15,6 +15,8 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; + +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import jakarta.inject.Inject; @@ -23,6 +25,7 @@ import java.util.stream.Collectors; import static com.objectcomputing.checkins.services.role.RoleType.Constants.*; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -33,11 +36,15 @@ public class CheckInControllerTest extends TestContainersSuite implements Member @Client("/services/check-ins") private HttpClient client; + @BeforeEach + void createRolesAndPermissions() { + createAndAssignRoles(); + } @Test public void testCreateACheckInByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignAdminRole(memberProfileOfUser); + Role role = assignAdminRole(memberProfileOfUser); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -61,7 +68,7 @@ public void testCreateACheckInByAdmin() { public void testCreateACheckInByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -85,7 +92,7 @@ public void testCreateACheckInByMember() { public void testCreateACheckInByPDL() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -110,7 +117,7 @@ public void testCreateACheckInByUnrelatedUser() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfMrNobody); + Role role = assignPdlRole(memberProfileOfMrNobody); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -134,7 +141,7 @@ public void testCreateACheckInByUnrelatedUser() { void testCreateACheckInForSamePDLAndMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn existingCheckIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); @@ -160,7 +167,6 @@ void testCreateAnInvalidCheckIn() { CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); MemberProfile memberProfile = createADefaultMemberProfile(); - Role role = createAndAssignAdminRole(memberProfile); final HttpRequest request = HttpRequest.POST("", checkInCreateDTO).basicAuth(memberProfile.getWorkEmail(), ADMIN_ROLE); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, @@ -182,7 +188,7 @@ void testCreateAnInvalidCheckIn() { void testCreateCheckInForNonExistingMember() { MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfMrNobody); + Role role = assignMemberRole(memberProfileOfMrNobody); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(UUID.randomUUID()); @@ -220,7 +226,7 @@ void testCreateANullCheckIn() { public void testCreateACheckInForInvalidPdlID() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -244,7 +250,7 @@ public void testCreateACheckInForInvalidPdlID() { void testCreateACheckInForInvalidDate() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckInCreateDTO checkInCreateDTO = new CheckInCreateDTO(); checkInCreateDTO.setTeamMemberId(memberProfileOfUser.getId()); @@ -280,7 +286,7 @@ public void testGetReadByIdByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileOfUser); + Role role = assignAdminRole(memberProfileOfUser); CheckIn expected = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -299,7 +305,7 @@ public void testGetReadByIdByPDL() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfUser); CheckIn expected = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -318,7 +324,7 @@ public void testGetReadByIdByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn expected = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -337,7 +343,7 @@ public void testGetReadByIdByUnrelatedUser() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfMrNobody); + Role role = assignMemberRole(memberProfileOfMrNobody); CheckIn expected = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -357,7 +363,7 @@ public void testGetReadByIdByUnrelatedUser() { void testGetReadCheckInDoesNotExist() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); UUID randomCheckinID = UUID.randomUUID(); final HttpRequest request = HttpRequest.GET(String.format("/%s", randomCheckinID)).basicAuth(memberProfileOfPDL.getWorkEmail(), role.getRole()); @@ -376,7 +382,7 @@ void testGetReadCheckInDoesNotExist() { void testUpdateCheckInByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.ADMIN, memberProfileOfPDL); + Role role = assignAdminRole(memberProfileOfPDL); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -392,7 +398,7 @@ void testUpdateCheckInByAdmin() { void testUpdateCheckInByPDL() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -408,7 +414,7 @@ void testUpdateCheckInByPDL() { void testUpdateCheckInByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -425,7 +431,7 @@ void testUpdateCheckInByUnrelatedUser() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfMrNobody = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfMrNobody); + Role role = assignPdlRole(memberProfileOfMrNobody); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -445,7 +451,7 @@ void testUpdateCheckInByUnrelatedUser() { void testUpdateNonExistingCheckIn() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); checkIn.setId(UUID.randomUUID()); @@ -467,7 +473,7 @@ void testUpdateNonExistingCheckIn() { void testUpdateNotExistingMemberCheckIn() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); checkIn.setTeamMemberId(UUID.randomUUID()); @@ -488,7 +494,7 @@ void testUpdateNotExistingMemberCheckIn() { void testUpdateNotMemberCheckInWithoutId() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); checkIn.setId(null); @@ -523,7 +529,7 @@ void testUpdateInvalidCheckIn() { MemberProfile memberProfile = createADefaultMemberProfile(); MemberProfile memberProfileForPDL = createADefaultMemberProfileForPdl(memberProfile); MemberProfile unrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, unrelatedUser); + Role role = assignMemberRole(unrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfile, memberProfileForPDL); checkIn.setTeamMemberId(null); @@ -548,7 +554,7 @@ void testUpdateInvalidCheckIn() { @Test void testUpdateANullCheckIn() { MemberProfile unrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, unrelatedUser); + Role role = assignMemberRole(unrelatedUser); final HttpRequest request = HttpRequest.PUT("", "").basicAuth(unrelatedUser.getWorkEmail(), role.getRole()); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, () -> client.toBlocking().exchange(request, Map.class)); @@ -566,7 +572,7 @@ void testUpdateANullCheckIn() { public void testUpdateACheckInForInvalidPdlID() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); checkIn.setPdlId(UUID.randomUUID()); @@ -587,7 +593,7 @@ public void testUpdateACheckInForInvalidPdlID() { void testUpdateInvalidDateCheckIn() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); checkIn.setCheckInDate(LocalDateTime.of(1965, 11, 12, 15, 56)); @@ -609,7 +615,7 @@ void testUpdateInvalidDateCheckIn() { void testCannotUpdateCheckInIfCompletedIsTrue() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -627,7 +633,7 @@ void testCannotUpdateCheckInIfCompletedIsTrue() { void testCannotUpdateCheckIfCompletedIsTrueUnlessMadeByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignAdminRole(memberProfileOfPDL); + Role role = assignAdminRole(memberProfileOfPDL); CheckIn checkIn = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -644,7 +650,7 @@ public void testGetFindByTeamMemberIdByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -659,7 +665,7 @@ public void testGetFindByTeamMemberIdByPdl() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -675,7 +681,7 @@ public void testGetFindByTeamMemberIdByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - Role role = createAndAssignAdminRole(memberProfileOfAdmin); + Role role = assignAdminRole(memberProfileOfAdmin); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -691,7 +697,7 @@ public void testGetFindByTeamMemberIdByUnrelatedUser() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUnrelatedUser); + Role role = assignMemberRole(memberProfileOfUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -710,7 +716,7 @@ public void testGetFindByPDLIdByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -729,7 +735,7 @@ public void testGetFindByPDLIdByPDL() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -745,7 +751,7 @@ public void testGetFindByPDLIdByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); - Role role = createAndAssignAdminRole(memberProfileOfAdmin); + Role role = assignAdminRole(memberProfileOfAdmin); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -761,7 +767,7 @@ public void testGetFindByPDLIdByUnrelatedUser() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfUnrelatedUser); + Role role = assignPdlRole(memberProfileOfUnrelatedUser); CheckIn checkIn = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -781,7 +787,7 @@ public void testGetFindByCompletedByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignAdminRole(memberProfileOfUnrelatedUser); + Role role = assignAdminRole(memberProfileOfUnrelatedUser); CheckIn checkIn1 = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); CheckIn checkIn2 = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -794,9 +800,15 @@ public void testGetFindByCompletedByAdmin() { expected.add(checkIn2); expected.add(checkIn3); + Set allCheckins = new HashSet<>(); + allCheckins.add(checkIn1); + allCheckins.add(checkIn2); + allCheckins.add(checkIn3); + assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(expected.size(), response.body().size()); assertEquals(expected, response.body()); + assertNotEquals(allCheckins, response.body()); } @Test @@ -805,7 +817,7 @@ public void testGetFindByCompletedByMember() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUser); + Role role = assignMemberRole(memberProfileOfUser); CheckIn checkIn1 = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); CheckIn checkIn2 = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -817,6 +829,8 @@ public void testGetFindByCompletedByMember() { assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(1, response.body().size()); assertEquals(checkIn2, response.body().iterator().next()); + assertNotEquals(checkIn1, response.body().iterator().next()); + assertNotEquals(checkIn3, response.body().iterator().next()); } @Test @@ -825,7 +839,7 @@ public void testGetFindByCompletedByPDL() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfPDL); + Role role = assignPdlRole(memberProfileOfPDL); CheckIn checkIn1 = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); CheckIn checkIn2 = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -838,9 +852,15 @@ public void testGetFindByCompletedByPDL() { expected.add(checkIn2); expected.add(checkIn3); + Set allCheckins = new HashSet<>(); + allCheckins.add(checkIn1); + allCheckins.add(checkIn2); + allCheckins.add(checkIn3); + assertEquals(HttpStatus.OK, response.getStatus()); assertEquals(expected.size(), response.body().size()); assertEquals(expected, response.body()); + assertNotEquals(allCheckins, response.body()); } @Test @@ -849,7 +869,7 @@ void testFindAllCheckInsByAdmin() { MemberProfile memberProfileOfPDL = createADefaultMemberProfile(); MemberProfile memberProfileOfUser = createADefaultMemberProfileForPdl(memberProfileOfPDL); MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignAdminRole(memberProfileOfUnrelatedUser); + Role role = assignAdminRole(memberProfileOfUnrelatedUser); CheckIn checkIn1 = createADefaultCheckIn(memberProfileOfUser, memberProfileOfPDL); CheckIn checkIn2 = createACompletedCheckIn(memberProfileOfUser, memberProfileOfPDL); @@ -872,7 +892,7 @@ void testFindAllCheckInsByAdmin() { void testFindAllCheckInsByMember() { MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUnrelatedUser); + Role role = assignMemberRole(memberProfileOfUnrelatedUser); final HttpRequest request = HttpRequest.GET(String.format("/")).basicAuth(memberProfileOfUnrelatedUser.getWorkEmail(), role.getRole()); @@ -889,7 +909,7 @@ void testFindAllCheckInsByMember() { void testFindAllCheckInsByPDL() { MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfUnrelatedUser); + Role role = assignPdlRole(memberProfileOfUnrelatedUser); final HttpRequest request = HttpRequest.GET(String.format("/")).basicAuth(memberProfileOfUnrelatedUser.getWorkEmail(), role.getRole()); HttpClientResponseException responseException = assertThrows(HttpClientResponseException.class, @@ -905,7 +925,7 @@ void testFindAllCheckInsByPDL() { void testCheckInDoesNotExistForTeamMemberID() { MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUnrelatedUser); + Role role = assignMemberRole(memberProfileOfUnrelatedUser); final HttpRequest request = HttpRequest.GET(String.format("/?teamMemberId=%s", memberProfileOfUnrelatedUser.getId())).basicAuth(memberProfileOfUnrelatedUser.getWorkEmail(), role.getRole()); HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(CheckIn.class)); @@ -918,7 +938,7 @@ void testCheckInDoesNotExistForTeamMemberID() { void testCheckInDoesNotExistForPdlId() { MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.PDL, memberProfileOfUnrelatedUser); + Role role = assignPdlRole(memberProfileOfUnrelatedUser); final HttpRequest request = HttpRequest.GET(String.format("/?pdlId=%s", memberProfileOfUnrelatedUser.getId())).basicAuth(memberProfileOfUnrelatedUser.getWorkEmail(), role.getRole()); HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(CheckIn.class)); @@ -931,7 +951,7 @@ void testCheckInDoesNotExistForPdlId() { public void testCheckInDoesNotExistForCompleted() { MemberProfile memberProfileOfUnrelatedUser = createAnUnrelatedUser(); - Role role = createAndAssignRole(RoleType.MEMBER, memberProfileOfUnrelatedUser); + Role role = assignMemberRole(memberProfileOfUnrelatedUser); final HttpRequest request = HttpRequest.GET(String.format("/?completed=%s", true)).basicAuth(memberProfileOfUnrelatedUser.getWorkEmail(), role.getRole()); final HttpResponse> response = client.toBlocking().exchange(request, Argument.setOf(CheckIn.class)); From 3205f277c418160d42f7a3663ba6085106c73037 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Mon, 11 Dec 2023 15:42:41 -0600 Subject: [PATCH 22/37] organize mock data more --- .../resources/db/dev/R__Load_testing_data.sql | 278 ++++++++++-------- 1 file changed, 155 insertions(+), 123 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 1a60b34a0f..771ba5ba3d 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -23,6 +23,7 @@ delete from feedback_templates; delete from member_profile; delete from skills; +-- Member Profiles INSERT INTO member_profile -- Gina Bremehr (id, firstName, lastName, title, location, workEmail, employeeid, startdate, biotext, supervisorid, birthDate) VALUES @@ -123,6 +124,8 @@ INSERT INTO member_profile -- Huey Emmerich VALUES ('8d75c07e-6adc-437a-8659-7dd953ce6600', PGP_SYM_ENCRYPT('Huey','${aeskey}'), PGP_SYM_ENCRYPT('Emmerich','${aeskey}'), PGP_SYM_ENCRYPT('Head of R&D','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Mother Base','${aeskey}'), PGP_SYM_ENCRYPT('emmerichh@objectcomputing.com','${aeskey}'), '657483498', '2022-03-29', PGP_SYM_ENCRYPT('Waiting for love to bloom on the battlefield','${aeskey}'), '43ee8e79-b33d-44cd-b23c-e183894ebfef', '1943-07-04'); + +-- Roles INSERT INTO role (id, description, role) VALUES @@ -285,7 +288,6 @@ VALUES ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '8fa673c0-ca19-4271-b759-41cb9db2e83a'); -- Holly Williams - -- Teams INSERT INTO team -- Checkins Experts (id, name, description) @@ -308,7 +310,8 @@ VALUES ('e545dfa1-a07d-4099-9a5b-ed14f07b87cc', PGP_SYM_ENCRYPT('PMO Superness','${aeskey}'), PGP_SYM_ENCRYPT('Excellent PMO Artists','${aeskey}')); --- Checkins Experts Members +-- Team Members +---- Checkins Experts Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES @@ -334,8 +337,7 @@ INSERT INTO team_member VALUES ('adff5631-d4dc-4c61-b3d4-232d1cce8ce0', 'a8733740-cf4c-4c16-a8cf-4f928c409acc', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', false); -- Suman Maroju - --- JavaScript Gurus Members +---- JavaScript Gurus Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES @@ -346,15 +348,13 @@ INSERT INTO team_member VALUES ('f84a21ca-1579-4c6a-8148-6a355518797a', 'e8f052a8-40b5-4fb4-9bab-8b16ed36adc7', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', true); -- Mark Volkmann - --- Micronaut Genii Members +---- Micronaut Genii Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES ('7cf7820a-b099-48e5-b630-4f921ee17d16', '036b95a5-357c-45bd-b60e-e8e2e1afec83', '8fa673c0-ca19-4271-b759-41cb9db2e83a', false); -- Holly Williams - --- PMO Superness Members +---- PMO Superness Members INSERT INTO team_member (id, teamid, memberid, lead) VALUES @@ -367,120 +367,136 @@ VALUES --- Checkins +-- Pramukh Bagur Check-ins +---- 2020-09-29 PM - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Michael Kimberlin VALUES ('92e91c5a-cb00-461a-86b4-d01b3f07754e', '6884ab96-2275-4af9-89d8-ad84254d8759', '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '2020-09-29 17:40:29.04' , false); +INSERT INTO action_items +(id, checkinid, createdbyid, description) -- created by: Holly Williams +Values('b0840fc5-9a8e-43d8-be99-9682fc32e69e', '92e91c5a-cb00-461a-86b4-d01b3f07754e', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Action Item for Holly Williams','${aeskey}')); + +INSERT INTO action_items +(id, checkinid, createdbyid, description) -- created by: Holly Williams +Values('9a779dec-c1b6-484e-ad76-38e7c06b011c', '92e91c5a-cb00-461a-86b4-d01b3f07754e', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Another Action Item for Holly Williams','${aeskey}')); + +---- 2020-09-29 AM - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: John Meyerin VALUES ('1343411e-26bf-4274-81ca-1b46ba3f0cb0', '6884ab96-2275-4af9-89d8-ad84254d8759', '802cb1f5-a255-4236-8719-773fa53d79d9', '2020-09-29 10:40:29.04' , false); +INSERT INTO action_items +(id, checkinid, createdbyid, description) -- created by: Pramukh Bagur +Values('0ead3434-82e7-47b4-a0ef-d1f44d01732b', '1343411e-26bf-4274-81ca-1b46ba3f0cb0', '6884ab96-2275-4af9-89d8-ad84254d8759', PGP_SYM_ENCRYPT('Action Item for Pramukh Bagur','${aeskey}')); + + +-- Mohit Bhatia Check-ins +---- 2020-09-29 - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Michael Kimberlin VALUES ('8aa38f8c-2169-41b1-8548-1c2472fab7ff', 'b2d35288-7f1e-4549-aa2b-68396b162490', '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '2020-09-29 15:40:29.04' , false); -INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) -VALUES -('cf806bb5-7269-48ee-8b72-0b2762c7669f', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '6884ab96-2275-4af9-89d8-ad84254d8759', '2020-09-29 13:42:29.04' , false); +-- Zack Brown Check-ins +---- 2020-09-29 - Completed INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Mark Volkmann VALUES ('bbc3db2a-181d-4ddb-a2e4-7a9842cdfd78', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', '2020-09-29 11:32:29.04' , true); + +-- Jesse Hanner Check-ins +---- 2020-03-20 - Completed INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Pramukh Bagur VALUES -('1f68cfdc-0a4b-4118-b38e-d862a8b82bbb', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '802cb1f5-a255-4236-8719-773fa53d79d9', '2020-09-20 11:32:29.04' , false); +('ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '6884ab96-2275-4af9-89d8-ad84254d8759', '2020-03-20 11:32:29.04' , true); -INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +INSERT INTO checkin_notes +(id, checkinid, createdbyid, description) -- created by: Jesse Hanner VALUES -('e60c3ca1-3894-4466-b418-9b743d058cc8', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '802cb1f5-a255-4236-8719-773fa53d79d9', '2020-06-20 11:32:29.04' , false); +('e5449026-cd9a-4bed-a648-fe3ad9382831', 'ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Jesses note','${aeskey}')); -INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +INSERT INTO private_notes +(id, checkinid, createdbyid, description) -- created by: Jesse Hanner VALUES -('ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '6884ab96-2275-4af9-89d8-ad84254d8759', '2020-03-20 11:32:29.04' , true); +('e5449026-cd9a-4bed-a648-fe3ad9382832', 'ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Jesses private note','${aeskey}')); +---- 2020-09-29 - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Pramukh Bagur VALUES -('10184287-1746-4827-93fe-4e13cc0d2a6d', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2021-02-25 11:32:29.04', true); +('cf806bb5-7269-48ee-8b72-0b2762c7669f', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '6884ab96-2275-4af9-89d8-ad84254d8759', '2020-09-29 13:42:29.04' , false); +INSERT INTO action_items +(id, checkinid, createdbyid, description) -- created by: Jesse Hanner +Values('a6e2c822-feab-4c8b-b164-78158b2d4993', 'cf806bb5-7269-48ee-8b72-0b2762c7669f', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Action Item for Jesse Hanner','${aeskey}')); + +---- 2020-09-20 - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: John Meyerin VALUES -('bdea5de0-4358-4b33-9772-0cd953567540', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2021-03-05 11:32:29.04', true); +('1f68cfdc-0a4b-4118-b38e-d862a8b82bbb', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '802cb1f5-a255-4236-8719-773fa53d79d9', '2020-09-20 11:32:29.04' , false); +---- 2020-06-20 - Active INSERT INTO checkins -(id, teammemberid, pdlid, checkindate, completed) +(id, teammemberid, pdlid, checkindate, completed) -- pdl: John Meyerin VALUES -('553aa528-d5f6-4d15-bfb6-b53738dc7954', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2022-01-16 11:32:29.04', true); +('e60c3ca1-3894-4466-b418-9b743d058cc8', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '802cb1f5-a255-4236-8719-773fa53d79d9', '2020-06-20 11:32:29.04' , false); +-- Unreal Ulysses Check-ins +---- 2021-02-25 - Completed +INSERT INTO checkins +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Geetika Sharma +VALUES +('10184287-1746-4827-93fe-4e13cc0d2a6d', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2021-02-25 11:32:29.04', true); --- Checkins Notes/Private Notes/Action Items INSERT INTO checkin_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Geetika Sharma VALUES ('226a2ab8-03cc-4f9e-96c8-55cf187df045', '10184287-1746-4827-93fe-4e13cc0d2a6d', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('Geetika''s first note for Ulysses', '${aeskey}')); INSERT INTO private_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Geetika Sharma VALUES ('444f6923-7b8e-4d03-8d33-021e7a72653c', '10184287-1746-4827-93fe-4e13cc0d2a6d', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('Geetika''s first private note for Ulysses', '${aeskey}')); +---- 2021-03-05 - Completed +INSERT INTO checkins +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Geetika Sharma +VALUES +('bdea5de0-4358-4b33-9772-0cd953567540', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2021-03-05 11:32:29.04', true); + INSERT INTO checkin_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Geetika Sharma VALUES ('c0d76e16-f96a-4598-8006-52b803e8b26d', 'bdea5de0-4358-4b33-9772-0cd953567540', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('Geetika''s second note for Ulysses', '${aeskey}')); INSERT INTO private_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Geetika Sharma VALUES ('cc47b557-ed78-45c4-b577-89c1c9e705bd', 'bdea5de0-4358-4b33-9772-0cd953567540', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', PGP_SYM_ENCRYPT('Geetika''s second private note for Ulysses', '${aeskey}')); -INSERT INTO checkin_notes -(id, checkinid, createdbyid, description) -VALUES -('73a5e7b5-9292-45c0-a605-5b5c63230892', '553aa528-d5f6-4d15-bfb6-b53738dc7954', '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Julia''s first note for Ulysses', '${aeskey}')); - -INSERT INTO private_notes -(id, checkinid, createdbyid, description) +---- 2022-01-16 - Completed +INSERT INTO checkins +(id, teammemberid, pdlid, checkindate, completed) -- pdl: Julia Smith VALUES -('73a5e7b5-9292-45c0-a605-5b5c63230892', '553aa528-d5f6-4d15-bfb6-b53738dc7954', '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Julia''s first private note for Ulysses', '${aeskey}')); +('553aa528-d5f6-4d15-bfb6-b53738dc7954', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2022-01-16 11:32:29.04', true); INSERT INTO checkin_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Julia Smith VALUES -('e5449026-cd9a-4bed-a648-fe3ad9382831', 'ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Jesses note','${aeskey}')); +('73a5e7b5-9292-45c0-a605-5b5c63230892', '553aa528-d5f6-4d15-bfb6-b53738dc7954', '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Julia''s first note for Ulysses', '${aeskey}')); INSERT INTO private_notes -(id, checkinid, createdbyid, description) +(id, checkinid, createdbyid, description) -- created by: Julia Smith VALUES -('e5449026-cd9a-4bed-a648-fe3ad9382832', 'ff52e697-55a1-4a89-a13f-f3d6fb8f6b3d', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Jesses private note','${aeskey}')); - -INSERT INTO action_items -(id, checkinid, createdbyid, description) -Values('b0840fc5-9a8e-43d8-be99-9682fc32e69e', '92e91c5a-cb00-461a-86b4-d01b3f07754e', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Action Item for Holly Williams','${aeskey}')); - -INSERT INTO action_items -(id, checkinid, createdbyid, description) -Values('9a779dec-c1b6-484e-ad76-38e7c06b011c', '92e91c5a-cb00-461a-86b4-d01b3f07754e', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Another Action Item for Holly Williams','${aeskey}')); - -INSERT INTO action_items -(id, checkinid, createdbyid, description) -Values('a6e2c822-feab-4c8b-b164-78158b2d4993', 'cf806bb5-7269-48ee-8b72-0b2762c7669f', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', PGP_SYM_ENCRYPT('Action Item for Jesse Hanner','${aeskey}')); - -INSERT INTO action_items -(id, checkinid, createdbyid, description) -Values('0ead3434-82e7-47b4-a0ef-d1f44d01732b', '1343411e-26bf-4274-81ca-1b46ba3f0cb0', '6884ab96-2275-4af9-89d8-ad84254d8759', PGP_SYM_ENCRYPT('Action Item for Pramukh Bagur','${aeskey}')); +('73a5e7b5-9292-45c0-a605-5b5c63230892', '553aa528-d5f6-4d15-bfb6-b53738dc7954', '59b790d2-fabc-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('Julia''s first private note for Ulysses', '${aeskey}')); -- Guilds @@ -518,7 +534,7 @@ values('dd694cf2-c0f9-4470-b897-00c564c1252b','06cd3202-a209-4ae1-a49a-10395fbe3 -- Pulse INSERT INTO pulse_response -(id, submissiondate, updateddate, teammemberid, internalfeelings, externalfeelings) +(id, submissiondate, updateddate, teammemberid, internalfeelings, externalfeelings) -- Holly Williams VALUES ('cda41eed-70ea-4d3f-a9d7-cd0c5158eb5f', '2021-01-29', '2021-02-02', '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('Feeling pretty happy','${aeskey}'), PGP_SYM_ENCRYPT('Feeling really good','${aeskey}')); @@ -758,9 +774,10 @@ values ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS --- Feedback Templates/Template Questions +-- Feedback Templates +---- Quarter 1 Feedback Template INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Michael Kimberlin VALUES ('18ef2032-c264-411e-a8e1-ddda9a714bae', 'Q1 Feedback', 'Get feedback for quarter 1', '6207b3fd-042d-49aa-9e28-dcc04f537c2d', '2021-06-06', true, true, false); @@ -774,8 +791,9 @@ INSERT INTO template_questions VALUES ('47f997ca-0045-4147-afcb-0c9ed0b44978', PGP_SYM_ENCRYPT('In what ways are this team member''s contributions impacting the objectives of the organization, their project, or their team?','${aeskey}'), '18ef2032-c264-411e-a8e1-ddda9a714bae', 2, 'TEXT'); +---- Generic Survey 1 INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Gina Bremehr VALUES ('97b0a312-e5dd-46f4-a600-d8be2ad925bb', 'Survey 1', 'Make a survey with a few questions', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2021-05-05', true, true, false); @@ -794,8 +812,9 @@ INSERT INTO template_questions VALUES ('afa7e2cb-366a-4c16-a205-c0d493b80d85', PGP_SYM_ENCRYPT('In what ways does this team member represent OCI values?','${aeskey}'), '97b0a312-e5dd-46f4-a600-d8be2ad925bb', 2, 'TEXT'); +---- Generic Mulitple Choice Survey INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Gina Bremehr VALUES ('1c8bc142-c447-4889-986e-42ab177da683', 'Multiple Choice Survey', 'This survey contains radio buttons and sliders.', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2022-04-04', true, true, false); @@ -814,23 +833,27 @@ INSERT INTO template_questions VALUES ('bf328e35-e486-4ec8-b3e8-acc2c09419fa', PGP_SYM_ENCRYPT('Feel free to elaborate on the choices you made above if you choose to do so', '${aeskey}'), '1c8bc142-c447-4889-986e-42ab177da683', 3, 'TEXT'); +---- Empty Template INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Ron Steinkamp VALUES ('2cb80a06-e723-482f-af9b-6b9516cabfcd', 'Empty Template', 'This template does not have any questions on it', '2559a257-ae84-4076-9ed4-3820c427beeb', '2020-04-04', true, true, false); +---- Private Template INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Geetika Sharma VALUES ('492e4f61-c7e3-4c30-a650-7ec74f2ba545', 'Private Template', 'This template is private', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2020-06-07', true, false, false); +---- Private Template 2 INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc) -- created by: Geetika Sharma VALUES ('c5d10880-f561-11eb-9a03-0242ac130003', 'Private Template 2', 'This template is private', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '2020-06-10', true, false, false); +---- Self Review - 2022 INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc, is_review) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc, is_review) -- created by: Gina Bremehr VALUES ('926a37a4-4ded-4633-8900-715b0383aecc', 'Self Review - 2022', 'This survey is intended for performance self-review.', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2022-11-01', true, true, false, true); @@ -889,8 +912,9 @@ INSERT INTO template_questions VALUES ('f9e5878c-6c4d-4249-8f1a-c3508d8c1597', PGP_SYM_ENCRYPT('Please provide any additional context or reasoning relevant to your self-assessment.', '${aeskey}'), '926a37a4-4ded-4633-8900-715b0383aecc', 11, 'TEXT'); +---- Annual Review - 2022 INSERT INTO feedback_templates -(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc, is_review) +(id, title, description, creator_id, date_created, active, is_public, is_ad_hoc, is_review) -- created by: Gina Bremehr VALUES ('d1e94b60-47c4-4945-87d1-4dc88f088e57', 'Annual Review - 2022', 'This survey is intended for performance review.', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2022-11-21', true, true, false, true); @@ -970,57 +994,83 @@ VALUES ('174e5851-cb24-4a0f-890c-e6f041db4127', PGP_SYM_ENCRYPT('Please provide any additional context or reasoning relevant to your assessment of this team member.', '${aeskey}'), 'd1e94b60-47c4-4945-87d1-4dc88f088e57', 15, 'TEXT'); - --- Feedback Requests +-- Feedback Requests without responses +---- Creator: Geetika Sharma INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Suman Maroju, recipient: Jesse Hanner VALUES ('d62b5c09-7ff9-4b0a-bfee-7f467470a7ef', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '1b4f99da-ef70-4a76-9b37-8bb783b749ad', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '18ef2032-c264-411e-a8e1-ddda9a714bae', '2020-07-07', '2021-08-01', null, 'pending'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Mohit Bhatia, recipient: Jesse Hanner VALUES ('ab7b21d4-f88c-4494-9b0b-8541636025eb', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', 'b2d35288-7f1e-4549-aa2b-68396b162490', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2020-07-07', null, null, 'pending'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Mohit Bhatia, recipient: Zack Brown VALUES ('2dd2347a-c296-4986-b428-3fbf6a24ea1e', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', 'b2d35288-7f1e-4549-aa2b-68396b162490', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2020-07-07', null, null, 'pending'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Mohit Bhatia, recipient: Mark Volkmann VALUES ('c15961e4-6e9b-42cd-8140-ece9efe2445c', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498' , 'b2d35288-7f1e-4549-aa2b-68396b162490', '2c1b77e2-e2fc-46d1-92f2-beabbd28ee3d', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2020-07-07', null, '2020-07-08', 'submitted'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Holly Williams, recipient: Pramukh Bagur VALUES ('e2e24336-0615-4564-af29-d0f7b3ac3db9', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '8fa673c0-ca19-4271-b759-41cb9db2e83a', '6884ab96-2275-4af9-89d8-ad84254d8759', '18ef2032-c264-411e-a8e1-ddda9a714bae', '2018-12-24', '2018-12-25', null, 'sent'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Mohit Bhatia, recipient: Gina Bremehr VALUES ('09fbdaf2-f554-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', 'b2d35288-7f1e-4549-aa2b-68396b162490', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9','97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2020-07-07', null, '2020-07-07', 'submitted'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Mohit Bhatia, recipient: Gina Bremehr VALUES ('82d9db7c-f554-11eb-9a03-0242ac130003', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', 'b2d35288-7f1e-4549-aa2b-68396b162490', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9','97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2020-07-05', null, '2020-07-10', 'submitted'); INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Holly Williams, recipient: Zack Brown VALUES ('e2af1c96-a593-48c2-b9e0-a00193a070c7', '7a6a2d4e-e435-4ec9-94d8-f1ed7c779498', '8fa673c0-ca19-4271-b759-41cb9db2e83a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2021-08-01', '2021-08-05', '2021-08-02', 'submitted'); +---- Creator: Gina Bremehr INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Ron Steinkamp VALUES -('d09031be-fac1-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2020-08-01', '2020-08-05', '2020-08-02', 'submitted'); +('a50f2f8a-7eb0-4456-b5ef-382086827ba0', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '2559a257-ae84-4076-9ed4-3820c427beeb', '1c8bc142-c447-4889-986e-42ab177da683', '2022-04-14', null, null, 'sent'); +---- Creator: Julia Smith INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Jesse Hanner VALUES -('a50f2f8a-7eb0-4456-b5ef-382086827ba0', '01b7d769-9fa2-43ff-95c7-f3b950a27bf9', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '2559a257-ae84-4076-9ed4-3820c427beeb', '1c8bc142-c447-4889-986e-42ab177da683', '2022-04-14', null, null, 'sent'); +('ab2da7fc-fac2-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3' ,'18ef2032-c264-411e-a8e1-ddda9a714bae', '2021-08-01', '2021-08-05', null, 'pending'); + +---- Creator: Zack Brown +INSERT INTO feedback_requests +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Zack Brown +VALUES +('0d0d872d-4f05-4af8-9804-d0a99e450c37', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); + +INSERT INTO feedback_requests +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Zack Brown +VALUES +('1aff4993-2324-41cc-8b21-2ab5715ca70b', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); + +INSERT INTO feedback_requests +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Zack Brown +VALUES +('7ca4d402-0bb9-4989-9087-8a52a63ee5d0', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); + + +-- Feedback Requests with responses +---- Creator: Julia Smith +INSERT INTO feedback_requests +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Zack Brown +VALUES +('d09031be-fac1-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2020-08-01', '2020-08-05', '2020-08-02', 'submitted'); INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) @@ -1032,8 +1082,9 @@ INSERT INTO feedback_answers VALUES ('766a3a2c-88de-4487-b285-e3c667ffe0e6', PGP_SYM_ENCRYPT('While they do a good job of innovating courageously, like I said, their presence sometimes impacts client relations.','${aeskey}'), '47f997ca-0045-4147-afcb-0c9ed0b44978', 'd09031be-fac1-11eb-9a03-0242ac130003', -0.2); +---- Creator: Julia Smith INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Suman Maroju VALUES ('b5596a80-fac3-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '1b4f99da-ef70-4a76-9b37-8bb783b749ad','18ef2032-c264-411e-a8e1-ddda9a714bae', '2021-02-15', '2021-02-25', '2021-02-20', 'submitted'); @@ -1047,13 +1098,9 @@ INSERT INTO feedback_answers VALUES ('98e0c286-facd-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('I have few complaints except the aforementioned need to communicate more with the client', '${aeskey}'), '47f997ca-0045-4147-afcb-0c9ed0b44978', 'b5596a80-fac3-11eb-9a03-0242ac130003', 0.2); +---- Creator: Zack Brown INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -VALUES -('ab2da7fc-fac2-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '67dc3a3b-5bfa-4759-997a-fb6bac98dcf3' ,'18ef2032-c264-411e-a8e1-ddda9a714bae', '2021-08-01', '2021-08-05', null, 'pending'); - -INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Faux Freddy, recipient: Zack Brown VALUES ('74623897-5279-4dbe-94d4-5a247d9f00b1', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); @@ -1067,23 +1114,9 @@ INSERT INTO feedback_answers VALUES ('01565a0e-b8ea-486f-af2e-821a74519953', PGP_SYM_ENCRYPT('Excellent feedback', '${aeskey}'), '47f997ca-0045-4147-afcb-0c9ed0b44978', '74623897-5279-4dbe-94d4-5a247d9f00b1', 0.7); +---- Creator: Julia Smith INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -VALUES -('0d0d872d-4f05-4af8-9804-d0a99e450c37', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); - -INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -VALUES -('1aff4993-2324-41cc-8b21-2ab5715ca70b', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); - -INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -VALUES -('7ca4d402-0bb9-4989-9087-8a52a63ee5d0', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '2dee821c-de32-4d9c-9ecb-f73e5903d17a', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2022-03-01', '2023-08-05', '2022-04-01', 'pending'); - -INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Unreal Ulysses, recipient: Zack Brown VALUES ('b1f60cfa-fac2-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '43ee8e79-b33d-44cd-b23c-e183894ebfef','18ef2032-c264-411e-a8e1-ddda9a714bae', '2021-07-22', '2021-07-31', '2021-07-29', 'submitted'); @@ -1097,19 +1130,12 @@ INSERT INTO feedback_answers VALUES ('c38e5fba-face-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('They are very fun to work with :)', '${aeskey}'), '47f997ca-0045-4147-afcb-0c9ed0b44978', 'b1f60cfa-fac2-11eb-9a03-0242ac130003', 0.8); +---- Creator: Julia Smith INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Unreal Ulysses, recipient: Zack Brown VALUES ('e238dd00-fac4-11eb-9a03-0242ac130003', '59b790d2-fabc-11eb-9a03-0242ac130003', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '43ee8e79-b33d-44cd-b23c-e183894ebfef', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2021-03-22', '2021-04-01', '2021-04-01', 'submitted'); -INSERT INTO feedback_requests -(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -VALUES -('4240735d-15fd-4eea-8bca-8c642a433036', '59b790d2-fabc-11eb-9a03-0242ac130003', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '066b186f-1425-45de-89f2-4ddcc6ebe237', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2021-03-22', '2021-04-01', '2021-04-01', 'submitted'); - - - --- Feedback Answers INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) VALUES @@ -1123,17 +1149,23 @@ VALUES INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) VALUES -('d19e6ac1-f081-414c-a51a-ccc684131bec', PGP_SYM_ENCRYPT('They could definitely learn how to use Vim better. They keep asking me how to exit!', '${aeskey}'), '89c8b612-fca8-4144-88cd-176ddfca35ad', '4240735d-15fd-4eea-8bca-8c642a433036', 0.3); +('5a65fe6b-0f27-4d2c-bc25-a637bc33d630', PGP_SYM_ENCRYPT('Nothing comes to mind.', '${aeskey}'), '3571cf89-22b9-4e0e-baff-1a1e45482472', 'e238dd00-fac4-11eb-9a03-0242ac130003', 0.5); INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) VALUES -('5a65fe6b-0f27-4d2c-bc25-a637bc33d630', PGP_SYM_ENCRYPT('Nothing comes to mind.', '${aeskey}'), '3571cf89-22b9-4e0e-baff-1a1e45482472', 'e238dd00-fac4-11eb-9a03-0242ac130003', 0.5); +('8c13ffa2-fad0-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('They are very good at working on a team--all of us is better than any one of us', '${aeskey}'), 'afa7e2cb-366a-4c16-a205-c0d493b80d85', 'e238dd00-fac4-11eb-9a03-0242ac130003', 0.8); + +---- Creator: Julia Smith +INSERT INTO feedback_requests +(id, creator_id, requestee_id, recipient_id, template_id, send_date, due_date, submit_date, status) -- requestee: Unreal Ulysses, recipient: Joe Warner +VALUES +('4240735d-15fd-4eea-8bca-8c642a433036', '59b790d2-fabc-11eb-9a03-0242ac130003', 'dfe2f986-fac0-11eb-9a03-0242ac130003', '066b186f-1425-45de-89f2-4ddcc6ebe237', '97b0a312-e5dd-46f4-a600-d8be2ad925bb', '2021-03-22', '2021-04-01', '2021-04-01', 'submitted'); INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) VALUES -('8c13ffa2-fad0-11eb-9a03-0242ac130003', PGP_SYM_ENCRYPT('They are very good at working on a team--all of us is better than any one of us', '${aeskey}'), 'afa7e2cb-366a-4c16-a205-c0d493b80d85', 'e238dd00-fac4-11eb-9a03-0242ac130003', 0.8); +('d19e6ac1-f081-414c-a51a-ccc684131bec', PGP_SYM_ENCRYPT('They could definitely learn how to use Vim better. They keep asking me how to exit!', '${aeskey}'), '89c8b612-fca8-4144-88cd-176ddfca35ad', '4240735d-15fd-4eea-8bca-8c642a433036', 0.3); INSERT INTO feedback_answers (id, answer, question_id, request_id, sentiment) From 741316ad9b8d3907e6a88866ca1c76e880a95c35 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Mon, 11 Dec 2023 18:00:04 -0600 Subject: [PATCH 23/37] add create permissions to check-in services --- .../services/action_item/ActionItemController.java | 1 + .../services/agenda_item/AgendaItemController.java | 1 + .../services/checkin_notes/CheckinNoteController.java | 1 + .../checkins/services/checkins/CheckInController.java | 1 + .../main/resources/db/dev/R__Load_testing_data.sql | 11 ++++++++++- .../checkins/services/fixture/PermissionFixture.java | 6 ++++-- 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java index a14a5d0207..951bc3a746 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java @@ -36,6 +36,7 @@ public ActionItemController(ActionItemServices actionItemServices) { * @return {@link HttpResponse } */ @Post() + @RequiredPermission(Permissions.CAN_CREATE_CHECKINS) public HttpResponse createActionItem(@Body @Valid ActionItemCreateDTO actionItem, HttpRequest request) { ActionItem newActionItem = actionItemServices.save(new ActionItem(actionItem.getCheckinid(), diff --git a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java index de90a1fbb2..8f2dc55b26 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java @@ -51,6 +51,7 @@ public AgendaItemController(AgendaItemServices agendaItemServices, * @return {@link HttpResponse } */ @Post("/") + @RequiredPermission(Permissions.CAN_CREATE_CHECKINS) public Mono> createAgendaItem(@Body @Valid AgendaItemCreateDTO agendaItem, HttpRequest request) { return Mono diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java index 18d5e1827d..61a6a4dffc 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java @@ -39,6 +39,7 @@ public CheckinNoteController(CheckinNoteServices checkinNoteServices) { * @return */ @Post() + @RequiredPermission(Permissions.CAN_CREATE_CHECKINS) public HttpResponse createCheckinNote(@Body @Valid CheckinNoteCreateDTO checkinNote, HttpRequest request) { CheckinNote newCheckinNote = checkinNoteServices.save(new CheckinNote(checkinNote.getCheckinid(), checkinNote.getCreatedbyid() , checkinNote.getDescription())); diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java index 40f9ee6eae..59ac1a54e9 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java @@ -69,6 +69,7 @@ public Mono>> findCheckIns(@Nullable UUID teamMemberId */ @Post("/") + @RequiredPermission(Permissions.CAN_CREATE_CHECKINS) public Mono> createCheckIn(@Body @Valid CheckInCreateDTO checkIn, HttpRequest request) { return Mono.fromCallable(() -> checkInServices.save(new CheckIn(checkIn.getTeamMemberId(), checkIn.getPdlId(), checkIn.getCheckInDate(), checkIn.isCompleted()))) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 771ba5ba3d..3fbf648b97 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -704,7 +704,6 @@ values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS - -- PDL Permissions insert into role_permissions (roleid, permissionid) @@ -746,6 +745,11 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); -- CAN_CREATE_CHECKINS + -- Member Permissions insert into role_permissions @@ -773,6 +777,11 @@ insert into role_permissions values ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'd04bd772-4a37-4cc3-91da-8fc7de08f3be'); -- CAN_VIEW_CHECKINS +insert into role_permissions +(roleid, permissionid) +values + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); -- CAN_CREATE_CHECKINS + -- Feedback Templates ---- Quarter 1 Feedback Template diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 85210cd258..3c78534d00 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -15,7 +15,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, Permissions.CAN_VIEW_PERMISSIONS, - Permissions.CAN_VIEW_CHECKINS + Permissions.CAN_VIEW_CHECKINS, + Permissions.CAN_CREATE_CHECKINS ); // Add PDL Permissions here @@ -25,7 +26,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, Permissions.CAN_VIEW_PERMISSIONS, - Permissions.CAN_VIEW_CHECKINS + Permissions.CAN_VIEW_CHECKINS, + Permissions.CAN_CREATE_CHECKINS ); // Add ADMIN Permissions here From 0ecb33084b7270b3bdd06b3e3fed69ae6506b348 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Mon, 11 Dec 2023 18:01:15 -0600 Subject: [PATCH 24/37] update front end error handling to allow for more readable errors --- web-ui/src/api/api.js | 2 +- web-ui/src/context/thunks.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/web-ui/src/api/api.js b/web-ui/src/api/api.js index a221a07364..58bc079866 100644 --- a/web-ui/src/api/api.js +++ b/web-ui/src/api/api.js @@ -66,7 +66,7 @@ export const resolve = async (payload) => { type: UPDATE_TOAST, payload: { severity: "error", - toast: e?.response?.data?.message, + toast: e?.response?.data?.message || e?.message, }, }); } diff --git a/web-ui/src/context/thunks.js b/web-ui/src/context/thunks.js index 777c07dcfa..7c773f8ca9 100644 --- a/web-ui/src/context/thunks.js +++ b/web-ui/src/context/thunks.js @@ -51,6 +51,9 @@ export const createNewCheckin = async (memberProfile, dispatch, csrf) => { }, csrf ); + + if (res.error) return; + const checkin = res.payload && res.payload.data && !res.error ? res.payload.data : null; From 46bc287108e4f044744033d0fea880751d10e542 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Tue, 12 Dec 2023 12:27:27 -0600 Subject: [PATCH 25/37] add update permissions for check-ins --- .../services/action_item/ActionItemController.java | 2 ++ .../services/agenda_item/AgendaItemController.java | 2 ++ .../services/checkin_notes/CheckinNoteController.java | 1 + .../checkins/services/checkins/CheckInController.java | 1 + .../src/main/resources/db/dev/R__Load_testing_data.sql | 10 ++++++++++ .../checkins/services/fixture/PermissionFixture.java | 6 ++++-- 6 files changed, 20 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java index 951bc3a746..adf0dcc4cd 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/action_item/ActionItemController.java @@ -54,6 +54,7 @@ public HttpResponse createActionItem(@Body @Valid ActionItemCreateDT * @return {@link HttpResponse< ActionItem >} */ @Put() + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public HttpResponse updateActionItem(@Body @Valid ActionItem actionItem, HttpRequest request) { ActionItem updatedActionItem = actionItemServices.update(actionItem); return HttpResponse @@ -70,6 +71,7 @@ public HttpResponse updateActionItem(@Body @Valid ActionItem actionItem, Http * @param id, id of {@link ActionItem} to delete */ @Delete("/{id}") + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public HttpResponse deleteActionItem(UUID id) { actionItemServices.delete(id); return HttpResponse diff --git a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java index 8f2dc55b26..5530f00ab1 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/agenda_item/AgendaItemController.java @@ -74,6 +74,7 @@ public Mono> createAgendaItem(@Body @Valid AgendaItemCr * @return {@link HttpResponse< AgendaItem >} */ @Put("/") + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public Mono> updateAgendaItem(@Body @Valid AgendaItem agendaItem, HttpRequest request) { if (agendaItem == null) { return Mono.just(HttpResponse.ok()); @@ -130,6 +131,7 @@ public Mono> readAgendaItem(UUID id) { * @param id, id of {@link AgendaItem} to delete */ @Delete("/{id}") + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public HttpResponse deleteAgendaItem(UUID id) { agendaItemServices.delete(id); return HttpResponse diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java index 61a6a4dffc..608b0a1f9e 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkin_notes/CheckinNoteController.java @@ -56,6 +56,7 @@ public HttpResponse createCheckinNote(@Body @Valid CheckinNoteCreat * @return */ @Put() + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public HttpResponse updateCheckinNote(@Body @Valid CheckinNote checkinNote, HttpRequest request) { CheckinNote updateCheckinNote = checkinNoteServices.update(checkinNote); return HttpResponse.ok().headers(headers -> headers.location( diff --git a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java index 59ac1a54e9..44e469a694 100755 --- a/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/checkins/CheckInController.java @@ -88,6 +88,7 @@ public Mono> createCheckIn(@Body @Valid CheckInCreateDTO c * @return {@link HttpResponse} */ @Put("/") + @RequiredPermission(Permissions.CAN_UPDATE_CHECKINS) public Mono> update(@Body @Valid @NotNull CheckIn checkIn, HttpRequest request) { return Mono.fromCallable(() -> checkInServices.update(checkIn)) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 3fbf648b97..ec31570346 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -750,6 +750,11 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); -- CAN_CREATE_CHECKINS +insert into role_permissions +(roleid, permissionid) +values + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS + -- Member Permissions insert into role_permissions @@ -782,6 +787,11 @@ insert into role_permissions values ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'd84772ac-85c5-4030-9a86-7db41770fbf3'); -- CAN_CREATE_CHECKINS +insert into role_permissions +(roleid, permissionid) +values + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS + -- Feedback Templates ---- Quarter 1 Feedback Template diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index 3c78534d00..a362e6b4e6 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -16,7 +16,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_VIEW_FEEDBACK_ANSWER, Permissions.CAN_VIEW_PERMISSIONS, Permissions.CAN_VIEW_CHECKINS, - Permissions.CAN_CREATE_CHECKINS + Permissions.CAN_CREATE_CHECKINS, + Permissions.CAN_UPDATE_CHECKINS ); // Add PDL Permissions here @@ -27,7 +28,8 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt Permissions.CAN_VIEW_FEEDBACK_ANSWER, Permissions.CAN_VIEW_PERMISSIONS, Permissions.CAN_VIEW_CHECKINS, - Permissions.CAN_CREATE_CHECKINS + Permissions.CAN_CREATE_CHECKINS, + Permissions.CAN_UPDATE_CHECKINS ); // Add ADMIN Permissions here From be5a2bc3fe7e7a3d9c4f9bedaa8fb63d090551e5 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Wed, 13 Dec 2023 17:25:38 -0600 Subject: [PATCH 26/37] add ability to request feedback from member profile for Admins, PDLs, and Supervisors --- web-ui/src/pages/MemberProfilePage.jsx | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/web-ui/src/pages/MemberProfilePage.jsx b/web-ui/src/pages/MemberProfilePage.jsx index 3b0abbc453..45276ab933 100644 --- a/web-ui/src/pages/MemberProfilePage.jsx +++ b/web-ui/src/pages/MemberProfilePage.jsx @@ -1,7 +1,7 @@ import React, { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; -import { selectProfile, selectTerminatedMembers } from "../context/selectors"; +import { selectCurrentUserId, selectIsAdmin, selectProfile, selectTerminatedMembers } from "../context/selectors"; import { AppContext } from "../context/AppContext"; import { getSelectedMemberSkills } from "../api/memberskill"; import { getTeamByMember } from "../api/team"; @@ -18,6 +18,7 @@ import "./MemberProfilePage.css"; import { Avatar, + Button, Card, CardContent, CardHeader, @@ -27,16 +28,23 @@ import { Tooltip, Typography, } from "@mui/material"; +import { useHistory } from "react-router-dom"; const MemberProfilePage = () => { const { state } = useContext(AppContext); + const history = useHistory(); const { csrf, skills, userProfile } = state; const { memberId } = useParams(); const [selectedMember, setSelectedMember] = useState(null); const sortedPdls = selectOrderedPdls(state); const sortedMembers = selectOrderedMemberFirstName(state); - let pdlInfo = sortedPdls && sortedPdls.find((pdl) => pdl?.id === selectedMember?.pdlId) - let supervisorInfo = sortedMembers && sortedMembers.find((memberProfile) => memberProfile?.id === selectedMember?.supervisorid) + const isAdmin = selectIsAdmin(state); + const currentUserId = selectCurrentUserId(state); + const pdlInfo = sortedPdls && sortedPdls.find((pdl) => pdl?.id === selectedMember?.pdlId); + const supervisorInfo = sortedMembers && sortedMembers.find((memberProfile) => memberProfile?.id === selectedMember?.supervisorid); + const currentUserIsPdl = pdlInfo?.id === currentUserId; + const currentUserIsSupervisor = supervisorInfo?.id === currentUserId; + const canRequestFeedback = isAdmin || currentUserIsPdl || currentUserIsSupervisor; useEffect(() => { @@ -157,6 +165,18 @@ const MemberProfilePage = () => {

{(pdlInfo && "PDL: " + pdlInfo.firstName + " " + pdlInfo.lastName) || ("")}

+ {canRequestFeedback && + + } )} From 7edf69951b52eee165841b5fc060e2270ecff6c5 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Thu, 14 Dec 2023 19:13:42 -0600 Subject: [PATCH 27/37] allow selected user's whole chain of command to request feedback on their behalf --- .../resources/db/dev/R__Load_testing_data.sql | 4 +- web-ui/src/context/selectors.js | 28 +++++--- web-ui/src/context/selectors.test.js | 70 ++++++++++++++++++- web-ui/src/pages/MemberProfilePage.jsx | 5 +- 4 files changed, 92 insertions(+), 15 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index ec31570346..66a317d36d 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -52,7 +52,7 @@ VALUES INSERT INTO member_profile -- Michael Kimberlin (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES -('6207b3fd-042d-49aa-9e28-dcc04f537c2d', PGP_SYM_ENCRYPT('Michael','${aeskey}'), PGP_SYM_ENCRYPT('Kimberlin','${aeskey}'), PGP_SYM_ENCRYPT('Director of Organizational Development','${aeskey}'), '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('kimberlinm@objectcomputing.com','${aeskey}'), '12312342', '2012-09-29', PGP_SYM_ENCRYPT('Developer of developers and others','${aeskey}'), null); +('6207b3fd-042d-49aa-9e28-dcc04f537c2d', PGP_SYM_ENCRYPT('Michael','${aeskey}'), PGP_SYM_ENCRYPT('Kimberlin','${aeskey}'), PGP_SYM_ENCRYPT('Director of Organizational Development','${aeskey}'), '8fa673c0-ca19-4271-b759-41cb9db2e83a', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('kimberlinm@objectcomputing.com','${aeskey}'), '12312342', '2012-09-29', PGP_SYM_ENCRYPT('Developer of developers and others','${aeskey}'), '01b7d769-9fa2-43ff-95c7-f3b950a27bf9'); INSERT INTO member_profile -- Mark Volkmann (id, firstName, lastName, title, location, workEmail, employeeid, startdate, biotext, supervisorid) @@ -82,7 +82,7 @@ VALUES INSERT INTO member_profile -- Zack Brown (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) VALUES -('43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Zack','${aeskey}'), PGP_SYM_ENCRYPT('Brown','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '2559a257-ae84-4076-9ed4-3820c427beeb', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('brownz@objectcomputing.com','${aeskey}'), '123123412', '2012-09-29', PGP_SYM_ENCRYPT('Engineer Phenomenal','${aeskey}'), null); +('43ee8e79-b33d-44cd-b23c-e183894ebfef', PGP_SYM_ENCRYPT('Zack','${aeskey}'), PGP_SYM_ENCRYPT('Brown','${aeskey}'), PGP_SYM_ENCRYPT('Software Engineer','${aeskey}'), '2559a257-ae84-4076-9ed4-3820c427beeb', PGP_SYM_ENCRYPT('St. Louis','${aeskey}'), PGP_SYM_ENCRYPT('brownz@objectcomputing.com','${aeskey}'), '123123412', '2012-09-29', PGP_SYM_ENCRYPT('Engineer Phenomenal','${aeskey}'), '6207b3fd-042d-49aa-9e28-dcc04f537c2d'); INSERT INTO member_profile -- Joe Warner (id, firstName, lastName, title, pdlid, location, workEmail, employeeid, startdate, biotext, supervisorid) diff --git a/web-ui/src/context/selectors.js b/web-ui/src/context/selectors.js index cfc8513e25..4391af4147 100644 --- a/web-ui/src/context/selectors.js +++ b/web-ui/src/context/selectors.js @@ -232,18 +232,26 @@ export const selectPDLCheckinMap = createSelector(selectCheckins, (checkins) => export const selectSupervisors = createSelector( selectCurrentMembers, selectProfileMap, - (currentMembers, memberProfileMap) => currentMembers?.reduce((supervisors, currentMember) => { - let supervisorId = currentMember.supervisorid; + (currentMembers, memberProfileMap) => { + const filteredMembers = currentMembers?.filter(member => member.supervisorid); - const inSupervisors = supervisors.find( - (supervisor) => supervisorId === supervisor?.id - ) - - if (!inSupervisors){ - supervisors.push(memberProfileMap[supervisorId]); - } + const supervisorIds = filteredMembers?.map(member => member.supervisorid); + const uniqueSupervisorIds = [...new Set(supervisorIds)]; + + const supervisors = uniqueSupervisorIds.map(id => memberProfileMap[id]); return supervisors; - }, []) + } +); + +const buildSupervisorHierarchy = (allSupervisors, member, supervisorChain ) => { + const memberSupervisor = allSupervisors?.find(supervisor => supervisor.id === member?.supervisorid); + supervisorChain.push(memberSupervisor); + return !memberSupervisor?.supervisorid ? supervisorChain : buildSupervisorHierarchy(allSupervisors, memberSupervisor, supervisorChain); +} + +export const selectSupervisorHierarchyIds = (selectedMember) => createSelector( + selectSupervisors, + (allSupervisors) => buildSupervisorHierarchy(allSupervisors, selectedMember, []).map(supervisor => supervisor?.id) ); export const selectIsSupervisor = createSelector( diff --git a/web-ui/src/context/selectors.test.js b/web-ui/src/context/selectors.test.js index 0c0efceb97..315da1e375 100644 --- a/web-ui/src/context/selectors.test.js +++ b/web-ui/src/context/selectors.test.js @@ -10,7 +10,7 @@ import { selectCurrentMembers, selectNormalizedMembers, selectNormalizedTeams, - selectMostRecentCheckin, selectSupervisors, + selectMostRecentCheckin, selectSupervisors, selectSupervisorHierarchyIds, } from "./selectors"; describe("Selectors", () => { @@ -867,6 +867,13 @@ it("selectSupervisors should return only members who are supervisors", () => { lastName: "Boss", supervisorid: 1, }, + { + id: 6, + employeeId: 15, + name: "No Supervisor", + firstName: "No", + lastName: "Supervisor", + }, ] const testState = { @@ -877,3 +884,64 @@ it("selectSupervisors should return only members who are supervisors", () => { expect(selectSupervisors(testState)).toEqual(expectedResult); }); + +it("selectSupervisorHierarchyIds should return a list of ids of everyone who is above the selected member", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 2, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 4, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 5, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 6, + }, + { + id: 5, + employeeId: 15, + name: "The Boss", + firstName: "The", + lastName: "Boss", + supervisorid: 6, + }, + { + id: 6, + employeeId: 15, + name: "No Supervisor", + firstName: "No", + lastName: "Supervisor", + }, + ] + + const testState = { + memberProfiles: testMemberProfiles + }; + + const expectedResult = [testMemberProfiles[1].id, testMemberProfiles[3].id, testMemberProfiles[5].id]; + + expect(selectSupervisorHierarchyIds(testMemberProfiles[0])(testState)).toEqual(expectedResult); +}); + diff --git a/web-ui/src/pages/MemberProfilePage.jsx b/web-ui/src/pages/MemberProfilePage.jsx index 45276ab933..19d34d4fb3 100644 --- a/web-ui/src/pages/MemberProfilePage.jsx +++ b/web-ui/src/pages/MemberProfilePage.jsx @@ -1,7 +1,7 @@ import React, { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; -import { selectCurrentUserId, selectIsAdmin, selectProfile, selectTerminatedMembers } from "../context/selectors"; +import { selectCurrentUserId, selectIsAdmin, selectProfile, selectTerminatedMembers, selectSupervisorHierarchyIds } from "../context/selectors"; import { AppContext } from "../context/AppContext"; import { getSelectedMemberSkills } from "../api/memberskill"; import { getTeamByMember } from "../api/team"; @@ -42,8 +42,9 @@ const MemberProfilePage = () => { const currentUserId = selectCurrentUserId(state); const pdlInfo = sortedPdls && sortedPdls.find((pdl) => pdl?.id === selectedMember?.pdlId); const supervisorInfo = sortedMembers && sortedMembers.find((memberProfile) => memberProfile?.id === selectedMember?.supervisorid); + const supervisorChain = selectSupervisorHierarchyIds(selectedMember)(state); const currentUserIsPdl = pdlInfo?.id === currentUserId; - const currentUserIsSupervisor = supervisorInfo?.id === currentUserId; + const currentUserIsSupervisor = supervisorChain.includes(currentUserId); const canRequestFeedback = isAdmin || currentUserIsPdl || currentUserIsSupervisor; From 5e61113db79b26c8b5937b5bca5bca34469b8bf4 Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Fri, 15 Dec 2023 13:31:57 -0600 Subject: [PATCH 28/37] allow feedback requests that are due in the new year to be submitted --- web-ui/src/pages/FeedbackRequestPage.jsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web-ui/src/pages/FeedbackRequestPage.jsx b/web-ui/src/pages/FeedbackRequestPage.jsx index 05ff6c4d0b..e6dac8fc20 100644 --- a/web-ui/src/pages/FeedbackRequestPage.jsx +++ b/web-ui/src/pages/FeedbackRequestPage.jsx @@ -149,17 +149,19 @@ const FeedbackRequestPage = () => { }, [memberIds, query, dispatch, handleQueryChange]); const isValidDate = useCallback((dateString) => { - let today = new Date(); - today = dateUtils.format(today, "MM/dd/yyyy"); - let timeStamp = Date.parse(dateString) - if (dateString < today) + const today = Date.now(); + const timeStamp = Date.parse(dateString); + if (timeStamp < today) return false; else return !isNaN(timeStamp); }, []); const hasSend = useCallback(() => { - const isValidPair = query.due ? query.due >= query.send : true; + const dueTimestamp = Date.parse(query.due); + const sendTimestamp = Date.parse(query.send); + + const isValidPair = query.due ? dueTimestamp >= sendTimestamp : true; return (query.send && isValidDate(query.send) && isValidPair) }, [query.send, isValidDate, query.due]); From ecef1942404a25d8daae5221faf7678f19a8b366 Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Fri, 15 Dec 2023 14:38:13 -0600 Subject: [PATCH 29/37] Fix selector for subordinates --- web-ui/src/context/selectors.js | 35 +- web-ui/src/context/selectors.test.js | 973 ++++++++++++++------------- 2 files changed, 551 insertions(+), 457 deletions(-) diff --git a/web-ui/src/context/selectors.js b/web-ui/src/context/selectors.js index 4391af4147..803277ee91 100644 --- a/web-ui/src/context/selectors.js +++ b/web-ui/src/context/selectors.js @@ -237,7 +237,7 @@ export const selectSupervisors = createSelector( const supervisorIds = filteredMembers?.map(member => member.supervisorid); const uniqueSupervisorIds = [...new Set(supervisorIds)]; - + const supervisors = uniqueSupervisorIds.map(id => memberProfileMap[id]); return supervisors; } @@ -283,19 +283,42 @@ export const selectMyTeam = createSelector( filterMembersBySupervisor ); +/* Internal Selector, not for export */ +const selectSubordinatesPreventCycle = createSelector( + selectTeamMembersBySupervisorId, + (_, managerId) => managerId, + (_, __, previouslyIncluded) => previouslyIncluded || [], + (state) => state, + (team, managerId, previouslyIncluded, state) => team.reduce((subordinates, teamMember) => { + if(previouslyIncluded.some((current) => current === teamMember.id)) + return subordinates; + else return [...subordinates, ...selectSubordinatesPreventCycle(state, teamMember.id, [...previouslyIncluded, managerId])]; + }, [...team]) +); + export const selectSubordinates = createSelector( selectTeamMembersBySupervisorId, - (state, managerId) => managerId, + (_, managerId) => managerId, (state) => state, (team, managerId, state) => team.reduce((subordinates, teamMember) => { - if(subordinates.some((current) => current.id === teamMember.id)) - return subordinates; - else return [...subordinates, ...selectSubordinates(state, teamMember.id)]; + return [...subordinates, ...selectSubordinatesPreventCycle(state, teamMember.id, [managerId])]; }, [...team]) ); +export const selectCurrentUserSubordinates = createSelector( + selectCurrentUserId, + (state) => state, + (currentUserId, state) => selectSubordinates(state, currentUserId) +); + +export const selectIsSubordinateOfCurrentUser = createSelector( + selectCurrentUserSubordinates, + (_, teamMemberId) => teamMemberId, + (subordinates, teamMemberId) => subordinates.some((teamMember) => teamMember.id == teamMemberId) +); + export const selectTeamMembersWithCheckinPDL = createSelector( - (state, pdlId) => pdlId, + (_, pdlId) => pdlId, selectPDLCheckinMap, selectProfileMap, (pdlId, pdlCheckinMap, profileMap) => diff --git a/web-ui/src/context/selectors.test.js b/web-ui/src/context/selectors.test.js index 315da1e375..12c4d554ad 100644 --- a/web-ui/src/context/selectors.test.js +++ b/web-ui/src/context/selectors.test.js @@ -10,7 +10,10 @@ import { selectCurrentMembers, selectNormalizedMembers, selectNormalizedTeams, - selectMostRecentCheckin, selectSupervisors, selectSupervisorHierarchyIds, + selectMostRecentCheckin, + selectSupervisors, + selectSupervisorHierarchyIds, + selectSubordinates, } from "./selectors"; describe("Selectors", () => { @@ -388,52 +391,9 @@ describe("Selectors", () => { }; expect(selectOrderedPdls(testState)).toEqual(matchingMembers); }); -}); -it("selectCheckinPdls should return an array of all member PDL profiles that have an associated checkin", () => { - const matchingMembers = [ - { - id: 12, - bioText: "foo", - name: "B PersonB", - firstName: "B", - lastName: "PersonB", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - startDate: [2012, 9, 29], - }, - { - id: 13, - bioText: "foo", - name: "C PersonC", - firstName: "C", - lastName: "PersonC", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - startDate: [2012, 9, 29], - }, - ]; - - const testState = { - checkins: [ - { pdlId: 13, completed: false, checkInDate: [2020, 9, 13] }, - { pdlId: 12, completed: false, checkInDate: [2021, 9, 12] }, - { pdlId: 12, completed: true, checkInDate: [2020, 9, 11] }, - ], - memberProfiles: [ - { - id: 11, - bioText: "foo", - name: "A PersonA", - firstName: "A", - lastName: "PersonA", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - startDate: [2012, 9, 29], - }, + it("selectCheckinPdls should return an array of all member PDL profiles that have an associated checkin", () => { + const matchingMembers = [ { id: 12, bioText: "foo", @@ -456,73 +416,55 @@ it("selectCheckinPdls should return an array of all member PDL profiles that hav workEmail: "employee@sample.com", startDate: [2012, 9, 29], }, - ], - }; - expect(selectCheckinPDLS(testState, true, true)).toEqual(matchingMembers); -}); + ]; -it("selectTeamMembersWithCheckinPDL should return an array of all members associated with a pdl that have a checkin", () => { - const matchingMembers = [ - { - id: 12, - bioText: "foo", - name: "B PersonB", - firstName: "B", - lastName: "PersonB", - location: "St Louis", - pdlId: 1, - title: "engineer", - workEmail: "employee@sample.com", - startDate: [2012, 9, 29], - }, - { - id: 13, - bioText: "foo", - name: "C PersonC", - firstName: "C", - lastName: "PersonC", - location: "St Louis", - pdlId: 1, - title: "engineer", - workEmail: "employee@sample.com", - startDate: [2012, 9, 29], - }, - ]; - - const testState = { - checkins: [ - { - teamMemberId: 12, - pdlId: 1, - completed: false, - checkInDate: [2020, 9, 10], - }, - { - teamMemberId: 13, - pdlId: 1, - completed: false, - checkInDate: [2020, 9, 10], - }, - { - teamMemberId: 11, - pdlId: 2, - completed: false, - checkInDate: [2020, 9, 10], - }, - ], - memberProfiles: [ - { - id: 11, - bioText: "foo", - name: "A PersonA", - firstName: "A", - lastName: "PersonA", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 2, - startDate: [2012, 9, 29], - }, + const testState = { + checkins: [ + { pdlId: 13, completed: false, checkInDate: [2020, 9, 13] }, + { pdlId: 12, completed: false, checkInDate: [2021, 9, 12] }, + { pdlId: 12, completed: true, checkInDate: [2020, 9, 11] }, + ], + memberProfiles: [ + { + id: 11, + bioText: "foo", + name: "A PersonA", + firstName: "A", + lastName: "PersonA", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + { + id: 12, + bioText: "foo", + name: "B PersonB", + firstName: "B", + lastName: "PersonB", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + { + id: 13, + bioText: "foo", + name: "C PersonC", + firstName: "C", + lastName: "PersonC", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + ], + }; + expect(selectCheckinPDLS(testState, true, true)).toEqual(matchingMembers); + }); + + it("selectTeamMembersWithCheckinPDL should return an array of all members associated with a pdl that have a checkin", () => { + const matchingMembers = [ { id: 12, bioText: "foo", @@ -547,33 +489,75 @@ it("selectTeamMembersWithCheckinPDL should return an array of all members associ workEmail: "employee@sample.com", startDate: [2012, 9, 29], }, - ], - }; - expect(selectTeamMembersWithCheckinPDL(testState, 1)).toEqual( - matchingMembers - ); -}); + ]; -it("selectCheckinsForTeamMemberAndPDL should return an array of all members associated with a pdl that have a checkin", () => { - const matchingCheckins = [ - { - id: 1, - teamMemberId: 12, - pdlId: 1, - completed: false, - checkInDate: [2020, 9, 10], - }, - { - id: 2, - teamMemberId: 12, - pdlId: 1, - completed: true, - checkInDate: [2020, 10, 10], - }, - ]; - - const testState = { - checkins: [ + const testState = { + checkins: [ + { + teamMemberId: 12, + pdlId: 1, + completed: false, + checkInDate: [2020, 9, 10], + }, + { + teamMemberId: 13, + pdlId: 1, + completed: false, + checkInDate: [2020, 9, 10], + }, + { + teamMemberId: 11, + pdlId: 2, + completed: false, + checkInDate: [2020, 9, 10], + }, + ], + memberProfiles: [ + { + id: 11, + bioText: "foo", + name: "A PersonA", + firstName: "A", + lastName: "PersonA", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + pdlId: 2, + startDate: [2012, 9, 29], + }, + { + id: 12, + bioText: "foo", + name: "B PersonB", + firstName: "B", + lastName: "PersonB", + location: "St Louis", + pdlId: 1, + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + { + id: 13, + bioText: "foo", + name: "C PersonC", + firstName: "C", + lastName: "PersonC", + location: "St Louis", + pdlId: 1, + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + ], + }; + expect(selectTeamMembersWithCheckinPDL(testState, 1)).toEqual( + matchingMembers + ); + }); + + it("selectCheckinsForTeamMemberAndPDL should return an array of all members associated with a pdl that have a checkin", () => { + const matchingCheckins = [ { id: 1, teamMemberId: 12, @@ -588,360 +572,447 @@ it("selectCheckinsForTeamMemberAndPDL should return an array of all members asso completed: true, checkInDate: [2020, 10, 10], }, + ]; + + const testState = { + checkins: [ + { + id: 1, + teamMemberId: 12, + pdlId: 1, + completed: false, + checkInDate: [2020, 9, 10], + }, + { + id: 2, + teamMemberId: 12, + pdlId: 1, + completed: true, + checkInDate: [2020, 10, 10], + }, + { + id: 3, + teamMemberId: 11, + pdlId: 2, + completed: false, + checkInDate: [2020, 9, 10], + }, + { + id: 4, + teamMemberId: 19, + pdlId: 4, + completed: false, + checkInDate: [2020, 9, 10], + }, + ], + memberProfiles: [ + { + id: 11, + bioText: "foo", + name: "A PersonA", + firstName: "A", + lastName: "PersonA", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + pdlId: 2, + startDate: [2012, 9, 29], + }, + { + id: 12, + bioText: "foo", + name: "B PersonB", + firstName: "B", + lastName: "PersonB", + location: "St Louis", + pdlId: 1, + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + { + id: 13, + bioText: "foo", + name: "C PersonC", + firstName: "C", + lastName: "PersonC", + location: "St Louis", + pdlId: 1, + title: "engineer", + workEmail: "employee@sample.com", + startDate: [2012, 9, 29], + }, + ], + }; + expect(selectCheckinsForTeamMemberAndPDL(testState, 12, 1)).toEqual( + matchingCheckins + ); + }); + + it("selectCurrentMembers should return an array of non-terminated profiles", () => { + const testMemberProfiles = [ { - id: 3, - teamMemberId: 11, - pdlId: 2, - completed: false, - checkInDate: [2020, 9, 10], + id: 1, + bioText: "foo", + employeeId: 11, + name: "Iván López Martín", + firstName: "Iván", + lastName: "Martín", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + pdlId: 9, + startDate: [2012, 9, 29], }, { - id: 4, - teamMemberId: 19, - pdlId: 4, - completed: false, - checkInDate: [2020, 9, 10], + id: 2, + bioText: "foo", + employeeId: 12, + name: "B Person", + firstName: "B", + lastName: "PersonB", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + pdlId: 9, + startDate: [2012, 9, 29], }, - ], - memberProfiles: [ { - id: 11, + id: 3, bioText: "foo", - name: "A PersonA", - firstName: "A", - lastName: "PersonA", + employeeId: 13, + name: "C Person", + firstName: "C", + lastName: "PersonC", location: "St Louis", title: "engineer", workEmail: "employee@sample.com", - pdlId: 2, + pdlId: 9, startDate: [2012, 9, 29], + terminationDate: [2020, 12, 31], }, + ]; + const testState = { + memberProfiles: [ + testMemberProfiles[0], + testMemberProfiles[1], + testMemberProfiles[2], + ], + }; + + const result = { + memberProfiles: [testMemberProfiles[0], testMemberProfiles[1]], + }; + + expect(selectCurrentMembers(testState)).toEqual(result.memberProfiles); + }); + + it("selectNormalizedMembers should return an array of appropriate member profiles despite accents", () => { + const testMemberProfiles = [ { - id: 12, + id: 1, bioText: "foo", - name: "B PersonB", + employeeId: 11, + name: "Iván López Martín", + firstName: "Iván", + lastName: "Martín", + location: "St Louis", + title: "engineer", + workEmail: "employee@sample.com", + pdlId: 9, + startDate: [2012, 9, 29], + }, + { + id: 2, + bioText: "foo", + employeeId: 12, + name: "B Person", firstName: "B", lastName: "PersonB", location: "St Louis", - pdlId: 1, title: "engineer", workEmail: "employee@sample.com", + pdlId: 9, startDate: [2012, 9, 29], }, { - id: 13, + id: 3, bioText: "foo", - name: "C PersonC", + employeeId: 13, + name: "C Person", firstName: "C", lastName: "PersonC", location: "St Louis", - pdlId: 1, title: "engineer", workEmail: "employee@sample.com", + pdlId: 9, startDate: [2012, 9, 29], }, - ], - }; - expect(selectCheckinsForTeamMemberAndPDL(testState, 12, 1)).toEqual( - matchingCheckins - ); -}); + ]; + const testState = { + memberProfiles: [ + testMemberProfiles[0], + testMemberProfiles[1], + testMemberProfiles[2], + ], + }; -it("selectCurrentMembers should return an array of non-terminated profiles", () => { - const testMemberProfiles = [ - { - id: 1, - bioText: "foo", - employeeId: 11, - name: "Iván López Martín", - firstName: "Iván", - lastName: "Martín", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - }, - { - id: 2, - bioText: "foo", - employeeId: 12, - name: "B Person", - firstName: "B", - lastName: "PersonB", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - }, - { - id: 3, - bioText: "foo", - employeeId: 13, - name: "C Person", - firstName: "C", - lastName: "PersonC", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - terminationDate: [2020, 12, 31], - }, - ]; - const testState = { - memberProfiles: [ - testMemberProfiles[0], - testMemberProfiles[1], - testMemberProfiles[2], - ], - }; - - const result = { - memberProfiles: [testMemberProfiles[0], testMemberProfiles[1]], - }; - - expect(selectCurrentMembers(testState)).toEqual(result.memberProfiles); -}); + const result = { + memberProfiles: [testMemberProfiles[0]], + }; -it("selectNormalizedMembers should return an array of appropriate member profiles despite accents", () => { - const testMemberProfiles = [ - { - id: 1, - bioText: "foo", - employeeId: 11, - name: "Iván López Martín", - firstName: "Iván", - lastName: "Martín", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - }, - { - id: 2, - bioText: "foo", - employeeId: 12, - name: "B Person", - firstName: "B", - lastName: "PersonB", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - }, - { - id: 3, - bioText: "foo", - employeeId: 13, - name: "C Person", - firstName: "C", - lastName: "PersonC", - location: "St Louis", - title: "engineer", - workEmail: "employee@sample.com", - pdlId: 9, - startDate: [2012, 9, 29], - }, - ]; - const testState = { - memberProfiles: [ - testMemberProfiles[0], - testMemberProfiles[1], - testMemberProfiles[2], - ], - }; - - const result = { - memberProfiles: [testMemberProfiles[0]], - }; - - const searchText = "ivan"; - - expect(selectNormalizedMembers(testState, searchText)).toEqual( - result.memberProfiles - ); -}); + const searchText = "ivan"; -it("selectNormalizedTeams should return an array of appropriate teams despite accents", () => { - const testTeams = [ - { - id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", - name: "Iváns Team", - description: "string", - }, - { - id: "3fa4-5717-4562-b3fc-2c963f66afa6", - name: "stuff", - description: "", - }, - ]; - const testState = { - teams: [testTeams[0], testTeams[1]], - }; - - const searchText = "ivan"; - - const result = { - teams: [testTeams[0]], - }; - - expect(selectNormalizedTeams(testState, searchText)).toEqual(result.teams); -}); + expect(selectNormalizedMembers(testState, searchText)).toEqual( + result.memberProfiles + ); + }); -it("selectMostRecentCheckin should return the most recent and or open checkin", () => { - const memberId = "1"; - const checkins = [ - { - checkInDate: [2020, 9, 29, 10, 32, 29, 40000000], - completed: false, - id: "2", - pdlId: "1", - teamMemberId: "1", - }, - { + it("selectNormalizedTeams should return an array of appropriate teams despite accents", () => { + const testTeams = [ + { + id: "3fa85f64-5717-4562-b3fc-2c963f66afa6", + name: "Iváns Team", + description: "string", + }, + { + id: "3fa4-5717-4562-b3fc-2c963f66afa6", + name: "stuff", + description: "", + }, + ]; + const testState = { + teams: [testTeams[0], testTeams[1]], + }; + + const searchText = "ivan"; + + const result = { + teams: [testTeams[0]], + }; + + expect(selectNormalizedTeams(testState, searchText)).toEqual(result.teams); + }); + + it("selectMostRecentCheckin should return the most recent and or open checkin", () => { + const memberId = "1"; + const checkins = [ + { + checkInDate: [2020, 9, 29, 10, 32, 29, 40000000], + completed: false, + id: "2", + pdlId: "1", + teamMemberId: "1", + }, + { + checkInDate: [2020, 9, 30, 10, 32, 29, 40000000], + completed: false, + id: "1", + pdlId: "1", + teamMemberId: "1", + }, + ]; + + const state = { checkins: [checkins[0], checkins[1]] }; + + const expectedResult = { checkInDate: [2020, 9, 30, 10, 32, 29, 40000000], completed: false, id: "1", pdlId: "1", teamMemberId: "1", - }, - ]; + }; - const state = { checkins: [checkins[0], checkins[1]] }; + console.log(selectMostRecentCheckin(state, memberId)); + expect(selectMostRecentCheckin(state, memberId)).toEqual(expectedResult); + }); - const expectedResult = { - checkInDate: [2020, 9, 30, 10, 32, 29, 40000000], - completed: false, - id: "1", - pdlId: "1", - teamMemberId: "1", - }; + it("selectSupervisors should return only members who are supervisors", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 1, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 1, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 3, + }, + { + id: 5, + employeeId: 15, + name: "The Boss", + firstName: "The", + lastName: "Boss", + }, + ] - console.log(selectMostRecentCheckin(state, memberId)); - expect(selectMostRecentCheckin(state, memberId)).toEqual(expectedResult); -}); + const testState = { + memberProfiles: testMemberProfiles + }; -it("selectSupervisors should return only members who are supervisors", () => { - const testMemberProfiles = [ - { - id: 1, - employeeId: 11, - name: "Big Boss", - firstName: "Big", - lastName: "Boss", - supervisorid: 5, - }, - { - id: 2, - employeeId: 12, - name: "Huey Emmerich", - firstName: "Huey", - lastName: "Emmerich", - supervisorid: 1, - }, - { - id: 3, - employeeId: 13, - name: "Kazuhira Miller", - firstName: "Kazuhira", - lastName: "Miller", - supervisorid: 1, - }, - { - id: 4, - employeeId: 14, - name: "Revolver Ocelot", - firstName: "Revolver", - lastName: "Ocelot", - supervisorid: 3, - }, - { - id: 5, - employeeId: 15, - name: "The Boss", - firstName: "The", - lastName: "Boss", - supervisorid: 1, - }, - { - id: 6, - employeeId: 15, - name: "No Supervisor", - firstName: "No", - lastName: "Supervisor", - }, - ] - - const testState = { - memberProfiles: testMemberProfiles - }; - - const expectedResult = [testMemberProfiles[4], testMemberProfiles[0], testMemberProfiles[2]]; - - expect(selectSupervisors(testState)).toEqual(expectedResult); -}); + const expectedResult = [testMemberProfiles[4], testMemberProfiles[0], testMemberProfiles[2]]; -it("selectSupervisorHierarchyIds should return a list of ids of everyone who is above the selected member", () => { - const testMemberProfiles = [ - { - id: 1, - employeeId: 11, - name: "Big Boss", - firstName: "Big", - lastName: "Boss", - supervisorid: 2, - }, - { - id: 2, - employeeId: 12, - name: "Huey Emmerich", - firstName: "Huey", - lastName: "Emmerich", - supervisorid: 4, - }, - { - id: 3, - employeeId: 13, - name: "Kazuhira Miller", - firstName: "Kazuhira", - lastName: "Miller", - supervisorid: 5, - }, - { - id: 4, - employeeId: 14, - name: "Revolver Ocelot", - firstName: "Revolver", - lastName: "Ocelot", - supervisorid: 6, - }, - { - id: 5, - employeeId: 15, - name: "The Boss", - firstName: "The", - lastName: "Boss", - supervisorid: 6, - }, - { - id: 6, - employeeId: 15, - name: "No Supervisor", - firstName: "No", - lastName: "Supervisor", - }, - ] - - const testState = { - memberProfiles: testMemberProfiles - }; - - const expectedResult = [testMemberProfiles[1].id, testMemberProfiles[3].id, testMemberProfiles[5].id]; - - expect(selectSupervisorHierarchyIds(testMemberProfiles[0])(testState)).toEqual(expectedResult); -}); + expect(selectSupervisors(testState)).toEqual(expectedResult); + }); + + it("selectSupervisorHierarchyIds should return a list of ids of everyone who is above the selected member", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 2, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 4, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 5, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 6, + }, + { + id: 5, + employeeId: 15, + name: "The Boss", + firstName: "The", + lastName: "Boss", + supervisorid: 6, + }, + { + id: 6, + employeeId: 15, + name: "No Supervisor", + firstName: "No", + lastName: "Supervisor", + }, + ] + + const testState = { + memberProfiles: testMemberProfiles + }; + + const expectedResult = [testMemberProfiles[1].id, testMemberProfiles[3].id, testMemberProfiles[5].id]; + + expect(selectSupervisorHierarchyIds(testMemberProfiles[0])(testState)).toEqual(expectedResult); + }); + + it("selectSubordinates should return entire subordinate heirarchy", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 1, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 1, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 3, + }, + { + id: 5, + employeeId: 15, + name: "THE Boss", + firstName: "THE", + lastName: "Boss", + }, + { + id: 6, + employeeId: 16, + name: "Entry Level", + firstName: "Entry", + lastName: "Level", + supervisorid: 4, + }, + { + id: 7, + employeeId: 15, + name: "Other Boss", + firstName: "Other", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 8, + employeeId: 15, + name: "Other Person", + firstName: "Other", + lastName: "Person", + supervisorid: 7, + }, + ] + const testState = { + memberProfiles: testMemberProfiles + }; + + const expectedResult = [testMemberProfiles[1], testMemberProfiles[2], testMemberProfiles[3], testMemberProfiles[5]]; + + expect(selectSubordinates(testState, testMemberProfiles[0].id)).toEqual(expectedResult); + }); + +}); From 39ab309d04233e3f9297a51b7bfee9f7ef3a51ee Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Fri, 15 Dec 2023 15:15:24 -0600 Subject: [PATCH 30/37] Added a couple quick selector tests --- web-ui/src/context/selectors.test.js | 155 +++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/web-ui/src/context/selectors.test.js b/web-ui/src/context/selectors.test.js index 12c4d554ad..3b3baf2e2e 100644 --- a/web-ui/src/context/selectors.test.js +++ b/web-ui/src/context/selectors.test.js @@ -14,6 +14,7 @@ import { selectSupervisors, selectSupervisorHierarchyIds, selectSubordinates, + selectIsSubordinateOfCurrentUser, } from "./selectors"; describe("Selectors", () => { @@ -1015,4 +1016,158 @@ describe("Selectors", () => { expect(selectSubordinates(testState, testMemberProfiles[0].id)).toEqual(expectedResult); }); +it("selectIsSubordinateOfCurrentUser should return true when user is in the current users' heirarchy", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 1, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 1, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 3, + }, + { + id: 5, + employeeId: 15, + name: "THE Boss", + firstName: "THE", + lastName: "Boss", + }, + { + id: 6, + employeeId: 16, + name: "Entry Level", + firstName: "Entry", + lastName: "Level", + supervisorid: 4, + }, + { + id: 7, + employeeId: 15, + name: "Other Boss", + firstName: "Other", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 8, + employeeId: 15, + name: "Other Person", + firstName: "Other", + lastName: "Person", + supervisorid: 7, + }, + ] + + const testState = { + userProfile: { + memberProfile: testMemberProfiles[0] + }, + memberProfiles: testMemberProfiles + }; + + expect(selectIsSubordinateOfCurrentUser(testState, testMemberProfiles[5].id)).toBe(true); + }); + +it("selectIsSubordinateOfCurrentUser should return false when user is not in the current users' heirarchy", () => { + const testMemberProfiles = [ + { + id: 1, + employeeId: 11, + name: "Big Boss", + firstName: "Big", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 2, + employeeId: 12, + name: "Huey Emmerich", + firstName: "Huey", + lastName: "Emmerich", + supervisorid: 1, + }, + { + id: 3, + employeeId: 13, + name: "Kazuhira Miller", + firstName: "Kazuhira", + lastName: "Miller", + supervisorid: 1, + }, + { + id: 4, + employeeId: 14, + name: "Revolver Ocelot", + firstName: "Revolver", + lastName: "Ocelot", + supervisorid: 3, + }, + { + id: 5, + employeeId: 15, + name: "THE Boss", + firstName: "THE", + lastName: "Boss", + }, + { + id: 6, + employeeId: 16, + name: "Entry Level", + firstName: "Entry", + lastName: "Level", + supervisorid: 4, + }, + { + id: 7, + employeeId: 15, + name: "Other Boss", + firstName: "Other", + lastName: "Boss", + supervisorid: 5, + }, + { + id: 8, + employeeId: 15, + name: "Other Person", + firstName: "Other", + lastName: "Person", + supervisorid: 7, + }, + ] + + const testState = { + userProfile: { + memberProfile: testMemberProfiles[0] + }, + memberProfiles: testMemberProfiles + }; + + expect(selectIsSubordinateOfCurrentUser(testState, testMemberProfiles[7].id)).toBe(false); + }); + }); From 5e99291aedf680a138c92ecf14aebd1f6f2cba37 Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Fri, 15 Dec 2023 15:28:56 -0600 Subject: [PATCH 31/37] Fix comparison error --- web-ui/src/context/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-ui/src/context/selectors.js b/web-ui/src/context/selectors.js index 803277ee91..4261c8fa57 100644 --- a/web-ui/src/context/selectors.js +++ b/web-ui/src/context/selectors.js @@ -314,7 +314,7 @@ export const selectCurrentUserSubordinates = createSelector( export const selectIsSubordinateOfCurrentUser = createSelector( selectCurrentUserSubordinates, (_, teamMemberId) => teamMemberId, - (subordinates, teamMemberId) => subordinates.some((teamMember) => teamMember.id == teamMemberId) + (subordinates, teamMemberId) => subordinates.some((teamMember) => teamMember.id === teamMemberId) ); export const selectTeamMembersWithCheckinPDL = createSelector( From 9a3a42d1bc15156c457f377313263463bdb53bae Mon Sep 17 00:00:00 2001 From: Sam Bley Date: Fri, 15 Dec 2023 16:55:34 -0600 Subject: [PATCH 32/37] fix bug to allow today to be the send date --- web-ui/src/pages/FeedbackRequestPage.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web-ui/src/pages/FeedbackRequestPage.jsx b/web-ui/src/pages/FeedbackRequestPage.jsx index e6dac8fc20..682902e2fc 100644 --- a/web-ui/src/pages/FeedbackRequestPage.jsx +++ b/web-ui/src/pages/FeedbackRequestPage.jsx @@ -149,7 +149,7 @@ const FeedbackRequestPage = () => { }, [memberIds, query, dispatch, handleQueryChange]); const isValidDate = useCallback((dateString) => { - const today = Date.now(); + const today = new Date().setHours(0, 0, 0, 0); const timeStamp = Date.parse(dateString); if (timeStamp < today) return false; @@ -173,6 +173,7 @@ const FeedbackRequestPage = () => { return hasFor() && templateIsValid && hasFrom(); } else if (activeStep === 3) { const dueQueryValid = query.due ? isValidDate(query.due) : true; + console.log({hasFor: hasFor(), templateIsValid, hasFrom: hasFrom(), hasSend: hasSend(), dueQueryValid}); return hasFor() && templateIsValid && hasFrom() && hasSend() && dueQueryValid; } else { return false; From 51beaa6214f5ebe61638c17626d6d1b4fd891a4a Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Sat, 16 Dec 2023 10:54:35 -0600 Subject: [PATCH 33/37] Fix loaded permissions --- .../resources/db/dev/R__Load_testing_data.sql | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 66a317d36d..c39882306b 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -703,7 +703,6 @@ insert into role_permissions values ('e8a4fff8-e984-4e59-be84-a713c9fa8d23', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS - -- PDL Permissions insert into role_permissions (roleid, permissionid) @@ -721,24 +720,14 @@ values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST insert into role_permissions -(roleid, permissionid) -values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e815de-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_SKILLS_REPORT - -insert into role_permissions -(roleid, permissionid) -values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f7e81958-8849-11ee-b9d1-0242ac120002'); -- CAN_VIEW_RETENTION_REPORT - -insert into role_permissions -(roleid, permissionid) + (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '056e32b2-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_ANNIVERSARY_REPORT + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '26a2f861-3f7d-4dc3-8762-716b184a3a47'); -- CAN_VIEW_FEEDBACK_ANSWER insert into role_permissions -(roleid, permissionid) + (roleid, permissionid) values - ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', '2d765f78-8d07-11ee-b9d1-0242ac120002'); -- CAN_VIEW_BIRTHDAY_REPORT + ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'f6961946-a792-4a16-b675-d8cf7980c17a'); -- CAN_VIEW_PERMISSIONS insert into role_permissions (roleid, permissionid) @@ -755,27 +744,31 @@ insert into role_permissions values ('d03f5f0b-e29c-4cf4-9ea4-6baa09405c56', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS +-- Member permissions +insert into role_permissions + (roleid, permissionid) +values + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST --- Member Permissions insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '439ad8a8-500f-4f3f-963b-a86437d5820a'); -- CAN_CREATE_ORGANIZATION_MEMBERS + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1bf32dfe-a204-4c80-889e-829ca66c999b'); -- CAN_CREATE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '008f6641-0b0a-4e89-84f0-c580f912b80d'); -- CAN_VIEW_FEEDBACK_REQUEST + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '1bf32dfe-a204-4c80-889e-829ca66c999b'); -- CAN_CREATE_FEEDBACK_REQUEST + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', '26a2f861-3f7d-4dc3-8762-716b184a3a47'); -- CAN_VIEW_FEEDBACK_ANSWER insert into role_permissions (roleid, permissionid) values - ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'a574feb9-f2d4-4cbf-9353-bfaccdffa74f'); -- CAN_DELETE_FEEDBACK_REQUEST + ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'f6961946-a792-4a16-b675-d8cf7980c17a'); -- CAN_VIEW_PERMISSIONS insert into role_permissions (roleid, permissionid) @@ -792,7 +785,6 @@ insert into role_permissions values ('8bda2ae9-58c1-4843-a0d5-d0952621f9df', 'ecd952a1-c7c8-47a9-b4ee-762b99276a6f'); -- CAN_UPDATE_CHECKINS - -- Feedback Templates ---- Quarter 1 Feedback Template INSERT INTO feedback_templates From e45c556724186a67436dbc92a3f053a12fb36afa Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Sat, 16 Dec 2023 11:00:07 -0600 Subject: [PATCH 34/37] Adjust fixture to allow for anyone to create a feedback request --- .../checkins/services/fixture/PermissionFixture.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java index a362e6b4e6..7a8bbcc738 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java @@ -12,6 +12,7 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt // Add MEMBER Permissions here List memberPermissions = List.of( Permissions.CAN_VIEW_FEEDBACK_REQUEST, + Permissions.CAN_CREATE_FEEDBACK_REQUEST, Permissions.CAN_DELETE_FEEDBACK_REQUEST, Permissions.CAN_VIEW_FEEDBACK_ANSWER, Permissions.CAN_VIEW_PERMISSIONS, From f87b1afacd969d59194ae10a932b3419d3f16298 Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Sun, 17 Dec 2023 10:28:09 -0600 Subject: [PATCH 35/37] clear our review periods when loading test data --- server/src/main/resources/db/dev/R__Load_testing_data.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index c39882306b..9af7dff33d 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -16,6 +16,7 @@ delete from permissions; delete from role; delete from team_member; delete from team; +delete from review_periods; delete from feedback_answers; delete from feedback_requests; delete from template_questions; From b065dbed311eadc34213d4adb1df5f4230af96cc Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Sun, 17 Dec 2023 10:51:00 -0600 Subject: [PATCH 36/37] Fix order of removal of test data --- server/src/main/resources/db/dev/R__Load_testing_data.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 9af7dff33d..1b0aaa47ad 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -16,11 +16,11 @@ delete from permissions; delete from role; delete from team_member; delete from team; -delete from review_periods; delete from feedback_answers; delete from feedback_requests; delete from template_questions; delete from feedback_templates; +delete from review_periods; delete from member_profile; delete from skills; From 46d2e86f399a350d2bc19437a4dbc4274fdcb2ac Mon Sep 17 00:00:00 2001 From: Michael Kimberlin Date: Sun, 17 Dec 2023 11:34:58 -0600 Subject: [PATCH 37/37] Fix order of removal of test data --- server/src/main/resources/db/dev/R__Load_testing_data.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/resources/db/dev/R__Load_testing_data.sql b/server/src/main/resources/db/dev/R__Load_testing_data.sql index 1b0aaa47ad..85bec60e01 100644 --- a/server/src/main/resources/db/dev/R__Load_testing_data.sql +++ b/server/src/main/resources/db/dev/R__Load_testing_data.sql @@ -19,8 +19,8 @@ delete from team; delete from feedback_answers; delete from feedback_requests; delete from template_questions; -delete from feedback_templates; delete from review_periods; +delete from feedback_templates; delete from member_profile; delete from skills;