use of org.mycore.restapi.v1.errors.MCRRestAPIError in project mycore by MyCoRe-Org.
the class MCRJSONWebTokenUtil method retrieveAuthenticationToken.
/**
* returns the access token from Request Header "Authorization"
* if the token is invalid an MCRRestAPIException is thrown
*
* @param request - the HTTPServletRequest object
* @return the JSON Web Token or null, if not provided in request
* @throws MCRRestAPIException
*/
public static SignedJWT retrieveAuthenticationToken(HttpServletRequest request) throws MCRRestAPIException {
String auth = request.getHeader("Authorization");
if (auth != null && auth.startsWith("Bearer ")) {
String authToken = auth.substring(7).trim();
try {
JWSObject jwsObj = JWSObject.parse(authToken);
SignedJWT signedJWT = jwsObj.getPayload().toSignedJWT();
// JWK class does equals only by object id
if (signedJWT.verify(new RSASSAVerifier((RSAPublicKey) MCRJSONWebTokenUtil.RSA_KEYS.getPublic())) && jwsObj.getHeader().getJWK().toJSONString().equals(JWK.parse(signedJWT.getJWTClaimsSet().getJSONObjectClaim("sub_jwk")).toJSONString())) {
Date expires = signedJWT.getJWTClaimsSet().getExpirationTime();
if (Instant.now().isBefore(expires.toInstant())) {
return signedJWT;
} else {
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT).withLocale(Locale.GERMANY).withZone(ZoneId.systemDefault());
throw new MCRRestAPIException(Status.UNAUTHORIZED, new MCRRestAPIError(MCRRestAPIError.CODE_INVALID_AUTHENCATION, "The Authentication Token expired at " + formatter.format(expires.toInstant()), "Please log-in again."));
}
} else {
throw new MCRRestAPIException(Status.UNAUTHORIZED, new MCRRestAPIError(MCRRestAPIError.CODE_INVALID_AUTHENCATION, "The signature of the Authentication Token could not be verified.", null));
}
} catch (ParseException | JOSEException e) {
LOGGER.error(e);
throw new MCRRestAPIException(Status.UNAUTHORIZED, new MCRRestAPIError(MCRRestAPIError.CODE_INVALID_AUTHENCATION, "Authentication is invalid.", e.getMessage()));
}
} else {
return null;
}
}
use of org.mycore.restapi.v1.errors.MCRRestAPIError in project mycore by MyCoRe-Org.
the class MCRRestAPIObjectsHelper method createSortObject.
private static MCRRestAPISortObject createSortObject(String input) throws MCRRestAPIException {
if (input == null) {
return null;
}
List<MCRRestAPIError> errors = new ArrayList<>();
MCRRestAPISortObject result = new MCRRestAPISortObject();
String[] data = input.split(":");
if (data.length == 2) {
result.setField(data[0].replace("|", ""));
String sortOrder = data[1].toLowerCase(Locale.GERMAN).replace("|", "");
if (!"ID".equals(result.getField()) && !"lastModified".equals(result.getField())) {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_QUERY_PARAMETER, "The sortField is wrong", "Allowed values are 'ID' and 'lastModified'."));
}
if ("asc".equals(sortOrder)) {
result.setOrder(SortOrder.ASC);
}
if ("desc".equals(sortOrder)) {
result.setOrder(SortOrder.DESC);
}
if (result.getOrder() == null) {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_QUERY_PARAMETER, "The sortOrder is wrong", "Allowed values for sortOrder are 'asc' and 'desc'."));
}
} else {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_QUERY_PARAMETER, "The sort parameter is wrong.", "The syntax should be [sortField]:[sortOrder]."));
}
if (errors.size() > 0) {
throw new MCRRestAPIException(Status.BAD_REQUEST, errors);
}
return result;
}
use of org.mycore.restapi.v1.errors.MCRRestAPIError in project mycore by MyCoRe-Org.
the class MCRRestAPIObjectsHelper method listObjects.
/**
* returns a list of objects
* @param info - the injected Jersey URIInfo object
*
* @param format - the output format ('xml'|'json')
* @param filter - a filter criteria
* @param sort - the sort criteria
*
* @return a Jersey response object
* @throws MCRRestAPIException
*
* @see org.mycore.restapi.v1.MCRRestAPIObjects#listObjects(UriInfo, HttpServletRequest, String, String, String)
*/
public static Response listObjects(UriInfo info, HttpServletRequest request, String format, String filter, String sort) throws MCRRestAPIException {
List<MCRRestAPIError> errors = new ArrayList<>();
// analyze sort
MCRRestAPISortObject sortObj = null;
try {
sortObj = createSortObject(sort);
} catch (MCRRestAPIException rae) {
errors.addAll(rae.getErrors());
}
if (format.equals(MCRRestAPIObjects.FORMAT_JSON) || format.equals(MCRRestAPIObjects.FORMAT_XML)) {
// ok
} else {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_PARAMETER, "The parameter 'format' is wrong.", "Allowed values for format are 'json' or 'xml'."));
}
// analyze filter
List<String> projectIDs = new ArrayList<>();
List<String> typeIDs = new ArrayList<>();
String lastModifiedBefore = null;
String lastModifiedAfter = null;
if (filter != null) {
for (String s : filter.split(";")) {
if (s.startsWith("project:")) {
projectIDs.add(s.substring(8));
continue;
}
if (s.startsWith("type:")) {
typeIDs.add(s.substring(5));
continue;
}
if (s.startsWith("lastModifiedBefore:")) {
if (!validateDateInput(s.substring(19))) {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_PARAMETER, "The parameter 'filter' is wrong.", "The value of lastModifiedBefore could not be parsed. Please use UTC syntax: yyyy-MM-dd'T'HH:mm:ss'Z'."));
continue;
}
if (lastModifiedBefore == null) {
lastModifiedBefore = s.substring(19);
} else if (s.substring(19).compareTo(lastModifiedBefore) < 0) {
lastModifiedBefore = s.substring(19);
}
continue;
}
if (s.startsWith("lastModifiedAfter:")) {
if (!validateDateInput(s.substring(18))) {
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_PARAMETER, "The parameter 'filter' is wrong.", "The value of lastModifiedAfter could not be parsed. Please use UTC syntax: yyyy-MM-dd'T'HH:mm:ss'Z'."));
continue;
}
if (lastModifiedAfter == null) {
lastModifiedAfter = s.substring(18);
} else if (s.substring(18).compareTo(lastModifiedAfter) > 0) {
lastModifiedAfter = s.substring(18);
}
continue;
}
errors.add(new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_PARAMETER, "The parameter 'filter' is wrong.", "The syntax of the filter '" + s + "'could not be parsed. The syntax should be [filterName]:[value]. Allowed filterNames are 'project', 'type', 'lastModifiedBefore' and 'lastModifiedAfter'."));
}
}
if (errors.size() > 0) {
throw new MCRRestAPIException(Status.BAD_REQUEST, errors);
}
// Parameters are validated - continue to retrieve data
// retrieve MCRIDs by Type and Project ID
Set<String> mcrIDs = new HashSet<>();
if (projectIDs.isEmpty()) {
if (typeIDs.isEmpty()) {
mcrIDs = MCRXMLMetadataManager.instance().listIDs().stream().filter(id -> !id.contains("_derivate_")).collect(Collectors.toSet());
} else {
for (String t : typeIDs) {
mcrIDs.addAll(MCRXMLMetadataManager.instance().listIDsOfType(t));
}
}
} else {
if (typeIDs.isEmpty()) {
for (String id : MCRXMLMetadataManager.instance().listIDs()) {
String[] split = id.split("_");
if (!split[1].equals("derivate") && projectIDs.contains(split[0])) {
mcrIDs.add(id);
}
}
} else {
for (String p : projectIDs) {
for (String t : typeIDs) {
mcrIDs.addAll(MCRXMLMetadataManager.instance().listIDsForBase(p + "_" + t));
}
}
}
}
// Filter by modifiedBefore and modifiedAfter
List<String> l = new ArrayList<>();
l.addAll(mcrIDs);
List<MCRObjectIDDate> objIdDates = new ArrayList<>();
try {
objIdDates = MCRXMLMetadataManager.instance().retrieveObjectDates(l);
} catch (IOException e) {
// TODO
}
if (lastModifiedAfter != null || lastModifiedBefore != null) {
List<MCRObjectIDDate> testObjIdDates = objIdDates;
objIdDates = new ArrayList<>();
for (MCRObjectIDDate oid : testObjIdDates) {
String test = SDF_UTC.format(oid.getLastModified());
if (lastModifiedAfter != null && test.compareTo(lastModifiedAfter) < 0)
continue;
if (lastModifiedBefore != null && lastModifiedBefore.compareTo(test.substring(0, lastModifiedBefore.length())) < 0)
continue;
objIdDates.add(oid);
}
}
// sort if necessary
if (sortObj != null) {
objIdDates.sort(new MCRRestAPISortObjectComparator(sortObj));
}
String authHeader = MCRJSONWebTokenUtil.createJWTAuthorizationHeader(MCRJSONWebTokenUtil.retrieveAuthenticationToken(request));
// output as XML
if (MCRRestAPIObjects.FORMAT_XML.equals(format)) {
Element eMcrobjects = new Element("mycoreobjects");
Document docOut = new Document(eMcrobjects);
eMcrobjects.setAttribute("numFound", Integer.toString(objIdDates.size()));
for (MCRObjectIDDate oid : objIdDates) {
Element eMcrObject = new Element("mycoreobject");
eMcrObject.setAttribute("ID", oid.getId());
eMcrObject.setAttribute("lastModified", SDF_UTC.format(oid.getLastModified()));
eMcrObject.setAttribute("href", info.getAbsolutePathBuilder().path(oid.getId()).build().toString());
eMcrobjects.addContent(eMcrObject);
}
try {
StringWriter sw = new StringWriter();
XMLOutputter xout = new XMLOutputter(Format.getPrettyFormat());
xout.output(docOut, sw);
return Response.ok(sw.toString()).type("application/xml; charset=UTF-8").header(HEADER_NAME_AUTHORIZATION, authHeader).build();
} catch (IOException e) {
throw new MCRRestAPIException(Response.Status.INTERNAL_SERVER_ERROR, new MCRRestAPIError(MCRRestAPIError.CODE_INTERNAL_ERROR, GENERAL_ERROR_MSG, e.getMessage()));
}
}
// output as JSON
if (MCRRestAPIObjects.FORMAT_JSON.equals(format)) {
StringWriter sw = new StringWriter();
try {
JsonWriter writer = new JsonWriter(sw);
writer.setIndent(" ");
writer.beginObject();
writer.name("numFound").value(objIdDates.size());
writer.name("mycoreobjects");
writer.beginArray();
for (MCRObjectIDDate oid : objIdDates) {
writer.beginObject();
writer.name("ID").value(oid.getId());
writer.name("lastModified").value(SDF_UTC.format(oid.getLastModified()));
writer.name("href").value(info.getAbsolutePathBuilder().path(oid.getId()).build().toString());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
return Response.ok(sw.toString()).type("application/json; charset=UTF-8").header(HEADER_NAME_AUTHORIZATION, authHeader).build();
} catch (IOException e) {
throw new MCRRestAPIException(Response.Status.INTERNAL_SERVER_ERROR, new MCRRestAPIError(MCRRestAPIError.CODE_INTERNAL_ERROR, GENERAL_ERROR_MSG, e.getMessage()));
}
}
throw new MCRRestAPIException(Response.Status.INTERNAL_SERVER_ERROR, new MCRRestAPIError(MCRRestAPIError.CODE_INTERNAL_ERROR, "A problem in programm flow", null));
}
use of org.mycore.restapi.v1.errors.MCRRestAPIError in project mycore by MyCoRe-Org.
the class MCRRestAPIObjectsHelper method retrieveMCRDerivate.
private static MCRDerivate retrieveMCRDerivate(MCRObject mcrObj, String derIDString) throws MCRRestAPIException {
// the default value for the key
String derKey = "mcr";
if (derIDString.contains(":")) {
int pos = derIDString.indexOf(":");
derKey = derIDString.substring(0, pos);
derIDString = derIDString.substring(pos + 1);
if (!derKey.equals("mcr") && !derKey.equals("label")) {
throw new MCRRestAPIException(Response.Status.BAD_REQUEST, new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_ID, "The ID is not valid.", "The prefix is unkown. Only 'mcr' or 'label' are allowed."));
}
}
String matchedDerID = null;
for (MCRMetaLinkID check : mcrObj.getStructure().getDerivates()) {
if (derKey.equals("mcr")) {
if (check.getXLinkHref().equals(derIDString)) {
matchedDerID = check.getXLinkHref();
break;
}
}
if (derKey.equals("label")) {
if (derIDString.equals(check.getXLinkLabel()) || derIDString.equals(check.getXLinkTitle())) {
matchedDerID = check.getXLinkHref();
break;
}
}
}
if (matchedDerID == null) {
throw new MCRRestAPIException(Response.Status.NOT_FOUND, new MCRRestAPIError(MCRRestAPIError.CODE_NOT_FOUND, "Derivate " + derIDString + " not found.", "The MyCoRe Object with id '" + mcrObj.getId() + "' does not contain a derivate with id '" + derIDString + "'."));
}
MCRObjectID derID = MCRObjectID.getInstance(matchedDerID);
if (!MCRMetadataManager.exists(derID)) {
throw new MCRRestAPIException(Response.Status.NOT_FOUND, new MCRRestAPIError(MCRRestAPIError.CODE_NOT_FOUND, "There is no derivate with the id '" + matchedDerID + "'.", null));
}
return MCRMetadataManager.retrieveMCRDerivate(derID);
}
use of org.mycore.restapi.v1.errors.MCRRestAPIError in project mycore by MyCoRe-Org.
the class MCRRestAPIUploadHelper method uploadObject.
/**
* uploads a MyCoRe Object
* based upon:
* http://puspendu.wordpress.com/2012/08/23/restful-webservice-file-upload-with-jersey/
*
* @param info - the Jersey UriInfo object
* @param request - the HTTPServletRequest object
* @param uploadedInputStream - the inputstream from HTTP Post request
* @param fileDetails - the file information from HTTP Post request
* @return a Jersey Response object
* @throws MCRRestAPIException
*/
public static Response uploadObject(UriInfo info, HttpServletRequest request, InputStream uploadedInputStream, FormDataContentDisposition fileDetails) throws MCRRestAPIException {
SignedJWT signedJWT = MCRJSONWebTokenUtil.retrieveAuthenticationToken(request);
java.nio.file.Path fXML = null;
try (MCRJPATransactionWrapper mtw = new MCRJPATransactionWrapper()) {
SAXBuilder sb = new SAXBuilder();
Document docOut = sb.build(uploadedInputStream);
MCRObjectID mcrID = MCRObjectID.getInstance(docOut.getRootElement().getAttributeValue("ID"));
if (mcrID.getNumberAsInteger() == 0) {
mcrID = MCRObjectID.getNextFreeId(mcrID.getBase());
}
fXML = UPLOAD_DIR.resolve(mcrID + ".xml");
docOut.getRootElement().setAttribute("ID", mcrID.toString());
docOut.getRootElement().setAttribute("label", mcrID.toString());
XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
try (BufferedWriter bw = Files.newBufferedWriter(fXML, StandardCharsets.UTF_8)) {
xmlOut.output(docOut, bw);
}
MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
MCRUserInformation currentUser = mcrSession.getUserInformation();
MCRUserInformation apiUser = MCRUserManager.getUser(MCRJSONWebTokenUtil.retrieveUsernameFromAuthenticationToken(signedJWT));
mcrSession.setUserInformation(apiUser);
// handles "create" as well
MCRObjectCommands.updateFromFile(fXML.toString(), false);
mcrSession.setUserInformation(currentUser);
return Response.created(info.getBaseUriBuilder().path("v1/objects/" + mcrID).build()).type("application/xml; charset=UTF-8").header(HEADER_NAME_AUTHORIZATION, MCRJSONWebTokenUtil.createJWTAuthorizationHeader(signedJWT)).build();
} catch (Exception e) {
LOGGER.error("Unable to Upload file: {}", String.valueOf(fXML), e);
throw new MCRRestAPIException(Status.BAD_REQUEST, new MCRRestAPIError(MCRRestAPIError.CODE_WRONG_PARAMETER, "Unable to Upload file: " + String.valueOf(fXML), e.getMessage()));
} finally {
if (fXML != null) {
try {
Files.delete(fXML);
} catch (IOException e) {
LOGGER.error("Unable to delete temporary workflow file: {}", String.valueOf(fXML), e);
}
}
}
}
Aggregations