|
1 | 1 | package com.researchspace.service.impl; |
2 | 2 |
|
3 | | -import static com.researchspace.service.RecordDeletionManager.MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER; |
4 | | - |
5 | 3 | import com.researchspace.model.AbstractUserOrGroupImpl; |
6 | 4 | import com.researchspace.model.Group; |
7 | 5 | import com.researchspace.model.RecordGroupSharing; |
|
10 | 8 | import com.researchspace.model.audittrail.AuditTrailService; |
11 | 9 | import com.researchspace.model.audittrail.GenericEvent; |
12 | 10 | import com.researchspace.model.audittrail.ShareRecordAuditEvent; |
| 11 | +import com.researchspace.model.dto.SharingResult; |
13 | 12 | import com.researchspace.model.dtos.ShareConfigCommand; |
14 | 13 | import com.researchspace.model.dtos.ShareConfigElement; |
| 14 | +import com.researchspace.model.field.ErrorList; |
15 | 15 | import com.researchspace.model.permissions.ConstraintBasedPermission; |
16 | 16 | import com.researchspace.model.permissions.IPermissionUtils; |
17 | 17 | import com.researchspace.model.permissions.IdConstraint; |
18 | 18 | import com.researchspace.model.permissions.PermissionDomain; |
| 19 | +import com.researchspace.model.record.BaseRecord; |
19 | 20 | import com.researchspace.model.record.Folder; |
20 | 21 | import com.researchspace.model.record.IllegalAddChildOperation; |
| 22 | +import com.researchspace.model.record.Notebook; |
21 | 23 | import com.researchspace.model.record.RSPath; |
22 | 24 | import com.researchspace.model.views.ServiceOperationResult; |
23 | 25 | import com.researchspace.model.views.ServiceOperationResultCollection; |
|
28 | 30 | import com.researchspace.service.UserManager; |
29 | 31 | import java.util.Arrays; |
30 | 32 | import java.util.List; |
31 | | -import java.util.Optional; |
| 33 | +import java.util.Objects; |
| 34 | +import java.util.stream.Collectors; |
32 | 35 | import lombok.extern.slf4j.Slf4j; |
| 36 | +import org.apache.commons.lang3.Validate; |
33 | 37 | import org.apache.shiro.authz.AuthorizationException; |
| 38 | +import org.jetbrains.annotations.NotNull; |
34 | 39 | import org.springframework.beans.factory.annotation.Autowired; |
| 40 | +import org.springframework.transaction.annotation.Transactional; |
35 | 41 |
|
36 | 42 | @Slf4j |
37 | 43 | public class SharingHandlerImpl implements SharingHandler { |
@@ -89,20 +95,7 @@ public ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> |
89 | 95 | @Override |
90 | 96 | public ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> |
91 | 97 | shareIntoSharedFolder(User user, Folder sharedFolder, Long recordId) { |
92 | | - Optional<Folder> sharedFolderRoot = |
93 | | - folderManager.getGroupOrIndividualShrdFolderRootFromSharedSubfolder( |
94 | | - sharedFolder.getId(), user); |
95 | | - RSPath path = folderManager.getShortestPathToSharedRootFolder(sharedFolder.getId(), user); |
96 | | - if (path.isEmpty() || path.size() <= MIN_PATH_LENGTH_TOSHARED_ROOT_FOLDER) { |
97 | | - String msg = |
98 | | - String.format( |
99 | | - "The folder '%s' is not a shared subfolder - id [%d] is not in a shared folder!", |
100 | | - sharedFolder.getName(), sharedFolder.getId()); |
101 | | - throw new IllegalArgumentException(msg); |
102 | | - } |
103 | | - |
104 | | - Group sharedGroup = |
105 | | - groupManager.getGroupByCommunalGroupFolderId(sharedFolderRoot.get().getId()); |
| 98 | + Group sharedGroup = groupManager.getGroupFromAnyLevelOfSharedFolder(user, sharedFolder); |
106 | 99 | ShareConfigElement shareConfigElement = new ShareConfigElement(sharedGroup.getId(), "write"); |
107 | 100 | shareConfigElement.setGroupFolderId(sharedFolder.getId()); |
108 | 101 | ShareConfigCommand shareConfig = |
@@ -162,4 +155,83 @@ private ServiceOperationResult<RecordGroupSharing> doUnshare( |
162 | 155 |
|
163 | 156 | return rc; |
164 | 157 | } |
| 158 | + |
| 159 | + @Override |
| 160 | + public SharingResult shareRecordsWithResult(ShareConfigCommand shareConfig, User sharer) { |
| 161 | + ErrorList error = new ErrorList(); |
| 162 | + ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result = |
| 163 | + this.shareRecords(shareConfig, sharer); |
| 164 | + result.getExceptions().forEach(e -> error.addErrorMsg(e.getMessage())); |
| 165 | + result.getFailures().forEach(rgs -> error.addErrorMsg(rgs.getShared().getName())); |
| 166 | + return new SharingResult(buildSharedIdList(result), buildPublicLinkList(result), error); |
| 167 | + } |
| 168 | + |
| 169 | + @Override |
| 170 | + @Transactional |
| 171 | + public SharingResult moveIntoSharedNotebook( |
| 172 | + Group group, BaseRecord baseRecordToMove, Notebook targetSharedNotebook) { |
| 173 | + Validate.isTrue( |
| 174 | + targetSharedNotebook != null && targetSharedNotebook.isShared(), |
| 175 | + "Notebook must be already shared"); |
| 176 | + |
| 177 | + if (baseRecordToMove.isShared()) { |
| 178 | + RSPath pathToRootSharedFolder = |
| 179 | + folderManager.getShortestPathToSharedRootFolder( |
| 180 | + targetSharedNotebook.getId(), baseRecordToMove.getOwner()); |
| 181 | + sharingManager.unshareFromSharedFolder( |
| 182 | + baseRecordToMove.getOwner(), baseRecordToMove, pathToRootSharedFolder); |
| 183 | + } |
| 184 | + ShareConfigCommand shareConfig = |
| 185 | + buildShareCommandForTarget(baseRecordToMove.getId(), group.getId(), targetSharedNotebook); |
| 186 | + SharingResult sharingResult = shareRecordsWithResult(shareConfig, baseRecordToMove.getOwner()); |
| 187 | + if (sharingResult.getError().hasErrorMessages()) { |
| 188 | + throw new IllegalStateException( |
| 189 | + "Errors while moving into Shared Notebook: [" |
| 190 | + + sharingResult.getError().getAllErrorMessagesAsStringsSeparatedBy(",") |
| 191 | + + "]"); |
| 192 | + } |
| 193 | + return sharingResult; |
| 194 | + } |
| 195 | + |
| 196 | + @NotNull |
| 197 | + private static ShareConfigCommand buildShareCommandForTarget( |
| 198 | + Long idToMove, Long groupId, Folder target) { |
| 199 | + ShareConfigElement shareElement = new ShareConfigElement(groupId, "read"); |
| 200 | + shareElement.setGroupFolderId(target.getId()); |
| 201 | + return new ShareConfigCommand( |
| 202 | + new Long[] {idToMove}, new ShareConfigElement[] {shareElement}, false); |
| 203 | + } |
| 204 | + |
| 205 | + @NotNull |
| 206 | + private static List<Long> buildSharedIdList( |
| 207 | + ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result) { |
| 208 | + List<Long> sharedIds = |
| 209 | + result.getResults().stream() |
| 210 | + .map(rgs -> rgs.getShared().getId()) |
| 211 | + .collect(Collectors.toList()); |
| 212 | + return sharedIds; |
| 213 | + } |
| 214 | + |
| 215 | + @NotNull |
| 216 | + private static List<String> buildPublicLinkList( |
| 217 | + ServiceOperationResultCollection<RecordGroupSharing, RecordGroupSharing> result) { |
| 218 | + List<String> publicLinks = |
| 219 | + result.getResults().stream() |
| 220 | + .map( |
| 221 | + rgs -> { |
| 222 | + if (rgs.getPublicLink() == null) { |
| 223 | + return null; |
| 224 | + } |
| 225 | + String prefix = ""; |
| 226 | + if (rgs.getShared().isStructuredDocument()) { |
| 227 | + prefix = "/public/publishedView/document/"; |
| 228 | + } else if (rgs.getShared().isNotebook()) { |
| 229 | + prefix = "/public/publishedView/notebook/"; |
| 230 | + } |
| 231 | + return rgs.getShared().getName() + "_&_&_" + prefix + rgs.getPublicLink(); |
| 232 | + }) |
| 233 | + .filter(Objects::nonNull) |
| 234 | + .collect(Collectors.toList()); |
| 235 | + return publicLinks; |
| 236 | + } |
165 | 237 | } |
0 commit comments