Skip to content

Commit e920319

Browse files
authored
Merge pull request #2758 from objectcomputing/bugfix-2753/reviewers-must-see-reviewees-self-review
Allow reviewers to see the self-reviews of their reviewees for a review period.
2 parents 319e965 + 75f2a2a commit e920319

File tree

6 files changed

+75
-38
lines changed

6 files changed

+75
-38
lines changed

server/src/main/java/com/objectcomputing/checkins/services/feedback_answer/FeedbackAnswerServices.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.objectcomputing.checkins.services.feedback_answer;
22

3+
import com.objectcomputing.checkins.services.feedback_request.FeedbackRequest;
34
import io.micronaut.core.annotation.Nullable;
45

56
import java.util.List;
@@ -14,4 +15,6 @@ public interface FeedbackAnswerServices {
1415
FeedbackAnswer getById(UUID id);
1516

1617
List<FeedbackAnswer> findByValues(@Nullable UUID questionId, @Nullable UUID requestId);
18+
19+
boolean getIsPermitted(FeedbackRequest feedbackRequest);
1720
}

server/src/main/java/com/objectcomputing/checkins/services/feedback_answer/FeedbackAnswerServicesImpl.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public List<FeedbackAnswer> findByValues(@Nullable UUID questionId, @Nullable UU
113113
boolean isRequesteesSupervisor = requesteeId != null ? memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId())) : false;
114114
MemberProfile requestee = memberProfileServices.getById(requesteeId);
115115
final UUID requesteePDL = requestee.getPdlId();
116-
if (currentUserServices.isAdmin() || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || recipientId.equals(currentUserId)) {
116+
if (currentUserServices.isAdmin() || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || recipientId.equals(currentUserId) || feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(feedbackRequest, currentUserId)) {
117117
response.addAll(feedbackAnswerRepository.getByQuestionIdAndRequestId(Util.nullSafeUUIDToString(questionId), Util.nullSafeUUIDToString(requestId)));
118118
return response;
119119
}
@@ -145,15 +145,36 @@ public boolean updateIsPermitted(FeedbackRequest feedbackRequest) {
145145
}
146146

147147
public boolean getIsPermitted(FeedbackRequest feedbackRequest) {
148-
final boolean isAdmin = currentUserServices.isAdmin();
149-
final UUID requestCreatorId = feedbackRequest.getCreatorId();
150-
UUID requesteeId = feedbackRequest.getRequesteeId();
151-
MemberProfile requestee = memberProfileServices.getById(requesteeId);
148+
// Admins can always get questions and answers.
149+
if (currentUserServices.isAdmin()) {
150+
return true;
151+
}
152+
153+
// See if the current user is the requestee's supervisor.
154+
final UUID requesteeId = feedbackRequest.getRequesteeId();
152155
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
156+
if (requesteeId != null &&
157+
memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId()))) {
158+
return true;
159+
}
160+
161+
// See if the current user is the requestee's PDL.
162+
final MemberProfile requestee = memberProfileServices.getById(requesteeId);
163+
if (currentUserId.equals(requestee.getPdlId())) {
164+
return true;
165+
}
166+
167+
// See if the current user is the request creator or the recipient of
168+
// the request.
169+
final UUID requestCreatorId = feedbackRequest.getCreatorId();
153170
final UUID recipientId = feedbackRequest.getRecipientId();
154-
boolean isRequesteesSupervisor = requesteeId != null ? memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId())) : false;
155-
final UUID requesteePDL = requestee.getPdlId();
171+
if (requestCreatorId.equals(currentUserId) ||
172+
recipientId.equals(currentUserId)) {
173+
return true;
174+
}
175+
156176

157-
return isAdmin || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || recipientId.equals(currentUserId);
177+
return feedbackRequestServices.selfRevieweeIsCurrentUserReviewee(
178+
feedbackRequest, currentUserId);
158179
}
159180
}

