security
This commit is contained in:
parent
ac019ac196
commit
c7c81a7243
8 changed files with 129 additions and 59 deletions
44
Dockerfile
44
Dockerfile
|
@ -1,31 +1,39 @@
|
||||||
# Build jbig2enc in a separate stage
|
# Use the base image
|
||||||
FROM frooodle/stirling-pdf-base:beta4
|
FROM frooodle/stirling-pdf-base:beta4
|
||||||
|
|
||||||
ARG VERSION_TAG
|
# Set Environment Variables
|
||||||
ENV VERSION_TAG=$VERSION_TAG
|
ENV PUID=1000 \
|
||||||
|
PGID=1000 \
|
||||||
|
UMASK=022 \
|
||||||
|
DOCKER_ENABLE_SECURITY=false \
|
||||||
|
HOME=/home/stirlingpdfuser \
|
||||||
|
VERSION_TAG=$VERSION_TAG
|
||||||
|
|
||||||
ENV DOCKER_ENABLE_SECURITY=false
|
# Create user and group
|
||||||
|
RUN groupadd -g $PGID stirlingpdfgroup && \
|
||||||
|
useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \
|
||||||
|
mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
|
||||||
|
|
||||||
# Create scripts folder and copy local scripts
|
# Set up necessary directories and permissions
|
||||||
RUN mkdir /scripts
|
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original
|
||||||
|
|
||||||
|
# Copy necessary files
|
||||||
COPY ./scripts/* /scripts/
|
COPY ./scripts/* /scripts/
|
||||||
|
|
||||||
#Install fonts
|
|
||||||
RUN mkdir /usr/share/fonts/opentype/noto/
|
|
||||||
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
||||||
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
|
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
|
||||||
RUN fc-cache -f -v
|
|
||||||
|
|
||||||
# Always copy the JAR
|
|
||||||
COPY build/libs/*.jar app.jar
|
COPY build/libs/*.jar app.jar
|
||||||
|
|
||||||
# Expose the application port
|
# Set font cache and permissions
|
||||||
|
RUN fc-cache -f -v && \
|
||||||
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
||||||
|
chmod +x /scripts/init.sh
|
||||||
|
|
||||||
|
# Expose necessary ports
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Set environment variables
|
# Set user and run command
|
||||||
ENV APP_HOME_NAME="Stirling PDF"
|
USER stirlingpdfuser
|
||||||
|
|
||||||
# Run the application
|
|
||||||
RUN chmod +x /scripts/init.sh
|
|
||||||
ENTRYPOINT ["/scripts/init.sh"]
|
ENTRYPOINT ["/scripts/init.sh"]
|
||||||
CMD ["java", "-jar", "/app.jar"]
|
CMD ["java", "-jar", "/app.jar"]
|
||||||
|
|
|
@ -10,17 +10,43 @@ RUN apt-get update && \
|
||||||
unoconv && \
|
unoconv && \
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy the application JAR file
|
|
||||||
|
# Set Environment Variables
|
||||||
|
ENV PUID=1000 \
|
||||||
|
PGID=1000 \
|
||||||
|
UMASK=022 \
|
||||||
|
DOCKER_ENABLE_SECURITY=false \
|
||||||
|
HOME=/home/stirlingpdfuser \
|
||||||
|
VERSION_TAG=$VERSION_TAG
|
||||||
|
|
||||||
|
# Create user and group
|
||||||
|
RUN groupadd -g $PGID stirlingpdfgroup && \
|
||||||
|
useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \
|
||||||
|
mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
|
||||||
|
|
||||||
|
# Set up necessary directories and permissions
|
||||||
|
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles && \
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/fonts/opentype/noto /configs /customFiles
|
||||||
|
|
||||||
|
# Copy necessary files
|
||||||
|
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
||||||
|
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
|
||||||
COPY build/libs/*.jar app.jar
|
COPY build/libs/*.jar app.jar
|
||||||
|
|
||||||
|
# Set font cache and permissions
|
||||||
|
RUN fc-cache -f -v && \
|
||||||
|
chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV GROUPS_TO_REMOVE=Python,OpenCV,OCRmyPDF
|
ENV ENDPOINTS_GROUPS_TO_REMOVE=Python,OpenCV,OCRmyPDF
|
||||||
ENV DOCKER_ENABLE_SECURITY=false
|
ENV DOCKER_ENABLE_SECURITY=false
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
|
USER stirlingpdfuser
|
||||||
CMD ["java", "-jar", "/app.jar"]
|
CMD ["java", "-jar", "/app.jar"]
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
# Build jbig2enc in a separate stage
|
# Build jbig2enc in a separate stage
|
||||||
FROM bellsoft/liberica-openjdk-alpine:17
|
FROM bellsoft/liberica-openjdk-alpine:17
|
||||||
|
|
||||||
# Copy the application JAR file
|
# Set Environment Variables
|
||||||
|
ENV PUID=1000 \
|
||||||
|
PGID=1000 \
|
||||||
|
UMASK=022 \
|
||||||
|
DOCKER_ENABLE_SECURITY=false \
|
||||||
|
HOME=/home/stirlingpdfuser \
|
||||||
|
VERSION_TAG=$VERSION_TAG
|
||||||
|
|
||||||
|
# Create user and group using Alpine's addgroup and adduser
|
||||||
|
RUN addgroup -g $PGID stirlingpdfgroup && \
|
||||||
|
adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \
|
||||||
|
mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
|
||||||
|
|
||||||
|
# Set up necessary directories and permissions
|
||||||
|
RUN mkdir -p /scripts /configs /customFiles && \
|
||||||
|
chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles
|
||||||
|
|
||||||
COPY build/libs/*.jar app.jar
|
COPY build/libs/*.jar app.jar
|
||||||
|
|
||||||
|
# Set font cache and permissions
|
||||||
|
RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar
|
||||||
|
|
||||||
# Expose the application port
|
# Expose the application port
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Set environment variables
|
# Set environment variables
|
||||||
ENV GROUPS_TO_REMOVE=CLI
|
ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
||||||
ENV DOCKER_ENABLE_SECURITY=false
|
ENV DOCKER_ENABLE_SECURITY=false
|
||||||
|
|
||||||
# Run the application
|
# Run the application
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class UserController {
|
||||||
|
|
||||||
|
|
||||||
userService.changePassword(user, newPassword);
|
userService.changePassword(user, newPassword);
|
||||||
if(!user.getUsername().equals(newUsername)) {
|
if(newUsername != null && newUsername.length() > 0 && !user.getUsername().equals(newUsername)) {
|
||||||
userService.changeUsername(user, newUsername);
|
userService.changeUsername(user, newUsername);
|
||||||
}
|
}
|
||||||
userService.changeFirstUse(user, false);
|
userService.changeFirstUse(user, false);
|
||||||
|
@ -111,8 +111,9 @@ public class UserController {
|
||||||
return new RedirectView("/account?messageType=usernameExists");
|
return new RedirectView("/account?messageType=usernameExists");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(newUsername != null && newUsername.length() > 0) {
|
||||||
userService.changeUsername(user, newUsername);
|
userService.changeUsername(user, newUsername);
|
||||||
|
}
|
||||||
|
|
||||||
// Logout using Spring's utility
|
// Logout using Spring's utility
|
||||||
new SecurityContextLogoutHandler().logout(request, response, null);
|
new SecurityContextLogoutHandler().logout(request, response, null);
|
||||||
|
@ -173,9 +174,14 @@ public class UserController {
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@PostMapping("/admin/saveUser")
|
@PostMapping("/admin/saveUser")
|
||||||
public String saveUser(@RequestParam String username, @RequestParam String password, @RequestParam String role) {
|
public RedirectView saveUser(@RequestParam String username, @RequestParam String password, @RequestParam String role,
|
||||||
userService.saveUser(username, password, role);
|
@RequestParam(name = "forceChange", required = false, defaultValue = "false") boolean forceChange) {
|
||||||
return "redirect:/addUsers"; // Redirect to account page after adding the user
|
|
||||||
|
if(userService.usernameExists(username)) {
|
||||||
|
return new RedirectView("/addUsers?messageType=usernameExists");
|
||||||
|
}
|
||||||
|
userService.saveUser(username, password, role, forceChange);
|
||||||
|
return new RedirectView("/addUsers"); // Redirect to account page after adding the user
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@ adminUserSettings.role=Role
|
||||||
adminUserSettings.actions=Actions
|
adminUserSettings.actions=Actions
|
||||||
adminUserSettings.apiUser=Limited API User
|
adminUserSettings.apiUser=Limited API User
|
||||||
adminUserSettings.webOnlyUser=Web Only User
|
adminUserSettings.webOnlyUser=Web Only User
|
||||||
|
adminUserSettings.forceChange = Force user to change username/password on login
|
||||||
adminUserSettings.submit=Save User
|
adminUserSettings.submit=Save User
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
@ -767,13 +768,6 @@ changeMetadata.selectText.5=Add Custom Metadata Entry
|
||||||
changeMetadata.submit=Change
|
changeMetadata.submit=Change
|
||||||
|
|
||||||
|
|
||||||
#xlsToPdf
|
|
||||||
xlsToPdf.title=Excel to PDF
|
|
||||||
xlsToPdf.header=Excel to PDF
|
|
||||||
xlsToPdf.selectText.1=Select XLS or XLSX Excel sheet to convert
|
|
||||||
xlsToPdf.convert=convert
|
|
||||||
|
|
||||||
|
|
||||||
#pdfToPDFA
|
#pdfToPDFA
|
||||||
pdfToPDFA.title=PDF To PDF/A
|
pdfToPDFA.title=PDF To PDF/A
|
||||||
pdfToPDFA.header=PDF To PDF/A
|
pdfToPDFA.header=PDF To PDF/A
|
||||||
|
|
|
@ -43,6 +43,9 @@
|
||||||
|
|
||||||
|
|
||||||
<h2 th:text="#{adminUserSettings.addUser}">Add New User</h2>
|
<h2 th:text="#{adminUserSettings.addUser}">Add New User</h2>
|
||||||
|
<div th:if="${param.messageType != null and param.messageType.size() > 0 and param.messageType[0] == 'usernameExists'}" class="alert alert-danger">
|
||||||
|
<span th:text="#{usernameExistsMessage}">Default message if not found</span>
|
||||||
|
</div>
|
||||||
<form action="/admin/saveUser" method="post">
|
<form action="/admin/saveUser" method="post">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="username" th:text="#{username}">Username</label>
|
<label for="username" th:text="#{username}">Username</label>
|
||||||
|
@ -61,6 +64,10 @@
|
||||||
<option value="ROLE_WEB_ONLY_USER" th:text="#{adminUserSettings.webOnlyUser}">Web Only User</option>
|
<option value="ROLE_WEB_ONLY_USER" th:text="#{adminUserSettings.webOnlyUser}">Web Only User</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<input type="checkbox" class="form-check-input" id="forceChange" name="forceChange">
|
||||||
|
<label class="form-check-label" for="forceChange" th:text="#{adminUserSettings.forceChange}">Force user to change username/password on login</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Add other fields as required -->
|
<!-- Add other fields as required -->
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button>
|
<button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button>
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<form action="/change-username-and-password" method="post">
|
<form action="/change-username-and-password" method="post">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="newUsername" th:text="#{changeCreds.newUsername}">New Username</label>
|
<label for="newUsername" th:text="#{changeCreds.newUsername}">New Username</label>
|
||||||
<input type="text" class="form-control" name="newUsername" id="newUsername" placeholder="New Username">
|
<input type="text" class="form-control" name="newUsername" id="newUsername" th:placeholder="${username}">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="currentPassword" th:text="#{changeCreds.oldPassword}">Old Password</label>
|
<label for="currentPassword" th:text="#{changeCreds.oldPassword}">Old Password</label>
|
||||||
|
|
|
@ -28,7 +28,16 @@
|
||||||
<option value="image">Image</option>
|
<option value="image">Image</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="alphabetGroup" class="mb-3">
|
||||||
|
<label for="fontSize" th:text="#{alphabet} + ':'"></label>
|
||||||
|
<select class="form-control" name="alphabet" id="alphabet-select">
|
||||||
|
<option value="roman">Roman</option>
|
||||||
|
<option value="arabic">العربية</option>
|
||||||
|
<option value="japanese">日本語</option>
|
||||||
|
<option value="korean">한국어</option>
|
||||||
|
<option value="chinese">简体中文</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div id="watermarkTextGroup" class="mb-3">
|
<div id="watermarkTextGroup" class="mb-3">
|
||||||
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
<label for="watermarkText" th:text="#{watermark.selectText.2}"></label>
|
||||||
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
|
<input type="text" id="watermarkText" name="watermarkText" class="form-control" placeholder="Stirling-PDF" required />
|
||||||
|
@ -101,25 +110,28 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function toggleFileOption() {
|
function toggleFileOption() {
|
||||||
const watermarkType = document.getElementById('watermarkType').value;
|
const watermarkType = document.getElementById('watermarkType').value;
|
||||||
const watermarkTextGroup = document.getElementById('watermarkTextGroup');
|
const watermarkTextGroup = document.getElementById('watermarkTextGroup');
|
||||||
const watermarkImageGroup = document.getElementById('watermarkImageGroup');
|
const watermarkImageGroup = document.getElementById('watermarkImageGroup');
|
||||||
const watermarkText = document.getElementById('watermarkText');
|
const alphabetGroup = document.getElementById('alphabetGroup'); // This is the new addition
|
||||||
const watermarkImage = document.getElementById('watermarkImage');
|
const watermarkText = document.getElementById('watermarkText');
|
||||||
|
const watermarkImage = document.getElementById('watermarkImage');
|
||||||
|
|
||||||
if (watermarkType === 'text') {
|
if (watermarkType === 'text') {
|
||||||
watermarkTextGroup.style.display = 'block';
|
watermarkTextGroup.style.display = 'block';
|
||||||
watermarkText.required = true;
|
watermarkText.required = true;
|
||||||
watermarkImageGroup.style.display = 'none';
|
watermarkImageGroup.style.display = 'none';
|
||||||
watermarkImage.required = false;
|
watermarkImage.required = false;
|
||||||
} else if (watermarkType === 'image') {
|
alphabetGroup.style.display = 'block';
|
||||||
watermarkTextGroup.style.display = 'none';
|
} else if (watermarkType === 'image') {
|
||||||
watermarkText.required = false;
|
watermarkTextGroup.style.display = 'none';
|
||||||
watermarkImageGroup.style.display = 'block';
|
watermarkText.required = false;
|
||||||
watermarkImage.required = true;
|
watermarkImageGroup.style.display = 'block';
|
||||||
}
|
watermarkImage.required = true;
|
||||||
}
|
alphabetGroup.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue