Skip to content

Commit 4d8d305

Browse files
authored
Merge pull request #2842 from objectcomputing/release/0.8
Release v0.8.13 to production
2 parents a25face + 682d22b commit 4d8d305

File tree

67 files changed

+868
-1126
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+868
-1126
lines changed

server/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
id "jacoco"
88
}
99

10-
version "0.8.12"
10+
version "0.8.13"
1111
group "com.objectcomputing.checkins"
1212

1313
repositories {

server/src/main/java/com/objectcomputing/checkins/services/employee_hours/EmployeeHoursController.java

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.objectcomputing.checkins.services.employee_hours;
22

3+
import com.objectcomputing.checkins.services.permissions.Permission;
4+
import com.objectcomputing.checkins.services.permissions.RequiredPermission;
35
import com.objectcomputing.checkins.exceptions.NotFoundException;
46
import io.micronaut.core.annotation.Nullable;
57
import io.micronaut.http.MediaType;
@@ -39,25 +41,13 @@ public Set<EmployeeHours> findEmployeeHours(@Nullable String employeeId) {
3941
}
4042

4143

42-
/**
43-
* @param id
44-
* @return
45-
*/
46-
@Get("/{id}")
47-
public EmployeeHours readEmployeeHours(@NotNull UUID id) {
48-
EmployeeHours result = employeeHoursServices.read(id);
49-
if (result == null) {
50-
throw new NotFoundException("No employee hours for employee id");
51-
}
52-
return result;
53-
}
54-
5544
/**
5645
* Parse the CSV file and store it to employee hours table
5746
* @param file
5847
* @{@link HttpResponse<EmployeeHoursResponseDTO>}
5948
*/
6049
@Post(uri="/upload" , consumes = MediaType.MULTIPART_FORM_DATA)
50+
@RequiredPermission(Permission.CAN_UPLOAD_HOURS)
6151
public EmployeeHoursResponseDTO upload(CompletedFileUpload file){
6252
return employeeHoursServices.save(file);
6353
}

server/src/main/java/com/objectcomputing/checkins/services/employee_hours/EmployeeHoursServices.java

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ public interface EmployeeHoursServices {
99

1010
EmployeeHoursResponseDTO save(CompletedFileUpload file);
1111

12-
EmployeeHours read(UUID id);
13-
1412
Set<EmployeeHours> findByFields(String employeeId);
1513

1614
}

server/src/main/java/com/objectcomputing/checkins/services/employee_hours/EmployeeHoursServicesImpl.java

-6
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ public EmployeeHoursResponseDTO save(CompletedFileUpload file) {
4040
List<EmployeeHours> employeeHoursList = new ArrayList<>();
4141
Set<EmployeeHours> employeeHours = new HashSet<>();
4242
EmployeeHoursResponseDTO responseDTO = new EmployeeHoursResponseDTO();
43-
validate(!isAdmin, NOT_AUTHORIZED_MSG);
4443
responseDTO.setRecordCountDeleted(employeehourRepo.count());
4544
employeehourRepo.deleteAll();
4645
try {
@@ -58,11 +57,6 @@ public EmployeeHoursResponseDTO save(CompletedFileUpload file) {
5857
}
5958

6059

61-
@Override
62-
public EmployeeHours read(UUID id) {
63-
return employeehourRepo.findById(id).orElse(null);
64-
}
65-
6660
@Override
6761
public Set<EmployeeHours> findByFields(String employeeId) {
6862
MemberProfile currentUser = currentUserServices.getCurrentUser();

server/src/main/java/com/objectcomputing/checkins/services/kudos/KudosConverter.java

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ public String toSlackBlock(Kudos kudos) {
5353
content.add(
5454
RichTextSectionElement.Text.builder()
5555
.text("\n" + kudos.getMessage() + "\n")
56-
.style(boldItalic())
5756
.build()
5857
);
5958

server/src/main/java/com/objectcomputing/checkins/services/kudos/KudosServicesImpl.java

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.objectcomputing.checkins.services.kudos;
22

3+
import com.objectcomputing.checkins.services.permissions.Permission;
34
import com.objectcomputing.checkins.configuration.CheckInsConfiguration;
45
import com.objectcomputing.checkins.notifications.email.EmailSender;
56
import com.objectcomputing.checkins.notifications.email.MailJetFactory;
@@ -121,10 +122,6 @@ public Kudos save(KudosCreateDTO kudosDTO) {
121122

122123
@Override
123124
public Kudos approve(Kudos kudos) {
124-
if (!currentUserServices.isAdmin()) {
125-
throw new PermissionException(NOT_AUTHORIZED_MSG);
126-
}
127-
128125
UUID kudosId = kudos.getId();
129126
Kudos existingKudos = kudosRepository.findById(kudosId).orElseThrow(() ->
130127
new BadArgException(KUDOS_DOES_NOT_EXIST_MSG.formatted(kudosId)));
@@ -151,7 +148,7 @@ public KudosResponseDTO getById(UUID id) {
151148

152149
if (kudos.getDateApproved() == null) {
153150
// If not yet approved, only admins and the sender can access the kudos
154-
if (!currentUserServices.isAdmin() && !isSender) {
151+
if (!hasAdministerKudosPermission() && !isSender) {
155152
throw new PermissionException(NOT_AUTHORIZED_MSG);
156153
}
157154
} else {
@@ -162,7 +159,7 @@ public KudosResponseDTO getById(UUID id) {
162159
.stream()
163160
.anyMatch(recipient -> recipient.getMemberId().equals(currentUserId));
164161

165-
if (!currentUserServices.isAdmin() && !isSender && !isRecipient) {
162+
if (!hasAdministerKudosPermission() && !isSender && !isRecipient) {
166163
throw new PermissionException(NOT_AUTHORIZED_MSG);
167164
}
168165
}
@@ -173,10 +170,6 @@ public KudosResponseDTO getById(UUID id) {
173170

174171
@Override
175172
public void delete(UUID id) {
176-
if (!currentUserServices.isAdmin()) {
177-
throw new PermissionException(NOT_AUTHORIZED_MSG);
178-
}
179-
180173
Kudos kudos = kudosRepository.findById(id).orElseThrow(() ->
181174
new NotFoundException(KUDOS_DOES_NOT_EXIST_MSG.formatted(id)));
182175

@@ -196,7 +189,7 @@ public List<KudosResponseDTO> findByValues(@Nullable UUID recipientId, @Nullable
196189
} else if (senderId != null) {
197190
return findAllFromMember(senderId);
198191
} else {
199-
if (!currentUserServices.isAdmin()) {
192+
if (!hasAdministerKudosPermission()) {
200193
throw new PermissionException(NOT_AUTHORIZED_MSG);
201194
}
202195

@@ -215,7 +208,7 @@ public List<KudosResponseDTO> getRecent() {
215208
}
216209

217210
private List<KudosResponseDTO> findByPending(boolean isPending) {
218-
if (!currentUserServices.isAdmin()) {
211+
if (!hasAdministerKudosPermission()) {
219212
throw new PermissionException(NOT_AUTHORIZED_MSG);
220213
}
221214

@@ -235,10 +228,10 @@ private List<KudosResponseDTO> findByPending(boolean isPending) {
235228

236229

237230
private List<KudosResponseDTO> findAllToMember(UUID memberId) {
238-
boolean isAdmin = currentUserServices.isAdmin();
239231
UUID currentUserId = currentUserServices.getCurrentUser().getId();
240232

241-
if (!currentUserId.equals(memberId) && !isAdmin) {
233+
if (!currentUserId.equals(memberId) &&
234+
!hasAdministerKudosPermission()) {
242235
throw new PermissionException("You are not authorized to retrieve the kudos another user has received");
243236
}
244237

@@ -261,10 +254,10 @@ private List<KudosResponseDTO> findAllToMember(UUID memberId) {
261254

262255
private List<KudosResponseDTO> findAllFromMember(UUID senderId) {
263256

264-
boolean isAdmin = currentUserServices.isAdmin();
265257
UUID currentUserId = currentUserServices.getCurrentUser().getId();
266258

267-
if (!currentUserId.equals(senderId) && !isAdmin) {
259+
if (!currentUserId.equals(senderId) &&
260+
!hasAdministerKudosPermission()) {
268261
throw new PermissionException("You are not authorized to retrieve the kudos another user has sent");
269262
}
270263

@@ -386,4 +379,8 @@ private void slackApprovedKudos(Kudos kudos) {
386379
LOG.error("Unable to POST to Slack: " + httpResponse.reason());
387380
}
388381
}
382+
383+
private boolean hasAdministerKudosPermission() {
384+
return currentUserServices.hasPermission(Permission.CAN_ADMINISTER_KUDOS);
385+
}
389386
}

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public HttpResponse<MemberProfileResponseDTO> save(@Body @Valid MemberProfileCre
111111
*/
112112
@Put
113113
public HttpResponse<MemberProfileResponseDTO> update(@Body @Valid MemberProfileUpdateDTO memberProfile) {
114-
MemberProfile savedProfile = memberProfileServices.saveProfile(fromDTO(memberProfile));
114+
MemberProfile savedProfile = memberProfileServices.updateProfile(fromDTO(memberProfile));
115115
return HttpResponse.ok(fromEntity(savedProfile))
116116
.headers(headers -> headers.location(location(savedProfile.getId())));
117117
}

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileServices.java

+2
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ Set<MemberProfile> findByValues(String firstName, String lastName, String title,
2727
List<MemberProfile> getSubordinatesForId(UUID id);
2828

2929
MemberProfile updateProfile(MemberProfile memberProfile);
30+
31+
void updateLastSeen(UUID id);
3032
}

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/MemberProfileServicesImpl.java

+52-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.objectcomputing.checkins.services.memberprofile;
22

3+
import com.objectcomputing.checkins.services.permissions.Permission;
34
import com.objectcomputing.checkins.exceptions.AlreadyExistsException;
45
import com.objectcomputing.checkins.exceptions.BadArgException;
56
import com.objectcomputing.checkins.exceptions.NotFoundException;
@@ -23,8 +24,10 @@
2324
import org.slf4j.LoggerFactory;
2425

2526
import java.util.*;
27+
import java.time.LocalDate;
2628

2729
import static com.objectcomputing.checkins.util.Util.nullSafeUUIDToString;
30+
import static com.objectcomputing.checkins.services.validate.PermissionsValidation.NOT_AUTHORIZED_MSG;
2831

2932
@Singleton
3033
@CacheConfig("member-cache")
@@ -110,27 +113,9 @@ public MemberProfile saveProfile(MemberProfile memberProfile) {
110113
emailAssignment(createdMemberProfile, true); // PDL
111114
emailAssignment(createdMemberProfile, false); // Supervisor
112115
return createdMemberProfile;
113-
}
114-
115-
Optional<MemberProfile> existingProfileOpt = memberProfileRepository.findById(memberProfile.getId());
116-
MemberProfile updatedMemberProfile = memberProfileRepository.update(memberProfile);
117-
if (existingProfileOpt.isEmpty()) {
118-
LOG.error("MemberProfile with id {} not found", memberProfile.getId());
119116
} else {
120-
MemberProfile existingProfile = existingProfileOpt.get();
121-
122-
boolean pdlChanged = !Objects.equals(existingProfile.getPdlId(), memberProfile.getPdlId());
123-
boolean supervisorChanged = !Objects.equals(existingProfile.getSupervisorid(), memberProfile.getSupervisorid());
124-
125-
if (pdlChanged) {
126-
emailAssignment(updatedMemberProfile, true); // PDL
127-
}
128-
if (supervisorChanged) {
129-
emailAssignment(updatedMemberProfile, false); // Supervisor
130-
}
117+
throw new BadArgException("New member created with an id");
131118
}
132-
133-
return updatedMemberProfile;
134119
}
135120

136121
public void emailAssignment(MemberProfile member, boolean isPDL) {
@@ -165,9 +150,6 @@ public void emailAssignment(MemberProfile member, boolean isPDL) {
165150
@Override
166151
@CacheInvalidate(cacheNames = {"member-cache"})
167152
public boolean deleteProfile(@NotNull UUID id) {
168-
if (!currentUserServices.isAdmin()) {
169-
throw new PermissionException("Requires admin privileges");
170-
}
171153
MemberProfile memberProfile = memberProfileRepository.findById(id).orElse(null);
172154
Set<Role> userRoles = (memberProfile != null) ? roleServices.findUserRoles(memberProfile.getId()) : Collections.emptySet();
173155

@@ -180,7 +162,7 @@ public boolean deleteProfile(@NotNull UUID id) {
180162
} else if (!teamMemberServices.findByFields(null, id, null).isEmpty()) {
181163
throw new BadArgException(String.format("User %s cannot be deleted since TeamMember record(s) exist", MemberProfileUtils.getFullName(memberProfile)));
182164
} else if (!userRoles.isEmpty()) {
183-
throw new BadArgException(String.format("User %s cannot be deleted since user has PDL role", MemberProfileUtils.getFullName(memberProfile)));
165+
throw new BadArgException(String.format("User %s cannot be deleted since user has one or more roles", MemberProfileUtils.getFullName(memberProfile)));
184166
}
185167

186168
// Update PDL ID for all associated members before termination
@@ -237,6 +219,52 @@ public List<MemberProfile> getSubordinatesForId(UUID id) {
237219
@Override
238220
@CacheInvalidate(cacheNames = {"member-cache"})
239221
public MemberProfile updateProfile(MemberProfile memberProfile) {
240-
return memberProfileRepository.update(memberProfile);
222+
if (memberProfile.getId() == null) {
223+
throw new BadArgException("Null profile id in update");
224+
}
225+
226+
MemberProfile currentUser = currentUserServices.getCurrentUser();
227+
if (!currentUserServices.hasPermission(Permission.CAN_EDIT_ALL_ORGANIZATION_MEMBERS) &&
228+
(currentUser == null || !currentUser.getId().equals(memberProfile.getId()))) {
229+
throw new PermissionException(NOT_AUTHORIZED_MSG);
230+
}
231+
232+
MemberProfile emailProfile = memberProfileRepository.findByWorkEmail(memberProfile.getWorkEmail()).orElse(null);
233+
234+
if (emailProfile != null && emailProfile.getId() != null && !Objects.equals(memberProfile.getId(), emailProfile.getId())) {
235+
throw new AlreadyExistsException(String.format("Email %s already exists in database",
236+
memberProfile.getWorkEmail()));
237+
}
238+
239+
Optional<MemberProfile> existingProfileOpt = memberProfileRepository.findById(memberProfile.getId());
240+
MemberProfile updatedMemberProfile = memberProfileRepository.update(memberProfile);
241+
if (existingProfileOpt.isEmpty()) {
242+
LOG.error("MemberProfile with id {} not found", memberProfile.getId());
243+
} else {
244+
MemberProfile existingProfile = existingProfileOpt.get();
245+
246+
boolean pdlChanged = !Objects.equals(existingProfile.getPdlId(), memberProfile.getPdlId());
247+
boolean supervisorChanged = !Objects.equals(existingProfile.getSupervisorid(), memberProfile.getSupervisorid());
248+
249+
if (pdlChanged) {
250+
emailAssignment(updatedMemberProfile, true); // PDL
251+
}
252+
if (supervisorChanged) {
253+
emailAssignment(updatedMemberProfile, false); // Supervisor
254+
}
255+
}
256+
257+
return updatedMemberProfile;
258+
}
259+
260+
@Override
261+
@CacheInvalidate(cacheNames = {"member-cache"})
262+
public void updateLastSeen(UUID id) {
263+
Optional<MemberProfile> profile = memberProfileRepository.findById(id);
264+
if (profile.isPresent()) {
265+
MemberProfile memberProfile = profile.get();
266+
memberProfile.setLastSeen(LocalDate.now());
267+
memberProfileRepository.update(memberProfile);
268+
}
241269
}
242270
}

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/currentuser/CurrentUserController.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import io.swagger.v3.oas.annotations.tags.Tag;
2020

2121
import java.net.URI;
22-
import java.time.LocalDate;
2322
import java.util.List;
2423
import java.util.Set;
2524
import java.util.UUID;
@@ -63,8 +62,7 @@ public HttpResponse<CurrentUserDTO> currentUser(@Nullable Authentication authent
6362

6463
MemberProfile user = currentUserServices.findOrSaveUser(firstName, lastName, workEmail);
6564

66-
user.setLastSeen(LocalDate.now());
67-
memberProfileServices.updateProfile(user);
65+
memberProfileServices.updateLastSeen(user.getId());
6866
List<Permission> permissions = rolePermissionServices.findUserPermissions(user.getId());
6967

7068
Set<Role> roles = roleServices.findUserRoles(user.getId());

server/src/main/java/com/objectcomputing/checkins/services/memberprofile/currentuser/CurrentUserServices.java

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.objectcomputing.checkins.services.memberprofile.currentuser;
22

33
import com.objectcomputing.checkins.services.memberprofile.MemberProfile;
4+
import com.objectcomputing.checkins.services.permissions.Permission;
45
import com.objectcomputing.checkins.services.role.RoleType;
56

67
public interface CurrentUserServices {
@@ -9,6 +10,8 @@ public interface CurrentUserServices {
910

1011
boolean hasRole(RoleType role);
1112

13+
boolean hasPermission(Permission permission);
14+
1215
boolean isAdmin();
1316

1417
MemberProfile getCurrentUser();

0 commit comments

Comments
 (0)