server/src/main/java/com/objectcomputing/checkins/services/feedback_answer/question_and_answer/QuestionAndAnswerServicesImpl.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public QuestionAndAnswerServicesImpl(FeedbackAnswerServices feedbackAnswerServic
4242
@Override
4343
public List<Tuple> getAllQuestionsAndAnswers(UUID requestId) {
4444
FeedbackRequest feedbackRequest = feedbackRequestServices.getById(requestId);
45-
if (!getIsPermitted(feedbackRequest)) {
45+
if (!feedbackAnswerServices.getIsPermitted(feedbackRequest)) {
4646
throw new PermissionException(NOT_AUTHORIZED_MSG);
4747
}
4848
List<TemplateQuestion> templateQuestions = templateQuestionServices.findByFields(feedbackRequest.getTemplateId());
@@ -77,7 +77,7 @@ public Tuple getQuestionAndAnswer(@Nullable UUID requestId, @Nullable UUID quest
7777
TemplateQuestion question = new TemplateQuestion();
7878
FeedbackRequest feedbackRequest = feedbackRequestServices.getById(requestId);
7979

80-
if (!getIsPermitted(feedbackRequest)) {
80+
if (!feedbackAnswerServices.getIsPermitted(feedbackRequest)) {
8181
throw new PermissionException(NOT_AUTHORIZED_MSG);
8282
}
8383

@@ -101,18 +101,4 @@ public Tuple getQuestionAndAnswer(@Nullable UUID requestId, @Nullable UUID quest
101101
}
102102
return new Tuple(question, returnedAnswer);
103103
}
104-
105-
public boolean getIsPermitted(FeedbackRequest feedbackRequest) {
106-
final boolean isAdmin = currentUserServices.isAdmin();
107-
final UUID requestCreatorId = feedbackRequest.getCreatorId();
108-
UUID requesteeId = feedbackRequest.getRequesteeId();
109-
MemberProfile requestee = memberProfileServices.getById(requesteeId);
110-
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
111-
final UUID recipientId = feedbackRequest.getRecipientId();
112-
boolean isRequesteesSupervisor = requesteeId != null ? memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId())) : false;
113-
final UUID requesteePDL = requestee.getPdlId();
114-
115-
return isAdmin || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || requestCreatorId.equals(currentUserId) || recipientId.equals(currentUserId);
116-
}
117-
118104
}

server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServices.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ public interface FeedbackRequestServices {
1414
FeedbackRequest getById(UUID id);
1515

1616
List<FeedbackRequest> findByValues(UUID creatorId, UUID requesteeId, UUID recipientId, LocalDate oldestDate, UUID reviewPeriodId, UUID templateId, List<UUID> requesteeIds);
17-
}
17+
18+
boolean selfRevieweeIsCurrentUserReviewee(FeedbackRequest request,
19+
UUID currentUserId);
20+
}

