Skip to content

Commit d71e927

Browse files
committed
Set up dtoken for every bitstream of the zip file. (#652)
1 parent d6de6b1 commit d71e927

2 files changed

Lines changed: 138 additions & 41 deletions

File tree

dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserMetadataImportController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,12 @@ public ClarinUserMetadataRest importUserMetadata(HttpServletRequest request) thr
168168
//create user metadata and license resource user allowance
169169
newClarinUserMetadataList = clarinUserMetadataRestController.processSignedInUser(
170170
context, ePerson, clarinUserMetadataRestList,
171-
clarinLicenseResourceMapping, bitstreamUUID, token);
171+
clarinLicenseResourceMapping, token);
172172
} else {
173173
// The user not is signed in
174174
//create user metadata and license resource user allowance
175175
newClarinUserMetadataList = clarinUserMetadataRestController.processNonSignedInUser(
176-
context, clarinUserMetadataRestList, clarinLicenseResourceMapping, bitstreamUUID, token);
176+
context, clarinUserMetadataRestList, clarinLicenseResourceMapping, token);
177177
}
178178
//set eperson_id (user registration) in user_metadata
179179
newClarinUserMetadataList.get(0).setEperson(userRegistration);

dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java

Lines changed: 136 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,19 @@
3232
import org.apache.commons.lang3.StringUtils;
3333
import org.dspace.app.rest.model.BitstreamRest;
3434
import org.dspace.app.rest.model.ClarinUserMetadataRest;
35+
import org.dspace.app.rest.model.ItemRest;
3536
import org.dspace.authorize.AuthorizeException;
3637
import org.dspace.content.Bitstream;
38+
import org.dspace.content.Bundle;
39+
import org.dspace.content.DSpaceObject;
40+
import org.dspace.content.Item;
3741
import org.dspace.content.clarin.ClarinLicense;
3842
import org.dspace.content.clarin.ClarinLicenseResourceMapping;
3943
import org.dspace.content.clarin.ClarinLicenseResourceUserAllowance;
4044
import org.dspace.content.clarin.ClarinUserMetadata;
4145
import org.dspace.content.clarin.ClarinUserRegistration;
4246
import org.dspace.content.service.BitstreamService;
47+
import org.dspace.content.service.ItemService;
4348
import org.dspace.content.service.clarin.ClarinLicenseResourceMappingService;
4449
import org.dspace.content.service.clarin.ClarinLicenseResourceUserAllowanceService;
4550
import org.dspace.content.service.clarin.ClarinUserMetadataService;
@@ -76,9 +81,105 @@ public class ClarinUserMetadataRestController {
7681
ClarinUserRegistrationService clarinUserRegistrationService;
7782
@Autowired
7883
BitstreamService bitstreamService;
84+
85+
@Autowired
86+
ItemService itemService;
87+
7988
@Autowired
8089
ConfigurationService configurationService;
8190

91+
@RequestMapping(value = "/zip", method = POST, consumes = APPLICATION_JSON)
92+
@PreAuthorize("permitAll()")
93+
public ResponseEntity manageUserMetadataForZIP(@RequestParam("itemUUID") UUID itemUUID,
94+
HttpServletRequest request)
95+
throws SQLException, ParseException, IOException, AuthorizeException, MessagingException {
96+
97+
// Get context from the request
98+
Context context = obtainContext(request);
99+
// Validate parameters
100+
if (Objects.isNull(context)) {
101+
return null;
102+
}
103+
if (Objects.isNull(itemUUID)) {
104+
return null;
105+
}
106+
107+
// Get current user from the context to find out if the user is signed in
108+
EPerson currentUser = context.getCurrentUser();
109+
String downloadToken = this.generateToken();
110+
111+
Item item = itemService.find(context, itemUUID);
112+
if (Objects.isNull(item)) {
113+
log.error("Cannot find the item with ID: " + itemUUID);
114+
throw new NotFoundException("Cannot find the item with ID: " + itemUUID);
115+
}
116+
// Load the name because it is used in the email, and it must be loaded before the `sendEmailWithDownloadLink`
117+
// method otherwise it will throw an exception about Lazy loading.
118+
item.getName();
119+
120+
boolean shouldEmailToken = false;
121+
ClarinLicense clarinLicense = null;
122+
// Get ClarinUserMetadataRest Array from the request body
123+
ClarinUserMetadataRest[] clarinUserMetadataRestArray =
124+
new ObjectMapper().readValue(request.getInputStream(), ClarinUserMetadataRest[].class);
125+
if (Objects.isNull(clarinUserMetadataRestArray)) {
126+
throw new RuntimeException("The clarinUserMetadataRestArray cannot be null. It could be empty, but" +
127+
" not null");
128+
}
129+
130+
// Convert Array to the List
131+
List<ClarinUserMetadataRest> clarinUserMetadataRestList = Arrays.asList(clarinUserMetadataRestArray);
132+
List<Bundle> bundles = item.getBundles("ORIGINAL");
133+
for (Bundle original : bundles) {
134+
List<Bitstream> bss = original.getBitstreams();
135+
for (Bitstream bitstream : bss) {
136+
UUID bitstreamUUID = bitstream.getID();
137+
// Get mapping between clarin license and the bitstream
138+
ClarinLicenseResourceMapping clarinLicenseResourceMapping =
139+
this.getLicenseResourceMapping(context, bitstreamUUID);
140+
if (Objects.isNull(clarinLicenseResourceMapping)) {
141+
throw new NotFoundException("Cannot find the license resource mapping between clarin license" +
142+
" and the bitstream");
143+
}
144+
if (Objects.isNull(currentUser)) {
145+
// The user is not signed in
146+
this.processNonSignedInUser(context, clarinUserMetadataRestList, clarinLicenseResourceMapping,
147+
downloadToken);
148+
149+
} else {
150+
// The user is signed in
151+
this.processSignedInUser(context, currentUser, clarinUserMetadataRestList,
152+
clarinLicenseResourceMapping, downloadToken);
153+
}
154+
155+
// Check (only once) if the Clarin License contains the required information to SEND_TOKEN, which means
156+
// the item must be downloaded after the user confirms the download with the token sent by email.
157+
if (Objects.isNull(clarinLicense)) {
158+
clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
159+
shouldEmailToken = this.shouldEmailToken(clarinLicenseResourceMapping);
160+
}
161+
}
162+
}
163+
164+
context.commit();
165+
if (shouldEmailToken) {
166+
// If yes - send token to e-mail
167+
try {
168+
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
169+
this.sendEmailWithDownloadLink(context, item, clarinLicense,
170+
email, downloadToken);
171+
} catch (MessagingException e) {
172+
log.error("Cannot send the download email because: " + e.getMessage());
173+
throw new RuntimeException("Cannot send the download email because: " + e.getMessage());
174+
}
175+
176+
return ResponseEntity.ok().body(CHECK_EMAIL_RESPONSE_CONTENT);
177+
} else {
178+
// If no - send token in the response to download the bitstream immediately
179+
return ResponseEntity.ok().body(downloadToken);
180+
}
181+
}
182+
82183
@RequestMapping(method = POST, consumes = APPLICATION_JSON)
83184
@PreAuthorize("permitAll()")
84185
public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bitstreamUUID,
@@ -91,13 +192,24 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
91192
if (Objects.isNull(context)) {
92193
return null;
93194
}
94-
if (Objects.isNull(bitstreamUUID)) {
195+
196+
197+
Bitstream bitstream = bitstreamService.find(context, bitstreamUUID);
198+
if (Objects.isNull(bitstream)) {
199+
log.error("Cannot find the bitstream with ID: " + bitstreamUUID);
95200
return null;
96201
}
202+
// Load the name because it is used in the email, and it must be loaded before the `sendEmailWithDownloadLink`
203+
// method otherwise it will throw an exception about Lazy loading.
204+
bitstream.getName();
205+
206+
// Get current user from the context to find out if the user is signed in
207+
EPerson currentUser = context.getCurrentUser();
208+
String downloadToken = this.generateToken();
97209

98210
// Get mapping between clarin license and the bitstream
99211
ClarinLicenseResourceMapping clarinLicenseResourceMapping =
100-
this.getLicenseResourceMapping(context, bitstreamUUID);
212+
this.getLicenseResourceMapping(context, bitstream.getID());
101213
if (Objects.isNull(clarinLicenseResourceMapping)) {
102214
throw new NotFoundException("Cannot find the license resource mapping between clarin license" +
103215
" and the bitstream");
@@ -113,28 +225,26 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
113225

114226
// Convert Array to the List
115227
List<ClarinUserMetadataRest> clarinUserMetadataRestList = Arrays.asList(clarinUserMetadataRestArray);
116-
117-
// Get current user from the context to find out if the user is signed in
118-
EPerson currentUser = context.getCurrentUser();
119-
String downloadToken = this.generateToken();
120228
if (Objects.isNull(currentUser)) {
121229
// The user is not signed in
122230
this.processNonSignedInUser(context, clarinUserMetadataRestList, clarinLicenseResourceMapping,
123-
bitstreamUUID, downloadToken);
231+
downloadToken);
124232

125233
} else {
126234
// The user is signed in
127235
this.processSignedInUser(context, currentUser, clarinUserMetadataRestList, clarinLicenseResourceMapping,
128-
bitstreamUUID, downloadToken);
236+
downloadToken);
129237
}
130238

131-
boolean shouldEmailToken = this.shouldEmailToken(context, bitstreamUUID, clarinLicenseResourceMapping);
239+
boolean shouldEmailToken = this.shouldEmailToken(clarinLicenseResourceMapping);
132240
context.commit();
133241
if (shouldEmailToken) {
134242
// If yes - send token to e-mail
135243
try {
136-
this.sendEmailWithDownloadLink(context, bitstreamUUID, clarinLicenseResourceMapping,
137-
clarinUserMetadataRestList, downloadToken);
244+
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
245+
ClarinLicense clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
246+
this.sendEmailWithDownloadLink(context, bitstream, clarinLicense,
247+
email, downloadToken);
138248
} catch (MessagingException e) {
139249
log.error("Cannot send the download email because: " + e.getMessage());
140250
throw new RuntimeException("Cannot send the download email because: " + e.getMessage());
@@ -147,30 +257,19 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
147257
}
148258
}
149259

150-
private void sendEmailWithDownloadLink(Context context, UUID bitstreamUUID,
151-
ClarinLicenseResourceMapping clarinLicenseResourceMapping,
152-
List<ClarinUserMetadataRest> clarinUserMetadataRestList,
260+
private void sendEmailWithDownloadLink(Context context, DSpaceObject dso,
261+
ClarinLicense clarinLicense,
262+
String email,
153263
String downloadToken)
154264
throws IOException, SQLException, MessagingException {
155-
// Get the recipient email
156-
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
157265
if (StringUtils.isBlank(email)) {
158266
log.error("Cannot send email with download link because the email is empty.");
159267
throw new BadRequestException("Cannot send email with download link because the email is empty.");
160268
}
161269

162-
// Get the file name
163-
Bitstream bitstream = bitstreamService.find(context, bitstreamUUID);
164-
if (Objects.isNull(bitstream)) {
165-
log.error("Cannot find bitstream with ID: " + bitstreamUUID);
166-
throw new BadRequestException("Cannot find bitstream with ID: " + bitstreamUUID);
167-
}
168-
169-
// Get Clarin License
170-
ClarinLicense clarinLicense = getClarinLicense(context, bitstreamUUID, clarinLicenseResourceMapping);
171-
if (Objects.isNull(clarinLicense)) {
172-
log.error("Cannot find the clarin license for the bitstream with ID: " + bitstreamUUID);
173-
throw new BadRequestException("Cannot find the clarin license for the bitstream with ID: " + bitstreamUUID);
270+
if (Objects.isNull(dso)) {
271+
log.error("Cannot send email with download link because the DSpaceObject is null.");
272+
throw new BadRequestException("Cannot send email with download link because the DSpaceObject is null.");
174273
}
175274

176275
// Fetch DSpace main cfg info and send it in the email
@@ -185,13 +284,15 @@ private void sendEmailWithDownloadLink(Context context, UUID bitstreamUUID,
185284
throw new RuntimeException("Cannot load the `dspace.ui.url` property from the cfg.");
186285
}
187286
// Compose download link
188-
String downloadLink = uiUrl + "/" + BitstreamRest.PLURAL_NAME + "/" + bitstream.getID() + "/download?dtoken=" +
189-
downloadToken;
287+
// Redirect to `/api/bitstreams/{bitstreamId}/download?dtoken={downloadToken}` or
288+
// `/api/items/{itemId}/download?dtoken={downloadToken}`
289+
String downloadLink = uiUrl + "/" + (dso instanceof Item ? ItemRest.PLURAL_NAME : BitstreamRest.PLURAL_NAME) +
290+
"/" + dso.getID() + "/download?dtoken=" + downloadToken;
190291

191292
try {
192293
Locale locale = context.getCurrentLocale();
193294
Email bean = Email.getEmail(I18nUtil.getEmailFilename(locale, "clarin_download_link"));
194-
bean.addArgument(bitstream.getName());
295+
bean.addArgument(dso.getName());
195296
bean.addArgument(downloadLink);
196297
bean.addArgument(clarinLicense.getDefinition());
197298
bean.addArgument(helpDeskEmail);
@@ -220,7 +321,7 @@ private String getEmailFromUserMetadata(List<ClarinUserMetadataRest> clarinUserM
220321
public List<ClarinUserMetadata> processSignedInUser(Context context, EPerson currentUser,
221322
List<ClarinUserMetadataRest> clarinUserMetadataRestList,
222323
ClarinLicenseResourceMapping clarinLicenseResourceMapping,
223-
UUID bitstreamUUID, String downloadToken)
324+
String downloadToken)
224325
throws SQLException {
225326
// If exists userMetadata records in the table update them or create them in other case
226327
// Get UserRegistration which has the UserMetadata list
@@ -289,7 +390,6 @@ private ClarinLicenseResourceUserAllowance createClrua(Context context,
289390
public List<ClarinUserMetadata> processNonSignedInUser(Context context,
290391
List<ClarinUserMetadataRest> clarinUserMetadataRestList,
291392
ClarinLicenseResourceMapping clarinLicenseResourceMapping,
292-
UUID bitstreamUUID,
293393
String downloadToken) throws SQLException {
294394
// Create ClarinUserMetadataRecord from the ClarinUserMetadataRest List.
295395
// Add created ClarinUserMetadata to the List.
@@ -343,9 +443,7 @@ public ClarinLicenseResourceMapping getLicenseResourceMapping(Context context, U
343443
return clarinLicenseResourceMapping;
344444
}
345445

346-
private ClarinLicense getClarinLicense(Context context, UUID bitstreamUUID,
347-
ClarinLicenseResourceMapping clarinLicenseResourceMapping)
348-
throws SQLException {
446+
private ClarinLicense getClarinLicense(ClarinLicenseResourceMapping clarinLicenseResourceMapping) {
349447
if (Objects.isNull(clarinLicenseResourceMapping)) {
350448
throw new NullPointerException("The clarinLicenseResourceMapping object is null.");
351449
}
@@ -359,9 +457,8 @@ private ClarinLicense getClarinLicense(Context context, UUID bitstreamUUID,
359457
return clarinLicense;
360458
}
361459

362-
private boolean shouldEmailToken(Context context, UUID bitstreamUUID,
363-
ClarinLicenseResourceMapping clarinLicenseResourceMapping) throws SQLException {
364-
ClarinLicense clarinLicense = this.getClarinLicense(context, bitstreamUUID, clarinLicenseResourceMapping);
460+
private boolean shouldEmailToken(ClarinLicenseResourceMapping clarinLicenseResourceMapping) {
461+
ClarinLicense clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
365462
if (Objects.isNull(clarinLicense)) {
366463
throw new NullPointerException("The ClarinLicense is null.");
367464
}

0 commit comments

Comments
 (0)