[FEAT] someting is wrong
This commit is contained in:
parent
37f1362c3c
commit
de08bcfab5
17
.classpath
17
.classpath
@ -25,21 +25,24 @@
|
|||||||
<attribute name="optional" value="true"/>
|
<attribute name="optional" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-21">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="test" value="true"/>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
<attribute name="ignore_optional_problems" value="true"/>
|
||||||
|
<attribute name="m2e-apt" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
<classpathentry kind="src" path="target/generated-sources/annotations">
|
<classpathentry kind="src" path="target/generated-sources/annotations">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="optional" value="true"/>
|
<attribute name="optional" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
|
|
||||||
<attributes>
|
|
||||||
<attribute name="test" value="true"/>
|
|
||||||
<attribute name="optional" value="true"/>
|
|
||||||
</attributes>
|
|
||||||
</classpathentry>
|
|
||||||
<classpathentry kind="output" path="target/classes"/>
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
28
pom.xml
28
pom.xml
@ -54,6 +54,31 @@
|
|||||||
<version>2.1.0-alpha1</version>
|
<version>2.1.0-alpha1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Decode webP images -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
|
<artifactId>imageio-webp</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Decode JPEG image -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||||
|
<artifactId>imageio-jpeg</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Encode file in webp -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.gotson</groupId>
|
||||||
|
<artifactId>webp-imageio</artifactId>
|
||||||
|
<version>0.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Detect type of a file with mime type -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
|
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-multipart -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.media</groupId>
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
@ -96,11 +121,13 @@
|
|||||||
<artifactId>istack-commons-runtime</artifactId>
|
<artifactId>istack-commons-runtime</artifactId>
|
||||||
<version>${istack.version}</version>
|
<version>${istack.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- continu to be needed ??? -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
||||||
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- Serialize and un-serialize request in JSON-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.media</groupId>
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
<artifactId>jersey-media-json-jackson</artifactId>
|
<artifactId>jersey-media-json-jackson</artifactId>
|
||||||
@ -110,6 +137,7 @@
|
|||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>2.17.1</version>
|
<version>2.17.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- encode output in CSV -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
<artifactId>jackson-dataformat-csv</artifactId>
|
<artifactId>jackson-dataformat-csv</artifactId>
|
||||||
|
@ -64,18 +64,18 @@ public class DataResource {
|
|||||||
private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
|
private final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
|
||||||
/** Upload some datas */
|
/** Upload some datas */
|
||||||
private static long tmpFolderId = 1;
|
private static long tmpFolderId = 1;
|
||||||
|
|
||||||
private static void createFolder(final String path) throws IOException {
|
private static void createFolder(final String path) throws IOException {
|
||||||
if (!Files.exists(java.nio.file.Path.of(path))) {
|
if (!Files.exists(java.nio.file.Path.of(path))) {
|
||||||
// Log.print("Create folder: " + path);
|
// Log.print("Create folder: " + path);
|
||||||
Files.createDirectories(java.nio.file.Path.of(path));
|
Files.createDirectories(java.nio.file.Path.of(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long getTmpDataId() {
|
public static long getTmpDataId() {
|
||||||
return tmpFolderId++;
|
return tmpFolderId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getTmpFileInData(final long tmpFolderId) {
|
public static String getTmpFileInData(final long tmpFolderId) {
|
||||||
final String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
|
final String filePath = ConfigBaseVariable.getTmpDataFolder() + File.separator + tmpFolderId;
|
||||||
try {
|
try {
|
||||||
@ -85,7 +85,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileDataOld(final long tmpFolderId) {
|
public static String getFileDataOld(final long tmpFolderId) {
|
||||||
final String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator
|
final String filePath = ConfigBaseVariable.getMediaDataFolder() + File.separator + tmpFolderId + File.separator
|
||||||
+ "data";
|
+ "data";
|
||||||
@ -96,7 +96,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileData(final UUID uuid) {
|
public static String getFileData(final UUID uuid) {
|
||||||
final String stringUUID = uuid.toString();
|
final String stringUUID = uuid.toString();
|
||||||
final String part1 = stringUUID.substring(0, 2);
|
final String part1 = stringUUID.substring(0, 2);
|
||||||
@ -113,11 +113,11 @@ public class DataResource {
|
|||||||
filePath += part3;
|
filePath += part3;
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileMetaData(final UUID uuid) {
|
public static String getFileMetaData(final UUID uuid) {
|
||||||
return getFileData(uuid) + ".json";
|
return getFileData(uuid) + ".json";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Data getWithSha512(final String sha512) {
|
public static Data getWithSha512(final String sha512) {
|
||||||
LOGGER.info("find sha512 = {}", sha512);
|
LOGGER.info("find sha512 = {}", sha512);
|
||||||
try {
|
try {
|
||||||
@ -128,7 +128,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Data getWithId(final long id) {
|
public static Data getWithId(final long id) {
|
||||||
LOGGER.info("find id = {}", id);
|
LOGGER.info("find id = {}", id);
|
||||||
try {
|
try {
|
||||||
@ -139,7 +139,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Data createNewData(final long tmpUID, final String originalFileName, final String sha512)
|
public static Data createNewData(final long tmpUID, final String originalFileName, final String sha512)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
// determine mime type:
|
// determine mime type:
|
||||||
@ -159,7 +159,7 @@ public class DataResource {
|
|||||||
injectedData.sha512 = sha512;
|
injectedData.sha512 = sha512;
|
||||||
final String tmpPath = getTmpFileInData(tmpUID);
|
final String tmpPath = getTmpFileInData(tmpUID);
|
||||||
injectedData.size = Files.size(Paths.get(tmpPath));
|
injectedData.size = Files.size(Paths.get(tmpPath));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
injectedData = DataAccess.insert(injectedData);
|
injectedData = DataAccess.insert(injectedData);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
@ -173,7 +173,7 @@ public class DataResource {
|
|||||||
LOGGER.info("Move done");
|
LOGGER.info("Move done");
|
||||||
return injectedData;
|
return injectedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void modeFileOldModelToNewModel(final long id, final UUID uuid) throws IOException {
|
public static void modeFileOldModelToNewModel(final long id, final UUID uuid) throws IOException {
|
||||||
String mediaCurentPath = getFileDataOld(id);
|
String mediaCurentPath = getFileDataOld(id);
|
||||||
String mediaDestPath = getFileData(uuid);
|
String mediaDestPath = getFileData(uuid);
|
||||||
@ -192,12 +192,12 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
LOGGER.info("Move done");
|
LOGGER.info("Move done");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String saveTemporaryFile(final InputStream uploadedInputStream, final long idData)
|
public static String saveTemporaryFile(final InputStream uploadedInputStream, final long idData)
|
||||||
throws FailException {
|
throws FailException {
|
||||||
return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
|
return saveFile(uploadedInputStream, DataResource.getTmpFileInData(idData));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removeTemporaryFile(final long idData) {
|
public static void removeTemporaryFile(final long idData) {
|
||||||
final String filepath = DataResource.getTmpFileInData(idData);
|
final String filepath = DataResource.getTmpFileInData(idData);
|
||||||
if (Files.exists(Paths.get(filepath))) {
|
if (Files.exists(Paths.get(filepath))) {
|
||||||
@ -209,7 +209,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save uploaded file to a defined location on the server
|
// save uploaded file to a defined location on the server
|
||||||
static String saveFile(final InputStream uploadedInputStream, final String serverLocation) throws FailException {
|
static String saveFile(final InputStream uploadedInputStream, final String serverLocation) throws FailException {
|
||||||
String out = "";
|
String out = "";
|
||||||
@ -243,7 +243,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String bytesToHex(final byte[] bytes) {
|
public static String bytesToHex(final byte[] bytes) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
for (final byte b : bytes) {
|
for (final byte b : bytes) {
|
||||||
@ -251,7 +251,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Data getSmall(final UUID id) {
|
public Data getSmall(final UUID id) {
|
||||||
try {
|
try {
|
||||||
return DataAccess.get(Data.class, id);
|
return DataAccess.get(Data.class, id);
|
||||||
@ -261,7 +261,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/upload/")
|
@Path("/upload/")
|
||||||
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
@Consumes({ MediaType.MULTIPART_FORM_DATA })
|
||||||
@ -286,7 +286,7 @@ public class DataResource {
|
|||||||
}
|
}
|
||||||
saveFile(fileInputStream, filePath);
|
saveFile(fileInputStream, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{uuid}")
|
@Path("{uuid}")
|
||||||
@PermitTokenInURI
|
@PermitTokenInURI
|
||||||
@ -313,7 +313,7 @@ public class DataResource {
|
|||||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("thumbnail/{uuid}")
|
@Path("thumbnail/{uuid}")
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
@ -326,10 +326,10 @@ public class DataResource {
|
|||||||
@QueryParam(HttpHeaders.AUTHORIZATION) final String token,
|
@QueryParam(HttpHeaders.AUTHORIZATION) final String token,
|
||||||
@HeaderParam("Range") final String range,
|
@HeaderParam("Range") final String range,
|
||||||
@PathParam("uuid") final UUID uuid) throws FailException {
|
@PathParam("uuid") final UUID uuid) throws FailException {
|
||||||
// GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
final GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
// logger.info("===================================================");
|
LOGGER.info("===================================================");
|
||||||
// logger.info("== DATA retrieveDataThumbnailId ? {}", (gc==null?"null":gc.user));
|
LOGGER.info("== DATA retrieveDataThumbnailId ? {}", (gc == null ? "null" : gc.userByToken));
|
||||||
// logger.info("===================================================");
|
LOGGER.info("===================================================");
|
||||||
final Data value = getSmall(uuid);
|
final Data value = getSmall(uuid);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return Response.status(404).entity("media NOT FOUND: " + uuid).type("text/plain").build();
|
return Response.status(404).entity("media NOT FOUND: " + uuid).type("text/plain").build();
|
||||||
@ -350,31 +350,43 @@ public class DataResource {
|
|||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to READ the image", ex);
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to READ the image", ex);
|
||||||
}
|
}
|
||||||
|
LOGGER.info("input size image: {}x{} type={}", inputImage.getWidth(), inputImage.getHeight(),
|
||||||
|
inputImage.getType());
|
||||||
final int scaledWidth = 250;
|
final int scaledWidth = 250;
|
||||||
final int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth()
|
final int scaledHeight = (int) ((float) inputImage.getHeight() / (float) inputImage.getWidth()
|
||||||
* scaledWidth);
|
* scaledWidth);
|
||||||
|
|
||||||
// creates output image
|
// creates output image
|
||||||
final BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
|
final BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
|
||||||
|
|
||||||
// scales the input image to the output image
|
// scales the input image to the output image
|
||||||
final Graphics2D g2d = outputImage.createGraphics();
|
final Graphics2D g2d = outputImage.createGraphics();
|
||||||
|
LOGGER.info("output size image: {}x{}", scaledWidth, scaledHeight);
|
||||||
g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
|
g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
|
||||||
g2d.dispose();
|
g2d.dispose();
|
||||||
|
for (final String data : ImageIO.getWriterFormatNames()) {
|
||||||
|
LOGGER.info("availlable format: {}", data);
|
||||||
|
}
|
||||||
// create the output stream:
|
// create the output stream:
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
// TODO: check how to remove buffer file !!! here, it is not needed at all...
|
// TODO: check how to remove buffer file !!! here, it is not needed at all...
|
||||||
ImageIO.write(outputImage, "JPG", baos);
|
//ImageIO.write(outputImage, "JPEG", baos);
|
||||||
|
//ImageIO.write(outputImage, "png", baos);
|
||||||
|
ImageIO.write(outputImage, "WebP", baos);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return Response.status(500).entity("Internal Error: resize fail: " + e.getMessage()).type("text/plain")
|
return Response.status(500).entity("Internal Error: resize fail: " + e.getMessage()).type("text/plain")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
final byte[] imageData = baos.toByteArray();
|
final byte[] imageData = baos.toByteArray();
|
||||||
|
LOGGER.info("output length {}", imageData.length);
|
||||||
// Response.ok(new ByteArrayInputStream(imageData)).build();
|
// Response.ok(new ByteArrayInputStream(imageData)).build();
|
||||||
final Response.ResponseBuilder out = Response.ok(imageData).header(HttpHeaders.CONTENT_LENGTH,
|
final Response.ResponseBuilder out = Response.ok(imageData).header(HttpHeaders.CONTENT_LENGTH,
|
||||||
imageData.length);
|
imageData.length);
|
||||||
out.type("image/jpeg");
|
//out.type("image/jpeg");
|
||||||
|
out.type("image/webp");
|
||||||
|
//out.type("image/png");
|
||||||
// TODO: move this in a decorator !!!
|
// TODO: move this in a decorator !!!
|
||||||
final CacheControl cc = new CacheControl();
|
final CacheControl cc = new CacheControl();
|
||||||
cc.setMaxAge(3600);
|
cc.setMaxAge(3600);
|
||||||
@ -388,7 +400,7 @@ public class DataResource {
|
|||||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to build output stream", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{uuid}/{name}")
|
@Path("{uuid}/{name}")
|
||||||
@PermitTokenInURI
|
@PermitTokenInURI
|
||||||
@ -412,7 +424,7 @@ public class DataResource {
|
|||||||
return buildStream(getFileData(uuid), range,
|
return buildStream(getFileData(uuid), range,
|
||||||
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
value.mimeType == null ? "application/octet-stream" : value.mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
|
/** Adapted from http://stackoverflow.com/questions/12768812/video-streaming-to-ipad-does-not-work-with-tapestry5/12829541#12829541
|
||||||
*
|
*
|
||||||
* @param range range header
|
* @param range range header
|
||||||
@ -451,12 +463,12 @@ public class DataResource {
|
|||||||
out.type(mimeType);
|
out.type(mimeType);
|
||||||
}
|
}
|
||||||
return out.build();
|
return out.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] ranges = range.split("=")[1].split("-");
|
final String[] ranges = range.split("=")[1].split("-");
|
||||||
final long from = Long.parseLong(ranges[0]);
|
final long from = Long.parseLong(ranges[0]);
|
||||||
|
|
||||||
// logger.info("request range : {}", ranges.length);
|
// logger.info("request range : {}", ranges.length);
|
||||||
// Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
|
// Chunk media if the range upper bound is unspecified. Chrome, Opera sends "bytes=0-"
|
||||||
long to = CHUNK_SIZE + from;
|
long to = CHUNK_SIZE + from;
|
||||||
@ -469,7 +481,7 @@ public class DataResource {
|
|||||||
// logger.info("responseRange: {}", responseRange);
|
// logger.info("responseRange: {}", responseRange);
|
||||||
try (final RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
try (final RandomAccessFile raf = new RandomAccessFile(file, "r")) {
|
||||||
raf.seek(from);
|
raf.seek(from);
|
||||||
|
|
||||||
final long len = to - from + 1;
|
final long len = to - from + 1;
|
||||||
final MediaStreamer streamer = new MediaStreamer(len, raf);
|
final MediaStreamer streamer = new MediaStreamer(len, raf);
|
||||||
final Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT)
|
final Response.ResponseBuilder out = Response.ok(streamer).status(Response.Status.PARTIAL_CONTENT)
|
||||||
@ -486,9 +498,9 @@ public class DataResource {
|
|||||||
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to access to the required file.", ex);
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR, "Fail to access to the required file.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void undelete(final Long id) throws Exception {
|
public static void undelete(final Long id) throws Exception {
|
||||||
DataAccess.unsetDelete(Data.class, id);
|
DataAccess.unsetDelete(Data.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
43
src/org/kar/archidata/api/ProxyResource.java
Normal file
43
src/org/kar/archidata/api/ProxyResource.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package org.kar.archidata.api;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.Produces;
|
||||||
|
import jakarta.ws.rs.QueryParam;
|
||||||
|
import jakarta.ws.rs.client.Client;
|
||||||
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
|
|
||||||
|
@Path("/proxy")
|
||||||
|
//@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public class ProxyResource {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ProxyResource.class);
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
public Response getImageFromUrl(@QueryParam("url") final String url) {
|
||||||
|
if (url == null || url.isEmpty()) {
|
||||||
|
return Response.status(Status.BAD_REQUEST).entity("URL manquante").build();
|
||||||
|
}
|
||||||
|
final Client client = ClientBuilder.newClient();
|
||||||
|
try {
|
||||||
|
final WebTarget target = client.target(url);
|
||||||
|
final Response response = target.request().get();
|
||||||
|
if (response.getStatus() != 200) {
|
||||||
|
return Response.status(Status.BAD_GATEWAY).entity("Can not get the image : " + response.getStatus())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return Response.ok(response.readEntity(byte[].class)).header("Access-Control-Allow-Origin", "*")
|
||||||
|
.header("Content-Type", response.getHeaderString("Content-Type")).build();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
return Response.status(Status.INTERNAL_SERVER_ERROR).entity("SERVER internal error : " + e.getMessage())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ public class RestErrorResponse {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Column(length = 0)
|
@Column(length = 0)
|
||||||
final public String statusMessage;
|
final public String statusMessage;
|
||||||
|
|
||||||
public RestErrorResponse(final Response.Status status, final String time, final String error,
|
public RestErrorResponse(final Response.Status status, final String time, final String error,
|
||||||
final String message) {
|
final String message) {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
@ -36,7 +36,7 @@ public class RestErrorResponse {
|
|||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestErrorResponse(final Response.Status status, final String error, final String message) {
|
public RestErrorResponse(final Response.Status status, final String error, final String message) {
|
||||||
this.time = Instant.now().toString();
|
this.time = Instant.now().toString();
|
||||||
this.name = error;
|
this.name = error;
|
||||||
@ -44,7 +44,7 @@ public class RestErrorResponse {
|
|||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public RestErrorResponse(final Response.Status status) {
|
public RestErrorResponse(final Response.Status status) {
|
||||||
this.name = "generic";
|
this.name = "generic";
|
||||||
this.message = "";
|
this.message = "";
|
||||||
@ -52,5 +52,5 @@ public class RestErrorResponse {
|
|||||||
this.status = status.getStatusCode();
|
this.status = status.getStatusCode();
|
||||||
this.statusMessage = status.getReasonPhrase();
|
this.statusMessage = status.getReasonPhrase();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ import java.nio.file.StandardCopyOption;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.tika.Tika;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
import org.kar.archidata.api.DataResource;
|
import org.kar.archidata.api.DataResource;
|
||||||
import org.kar.archidata.dataAccess.DataAccess;
|
import org.kar.archidata.dataAccess.DataAccess;
|
||||||
@ -28,6 +30,9 @@ import org.kar.archidata.model.Data;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.client.Client;
|
||||||
|
import jakarta.ws.rs.client.ClientBuilder;
|
||||||
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
public class DataTools {
|
public class DataTools {
|
||||||
@ -37,6 +42,9 @@ public class DataTools {
|
|||||||
public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
|
public final static int CHUNK_SIZE_IN = 50 * 1024 * 1024; // 1MB chunks
|
||||||
/** Upload some data */
|
/** Upload some data */
|
||||||
private static long tmpFolderId = 1;
|
private static long tmpFolderId = 1;
|
||||||
|
public final static String[] SUPPORTED_IMAGE_MIME_TYPE = { "image/jpeg", "image/png", "image/webp" };
|
||||||
|
public final static String[] SUPPORTED_AUDIO_MIME_TYPE = { "audio/x-matroska" };
|
||||||
|
public final static String[] SUPPORTED_VIDEO_MIME_TYPE = { "video/x-matroska", "video/webm" };
|
||||||
|
|
||||||
public static void createFolder(final String path) throws IOException {
|
public static void createFolder(final String path) throws IOException {
|
||||||
if (!Files.exists(java.nio.file.Path.of(path))) {
|
if (!Files.exists(java.nio.file.Path.of(path))) {
|
||||||
@ -91,20 +99,12 @@ public class DataTools {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Data createNewData(final long tmpUID, final String originalFileName, final String sha512)
|
public static Data createNewData(
|
||||||
throws IOException, SQLException {
|
final long tmpUID,
|
||||||
// determine mime type:
|
final String originalFileName,
|
||||||
String mimeType = "";
|
final String sha512,
|
||||||
final String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
|
final String mimeType) throws IOException, SQLException {
|
||||||
mimeType = switch (extension.toLowerCase()) {
|
|
||||||
case "jpg", "jpeg" -> "image/jpeg";
|
|
||||||
case "png" -> "image/png";
|
|
||||||
case "webp" -> "image/webp";
|
|
||||||
case "mka" -> "audio/x-matroska";
|
|
||||||
case "mkv" -> "video/x-matroska";
|
|
||||||
case "webm" -> "video/webm";
|
|
||||||
default -> throw new IOException("Can not find the mime type of data input: '" + extension + "'");
|
|
||||||
};
|
|
||||||
final String tmpPath = getTmpFileInData(tmpUID);
|
final String tmpPath = getTmpFileInData(tmpUID);
|
||||||
final long fileSize = Files.size(Paths.get(tmpPath));
|
final long fileSize = Files.size(Paths.get(tmpPath));
|
||||||
Data out = new Data();
|
Data out = new Data();
|
||||||
@ -130,6 +130,23 @@ public class DataTools {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Data createNewData(final long tmpUID, final String originalFileName, final String sha512)
|
||||||
|
throws IOException, SQLException {
|
||||||
|
// determine mime type:
|
||||||
|
String mimeType = "";
|
||||||
|
final String extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);
|
||||||
|
mimeType = switch (extension.toLowerCase()) {
|
||||||
|
case "jpg", "jpeg" -> "image/jpeg";
|
||||||
|
case "png" -> "image/png";
|
||||||
|
case "webp" -> "image/webp";
|
||||||
|
case "mka" -> "audio/x-matroska";
|
||||||
|
case "mkv" -> "video/x-matroska";
|
||||||
|
case "webm" -> "video/webm";
|
||||||
|
default -> throw new IOException("Can not find the mime type of data input: '" + extension + "'");
|
||||||
|
};
|
||||||
|
return createNewData(tmpUID, originalFileName, sha512, mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
public static void undelete(final UUID id) {
|
public static void undelete(final UUID id) {
|
||||||
try {
|
try {
|
||||||
DataAccess.unsetDelete(Data.class, id);
|
DataAccess.unsetDelete(Data.class, id);
|
||||||
@ -143,6 +160,10 @@ public class DataTools {
|
|||||||
return saveFile(uploadedInputStream, getTmpFileInData(idData));
|
return saveFile(uploadedInputStream, getTmpFileInData(idData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String saveTemporaryFile(final byte[] uploadedInputStream, final long idData) {
|
||||||
|
return saveFile(uploadedInputStream, getTmpFileInData(idData));
|
||||||
|
}
|
||||||
|
|
||||||
public static void removeTemporaryFile(final long idData) {
|
public static void removeTemporaryFile(final long idData) {
|
||||||
final String filepath = getTmpFileInData(idData);
|
final String filepath = getTmpFileInData(idData);
|
||||||
if (Files.exists(Paths.get(filepath))) {
|
if (Files.exists(Paths.get(filepath))) {
|
||||||
@ -188,6 +209,31 @@ public class DataTools {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String saveFile(final byte[] bytes, final String serverLocation) {
|
||||||
|
String out = "";
|
||||||
|
try {
|
||||||
|
final OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
|
||||||
|
final MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||||
|
md.update(bytes, 0, bytes.length);
|
||||||
|
outpuStream.write(bytes, 0, bytes.length);
|
||||||
|
|
||||||
|
LOGGER.info("Flush input stream ... {}", serverLocation);
|
||||||
|
outpuStream.flush();
|
||||||
|
outpuStream.close();
|
||||||
|
// create the end of sha512
|
||||||
|
final byte[] sha512Digest = md.digest();
|
||||||
|
// convert in hexadecimal
|
||||||
|
out = bytesToHex(sha512Digest);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
LOGGER.error("Can not write in temporary file ... ");
|
||||||
|
ex.printStackTrace();
|
||||||
|
} catch (final NoSuchAlgorithmException ex) {
|
||||||
|
LOGGER.error("Can not find sha512 algorithms");
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// curl http://localhost:9993/api/users/3
|
// curl http://localhost:9993/api/users/3
|
||||||
// @Secured
|
// @Secured
|
||||||
/* @GET
|
/* @GET
|
||||||
@ -216,6 +262,90 @@ public class DataTools {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getMimeType(final byte[] data) {
|
||||||
|
final Tika tika = new Tika();
|
||||||
|
final String mimeType = tika.detect(data);
|
||||||
|
return mimeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <CLASS_TYPE, ID_TYPE> void uploadCoverFromUri(
|
||||||
|
final Class<CLASS_TYPE> clazz,
|
||||||
|
final ID_TYPE id,
|
||||||
|
final String url) throws Exception {
|
||||||
|
|
||||||
|
LOGGER.info(" - id: {}", id);
|
||||||
|
LOGGER.info(" - url: {} ", url);
|
||||||
|
final CLASS_TYPE media = DataAccess.get(clazz, id);
|
||||||
|
if (media == null) {
|
||||||
|
throw new InputException(clazz.getCanonicalName(),
|
||||||
|
"[" + id.toString() + "] Id does not exist or removed...");
|
||||||
|
}
|
||||||
|
// Download data:
|
||||||
|
|
||||||
|
final Client client = ClientBuilder.newClient();
|
||||||
|
byte[] dataResponse = null;
|
||||||
|
try {
|
||||||
|
final WebTarget target = client.target(url);
|
||||||
|
final Response response = target.request().get();
|
||||||
|
if (response.getStatus() != 200) {
|
||||||
|
throw new FailException(Response.Status.BAD_GATEWAY,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] Can not download the media");
|
||||||
|
}
|
||||||
|
dataResponse = response.readEntity(byte[].class);
|
||||||
|
} catch (final Exception ex) {
|
||||||
|
throw new FailException(Response.Status.INTERNAL_SERVER_ERROR,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] can not create input media", ex);
|
||||||
|
}
|
||||||
|
if (dataResponse == null) {
|
||||||
|
throw new FailException(Response.Status.NOT_ACCEPTABLE,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] Data does not exist");
|
||||||
|
}
|
||||||
|
if (dataResponse.length == 0 || dataResponse.length == 50 * 1024 * 1024) {
|
||||||
|
throw new FailException(Response.Status.NOT_ACCEPTABLE, clazz.getCanonicalName() + "[" + id.toString()
|
||||||
|
+ "] Data size is not correct " + dataResponse.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
final long tmpUID = getTmpDataId();
|
||||||
|
final String sha512 = saveTemporaryFile(dataResponse, tmpUID);
|
||||||
|
Data data = getWithSha512(sha512);
|
||||||
|
final String mimeType = getMimeType(dataResponse);
|
||||||
|
if (!Arrays.asList(SUPPORTED_IMAGE_MIME_TYPE).contains(mimeType)) {
|
||||||
|
throw new FailException(Response.Status.NOT_ACCEPTABLE,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] Data CoverType is not accesptable: " + mimeType
|
||||||
|
+ "support only: " + String.join(", ", SUPPORTED_IMAGE_MIME_TYPE));
|
||||||
|
|
||||||
|
}
|
||||||
|
if (data == null) {
|
||||||
|
LOGGER.info("Need to add the data in the BDD ... ");
|
||||||
|
try {
|
||||||
|
data = createNewData(tmpUID, url, sha512, mimeType);
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
removeTemporaryFile(tmpUID);
|
||||||
|
throw new FailException(Response.Status.NOT_MODIFIED,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] can not create input media", ex);
|
||||||
|
} catch (final SQLException ex) {
|
||||||
|
removeTemporaryFile(tmpUID);
|
||||||
|
throw new FailException(Response.Status.NOT_MODIFIED,
|
||||||
|
clazz.getCanonicalName() + "[" + id.toString() + "] Error in SQL insertion", ex);
|
||||||
|
}
|
||||||
|
} else if (data.deleted) {
|
||||||
|
LOGGER.error("Data already exist but deleted");
|
||||||
|
undelete(data.uuid);
|
||||||
|
data.deleted = false;
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Data already exist ... all good");
|
||||||
|
}
|
||||||
|
// Fist step: retrieve all the Id of each parents:...
|
||||||
|
LOGGER.info("Find typeNode");
|
||||||
|
if (id instanceof final Long idLong) {
|
||||||
|
AddOnDataJson.addLink(clazz, idLong, "covers", data.uuid);
|
||||||
|
} else if (id instanceof final UUID idUUID) {
|
||||||
|
AddOnDataJson.addLink(clazz, idUUID, "covers", data.uuid);
|
||||||
|
} else {
|
||||||
|
throw new IOException("Fail to add Cover can not detect type...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static <CLASS_TYPE, ID_TYPE> void uploadCover(
|
public static <CLASS_TYPE, ID_TYPE> void uploadCover(
|
||||||
final Class<CLASS_TYPE> clazz,
|
final Class<CLASS_TYPE> clazz,
|
||||||
final ID_TYPE id,
|
final ID_TYPE id,
|
||||||
|
@ -35,7 +35,7 @@ import com.nimbusds.jwt.SignedJWT;
|
|||||||
|
|
||||||
class TestSigner implements JWSSigner {
|
class TestSigner implements JWSSigner {
|
||||||
public static String test_signature = "TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E";
|
public static String test_signature = "TEST_SIGNATURE_FOR_LOCAL_TEST_AND_TEST_E2E";
|
||||||
|
|
||||||
/** Signs the specified {@link JWSObject#getSigningInput input} of a {@link JWSObject JWS object}.
|
/** Signs the specified {@link JWSObject#getSigningInput input} of a {@link JWSObject JWS object}.
|
||||||
*
|
*
|
||||||
* @param header The JSON Web Signature (JWS) header. Must specify a supported JWS algorithm and must not be {@code null}.
|
* @param header The JSON Web Signature (JWS) header. Must specify a supported JWS algorithm and must not be {@code null}.
|
||||||
@ -49,13 +49,13 @@ class TestSigner implements JWSSigner {
|
|||||||
public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException {
|
public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException {
|
||||||
return new Base64URL(test_signature);
|
return new Base64URL(test_signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<JWSAlgorithm> supportedJWSAlgorithms() {
|
public Set<JWSAlgorithm> supportedJWSAlgorithms() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return Set.of(JWSAlgorithm.RS256);
|
return Set.of(JWSAlgorithm.RS256);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JCAContext getJCAContext() {
|
public JCAContext getJCAContext() {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -65,20 +65,20 @@ class TestSigner implements JWSSigner {
|
|||||||
|
|
||||||
public class JWTWrapper {
|
public class JWTWrapper {
|
||||||
static final Logger LOGGER = LoggerFactory.getLogger(JWTWrapper.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(JWTWrapper.class);
|
||||||
|
|
||||||
private static RSAKey rsaJWK = null;
|
private static RSAKey rsaJWK = null;
|
||||||
private static RSAKey rsaPublicJWK = null;
|
private static RSAKey rsaPublicJWK = null;
|
||||||
|
|
||||||
public static class PublicKey {
|
public static class PublicKey {
|
||||||
public String key;
|
public String key;
|
||||||
|
|
||||||
public PublicKey(final String key) {
|
public PublicKey(final String key) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PublicKey() {}
|
public PublicKey() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initLocalTokenRemote(final String ssoUri, final String application)
|
public static void initLocalTokenRemote(final String ssoUri, final String application)
|
||||||
throws IOException, ParseException {
|
throws IOException, ParseException {
|
||||||
// check Token:
|
// check Token:
|
||||||
@ -95,11 +95,11 @@ public class JWTWrapper {
|
|||||||
con.setRequestProperty(AuthenticationFilter.APIKEY, ssoToken);
|
con.setRequestProperty(AuthenticationFilter.APIKEY, ssoToken);
|
||||||
}
|
}
|
||||||
final int responseCode = con.getResponseCode();
|
final int responseCode = con.getResponseCode();
|
||||||
|
|
||||||
// LOGGER.debug("GET Response Code :: {}", responseCode);
|
// LOGGER.debug("GET Response Code :: {}", responseCode);
|
||||||
if (responseCode == HttpURLConnection.HTTP_OK) { // success
|
if (responseCode == HttpURLConnection.HTTP_OK) { // success
|
||||||
final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||||
|
|
||||||
String inputLine;
|
String inputLine;
|
||||||
final StringBuffer response = new StringBuffer();
|
final StringBuffer response = new StringBuffer();
|
||||||
while ((inputLine = in.readLine()) != null) {
|
while ((inputLine = in.readLine()) != null) {
|
||||||
@ -107,7 +107,7 @@ public class JWTWrapper {
|
|||||||
}
|
}
|
||||||
in.close();
|
in.close();
|
||||||
// print result
|
// print result
|
||||||
// LOGGER.debug(response.toString());
|
LOGGER.debug(response.toString());
|
||||||
final ObjectMapper mapper = new ObjectMapper();
|
final ObjectMapper mapper = new ObjectMapper();
|
||||||
final PublicKey values = mapper.readValue(response.toString(), PublicKey.class);
|
final PublicKey values = mapper.readValue(response.toString(), PublicKey.class);
|
||||||
rsaPublicJWK = RSAKey.parse(values.key);
|
rsaPublicJWK = RSAKey.parse(values.key);
|
||||||
@ -115,7 +115,7 @@ public class JWTWrapper {
|
|||||||
}
|
}
|
||||||
LOGGER.debug("GET JWT validator token not worked response code {} from {} ", responseCode, obj);
|
LOGGER.debug("GET JWT validator token not worked response code {} from {} ", responseCode, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initLocalToken(final String baseUUID) throws Exception {
|
public static void initLocalToken(final String baseUUID) throws Exception {
|
||||||
// RSA signatures require a public and private RSA key pair, the public key
|
// RSA signatures require a public and private RSA key pair, the public key
|
||||||
// must be made known to the JWS recipient in order to verify the signatures
|
// must be made known to the JWS recipient in order to verify the signatures
|
||||||
@ -139,7 +139,7 @@ public class JWTWrapper {
|
|||||||
rsaPublicJWK = null;
|
rsaPublicJWK = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void initValidateToken(final String publicKey) {
|
public static void initValidateToken(final String publicKey) {
|
||||||
try {
|
try {
|
||||||
rsaPublicJWK = RSAKey.parse(publicKey);
|
rsaPublicJWK = RSAKey.parse(publicKey);
|
||||||
@ -147,16 +147,16 @@ public class JWTWrapper {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
LOGGER.debug("Can not retrieve public Key !!!!!!!! RSAKey='{}'", publicKey);
|
LOGGER.debug("Can not retrieve public Key !!!!!!!! RSAKey='{}'", publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPublicKeyJson() {
|
public static String getPublicKeyJson() {
|
||||||
if (rsaPublicJWK == null) {
|
if (rsaPublicJWK == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return rsaPublicJWK.toJSONString();
|
return rsaPublicJWK.toJSONString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException {
|
public static java.security.interfaces.RSAPublicKey getPublicKeyJava() throws JOSEException {
|
||||||
if (rsaPublicJWK == null) {
|
if (rsaPublicJWK == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -164,7 +164,7 @@ public class JWTWrapper {
|
|||||||
// Convert back to std Java interface
|
// Convert back to std Java interface
|
||||||
return rsaPublicJWK.toRSAPublicKey();
|
return rsaPublicJWK.toRSAPublicKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a token with the provided elements
|
/** Create a token with the provided elements
|
||||||
* @param userID UniqueId of the USER (global unique ID)
|
* @param userID UniqueId of the USER (global unique ID)
|
||||||
* @param userLogin Login of the user (never change)
|
* @param userLogin Login of the user (never change)
|
||||||
@ -187,12 +187,12 @@ public class JWTWrapper {
|
|||||||
try {
|
try {
|
||||||
// Create RSA-signer with the private key
|
// Create RSA-signer with the private key
|
||||||
final JWSSigner signer = new RSASSASigner(rsaJWK);
|
final JWSSigner signer = new RSASSASigner(rsaJWK);
|
||||||
|
|
||||||
LOGGER.warn("timeOutInMunites= {}", timeOutInMunites);
|
LOGGER.warn("timeOutInMunites= {}", timeOutInMunites);
|
||||||
final Date now = new Date();
|
final Date now = new Date();
|
||||||
LOGGER.warn("now = {}", now);
|
LOGGER.warn("now = {}", now);
|
||||||
final Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
|
final Date expiration = new Date(new Date().getTime() - 60 * timeOutInMunites * 1000 /* millisecond */);
|
||||||
|
|
||||||
LOGGER.warn("expiration= {}", expiration);
|
LOGGER.warn("expiration= {}", expiration);
|
||||||
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID))
|
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID))
|
||||||
.claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
|
.claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
|
||||||
@ -205,7 +205,7 @@ public class JWTWrapper {
|
|||||||
final JWTClaimsSet claimsSet = builder.build();
|
final JWTClaimsSet claimsSet = builder.build();
|
||||||
final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)
|
final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)
|
||||||
/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet);
|
/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet);
|
||||||
|
|
||||||
// Compute the RSA signature
|
// Compute the RSA signature
|
||||||
signedJWT.sign(signer);
|
signedJWT.sign(signer);
|
||||||
// serialize the output...
|
// serialize the output...
|
||||||
@ -215,7 +215,7 @@ public class JWTWrapper {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JWTClaimsSet validateToken(final String signedToken, final String isuer, final String application) {
|
public static JWTClaimsSet validateToken(final String signedToken, final String isuer, final String application) {
|
||||||
try {
|
try {
|
||||||
// On the consumer side, parse the JWS and verify its RSA signature
|
// On the consumer side, parse the JWS and verify its RSA signature
|
||||||
@ -267,7 +267,7 @@ public class JWTWrapper {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String createJwtTestToken(
|
public static String createJwtTestToken(
|
||||||
final long userID,
|
final long userID,
|
||||||
final String userLogin,
|
final String userLogin,
|
||||||
@ -280,10 +280,10 @@ public class JWTWrapper {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final int timeOutInMunites = 3600;
|
final int timeOutInMunites = 3600;
|
||||||
|
|
||||||
final Date now = new Date();
|
final Date now = new Date();
|
||||||
final Date expiration = new Date(new Date().getTime() + timeOutInMunites * 1000 /* ms */);
|
final Date expiration = new Date(new Date().getTime() + timeOutInMunites * 1000 /* ms */);
|
||||||
|
|
||||||
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID))
|
final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder().subject(Long.toString(userID))
|
||||||
.claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
|
.claim("login", userLogin).claim("application", application).issuer(isuer).issueTime(now)
|
||||||
.expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
|
.expirationTime(expiration); // Do not ask why we need a "-" here ... this have no meaning
|
||||||
@ -295,10 +295,10 @@ public class JWTWrapper {
|
|||||||
final JWTClaimsSet claimsSet = builder.build();
|
final JWTClaimsSet claimsSet = builder.build();
|
||||||
final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)
|
final SignedJWT signedJWT = new SignedJWT(new JWSHeader.Builder(JWSAlgorithm.RS256).type(JOSEObjectType.JWT)
|
||||||
/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet);
|
/* .keyID(rsaJWK.getKeyID()) */.build(), claimsSet);
|
||||||
|
|
||||||
// Compute the RSA signature
|
// Compute the RSA signature
|
||||||
signedJWT.sign(new TestSigner());
|
signedJWT.sign(new TestSigner());
|
||||||
|
|
||||||
// serialize the output...
|
// serialize the output...
|
||||||
return signedJWT.serialize();
|
return signedJWT.serialize();
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
|
Loading…
Reference in New Issue
Block a user