mirror of
https://github.com/sismics/docs.git
synced 2025-12-14 10:16:21 +00:00
Compare commits
17 Commits
sismics_pr
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2d7f3ebc6 | ||
|
|
8f1ff56d34 | ||
|
|
11ae0ea7d3 | ||
|
|
afa78857f9 | ||
|
|
ae2423b2e9 | ||
|
|
01d3e746d8 | ||
|
|
13cd03a762 | ||
|
|
ac7b3c4eb9 | ||
|
|
7effbc8de0 | ||
|
|
8c5f0c78e7 | ||
|
|
45e00ac93d | ||
|
|
80454afc0d | ||
|
|
428e898a7a | ||
|
|
13762eb67f | ||
|
|
04c43ebf7b | ||
|
|
f9b5a5212d | ||
|
|
0351f94761 |
2
.github/workflows/build-deploy.yml
vendored
2
.github/workflows/build-deploy.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- name: Install test dependencies
|
- name: Install test dependencies
|
||||||
run: sudo apt-get update && sudo apt-get -y -q --no-install-recommends install ffmpeg mediainfo tesseract-ocr tesseract-ocr-deu
|
run: sudo apt-get update && sudo apt-get -y -q --no-install-recommends install ffmpeg mediainfo tesseract-ocr tesseract-ocr-deu
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn -Pprod clean install
|
run: mvn --batch-mode -Pprod clean install
|
||||||
- name: Upload war artifact
|
- name: Upload war artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
41
Dockerfile
41
Dockerfile
@@ -1,8 +1,21 @@
|
|||||||
FROM sismics/ubuntu-jetty:11.0.14
|
FROM ubuntu:22.04
|
||||||
LABEL maintainer="b.gamard@sismics.com"
|
LABEL maintainer="b.gamard@sismics.com"
|
||||||
|
|
||||||
|
# Run Debian in non interactive mode
|
||||||
|
ENV DEBIAN_FRONTEND noninteractive
|
||||||
|
|
||||||
|
# Configure env
|
||||||
|
ENV LANG C.UTF-8
|
||||||
|
ENV LC_ALL C.UTF-8
|
||||||
|
ENV JAVA_HOME /usr/lib/jvm/java-11-openjdk-amd64/
|
||||||
|
ENV JAVA_OPTIONS -Dfile.encoding=UTF-8 -Xmx1g
|
||||||
|
ENV JETTY_VERSION 11.0.20
|
||||||
|
ENV JETTY_HOME /opt/jetty
|
||||||
|
|
||||||
|
# Install packages
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get -y -q --no-install-recommends install \
|
apt-get -y -q --no-install-recommends install \
|
||||||
|
vim less procps unzip wget tzdata openjdk-11-jdk \
|
||||||
ffmpeg \
|
ffmpeg \
|
||||||
mediainfo \
|
mediainfo \
|
||||||
tesseract-ocr \
|
tesseract-ocr \
|
||||||
@@ -32,17 +45,31 @@ RUN apt-get update && \
|
|||||||
tesseract-ocr-tur \
|
tesseract-ocr-tur \
|
||||||
tesseract-ocr-ukr \
|
tesseract-ocr-ukr \
|
||||||
tesseract-ocr-vie \
|
tesseract-ocr-vie \
|
||||||
tesseract-ocr-sqi && \
|
tesseract-ocr-sqi \
|
||||||
apt-get clean && rm -rf /var/lib/apt/lists/* && \
|
&& apt-get clean && \
|
||||||
mkdir /app && \
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN dpkg-reconfigure -f noninteractive tzdata
|
||||||
|
|
||||||
|
# Install Jetty
|
||||||
|
RUN wget -nv -O /tmp/jetty.tar.gz \
|
||||||
|
"https://repo1.maven.org/maven2/org/eclipse/jetty/jetty-home/${JETTY_VERSION}/jetty-home-${JETTY_VERSION}.tar.gz" \
|
||||||
|
&& tar xzf /tmp/jetty.tar.gz -C /opt \
|
||||||
|
&& mv /opt/jetty* /opt/jetty \
|
||||||
|
&& useradd jetty -U -s /bin/false \
|
||||||
|
&& chown -R jetty:jetty /opt/jetty \
|
||||||
|
&& mkdir /opt/jetty/webapps \
|
||||||
|
&& chmod +x /opt/jetty/bin/jetty.sh
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Install app
|
||||||
|
RUN mkdir /app && \
|
||||||
cd /app && \
|
cd /app && \
|
||||||
java -jar /opt/jetty/start.jar --add-modules=server,http,webapp,deploy
|
java -jar /opt/jetty/start.jar --add-modules=server,http,webapp,deploy
|
||||||
|
|
||||||
ADD docs.xml /app/webapps/docs.xml
|
ADD docs.xml /app/webapps/docs.xml
|
||||||
ADD docs-web/target/docs-web-*.war /app/webapps/docs.war
|
ADD docs-web/target/docs-web-*.war /app/webapps/docs.war
|
||||||
|
|
||||||
ENV JAVA_OPTIONS -Xmx1g
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
CMD ["java", "-jar", "/opt/jetty/start.jar"]
|
|
||||||
|
|
||||||
|
CMD ["java", "-jar", "/opt/jetty/start.jar"]
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ To build external URL, the server is expecting a `DOCS_BASE_URL` environment var
|
|||||||
- `DATABASE_URL`: The jdbc connection string to be used by `hibernate`.
|
- `DATABASE_URL`: The jdbc connection string to be used by `hibernate`.
|
||||||
- `DATABASE_USER`: The user which should be used for the database connection.
|
- `DATABASE_USER`: The user which should be used for the database connection.
|
||||||
- `DATABASE_PASSWORD`: The password to be used for the database connection.
|
- `DATABASE_PASSWORD`: The password to be used for the database connection.
|
||||||
|
- `DATABASE_POOL_SIZE`: The pool size to be used for the database connection.
|
||||||
|
|
||||||
- Language
|
- Language
|
||||||
- `DOCS_DEFAULT_LANGUAGE`: The language which will be used as default. Currently supported values are:
|
- `DOCS_DEFAULT_LANGUAGE`: The language which will be used as default. Currently supported values are:
|
||||||
@@ -122,6 +123,7 @@ services:
|
|||||||
DATABASE_URL: "jdbc:postgresql://teedy-db:5432/teedy"
|
DATABASE_URL: "jdbc:postgresql://teedy-db:5432/teedy"
|
||||||
DATABASE_USER: "teedy_db_user"
|
DATABASE_USER: "teedy_db_user"
|
||||||
DATABASE_PASSWORD: "teedy_db_password"
|
DATABASE_PASSWORD: "teedy_db_password"
|
||||||
|
DATABASE_POOL_SIZE: "10"
|
||||||
volumes:
|
volumes:
|
||||||
- ./docs/data:/data
|
- ./docs/data:/data
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<version>1.12-SNAPSHOT</version>
|
<version>1.12-SNAPSHOT</version>
|
||||||
<relativePath>../pom.xml</relativePath>
|
<relativePath>../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>docs-core</artifactId>
|
<artifactId>docs-core</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@@ -17,10 +17,10 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Persistence layer dependencies -->
|
<!-- Persistence layer dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate.orm</groupId>
|
||||||
<artifactId>hibernate-core-jakarta</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Other external dependencies -->
|
<!-- Other external dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-email</artifactId>
|
<artifactId>commons-email</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.freemarker</groupId>
|
<groupId>org.freemarker</groupId>
|
||||||
<artifactId>freemarker</artifactId>
|
<artifactId>freemarker</artifactId>
|
||||||
@@ -66,17 +66,17 @@
|
|||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
@@ -86,17 +86,17 @@
|
|||||||
<groupId>at.favre.lib</groupId>
|
<groupId>at.favre.lib</groupId>
|
||||||
<artifactId>bcrypt</artifactId>
|
<artifactId>bcrypt</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-core</artifactId>
|
<artifactId>lucene-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-analyzers-common</artifactId>
|
<artifactId>lucene-analyzers-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-queryparser</artifactId>
|
<artifactId>lucene-queryparser</artifactId>
|
||||||
@@ -119,7 +119,12 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.directory.api</groupId>
|
<groupId>org.apache.directory.api</groupId>
|
||||||
<artifactId>api-all</artifactId>
|
<artifactId>api-ldap-client-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.directory.api</groupId>
|
||||||
|
<artifactId>api-ldap-codec-standalone</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Only there to read old index and rebuild them -->
|
<!-- Only there to read old index and rebuild them -->
|
||||||
@@ -127,22 +132,22 @@
|
|||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-backward-codecs</artifactId>
|
<artifactId>lucene-backward-codecs</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.imgscalr</groupId>
|
<groupId>org.imgscalr</groupId>
|
||||||
<artifactId>imgscalr-lib</artifactId>
|
<artifactId>imgscalr-lib</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>fr.opensagres.xdocreport</groupId>
|
<groupId>fr.opensagres.xdocreport</groupId>
|
||||||
<artifactId>fr.opensagres.odfdom.converter.pdf</artifactId>
|
<artifactId>fr.opensagres.odfdom.converter.pdf</artifactId>
|
||||||
@@ -186,14 +191,14 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<!-- Development profile (active by default) -->
|
<!-- Development profile (active by default) -->
|
||||||
<profile>
|
<profile>
|
||||||
@@ -205,7 +210,7 @@
|
|||||||
<value>dev</value>
|
<value>dev</value>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
@@ -221,7 +226,7 @@
|
|||||||
<id>prod</id>
|
<id>prod</id>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.sismics.docs.core.constant;
|
package com.sismics.docs.core.constant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration parameters.
|
* Configuration parameters.
|
||||||
*
|
*
|
||||||
* @author jtremeaux
|
* @author jtremeaux
|
||||||
*/
|
*/
|
||||||
public enum ConfigType {
|
public enum ConfigType {
|
||||||
/**
|
/**
|
||||||
@@ -20,6 +20,11 @@ public enum ConfigType {
|
|||||||
*/
|
*/
|
||||||
GUEST_LOGIN,
|
GUEST_LOGIN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OCR enabled.
|
||||||
|
*/
|
||||||
|
OCR_ENABLED,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default language.
|
* Default language.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class DocumentDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_UPDATEDATE_D, d.DOC_LANGUAGE_C, ");
|
StringBuilder sb = new StringBuilder("select distinct d.DOC_ID_C, d.DOC_TITLE_C, d.DOC_DESCRIPTION_C, d.DOC_SUBJECT_C, d.DOC_IDENTIFIER_C, d.DOC_PUBLISHER_C, d.DOC_FORMAT_C, d.DOC_SOURCE_C, d.DOC_TYPE_C, d.DOC_COVERAGE_C, d.DOC_RIGHTS_C, d.DOC_CREATEDATE_D, d.DOC_UPDATEDATE_D, d.DOC_LANGUAGE_C, d.DOC_IDFILE_C,");
|
||||||
sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null) shareCount, ");
|
sb.append(" (select count(s.SHA_ID_C) from T_SHARE s, T_ACL ac where ac.ACL_SOURCEID_C = d.DOC_ID_C and ac.ACL_TARGETID_C = s.SHA_ID_C and ac.ACL_DELETEDATE_D is null and s.SHA_DELETEDATE_D is null) shareCount, ");
|
||||||
sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C) fileCount, ");
|
sb.append(" (select count(f.FIL_ID_C) from T_FILE f where f.FIL_DELETEDATE_D is null and f.FIL_IDDOC_C = d.DOC_ID_C) fileCount, ");
|
||||||
sb.append(" u.USE_USERNAME_C ");
|
sb.append(" u.USE_USERNAME_C ");
|
||||||
@@ -121,6 +121,7 @@ public class DocumentDao {
|
|||||||
documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
documentDto.setCreateTimestamp(((Timestamp) o[i++]).getTime());
|
||||||
documentDto.setUpdateTimestamp(((Timestamp) o[i++]).getTime());
|
documentDto.setUpdateTimestamp(((Timestamp) o[i++]).getTime());
|
||||||
documentDto.setLanguage((String) o[i++]);
|
documentDto.setLanguage((String) o[i++]);
|
||||||
|
documentDto.setFileId((String) o[i++]);
|
||||||
documentDto.setShared(((Number) o[i++]).intValue() > 0);
|
documentDto.setShared(((Number) o[i++]).intValue() > 0);
|
||||||
documentDto.setFileCount(((Number) o[i++]).intValue());
|
documentDto.setFileCount(((Number) o[i++]).intValue());
|
||||||
documentDto.setCreator((String) o[i]);
|
documentDto.setCreator((String) o[i]);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class DocumentCriteria {
|
|||||||
/**
|
/**
|
||||||
* Search query.
|
* Search query.
|
||||||
*/
|
*/
|
||||||
private String search;
|
private String simpleSearch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full content search query.
|
* Full content search query.
|
||||||
@@ -96,12 +96,12 @@ public class DocumentCriteria {
|
|||||||
this.targetIdList = targetIdList;
|
this.targetIdList = targetIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSearch() {
|
public String getSimpleSearch() {
|
||||||
return search;
|
return simpleSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSearch(String search) {
|
public void setSimpleSearch(String search) {
|
||||||
this.search = search;
|
this.simpleSearch = search;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullSearch() {
|
public String getFullSearch() {
|
||||||
|
|||||||
@@ -8,13 +8,12 @@ import java.util.ResourceBundle;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration parameter utilities.
|
* Configuration parameter utilities.
|
||||||
*
|
*
|
||||||
* @author jtremeaux
|
|
||||||
*/
|
*/
|
||||||
public class ConfigUtil {
|
public class ConfigUtil {
|
||||||
/**
|
/**
|
||||||
* Returns the textual value of a configuration parameter.
|
* Returns the textual value of a configuration parameter.
|
||||||
*
|
*
|
||||||
* @param configType Type of the configuration parameter
|
* @param configType Type of the configuration parameter
|
||||||
* @return Textual value of the configuration parameter
|
* @return Textual value of the configuration parameter
|
||||||
* @throws IllegalStateException Configuration parameter undefined
|
* @throws IllegalStateException Configuration parameter undefined
|
||||||
@@ -30,7 +29,7 @@ public class ConfigUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the configuration resource bundle.
|
* Returns the configuration resource bundle.
|
||||||
*
|
*
|
||||||
* @return Resource bundle
|
* @return Resource bundle
|
||||||
*/
|
*/
|
||||||
public static ResourceBundle getConfigBundle() {
|
public static ResourceBundle getConfigBundle() {
|
||||||
@@ -39,14 +38,14 @@ public class ConfigUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the integer value of a configuration parameter.
|
* Returns the integer value of a configuration parameter.
|
||||||
*
|
*
|
||||||
* @param configType Type of the configuration parameter
|
* @param configType Type of the configuration parameter
|
||||||
* @return Integer value of the configuration parameter
|
* @return Integer value of the configuration parameter
|
||||||
* @throws IllegalStateException Configuration parameter undefined
|
* @throws IllegalStateException Configuration parameter undefined
|
||||||
*/
|
*/
|
||||||
public static int getConfigIntegerValue(ConfigType configType) {
|
public static int getConfigIntegerValue(ConfigType configType) {
|
||||||
String value = getConfigStringValue(configType);
|
String value = getConfigStringValue(configType);
|
||||||
|
|
||||||
return Integer.parseInt(value);
|
return Integer.parseInt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,14 +64,28 @@ public class ConfigUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the boolean value of a configuration parameter.
|
* Returns the boolean value of a configuration parameter.
|
||||||
*
|
*
|
||||||
* @param configType Type of the configuration parameter
|
* @param configType Type of the configuration parameter
|
||||||
* @return Boolean value of the configuration parameter
|
* @return Boolean value of the configuration parameter
|
||||||
* @throws IllegalStateException Configuration parameter undefined
|
* @throws IllegalStateException Configuration parameter undefined
|
||||||
*/
|
*/
|
||||||
public static boolean getConfigBooleanValue(ConfigType configType) {
|
public static boolean getConfigBooleanValue(ConfigType configType) {
|
||||||
String value = getConfigStringValue(configType);
|
String value = getConfigStringValue(configType);
|
||||||
|
|
||||||
return Boolean.parseBoolean(value);
|
return Boolean.parseBoolean(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the boolean value of a configuration parameter with a default value.
|
||||||
|
*
|
||||||
|
* @param configType Type of the configuration parameter
|
||||||
|
* @param defaultValue Default value to return if the configuration parameter is undefined
|
||||||
|
* @return Boolean value of the configuration parameter
|
||||||
|
*/
|
||||||
|
public static boolean getConfigBooleanValue(ConfigType configType, boolean defaultValue) {
|
||||||
|
try {
|
||||||
|
return getConfigBooleanValue(configType);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public class LdapAuthenticationHandler implements AuthenticationHandler {
|
|||||||
if (ldapConnection == null) {
|
if (ldapConnection == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
ldapConnection.bind();
|
||||||
|
|
||||||
EntryCursor cursor = ldapConnection.search(ConfigUtil.getConfigStringValue(ConfigType.LDAP_BASE_DN),
|
EntryCursor cursor = ldapConnection.search(ConfigUtil.getConfigStringValue(ConfigType.LDAP_BASE_DN),
|
||||||
ConfigUtil.getConfigStringValue(ConfigType.LDAP_FILTER).replace("USERNAME", username), SearchScope.SUBTREE);
|
ConfigUtil.getConfigStringValue(ConfigType.LDAP_FILTER).replace("USERNAME", username), SearchScope.SUBTREE);
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.sismics.docs.core.util.format;
|
|||||||
import com.google.common.io.Closer;
|
import com.google.common.io.Closer;
|
||||||
import com.sismics.docs.core.constant.Constants;
|
import com.sismics.docs.core.constant.Constants;
|
||||||
import com.sismics.docs.core.util.FileUtil;
|
import com.sismics.docs.core.util.FileUtil;
|
||||||
|
import com.sismics.docs.core.util.ConfigUtil;
|
||||||
|
import com.sismics.docs.core.constant.ConfigType;
|
||||||
import com.sismics.util.mime.MimeType;
|
import com.sismics.util.mime.MimeType;
|
||||||
import org.apache.pdfbox.io.MemoryUsageSetting;
|
import org.apache.pdfbox.io.MemoryUsageSetting;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@@ -22,7 +24,6 @@ import java.nio.file.Path;
|
|||||||
/**
|
/**
|
||||||
* Image format handler.
|
* Image format handler.
|
||||||
*
|
*
|
||||||
* @author bgamard
|
|
||||||
*/
|
*/
|
||||||
public class ImageFormatHandler implements FormatHandler {
|
public class ImageFormatHandler implements FormatHandler {
|
||||||
/**
|
/**
|
||||||
@@ -45,7 +46,7 @@ public class ImageFormatHandler implements FormatHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String extractContent(String language, Path file) throws Exception {
|
public String extractContent(String language, Path file) throws Exception {
|
||||||
if (language == null) {
|
if (language == null || !ConfigUtil.getConfigBooleanValue(ConfigType.OCR_ENABLED, true)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.sismics.docs.core.util.format;
|
|||||||
|
|
||||||
import com.google.common.io.Closer;
|
import com.google.common.io.Closer;
|
||||||
import com.sismics.docs.core.util.FileUtil;
|
import com.sismics.docs.core.util.FileUtil;
|
||||||
|
import com.sismics.docs.core.util.ConfigUtil;
|
||||||
|
import com.sismics.docs.core.constant.ConfigType;
|
||||||
import com.sismics.util.mime.MimeType;
|
import com.sismics.util.mime.MimeType;
|
||||||
import org.apache.pdfbox.io.MemoryUsageSetting;
|
import org.apache.pdfbox.io.MemoryUsageSetting;
|
||||||
import org.apache.pdfbox.multipdf.PDFMergerUtility;
|
import org.apache.pdfbox.multipdf.PDFMergerUtility;
|
||||||
@@ -53,7 +55,7 @@ public class PdfFormatHandler implements FormatHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No text content, try to OCR it
|
// No text content, try to OCR it
|
||||||
if (language != null && content != null && content.trim().isEmpty()) {
|
if (language != null && content != null && content.trim().isEmpty() && ConfigUtil.getConfigBooleanValue(ConfigType.OCR_ENABLED, true)) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
try (InputStream inputStream = Files.newInputStream(file);
|
try (InputStream inputStream = Files.newInputStream(file);
|
||||||
PDDocument pdfDocument = PDDocument.load(inputStream)) {
|
PDDocument pdfDocument = PDDocument.load(inputStream)) {
|
||||||
|
|||||||
@@ -276,9 +276,8 @@ public class LuceneIndexingHandler implements IndexingHandler {
|
|||||||
criteriaList.add("(a.ACL_ID_C is not null or a2.ACL_ID_C is not null)");
|
criteriaList.add("(a.ACL_ID_C is not null or a2.ACL_ID_C is not null)");
|
||||||
}
|
}
|
||||||
parameterMap.put("targetIdList", criteria.getTargetIdList());
|
parameterMap.put("targetIdList", criteria.getTargetIdList());
|
||||||
|
if (!Strings.isNullOrEmpty(criteria.getSimpleSearch()) || !Strings.isNullOrEmpty(criteria.getFullSearch())) {
|
||||||
if (!Strings.isNullOrEmpty(criteria.getSearch()) || !Strings.isNullOrEmpty(criteria.getFullSearch())) {
|
documentSearchMap = search(criteria.getSimpleSearch(), criteria.getFullSearch());
|
||||||
documentSearchMap = search(criteria.getSearch(), criteria.getFullSearch());
|
|
||||||
if (documentSearchMap.isEmpty()) {
|
if (documentSearchMap.isEmpty()) {
|
||||||
// If the search doesn't find any document, the request should return nothing
|
// If the search doesn't find any document, the request should return nothing
|
||||||
documentSearchMap.put(UUID.randomUUID().toString(), null);
|
documentSearchMap.put(UUID.randomUUID().toString(), null);
|
||||||
@@ -413,14 +412,14 @@ public class LuceneIndexingHandler implements IndexingHandler {
|
|||||||
/**
|
/**
|
||||||
* Fulltext search in files and documents.
|
* Fulltext search in files and documents.
|
||||||
*
|
*
|
||||||
* @param searchQuery Search query on metadatas
|
* @param simpleSearchQuery Search query on metadatas
|
||||||
* @param fullSearchQuery Search query on all fields
|
* @param fullSearchQuery Search query on all fields
|
||||||
* @return Map of document IDs as key and highlight as value
|
* @return Map of document IDs as key and highlight as value
|
||||||
* @throws Exception e
|
* @throws Exception e
|
||||||
*/
|
*/
|
||||||
private Map<String, String> search(String searchQuery, String fullSearchQuery) throws Exception {
|
private Map<String, String> search(String simpleSearchQuery, String fullSearchQuery) throws Exception {
|
||||||
// The fulltext query searches in all fields
|
// The fulltext query searches in all fields
|
||||||
searchQuery = searchQuery + " " + fullSearchQuery;
|
String searchQuery = simpleSearchQuery + " " + fullSearchQuery;
|
||||||
|
|
||||||
// Build search query
|
// Build search query
|
||||||
Analyzer analyzer = new StandardAnalyzer();
|
Analyzer analyzer = new StandardAnalyzer();
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class PaginatedLists {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a query and returns the data of the currunt page.
|
* Executes a query and returns the data of the current page.
|
||||||
*
|
*
|
||||||
* @param paginatedList Paginated list object containing parameters, and into which results are added by side effects
|
* @param paginatedList Paginated list object containing parameters, and into which results are added by side effects
|
||||||
* @param queryParam Query parameters
|
* @param queryParam Query parameters
|
||||||
@@ -82,18 +82,6 @@ public class PaginatedLists {
|
|||||||
q.setMaxResults(paginatedList.getLimit());
|
q.setMaxResults(paginatedList.getLimit());
|
||||||
return q.getResultList();
|
return q.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes a paginated request with 2 native queries (one to count the number of results, and one to return the page).
|
|
||||||
*
|
|
||||||
* @param paginatedList Paginated list object containing parameters, and into which results are added by side effects
|
|
||||||
* @param queryParam Query parameters
|
|
||||||
* @return List of results
|
|
||||||
*/
|
|
||||||
public static <E> List<Object[]> executePaginatedQuery(PaginatedList<E> paginatedList, QueryParam queryParam) {
|
|
||||||
executeCountQuery(paginatedList, queryParam);
|
|
||||||
return executeResultQuery(paginatedList, queryParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a paginated request with 2 native queries (one to count the number of results, and one to return the page).
|
* Executes a paginated request with 2 native queries (one to count the number of results, and one to return the page).
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ abstract class DbOpenHelper {
|
|||||||
private static final Logger log = LoggerFactory.getLogger(DbOpenHelper.class);
|
private static final Logger log = LoggerFactory.getLogger(DbOpenHelper.class);
|
||||||
|
|
||||||
private final JdbcConnectionAccess jdbcConnectionAccess;
|
private final JdbcConnectionAccess jdbcConnectionAccess;
|
||||||
|
|
||||||
private final List<Exception> exceptions = new ArrayList<>();
|
private final List<Exception> exceptions = new ArrayList<>();
|
||||||
|
|
||||||
private Formatter formatter;
|
private Formatter formatter;
|
||||||
@@ -99,7 +99,7 @@ abstract class DbOpenHelper {
|
|||||||
onCreate();
|
onCreate();
|
||||||
oldVersion = 0;
|
oldVersion = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute update script
|
// Execute update script
|
||||||
ResourceBundle configBundle = ConfigUtil.getConfigBundle();
|
ResourceBundle configBundle = ConfigUtil.getConfigBundle();
|
||||||
Integer currentVersion = Integer.parseInt(configBundle.getString("db.version"));
|
Integer currentVersion = Integer.parseInt(configBundle.getString("db.version"));
|
||||||
@@ -126,7 +126,7 @@ abstract class DbOpenHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute all upgrade scripts in ascending order for a given version.
|
* Execute all upgrade scripts in ascending order for a given version.
|
||||||
*
|
*
|
||||||
* @param version Version number
|
* @param version Version number
|
||||||
* @throws Exception e
|
* @throws Exception e
|
||||||
*/
|
*/
|
||||||
@@ -136,7 +136,7 @@ abstract class DbOpenHelper {
|
|||||||
return name.matches("dbupdate-" + versionString + "-\\d+\\.sql");
|
return name.matches("dbupdate-" + versionString + "-\\d+\\.sql");
|
||||||
});
|
});
|
||||||
Collections.sort(fileNameList);
|
Collections.sort(fileNameList);
|
||||||
|
|
||||||
for (String fileName : fileNameList) {
|
for (String fileName : fileNameList) {
|
||||||
if (log.isInfoEnabled()) {
|
if (log.isInfoEnabled()) {
|
||||||
log.info(MessageFormat.format("Executing script: {0}", fileName));
|
log.info(MessageFormat.format("Executing script: {0}", fileName));
|
||||||
@@ -145,16 +145,16 @@ abstract class DbOpenHelper {
|
|||||||
executeScript(is);
|
executeScript(is);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a SQL script. All statements must be one line only.
|
* Execute a SQL script. All statements must be one line only.
|
||||||
*
|
*
|
||||||
* @param inputScript Script to execute
|
* @param inputScript Script to execute
|
||||||
* @throws IOException e
|
* @throws IOException e
|
||||||
*/
|
*/
|
||||||
private void executeScript(InputStream inputScript) throws IOException {
|
private void executeScript(InputStream inputScript) throws IOException {
|
||||||
List<String> lines = CharStreams.readLines(new InputStreamReader(inputScript));
|
List<String> lines = CharStreams.readLines(new InputStreamReader(inputScript));
|
||||||
|
|
||||||
for (String sql : lines) {
|
for (String sql : lines) {
|
||||||
if (Strings.isNullOrEmpty(sql) || sql.startsWith("--")) {
|
if (Strings.isNullOrEmpty(sql) || sql.startsWith("--")) {
|
||||||
continue;
|
continue;
|
||||||
@@ -178,13 +178,13 @@ abstract class DbOpenHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract void onCreate() throws Exception;
|
public abstract void onCreate() throws Exception;
|
||||||
|
|
||||||
public abstract void onUpgrade(int oldVersion, int newVersion) throws Exception;
|
public abstract void onUpgrade(int oldVersion, int newVersion) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a List of all Exceptions which occured during the export.
|
* Returns a List of all Exceptions which occurred during the export.
|
||||||
*
|
*
|
||||||
* @return A List containig the Exceptions occured during the export
|
* @return A List containing the Exceptions occurred during the export
|
||||||
*/
|
*/
|
||||||
public List<?> getExceptions() {
|
public List<?> getExceptions() {
|
||||||
return exceptions;
|
return exceptions;
|
||||||
@@ -192,7 +192,7 @@ abstract class DbOpenHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Format the output SQL statements.
|
* Format the output SQL statements.
|
||||||
*
|
*
|
||||||
* @param format True to format
|
* @param format True to format
|
||||||
*/
|
*/
|
||||||
public void setFormat(boolean format) {
|
public void setFormat(boolean format) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import java.util.Properties;
|
|||||||
public final class EMF {
|
public final class EMF {
|
||||||
private static final Logger log = LoggerFactory.getLogger(EMF.class);
|
private static final Logger log = LoggerFactory.getLogger(EMF.class);
|
||||||
|
|
||||||
private static Map<Object, Object> properties;
|
private static Properties properties;
|
||||||
|
|
||||||
private static EntityManagerFactory emfInstance;
|
private static EntityManagerFactory emfInstance;
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ public final class EMF {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Object, Object> getEntityManagerProperties() {
|
private static Properties getEntityManagerProperties() {
|
||||||
// Use properties file if exists
|
// Use properties file if exists
|
||||||
try {
|
try {
|
||||||
URL hibernatePropertiesUrl = EMF.class.getResource("/hibernate.properties");
|
URL hibernatePropertiesUrl = EMF.class.getResource("/hibernate.properties");
|
||||||
@@ -79,9 +79,13 @@ public final class EMF {
|
|||||||
String databaseUrl = System.getenv("DATABASE_URL");
|
String databaseUrl = System.getenv("DATABASE_URL");
|
||||||
String databaseUsername = System.getenv("DATABASE_USER");
|
String databaseUsername = System.getenv("DATABASE_USER");
|
||||||
String databasePassword = System.getenv("DATABASE_PASSWORD");
|
String databasePassword = System.getenv("DATABASE_PASSWORD");
|
||||||
|
String databasePoolSize = System.getenv("DATABASE_POOL_SIZE");
|
||||||
|
if(databasePoolSize == null) {
|
||||||
|
databasePoolSize = "10";
|
||||||
|
}
|
||||||
|
|
||||||
log.info("Configuring EntityManager from environment parameters");
|
log.info("Configuring EntityManager from environment parameters");
|
||||||
Map<Object, Object> props = new HashMap<>();
|
Properties props = new Properties();
|
||||||
Path dbDirectory = DirectoryUtil.getDbDirectory();
|
Path dbDirectory = DirectoryUtil.getDbDirectory();
|
||||||
String dbFile = dbDirectory.resolve("docs").toAbsolutePath().toString();
|
String dbFile = dbDirectory.resolve("docs").toAbsolutePath().toString();
|
||||||
if (Strings.isNullOrEmpty(databaseUrl)) {
|
if (Strings.isNullOrEmpty(databaseUrl)) {
|
||||||
@@ -92,7 +96,7 @@ public final class EMF {
|
|||||||
props.put("hibernate.connection.username", "sa");
|
props.put("hibernate.connection.username", "sa");
|
||||||
} else {
|
} else {
|
||||||
props.put("hibernate.connection.driver_class", "org.postgresql.Driver");
|
props.put("hibernate.connection.driver_class", "org.postgresql.Driver");
|
||||||
props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL94Dialect");
|
props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
|
||||||
props.put("hibernate.connection.url", databaseUrl);
|
props.put("hibernate.connection.url", databaseUrl);
|
||||||
props.put("hibernate.connection.username", databaseUsername);
|
props.put("hibernate.connection.username", databaseUsername);
|
||||||
props.put("hibernate.connection.password", databasePassword);
|
props.put("hibernate.connection.password", databasePassword);
|
||||||
@@ -103,7 +107,7 @@ public final class EMF {
|
|||||||
props.put("hibernate.max_fetch_depth", "5");
|
props.put("hibernate.max_fetch_depth", "5");
|
||||||
props.put("hibernate.cache.use_second_level_cache", "false");
|
props.put("hibernate.cache.use_second_level_cache", "false");
|
||||||
props.put("hibernate.connection.initial_pool_size", "1");
|
props.put("hibernate.connection.initial_pool_size", "1");
|
||||||
props.put("hibernate.connection.pool_size", "10");
|
props.put("hibernate.connection.pool_size", databasePoolSize);
|
||||||
props.put("hibernate.connection.pool_validation_interval", "5");
|
props.put("hibernate.connection.pool_validation_interval", "5");
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
@@ -136,4 +140,4 @@ public final class EMF {
|
|||||||
public static String getDriver() {
|
public static String getDriver() {
|
||||||
return (String) properties.get("hibernate.connection.driver_class");
|
return (String) properties.get("hibernate.connection.driver_class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
db.version=30
|
db.version=31
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
-- DBUPDATE-031-0.SQL
|
||||||
|
|
||||||
|
-- Insert a new setting for OCR recognition
|
||||||
|
insert into T_CONFIG (CFG_ID_C, CFG_VALUE_C) values ('OCR_ENABLED', 'true');
|
||||||
|
|
||||||
|
-- Update the database version
|
||||||
|
update T_CONFIG set CFG_VALUE_C = '31' where CFG_ID_C = 'DB_VERSION';
|
||||||
@@ -30,7 +30,7 @@ import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
|||||||
*/
|
*/
|
||||||
public abstract class BaseTransactionalTest extends BaseTest {
|
public abstract class BaseTransactionalTest extends BaseTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() {
|
||||||
// Initialize the entity manager
|
// Initialize the entity manager
|
||||||
EntityManager em = EMF.get().createEntityManager();
|
EntityManager em = EMF.get().createEntityManager();
|
||||||
ThreadLocalContext context = ThreadLocalContext.get();
|
ThreadLocalContext context = ThreadLocalContext.get();
|
||||||
@@ -40,7 +40,8 @@ public abstract class BaseTransactionalTest extends BaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() {
|
||||||
|
ThreadLocalContext.get().getEntityManager().getTransaction().rollback();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected User createUser(String userName) throws Exception {
|
protected User createUser(String userName) throws Exception {
|
||||||
|
|||||||
@@ -29,5 +29,9 @@ public class TestJpa extends BaseTransactionalTest {
|
|||||||
|
|
||||||
// Authenticate using the database
|
// Authenticate using the database
|
||||||
Assert.assertNotNull(new InternalAuthenticationHandler().authenticate("testJpa", "12345678"));
|
Assert.assertNotNull(new InternalAuthenticationHandler().authenticate("testJpa", "12345678"));
|
||||||
|
|
||||||
|
// Delete the created user
|
||||||
|
userDao.delete("testJpa", user.getId());
|
||||||
|
TransactionUtil.commit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,12 @@
|
|||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jul-to-slf4j</artifactId>
|
<artifactId>jul-to-slf4j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.auth0</groupId>
|
||||||
|
<artifactId>java-jwt</artifactId>
|
||||||
|
<version>4.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Test dependencies -->
|
<!-- Test dependencies -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class ValidationUtil {
|
|||||||
|
|
||||||
private static Pattern ALPHANUMERIC_PATTERN = Pattern.compile("[a-zA-Z0-9_]+");
|
private static Pattern ALPHANUMERIC_PATTERN = Pattern.compile("[a-zA-Z0-9_]+");
|
||||||
|
|
||||||
private static Pattern USERNAME_PATTERN = Pattern.compile("[a-zA-Z0-9_@\\.]+");
|
private static Pattern USERNAME_PATTERN = Pattern.compile("[a-zA-Z0-9_@.-]+");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks that the argument is not null.
|
* Checks that the argument is not null.
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package com.sismics.util.filter;
|
||||||
|
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm;
|
||||||
|
import com.auth0.jwt.JWT;
|
||||||
|
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||||
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||||
|
import com.auth0.jwt.interfaces.JWTVerifier;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.constant.Constants;
|
||||||
|
import com.sismics.docs.core.dao.UserDao;
|
||||||
|
import com.sismics.docs.core.model.jpa.User;
|
||||||
|
import jakarta.json.Json;
|
||||||
|
import jakarta.json.JsonArray;
|
||||||
|
import jakarta.json.JsonObject;
|
||||||
|
import jakarta.json.JsonReader;
|
||||||
|
import jakarta.servlet.FilterConfig;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Optional.ofNullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This filter is used to authenticate the user having an active session by validating a jwt token.
|
||||||
|
* The filter extracts the jwt token stored from Authorization header.
|
||||||
|
* It validates the token by calling an Identity Broker like KeyCloak.
|
||||||
|
* If validated, the user is retrieved, and the filter injects a UserPrincipal into the request attribute.
|
||||||
|
*
|
||||||
|
* @author smitra
|
||||||
|
*/
|
||||||
|
public class JwtBasedSecurityFilter extends SecurityFilter {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(JwtBasedSecurityFilter.class);
|
||||||
|
private static final okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
||||||
|
/**
|
||||||
|
* Name of the header used to store the authentication token.
|
||||||
|
*/
|
||||||
|
public static final String HEADER_NAME = "Authorization";
|
||||||
|
/**
|
||||||
|
* True if this authentication method is enabled.
|
||||||
|
*/
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) {
|
||||||
|
enabled = Boolean.parseBoolean(filterConfig.getInitParameter("enabled"))
|
||||||
|
|| Boolean.parseBoolean(System.getProperty("docs.jwt_authentication"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected User authenticate(final HttpServletRequest request) {
|
||||||
|
if (!enabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.info("Jwt authentication started");
|
||||||
|
User user = null;
|
||||||
|
String token = extractAuthToken(request).replace("Bearer ", "");
|
||||||
|
DecodedJWT jwt = JWT.decode(token);
|
||||||
|
if (verifyJwt(jwt, token)) {
|
||||||
|
String email = jwt.getClaim("preferred_username").toString();
|
||||||
|
UserDao userDao = new UserDao();
|
||||||
|
user = userDao.getActiveByUsername(email);
|
||||||
|
if (user == null) {
|
||||||
|
user = new User();
|
||||||
|
user.setRoleId(Constants.DEFAULT_USER_ROLE);
|
||||||
|
user.setUsername(email);
|
||||||
|
user.setEmail(email);
|
||||||
|
user.setStorageQuota(Long.parseLong(ofNullable(System.getenv(Constants.GLOBAL_QUOTA_ENV))
|
||||||
|
.orElse("1073741824")));
|
||||||
|
user.setPassword(UUID.randomUUID().toString());
|
||||||
|
try {
|
||||||
|
userDao.create(user, email);
|
||||||
|
log.info("user created");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.info("Error:" + e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean verifyJwt(final DecodedJWT jwt, final String token) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
buildJWTVerifier(jwt).verify(token);
|
||||||
|
// if token is valid no exception will be thrown
|
||||||
|
log.info("Valid TOKEN");
|
||||||
|
return Boolean.TRUE;
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
//if CertificateException comes from buildJWTVerifier()
|
||||||
|
log.info("InValid TOKEN: " + e.getMessage());
|
||||||
|
return Boolean.FALSE;
|
||||||
|
} catch (JWTVerificationException e) {
|
||||||
|
// if JWT Token in invalid
|
||||||
|
log.info("InValid TOKEN: " + e.getMessage() );
|
||||||
|
return Boolean.FALSE;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// If any other exception comes
|
||||||
|
log.info("InValid TOKEN, Exception Occurred: " + e.getMessage());
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractAuthToken(final HttpServletRequest request) {
|
||||||
|
return ofNullable(request.getHeader("Authorization")).orElse("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private RSAPublicKey getPublicKey(DecodedJWT jwt) {
|
||||||
|
String jwtIssuerCerts = jwt.getIssuer() + "/protocol/openid-connect/certs";
|
||||||
|
String publicKey = "";
|
||||||
|
RSAPublicKey rsaPublicKey = null;
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(jwtIssuerCerts)
|
||||||
|
.get()
|
||||||
|
.build();
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
log.info("Successfully called the jwt issuer at: " + jwtIssuerCerts + " - " + response.code());
|
||||||
|
assert response.body() != null;
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
try (Reader reader = response.body().charStream()) {
|
||||||
|
try (JsonReader jsonReader = Json.createReader(reader)) {
|
||||||
|
JsonObject jwks = jsonReader.readObject();
|
||||||
|
JsonArray keys = jwks.getJsonArray("keys");
|
||||||
|
publicKey = keys.stream().filter(key -> Objects.equals(key.asJsonObject().getString("kid"),
|
||||||
|
jwt.getKeyId()))
|
||||||
|
.findFirst()
|
||||||
|
.map(k -> k.asJsonObject().getJsonArray("x5c").getString(0))
|
||||||
|
.orElse("");
|
||||||
|
var decode = Base64.getDecoder().decode(publicKey);
|
||||||
|
var certificate = CertificateFactory.getInstance("X.509")
|
||||||
|
.generateCertificate(new ByteArrayInputStream(decode));
|
||||||
|
rsaPublicKey = (RSAPublicKey) certificate.getPublicKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error calling the jwt issuer at: " + jwtIssuerCerts, e);
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
log.error("Error in getting the certificate: ", e);
|
||||||
|
}
|
||||||
|
return rsaPublicKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JWTVerifier buildJWTVerifier(DecodedJWT jwt) throws CertificateException {
|
||||||
|
var algo = Algorithm.RSA256(getPublicKey(jwt), null);
|
||||||
|
return JWT.require(algo).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,7 +63,11 @@ public abstract class BaseJerseyTest extends JerseyTest {
|
|||||||
* Test mail server.
|
* Test mail server.
|
||||||
*/
|
*/
|
||||||
private Wiser wiser;
|
private Wiser wiser;
|
||||||
|
|
||||||
|
public String adminToken() {
|
||||||
|
return clientUtil.login("admin", "admin", false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
|
protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
|
||||||
return new ExternalTestContainerFactory();
|
return new ExternalTestContainerFactory();
|
||||||
|
|||||||
@@ -129,6 +129,12 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.directory.server</groupId>
|
||||||
|
<artifactId>apacheds-all</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -182,7 +188,7 @@
|
|||||||
</systemProperties>
|
</systemProperties>
|
||||||
<webApp>
|
<webApp>
|
||||||
<contextPath>/docs-web</contextPath>
|
<contextPath>/docs-web</contextPath>
|
||||||
<overrideDescriptor>src/dev/main/webapp/web-override.xml</overrideDescriptor>
|
<overrideDescriptor>${project.basedir}/src/dev/main/webapp/web-override.xml</overrideDescriptor>
|
||||||
</webApp>
|
</webApp>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
@@ -260,8 +266,8 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
<configuration>
|
<configuration>
|
||||||
<warSourceDirectory>${basedir}/src/main/webapp/dist</warSourceDirectory>
|
<warSourceDirectory>${project.basedir}/src/main/webapp/dist</warSourceDirectory>
|
||||||
<webXml>src\main\webapp\WEB-INF\web.xml</webXml>
|
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
api.current_version=${project.version}
|
api.current_version=${project.version}
|
||||||
api.min_version=1.0
|
api.min_version=1.0
|
||||||
db.version=30
|
db.version=31
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import java.util.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* General app REST resource.
|
* General app REST resource.
|
||||||
*
|
*
|
||||||
* @author jtremeaux
|
* @author jtremeaux
|
||||||
*/
|
*/
|
||||||
@Path("/app")
|
@Path("/app")
|
||||||
@@ -56,11 +56,11 @@ public class AppResource extends BaseResource {
|
|||||||
* Logger.
|
* Logger.
|
||||||
*/
|
*/
|
||||||
private static final Logger log = LoggerFactory.getLogger(AppResource.class);
|
private static final Logger log = LoggerFactory.getLogger(AppResource.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns informations about the application.
|
* Returns information about the application.
|
||||||
*
|
*
|
||||||
* @api {get} /app Get application informations
|
* @api {get} /app Get application information
|
||||||
* @apiName GetApp
|
* @apiName GetApp
|
||||||
* @apiGroup App
|
* @apiGroup App
|
||||||
* @apiSuccess {String} current_version API current version
|
* @apiSuccess {String} current_version API current version
|
||||||
@@ -85,6 +85,7 @@ public class AppResource extends BaseResource {
|
|||||||
String currentVersion = configBundle.getString("api.current_version");
|
String currentVersion = configBundle.getString("api.current_version");
|
||||||
String minVersion = configBundle.getString("api.min_version");
|
String minVersion = configBundle.getString("api.min_version");
|
||||||
Boolean guestLogin = ConfigUtil.getConfigBooleanValue(ConfigType.GUEST_LOGIN);
|
Boolean guestLogin = ConfigUtil.getConfigBooleanValue(ConfigType.GUEST_LOGIN);
|
||||||
|
Boolean ocrEnabled = ConfigUtil.getConfigBooleanValue(ConfigType.OCR_ENABLED, true);
|
||||||
String defaultLanguage = ConfigUtil.getConfigStringValue(ConfigType.DEFAULT_LANGUAGE);
|
String defaultLanguage = ConfigUtil.getConfigStringValue(ConfigType.DEFAULT_LANGUAGE);
|
||||||
UserDao userDao = new UserDao();
|
UserDao userDao = new UserDao();
|
||||||
DocumentDao documentDao = new DocumentDao();
|
DocumentDao documentDao = new DocumentDao();
|
||||||
@@ -98,6 +99,7 @@ public class AppResource extends BaseResource {
|
|||||||
.add("current_version", currentVersion.replace("-SNAPSHOT", ""))
|
.add("current_version", currentVersion.replace("-SNAPSHOT", ""))
|
||||||
.add("min_version", minVersion)
|
.add("min_version", minVersion)
|
||||||
.add("guest_login", guestLogin)
|
.add("guest_login", guestLogin)
|
||||||
|
.add("ocr_enabled", ocrEnabled)
|
||||||
.add("default_language", defaultLanguage)
|
.add("default_language", defaultLanguage)
|
||||||
.add("queued_tasks", AppContext.getInstance().getQueuedTaskCount())
|
.add("queued_tasks", AppContext.getInstance().getQueuedTaskCount())
|
||||||
.add("total_memory", Runtime.getRuntime().totalMemory())
|
.add("total_memory", Runtime.getRuntime().totalMemory())
|
||||||
@@ -140,6 +142,34 @@ public class AppResource extends BaseResource {
|
|||||||
return Response.ok().build();
|
return Response.ok().build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable/disable OCR.
|
||||||
|
*
|
||||||
|
* @api {post} /app/ocr Enable/disable OCR
|
||||||
|
* @apiName PostAppOcr
|
||||||
|
* @apiGroup App
|
||||||
|
* @apiParam {Boolean} enabled If true, enable OCR
|
||||||
|
* @apiError (client) ForbiddenError Access denied
|
||||||
|
* @apiPermission admin
|
||||||
|
* @apiVersion 1.5.0
|
||||||
|
*
|
||||||
|
* @param enabled If true, enable OCR
|
||||||
|
* @return Response
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("ocr")
|
||||||
|
public Response ocr(@FormParam("enabled") Boolean enabled) {
|
||||||
|
if (!authenticate()) {
|
||||||
|
throw new ForbiddenClientException();
|
||||||
|
}
|
||||||
|
checkBaseFunction(BaseFunction.ADMIN);
|
||||||
|
|
||||||
|
ConfigDao configDao = new ConfigDao();
|
||||||
|
configDao.update(ConfigType.OCR_ENABLED, enabled.toString());
|
||||||
|
|
||||||
|
return Response.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General application configuration.
|
* General application configuration.
|
||||||
*
|
*
|
||||||
@@ -240,7 +270,7 @@ public class AppResource extends BaseResource {
|
|||||||
|
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the SMTP server.
|
* Configure the SMTP server.
|
||||||
*
|
*
|
||||||
@@ -546,13 +576,13 @@ public class AppResource extends BaseResource {
|
|||||||
throw new ServerException("ServerError", "MEMORY appender not configured");
|
throw new ServerException("ServerError", "MEMORY appender not configured");
|
||||||
}
|
}
|
||||||
MemoryAppender memoryAppender = (MemoryAppender) appender;
|
MemoryAppender memoryAppender = (MemoryAppender) appender;
|
||||||
|
|
||||||
// Find the logs
|
// Find the logs
|
||||||
LogCriteria logCriteria = new LogCriteria()
|
LogCriteria logCriteria = new LogCriteria()
|
||||||
.setMinLevel(Level.toLevel(StringUtils.stripToNull(minLevel)))
|
.setMinLevel(Level.toLevel(StringUtils.stripToNull(minLevel)))
|
||||||
.setTag(StringUtils.stripToNull(tag))
|
.setTag(StringUtils.stripToNull(tag))
|
||||||
.setMessage(StringUtils.stripToNull(message));
|
.setMessage(StringUtils.stripToNull(message));
|
||||||
|
|
||||||
PaginatedList<LogEntry> paginatedList = PaginatedLists.create(limit, offset);
|
PaginatedList<LogEntry> paginatedList = PaginatedLists.create(limit, offset);
|
||||||
memoryAppender.find(logCriteria, paginatedList);
|
memoryAppender.find(logCriteria, paginatedList);
|
||||||
JsonArrayBuilder logs = Json.createArrayBuilder();
|
JsonArrayBuilder logs = Json.createArrayBuilder();
|
||||||
@@ -563,14 +593,14 @@ public class AppResource extends BaseResource {
|
|||||||
.add("tag", logEntry.getTag())
|
.add("tag", logEntry.getTag())
|
||||||
.add("message", logEntry.getMessage()));
|
.add("message", logEntry.getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
.add("total", paginatedList.getResultCount())
|
.add("total", paginatedList.getResultCount())
|
||||||
.add("logs", logs);
|
.add("logs", logs);
|
||||||
|
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy and rebuild the search index.
|
* Destroy and rebuild the search index.
|
||||||
*
|
*
|
||||||
@@ -592,7 +622,7 @@ public class AppResource extends BaseResource {
|
|||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
checkBaseFunction(BaseFunction.ADMIN);
|
checkBaseFunction(BaseFunction.ADMIN);
|
||||||
|
|
||||||
RebuildIndexAsyncEvent rebuildIndexAsyncEvent = new RebuildIndexAsyncEvent();
|
RebuildIndexAsyncEvent rebuildIndexAsyncEvent = new RebuildIndexAsyncEvent();
|
||||||
ThreadLocalContext.get().addAsyncEvent(rebuildIndexAsyncEvent);
|
ThreadLocalContext.get().addAsyncEvent(rebuildIndexAsyncEvent);
|
||||||
|
|
||||||
@@ -601,7 +631,7 @@ public class AppResource extends BaseResource {
|
|||||||
.add("status", "ok");
|
.add("status", "ok");
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean storage.
|
* Clean storage.
|
||||||
*
|
*
|
||||||
@@ -623,7 +653,7 @@ public class AppResource extends BaseResource {
|
|||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
checkBaseFunction(BaseFunction.ADMIN);
|
checkBaseFunction(BaseFunction.ADMIN);
|
||||||
|
|
||||||
// Get all files
|
// Get all files
|
||||||
FileDao fileDao = new FileDao();
|
FileDao fileDao = new FileDao();
|
||||||
List<File> fileList = fileDao.findAll(0, Integer.MAX_VALUE);
|
List<File> fileList = fileDao.findAll(0, Integer.MAX_VALUE);
|
||||||
@@ -632,7 +662,7 @@ public class AppResource extends BaseResource {
|
|||||||
fileMap.put(file.getId(), file);
|
fileMap.put(file.getId(), file);
|
||||||
}
|
}
|
||||||
log.info("Checking {} files", fileMap.size());
|
log.info("Checking {} files", fileMap.size());
|
||||||
|
|
||||||
// Check if each stored file is valid
|
// Check if each stored file is valid
|
||||||
try (DirectoryStream<java.nio.file.Path> storedFileList = Files.newDirectoryStream(DirectoryUtil.getStorageDirectory())) {
|
try (DirectoryStream<java.nio.file.Path> storedFileList = Files.newDirectoryStream(DirectoryUtil.getStorageDirectory())) {
|
||||||
for (java.nio.file.Path storedFile : storedFileList) {
|
for (java.nio.file.Path storedFile : storedFileList) {
|
||||||
@@ -646,7 +676,7 @@ public class AppResource extends BaseResource {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ServerException("FileError", "Error deleting orphan files", e);
|
throw new ServerException("FileError", "Error deleting orphan files", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hard delete orphan audit logs
|
// Hard delete orphan audit logs
|
||||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
StringBuilder sb = new StringBuilder("delete from T_AUDIT_LOG al where al.LOG_ID_C in (select al.LOG_ID_C from T_AUDIT_LOG al ");
|
StringBuilder sb = new StringBuilder("delete from T_AUDIT_LOG al where al.LOG_ID_C in (select al.LOG_ID_C from T_AUDIT_LOG al ");
|
||||||
@@ -660,7 +690,7 @@ public class AppResource extends BaseResource {
|
|||||||
sb.append(" where d.DOC_ID_C is null and a.ACL_ID_C is null and c.COM_ID_C is null and f.FIL_ID_C is null and t.TAG_ID_C is null and u.USE_ID_C is null and g.GRP_ID_C is null)");
|
sb.append(" where d.DOC_ID_C is null and a.ACL_ID_C is null and c.COM_ID_C is null and f.FIL_ID_C is null and t.TAG_ID_C is null and u.USE_ID_C is null and g.GRP_ID_C is null)");
|
||||||
Query q = em.createNativeQuery(sb.toString());
|
Query q = em.createNativeQuery(sb.toString());
|
||||||
log.info("Deleting {} orphan audit logs", q.executeUpdate());
|
log.info("Deleting {} orphan audit logs", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan ACLs
|
// Soft delete orphan ACLs
|
||||||
sb = new StringBuilder("update T_ACL a set ACL_DELETEDATE_D = :dateNow where a.ACL_ID_C in (select a.ACL_ID_C from T_ACL a ");
|
sb = new StringBuilder("update T_ACL a set ACL_DELETEDATE_D = :dateNow where a.ACL_ID_C in (select a.ACL_ID_C from T_ACL a ");
|
||||||
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
|
sb.append(" left join T_SHARE s on s.SHA_ID_C = a.ACL_TARGETID_C ");
|
||||||
@@ -672,37 +702,37 @@ public class AppResource extends BaseResource {
|
|||||||
q = em.createNativeQuery(sb.toString());
|
q = em.createNativeQuery(sb.toString());
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan ACLs", q.executeUpdate());
|
log.info("Deleting {} orphan ACLs", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan comments
|
// Soft delete orphan comments
|
||||||
q = em.createNativeQuery("update T_COMMENT set COM_DELETEDATE_D = :dateNow where COM_ID_C in (select c.COM_ID_C from T_COMMENT c left join T_DOCUMENT d on d.DOC_ID_C = c.COM_IDDOC_C and d.DOC_DELETEDATE_D is null where d.DOC_ID_C is null)");
|
q = em.createNativeQuery("update T_COMMENT set COM_DELETEDATE_D = :dateNow where COM_ID_C in (select c.COM_ID_C from T_COMMENT c left join T_DOCUMENT d on d.DOC_ID_C = c.COM_IDDOC_C and d.DOC_DELETEDATE_D is null where d.DOC_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan comments", q.executeUpdate());
|
log.info("Deleting {} orphan comments", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan document tag links
|
// Soft delete orphan document tag links
|
||||||
q = em.createNativeQuery("update T_DOCUMENT_TAG set DOT_DELETEDATE_D = :dateNow where DOT_ID_C in (select dt.DOT_ID_C from T_DOCUMENT_TAG dt left join T_DOCUMENT d on dt.DOT_IDDOCUMENT_C = d.DOC_ID_C and d.DOC_DELETEDATE_D is null left join T_TAG t on t.TAG_ID_C = dt.DOT_IDTAG_C and t.TAG_DELETEDATE_D is null where d.DOC_ID_C is null or t.TAG_ID_C is null)");
|
q = em.createNativeQuery("update T_DOCUMENT_TAG set DOT_DELETEDATE_D = :dateNow where DOT_ID_C in (select dt.DOT_ID_C from T_DOCUMENT_TAG dt left join T_DOCUMENT d on dt.DOT_IDDOCUMENT_C = d.DOC_ID_C and d.DOC_DELETEDATE_D is null left join T_TAG t on t.TAG_ID_C = dt.DOT_IDTAG_C and t.TAG_DELETEDATE_D is null where d.DOC_ID_C is null or t.TAG_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan document tag links", q.executeUpdate());
|
log.info("Deleting {} orphan document tag links", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan shares
|
// Soft delete orphan shares
|
||||||
q = em.createNativeQuery("update T_SHARE set SHA_DELETEDATE_D = :dateNow where SHA_ID_C in (select s.SHA_ID_C from T_SHARE s left join T_ACL a on a.ACL_TARGETID_C = s.SHA_ID_C and a.ACL_DELETEDATE_D is null where a.ACL_ID_C is null)");
|
q = em.createNativeQuery("update T_SHARE set SHA_DELETEDATE_D = :dateNow where SHA_ID_C in (select s.SHA_ID_C from T_SHARE s left join T_ACL a on a.ACL_TARGETID_C = s.SHA_ID_C and a.ACL_DELETEDATE_D is null where a.ACL_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan shares", q.executeUpdate());
|
log.info("Deleting {} orphan shares", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan tags
|
// Soft delete orphan tags
|
||||||
q = em.createNativeQuery("update T_TAG set TAG_DELETEDATE_D = :dateNow where TAG_ID_C in (select t.TAG_ID_C from T_TAG t left join T_USER u on u.USE_ID_C = t.TAG_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
q = em.createNativeQuery("update T_TAG set TAG_DELETEDATE_D = :dateNow where TAG_ID_C in (select t.TAG_ID_C from T_TAG t left join T_USER u on u.USE_ID_C = t.TAG_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan tags", q.executeUpdate());
|
log.info("Deleting {} orphan tags", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan documents
|
// Soft delete orphan documents
|
||||||
q = em.createNativeQuery("update T_DOCUMENT set DOC_DELETEDATE_D = :dateNow where DOC_ID_C in (select d.DOC_ID_C from T_DOCUMENT d left join T_USER u on u.USE_ID_C = d.DOC_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
q = em.createNativeQuery("update T_DOCUMENT set DOC_DELETEDATE_D = :dateNow where DOC_ID_C in (select d.DOC_ID_C from T_DOCUMENT d left join T_USER u on u.USE_ID_C = d.DOC_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan documents", q.executeUpdate());
|
log.info("Deleting {} orphan documents", q.executeUpdate());
|
||||||
|
|
||||||
// Soft delete orphan files
|
// Soft delete orphan files
|
||||||
q = em.createNativeQuery("update T_FILE set FIL_DELETEDATE_D = :dateNow where FIL_ID_C in (select f.FIL_ID_C from T_FILE f left join T_USER u on u.USE_ID_C = f.FIL_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
q = em.createNativeQuery("update T_FILE set FIL_DELETEDATE_D = :dateNow where FIL_ID_C in (select f.FIL_ID_C from T_FILE f left join T_USER u on u.USE_ID_C = f.FIL_IDUSER_C and u.USE_DELETEDATE_D is null where u.USE_ID_C is null)");
|
||||||
q.setParameter("dateNow", new Date());
|
q.setParameter("dateNow", new Date());
|
||||||
log.info("Deleting {} orphan files", q.executeUpdate());
|
log.info("Deleting {} orphan files", q.executeUpdate());
|
||||||
|
|
||||||
// Hard delete softly deleted data
|
// Hard delete softly deleted data
|
||||||
log.info("Deleting {} soft deleted document tag links", em.createQuery("delete DocumentTag where deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted document tag links", em.createQuery("delete DocumentTag where deleteDate is not null").executeUpdate());
|
||||||
log.info("Deleting {} soft deleted ACLs", em.createQuery("delete Acl where deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted ACLs", em.createQuery("delete Acl where deleteDate is not null").executeUpdate());
|
||||||
@@ -713,7 +743,7 @@ public class AppResource extends BaseResource {
|
|||||||
log.info("Deleting {} soft deleted documents", em.createQuery("delete Document where deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted documents", em.createQuery("delete Document where deleteDate is not null").executeUpdate());
|
||||||
log.info("Deleting {} soft deleted users", em.createQuery("delete User where deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted users", em.createQuery("delete User where deleteDate is not null").executeUpdate());
|
||||||
log.info("Deleting {} soft deleted groups", em.createQuery("delete Group where deleteDate is not null").executeUpdate());
|
log.info("Deleting {} soft deleted groups", em.createQuery("delete Group where deleteDate is not null").executeUpdate());
|
||||||
|
|
||||||
// Always return OK
|
// Always return OK
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
.add("status", "ok");
|
.add("status", "ok");
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package com.sismics.docs.rest.resource;
|
package com.sismics.docs.rest.resource;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.sismics.docs.core.constant.AclType;
|
import com.sismics.docs.core.constant.AclType;
|
||||||
import com.sismics.docs.core.constant.ConfigType;
|
import com.sismics.docs.core.constant.ConfigType;
|
||||||
@@ -36,10 +34,10 @@ import com.sismics.docs.core.util.DocumentUtil;
|
|||||||
import com.sismics.docs.core.util.FileUtil;
|
import com.sismics.docs.core.util.FileUtil;
|
||||||
import com.sismics.docs.core.util.MetadataUtil;
|
import com.sismics.docs.core.util.MetadataUtil;
|
||||||
import com.sismics.docs.core.util.PdfUtil;
|
import com.sismics.docs.core.util.PdfUtil;
|
||||||
import com.sismics.docs.core.util.TagUtil;
|
|
||||||
import com.sismics.docs.core.util.jpa.PaginatedList;
|
import com.sismics.docs.core.util.jpa.PaginatedList;
|
||||||
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
import com.sismics.docs.core.util.jpa.PaginatedLists;
|
||||||
import com.sismics.docs.core.util.jpa.SortCriteria;
|
import com.sismics.docs.core.util.jpa.SortCriteria;
|
||||||
|
import com.sismics.docs.rest.util.DocumentSearchCriteriaUtil;
|
||||||
import com.sismics.rest.exception.ClientException;
|
import com.sismics.rest.exception.ClientException;
|
||||||
import com.sismics.rest.exception.ForbiddenClientException;
|
import com.sismics.rest.exception.ForbiddenClientException;
|
||||||
import com.sismics.rest.exception.ServerException;
|
import com.sismics.rest.exception.ServerException;
|
||||||
@@ -57,6 +55,7 @@ import jakarta.ws.rs.Consumes;
|
|||||||
import jakarta.ws.rs.DELETE;
|
import jakarta.ws.rs.DELETE;
|
||||||
import jakarta.ws.rs.FormParam;
|
import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.HEAD;
|
||||||
import jakarta.ws.rs.NotFoundException;
|
import jakarta.ws.rs.NotFoundException;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.PUT;
|
import jakarta.ws.rs.PUT;
|
||||||
@@ -69,11 +68,6 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
|
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.joda.time.DateTime;
|
|
||||||
import org.joda.time.format.DateTimeFormat;
|
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
|
||||||
import org.joda.time.format.DateTimeFormatterBuilder;
|
|
||||||
import org.joda.time.format.DateTimeParser;
|
|
||||||
|
|
||||||
import javax.mail.Message;
|
import javax.mail.Message;
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
@@ -97,26 +91,12 @@ import java.util.UUID;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Document REST resources.
|
* Document REST resources.
|
||||||
*
|
*
|
||||||
* @author bgamard
|
* @author bgamard
|
||||||
*/
|
*/
|
||||||
@Path("/document")
|
@Path("/document")
|
||||||
public class DocumentResource extends BaseResource {
|
public class DocumentResource extends BaseResource {
|
||||||
|
|
||||||
protected static final DateTimeParser YEAR_PARSER = DateTimeFormat.forPattern("yyyy").getParser();
|
|
||||||
protected static final DateTimeParser MONTH_PARSER = DateTimeFormat.forPattern("yyyy-MM").getParser();
|
|
||||||
protected static final DateTimeParser DAY_PARSER = DateTimeFormat.forPattern("yyyy-MM-dd").getParser();
|
|
||||||
|
|
||||||
private static final DateTimeFormatter DAY_FORMATTER = new DateTimeFormatter(null, DAY_PARSER);
|
|
||||||
private static final DateTimeFormatter MONTH_FORMATTER = new DateTimeFormatter(null, MONTH_PARSER);
|
|
||||||
private static final DateTimeFormatter YEAR_FORMATTER = new DateTimeFormatter(null, YEAR_PARSER);
|
|
||||||
|
|
||||||
private static final DateTimeParser[] DATE_PARSERS = new DateTimeParser[]{
|
|
||||||
YEAR_PARSER,
|
|
||||||
MONTH_PARSER,
|
|
||||||
DAY_PARSER};
|
|
||||||
private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().append( null, DATE_PARSERS).toFormatter();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a document.
|
* Returns a document.
|
||||||
*
|
*
|
||||||
@@ -124,8 +104,8 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @apiName GetDocument
|
* @apiName GetDocument
|
||||||
* @apiGroup Document
|
* @apiGroup Document
|
||||||
* @apiParam {String} id Document ID
|
* @apiParam {String} id Document ID
|
||||||
* @apiParam {String} share Share ID
|
* @apiParam {String} [share] Share ID
|
||||||
* @apiParam {Booleans} files If true includes files information
|
* @apiParam {Boolean} [files] If true includes files information
|
||||||
* @apiSuccess {String} id ID
|
* @apiSuccess {String} id ID
|
||||||
* @apiSuccess {String} title Title
|
* @apiSuccess {String} title Title
|
||||||
* @apiSuccess {String} description Description
|
* @apiSuccess {String} description Description
|
||||||
@@ -147,6 +127,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @apiSuccess {String} coverage Coverage
|
* @apiSuccess {String} coverage Coverage
|
||||||
* @apiSuccess {String} rights Rights
|
* @apiSuccess {String} rights Rights
|
||||||
* @apiSuccess {String} creator Username of the creator
|
* @apiSuccess {String} creator Username of the creator
|
||||||
|
* @apiSuccess {String} file_id Main file ID
|
||||||
* @apiSuccess {Boolean} writable True if the document is writable by the current user
|
* @apiSuccess {Boolean} writable True if the document is writable by the current user
|
||||||
* @apiSuccess {Object[]} acls List of ACL
|
* @apiSuccess {Object[]} acls List of ACL
|
||||||
* @apiSuccess {String} acls.id ID
|
* @apiSuccess {String} acls.id ID
|
||||||
@@ -198,22 +179,24 @@ public class DocumentResource extends BaseResource {
|
|||||||
@QueryParam("share") String shareId,
|
@QueryParam("share") String shareId,
|
||||||
@QueryParam("files") Boolean files) {
|
@QueryParam("files") Boolean files) {
|
||||||
authenticate();
|
authenticate();
|
||||||
|
|
||||||
DocumentDao documentDao = new DocumentDao();
|
DocumentDao documentDao = new DocumentDao();
|
||||||
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
||||||
if (documentDto == null) {
|
if (documentDto == null) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObjectBuilder document = Json.createObjectBuilder()
|
JsonObjectBuilder document = createDocumentObjectBuilder(documentDto)
|
||||||
.add("id", documentDto.getId())
|
.add("creator", documentDto.getCreator())
|
||||||
.add("title", documentDto.getTitle())
|
.add("coverage", JsonUtil.nullable(documentDto.getCoverage()))
|
||||||
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
.add("file_count", documentDto.getFileCount())
|
||||||
.add("create_date", documentDto.getCreateTimestamp())
|
.add("format", JsonUtil.nullable(documentDto.getFormat()))
|
||||||
.add("update_date", documentDto.getUpdateTimestamp())
|
.add("identifier", JsonUtil.nullable(documentDto.getIdentifier()))
|
||||||
.add("language", documentDto.getLanguage())
|
.add("publisher", JsonUtil.nullable(documentDto.getPublisher()))
|
||||||
.add("shared", documentDto.getShared())
|
.add("rights", JsonUtil.nullable(documentDto.getRights()))
|
||||||
.add("file_count", documentDto.getFileCount());
|
.add("source", JsonUtil.nullable(documentDto.getSource()))
|
||||||
|
.add("subject", JsonUtil.nullable(documentDto.getSubject()))
|
||||||
|
.add("type", JsonUtil.nullable(documentDto.getType()));
|
||||||
|
|
||||||
List<TagDto> tagDtoList = null;
|
List<TagDto> tagDtoList = null;
|
||||||
if (principal.isAnonymous()) {
|
if (principal.isAnonymous()) {
|
||||||
@@ -227,26 +210,8 @@ public class DocumentResource extends BaseResource {
|
|||||||
.setTargetIdList(getTargetIdList(null)) // No tags for shares
|
.setTargetIdList(getTargetIdList(null)) // No tags for shares
|
||||||
.setDocumentId(documentId),
|
.setDocumentId(documentId),
|
||||||
new SortCriteria(1, true));
|
new SortCriteria(1, true));
|
||||||
JsonArrayBuilder tags = Json.createArrayBuilder();
|
document.add("tags", createTagsArrayBuilder(tagDtoList));
|
||||||
for (TagDto tagDto : tagDtoList) {
|
|
||||||
tags.add(Json.createObjectBuilder()
|
|
||||||
.add("id", tagDto.getId())
|
|
||||||
.add("name", tagDto.getName())
|
|
||||||
.add("color", tagDto.getColor()));
|
|
||||||
}
|
|
||||||
document.add("tags", tags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Below is specific to GET /document/id
|
|
||||||
document.add("subject", JsonUtil.nullable(documentDto.getSubject()));
|
|
||||||
document.add("identifier", JsonUtil.nullable(documentDto.getIdentifier()));
|
|
||||||
document.add("publisher", JsonUtil.nullable(documentDto.getPublisher()));
|
|
||||||
document.add("format", JsonUtil.nullable(documentDto.getFormat()));
|
|
||||||
document.add("source", JsonUtil.nullable(documentDto.getSource()));
|
|
||||||
document.add("type", JsonUtil.nullable(documentDto.getType()));
|
|
||||||
document.add("coverage", JsonUtil.nullable(documentDto.getCoverage()));
|
|
||||||
document.add("rights", JsonUtil.nullable(documentDto.getRights()));
|
|
||||||
document.add("creator", documentDto.getCreator());
|
|
||||||
|
|
||||||
// Add ACL
|
// Add ACL
|
||||||
AclUtil.addAcls(document, documentId, getTargetIdList(shareId));
|
AclUtil.addAcls(document, documentId, getTargetIdList(shareId));
|
||||||
@@ -270,7 +235,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
}
|
}
|
||||||
document.add("inherited_acls", aclList);
|
document.add("inherited_acls", aclList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add contributors
|
// Add contributors
|
||||||
ContributorDao contributorDao = new ContributorDao();
|
ContributorDao contributorDao = new ContributorDao();
|
||||||
List<ContributorDto> contributorDtoList = contributorDao.getByDocumentId(documentId);
|
List<ContributorDto> contributorDtoList = contributorDao.getByDocumentId(documentId);
|
||||||
@@ -281,7 +246,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
.add("email", contributorDto.getEmail()));
|
.add("email", contributorDto.getEmail()));
|
||||||
}
|
}
|
||||||
document.add("contributors", contributorList);
|
document.add("contributors", contributorList);
|
||||||
|
|
||||||
// Add relations
|
// Add relations
|
||||||
RelationDao relationDao = new RelationDao();
|
RelationDao relationDao = new RelationDao();
|
||||||
List<RelationDto> relationDtoList = relationDao.getByDocumentId(documentId);
|
List<RelationDto> relationDtoList = relationDao.getByDocumentId(documentId);
|
||||||
@@ -320,7 +285,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
|
|
||||||
return Response.ok().entity(document.build()).build();
|
return Response.ok().entity(document.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export a document to PDF.
|
* Export a document to PDF.
|
||||||
*
|
*
|
||||||
@@ -330,7 +295,6 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @apiParam {String} id Document ID
|
* @apiParam {String} id Document ID
|
||||||
* @apiParam {String} share Share ID
|
* @apiParam {String} share Share ID
|
||||||
* @apiParam {Boolean} metadata If true, export metadata
|
* @apiParam {Boolean} metadata If true, export metadata
|
||||||
* @apiParam {Boolean} comments If true, export comments
|
|
||||||
* @apiParam {Boolean} fitimagetopage If true, fit the images to pages
|
* @apiParam {Boolean} fitimagetopage If true, fit the images to pages
|
||||||
* @apiParam {Number} margin Margin around the pages, in millimeter
|
* @apiParam {Number} margin Margin around the pages, in millimeter
|
||||||
* @apiSuccess {String} pdf The whole response is the PDF file
|
* @apiSuccess {String} pdf The whole response is the PDF file
|
||||||
@@ -342,7 +306,6 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @param documentId Document ID
|
* @param documentId Document ID
|
||||||
* @param shareId Share ID
|
* @param shareId Share ID
|
||||||
* @param metadata Export metadata
|
* @param metadata Export metadata
|
||||||
* @param comments Export comments
|
|
||||||
* @param fitImageToPage Fit images to page
|
* @param fitImageToPage Fit images to page
|
||||||
* @param marginStr Margins
|
* @param marginStr Margins
|
||||||
* @return Response
|
* @return Response
|
||||||
@@ -353,21 +316,20 @@ public class DocumentResource extends BaseResource {
|
|||||||
@PathParam("id") String documentId,
|
@PathParam("id") String documentId,
|
||||||
@QueryParam("share") String shareId,
|
@QueryParam("share") String shareId,
|
||||||
final @QueryParam("metadata") Boolean metadata,
|
final @QueryParam("metadata") Boolean metadata,
|
||||||
final @QueryParam("comments") Boolean comments,
|
|
||||||
final @QueryParam("fitimagetopage") Boolean fitImageToPage,
|
final @QueryParam("fitimagetopage") Boolean fitImageToPage,
|
||||||
@QueryParam("margin") String marginStr) {
|
@QueryParam("margin") String marginStr) {
|
||||||
authenticate();
|
authenticate();
|
||||||
|
|
||||||
// Validate input
|
// Validate input
|
||||||
final int margin = ValidationUtil.validateInteger(marginStr, "margin");
|
final int margin = ValidationUtil.validateInteger(marginStr, "margin");
|
||||||
|
|
||||||
// Get document and check read permission
|
// Get document and check read permission
|
||||||
DocumentDao documentDao = new DocumentDao();
|
DocumentDao documentDao = new DocumentDao();
|
||||||
final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
final DocumentDto documentDto = documentDao.getDocument(documentId, PermType.READ, getTargetIdList(shareId));
|
||||||
if (documentDto == null) {
|
if (documentDto == null) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get files
|
// Get files
|
||||||
FileDao fileDao = new FileDao();
|
FileDao fileDao = new FileDao();
|
||||||
UserDao userDao = new UserDao();
|
UserDao userDao = new UserDao();
|
||||||
@@ -378,7 +340,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
User user = userDao.getById(file.getUserId());
|
User user = userDao.getById(file.getUserId());
|
||||||
file.setPrivateKey(user.getPrivateKey());
|
file.setPrivateKey(user.getPrivateKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to PDF
|
// Convert to PDF
|
||||||
StreamingOutput stream = outputStream -> {
|
StreamingOutput stream = outputStream -> {
|
||||||
try {
|
try {
|
||||||
@@ -393,19 +355,36 @@ public class DocumentResource extends BaseResource {
|
|||||||
.header("Content-Disposition", "inline; filename=\"" + documentDto.getTitle() + ".pdf\"")
|
.header("Content-Disposition", "inline; filename=\"" + documentDto.getTitle() + ".pdf\"")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all documents.
|
* Returns all documents, if a parameter is considered invalid, the search result will be empty.
|
||||||
*
|
*
|
||||||
* @api {get} /document/list Get documents
|
* @api {get} /document/list Get documents
|
||||||
* @apiName GetDocumentList
|
* @apiName GetDocumentList
|
||||||
* @apiGroup Document
|
* @apiGroup Document
|
||||||
* @apiParam {String} limit Total number of documents to return
|
*
|
||||||
* @apiParam {String} offset Start at this index
|
* @apiParam {String} [limit] Total number of documents to return (default is <code>10</code>)
|
||||||
* @apiParam {Number} sort_column Column index to sort on
|
* @apiParam {String} [offset] Start at this index (default is <code>0</code>)
|
||||||
* @apiParam {Boolean} asc If true, sort in ascending order
|
* @apiParam {Number} [sort_column] Column index to sort on
|
||||||
* @apiParam {String} search Search query (see "Document search syntax" on the top of the page for explanations)
|
* @apiParam {Boolean} [asc] If <code>true</code> sorts in ascending order
|
||||||
* @apiParam {Booleans} files If true includes files information
|
* @apiParam {String} [search] Search query (see "Document search syntax" on the top of the page for explanations) when the input is entered by a human.
|
||||||
|
* @apiParam {Boolean} [files] If <code>true</code> includes files information
|
||||||
|
*
|
||||||
|
* @apiParam {String} [search[after]] The document must have been created after or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||||
|
* @apiParam {String} [search[before]] The document must have been created before or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||||
|
* @apiParam {String} [search[by]] The document must have been created by the specified creator's username with an exact match, the user must not be deleted
|
||||||
|
* @apiParam {String} [search[full]] Used as a search criteria for all fields including the document's files content, several comma-separated values can be specified and the document must match any of them
|
||||||
|
* @apiParam {String} [search[lang]] The document must be of the specified language (example: <code>en</code>)
|
||||||
|
* @apiParam {String} [search[mime]] The document must be of the specified mime type (example: <code>image/png</code>)
|
||||||
|
* @apiParam {String} [search[simple]] Used as a search criteria for all fields except the document's files content, several comma-separated values can be specified and the document must match any of them
|
||||||
|
* @apiParam {Boolean} [search[shared]] If <code>true</code> the document must be shared, else it is ignored
|
||||||
|
* @apiParam {String} [search[tag]] The document must contain a tag or a child of a tag that starts with the value, case is ignored, several comma-separated values can be specified and the document must match all tag filters
|
||||||
|
* @apiParam {String} [search[nottag]] The document must not contain a tag or a child of a tag that starts with the value, case is ignored, several comma-separated values can be specified and the document must match all tag filters
|
||||||
|
* @apiParam {String} [search[title]] The document's title must be the value, several comma-separated values can be specified and the document must match any of the titles
|
||||||
|
* @apiParam {String} [search[uafter]] The document must have been updated after or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||||
|
* @apiParam {String} [search[ubefore]] The document must have been updated before or at the value moment, accepted format is <code>yyyy-MM-dd</code>
|
||||||
|
* @apiParam {String} [search[workflow]] If the value is <code>me</code> the document must have an active route, for other values the criteria is ignored
|
||||||
|
*
|
||||||
* @apiSuccess {Number} total Total number of documents
|
* @apiSuccess {Number} total Total number of documents
|
||||||
* @apiSuccess {Object[]} documents List of documents
|
* @apiSuccess {Object[]} documents List of documents
|
||||||
* @apiSuccess {String} documents.id ID
|
* @apiSuccess {String} documents.id ID
|
||||||
@@ -431,6 +410,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @apiSuccess {String} documents.files.mimetype MIME type
|
* @apiSuccess {String} documents.files.mimetype MIME type
|
||||||
* @apiSuccess {String} documents.files.create_date Create date (timestamp)
|
* @apiSuccess {String} documents.files.create_date Create date (timestamp)
|
||||||
* @apiSuccess {String[]} suggestions List of search suggestions
|
* @apiSuccess {String[]} suggestions List of search suggestions
|
||||||
|
*
|
||||||
* @apiError (client) ForbiddenError Access denied
|
* @apiError (client) ForbiddenError Access denied
|
||||||
* @apiError (server) SearchError Error searching in documents
|
* @apiError (server) SearchError Error searching in documents
|
||||||
* @apiPermission user
|
* @apiPermission user
|
||||||
@@ -452,19 +432,56 @@ public class DocumentResource extends BaseResource {
|
|||||||
@QueryParam("sort_column") Integer sortColumn,
|
@QueryParam("sort_column") Integer sortColumn,
|
||||||
@QueryParam("asc") Boolean asc,
|
@QueryParam("asc") Boolean asc,
|
||||||
@QueryParam("search") String search,
|
@QueryParam("search") String search,
|
||||||
@QueryParam("files") Boolean files) {
|
@QueryParam("files") Boolean files,
|
||||||
|
|
||||||
|
@QueryParam("search[after]") String searchCreatedAfter,
|
||||||
|
@QueryParam("search[before]") String searchCreatedBefore,
|
||||||
|
@QueryParam("search[by]") String searchBy,
|
||||||
|
@QueryParam("search[full]") String searchFull,
|
||||||
|
@QueryParam("search[lang]") String searchLang,
|
||||||
|
@QueryParam("search[mime]") String searchMime,
|
||||||
|
@QueryParam("search[shared]") Boolean searchShared,
|
||||||
|
@QueryParam("search[simple]") String searchSimple,
|
||||||
|
@QueryParam("search[tag]") String searchTag,
|
||||||
|
@QueryParam("search[nottag]") String searchTagNot,
|
||||||
|
@QueryParam("search[title]") String searchTitle,
|
||||||
|
@QueryParam("search[uafter]") String searchUpdatedAfter,
|
||||||
|
@QueryParam("search[ubefore]") String searchUpdatedBefore,
|
||||||
|
@QueryParam("search[searchworkflow]") String searchWorkflow
|
||||||
|
) {
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder();
|
JsonObjectBuilder response = Json.createObjectBuilder();
|
||||||
JsonArrayBuilder documents = Json.createArrayBuilder();
|
JsonArrayBuilder documents = Json.createArrayBuilder();
|
||||||
|
|
||||||
TagDao tagDao = new TagDao();
|
TagDao tagDao = new TagDao();
|
||||||
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(limit, offset);
|
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(limit, offset);
|
||||||
List<String> suggestionList = Lists.newArrayList();
|
List<String> suggestionList = Lists.newArrayList();
|
||||||
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
||||||
DocumentCriteria documentCriteria = parseSearchQuery(search);
|
|
||||||
|
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), null);
|
||||||
|
|
||||||
|
DocumentCriteria documentCriteria = DocumentSearchCriteriaUtil.parseSearchQuery(search, allTagDtoList);
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
searchBy,
|
||||||
|
searchCreatedAfter,
|
||||||
|
searchCreatedBefore,
|
||||||
|
searchFull,
|
||||||
|
searchLang,
|
||||||
|
searchMime,
|
||||||
|
searchShared,
|
||||||
|
searchSimple,
|
||||||
|
searchTag,
|
||||||
|
searchTagNot,
|
||||||
|
searchTitle,
|
||||||
|
searchUpdatedAfter,
|
||||||
|
searchUpdatedBefore,
|
||||||
|
searchWorkflow,
|
||||||
|
allTagDtoList);
|
||||||
|
|
||||||
documentCriteria.setTargetIdList(getTargetIdList(null));
|
documentCriteria.setTargetIdList(getTargetIdList(null));
|
||||||
try {
|
try {
|
||||||
AppContext.getInstance().getIndexingHandler().findByCriteria(paginatedList, suggestionList, documentCriteria, sortCriteria);
|
AppContext.getInstance().getIndexingHandler().findByCriteria(paginatedList, suggestionList, documentCriteria, sortCriteria);
|
||||||
@@ -488,13 +505,6 @@ public class DocumentResource extends BaseResource {
|
|||||||
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria()
|
List<TagDto> tagDtoList = tagDao.findByCriteria(new TagCriteria()
|
||||||
.setTargetIdList(getTargetIdList(null))
|
.setTargetIdList(getTargetIdList(null))
|
||||||
.setDocumentId(documentDto.getId()), new SortCriteria(1, true));
|
.setDocumentId(documentDto.getId()), new SortCriteria(1, true));
|
||||||
JsonArrayBuilder tags = Json.createArrayBuilder();
|
|
||||||
for (TagDto tagDto : tagDtoList) {
|
|
||||||
tags.add(Json.createObjectBuilder()
|
|
||||||
.add("id", tagDto.getId())
|
|
||||||
.add("name", tagDto.getName())
|
|
||||||
.add("color", tagDto.getColor()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Long filesCount;
|
Long filesCount;
|
||||||
Collection<File> filesOfDocument = null;
|
Collection<File> filesOfDocument = null;
|
||||||
@@ -506,20 +516,13 @@ public class DocumentResource extends BaseResource {
|
|||||||
filesCount = filesCountByDocument.getOrDefault(documentDto.getId(), 0L);
|
filesCount = filesCountByDocument.getOrDefault(documentDto.getId(), 0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonObjectBuilder documentObjectBuilder = Json.createObjectBuilder()
|
JsonObjectBuilder documentObjectBuilder = createDocumentObjectBuilder(documentDto)
|
||||||
.add("id", documentDto.getId())
|
|
||||||
.add("highlight", JsonUtil.nullable(documentDto.getHighlight()))
|
|
||||||
.add("file_id", JsonUtil.nullable(documentDto.getFileId()))
|
|
||||||
.add("title", documentDto.getTitle())
|
|
||||||
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
|
||||||
.add("create_date", documentDto.getCreateTimestamp())
|
|
||||||
.add("update_date", documentDto.getUpdateTimestamp())
|
|
||||||
.add("language", documentDto.getLanguage())
|
|
||||||
.add("shared", documentDto.getShared())
|
|
||||||
.add("active_route", documentDto.isActiveRoute())
|
.add("active_route", documentDto.isActiveRoute())
|
||||||
.add("current_step_name", JsonUtil.nullable(documentDto.getCurrentStepName()))
|
.add("current_step_name", JsonUtil.nullable(documentDto.getCurrentStepName()))
|
||||||
|
.add("highlight", JsonUtil.nullable(documentDto.getHighlight()))
|
||||||
.add("file_count", filesCount)
|
.add("file_count", filesCount)
|
||||||
.add("tags", tags);
|
.add("tags", createTagsArrayBuilder(tagDtoList));
|
||||||
|
|
||||||
if (Boolean.TRUE == files) {
|
if (Boolean.TRUE == files) {
|
||||||
JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
|
JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
|
||||||
for (File fileDb : filesOfDocument) {
|
for (File fileDb : filesOfDocument) {
|
||||||
@@ -538,7 +541,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
response.add("total", paginatedList.getResultCount())
|
response.add("total", paginatedList.getResultCount())
|
||||||
.add("documents", documents)
|
.add("documents", documents)
|
||||||
.add("suggestions", suggestions);
|
.add("suggestions", suggestions);
|
||||||
|
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,188 +570,44 @@ public class DocumentResource extends BaseResource {
|
|||||||
@FormParam("sort_column") Integer sortColumn,
|
@FormParam("sort_column") Integer sortColumn,
|
||||||
@FormParam("asc") Boolean asc,
|
@FormParam("asc") Boolean asc,
|
||||||
@FormParam("search") String search,
|
@FormParam("search") String search,
|
||||||
@FormParam("files") Boolean files) {
|
@FormParam("files") Boolean files,
|
||||||
return list(limit, offset, sortColumn, asc, search, files);
|
@FormParam("search[after]") String searchCreatedAfter,
|
||||||
}
|
@FormParam("search[before]") String searchCreatedBefore,
|
||||||
|
@FormParam("search[by]") String searchBy,
|
||||||
/**
|
@FormParam("search[full]") String searchFull,
|
||||||
* Parse a query according to the specified syntax, eg.:
|
@FormParam("search[lang]") String searchLang,
|
||||||
* tag:assurance tag:other before:2012 after:2011-09 shared:yes lang:fra thing
|
@FormParam("search[mime]") String searchMime,
|
||||||
*
|
@FormParam("search[shared]") Boolean searchShared,
|
||||||
* @param search Search query
|
@FormParam("search[simple]") String searchSimple,
|
||||||
* @return DocumentCriteria
|
@FormParam("search[tag]") String searchTag,
|
||||||
*/
|
@FormParam("search[nottag]") String searchTagNot,
|
||||||
private DocumentCriteria parseSearchQuery(String search) {
|
@FormParam("search[title]") String searchTitle,
|
||||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
@FormParam("search[uafter]") String searchUpdatedAfter,
|
||||||
if (Strings.isNullOrEmpty(search)) {
|
@FormParam("search[ubefore]") String searchUpdatedBefore,
|
||||||
return documentCriteria;
|
@FormParam("search[searchworkflow]") String searchWorkflow
|
||||||
}
|
) {
|
||||||
|
return list(
|
||||||
TagDao tagDao = new TagDao();
|
limit,
|
||||||
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria().setTargetIdList(getTargetIdList(null)), null);
|
offset,
|
||||||
UserDao userDao = new UserDao();
|
sortColumn,
|
||||||
|
asc,
|
||||||
String[] criteriaList = search.split(" +");
|
search,
|
||||||
List<String> query = new ArrayList<>();
|
files,
|
||||||
List<String> fullQuery = new ArrayList<>();
|
searchCreatedAfter,
|
||||||
for (String criteria : criteriaList) {
|
searchCreatedBefore,
|
||||||
String[] params = criteria.split(":");
|
searchBy,
|
||||||
if (params.length != 2 || Strings.isNullOrEmpty(params[0]) || Strings.isNullOrEmpty(params[1])) {
|
searchFull,
|
||||||
// This is not a special criteria, do a fulltext search on it
|
searchLang,
|
||||||
fullQuery.add(criteria);
|
searchMime,
|
||||||
continue;
|
searchShared,
|
||||||
}
|
searchSimple,
|
||||||
String paramName = params[0];
|
searchTag,
|
||||||
String paramValue = params[1];
|
searchTagNot,
|
||||||
|
searchTitle,
|
||||||
switch (paramName) {
|
searchUpdatedAfter,
|
||||||
case "tag":
|
searchUpdatedBefore,
|
||||||
case "!tag":
|
searchWorkflow
|
||||||
// New tag criteria
|
);
|
||||||
List<TagDto> tagDtoList = TagUtil.findByName(paramValue, allTagDtoList);
|
|
||||||
if (tagDtoList.isEmpty()) {
|
|
||||||
// No tag found, the request must return nothing
|
|
||||||
documentCriteria.getTagIdList().add(Lists.newArrayList(UUID.randomUUID().toString()));
|
|
||||||
} else {
|
|
||||||
List<String> tagIdList = Lists.newArrayList();
|
|
||||||
for (TagDto tagDto : tagDtoList) {
|
|
||||||
tagIdList.add(tagDto.getId());
|
|
||||||
List<TagDto> childrenTagDtoList = TagUtil.findChildren(tagDto, allTagDtoList);
|
|
||||||
for (TagDto childrenTagDto : childrenTagDtoList) {
|
|
||||||
tagIdList.add(childrenTagDto.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (paramName.startsWith("!")) {
|
|
||||||
documentCriteria.getExcludedTagIdList().add(tagIdList);
|
|
||||||
} else {
|
|
||||||
documentCriteria.getTagIdList().add(tagIdList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "after":
|
|
||||||
case "before":
|
|
||||||
case "uafter":
|
|
||||||
case "ubefore":
|
|
||||||
// New date span criteria
|
|
||||||
try {
|
|
||||||
boolean isUpdated = paramName.startsWith("u");
|
|
||||||
DateTime date = DATE_FORMATTER.parseDateTime(paramValue);
|
|
||||||
if (paramName.endsWith("before")) {
|
|
||||||
if (isUpdated) documentCriteria.setUpdateDateMax(date.toDate());
|
|
||||||
else documentCriteria.setCreateDateMax(date.toDate());
|
|
||||||
} else {
|
|
||||||
if (isUpdated) documentCriteria.setUpdateDateMin(date.toDate());
|
|
||||||
else documentCriteria.setCreateDateMin(date.toDate());
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// Invalid date, returns no documents
|
|
||||||
documentCriteria.setCreateDateMin(new Date(0));
|
|
||||||
documentCriteria.setCreateDateMax(new Date(0));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "uat":
|
|
||||||
case "at":
|
|
||||||
// New specific date criteria
|
|
||||||
boolean isUpdated = params[0].startsWith("u");
|
|
||||||
try {
|
|
||||||
switch (paramValue.length()) {
|
|
||||||
case 10: {
|
|
||||||
DateTime date = DATE_FORMATTER.parseDateTime(params[1]);
|
|
||||||
if (isUpdated) {
|
|
||||||
documentCriteria.setUpdateDateMin(date.toDate());
|
|
||||||
documentCriteria.setUpdateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
|
||||||
} else {
|
|
||||||
documentCriteria.setCreateDateMin(date.toDate());
|
|
||||||
documentCriteria.setCreateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 7: {
|
|
||||||
DateTime date = MONTH_FORMATTER.parseDateTime(params[1]);
|
|
||||||
if (isUpdated) {
|
|
||||||
documentCriteria.setUpdateDateMin(date.toDate());
|
|
||||||
documentCriteria.setUpdateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
|
||||||
} else {
|
|
||||||
documentCriteria.setCreateDateMin(date.toDate());
|
|
||||||
documentCriteria.setCreateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 4: {
|
|
||||||
DateTime date = YEAR_FORMATTER.parseDateTime(params[1]);
|
|
||||||
if (isUpdated) {
|
|
||||||
documentCriteria.setUpdateDateMin(date.toDate());
|
|
||||||
documentCriteria.setUpdateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
|
||||||
} else {
|
|
||||||
documentCriteria.setCreateDateMin(date.toDate());
|
|
||||||
documentCriteria.setCreateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
// Invalid format, returns no documents
|
|
||||||
documentCriteria.setCreateDateMin(new Date(0));
|
|
||||||
documentCriteria.setCreateDateMax(new Date(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// Invalid date, returns no documents
|
|
||||||
documentCriteria.setCreateDateMin(new Date(0));
|
|
||||||
documentCriteria.setCreateDateMax(new Date(0));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "shared":
|
|
||||||
// New shared state criteria
|
|
||||||
documentCriteria.setShared(paramValue.equals("yes"));
|
|
||||||
break;
|
|
||||||
case "lang":
|
|
||||||
// New language criteria
|
|
||||||
if (Constants.SUPPORTED_LANGUAGES.contains(paramValue)) {
|
|
||||||
documentCriteria.setLanguage(paramValue);
|
|
||||||
} else {
|
|
||||||
// Unsupported language, returns no documents
|
|
||||||
documentCriteria.setLanguage(UUID.randomUUID().toString());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "mime":
|
|
||||||
// New mime type criteria
|
|
||||||
documentCriteria.setMimeType(paramValue);
|
|
||||||
break;
|
|
||||||
case "by":
|
|
||||||
// New creator criteria
|
|
||||||
User user = userDao.getActiveByUsername(paramValue);
|
|
||||||
if (user == null) {
|
|
||||||
// This user doesn't exist, return nothing
|
|
||||||
documentCriteria.setCreatorId(UUID.randomUUID().toString());
|
|
||||||
} else {
|
|
||||||
// This user exists, search its documents
|
|
||||||
documentCriteria.setCreatorId(user.getId());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "workflow":
|
|
||||||
// New shared state criteria
|
|
||||||
documentCriteria.setActiveRoute(paramValue.equals("me"));
|
|
||||||
break;
|
|
||||||
case "simple":
|
|
||||||
// New simple search criteria
|
|
||||||
query.add(paramValue);
|
|
||||||
break;
|
|
||||||
case "full":
|
|
||||||
// New fulltext search criteria
|
|
||||||
fullQuery.add(paramValue);
|
|
||||||
break;
|
|
||||||
case "title":
|
|
||||||
// New title criteria
|
|
||||||
documentCriteria.getTitleList().add(paramValue);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fullQuery.add(criteria);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
documentCriteria.setSearch(Joiner.on(" ").join(query));
|
|
||||||
documentCriteria.setFullSearch(Joiner.on(" ").join(fullQuery));
|
|
||||||
return documentCriteria;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -818,7 +677,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate input data
|
// Validate input data
|
||||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||||
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
||||||
@@ -882,7 +741,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
.add("id", document.getId());
|
.add("id", document.getId());
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the document.
|
* Updates the document.
|
||||||
*
|
*
|
||||||
@@ -904,7 +763,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @apiParam {String[]} [relations] List of related documents ID
|
* @apiParam {String[]} [relations] List of related documents ID
|
||||||
* @apiParam {String[]} [metadata_id] List of metadata ID
|
* @apiParam {String[]} [metadata_id] List of metadata ID
|
||||||
* @apiParam {String[]} [metadata_value] List of metadata values
|
* @apiParam {String[]} [metadata_value] List of metadata values
|
||||||
* @apiParam {String} language Language
|
* @apiParam {String} [language] Language
|
||||||
* @apiParam {Number} [create_date] Create date (timestamp)
|
* @apiParam {Number} [create_date] Create date (timestamp)
|
||||||
* @apiSuccess {String} id Document ID
|
* @apiSuccess {String} id Document ID
|
||||||
* @apiError (client) ForbiddenError Access denied or document not writable
|
* @apiError (client) ForbiddenError Access denied or document not writable
|
||||||
@@ -940,7 +799,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate input data
|
// Validate input data
|
||||||
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
title = ValidationUtil.validateLength(title, "title", 1, 100, false);
|
||||||
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
language = ValidationUtil.validateLength(language, "language", 3, 7, false);
|
||||||
@@ -957,20 +816,20 @@ public class DocumentResource extends BaseResource {
|
|||||||
if (language != null && !Constants.SUPPORTED_LANGUAGES.contains(language)) {
|
if (language != null && !Constants.SUPPORTED_LANGUAGES.contains(language)) {
|
||||||
throw new ClientException("ValidationError", MessageFormat.format("{0} is not a supported language", language));
|
throw new ClientException("ValidationError", MessageFormat.format("{0} is not a supported language", language));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check write permission
|
// Check write permission
|
||||||
AclDao aclDao = new AclDao();
|
AclDao aclDao = new AclDao();
|
||||||
if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
|
if (!aclDao.checkPermission(id, PermType.WRITE, getTargetIdList(null))) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the document
|
// Get the document
|
||||||
DocumentDao documentDao = new DocumentDao();
|
DocumentDao documentDao = new DocumentDao();
|
||||||
Document document = documentDao.getById(id);
|
Document document = documentDao.getById(id);
|
||||||
if (document == null) {
|
if (document == null) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the document
|
// Update the document
|
||||||
document.setTitle(title);
|
document.setTitle(title);
|
||||||
document.setDescription(description);
|
document.setDescription(description);
|
||||||
@@ -988,12 +847,12 @@ public class DocumentResource extends BaseResource {
|
|||||||
} else {
|
} else {
|
||||||
document.setCreateDate(createDate);
|
document.setCreateDate(createDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
documentDao.update(document, principal.getId());
|
documentDao.update(document, principal.getId());
|
||||||
|
|
||||||
// Update tags
|
// Update tags
|
||||||
updateTagList(id, tagList);
|
updateTagList(id, tagList);
|
||||||
|
|
||||||
// Update relations
|
// Update relations
|
||||||
updateRelationList(id, relationList);
|
updateRelationList(id, relationList);
|
||||||
|
|
||||||
@@ -1009,7 +868,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
documentUpdatedAsyncEvent.setUserId(principal.getId());
|
documentUpdatedAsyncEvent.setUserId(principal.getId());
|
||||||
documentUpdatedAsyncEvent.setDocumentId(id);
|
documentUpdatedAsyncEvent.setDocumentId(id);
|
||||||
ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent);
|
ThreadLocalContext.get().addAsyncEvent(documentUpdatedAsyncEvent);
|
||||||
|
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
.add("id", id);
|
.add("id", id);
|
||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
@@ -1144,7 +1003,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
List<File> fileList = fileDao.getByDocumentId(principal.getId(), id);
|
List<File> fileList = fileDao.getByDocumentId(principal.getId(), id);
|
||||||
|
|
||||||
// Delete the document
|
// Delete the document
|
||||||
documentDao.delete(id, principal.getId());
|
documentDao.delete(id, principal.getId());
|
||||||
|
|
||||||
@@ -1162,7 +1021,7 @@ public class DocumentResource extends BaseResource {
|
|||||||
documentDeletedAsyncEvent.setUserId(principal.getId());
|
documentDeletedAsyncEvent.setUserId(principal.getId());
|
||||||
documentDeletedAsyncEvent.setDocumentId(id);
|
documentDeletedAsyncEvent.setDocumentId(id);
|
||||||
ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent);
|
ThreadLocalContext.get().addAsyncEvent(documentDeletedAsyncEvent);
|
||||||
|
|
||||||
// Always return OK
|
// Always return OK
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||||
.add("status", "ok");
|
.add("status", "ok");
|
||||||
@@ -1215,4 +1074,27 @@ public class DocumentResource extends BaseResource {
|
|||||||
relationDao.updateRelationList(documentId, documentIdSet);
|
relationDao.updateRelationList(documentId, documentIdSet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JsonObjectBuilder createDocumentObjectBuilder(DocumentDto documentDto) {
|
||||||
|
return Json.createObjectBuilder()
|
||||||
|
.add("create_date", documentDto.getCreateTimestamp())
|
||||||
|
.add("description", JsonUtil.nullable(documentDto.getDescription()))
|
||||||
|
.add("file_id", JsonUtil.nullable(documentDto.getFileId()))
|
||||||
|
.add("id", documentDto.getId())
|
||||||
|
.add("language", documentDto.getLanguage())
|
||||||
|
.add("shared", documentDto.getShared())
|
||||||
|
.add("title", documentDto.getTitle())
|
||||||
|
.add("update_date", documentDto.getUpdateTimestamp());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonArrayBuilder createTagsArrayBuilder(List<TagDto> tagDtoList) {
|
||||||
|
JsonArrayBuilder tags = Json.createArrayBuilder();
|
||||||
|
for (TagDto tagDto : tagDtoList) {
|
||||||
|
tags.add(Json.createObjectBuilder()
|
||||||
|
.add("id", tagDto.getId())
|
||||||
|
.add("name", tagDto.getName())
|
||||||
|
.add("color", tagDto.getColor()));
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ public class FileResource extends BaseResource {
|
|||||||
* This resource accepts only multipart/form-data.
|
* This resource accepts only multipart/form-data.
|
||||||
* @apiName PutFile
|
* @apiName PutFile
|
||||||
* @apiGroup File
|
* @apiGroup File
|
||||||
* @apiParam {String} id Document ID
|
* @apiParam {String} [id] Document ID
|
||||||
* @apiParam {String} previousFileId ID of the file to replace by this new version
|
* @apiParam {String} [previousFileId] ID of the file to replace by this new version
|
||||||
* @apiParam {String} file File data
|
* @apiParam {String} file File data
|
||||||
* @apiSuccess {String} status Status OK
|
* @apiSuccess {String} status Status OK
|
||||||
* @apiSuccess {String} id File ID
|
* @apiSuccess {String} id File ID
|
||||||
@@ -390,8 +390,8 @@ public class FileResource extends BaseResource {
|
|||||||
* @api {get} /file/list Get files
|
* @api {get} /file/list Get files
|
||||||
* @apiName GetFileList
|
* @apiName GetFileList
|
||||||
* @apiGroup File
|
* @apiGroup File
|
||||||
* @apiParam {String} id Document ID
|
* @apiParam {String} [id] Document ID
|
||||||
* @apiParam {String} share Share ID
|
* @apiParam {String} [share] Share ID
|
||||||
* @apiSuccess {Object[]} files List of files
|
* @apiSuccess {Object[]} files List of files
|
||||||
* @apiSuccess {String} files.id ID
|
* @apiSuccess {String} files.id ID
|
||||||
* @apiSuccess {String} files.processing True if the file is currently processing
|
* @apiSuccess {String} files.processing True if the file is currently processing
|
||||||
@@ -497,7 +497,6 @@ public class FileResource extends BaseResource {
|
|||||||
* @apiName DeleteFile
|
* @apiName DeleteFile
|
||||||
* @apiGroup File
|
* @apiGroup File
|
||||||
* @apiParam {String} id File ID
|
* @apiParam {String} id File ID
|
||||||
* @apiParam {String} share Share ID
|
|
||||||
* @apiSuccess {String} status Status OK
|
* @apiSuccess {String} status Status OK
|
||||||
* @apiError (client) ForbiddenError Access denied
|
* @apiError (client) ForbiddenError Access denied
|
||||||
* @apiError (client) NotFound File or document not found
|
* @apiError (client) NotFound File or document not found
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ public class GroupResource extends BaseResource {
|
|||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{groupName: [a-zA-Z0-9_]+}/{username: [a-zA-Z0-9_@\\.]+}")
|
@Path("{groupName: [a-zA-Z0-9_]+}/{username: [a-zA-Z0-9_@.-]+}")
|
||||||
public Response removeMember(@PathParam("groupName") String groupName,
|
public Response removeMember(@PathParam("groupName") String groupName,
|
||||||
@PathParam("username") String username) {
|
@PathParam("username") String username) {
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ import com.sismics.util.context.ThreadLocalContext;
|
|||||||
import com.sismics.util.filter.TokenBasedSecurityFilter;
|
import com.sismics.util.filter.TokenBasedSecurityFilter;
|
||||||
import com.sismics.util.totp.GoogleAuthenticator;
|
import com.sismics.util.totp.GoogleAuthenticator;
|
||||||
import com.sismics.util.totp.GoogleAuthenticatorKey;
|
import com.sismics.util.totp.GoogleAuthenticatorKey;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import jakarta.json.Json;
|
import jakarta.json.Json;
|
||||||
import jakarta.json.JsonArrayBuilder;
|
import jakarta.json.JsonArrayBuilder;
|
||||||
import jakarta.json.JsonObjectBuilder;
|
import jakarta.json.JsonObjectBuilder;
|
||||||
@@ -40,6 +38,8 @@ import jakarta.ws.rs.*;
|
|||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.NewCookie;
|
import jakarta.ws.rs.core.NewCookie;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -195,7 +195,7 @@ public class UserResource extends BaseResource {
|
|||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("{username: [a-zA-Z0-9_@\\.]+}")
|
@Path("{username: [a-zA-Z0-9_@.-]+}")
|
||||||
public Response update(
|
public Response update(
|
||||||
@PathParam("username") String username,
|
@PathParam("username") String username,
|
||||||
@FormParam("password") String password,
|
@FormParam("password") String password,
|
||||||
@@ -256,39 +256,6 @@ public class UserResource extends BaseResource {
|
|||||||
return Response.ok().entity(response.build()).build();
|
return Response.ok().entity(response.build()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a username is available.
|
|
||||||
* Search only on active accounts.
|
|
||||||
*
|
|
||||||
* @api {get} /user/check_username Check username availability
|
|
||||||
* @apiName GetUserCheckUsername
|
|
||||||
* @apiGroup User
|
|
||||||
* @apiParam {String} username Username
|
|
||||||
* @apiSuccess {String} status Status OK or KO
|
|
||||||
* @apiPermission none
|
|
||||||
* @apiVersion 1.5.0
|
|
||||||
*
|
|
||||||
* @param username Username to check
|
|
||||||
* @return Response
|
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@Path("check_username")
|
|
||||||
public Response checkUsername(
|
|
||||||
@QueryParam("username") String username) {
|
|
||||||
UserDao userDao = new UserDao();
|
|
||||||
User user = userDao.getActiveByUsername(username);
|
|
||||||
|
|
||||||
JsonObjectBuilder response = Json.createObjectBuilder();
|
|
||||||
if (user != null) {
|
|
||||||
response.add("status", "ko")
|
|
||||||
.add("message", "Username already registered");
|
|
||||||
} else {
|
|
||||||
response.add("status", "ok");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Response.ok().entity(response.build()).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This resource is used to authenticate the user and create a user session.
|
* This resource is used to authenticate the user and create a user session.
|
||||||
* The "session" is only used to identify the user, no other data is stored in the session.
|
* The "session" is only used to identify the user, no other data is stored in the session.
|
||||||
@@ -497,7 +464,7 @@ public class UserResource extends BaseResource {
|
|||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{username: [a-zA-Z0-9_@\\.]+}")
|
@Path("{username: [a-zA-Z0-9_@.-]+}")
|
||||||
public Response delete(@PathParam("username") String username) {
|
public Response delete(@PathParam("username") String username) {
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
@@ -563,7 +530,7 @@ public class UserResource extends BaseResource {
|
|||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
@POST
|
@POST
|
||||||
@Path("{username: [a-zA-Z0-9_@\\.]+}/disable_totp")
|
@Path("{username: [a-zA-Z0-9_@.-]+}/disable_totp")
|
||||||
public Response disableTotpUsername(@PathParam("username") String username) {
|
public Response disableTotpUsername(@PathParam("username") String username) {
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
@@ -685,7 +652,7 @@ public class UserResource extends BaseResource {
|
|||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Path("{username: [a-zA-Z0-9_@\\.]+}")
|
@Path("{username: [a-zA-Z0-9_@.-]+}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Response view(@PathParam("username") String username) {
|
public Response view(@PathParam("username") String username) {
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
|
|||||||
@@ -0,0 +1,318 @@
|
|||||||
|
package com.sismics.docs.rest.util;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.sismics.docs.core.constant.Constants;
|
||||||
|
import com.sismics.docs.core.dao.UserDao;
|
||||||
|
import com.sismics.docs.core.dao.criteria.DocumentCriteria;
|
||||||
|
import com.sismics.docs.core.dao.dto.TagDto;
|
||||||
|
import com.sismics.docs.core.model.jpa.User;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.format.DateTimeFormat;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.joda.time.format.DateTimeFormatterBuilder;
|
||||||
|
import org.joda.time.format.DateTimeParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DocumentSearchCriteriaUtil {
|
||||||
|
private static final DateTimeParser YEAR_PARSER = DateTimeFormat.forPattern("yyyy").getParser();
|
||||||
|
private static final DateTimeParser MONTH_PARSER = DateTimeFormat.forPattern("yyyy-MM").getParser();
|
||||||
|
private static final DateTimeParser DAY_PARSER = DateTimeFormat.forPattern("yyyy-MM-dd").getParser();
|
||||||
|
private static final DateTimeParser[] DATE_PARSERS = new DateTimeParser[]{
|
||||||
|
YEAR_PARSER,
|
||||||
|
MONTH_PARSER,
|
||||||
|
DAY_PARSER};
|
||||||
|
|
||||||
|
private static final DateTimeFormatter YEAR_FORMATTER = new DateTimeFormatter(null, YEAR_PARSER);
|
||||||
|
private static final DateTimeFormatter MONTH_FORMATTER = new DateTimeFormatter(null, MONTH_PARSER);
|
||||||
|
private static final DateTimeFormatter DAY_FORMATTER = new DateTimeFormatter(null, DAY_PARSER);
|
||||||
|
private static final DateTimeFormatter DATES_FORMATTER = new DateTimeFormatterBuilder().append(null, DATE_PARSERS).toFormatter();
|
||||||
|
|
||||||
|
private static final String PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR = ",";
|
||||||
|
private static final String WORKFLOW_ME = "me";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a query according to the specified syntax, eg.:
|
||||||
|
* tag:assurance tag:other before:2012 after:2011-09 shared:yes lang:fra thing
|
||||||
|
*
|
||||||
|
* @param search Search query
|
||||||
|
* @param allTagDtoList List of tags
|
||||||
|
* @return DocumentCriteria
|
||||||
|
*/
|
||||||
|
public static DocumentCriteria parseSearchQuery(String search, List<TagDto> allTagDtoList) {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
if (Strings.isNullOrEmpty(search)) {
|
||||||
|
return documentCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] criteriaList = search.split(" +");
|
||||||
|
List<String> simpleQuery = new ArrayList<>();
|
||||||
|
List<String> fullQuery = new ArrayList<>();
|
||||||
|
for (String criteria : criteriaList) {
|
||||||
|
String[] params = criteria.split(":");
|
||||||
|
if (params.length != 2 || Strings.isNullOrEmpty(params[0]) || Strings.isNullOrEmpty(params[1])) {
|
||||||
|
// This is not a special criteria, do a fulltext search on it
|
||||||
|
fullQuery.add(criteria);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String paramName = params[0];
|
||||||
|
String paramValue = params[1];
|
||||||
|
|
||||||
|
switch (paramName) {
|
||||||
|
case "tag":
|
||||||
|
case "!tag":
|
||||||
|
parseTagCriteria(documentCriteria, paramValue, allTagDtoList, paramName.startsWith("!"));
|
||||||
|
break;
|
||||||
|
case "after":
|
||||||
|
case "before":
|
||||||
|
case "uafter":
|
||||||
|
case "ubefore":
|
||||||
|
parseDateCriteria(documentCriteria, paramValue, DATES_FORMATTER, paramName.startsWith("u"), paramName.endsWith("before"));
|
||||||
|
break;
|
||||||
|
case "uat":
|
||||||
|
case "at":
|
||||||
|
parseDateAtCriteria(documentCriteria, paramValue, params[0].startsWith("u"));
|
||||||
|
break;
|
||||||
|
case "shared":
|
||||||
|
documentCriteria.setShared(paramValue.equals("yes"));
|
||||||
|
break;
|
||||||
|
case "lang":
|
||||||
|
parseLangCriteria(documentCriteria, paramValue);
|
||||||
|
break;
|
||||||
|
case "mime":
|
||||||
|
documentCriteria.setMimeType(paramValue);
|
||||||
|
break;
|
||||||
|
case "by":
|
||||||
|
parseByCriteria(documentCriteria, paramValue);
|
||||||
|
break;
|
||||||
|
case "workflow":
|
||||||
|
documentCriteria.setActiveRoute(paramValue.equals(WORKFLOW_ME));
|
||||||
|
break;
|
||||||
|
case "simple":
|
||||||
|
simpleQuery.add(paramValue);
|
||||||
|
break;
|
||||||
|
case "full":
|
||||||
|
fullQuery.add(paramValue);
|
||||||
|
break;
|
||||||
|
case "title":
|
||||||
|
documentCriteria.getTitleList().add(paramValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fullQuery.add(criteria);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
documentCriteria.setSimpleSearch(Joiner.on(" ").join(simpleQuery));
|
||||||
|
documentCriteria.setFullSearch(Joiner.on(" ").join(fullQuery));
|
||||||
|
return documentCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill the document criteria with various possible parameters
|
||||||
|
*
|
||||||
|
* @param documentCriteria structure to be filled
|
||||||
|
* @param searchBy author
|
||||||
|
* @param searchCreatedAfter creation moment after
|
||||||
|
* @param searchCreatedBefore creation moment before
|
||||||
|
* @param searchFull full search
|
||||||
|
* @param searchLang lang
|
||||||
|
* @param searchMime mime type
|
||||||
|
* @param searchShared share state
|
||||||
|
* @param searchSimple search in
|
||||||
|
* @param searchTag tags or parent tags
|
||||||
|
* @param searchNotTag tags or parent tags to ignore
|
||||||
|
* @param searchTitle title
|
||||||
|
* @param searchUpdatedAfter update moment after
|
||||||
|
* @param searchUpdatedBefore update moment before
|
||||||
|
* @param searchWorkflow exiting workflow
|
||||||
|
* @param allTagDtoList list of existing tags
|
||||||
|
*/
|
||||||
|
public static void addHttpSearchParams(
|
||||||
|
DocumentCriteria documentCriteria,
|
||||||
|
String searchBy,
|
||||||
|
String searchCreatedAfter,
|
||||||
|
String searchCreatedBefore,
|
||||||
|
String searchFull,
|
||||||
|
String searchLang,
|
||||||
|
String searchMime,
|
||||||
|
Boolean searchShared,
|
||||||
|
String searchSimple,
|
||||||
|
String searchTag,
|
||||||
|
String searchNotTag,
|
||||||
|
String searchTitle,
|
||||||
|
String searchUpdatedAfter,
|
||||||
|
String searchUpdatedBefore,
|
||||||
|
String searchWorkflow,
|
||||||
|
List<TagDto> allTagDtoList
|
||||||
|
) {
|
||||||
|
if (searchBy != null) {
|
||||||
|
parseByCriteria(documentCriteria, searchBy);
|
||||||
|
}
|
||||||
|
if (searchCreatedAfter != null) {
|
||||||
|
parseDateCriteria(documentCriteria, searchCreatedAfter, DAY_FORMATTER, false, false);
|
||||||
|
}
|
||||||
|
if (searchCreatedBefore != null) {
|
||||||
|
parseDateCriteria(documentCriteria, searchCreatedBefore, DAY_FORMATTER, false, true);
|
||||||
|
}
|
||||||
|
if (searchFull != null) {
|
||||||
|
documentCriteria.setFullSearch(Joiner.on(" ").join(searchFull.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||||
|
}
|
||||||
|
if (searchLang != null) {
|
||||||
|
parseLangCriteria(documentCriteria, searchLang);
|
||||||
|
}
|
||||||
|
if (searchMime != null) {
|
||||||
|
documentCriteria.setMimeType(searchMime);
|
||||||
|
}
|
||||||
|
if ((searchShared != null) && searchShared) {
|
||||||
|
documentCriteria.setShared(true);
|
||||||
|
}
|
||||||
|
if (searchSimple != null) {
|
||||||
|
documentCriteria.setSimpleSearch(Joiner.on(" ").join(searchSimple.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||||
|
}
|
||||||
|
if (searchTitle != null) {
|
||||||
|
documentCriteria.getTitleList().addAll(Arrays.asList(searchTitle.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)));
|
||||||
|
}
|
||||||
|
if (searchTag != null) {
|
||||||
|
for (String tag : searchTag.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)) {
|
||||||
|
parseTagCriteria(documentCriteria, tag, allTagDtoList, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (searchNotTag != null) {
|
||||||
|
for (String tag : searchNotTag.split(PARAMETER_WITH_MULTIPLE_VALUES_SEPARATOR)) {
|
||||||
|
parseTagCriteria(documentCriteria, tag, allTagDtoList, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (searchUpdatedAfter != null) {
|
||||||
|
parseDateCriteria(documentCriteria, searchUpdatedAfter, DAY_FORMATTER, true, false);
|
||||||
|
}
|
||||||
|
if (searchUpdatedBefore != null) {
|
||||||
|
parseDateCriteria(documentCriteria, searchUpdatedBefore, DAY_FORMATTER, true, true);
|
||||||
|
}
|
||||||
|
if ((WORKFLOW_ME.equals(searchWorkflow))) {
|
||||||
|
documentCriteria.setActiveRoute(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseDateCriteria(DocumentCriteria documentCriteria, String value, DateTimeFormatter formatter, boolean isUpdated, boolean isBefore) {
|
||||||
|
try {
|
||||||
|
DateTime date = formatter.parseDateTime(value);
|
||||||
|
if (isBefore) {
|
||||||
|
if (isUpdated) {
|
||||||
|
documentCriteria.setUpdateDateMax(date.toDate());
|
||||||
|
} else {
|
||||||
|
documentCriteria.setCreateDateMax(date.toDate());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isUpdated) {
|
||||||
|
documentCriteria.setUpdateDateMin(date.toDate());
|
||||||
|
} else {
|
||||||
|
documentCriteria.setCreateDateMin(date.toDate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Invalid date, returns no documents
|
||||||
|
documentCriteria.setCreateDateMin(new Date(0));
|
||||||
|
documentCriteria.setCreateDateMax(new Date(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseDateAtCriteria(DocumentCriteria documentCriteria, String value, boolean isUpdated) {
|
||||||
|
try {
|
||||||
|
switch (value.length()) {
|
||||||
|
case 10: {
|
||||||
|
DateTime date = DATES_FORMATTER.parseDateTime(value);
|
||||||
|
if (isUpdated) {
|
||||||
|
documentCriteria.setUpdateDateMin(date.toDate());
|
||||||
|
documentCriteria.setUpdateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||||
|
} else {
|
||||||
|
documentCriteria.setCreateDateMin(date.toDate());
|
||||||
|
documentCriteria.setCreateDateMax(date.plusDays(1).minusSeconds(1).toDate());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7: {
|
||||||
|
DateTime date = MONTH_FORMATTER.parseDateTime(value);
|
||||||
|
if (isUpdated) {
|
||||||
|
documentCriteria.setUpdateDateMin(date.toDate());
|
||||||
|
documentCriteria.setUpdateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||||
|
} else {
|
||||||
|
documentCriteria.setCreateDateMin(date.toDate());
|
||||||
|
documentCriteria.setCreateDateMax(date.plusMonths(1).minusSeconds(1).toDate());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
DateTime date = YEAR_FORMATTER.parseDateTime(value);
|
||||||
|
if (isUpdated) {
|
||||||
|
documentCriteria.setUpdateDateMin(date.toDate());
|
||||||
|
documentCriteria.setUpdateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||||
|
} else {
|
||||||
|
documentCriteria.setCreateDateMin(date.toDate());
|
||||||
|
documentCriteria.setCreateDateMax(date.plusYears(1).minusSeconds(1).toDate());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// Invalid format, returns no documents
|
||||||
|
documentCriteria.setCreateDateMin(new Date(0));
|
||||||
|
documentCriteria.setCreateDateMax(new Date(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// Invalid date, returns no documents
|
||||||
|
documentCriteria.setCreateDateMin(new Date(0));
|
||||||
|
documentCriteria.setCreateDateMax(new Date(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseTagCriteria(DocumentCriteria documentCriteria, String value, List<TagDto> allTagDtoList, boolean exclusion) {
|
||||||
|
List<TagDto> tagDtoList = TagUtil.findByName(value, allTagDtoList);
|
||||||
|
if (tagDtoList.isEmpty()) {
|
||||||
|
// No tag found, the request must return nothing
|
||||||
|
documentCriteria.getTagIdList().add(Lists.newArrayList(UUID.randomUUID().toString()));
|
||||||
|
} else {
|
||||||
|
List<String> tagIdList = Lists.newArrayList();
|
||||||
|
for (TagDto tagDto : tagDtoList) {
|
||||||
|
tagIdList.add(tagDto.getId());
|
||||||
|
List<TagDto> childrenTagDtoList = TagUtil.findChildren(tagDto, allTagDtoList);
|
||||||
|
for (TagDto childrenTagDto : childrenTagDtoList) {
|
||||||
|
tagIdList.add(childrenTagDto.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exclusion) {
|
||||||
|
documentCriteria.getExcludedTagIdList().add(tagIdList);
|
||||||
|
} else {
|
||||||
|
documentCriteria.getTagIdList().add(tagIdList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseLangCriteria(DocumentCriteria documentCriteria, String value) {
|
||||||
|
// New language criteria
|
||||||
|
if (Constants.SUPPORTED_LANGUAGES.contains(value)) {
|
||||||
|
documentCriteria.setLanguage(value);
|
||||||
|
} else {
|
||||||
|
// Unsupported language, returns no documents
|
||||||
|
documentCriteria.setLanguage(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void parseByCriteria(DocumentCriteria documentCriteria, String value) {
|
||||||
|
User user = new UserDao().getActiveByUsername(value);
|
||||||
|
if (user == null) {
|
||||||
|
// This user doesn't exist, return nothing
|
||||||
|
documentCriteria.setCreatorId(UUID.randomUUID().toString());
|
||||||
|
} else {
|
||||||
|
// This user exists, search its documents
|
||||||
|
documentCriteria.setCreatorId(user.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.sismics.docs.core.util;
|
package com.sismics.docs.rest.util;
|
||||||
|
|
||||||
import com.sismics.docs.core.dao.dto.TagDto;
|
import com.sismics.docs.core.dao.dto.TagDto;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,10 +40,10 @@ public class TagUtil {
|
|||||||
* @return List of filtered tags
|
* @return List of filtered tags
|
||||||
*/
|
*/
|
||||||
public static List<TagDto> findByName(String name, List<TagDto> allTagDtoList) {
|
public static List<TagDto> findByName(String name, List<TagDto> allTagDtoList) {
|
||||||
List<TagDto> tagDtoList = new ArrayList<>();
|
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
return tagDtoList;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
List<TagDto> tagDtoList = new ArrayList<>();
|
||||||
name = name.toLowerCase();
|
name = name.toLowerCase();
|
||||||
for (TagDto tagDto : allTagDtoList) {
|
for (TagDto tagDto : allTagDtoList) {
|
||||||
if (tagDto.getName().toLowerCase().startsWith(name)) {
|
if (tagDto.getName().toLowerCase().startsWith(name)) {
|
||||||
@@ -44,6 +44,16 @@
|
|||||||
<async-supported>true</async-supported>
|
<async-supported>true</async-supported>
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>jwtBasedSecurityFilter</filter-name>
|
||||||
|
<filter-class>com.sismics.util.filter.JwtBasedSecurityFilter</filter-class>
|
||||||
|
<async-supported>true</async-supported>
|
||||||
|
<init-param>
|
||||||
|
<param-name>enabled</param-name>
|
||||||
|
<param-value>false</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
|
||||||
<filter>
|
<filter>
|
||||||
<filter-name>headerBasedSecurityFilter</filter-name>
|
<filter-name>headerBasedSecurityFilter</filter-name>
|
||||||
<filter-class>com.sismics.util.filter.HeaderBasedSecurityFilter</filter-class>
|
<filter-class>com.sismics.util.filter.HeaderBasedSecurityFilter</filter-class>
|
||||||
@@ -59,6 +69,11 @@
|
|||||||
<url-pattern>/api/*</url-pattern>
|
<url-pattern>/api/*</url-pattern>
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
|
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>jwtBasedSecurityFilter</filter-name>
|
||||||
|
<url-pattern>/api/*</url-pattern>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
<filter-mapping>
|
<filter-mapping>
|
||||||
<filter-name>headerBasedSecurityFilter</filter-name>
|
<filter-name>headerBasedSecurityFilter</filter-name>
|
||||||
<url-pattern>/api/*</url-pattern>
|
<url-pattern>/api/*</url-pattern>
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ curl -i -X POST -H "Cookie: auth_token=64085630-2ae6-415c-9a92-4b22c107eaa4" htt
|
|||||||
|
|
||||||
## Document search syntax
|
## Document search syntax
|
||||||
|
|
||||||
The `/api/document/list` endpoint use a String `search` parameter.
|
The `/api/document/list` endpoint use a String `search` parameter, useful when the query is entered by a human.
|
||||||
|
|
||||||
This parameter is split in segments using the space character (the other whitespace characters are not considered).
|
This parameter is split in segments using the space character (the other whitespace characters are not considered).
|
||||||
|
|
||||||
If a segment contains exactly one colon (`:`), it will used as a field criteria (see bellow).
|
If a segment contains exactly one colon (`:`), it will be used as a field criteria (see bellow).
|
||||||
In other cases (zero or more than one colon), the segment will be used as a search criteria for all fields including the document's files content.
|
In other cases (zero or more than one colon), the segment will be used as a search criteria for all fields including the document's files content.
|
||||||
|
|
||||||
### Search fields
|
### Search fields
|
||||||
@@ -69,7 +69,7 @@ If a search `VALUE` is considered invalid, the search result will be empty.
|
|||||||
* `at:VALUE`: the document must have been created at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
* `at:VALUE`: the document must have been created at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
||||||
* `before:VALUE`: the document must have been created before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
* `before:VALUE`: the document must have been created before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||||
* `uafter:VALUE`: the document must have been last updated after or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
* `uafter:VALUE`: the document must have been last updated after or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||||
* `at:VALUE`: the document must have been updated at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
* `uat:VALUE`: the document must have been updated at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd` (for `yyyy` it must be the same year, for `yyyy-MM` the same month, for `yyyy-MM-dd` the same day)
|
||||||
* `ubefore:VALUE`: the document must have been updated before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
* `ubefore:VALUE`: the document must have been updated before or at the `VALUE` moment, accepted format are `yyyy`, `yyyy-MM` and `yyyy-MM-dd`
|
||||||
* Language
|
* Language
|
||||||
* `lang:VALUE`: the document must be of the specified language (example: `en`)
|
* `lang:VALUE`: the document must be of the specified language (example: `en`)
|
||||||
|
|||||||
@@ -21,6 +21,15 @@ angular.module('docs').controller('SettingsConfig', function($scope, $rootScope,
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Enable/disable OCR
|
||||||
|
$scope.changeOcrEnabled = function (enabled) {
|
||||||
|
Restangular.one('app').post('ocr', {
|
||||||
|
enabled: enabled
|
||||||
|
}).then(function () {
|
||||||
|
$scope.app.ocr_enabled = enabled;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Fetch the current theme configuration
|
// Fetch the current theme configuration
|
||||||
Restangular.one('theme').get().then(function (data) {
|
Restangular.one('theme').get().then(function (data) {
|
||||||
$scope.theme = data;
|
$scope.theme = data;
|
||||||
@@ -36,7 +45,7 @@ angular.module('docs').controller('SettingsConfig', function($scope, $rootScope,
|
|||||||
$rootScope.appName = $scope.theme.name;
|
$rootScope.appName = $scope.theme.name;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send an image
|
// Send an image
|
||||||
$scope.sendingImage = false;
|
$scope.sendingImage = false;
|
||||||
$scope.sendImage = function (type, image) {
|
$scope.sendImage = function (type, image) {
|
||||||
@@ -108,4 +117,4 @@ angular.module('docs').controller('SettingsConfig', function($scope, $rootScope,
|
|||||||
$scope.loadWebhooks();
|
$scope.loadWebhooks();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,6 +4,15 @@
|
|||||||
* Share controller.
|
* Share controller.
|
||||||
*/
|
*/
|
||||||
angular.module('share').controller('Share', function($scope, $state, $stateParams, Restangular, $uibModal) {
|
angular.module('share').controller('Share', function($scope, $state, $stateParams, Restangular, $uibModal) {
|
||||||
|
$scope.displayMode = _.isUndefined(localStorage.fileDisplayMode) ? 'grid' : localStorage.fileDisplayMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watch for display mode change.
|
||||||
|
*/
|
||||||
|
$scope.$watch('displayMode', function (next) {
|
||||||
|
localStorage.fileDisplayMode = next;
|
||||||
|
});
|
||||||
|
|
||||||
// Load document
|
// Load document
|
||||||
Restangular.one('document', $stateParams.documentId).get({ share: $stateParams.shareId })
|
Restangular.one('document', $stateParams.documentId).get({ share: $stateParams.shareId })
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
|
|||||||
@@ -421,6 +421,10 @@
|
|||||||
"smtp_username": "SMTP-Benutzername",
|
"smtp_username": "SMTP-Benutzername",
|
||||||
"smtp_password": "SMTP-Passwort",
|
"smtp_password": "SMTP-Passwort",
|
||||||
"smtp_updated": "SMTP-Konfiguration erfolgreich aktualisiert",
|
"smtp_updated": "SMTP-Konfiguration erfolgreich aktualisiert",
|
||||||
|
"title_ocr": "Texterkennung (OCR)",
|
||||||
|
"message_ocr": "OCR ist eine Technologie, die es ermöglicht, Text aus Bildern zu extrahieren. Es wird verwendet, um den Inhalt von Bildern zu durchsuchen und zu indizieren. Diese Funktionalität setzt voraus, dass die Tesseract auf Ihrem Server installiert ist.",
|
||||||
|
"enable_ocr": "OCR aktivieren",
|
||||||
|
"disable_ocr": "OCR deaktivieren",
|
||||||
"webhooks": "Webhooks",
|
"webhooks": "Webhooks",
|
||||||
"webhooks_explain": "Webhooks werden aufgerufen, wenn das angegebene Ereignis eintritt. Die angegebene URL wird mit einer JSON-Payload gepostet, die den Ereignisnamen und die ID der betreffenden Ressource enthält.",
|
"webhooks_explain": "Webhooks werden aufgerufen, wenn das angegebene Ereignis eintritt. Die angegebene URL wird mit einer JSON-Payload gepostet, die den Ereignisnamen und die ID der betreffenden Ressource enthält.",
|
||||||
"webhook_event": "Ereignisse",
|
"webhook_event": "Ereignisse",
|
||||||
|
|||||||
@@ -421,6 +421,10 @@
|
|||||||
"smtp_username": "SMTP username",
|
"smtp_username": "SMTP username",
|
||||||
"smtp_password": "SMTP password",
|
"smtp_password": "SMTP password",
|
||||||
"smtp_updated": "SMTP configuration updated successfully",
|
"smtp_updated": "SMTP configuration updated successfully",
|
||||||
|
"title_ocr": "Optical Character Recognition (OCR)",
|
||||||
|
"message_ocr": "OCR is a feature that extracts text from images and PDF files. This feature requires a working Tesseract installation on the server.",
|
||||||
|
"enable_ocr": "Enable OCR",
|
||||||
|
"disable_ocr": "Disable OCR",
|
||||||
"webhooks": "Webhooks",
|
"webhooks": "Webhooks",
|
||||||
"webhooks_explain": "Webhooks will be called when the specified event occur. The given URL will be POST-ed with a JSON payload containing the event name and the ID of the concerned resource.",
|
"webhooks_explain": "Webhooks will be called when the specified event occur. The given URL will be POST-ed with a JSON payload containing the event name and the ID of the concerned resource.",
|
||||||
"webhook_event": "Event",
|
"webhook_event": "Event",
|
||||||
|
|||||||
@@ -77,12 +77,13 @@
|
|||||||
<span class="fas fa-spin fa-circle-notch"></span>
|
<span class="fas fa-spin fa-circle-notch"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a class="file-thumbnail" ng-click="openFile(file, $event)">
|
<a class="file-thumbnail" ng-click="openFile(file, $event)"
|
||||||
<img ng-src="../api/file/{{ file.id }}/data?size=thumb" uib-tooltip="{{ file.mimetype }} | {{ file.size | filesize }}" tooltip-placement="top" />
|
uib-tooltip="{{ file.mimetype }} | {{ file.size | filesize }}" tooltip-placement="top">
|
||||||
|
<img ng-src="../api/file/{{ file.id }}/data?size=thumb" />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="file-info">
|
<div class="file-info">
|
||||||
<div></div><!-- Actually useful -->
|
<div></div>
|
||||||
<div class="v-align file-name" ng-if="file.name" title="{{ file.name }} (v{{ file.version + 1 }}.0)">{{ file.name }}</div>
|
<div class="v-align file-name" ng-if="file.name" title="{{ file.name }} (v{{ file.version + 1 }}.0)">{{ file.name }}</div>
|
||||||
<div class="v-align" ng-show="document.writable">
|
<div class="v-align" ng-show="document.writable">
|
||||||
<div uib-dropdown>
|
<div uib-dropdown>
|
||||||
|
|||||||
@@ -31,6 +31,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
<span translate="settings.config.title_ocr"></span>
|
||||||
|
<span class="label" ng-class="{ 'label-success': app.ocr_enabled, 'label-danger': !app.ocr_enabled }">
|
||||||
|
{{ app.ocr_enabled ? 'enabled' : 'disabled' | translate }}
|
||||||
|
</h2>
|
||||||
|
<p translate="settings.config.message_ocr" translate-values="{ appName: appName }"></p>
|
||||||
|
<div ng-if="app">
|
||||||
|
<button ng-if="!app.ocr_enabled" class="btn btn-primary" ng-click="changeOcrEnabled(true)">{{ 'settings.config.enable_ocr' | translate }}</button>
|
||||||
|
<button ng-if="app.ocr_enabled" class="btn btn-danger" ng-click="changeOcrEnabled(false)">{{ 'settings.config.disable_ocr' | translate }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2 translate="settings.config.title_theme"></h2>
|
<h2 translate="settings.config.title_theme"></h2>
|
||||||
<form class="form-horizontal" name="editColorForm" novalidate>
|
<form class="form-horizontal" name="editColorForm" novalidate>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -196,4 +207,4 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<label class="col-sm-2 control-label" for="inputUserUsername">{{ 'settings.user.edit.username' | translate }}</label>
|
<label class="col-sm-2 control-label" for="inputUserUsername">{{ 'settings.user.edit.username' | translate }}</label>
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-7">
|
||||||
<input name="userUsername" type="text" id="inputUserUsername" required ng-disabled="isEdit()" class="form-control"
|
<input name="userUsername" type="text" id="inputUserUsername" required ng-disabled="isEdit()" class="form-control"
|
||||||
ng-pattern="/^[a-zA-Z0-9_@\.]*$/"
|
ng-pattern="/^[a-zA-Z0-9_@.-]*$/"
|
||||||
ng-minlength="3" ng-maxlength="50" ng-attr-placeholder="{{ 'settings.user.edit.username' | translate }}" ng-model="user.username"/>
|
ng-minlength="3" ng-maxlength="50" ng-attr-placeholder="{{ 'settings.user.edit.username' | translate }}" ng-model="user.username"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p ng-bind-html="document.description"></p>
|
<p class="well-sm" ng-bind-html="document.description"></p>
|
||||||
<dl class="dl-horizontal">
|
<dl class="dl-horizontal">
|
||||||
<dt ng-if="document.subject">{{ 'document.subject' | translate }}</dt>
|
<dt ng-if="document.subject">{{ 'document.subject' | translate }}</dt>
|
||||||
<dd ng-if="document.subject">{{ document.subject }}</dd>
|
<dd ng-if="document.subject">{{ document.subject }}</dd>
|
||||||
@@ -63,18 +63,80 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dt ng-if="false" ng-repeat-start="meta in document.metadata"></dt>
|
||||||
|
<dt ng-if="meta.value != null">{{ meta.name }}</dt>
|
||||||
|
<dd ng-if="meta.value != null && (meta.type == 'STRING' || meta.type == 'INTEGER' || meta.type == 'FLOAT')">{{ meta.value }}</dd>
|
||||||
|
<dd ng-if="meta.value != null && meta.type == 'DATE'">{{ meta.value | date: dateFormat }}</dd>
|
||||||
|
<dd ng-if="meta.value != null && meta.type == 'BOOLEAN'">{{ meta.value ? 'yes' : 'no' | translate }}</dd>
|
||||||
|
<dd ng-if="false" ng-repeat-end></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
<!-- Display mode (list or grid) -->
|
||||||
|
<div class="btn-group mt-10 mb-10 pull-right">
|
||||||
|
<span class="btn btn-default" ng-class="{ active: displayMode == 'list' }"
|
||||||
|
uib-tooltip="{{ 'document.view.content.display_mode_list' | translate }}"
|
||||||
|
tooltip-append-to-body="true"
|
||||||
|
ng-click="displayMode = 'list'">
|
||||||
|
<span class="fas fa-list"></span>
|
||||||
|
</span>
|
||||||
|
<span class="btn btn-default" ng-class="{ active: displayMode == 'grid' }"
|
||||||
|
uib-tooltip="{{ 'document.view.content.display_mode_grid' | translate }}"
|
||||||
|
tooltip-append-to-body="true"
|
||||||
|
ng-click="displayMode = 'grid'">
|
||||||
|
<span class="fas fa-th"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
|
||||||
|
<!-- List of files -->
|
||||||
<div class="row" ng-show="files.length > 0">
|
<div class="row" ng-show="files.length > 0">
|
||||||
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2 text-center" ng-repeat="file in files">
|
<!-- Grid view -->
|
||||||
<div class="thumbnail">
|
<div ng-show="displayMode == 'grid'">
|
||||||
<a ng-click="openFile(file)">
|
<div class="col-xs-6 col-sm-4 col-md-4 col-lg-3 text-center" ng-repeat="file in files">
|
||||||
<img ng-src="../api/file/{{ file.id }}/data?size=thumb&share={{ $stateParams.shareId }}"
|
<div class="thumbnail">
|
||||||
uib-tooltip="{{ file.mimetype }} | {{ file.size | filesize }}" tooltip-placement="top" />
|
<a class="file-thumbnail" ng-click="openFile(file)"
|
||||||
</a>
|
uib-tooltip="{{ file.mimetype }} | {{ file.size | filesize }}" tooltip-placement="top">
|
||||||
|
<img ng-src="../api/file/{{ file.id }}/data?size=thumb&share={{ $stateParams.shareId }}" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="file-info">
|
||||||
|
<div></div>
|
||||||
|
<div class="v-align file-name" ng-if="file.name" title="{{ file.name }} (v{{ file.version + 1 }}.0)">{{ file.name }}</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- List view -->
|
||||||
|
<table ng-show="displayMode == 'list'" class="table table-hover table-files">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th width="3%"></th>
|
||||||
|
<th>Filename</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Size</th>
|
||||||
|
<th width="10%">Version</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="file in files">
|
||||||
|
<td class="pointer" ng-click="openFile(file)">
|
||||||
|
<div class="thumbnail-list">
|
||||||
|
<img ng-src="../api/file/{{ file.id }}/data?size=thumb&share={{ $stateParams.shareId }}" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="pointer" ng-click="openFile(file)">
|
||||||
|
{{ file.name }}
|
||||||
|
</td>
|
||||||
|
<td>{{ file.mimetype }}</td>
|
||||||
|
<td>{{ file.size | filesize }}</td>
|
||||||
|
<td>v{{ file.version + 1 }}.0</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div ui-view="file"></div>
|
<div ui-view="file"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
api.current_version=${project.version}
|
api.current_version=${project.version}
|
||||||
api.min_version=1.0
|
api.min_version=1.0
|
||||||
db.version=30
|
db.version=31
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.sismics.docs.rest;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.dao.UserDao;
|
||||||
|
import com.sismics.docs.core.model.jpa.User;
|
||||||
|
import com.sismics.util.context.ThreadLocalContext;
|
||||||
|
import com.sismics.util.jpa.EMF;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import jakarta.persistence.EntityTransaction;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
public abstract class BaseTransactionalTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
// Initialize the entity manager
|
||||||
|
EntityManager em = EMF.get().createEntityManager();
|
||||||
|
ThreadLocalContext context = ThreadLocalContext.get();
|
||||||
|
context.setEntityManager(em);
|
||||||
|
em.getTransaction().begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
ThreadLocalContext.get().getEntityManager().getTransaction().rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected User createUser(String userName) throws Exception {
|
||||||
|
UserDao userDao = new UserDao();
|
||||||
|
User user = new User();
|
||||||
|
user.setUsername(userName);
|
||||||
|
user.setPassword("12345678");
|
||||||
|
user.setEmail("toto@docs.com");
|
||||||
|
user.setRoleId("admin");
|
||||||
|
user.setStorageQuota(100_000L);
|
||||||
|
userDao.create(user, userName);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,35 +1,52 @@
|
|||||||
package com.sismics.docs.rest;
|
package com.sismics.docs.rest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import com.google.common.io.Resources;
|
||||||
import com.icegreen.greenmail.util.GreenMail;
|
import com.icegreen.greenmail.util.GreenMail;
|
||||||
import com.icegreen.greenmail.util.GreenMailUtil;
|
import com.icegreen.greenmail.util.GreenMailUtil;
|
||||||
import com.icegreen.greenmail.util.ServerSetup;
|
import com.icegreen.greenmail.util.ServerSetup;
|
||||||
import com.sismics.docs.core.model.context.AppContext;
|
import com.sismics.docs.core.model.context.AppContext;
|
||||||
import com.sismics.util.filter.TokenBasedSecurityFilter;
|
import com.sismics.util.filter.TokenBasedSecurityFilter;
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import jakarta.json.JsonArray;
|
import jakarta.json.JsonArray;
|
||||||
import jakarta.json.JsonObject;
|
import jakarta.json.JsonObject;
|
||||||
import jakarta.ws.rs.client.Entity;
|
import jakarta.ws.rs.client.Entity;
|
||||||
import jakarta.ws.rs.core.Form;
|
import jakarta.ws.rs.core.Form;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import jakarta.ws.rs.core.Response.Status;
|
import jakarta.ws.rs.core.Response.Status;
|
||||||
|
import org.apache.directory.api.ldap.model.name.Dn;
|
||||||
|
import org.apache.directory.server.core.api.DirectoryService;
|
||||||
|
import org.apache.directory.server.core.api.partition.Partition;
|
||||||
|
import org.apache.directory.server.core.factory.DefaultDirectoryServiceFactory;
|
||||||
|
import org.apache.directory.server.core.factory.DirectoryServiceFactory;
|
||||||
|
import org.apache.directory.server.core.partition.impl.avl.AvlPartition;
|
||||||
|
import org.apache.directory.server.ldap.LdapServer;
|
||||||
|
import org.apache.directory.server.protocol.shared.store.LdifFileLoader;
|
||||||
|
import org.apache.directory.server.protocol.shared.transport.TcpTransport;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the app resource.
|
* Test the app resource.
|
||||||
*
|
*
|
||||||
* @author jtremeaux
|
* @author jtremeaux
|
||||||
*/
|
*/
|
||||||
public class TestAppResource extends BaseJerseyTest {
|
public class TestAppResource extends BaseJerseyTest {
|
||||||
/**
|
/**
|
||||||
* Test the API resource.
|
* Test the API resource.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Record if config has been changed by previous test runs
|
||||||
|
private static boolean configInboxChanged = false;
|
||||||
|
private static boolean configSmtpChanged = false;
|
||||||
|
private static boolean configLdapChanged = false;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAppResource() {
|
public void testAppResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Check the application info
|
// Check the application info
|
||||||
JsonObject json = target().path("/app").request()
|
JsonObject json = target().path("/app").request()
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
@@ -41,6 +58,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory);
|
Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory);
|
||||||
Assert.assertEquals(0, json.getJsonNumber("queued_tasks").intValue());
|
Assert.assertEquals(0, json.getJsonNumber("queued_tasks").intValue());
|
||||||
Assert.assertFalse(json.getBoolean("guest_login"));
|
Assert.assertFalse(json.getBoolean("guest_login"));
|
||||||
|
Assert.assertFalse(json.getBoolean("ocr_enabled"));
|
||||||
Assert.assertEquals("eng", json.getString("default_language"));
|
Assert.assertEquals("eng", json.getString("default_language"));
|
||||||
Assert.assertTrue(json.containsKey("global_storage_current"));
|
Assert.assertTrue(json.containsKey("global_storage_current"));
|
||||||
Assert.assertTrue(json.getJsonNumber("active_user_count").longValue() > 0);
|
Assert.assertTrue(json.getJsonNumber("active_user_count").longValue() > 0);
|
||||||
@@ -50,13 +68,13 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.post(Entity.form(new Form()));
|
.post(Entity.form(new Form()));
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
|
|
||||||
// Clean storage
|
// Clean storage
|
||||||
response = target().path("/app/batch/clean_storage").request()
|
response = target().path("/app/batch/clean_storage").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.post(Entity.form(new Form()));
|
.post(Entity.form(new Form()));
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
|
|
||||||
// Change the default language
|
// Change the default language
|
||||||
response = target().path("/app/config").request()
|
response = target().path("/app/config").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
@@ -86,8 +104,8 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testLogResource() {
|
public void testLogResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Check the logs (page 1)
|
// Check the logs (page 1)
|
||||||
JsonObject json = target().path("/app/log")
|
JsonObject json = target().path("/app/log")
|
||||||
.queryParam("level", "DEBUG")
|
.queryParam("level", "DEBUG")
|
||||||
@@ -99,7 +117,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
Long date1 = logs.getJsonObject(0).getJsonNumber("date").longValue();
|
Long date1 = logs.getJsonObject(0).getJsonNumber("date").longValue();
|
||||||
Long date2 = logs.getJsonObject(9).getJsonNumber("date").longValue();
|
Long date2 = logs.getJsonObject(9).getJsonNumber("date").longValue();
|
||||||
Assert.assertTrue(date1 >= date2);
|
Assert.assertTrue(date1 >= date2);
|
||||||
|
|
||||||
// Check the logs (page 2)
|
// Check the logs (page 2)
|
||||||
json = target().path("/app/log")
|
json = target().path("/app/log")
|
||||||
.queryParam("offset", "10")
|
.queryParam("offset", "10")
|
||||||
@@ -120,7 +138,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGuestLogin() {
|
public void testGuestLogin() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Try to login as guest
|
// Try to login as guest
|
||||||
Response response = target().path("/user/login").request()
|
Response response = target().path("/user/login").request()
|
||||||
@@ -177,6 +195,43 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
target().path("/document/list").request()
|
target().path("/document/list").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, guestToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, guestToken)
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
|
|
||||||
|
// Disable guest login (clean up state)
|
||||||
|
target().path("/app/guest_login").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.post(Entity.form(new Form()
|
||||||
|
.param("enabled", "false")), JsonObject.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the ocr setting
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testOcrSetting() {
|
||||||
|
// Login admin
|
||||||
|
String adminToken = adminToken();
|
||||||
|
|
||||||
|
// Get OCR configuration
|
||||||
|
JsonObject json = target().path("/app/ocr").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.get(JsonObject.class);
|
||||||
|
if (!configInboxChanged) {
|
||||||
|
Assert.assertFalse(json.getBoolean("enabled"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change OCR configuration
|
||||||
|
target().path("/app/ocr").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.post(Entity.form(new Form()
|
||||||
|
.param("enabled", "true")
|
||||||
|
), JsonObject.class);
|
||||||
|
configInboxChanged = true;
|
||||||
|
|
||||||
|
// Get OCR configuration
|
||||||
|
json = target().path("/app/ocr").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.get(JsonObject.class);
|
||||||
|
Assert.assertTrue(json.getBoolean("enabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -185,17 +240,19 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testSmtpConfiguration() {
|
public void testSmtpConfiguration() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Get SMTP configuration
|
// Get SMTP configuration
|
||||||
JsonObject json = target().path("/app/config_smtp").request()
|
JsonObject json = target().path("/app/config_smtp").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
Assert.assertTrue(json.isNull("hostname"));
|
if (!configSmtpChanged) {
|
||||||
Assert.assertTrue(json.isNull("port"));
|
Assert.assertTrue(json.isNull("hostname"));
|
||||||
Assert.assertTrue(json.isNull("username"));
|
Assert.assertTrue(json.isNull("port"));
|
||||||
Assert.assertTrue(json.isNull("password"));
|
Assert.assertTrue(json.isNull("username"));
|
||||||
Assert.assertTrue(json.isNull("from"));
|
Assert.assertTrue(json.isNull("password"));
|
||||||
|
Assert.assertTrue(json.isNull("from"));
|
||||||
|
}
|
||||||
|
|
||||||
// Change SMTP configuration
|
// Change SMTP configuration
|
||||||
target().path("/app/config_smtp").request()
|
target().path("/app/config_smtp").request()
|
||||||
@@ -206,6 +263,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
.param("username", "sismics")
|
.param("username", "sismics")
|
||||||
.param("from", "contact@sismics.com")
|
.param("from", "contact@sismics.com")
|
||||||
), JsonObject.class);
|
), JsonObject.class);
|
||||||
|
configSmtpChanged = true;
|
||||||
|
|
||||||
// Get SMTP configuration
|
// Get SMTP configuration
|
||||||
json = target().path("/app/config_smtp").request()
|
json = target().path("/app/config_smtp").request()
|
||||||
@@ -224,7 +282,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testInbox() {
|
public void testInbox() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Create a tag
|
// Create a tag
|
||||||
JsonObject json = target().path("/tag").request()
|
JsonObject json = target().path("/tag").request()
|
||||||
@@ -238,23 +296,26 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
json = target().path("/app/config_inbox").request()
|
json = target().path("/app/config_inbox").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
Assert.assertFalse(json.getBoolean("enabled"));
|
|
||||||
Assert.assertEquals("", json.getString("hostname"));
|
|
||||||
Assert.assertEquals(993, json.getJsonNumber("port").intValue());
|
|
||||||
Assert.assertEquals("", json.getString("username"));
|
|
||||||
Assert.assertEquals("", json.getString("password"));
|
|
||||||
Assert.assertEquals("INBOX", json.getString("folder"));
|
|
||||||
Assert.assertEquals("", json.getString("tag"));
|
|
||||||
JsonObject lastSync = json.getJsonObject("last_sync");
|
JsonObject lastSync = json.getJsonObject("last_sync");
|
||||||
Assert.assertTrue(lastSync.isNull("date"));
|
if (!configInboxChanged) {
|
||||||
Assert.assertTrue(lastSync.isNull("error"));
|
Assert.assertFalse(json.getBoolean("enabled"));
|
||||||
Assert.assertEquals(0, lastSync.getJsonNumber("count").intValue());
|
Assert.assertEquals("", json.getString("hostname"));
|
||||||
|
Assert.assertEquals(993, json.getJsonNumber("port").intValue());
|
||||||
|
Assert.assertEquals("", json.getString("username"));
|
||||||
|
Assert.assertEquals("", json.getString("password"));
|
||||||
|
Assert.assertEquals("INBOX", json.getString("folder"));
|
||||||
|
Assert.assertEquals("", json.getString("tag"));
|
||||||
|
Assert.assertTrue(lastSync.isNull("date"));
|
||||||
|
Assert.assertTrue(lastSync.isNull("error"));
|
||||||
|
Assert.assertEquals(0, lastSync.getJsonNumber("count").intValue());
|
||||||
|
}
|
||||||
|
|
||||||
// Change inbox configuration
|
// Change inbox configuration
|
||||||
target().path("/app/config_inbox").request()
|
target().path("/app/config_inbox").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.post(Entity.form(new Form()
|
.post(Entity.form(new Form()
|
||||||
.param("enabled", "true")
|
.param("enabled", "true")
|
||||||
|
.param("starttls", "false")
|
||||||
.param("autoTagsEnabled", "false")
|
.param("autoTagsEnabled", "false")
|
||||||
.param("deleteImported", "false")
|
.param("deleteImported", "false")
|
||||||
.param("hostname", "localhost")
|
.param("hostname", "localhost")
|
||||||
@@ -264,6 +325,7 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
.param("folder", "INBOX")
|
.param("folder", "INBOX")
|
||||||
.param("tag", tagInboxId)
|
.param("tag", tagInboxId)
|
||||||
), JsonObject.class);
|
), JsonObject.class);
|
||||||
|
configInboxChanged = true;
|
||||||
|
|
||||||
// Get inbox configuration
|
// Get inbox configuration
|
||||||
json = target().path("/app/config_inbox").request()
|
json = target().path("/app/config_inbox").request()
|
||||||
@@ -340,89 +402,93 @@ public class TestAppResource extends BaseJerseyTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testLdapAuthentication() throws Exception {
|
public void testLdapAuthentication() throws Exception {
|
||||||
// // Start LDAP server
|
// Start LDAP server
|
||||||
// final DirectoryServiceFactory factory = new DefaultDirectoryServiceFactory();
|
final DirectoryServiceFactory factory = new DefaultDirectoryServiceFactory();
|
||||||
// factory.init("Test");
|
factory.init("Test");
|
||||||
//
|
|
||||||
// final DirectoryService directoryService = factory.getDirectoryService();
|
final DirectoryService directoryService = factory.getDirectoryService();
|
||||||
// directoryService.getChangeLog().setEnabled(false);
|
directoryService.getChangeLog().setEnabled(false);
|
||||||
// directoryService.setShutdownHookEnabled(true);
|
directoryService.setShutdownHookEnabled(true);
|
||||||
//
|
|
||||||
// final Partition partition = new AvlPartition(directoryService.getSchemaManager());
|
final Partition partition = new AvlPartition(directoryService.getSchemaManager());
|
||||||
// partition.setId("Test");
|
partition.setId("Test");
|
||||||
// partition.setSuffixDn(new Dn(directoryService.getSchemaManager(), "o=TEST"));
|
partition.setSuffixDn(new Dn(directoryService.getSchemaManager(), "o=TEST"));
|
||||||
// partition.initialize();
|
partition.initialize();
|
||||||
// directoryService.addPartition(partition);
|
directoryService.addPartition(partition);
|
||||||
//
|
|
||||||
// final LdapServer ldapServer = new LdapServer();
|
final LdapServer ldapServer = new LdapServer();
|
||||||
// ldapServer.setTransports(new TcpTransport("localhost", 11389));
|
ldapServer.setTransports(new TcpTransport("localhost", 11389));
|
||||||
// ldapServer.setDirectoryService(directoryService);
|
ldapServer.setDirectoryService(directoryService);
|
||||||
//
|
|
||||||
// directoryService.startup();
|
directoryService.startup();
|
||||||
// ldapServer.start();
|
ldapServer.start();
|
||||||
//
|
|
||||||
// // Load test data in LDAP
|
// Load test data in LDAP
|
||||||
// new LdifFileLoader(directoryService.getAdminSession(), new File(Resources.getResource("test.ldif").getFile()), null).execute();
|
new LdifFileLoader(directoryService.getAdminSession(), new File(Resources.getResource("test.ldif").getFile()), null).execute();
|
||||||
//
|
|
||||||
// // Login admin
|
// Login admin
|
||||||
// String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
//
|
|
||||||
// // Get the LDAP configuration
|
// Get the LDAP configuration
|
||||||
// JsonObject json = target().path("/app/config_ldap").request()
|
JsonObject json = target().path("/app/config_ldap").request()
|
||||||
// .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
// .get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
// Assert.assertFalse(json.getBoolean("enabled"));
|
if (!configLdapChanged) {
|
||||||
//
|
Assert.assertFalse(json.getBoolean("enabled"));
|
||||||
// // Change LDAP configuration
|
}
|
||||||
// target().path("/app/config_ldap").request()
|
|
||||||
// .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
// Change LDAP configuration
|
||||||
// .post(Entity.form(new Form()
|
target().path("/app/config_ldap").request()
|
||||||
// .param("enabled", "true")
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
// .param("host", "localhost")
|
.post(Entity.form(new Form()
|
||||||
// .param("port", "11389")
|
.param("enabled", "true")
|
||||||
// .param("admin_dn", "uid=admin,ou=system")
|
.param("host", "localhost")
|
||||||
// .param("admin_password", "secret")
|
.param("port", "11389")
|
||||||
// .param("base_dn", "o=TEST")
|
.param("usessl", "false")
|
||||||
// .param("filter", "(&(objectclass=inetOrgPerson)(uid=USERNAME))")
|
.param("admin_dn", "uid=admin,ou=system")
|
||||||
// .param("default_email", "devnull@teedy.io")
|
.param("admin_password", "secret")
|
||||||
// .param("default_storage", "100000000")
|
.param("base_dn", "o=TEST")
|
||||||
// ), JsonObject.class);
|
.param("filter", "(&(objectclass=inetOrgPerson)(uid=USERNAME))")
|
||||||
//
|
.param("default_email", "devnull@teedy.io")
|
||||||
// // Get the LDAP configuration
|
.param("default_storage", "100000000")
|
||||||
// json = target().path("/app/config_ldap").request()
|
), JsonObject.class);
|
||||||
// .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
configLdapChanged = true;
|
||||||
// .get(JsonObject.class);
|
|
||||||
// Assert.assertTrue(json.getBoolean("enabled"));
|
// Get the LDAP configuration
|
||||||
// Assert.assertEquals("localhost", json.getString("host"));
|
json = target().path("/app/config_ldap").request()
|
||||||
// Assert.assertEquals(11389, json.getJsonNumber("port").intValue());
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
// Assert.assertEquals("uid=admin,ou=system", json.getString("admin_dn"));
|
.get(JsonObject.class);
|
||||||
// Assert.assertEquals("secret", json.getString("admin_password"));
|
Assert.assertTrue(json.getBoolean("enabled"));
|
||||||
// Assert.assertEquals("o=TEST", json.getString("base_dn"));
|
Assert.assertEquals("localhost", json.getString("host"));
|
||||||
// Assert.assertEquals("(&(objectclass=inetOrgPerson)(uid=USERNAME))", json.getString("filter"));
|
Assert.assertEquals(11389, json.getJsonNumber("port").intValue());
|
||||||
// Assert.assertEquals("devnull@teedy.io", json.getString("default_email"));
|
Assert.assertEquals("uid=admin,ou=system", json.getString("admin_dn"));
|
||||||
// Assert.assertEquals(100000000L, json.getJsonNumber("default_storage").longValue());
|
Assert.assertEquals("secret", json.getString("admin_password"));
|
||||||
//
|
Assert.assertEquals("o=TEST", json.getString("base_dn"));
|
||||||
// // Login with a LDAP user
|
Assert.assertEquals("(&(objectclass=inetOrgPerson)(uid=USERNAME))", json.getString("filter"));
|
||||||
// String ldapTopen = clientUtil.login("ldap1", "secret", false);
|
Assert.assertEquals("devnull@teedy.io", json.getString("default_email"));
|
||||||
//
|
Assert.assertEquals(100000000L, json.getJsonNumber("default_storage").longValue());
|
||||||
// // Check user informations
|
|
||||||
// json = target().path("/user").request()
|
// Login with a LDAP user
|
||||||
// .cookie(TokenBasedSecurityFilter.COOKIE_NAME, ldapTopen)
|
String ldapTopen = clientUtil.login("ldap1", "secret", false);
|
||||||
// .get(JsonObject.class);
|
|
||||||
// Assert.assertEquals("ldap1@teedy.io", json.getString("email"));
|
// Check user informations
|
||||||
//
|
json = target().path("/user").request()
|
||||||
// // List all documents
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, ldapTopen)
|
||||||
// json = target().path("/document/list")
|
.get(JsonObject.class);
|
||||||
// .queryParam("sort_column", 3)
|
Assert.assertEquals("ldap1@teedy.io", json.getString("email"));
|
||||||
// .queryParam("asc", true)
|
|
||||||
// .request()
|
// List all documents
|
||||||
// .cookie(TokenBasedSecurityFilter.COOKIE_NAME, ldapTopen)
|
json = target().path("/document/list")
|
||||||
// .get(JsonObject.class);
|
.queryParam("sort_column", 3)
|
||||||
// JsonArray documents = json.getJsonArray("documents");
|
.queryParam("asc", true)
|
||||||
// Assert.assertEquals(0, documents.size());
|
.request()
|
||||||
//
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, ldapTopen)
|
||||||
// // Stop LDAP server
|
.get(JsonObject.class);
|
||||||
// ldapServer.stop();
|
JsonArray documents = json.getJsonArray("documents");
|
||||||
// directoryService.shutdown();
|
Assert.assertEquals(0, documents.size());
|
||||||
|
|
||||||
|
// Stop LDAP server
|
||||||
|
ldapServer.stop();
|
||||||
|
directoryService.shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ public class TestAuditLogResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(countByClass(logs, "Document"), 1);
|
Assert.assertEquals(countByClass(logs, "Document"), 1);
|
||||||
Assert.assertEquals(countByClass(logs, "Acl"), 2);
|
Assert.assertEquals(countByClass(logs, "Acl"), 2);
|
||||||
Assert.assertEquals(countByClass(logs, "File"), 1);
|
Assert.assertEquals(countByClass(logs, "File"), 1);
|
||||||
|
|
||||||
|
// Delete auditlog1
|
||||||
|
String adminToken = adminToken();
|
||||||
|
target().path("/user/auditlog1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
Assert.assertFalse(relations.getJsonObject(0).getBoolean("source"));
|
Assert.assertFalse(relations.getJsonObject(0).getBoolean("source"));
|
||||||
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
Assert.assertEquals("My super title document 2", relations.getJsonObject(0).getString("title"));
|
||||||
Assert.assertFalse(json.containsKey("files"));
|
Assert.assertFalse(json.containsKey("files"));
|
||||||
|
Assert.assertEquals(file1Id, json.getString("file_id"));
|
||||||
|
|
||||||
// Get document 2
|
// Get document 2
|
||||||
json = target().path("/document/" + document2Id).request()
|
json = target().path("/document/" + document2Id).request()
|
||||||
@@ -285,6 +286,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
Assert.assertTrue(relations.getJsonObject(0).getBoolean("source"));
|
Assert.assertTrue(relations.getJsonObject(0).getBoolean("source"));
|
||||||
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
Assert.assertEquals("My super title document 1", relations.getJsonObject(0).getString("title"));
|
||||||
Assert.assertFalse(json.containsKey("files"));
|
Assert.assertFalse(json.containsKey("files"));
|
||||||
|
Assert.assertEquals(file1Id, json.getString("file_id"));
|
||||||
|
|
||||||
// Create a tag
|
// Create a tag
|
||||||
json = target().path("/tag").request()
|
json = target().path("/tag").request()
|
||||||
@@ -818,7 +820,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCustomMetadata() {
|
public void testCustomMetadata() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Login metadata1
|
// Login metadata1
|
||||||
clientUtil.createUser("metadata1");
|
clientUtil.createUser("metadata1");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class TestGroupResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGroupResource() {
|
public void testGroupResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Create group hierarchy
|
// Create group hierarchy
|
||||||
clientUtil.createGroup("g1");
|
clientUtil.createGroup("g1");
|
||||||
@@ -188,5 +188,25 @@ public class TestGroupResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(2, groups.size());
|
Assert.assertEquals(2, groups.size());
|
||||||
Assert.assertTrue(groupList.contains("g11"));
|
Assert.assertTrue(groupList.contains("g11"));
|
||||||
Assert.assertTrue(groupList.contains("g112"));
|
Assert.assertTrue(groupList.contains("g112"));
|
||||||
|
|
||||||
|
// Delete all remaining groups and users
|
||||||
|
target().path("/group/g11").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete(JsonObject.class);
|
||||||
|
target().path("/group/g12new").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete(JsonObject.class);
|
||||||
|
target().path("/group/g111").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete(JsonObject.class);
|
||||||
|
target().path("/group/g112").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete(JsonObject.class);
|
||||||
|
target().path("/user/group1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
|
target().path("/user/admin2").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class TestMetadataResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testMetadataResource() {
|
public void testMetadataResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Get all metadata with admin
|
// Get all metadata with admin
|
||||||
JsonObject json = target().path("/metadata")
|
JsonObject json = target().path("/metadata")
|
||||||
@@ -79,4 +79,4 @@ public class TestMetadataResource extends BaseJerseyTest {
|
|||||||
metadata = json.getJsonArray("metadata");
|
metadata = json.getJsonArray("metadata");
|
||||||
Assert.assertEquals(0, metadata.size());
|
Assert.assertEquals(0, metadata.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class TestRouteModelResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testRouteModelResource() {
|
public void testRouteModelResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Login routeModel1
|
// Login routeModel1
|
||||||
clientUtil.createUser("routeModel1");
|
clientUtil.createUser("routeModel1");
|
||||||
@@ -137,5 +137,10 @@ public class TestRouteModelResource extends BaseJerseyTest {
|
|||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
routeModels = json.getJsonArray("routemodels");
|
routeModels = json.getJsonArray("routemodels");
|
||||||
Assert.assertEquals(1, routeModels.size());
|
Assert.assertEquals(1, routeModels.size());
|
||||||
|
|
||||||
|
// Deletes routeModel1 user
|
||||||
|
target().path("/user/routeModel1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class TestRouteResource extends BaseJerseyTest {
|
|||||||
String route1Token = clientUtil.login("route1");
|
String route1Token = clientUtil.login("route1");
|
||||||
|
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Change SMTP configuration to target Wiser
|
// Change SMTP configuration to target Wiser
|
||||||
target().path("/app/config_smtp").request()
|
target().path("/app/config_smtp").request()
|
||||||
@@ -364,7 +364,7 @@ public class TestRouteResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTagActions() {
|
public void testTagActions() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Create an Approved tag
|
// Create an Approved tag
|
||||||
JsonObject json = target().path("/tag").request()
|
JsonObject json = target().path("/tag").request()
|
||||||
@@ -511,4 +511,4 @@ public class TestRouteResource extends BaseJerseyTest {
|
|||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.delete(JsonObject.class);
|
.delete(JsonObject.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ public class TestSecurity extends BaseJerseyTest {
|
|||||||
|
|
||||||
// User testsecurity logs out
|
// User testsecurity logs out
|
||||||
clientUtil.logout(testSecurityToken);
|
clientUtil.logout(testSecurityToken);
|
||||||
|
|
||||||
|
// Delete the user
|
||||||
|
String adminToken = adminToken();
|
||||||
|
target().path("/user/testsecurity").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -98,5 +104,11 @@ public class TestSecurity extends BaseJerseyTest {
|
|||||||
.header(HeaderBasedSecurityFilter.AUTHENTICATED_USER_HEADER, "idontexist")
|
.header(HeaderBasedSecurityFilter.AUTHENTICATED_USER_HEADER, "idontexist")
|
||||||
.get()
|
.get()
|
||||||
.getStatus());
|
.getStatus());
|
||||||
|
|
||||||
|
// Delete the user
|
||||||
|
String adminToken = adminToken();
|
||||||
|
target().path("/user/header_auth_test").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,5 +127,14 @@ public class TestShareResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus()));
|
||||||
json = response.readEntity(JsonObject.class);
|
json = response.readEntity(JsonObject.class);
|
||||||
Assert.assertEquals("ShareNotFound", json.getString("type"));
|
Assert.assertEquals("ShareNotFound", json.getString("type"));
|
||||||
|
|
||||||
|
// Deletes share1 and share 2
|
||||||
|
String adminToken = adminToken();
|
||||||
|
target().path("/user/share1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
|
target().path("/user/share2").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,5 +230,11 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(1, tags.size());
|
Assert.assertEquals(1, tags.size());
|
||||||
Assert.assertEquals("UpdatedName", tags.getJsonObject(0).getString("name"));
|
Assert.assertEquals("UpdatedName", tags.getJsonObject(0).getString("name"));
|
||||||
Assert.assertNull(tags.getJsonObject(0).get("parent"));
|
Assert.assertNull(tags.getJsonObject(0).get("parent"));
|
||||||
|
|
||||||
|
// Deletes user tag1
|
||||||
|
String adminToken = adminToken();
|
||||||
|
target().path("/user/tag1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ public class TestThemeResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testThemeResource() throws Exception {
|
public void testThemeResource() throws Exception {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Get the stylesheet anonymously
|
// Get the stylesheet anonymously
|
||||||
String stylesheet = target().path("/theme/stylesheet").request()
|
String stylesheet = target().path("/theme/stylesheet").request()
|
||||||
@@ -103,5 +103,13 @@ public class TestThemeResource extends BaseJerseyTest {
|
|||||||
// Get the background
|
// Get the background
|
||||||
response = target().path("/theme/image/background").request().get();
|
response = target().path("/theme/image/background").request().get();
|
||||||
Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
|
Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
|
||||||
|
|
||||||
|
// Reset the main color as admin
|
||||||
|
target().path("/theme").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.post(Entity.form(new Form()
|
||||||
|
.param("color", "#ffffff")
|
||||||
|
.param("name", "Teedy")
|
||||||
|
.param("css", "")), JsonObject.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
clientUtil.createUser("alice");
|
clientUtil.createUser("alice");
|
||||||
|
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// List all users
|
// List all users
|
||||||
json = target().path("/user/list")
|
json = target().path("/user/list")
|
||||||
@@ -75,7 +75,7 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
response = target().path("/user").request()
|
response = target().path("/user").request()
|
||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
.put(Entity.form(new Form()
|
.put(Entity.form(new Form()
|
||||||
.param("username", "bob-")
|
.param("username", "bob/")
|
||||||
.param("email", "bob@docs.com")
|
.param("email", "bob@docs.com")
|
||||||
.param("password", "12345678")
|
.param("password", "12345678")
|
||||||
.param("storage_quota", "10")));
|
.param("storage_quota", "10")));
|
||||||
@@ -128,15 +128,6 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
json = response.readEntity(JsonObject.class);
|
json = response.readEntity(JsonObject.class);
|
||||||
Assert.assertEquals("AlreadyExistingUsername", json.getString("type"));
|
Assert.assertEquals("AlreadyExistingUsername", json.getString("type"));
|
||||||
|
|
||||||
// Check if a username is free : OK
|
|
||||||
target().path("/user/check_username").queryParam("username", "carol").request().get(JsonObject.class);
|
|
||||||
|
|
||||||
// Check if a username is free : KO
|
|
||||||
response = target().path("/user/check_username").queryParam("username", "alice").request().get();
|
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
|
||||||
json = response.readEntity(JsonObject.class);
|
|
||||||
Assert.assertEquals("ko", json.getString("status"));
|
|
||||||
|
|
||||||
// Login alice with extra whitespaces
|
// Login alice with extra whitespaces
|
||||||
response = target().path("/user/login").request()
|
response = target().path("/user/login").request()
|
||||||
.post(Entity.form(new Form()
|
.post(Entity.form(new Form()
|
||||||
@@ -239,6 +230,11 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
.param("username", "alice")
|
.param("username", "alice")
|
||||||
.param("password", "12345678")));
|
.param("password", "12345678")));
|
||||||
Assert.assertEquals(Status.FORBIDDEN, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.FORBIDDEN, Status.fromStatusCode(response.getStatus()));
|
||||||
|
|
||||||
|
// Delete user bob
|
||||||
|
target().path("/user").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -250,7 +246,7 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
clientUtil.createUser("admin_user1");
|
clientUtil.createUser("admin_user1");
|
||||||
|
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Check admin information
|
// Check admin information
|
||||||
JsonObject json = target().path("/user").request()
|
JsonObject json = target().path("/user").request()
|
||||||
@@ -336,7 +332,7 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testTotp() {
|
public void testTotp() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Create totp1 user
|
// Create totp1 user
|
||||||
clientUtil.createUser("totp1");
|
clientUtil.createUser("totp1");
|
||||||
@@ -420,12 +416,18 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, totp1Token)
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, totp1Token)
|
||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
Assert.assertFalse(json.getBoolean("totp_enabled"));
|
Assert.assertFalse(json.getBoolean("totp_enabled"));
|
||||||
|
|
||||||
|
// Delete totp1
|
||||||
|
response = target().path("/user/totp1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
|
Assert.assertEquals(Response.Status.OK, Response.Status.fromStatusCode(response.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResetPassword() throws Exception {
|
public void testResetPassword() throws Exception {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Change SMTP configuration to target Wiser
|
// Change SMTP configuration to target Wiser
|
||||||
target().path("/app/config_smtp").request()
|
target().path("/app/config_smtp").request()
|
||||||
@@ -492,5 +494,11 @@ public class TestUserResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(Response.Status.BAD_REQUEST, Response.Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Response.Status.BAD_REQUEST, Response.Status.fromStatusCode(response.getStatus()));
|
||||||
json = response.readEntity(JsonObject.class);
|
json = response.readEntity(JsonObject.class);
|
||||||
Assert.assertEquals("KeyNotFound", json.getString("type"));
|
Assert.assertEquals("KeyNotFound", json.getString("type"));
|
||||||
|
|
||||||
|
// Delete absent_minded
|
||||||
|
response = target().path("/user/absent_minded").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
|
Assert.assertEquals(Response.Status.OK, Response.Status.fromStatusCode(response.getStatus()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class TestVocabularyResource extends BaseJerseyTest {
|
|||||||
String vocabulary1Token = clientUtil.login("vocabulary1");
|
String vocabulary1Token = clientUtil.login("vocabulary1");
|
||||||
|
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Get coverage vocabularies entries
|
// Get coverage vocabularies entries
|
||||||
JsonObject json = target().path("/vocabulary/coverage").request()
|
JsonObject json = target().path("/vocabulary/coverage").request()
|
||||||
@@ -109,4 +109,4 @@ public class TestVocabularyResource extends BaseJerseyTest {
|
|||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
Assert.assertEquals(0, json.getJsonArray("entries").size());
|
Assert.assertEquals(0, json.getJsonArray("entries").size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class TestWebhookResource extends BaseJerseyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testWebhookResource() {
|
public void testWebhookResource() {
|
||||||
// Login admin
|
// Login admin
|
||||||
String adminToken = clientUtil.login("admin", "admin", false);
|
String adminToken = adminToken();
|
||||||
|
|
||||||
// Login webhook1
|
// Login webhook1
|
||||||
clientUtil.createUser("webhook1");
|
clientUtil.createUser("webhook1");
|
||||||
@@ -84,5 +84,10 @@ public class TestWebhookResource extends BaseJerseyTest {
|
|||||||
.get(JsonObject.class);
|
.get(JsonObject.class);
|
||||||
webhooks = json.getJsonArray("webhooks");
|
webhooks = json.getJsonArray("webhooks");
|
||||||
Assert.assertEquals(0, webhooks.size());
|
Assert.assertEquals(0, webhooks.size());
|
||||||
|
|
||||||
|
// Deletes webhook1
|
||||||
|
target().path("/user/webhook1").request()
|
||||||
|
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken)
|
||||||
|
.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,492 @@
|
|||||||
|
package com.sismics.docs.rest.util;
|
||||||
|
|
||||||
|
import com.sismics.docs.core.dao.TagDao;
|
||||||
|
import com.sismics.docs.core.dao.criteria.DocumentCriteria;
|
||||||
|
import com.sismics.docs.core.dao.criteria.TagCriteria;
|
||||||
|
import com.sismics.docs.core.dao.dto.TagDto;
|
||||||
|
import com.sismics.docs.core.model.jpa.Tag;
|
||||||
|
import com.sismics.docs.core.model.jpa.User;
|
||||||
|
import com.sismics.docs.rest.BaseTransactionalTest;
|
||||||
|
import com.sismics.util.mime.MimeType;
|
||||||
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TestDocumentSearchCriteriaUtil extends BaseTransactionalTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsBy() throws Exception {
|
||||||
|
User user = createUser("user1");
|
||||||
|
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
"user1",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getCreatorId(), user.getId());
|
||||||
|
|
||||||
|
documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
"missing",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertNotNull(documentCriteria.getCreatorId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsCreatedAfter() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
"2022-03-27",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getCreateDateMin(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsCreatedBefore() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"2022-03-27",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getCreateDateMax(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsFull() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"full",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getFullSearch(), "full");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsLang() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"fra",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getLanguage(), "fra");
|
||||||
|
|
||||||
|
documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"unknown",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertNotNull(documentCriteria.getLanguage());
|
||||||
|
Assert.assertNotEquals(documentCriteria.getLanguage(), "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsMime() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
MimeType.IMAGE_GIF,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getMimeType(), MimeType.IMAGE_GIF);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsShared() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertTrue(documentCriteria.getShared());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsSimple() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"simple",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getSimpleSearch(), "simple");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsTag() throws Exception {
|
||||||
|
TagDao tagDao = new TagDao();
|
||||||
|
|
||||||
|
User user = createUser("user1");
|
||||||
|
Tag tag1 = new Tag();
|
||||||
|
tag1.setName("tag1");
|
||||||
|
tag1.setColor("#bbb");
|
||||||
|
tag1.setUserId(user.getId());
|
||||||
|
tagDao.create(tag1, user.getId());
|
||||||
|
|
||||||
|
Tag tag2 = new Tag();
|
||||||
|
tag2.setName("tag2");
|
||||||
|
tag2.setColor("#bbb");
|
||||||
|
tag2.setUserId(user.getId());
|
||||||
|
tagDao.create(tag2, user.getId());
|
||||||
|
|
||||||
|
Tag tag3 = new Tag();
|
||||||
|
tag3.setName("tag3");
|
||||||
|
tag3.setColor("#bbb");
|
||||||
|
tag3.setUserId(user.getId());
|
||||||
|
tag3.setParentId(tag2.getId());
|
||||||
|
tagDao.create(tag3, user.getId());
|
||||||
|
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria(), null);
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"tag1",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
allTagDtoList
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getTagIdList(), List.of(Collections.singletonList(tag1.getId())));
|
||||||
|
|
||||||
|
documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"tag2",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
allTagDtoList
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getTagIdList(), List.of(List.of(tag2.getId(), tag3.getId())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsNotTag() throws Exception {
|
||||||
|
TagDao tagDao = new TagDao();
|
||||||
|
|
||||||
|
User user = createUser("user1");
|
||||||
|
Tag tag1 = new Tag();
|
||||||
|
tag1.setName("tag1");
|
||||||
|
tag1.setColor("#bbb");
|
||||||
|
tag1.setUserId(user.getId());
|
||||||
|
tagDao.create(tag1, user.getId());
|
||||||
|
|
||||||
|
Tag tag2 = new Tag();
|
||||||
|
tag2.setName("tag2");
|
||||||
|
tag2.setColor("#bbb");
|
||||||
|
tag2.setUserId(user.getId());
|
||||||
|
tagDao.create(tag2, user.getId());
|
||||||
|
|
||||||
|
Tag tag3 = new Tag();
|
||||||
|
tag3.setName("tag3");
|
||||||
|
tag3.setColor("#bbb");
|
||||||
|
tag3.setUserId(user.getId());
|
||||||
|
tag3.setParentId(tag2.getId());
|
||||||
|
tagDao.create(tag3, user.getId());
|
||||||
|
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
List<TagDto> allTagDtoList = tagDao.findByCriteria(new TagCriteria(), null);
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"tag1",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
allTagDtoList
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getExcludedTagIdList(), List.of(Collections.singletonList(tag1.getId())));
|
||||||
|
|
||||||
|
documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"tag2",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
allTagDtoList
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getExcludedTagIdList(), List.of(List.of(tag2.getId(), tag3.getId())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsTitle() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"title1,title2",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getTitleList(), Arrays.asList(new String[]{"title1", "title2"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsUpdatedAfter() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"2022-03-27",
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getUpdateDateMin(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsUpdatedBefore() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"2022-03-27",
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertEquals(documentCriteria.getUpdateDateMax(), new DateTime(2022, 3, 27, 0, 0, 0).toDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpParamsWorkflow() {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
DocumentSearchCriteriaUtil.addHttpSearchParams(
|
||||||
|
documentCriteria,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
"me",
|
||||||
|
null
|
||||||
|
);
|
||||||
|
Assert.assertTrue(documentCriteria.getActiveRoute());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
103
pom.xml
103
pom.xml
@@ -32,10 +32,10 @@
|
|||||||
<at.favre.lib.bcrypt.version>0.10.2</at.favre.lib.bcrypt.version>
|
<at.favre.lib.bcrypt.version>0.10.2</at.favre.lib.bcrypt.version>
|
||||||
<org.apache.lucene.version>8.7.0</org.apache.lucene.version>
|
<org.apache.lucene.version>8.7.0</org.apache.lucene.version>
|
||||||
<org.imgscalr.imgscalr-lib.version>4.2</org.imgscalr.imgscalr-lib.version>
|
<org.imgscalr.imgscalr-lib.version>4.2</org.imgscalr.imgscalr-lib.version>
|
||||||
<org.apache.pdfbox.pdfbox.version>2.0.27</org.apache.pdfbox.pdfbox.version>
|
<org.apache.pdfbox.pdfbox.version>2.0.29</org.apache.pdfbox.pdfbox.version>
|
||||||
<org.bouncycastle.bcprov-jdk15on.version>1.70</org.bouncycastle.bcprov-jdk15on.version>
|
<org.bouncycastle.bcprov-jdk15on.version>1.70</org.bouncycastle.bcprov-jdk15on.version>
|
||||||
<joda-time.joda-time.version>2.12.2</joda-time.joda-time.version>
|
<joda-time.joda-time.version>2.12.2</joda-time.joda-time.version>
|
||||||
<org.hibernate.hibernate.version>5.6.15.Final</org.hibernate.hibernate.version>
|
<org.hibernate.hibernate.version>6.3.1.Final</org.hibernate.hibernate.version>
|
||||||
<fr.opensagres.xdocreport.version>2.0.4</fr.opensagres.xdocreport.version>
|
<fr.opensagres.xdocreport.version>2.0.4</fr.opensagres.xdocreport.version>
|
||||||
<net.java.dev.jna.jna.version>5.13.0</net.java.dev.jna.jna.version>
|
<net.java.dev.jna.jna.version>5.13.0</net.java.dev.jna.jna.version>
|
||||||
<com.twelvemonkeys.imageio.version>3.9.4</com.twelvemonkeys.imageio.version>
|
<com.twelvemonkeys.imageio.version>3.9.4</com.twelvemonkeys.imageio.version>
|
||||||
@@ -46,22 +46,23 @@
|
|||||||
<com.icegreen.greenmail.version>1.6.14</com.icegreen.greenmail.version>
|
<com.icegreen.greenmail.version>1.6.14</com.icegreen.greenmail.version>
|
||||||
<org.jsoup.jsoup.version>1.15.4</org.jsoup.jsoup.version>
|
<org.jsoup.jsoup.version>1.15.4</org.jsoup.jsoup.version>
|
||||||
<com.squareup.okhttp3.okhttp.version>4.10.0</com.squareup.okhttp3.okhttp.version>
|
<com.squareup.okhttp3.okhttp.version>4.10.0</com.squareup.okhttp3.okhttp.version>
|
||||||
<org.apache.directory.api.api-all.version>2.1.3</org.apache.directory.api.api-all.version>
|
<org.apache.directory.api.version>2.1.3</org.apache.directory.api.version>
|
||||||
|
<org.apache.directory.server.apacheds-all.version>2.0.0.AM27</org.apache.directory.server.apacheds-all.version>
|
||||||
|
|
||||||
<org.glassfish.jersey.version>3.0.10</org.glassfish.jersey.version>
|
<org.glassfish.jersey.version>3.0.10</org.glassfish.jersey.version>
|
||||||
<jakarta.servlet.jakarta.servlet-api.version>5.0.0</jakarta.servlet.jakarta.servlet-api.version>
|
<jakarta.servlet.jakarta.servlet-api.version>5.0.0</jakarta.servlet.jakarta.servlet-api.version>
|
||||||
<org.eclipse.jetty.jetty-server.version>11.0.14</org.eclipse.jetty.jetty-server.version>
|
<org.eclipse.jetty.jetty-server.version>11.0.20</org.eclipse.jetty.jetty-server.version>
|
||||||
<org.eclipse.jetty.jetty-webapp.version>11.0.14</org.eclipse.jetty.jetty-webapp.version>
|
<org.eclipse.jetty.jetty-webapp.version>11.0.20</org.eclipse.jetty.jetty-webapp.version>
|
||||||
<org.eclipse.jetty.jetty-servlet.version>11.0.14</org.eclipse.jetty.jetty-servlet.version>
|
<org.eclipse.jetty.jetty-servlet.version>11.0.20</org.eclipse.jetty.jetty-servlet.version>
|
||||||
|
|
||||||
<!-- Plugins version -->
|
<!-- Plugins version -->
|
||||||
<org.apache.maven.plugins.maven-antrun-plugin.version>3.1.0</org.apache.maven.plugins.maven-antrun-plugin.version>
|
<org.apache.maven.plugins.maven-antrun-plugin.version>3.1.0</org.apache.maven.plugins.maven-antrun-plugin.version>
|
||||||
<org.apache.maven.plugins.maven-jar-plugin.version>3.3.0</org.apache.maven.plugins.maven-jar-plugin.version>
|
<org.apache.maven.plugins.maven-jar-plugin.version>3.3.0</org.apache.maven.plugins.maven-jar-plugin.version>
|
||||||
<org.apache.maven.plugins.maven-war-plugin.version>3.3.2</org.apache.maven.plugins.maven-war-plugin.version>
|
<org.apache.maven.plugins.maven-war-plugin.version>3.3.2</org.apache.maven.plugins.maven-war-plugin.version>
|
||||||
<org.apache.maven.plugins.maven-surefire-plugin.version>3.0.0</org.apache.maven.plugins.maven-surefire-plugin.version>
|
<org.apache.maven.plugins.maven-surefire-plugin.version>3.0.0</org.apache.maven.plugins.maven-surefire-plugin.version>
|
||||||
<org.eclipse.jetty.jetty-maven-plugin.version>11.0.14</org.eclipse.jetty.jetty-maven-plugin.version>
|
<org.eclipse.jetty.jetty-maven-plugin.version>11.0.20</org.eclipse.jetty.jetty-maven-plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:git:https://github.com/sismics/docs.git</connection>
|
<connection>scm:git:https://github.com/sismics/docs.git</connection>
|
||||||
<developerConnection>scm:git:https://github.com/docs/docs.git</developerConnection>
|
<developerConnection>scm:git:https://github.com/docs/docs.git</developerConnection>
|
||||||
@@ -93,7 +94,7 @@
|
|||||||
<artifactId>maven-war-plugin</artifactId>
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
<version>${org.apache.maven.plugins.maven-war-plugin.version}</version>
|
<version>${org.apache.maven.plugins.maven-war-plugin.version}</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
@@ -109,7 +110,7 @@
|
|||||||
<reuseForks>false</reuseForks>
|
<reuseForks>false</reuseForks>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-maven-plugin</artifactId>
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
@@ -117,13 +118,13 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>docs-core</module>
|
<module>docs-core</module>
|
||||||
<module>docs-web-common</module>
|
<module>docs-web-common</module>
|
||||||
<module>docs-web</module>
|
<module>docs-web</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -131,38 +132,38 @@
|
|||||||
<artifactId>docs-core</artifactId>
|
<artifactId>docs-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-web-common</artifactId>
|
<artifactId>docs-web-common</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-web-common</artifactId>
|
<artifactId>docs-web-common</artifactId>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sismics.docs</groupId>
|
<groupId>com.sismics.docs</groupId>
|
||||||
<artifactId>docs-web</artifactId>
|
<artifactId>docs-web</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-server</artifactId>
|
<artifactId>jetty-server</artifactId>
|
||||||
<version>${org.eclipse.jetty.jetty-server.version}</version>
|
<version>${org.eclipse.jetty.jetty-server.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-webapp</artifactId>
|
<artifactId>jetty-webapp</artifactId>
|
||||||
<version>${org.eclipse.jetty.jetty-webapp.version}</version>
|
<version>${org.eclipse.jetty.jetty-webapp.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-servlet</artifactId>
|
<artifactId>jetty-servlet</artifactId>
|
||||||
@@ -180,7 +181,7 @@
|
|||||||
<artifactId>commons-compress</artifactId>
|
<artifactId>commons-compress</artifactId>
|
||||||
<version>${org.apache.commons.commons-compress.version}</version>
|
<version>${org.apache.commons.commons-compress.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
@@ -198,7 +199,7 @@
|
|||||||
<artifactId>commons-email</artifactId>
|
<artifactId>commons-email</artifactId>
|
||||||
<version>${org.apache.commons.commons-email.version}</version>
|
<version>${org.apache.commons.commons-email.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
@@ -222,19 +223,19 @@
|
|||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>${log4j.log4j.version}</version>
|
<version>${log4j.log4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>${org.slf4j.version}</version>
|
<version>${org.slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
@@ -264,7 +265,7 @@
|
|||||||
<artifactId>jersey-container-servlet</artifactId>
|
<artifactId>jersey-container-servlet</artifactId>
|
||||||
<version>${org.glassfish.jersey.version}</version>
|
<version>${org.glassfish.jersey.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.media</groupId>
|
<groupId>org.glassfish.jersey.media</groupId>
|
||||||
<artifactId>jersey-media-json-processing</artifactId>
|
<artifactId>jersey-media-json-processing</artifactId>
|
||||||
@@ -276,7 +277,7 @@
|
|||||||
<artifactId>jersey-media-multipart</artifactId>
|
<artifactId>jersey-media-multipart</artifactId>
|
||||||
<version>${org.glassfish.jersey.version}</version>
|
<version>${org.glassfish.jersey.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.inject</groupId>
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
<artifactId>jersey-hk2</artifactId>
|
<artifactId>jersey-hk2</artifactId>
|
||||||
@@ -288,7 +289,7 @@
|
|||||||
<artifactId>jersey-client</artifactId>
|
<artifactId>jersey-client</artifactId>
|
||||||
<version>${org.glassfish.jersey.version}</version>
|
<version>${org.glassfish.jersey.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
|
||||||
<artifactId>jersey-test-framework-provider-bundle</artifactId>
|
<artifactId>jersey-test-framework-provider-bundle</artifactId>
|
||||||
@@ -307,7 +308,7 @@
|
|||||||
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
|
||||||
<version>${org.glassfish.jersey.version}</version>
|
<version>${org.glassfish.jersey.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish.jersey.containers</groupId>
|
<groupId>org.glassfish.jersey.containers</groupId>
|
||||||
<artifactId>jersey-container-grizzly2-servlet</artifactId>
|
<artifactId>jersey-container-grizzly2-servlet</artifactId>
|
||||||
@@ -327,11 +328,11 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate.orm</groupId>
|
||||||
<artifactId>hibernate-core-jakarta</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
<version>${org.hibernate.hibernate.version}</version>
|
<version>${org.hibernate.hibernate.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.freemarker</groupId>
|
<groupId>org.freemarker</groupId>
|
||||||
<artifactId>freemarker</artifactId>
|
<artifactId>freemarker</artifactId>
|
||||||
@@ -349,25 +350,25 @@
|
|||||||
<artifactId>lucene-core</artifactId>
|
<artifactId>lucene-core</artifactId>
|
||||||
<version>${org.apache.lucene.version}</version>
|
<version>${org.apache.lucene.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-analyzers-common</artifactId>
|
<artifactId>lucene-analyzers-common</artifactId>
|
||||||
<version>${org.apache.lucene.version}</version>
|
<version>${org.apache.lucene.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-queryparser</artifactId>
|
<artifactId>lucene-queryparser</artifactId>
|
||||||
<version>${org.apache.lucene.version}</version>
|
<version>${org.apache.lucene.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-backward-codecs</artifactId>
|
<artifactId>lucene-backward-codecs</artifactId>
|
||||||
<version>${org.apache.lucene.version}</version>
|
<version>${org.apache.lucene.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-suggest</artifactId>
|
<artifactId>lucene-suggest</artifactId>
|
||||||
@@ -385,25 +386,25 @@
|
|||||||
<artifactId>imgscalr-lib</artifactId>
|
<artifactId>imgscalr-lib</artifactId>
|
||||||
<version>${org.imgscalr.imgscalr-lib.version}</version>
|
<version>${org.imgscalr.imgscalr-lib.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
<version>${org.apache.pdfbox.pdfbox.version}</version>
|
<version>${org.apache.pdfbox.pdfbox.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bouncycastle</groupId>
|
<groupId>org.bouncycastle</groupId>
|
||||||
<artifactId>bcprov-jdk15on</artifactId>
|
<artifactId>bcprov-jdk15on</artifactId>
|
||||||
<version>${org.bouncycastle.bcprov-jdk15on.version}</version>
|
<version>${org.bouncycastle.bcprov-jdk15on.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>fr.opensagres.xdocreport</groupId>
|
<groupId>fr.opensagres.xdocreport</groupId>
|
||||||
<artifactId>fr.opensagres.odfdom.converter.pdf</artifactId>
|
<artifactId>fr.opensagres.odfdom.converter.pdf</artifactId>
|
||||||
<version>${fr.opensagres.xdocreport.version}</version>
|
<version>${fr.opensagres.xdocreport.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>fr.opensagres.xdocreport</groupId>
|
<groupId>fr.opensagres.xdocreport</groupId>
|
||||||
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
|
<artifactId>fr.opensagres.poi.xwpf.converter.pdf</artifactId>
|
||||||
@@ -436,8 +437,26 @@
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.directory.api</groupId>
|
<groupId>org.apache.directory.api</groupId>
|
||||||
<artifactId>api-all</artifactId>
|
<artifactId>api-ldap-client-api</artifactId>
|
||||||
<version>${org.apache.directory.api.api-all.version}</version>
|
<version>${org.apache.directory.api.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.directory.api</groupId>
|
||||||
|
<artifactId>api-ldap-schema-data</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.directory.api</groupId>
|
||||||
|
<artifactId>api-ldap-codec-standalone</artifactId>
|
||||||
|
<version>${org.apache.directory.api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.directory.server</groupId>
|
||||||
|
<artifactId>apacheds-all</artifactId>
|
||||||
|
<version>${org.apache.directory.server.apacheds-all.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- ImageIO plugins -->
|
<!-- ImageIO plugins -->
|
||||||
@@ -471,5 +490,5 @@
|
|||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
41
scripts/dev_setup.sh
Executable file
41
scripts/dev_setup.sh
Executable file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
install_macos_dependencies() {
|
||||||
|
brew install openjdk@11
|
||||||
|
export JAVA_HOME=/usr/local/opt/openjdk@11
|
||||||
|
brew install maven
|
||||||
|
brew install node
|
||||||
|
npm install -g grunt-cli
|
||||||
|
brew install tesseract
|
||||||
|
brew install ffmpeg
|
||||||
|
brew install mediainfo
|
||||||
|
}
|
||||||
|
|
||||||
|
install_ubuntu_debian_dependencies() {
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install -y openjdk-11-jdk maven nodejs npm tesseract-ocr ffmpeg mediainfo
|
||||||
|
sudo npm install -g grunt-cli
|
||||||
|
}
|
||||||
|
|
||||||
|
install_fedora_dependencies() {
|
||||||
|
sudo dnf install -y java-11-openjdk-devel maven nodejs npm tesseract ffmpeg mediainfo
|
||||||
|
sudo npm install -g grunt-cli
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "📥 Installing dependencies"
|
||||||
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
|
install_macos_dependencies
|
||||||
|
elif [[ -f /etc/debian_version ]]; then
|
||||||
|
install_ubuntu_debian_dependencies
|
||||||
|
elif [[ -f /etc/fedora-release ]]; then
|
||||||
|
install_fedora_dependencies
|
||||||
|
else
|
||||||
|
echo "❔ Unsupported OS. Feel free to contribute!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Dependencies installed."
|
||||||
|
|
||||||
|
mvn clean -DskipTests install
|
||||||
|
|
||||||
|
echo "You can start the server with 'mvn jetty:run' and then access it at http://localhost:8080/docs-web/src/"
|
||||||
Reference in New Issue
Block a user