Skip to content

Commit 747b6b1

Browse files
committed
Merge branch 'develop' of https://github.com/objectcomputing/check-ins into feature-2106/add-category-to-skills
# Conflicts: # server/src/main/java/com/objectcomputing/checkins/security/permissions/Permissions.java # web-ui/src/components/routes/Routes.jsx
2 parents 46f3beb + f24d263 commit 747b6b1

File tree

22 files changed

+2291
-31
lines changed

22 files changed

+2291
-31
lines changed
Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,39 @@
11
package com.objectcomputing.checkins.security.permissions;
22

33
public enum Permissions {
4-
CAN_VIEW_FEEDBACK_REQUEST,
5-
CAN_CREATE_FEEDBACK_REQUEST,
6-
CAN_DELETE_FEEDBACK_REQUEST,
7-
CAN_VIEW_FEEDBACK_ANSWER,
8-
CAN_DELETE_ORGANIZATION_MEMBERS,
9-
CAN_CREATE_ORGANIZATION_MEMBERS,
10-
CAN_VIEW_ROLE_PERMISSIONS,
11-
CAN_ASSIGN_ROLE_PERMISSIONS,
12-
CAN_VIEW_PERMISSIONS,
13-
CAN_VIEW_SKILLS_REPORT,
14-
CAN_VIEW_RETENTION_REPORT,
15-
CAN_VIEW_ANNIVERSARY_REPORT,
16-
CAN_VIEW_BIRTHDAY_REPORT,
17-
CAN_VIEW_PROFILE_REPORT,
18-
CAN_CREATE_CHECKINS,
19-
CAN_VIEW_CHECKINS,
20-
CAN_UPDATE_CHECKINS,
21-
CAN_EDIT_SKILL_CATEGORIES,
22-
CAN_VIEW_SKILL_CATEGORIES,
23-
}
4+
CAN_VIEW_FEEDBACK_REQUEST("View feedback requests", "Feedback"),
5+
CAN_CREATE_FEEDBACK_REQUEST("Create feedback requests", "Feedback"),
6+
CAN_DELETE_FEEDBACK_REQUEST("Delete feedback requests", "Feedback"),
7+
CAN_VIEW_FEEDBACK_ANSWER("View feedback answers", "Feedback"),
8+
CAN_DELETE_ORGANIZATION_MEMBERS("Delete organization members", "User Management"),
9+
CAN_CREATE_ORGANIZATION_MEMBERS("Create organization members", "User Management"),
10+
CAN_VIEW_ROLE_PERMISSIONS("View role permissions", "Security"),
11+
CAN_ASSIGN_ROLE_PERMISSIONS("Assign role permissions", "Security"),
12+
CAN_VIEW_PERMISSIONS("View all permissions", "Security"),
13+
CAN_VIEW_SKILLS_REPORT("View skills report", "Reporting"),
14+
CAN_VIEW_RETENTION_REPORT("View retention report", "Reporting"),
15+
CAN_VIEW_ANNIVERSARY_REPORT("View anniversary report", "Reporting"),
16+
CAN_VIEW_BIRTHDAY_REPORT("View birthday report", "Reporting"),
17+
CAN_VIEW_PROFILE_REPORT("View profile report", "Reporting"),
18+
CAN_CREATE_CHECKINS("Create check-ins", "Check-ins"),
19+
CAN_VIEW_CHECKINS("View check-ins", "Check-ins"),
20+
CAN_UPDATE_CHECKINS("Update check-ins", "Check-ins"),
21+
CAN_EDIT_SKILL_CATEGORIES("Edit skill categories", "Skills"),
22+
CAN_VIEW_SKILL_CATEGORIES("View skill categories", "Skills");
23+
24+
private final String description;
25+
private final String category;
26+
27+
Permissions(String description, String category) {
28+
this.description = description;
29+
this.category = category;
30+
}
31+
32+
public String getDescription() {
33+
return description;
34+
}
35+
36+
public String getCategory() {
37+
return category;
38+
}
39+
}