server/src/main/java/com/objectcomputing/checkins/services/feedback_request/FeedbackRequestServicesImpl.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,8 @@ public FeedbackRequest getById(UUID id) {
272272
if (feedbackReq.isEmpty()) {
273273
throw new NotFoundException("No feedback req with id " + id);
274274
}
275-
final LocalDate sendDate = feedbackReq.get().getSendDate();
276-
final UUID requesteeId = feedbackReq.get().getRequesteeId();
277-
final UUID recipientId = feedbackReq.get().getRecipientId();
278-
if (!getIsPermitted(requesteeId, recipientId, sendDate)) {
275+
276+
if (!getIsPermitted(feedbackReq.get())) {
279277
throw new PermissionException(NOT_AUTHORIZED_MSG);
280278
}
281279

@@ -303,9 +301,12 @@ public List<FeedbackRequest> findByValues(UUID creatorId, UUID requesteeId, UUID
303301
if (currentUserServices.isAdmin()) {
304302
visible = true;
305303
} else if (request != null) {
306-
if (currentUserId.equals(request.getCreatorId())) visible = true;
307-
if (isSupervisor(request.getRequesteeId(), currentUserId)) visible = true;
308-
if (currentUserId.equals(request.getRecipientId())) visible = true;
304+
if (currentUserId.equals(request.getCreatorId()) ||
305+
isSupervisor(request.getRequesteeId(), currentUserId) ||
306+
currentUserId.equals(request.getRecipientId()) ||
307+
selfRevieweeIsCurrentUserReviewee(request, currentUserId)) {
308+
visible = true;
309+
}
309310
}
310311
return visible;
311312
}).toList();
@@ -318,6 +319,23 @@ private boolean isSupervisor(UUID requesteeId, UUID currentUserId) {
318319
&& memberProfileServices.getSupervisorsForId(requesteeId).stream().anyMatch(profile -> currentUserId.equals(profile.getId()));
319320
}
320321

322+
public boolean selfRevieweeIsCurrentUserReviewee(FeedbackRequest request,
323+
UUID currentUserId) {
324+
// If we are looking at a self-review request, see if there is a review
325+
// request in the same review period that is assigned to the current
326+
// user and the requestee is the same as the self-review request. If
327+
// so, this user is allowed to see the self-review request.
328+
if (request.getRecipientId().equals(request.getRequesteeId())) {
329+
List<FeedbackRequest> other = feedbackReqRepository.findByValues(
330+
null, request.getRecipientId().toString(),
331+
currentUserId.toString(), null,
332+
Util.nullSafeUUIDToString(request.getReviewPeriodId()),
333+
null);
334+
return (other.size() == 1);
335+
}
336+
return false;
337+
}
338+
321339
private boolean createIsPermitted(UUID requesteeId) {
322340
final boolean isAdmin = currentUserServices.isAdmin();
323341
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
@@ -329,16 +347,21 @@ private boolean createIsPermitted(UUID requesteeId) {
329347
return isAdmin || currentUserId.equals(requesteePDL) || isRequesteesSupervisor || currentUserId.equals(requesteeId);
330348
}
331349

332-
private boolean getIsPermitted(UUID requesteeId, UUID recipientId, LocalDate sendDate) {
333-
LocalDate today = LocalDate.now();
350+
private boolean getIsPermitted(FeedbackRequest feedbackReq) {
351+
final LocalDate sendDate = feedbackReq.getSendDate();
352+
final UUID requesteeId = feedbackReq.getRequesteeId();
353+
final UUID recipientId = feedbackReq.getRecipientId();
354+
final LocalDate today = LocalDate.now();
334355
final UUID currentUserId = currentUserServices.getCurrentUser().getId();
335356

336357
// The recipient can only access the feedback request after it has been sent
337358
if (sendDate.isAfter(today) && currentUserId.equals(recipientId)) {
338359
throw new PermissionException("You are not permitted to access this request before the send date.");
339360
}
340361

341-
return createIsPermitted(requesteeId) || currentUserId.equals(recipientId);
362+
return createIsPermitted(requesteeId) ||
363+
currentUserId.equals(recipientId) ||
364+
selfRevieweeIsCurrentUserReviewee(feedbackReq, currentUserId);
342365
}
343366

344367
private boolean updateDueDateIsPermitted(FeedbackRequest feedbackRequest) {

web-ui/src/components/reviews/TeamReviews.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import {
5555
} from '../../context/actions';
5656
import { AppContext } from '../../context/AppContext';
5757
import {
58+
selectIsAdmin,
5859
selectCsrfToken,
5960
selectCurrentMembers,
6061
selectCurrentUser,
@@ -125,7 +126,7 @@ const ReviewStatus = {
125126
const TeamReviews = ({ onBack, periodId }) => {
126127
const { state, dispatch } = useContext(AppContext);
127128
const location = useLocation();
128-
129+
const isAdmin = selectIsAdmin(state);
129130
const [openMode, setOpenMode] = useState(false);
130131
const [approvalState, setApprovalState] = useState(false);
131132
const [assignments, setAssignments] = useState([]);
@@ -796,7 +797,7 @@ const TeamReviews = ({ onBack, periodId }) => {
796797
const url = getReviewerURL(request, selfReviewRequest);
797798

798799
return (url ?
799-
<Link to={url}>
800+
<Link key={member?.id} to={url}>
800801
<Chip
801802
key={reviewer.id}
802803
label={statusLabel}
@@ -840,7 +841,7 @@ const TeamReviews = ({ onBack, periodId }) => {
840841
const manages = recipientProfile.supervisorid == currentUser?.id;
841842
const request = getReviewRequest(member, currentUser);
842843
const isReviewer = request?.recipientId == currentUser?.id;
843-
if (manages || isReviewer) {
844+
if (isAdmin || manages || isReviewer) {
844845
const selfReviewRequest = getSelfReviewRequest(member);
845846
return (
846847
<Chip

0 commit comments

Comments
 (0)