Skip to content

Feature 2645/feedback request add ability to request feedback from external source #2856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 123 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
123 commits
Select commit Hold shift + click to select a range
2e716f8
2024-10-18 - feedback - external reviewer - serverl-side
Luch76 Oct 18, 2024
8f5fcbf
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 18, 2024
75895e8
2024-10-18 - feedback - external reviewer - serverl-side
Luch76 Oct 19, 2024
3fbe561
2024-10-21 - feedback - external reviewer - serverl-side
Luch76 Oct 21, 2024
ff2e29b
2024-10-21 - feedback - external reviewer - serverl-side
Luch76 Oct 21, 2024
a68340d
2024-10-21 - feedback - external reviewer - server-side
Luch76 Oct 21, 2024
1f5a7ed
2024-10-21 - feedback - external reviewer - server-side
Luch76 Oct 21, 2024
5c1c584
2024-10-21 - feedback - external reviewer - server-side
Luch76 Oct 21, 2024
20ee809
2024-10-21 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
d85c4df
2024-10-21 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
ed276b7
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
a13ed8c
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
41ac1aa
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 22, 2024
6723dc6
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
72f24b2
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
f8cee94
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
2eb6270
2024-10-22 - feedback - external reviewer - server-side
Luch76 Oct 22, 2024
f9cc72e
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
0038286
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
848555c
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
227899e
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
c811d62
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
af123be
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 23, 2024
2429ca3
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 24, 2024
b428976
2024-10-23 - feedback - external reviewer - server-side
Luch76 Oct 24, 2024
4931539
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 24, 2024
936b1bc
2024-10-24 - feedback - external reviewer - server-side
Luch76 Oct 24, 2024
71fb9e2
2024-10-24 - feedback - external reviewer - server-side
Luch76 Oct 24, 2024
8179528
2024-10-25 - feedback - external reviewer - server-side
Luch76 Oct 25, 2024
83c6394
2024-10-28 - feedback - external reviewer - server-side
Luch76 Oct 28, 2024
fd2ee9d
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 28, 2024
076f81a
2024-10-30 - feedback - external reviewer - server-side
Luch76 Oct 30, 2024
f4888f3
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 30, 2024
ad7b9e4
2024-10-30 - feedback - external reviewer - server-side
Luch76 Oct 30, 2024
9bb18c2
2024-10-30 - feedback - external reviewer - server-side
Luch76 Oct 30, 2024
8ef5420
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Oct 30, 2024
6ddafa2
2024-10-31 - external-recip get-all
Luch76 Oct 31, 2024
5f07db4
2024-10-31 - external-recip jsx
Luch76 Oct 31, 2024
096eab9
2024-11-01 - external-recip jsx
Luch76 Nov 1, 2024
1b43786
2024-11-04 - external-recips page
Luch76 Nov 4, 2024
e41590f
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 4, 2024
0439bb0
2024-11-04 - external-recips page
Luch76 Nov 4, 2024
e06459a
2024-11-04 - external-recips page
Luch76 Nov 4, 2024
819b9b4
2024-11-04 - external-recips page
Luch76 Nov 4, 2024
40610f0
2024-11-04 - external-recips page
Luch76 Nov 4, 2024
3b72766
2024-11-05 - external-recips page
Luch76 Nov 5, 2024
9b93580
2024-11-06 - add inactive flag to ext-recip
Luch76 Nov 6, 2024
3aae481
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 6, 2024
9525260
2024-11-07 - add inactive flag to ext-recip
Luch76 Nov 7, 2024
9aaf10b
2024-11-07 - add close-button to new-recip-modal screen
Luch76 Nov 7, 2024
0c7bc38
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 7, 2024
24f060f
2024-11-07 - add close-button to new-recip-modal screen
Luch76 Nov 7, 2024
bef7e3a
2024-11-08 - non-recipient search
Luch76 Nov 8, 2024
48a2f35
2024-11-08 - non-recipient search
Luch76 Nov 8, 2024
6aa1bda
2024-11-08 - non-recipient search
Luch76 Nov 8, 2024
9fd2a8a
2024-11-08 - non-recipient search
Luch76 Nov 8, 2024
1e4d0d5
2024-11-11 - search and add-new external-recip
Luch76 Nov 11, 2024
365dbc6
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 11, 2024
24629e1
2024-11-11 - search and add-new external-recip
Luch76 Nov 11, 2024
31037f1
2024-11-11 - search and add-new external-recip
Luch76 Nov 11, 2024
db27a4d
2024-11-11 - Email link correction
Luch76 Nov 11, 2024
ec026e6
2024-11-12 - routes
Luch76 Nov 12, 2024
a957972
2024-11-12 - remove ext recips from context
Luch76 Nov 12, 2024
2387c4d
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 12, 2024
b9767f8
2024-11-12 - routes
Luch76 Nov 12, 2024
8571eca
2024-11-12 - routes
Luch76 Nov 12, 2024
d57b5e5
2024-11-13 - routes
Luch76 Nov 13, 2024
b30e338
2024-11-13 - routes
Luch76 Nov 13, 2024
96e498c
2024-11-13 - removed new index & related pages
Luch76 Nov 13, 2024
38a9104
2024-11-13 - created web-ui-external-feedback
Luch76 Nov 13, 2024
165b301
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 13, 2024
05936f0
2024-11-14 - server-side merges
Luch76 Nov 14, 2024
0e7ba10
2024-11-14 - web-ui-external include with sonarqube
Luch76 Nov 14, 2024
6b22e80
2024-11-14 - web-ui - external feedback
Luch76 Nov 14, 2024
0459ae9
2024-11-14 - web-ui - external feedback
Luch76 Nov 14, 2024
0661d63
Split the configurations so we have one for the webUi and one for the…
timyates Nov 14, 2024
16830e9
2024-11-14 - web-ui - external feedback
Luch76 Nov 14, 2024
ad99e4c
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 14, 2024
e9e04c5
2024-11-14 - feedback ext recip
Luch76 Nov 14, 2024
af4f493
2024-11-15 - feedback ext recip
Luch76 Nov 15, 2024
cd41d4e
2024-11-18 - cleanup web-ui-external
Luch76 Nov 18, 2024
b477a7f
2024-11-18 - cleanup submit page for ext-recip
Luch76 Nov 18, 2024
b36e527
2024-11-18 - cleanup submit page for ext-recip
Luch76 Nov 18, 2024
96bbb05
2024-11-19 - cleanup submit page for ext-recip
Luch76 Nov 19, 2024
dfdbfcd
2024-11-19 - Merge changes regarding feedbackRequestServices.selfRevi…
Luch76 Nov 19, 2024
8560502
2024-11-19 - Correction to regex on homecontroller-external
Luch76 Nov 19, 2024
7e2785d
2024-11-19 - Correction to test-cases
Luch76 Nov 19, 2024
1ee2918
2024-11-20 - Feedback submission for ext-recip
Luch76 Nov 20, 2024
aa8c36a
2024-11-20 - Feedback confirmation page
Luch76 Nov 20, 2024
0ae06db
2024-11-20 - test-case fix
Luch76 Nov 21, 2024
ae424ae
2024-11-21 - updated snapshot
Luch76 Nov 21, 2024
2819eea
2024-11-21 - feedback confirmation page
Luch76 Nov 21, 2024
51cc1b2
2024-11-21 - feedback confirmation page alignment
Luch76 Nov 21, 2024
3d45329
2024-11-22 - feedback confirmation page alignment
Luch76 Nov 22, 2024
e97be27
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Nov 22, 2024
92fa2bf
2024-11-22 - snapshot fix
Luch76 Nov 22, 2024
1de3da9
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
7cfe3e9
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
3a00867
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
bedd3d7
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
5c5a076
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
2259dfc
2024-11-22 - allow edit of ext-recip
Luch76 Nov 22, 2024
b0547d5
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Nov 25, 2024
7e842ac
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Nov 26, 2024
dd6e579
2024-12-03 - check-ins
Luch76 Dec 3, 2024
fad9ced
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
Luch76 Dec 3, 2024
bba5302
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
ocielliottc Jan 14, 2025
f7d1195
Added a separate mjml template so that the email can be tailored towa…
ocielliottc Jan 16, 2025
12a32b6
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
ocielliottc Jan 27, 2025
44f279a
Corrected template type.
ocielliottc Jan 27, 2025
654ff60
Merged the non-external changes into this to remove warnings.
ocielliottc Jan 27, 2025
97652f7
Removed the self-review tab.
ocielliottc Jan 27, 2025
f0b6d7d
Removed console.log calls.
ocielliottc Jan 27, 2025
0d5bef3
Only add the company name if it is not empty.
ocielliottc Jan 27, 2025
da10911
Updated to match the external request template.
ocielliottc Jan 27, 2025
f870a59
Added a second email to be sent as a sort-of two step process.
ocielliottc Jan 28, 2025
5ae8181
Added a mechanism to ensure we do not send too many emails.
ocielliottc Jan 28, 2025
f2f7cef
Added a method to get the current user id that does not throw an exce…
ocielliottc Jan 30, 2025
4bbc2c7
Handle external recipients when viewing feedback.
ocielliottc Jan 31, 2025
2e9c7f1
Removed console.log() calls.
ocielliottc Jan 31, 2025
adde728
Fixed formatting and removed console.log() calls.
ocielliottc Jan 31, 2025
72ef550
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
ocielliottc Jan 31, 2025
4602de6
Merge branch 'develop' into feature-2645/feedback-request-add-ability…
ocielliottc Feb 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ plugins {

tasks.named("sonarqube") {
dependsOn ":web-ui:yarn_run_coverage", ":server:jacocoTestReport"
dependsOn ":web-ui-external-feedback:yarn_run_coverage", ":server:jacocoTestReport"
}

tasks.named("sonar") {
dependsOn ":web-ui:yarn_run_coverage", ":server:jacocoTestReport"
dependsOn ":web-ui-external-feedback:yarn_run_coverage", ":server:jacocoTestReport"
}
21 changes: 17 additions & 4 deletions server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,18 @@ graalvmNative {
}

configurations {
yarnBuildElements {
webUi {
canBeResolved = true
canBeConsumed = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage, "yarnBuild-elements"))
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage, "web-ui"))
}
}
webUiExternalFeedback {
canBeResolved = true
canBeConsumed = false
attributes {
attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage, "web-ui-external-feedback"))
}
}
}
Expand All @@ -77,7 +84,8 @@ dependencies {
annotationProcessor("io.micronaut.openapi:micronaut-openapi")
annotationProcessor("io.micronaut.security:micronaut-security-annotations")

yarnBuildElements(project(":web-ui"))
webUi(project(":web-ui"))
webUiExternalFeedback(project(":web-ui-external-feedback"))

implementation("net.steppschuh.markdowngenerator:markdowngenerator:1.3.1.1")
implementation("io.micronaut:micronaut-jackson-databind")
Expand Down Expand Up @@ -174,7 +182,12 @@ tasks.withType(JavaCompile).configureEach {
if(System.getenv("SKIP_WEB_UI") == null || System.getenv("SKIP_WEB_UI") == "false") {
processResources {
into('public') {
from configurations.named('yarnBuildElements')
from configurations.named('webUi')
}
}
processResources {
into('public-external-feedback') {
from configurations.named('webUiExternalFeedback')
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@ public int getOrder() {
void intercept(HttpRequest<?> request, @Body @Nullable String body) {
Optional<Authentication> auth = request.getAttribute(SecurityFilter.AUTHENTICATION, Authentication.class);
request.getAttribute(HttpAttributes.ROUTE_INFO, MethodBasedRouteInfo.class).ifPresent(routeBuilder -> {
String username = auth.map(Principal::getName).map(n -> n.isBlank() ? null : n).orElse("not authenticated");
String username = auth.map(Principal::getName).map(n -> n.isBlank() ? null : n).orElse("(Un-authenticated user)");
String requestVerb = request.getMethodName();
ExecutableMethod<?, ?> targetMethod = routeBuilder.getTargetMethod().getExecutableMethod();
String params = request.getParameters().asMap().entrySet().stream()
.map(e -> e.getKey() + ":" + e.getValue())
.collect(Collectors.joining(","));
String requestBody = body == null ? "empty" : body;
LOG.info(
"User {} {} request to {} with body {} and parameters {} being handled by {}.{}",
LOG.info("User: {} - {} request to {} with body {} and parameters {} being handled by {}.{}",
username,
requestVerb,
request.getUri().getPath(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.objectcomputing.checkins.security;

import io.micronaut.context.env.Environment;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.server.types.files.StreamedFile;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import io.micronaut.views.View;

import io.micronaut.core.annotation.Nullable;
import java.security.Principal;
import java.util.HashMap;
Expand All @@ -34,8 +36,10 @@ public Map<String, Object> forbidden(@Nullable Principal principal) {
* Forwards any unmapped paths (except those containing a period) to the client {@code index.html}.
* @return forward to client {@code index.html}.
*/
@Get("/{path:[^\\.]*}")
// 2024-10-29 - Note the path excludes "/externalFeedback", which is handled by HomeExternalRecipientController
@Get("/{path:^(?!externalFeedback)([^\\.]+)$}")
public Optional<StreamedFile> forward(String path) {
return environment.getResource("public/index.html").map(StreamedFile::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.objectcomputing.checkins.security;

import io.micronaut.context.env.Environment;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.server.types.files.StreamedFile;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import java.util.Optional;

@Controller
@Secured(SecurityRule.IS_ANONYMOUS)
public class HomeExternalRecipientController {

private final Environment environment;

public HomeExternalRecipientController(Environment environment) {
this.environment = environment;
}

@Get("/externalFeedback/{path:([^\\.]+)$}")
public Optional<StreamedFile> forward(String path) {
return environment.getResource("public-external-feedback/index.html").map(StreamedFile::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.objectcomputing.checkins.services.feedback_answer;

import com.objectcomputing.checkins.exceptions.BadArgException;
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequest;
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestServices;
import com.objectcomputing.checkins.services.permissions.Permission;
import com.objectcomputing.checkins.services.permissions.RequiredPermission;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.annotation.*;
import io.micronaut.scheduling.TaskExecutors;
import io.micronaut.scheduling.annotation.ExecuteOn;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;

import java.net.URI;
import java.util.List;
import java.util.UUID;

@Controller("/services/feedback/answers/external/recipients")
@ExecuteOn(TaskExecutors.BLOCKING)
@Secured(SecurityRule.IS_ANONYMOUS)
public class FeedbackAnswerExternalRecipientController {

private final FeedbackAnswerServices feedbackAnswerServices;
private final FeedbackRequestServices feedbackRequestServices;

public FeedbackAnswerExternalRecipientController(FeedbackAnswerServices feedbackAnswerServices, FeedbackRequestServices feedbackRequestServices) {
this.feedbackAnswerServices = feedbackAnswerServices;
this.feedbackRequestServices = feedbackRequestServices;
}

/**
* Create a feedback answer
*
* @param requestBody {@link FeedbackAnswerCreateDTO} New feedback answer to create
* @return {@link FeedbackAnswerResponseDTO}
*/
@Post
public HttpResponse<FeedbackAnswerResponseDTO> save(@Body @Valid @NotNull FeedbackAnswerCreateDTO requestBody) {
FeedbackRequest feedbackRequest = this.feedbackRequestServices.getById(requestBody.getRequestId());
if (feedbackRequest.getExternalRecipientId() == null) {
throw new BadArgException("This feedback request is not for an external recipient");
}
FeedbackAnswer savedAnswer = feedbackAnswerServices.save(fromDTO(requestBody));
return HttpResponse.created(fromEntity(savedAnswer))
.headers(headers -> headers.location(URI.create("/feedback_answer/" + savedAnswer.getId())));
}

/**
* Update a feedback answer
*
* @param requestBody {@link FeedbackAnswerUpdateDTO} The updated feedback answer
* @return {@link FeedbackAnswerResponseDTO}
*/
@Put
public HttpResponse<FeedbackAnswerResponseDTO> update(@Body @Valid @NotNull FeedbackAnswerUpdateDTO requestBody) {
FeedbackAnswer feedbackAnswerExistingRecord = this.feedbackAnswerServices.getById(requestBody.getId());
FeedbackRequest feedbackRequest = this.feedbackRequestServices.getById(feedbackAnswerExistingRecord.getRequestId());
if (feedbackRequest.getExternalRecipientId() == null) {
throw new BadArgException("This feedback request is not for an external recipient");
}
FeedbackAnswer savedAnswer = feedbackAnswerServices.update(fromDTO(requestBody));
return HttpResponse.ok(fromEntity(savedAnswer))
.headers(headers -> headers.location(URI.create("/feedback_answer/" + savedAnswer.getId())));
}

/**
* Get a feedback answer by ID
*
* @param id {@link UUID} ID of the feedback answer
* @return {@link FeedbackAnswerResponseDTO}
*/
@Get("/{id}")
public HttpResponse<FeedbackAnswerResponseDTO> getById(UUID id) {
FeedbackAnswer savedAnswer = feedbackAnswerServices.getById(id);
FeedbackRequest feedbackRequest = this.feedbackRequestServices.getById(savedAnswer.getRequestId());
if (feedbackRequest.getExternalRecipientId() == null) {
throw new BadArgException("This feedback request is not for an external recipient");
}
return HttpResponse.ok(fromEntity(savedAnswer))
.headers(headers -> headers.location(URI.create("/feedback_answer/" + savedAnswer.getId())));
}

/**
* Search for all feedback requests that match the intersection of the provided values
* Any values that are null are not applied to the intersection
*
* @param questionId The attached {@link UUID} of the related question
* @param requestId The attached {@link UUID} of the request that corresponds with the answer
* @return {@link FeedbackAnswerResponseDTO}
*/
@Get("/{?questionId,requestId}")
public List<FeedbackAnswerResponseDTO> findByValues(@Nullable UUID questionId, @Nullable UUID requestId) {
return feedbackAnswerServices.findByValues(questionId, requestId)
.stream()
.map(this::fromEntity)
.toList();
}

private FeedbackAnswer fromDTO(FeedbackAnswerCreateDTO dto) {
return new FeedbackAnswer(dto.getAnswer(), dto.getQuestionId(), dto.getRequestId(), dto.getSentiment());
}

private FeedbackAnswer fromDTO(FeedbackAnswerUpdateDTO dto) {
return new FeedbackAnswer(dto.getId(), dto.getAnswer(), dto.getSentiment());
}

private FeedbackAnswerResponseDTO fromEntity(FeedbackAnswer feedbackAnswer) {
FeedbackAnswerResponseDTO dto = new FeedbackAnswerResponseDTO();
dto.setId(feedbackAnswer.getId());
dto.setAnswer(feedbackAnswer.getAnswer());
dto.setQuestionId(feedbackAnswer.getQuestionId());
dto.setRequestId(feedbackAnswer.getRequestId());
dto.setSentiment(feedbackAnswer.getSentiment());
return dto;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public interface FeedbackAnswerRepository extends CrudRepository<FeedbackAnswer,
@Override
<S extends FeedbackAnswer> S update(@NotNull @Valid S entity);

@Query("SELECT id, PGP_SYM_DECRYPT(cast(answer as bytea), '${aes.key}') as answer, question_id, request_id, sentiment FROM feedback_answers WHERE (:questionId IS NULL OR question_id = :questionId) AND (request_id = :requestId)")
@Query("SELECT id, PGP_SYM_DECRYPT(cast(answer as bytea), '${aes.key}') as answer, question_id, request_id, sentiment " +
"FROM feedback_answers WHERE (:questionId IS NULL OR question_id = :questionId) AND (request_id = :requestId)")
List<FeedbackAnswer> getByQuestionIdAndRequestId(@Nullable String questionId, @Nullable String requestId);

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.objectcomputing.checkins.exceptions.PermissionException;
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequest;
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequestServices;
import com.objectcomputing.checkins.services.feedback_template.template_question.TemplateQuestion;
import com.objectcomputing.checkins.services.feedback_template.template_question.TemplateQuestionServices;
import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices;
Expand Down Expand Up @@ -43,9 +44,10 @@ public FeedbackAnswerServicesImpl(FeedbackAnswerRepository feedbackAnswerReposit

@Override
public FeedbackAnswer save(FeedbackAnswer feedbackAnswer) {
UUID questionId = feedbackAnswer.getQuestionId();

// Ensure that related question exists
templateQuestionServices.getById(feedbackAnswer.getQuestionId());
TemplateQuestion templateQuestion = templateQuestionServices.getById(questionId);

FeedbackRequest relatedFeedbackRequest = getRelatedFeedbackRequest(feedbackAnswer);
if (!createIsPermitted(relatedFeedbackRequest)) {
Expand Down Expand Up @@ -101,7 +103,8 @@ public FeedbackAnswer getById(UUID id) {
public List<FeedbackAnswer> findByValues(@Nullable UUID questionId, @Nullable UUID requestId) {
List<FeedbackAnswer> response = new ArrayList<>();
FeedbackRequest feedbackRequest;
UUID currentUserId = currentUserServices.getCurrentUser().getId();
final UUID currentUserId = currentUserServices.getCurrentUserId();

try {
feedbackRequest = feedbackRequestServices.getById(requestId);
} catch (NotFoundException e) {
Expand All @@ -110,16 +113,18 @@ public List<FeedbackAnswer> findByValues(@Nullable UUID questionId, @Nullable UU
final UUID requestCreatorId = feedbackRequest.getCreatorId();
final UUID requesteeId = feedbackRequest.getRequesteeId();
final UUID recipientId = feedbackRequest.getRecipientId();
boolean isRequesteesSupervisor = requesteeId != null ? memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId())) : false;
boolean isRequesteesSupervisor = requesteeId != null && currentUserId != null ? memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId())) : false;
MemberProfile requestee = memberProfileServices.getById(requesteeId);
final UUID requesteePDL = requestee.getPdlId();
if (currentUserServices.isAdmin() || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || recipientId.equals(currentUserId) || feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(feedbackRequest, currentUserId)) {
if (currentUserServices.isAdmin() || (currentUserId != null && currentUserId.equals(requesteePDL)) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || (recipientId != null && recipientId.equals(currentUserId)) || (currentUserId != null && feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(feedbackRequest, currentUserId))) {
response.addAll(feedbackAnswerRepository.getByQuestionIdAndRequestId(Util.nullSafeUUIDToString(questionId), Util.nullSafeUUIDToString(requestId)));
return response;
} else if (feedbackRequest.getExternalRecipientId() != null) {
response.addAll(feedbackAnswerRepository.getByQuestionIdAndRequestId(Util.nullSafeUUIDToString(questionId), Util.nullSafeUUIDToString(requestId)));
return response;
}

throw new PermissionException(NOT_AUTHORIZED_MSG);

}

public FeedbackRequest getRelatedFeedbackRequest(FeedbackAnswer feedbackAnswer) {
Expand All @@ -136,45 +141,43 @@ public FeedbackRequest getRelatedFeedbackRequest(FeedbackAnswer feedbackAnswer)

public boolean createIsPermitted(FeedbackRequest feedbackRequest) {
final UUID recipientId = feedbackRequest.getRecipientId();
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
return recipientId.equals(currentUserId);
return (recipientId != null && recipientId.equals(currentUserServices.getCurrentUserId())) || (feedbackRequest.getExternalRecipientId() != null);
}

public boolean updateIsPermitted(FeedbackRequest feedbackRequest) {
return createIsPermitted(feedbackRequest);
}

public boolean getIsPermitted(FeedbackRequest feedbackRequest) {
final UUID currentUserId = currentUserServices.getCurrentUserId();

// Admins can always get questions and answers.
if (currentUserServices.isAdmin()) {
if (currentUserId != null && currentUserServices.isAdmin()) {
return true;
}

final UUID requestCreatorId = feedbackRequest.getCreatorId();
if (requestCreatorId.equals(currentUserId)) return true;

UUID requesteeId = feedbackRequest.getRequesteeId();
MemberProfile requestee = memberProfileServices.getById(requesteeId);
final UUID recipientId = feedbackRequest.getRecipientId();
if ((recipientId != null && recipientId.equals(currentUserId))) return true;

// See if the current user is the requestee's supervisor.
final UUID requesteeId = feedbackRequest.getRequesteeId();
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
if (requesteeId != null &&
memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId()))) {
return true;
if (requesteeId != null && currentUserId != null) {
boolean isRequesteesSupervisor = memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId()));
if (isRequesteesSupervisor) return true;
}

// See if the current user is the requestee's PDL.
final MemberProfile requestee = memberProfileServices.getById(requesteeId);
if (currentUserId.equals(requestee.getPdlId())) {
return true;
}
final UUID requesteePDL = requestee.getPdlId();
if (currentUserId != null && currentUserId.equals(requesteePDL)) return true;

// See if the current user is the request creator or the recipient of
// the request.
final UUID requestCreatorId = feedbackRequest.getCreatorId();
final UUID recipientId = feedbackRequest.getRecipientId();
if (requestCreatorId.equals(currentUserId) ||
recipientId.equals(currentUserId)) {
return true;
}
if (feedbackRequest.getExternalRecipientId()!= null) return true;

if (feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(feedbackRequest, currentUserId)) return true;

return feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(
feedbackRequest, currentUserId);
return false;
}
}
Loading
Loading