server/src/main/java/com/objectcomputing/checkins/services/feedback/suggestions/FeedbackSuggestionServiceImpl.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import io.micronaut.context.annotation.Property;
1010
import com.objectcomputing.checkins.exceptions.PermissionException;
1111
import jakarta.inject.Singleton;
12+
13+
import java.time.LocalDate;
1214
import java.util.LinkedList;
1315
import java.util.List;
1416
import java.util.Set;
@@ -47,11 +49,11 @@ public List<FeedbackSuggestionDTO> getSuggestionsByProfileId(UUID id) {
4749
}
4850

4951
List<FeedbackSuggestionDTO> suggestions = new LinkedList<>();
50-
if(suggestFor.getSupervisorid() != null && !suggestFor.getSupervisorid().equals(currentUser.getId())) {
52+
if(suggestFor.getSupervisorid() != null && !suggestFor.getSupervisorid().equals(currentUser.getId()) && isMemberActive(suggestFor.getSupervisorid())) {
5153
suggestions.add(new FeedbackSuggestionDTO("Supervisor of requestee", suggestFor.getSupervisorid()));
5254
}
5355

54-
if(suggestFor.getPdlId() != null && !suggestFor.getPdlId().equals(currentUser.getId())) {
56+
if(suggestFor.getPdlId() != null && !suggestFor.getPdlId().equals(currentUser.getId()) && isMemberActive(suggestFor.getPdlId())) {
5557
suggestions.add(new FeedbackSuggestionDTO("PDL of requestee", suggestFor.getPdlId()));
5658
}
5759

@@ -60,6 +62,7 @@ public List<FeedbackSuggestionDTO> getSuggestionsByProfileId(UUID id) {
6062
for(TeamMember currentMembership: teamMemberships){
6163
Set<TeamMember> teamMembers = teamMemberServices.findByFields(currentMembership.getTeamId(), null, null);
6264
Set<TeamMember> leads = teamMembers.stream().filter((member)-> member.isLead()).collect(Collectors.toSet());
65+
leads = filterTerminated(leads);
6366
for(TeamMember lead: leads) {
6467
if(suggestions.size() < maxSuggestions && !lead.getMemberId().equals(id) && !lead.getMemberId().equals(currentUserId)) {
6568
suggestions.add(new FeedbackSuggestionDTO("Team lead for requestee", lead.getMemberId()));
@@ -72,6 +75,7 @@ public List<FeedbackSuggestionDTO> getSuggestionsByProfileId(UUID id) {
7275
for(TeamMember currentMembership: teamMemberships){
7376
Set<TeamMember> teamMembers = teamMemberServices.findByFields(currentMembership.getTeamId(), null, null);
7477
teamMembers = teamMembers.stream().filter((member)-> !member.isLead()).collect(Collectors.toSet());
78+
teamMembers = filterTerminated(teamMembers);
7579
for(TeamMember teamMember: teamMembers) {
7680
if(suggestions.size() < maxSuggestions && !teamMember.getMemberId().equals(id) && !teamMember.getMemberId().equals(currentUserId)) {
7781
suggestions.add(new FeedbackSuggestionDTO("Team member for requestee", teamMember.getMemberId()));
@@ -80,6 +84,20 @@ public List<FeedbackSuggestionDTO> getSuggestionsByProfileId(UUID id) {
8084

8185
if(suggestions.size() >= maxSuggestions) break;
8286
}
87+
88+
return suggestions;
89+
}
90+
91+
private Set<TeamMember> filterTerminated(Set<TeamMember> suggestions) {
92+
suggestions = suggestions.stream().filter((TeamMember suggestion) -> {
93+
return isMemberActive(suggestion.getMemberId());
94+
}).collect(Collectors.toSet());
8395
return suggestions;
8496
}
97+
98+
private boolean isMemberActive(UUID memberId) {
99+
MemberProfile suggested = memberProfileServices.getById(memberId);
100+
LocalDate terminationDate = suggested.getTerminationDate();
101+
return !(terminationDate != null && terminationDate.isBefore(LocalDate.now().atStartOfDay().toLocalDate()));
102+
}
85103
}

server/src/main/java/com/objectcomputing/checkins/services/permissions/Permission.java

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

3+
import com.objectcomputing.checkins.security.permissions.Permissions;
34
import io.micronaut.core.annotation.Introspected;
45
import io.micronaut.core.annotation.Nullable;
56
import io.micronaut.data.annotation.AutoPopulated;
@@ -11,6 +12,7 @@
1112
import javax.persistence.Entity;
1213
import javax.persistence.Id;
1314
import javax.persistence.Table;
15+
import javax.persistence.Transient;
1416
import javax.validation.constraints.NotBlank;
1517
import java.util.Objects;
1618
import java.util.UUID;
@@ -36,6 +38,8 @@ public class Permission {
3638
@Schema(description = "A more verbose description of the permission to be displayed on UI")
3739
private String description;
3840

41+
public Permission() {}
42+
3943
public Permission(UUID id, String permission, @Nullable String description) {
4044
this.id = id;
4145
this.permission = permission;
@@ -59,13 +63,18 @@ public void setPermission(String permission) {
5963
}
6064

6165
public String getDescription() {
62-
return description;
66+
return Permissions.valueOf(permission).getDescription(); //ignoring the database for now...
6367
}
6468

65-
public void setDescription(String description) {
69+
public void setDescription(@Nullable String description) {
6670
this.description = description;
6771
}
6872

73+
@Transient
74+
public String getCategory() {
75+
return Permissions.valueOf(permission).getCategory();
76+
}
77+
6978
@Override
7079
public boolean equals(Object o) {
7180
if (this == o) return true;

server/src/test/java/com/objectcomputing/checkins/services/feedback/suggestions/FeedbackSuggestionsControllerTest.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,44 @@ void testGetRecsIfTeamMember() {
151151

152152
assertNotNull(JSON.toString(response.getBody().get()));
153153
assertEquals(HttpStatus.OK, response.getStatus());
154-
assertEquals(response.getBody().get().size(), 3 );
154+
assertEquals( 3, response.getBody().get().size() );
155155
assertContentEqualsEntity(idealOne, response.getBody().get().get(0));
156156
assertContentEqualsEntity(idealTwo, response.getBody().get().get(1));
157157
assertContentEqualsEntity(idealThree, response.getBody().get().get(2));
158158

159159
}
160160

161+
@Test
162+
void testDoesNotIncludeTerminatedTeamMembers() {
163+
Team team = createDefaultTeam();
164+
MemberProfile pdlProfile = createADefaultMemberProfile();
165+
createAndAssignRole(RoleType.PDL, pdlProfile);
166+
MemberProfile supervisor = createADefaultSupervisor();
167+
createAndAssignRole(RoleType.ADMIN, supervisor);
168+
MemberProfile requestee = createAProfileWithSupervisorAndPDL(supervisor, pdlProfile);
169+
MemberProfile requesteeTeamLead = createAnUnrelatedUser();
170+
MemberProfile teamMemberofRequestee = createASecondDefaultMemberProfile();
171+
MemberProfile termedTeamMemberofRequestee = createAPastTerminatedMemberProfile();
172+
createLeadTeamMember(team, requesteeTeamLead);
173+
createDefaultTeamMember(team, requestee);
174+
createDefaultTeamMember(team, teamMemberofRequestee);
175+
createDefaultTeamMember(team, termedTeamMemberofRequestee);
161176

177+
final HttpRequest<?> request = HttpRequest.GET(String.format("/%s", requestee.getId()))
178+
.basicAuth(teamMemberofRequestee.getWorkEmail(), RoleType.Constants.MEMBER_ROLE);
179+
final HttpResponse<List<FeedbackSuggestionDTO>> response = client.toBlocking()
180+
.exchange(request, Argument.listOf(FeedbackSuggestionDTO.class));
181+
182+
183+
FeedbackSuggestionDTO idealOne = createFeedbackSuggestion(supervisorReason, supervisor.getId());
184+
FeedbackSuggestionDTO idealTwo = createFeedbackSuggestion(pdlReason, pdlProfile.getId());
185+
FeedbackSuggestionDTO idealThree = createFeedbackSuggestion(teamLeadReason, requesteeTeamLead.getId());
162186

187+
assertNotNull(JSON.toString(response.getBody().get()));
188+
assertEquals(HttpStatus.OK, response.getStatus());
189+
assertEquals( 3, response.getBody().get().size() );
190+
assertContentEqualsEntity(idealOne, response.getBody().get().get(0));
191+
assertContentEqualsEntity(idealTwo, response.getBody().get().get(1));
192+
assertContentEqualsEntity(idealThree, response.getBody().get().get(2));
193+
}
163194
}

server/src/test/java/com/objectcomputing/checkins/services/fixture/PermissionFixture.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ public interface PermissionFixture extends RepositoryFixture, RolePermissionFixt
5757
);
5858

5959
default Permission createACustomPermission(Permissions perm) {
60-
return getPermissionRepository().save(new Permission(null, perm.name(), null));
60+
return getPermissionRepository().save(new Permission(null, perm.name(), perm.getDescription()));
6161
}
6262

6363
default void saveAllPermissions() {
6464
for(Permissions permissions : Permissions.values()) {
65-
getPermissionRepository().save(new Permission(null, permissions.name(), null));
65+
getPermissionRepository().save(new Permission(null, permissions.name(), permissions.getDescription()));
6666
}
6767
}
6868

web-ui/src/api/memberroles.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { resolve } from "./api.js";
2+
3+
const memberRolesUrl = "/services/roles/members"
4+
5+
export const getMemberRolesList = async (cookie) => {
6+
return resolve({
7+
url: memberRolesUrl,
8+
responseType: "json",
9+
headers: { "X-CSRF-Header": cookie },
10+
});
11+
};

web-ui/src/api/permissions.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { resolve } from "./api.js";
2+
3+
const permissionsListUrl = "/services/permissions"
4+
5+
export const getPermissionsList = async (cookie) => {
6+
return resolve({
7+
url: permissionsListUrl,
8+
responseType: "json",
9+
headers: { "X-CSRF-Header": cookie },
10+
});
11+
};

web-ui/src/api/rolepermissions.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { resolve } from "./api.js";
2+
3+
const rolePermissionsListUrl = "/services/roles/role-permissions";
4+
5+
export const getRolePermissionsList = async (cookie) => {
6+
return resolve({
7+
url: rolePermissionsListUrl,
8+
responseType: "json",
9+
headers: { "X-CSRF-Header": cookie },
10+
});
11+
};
12+
13+
export const postRolePermission = async (roleData, cookie) => {
14+
return resolve({
15+
method: "post",
16+
url: rolePermissionsListUrl,
17+
responseType: "json",
18+
data: roleData,
19+
headers: { "X-CSRF-Header": cookie },
20+
});
21+
};
22+
23+
export const deleteRolePermission = async (roleData, cookie) => {
24+
return resolve({
25+
method: "delete",
26+
url: rolePermissionsListUrl,
27+
responseType: "json",
28+
data: roleData,
29+
headers: { "X-CSRF-Header": cookie },
30+
});
31+
};

web-ui/src/components/menu/Menu.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const Root = styled('div')(({theme}) => ({
9595
}));
9696

9797
const adminLinks = [
98-
// ["/admin/permissions", "Permissions"],
98+
["/admin/permissions", "Permissions"],
9999
["/admin/roles", "Roles"],
100100
["/admin/users", "Users"],
101101
["/admin/email", "Send Email"],

web-ui/src/components/routes/Routes.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import BirthdayAnniversaryReportPage from "../../pages/BirthdayAnniversaryReport
77
import CheckinsPage from "../../pages/CheckinsPage";
88
import CheckinsReportPage from "../../pages/CheckinsReportPage";
99
import EditSkillsPage from "../../pages/EditSkillsPage";
10+
import EditPermissionsPage from "../../pages/PermissionsPage";
1011
import GroupIcon from "@mui/icons-material/Group";
1112
import GuildsPage from "../../pages/GuildsPage";
1213
import Header from "../header/Header";
@@ -103,6 +104,10 @@ export default function Routes() {
103104
<Header title="Skills" />
104105
<EditSkillsPage />
105106
</Route>
107+
<Route path="/admin/permissions">
108+
<Header title="Permissions" />
109+
<EditPermissionsPage />
110+
</Route>
106111
<Route path="/admin/skill-categories/:categoryId">
107112
<SkillCategoryEditPage />
108113
</Route>

0 commit comments

Comments
 (0)