mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 11:23:10 +02:00
Pipeline changes and version bump (#6047)
# Description of Changes <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### Translations (if applicable) - [ ] I ran [`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: a <a>
This commit is contained in:
co-authored by
a <a>
parent
da9327ab1c
commit
de9625942b
@@ -5,6 +5,8 @@ public interface UserServiceInterface {
|
|||||||
|
|
||||||
String getCurrentUsername();
|
String getCurrentUsername();
|
||||||
|
|
||||||
|
String getCurrentUserApiKey();
|
||||||
|
|
||||||
long getTotalUsersCount();
|
long getTotalUsersCount();
|
||||||
|
|
||||||
boolean isCurrentUserAdmin();
|
boolean isCurrentUserAdmin();
|
||||||
|
|||||||
+28
-2
@@ -37,7 +37,6 @@ import stirling.software.SPDF.model.PipelineConfig;
|
|||||||
import stirling.software.SPDF.model.PipelineOperation;
|
import stirling.software.SPDF.model.PipelineOperation;
|
||||||
import stirling.software.SPDF.model.PipelineResult;
|
import stirling.software.SPDF.model.PipelineResult;
|
||||||
import stirling.software.SPDF.service.ApiDocService;
|
import stirling.software.SPDF.service.ApiDocService;
|
||||||
import stirling.software.common.model.enumeration.Role;
|
|
||||||
import stirling.software.common.service.UserServiceInterface;
|
import stirling.software.common.service.UserServiceInterface;
|
||||||
import stirling.software.common.util.TempFile;
|
import stirling.software.common.util.TempFile;
|
||||||
import stirling.software.common.util.TempFileManager;
|
import stirling.software.common.util.TempFileManager;
|
||||||
@@ -84,9 +83,35 @@ public class PipelineProcessor {
|
|||||||
return name.substring(0, underscoreIndex) + extension;
|
return name.substring(0, underscoreIndex) + extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allowlist of URL path prefixes permitted through the pipeline.
|
||||||
|
private static final List<String> ALLOWED_PIPELINE_PATH_PREFIXES =
|
||||||
|
List.of(
|
||||||
|
"/api/v1/general/",
|
||||||
|
"/api/v1/misc/",
|
||||||
|
"/api/v1/security/",
|
||||||
|
"/api/v1/convert/",
|
||||||
|
"/api/v1/filter/");
|
||||||
|
|
||||||
|
private void validatePipelineUrl(String url) {
|
||||||
|
// Strip scheme+host to get the path portion for comparison
|
||||||
|
String path = url;
|
||||||
|
int schemeEnd = url.indexOf("://");
|
||||||
|
if (schemeEnd != -1) {
|
||||||
|
int pathStart = url.indexOf('/', schemeEnd + 3);
|
||||||
|
path = pathStart != -1 ? url.substring(pathStart) : "/";
|
||||||
|
}
|
||||||
|
final String pathToCheck = path;
|
||||||
|
boolean allowed = ALLOWED_PIPELINE_PATH_PREFIXES.stream().anyMatch(pathToCheck::contains);
|
||||||
|
if (!allowed) {
|
||||||
|
log.warn("Blocked pipeline request to disallowed URL: {}", url);
|
||||||
|
throw new SecurityException(
|
||||||
|
"Pipeline operation not permitted for endpoint: " + pathToCheck);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String getApiKeyForUser() {
|
private String getApiKeyForUser() {
|
||||||
if (userService == null) return "";
|
if (userService == null) return "";
|
||||||
return userService.getApiKeyForUser(Role.INTERNAL_API_USER.getRoleId());
|
return userService.getCurrentUserApiKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getBaseUrl() {
|
private String getBaseUrl() {
|
||||||
@@ -283,6 +308,7 @@ public class PipelineProcessor {
|
|||||||
|
|
||||||
/* package */ ResponseEntity<Resource> sendWebRequest(
|
/* package */ ResponseEntity<Resource> sendWebRequest(
|
||||||
String url, MultiValueMap<String, Object> body) {
|
String url, MultiValueMap<String, Object> body) {
|
||||||
|
validatePipelineUrl(url);
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
RestTemplate restTemplate = new RestTemplate();
|
||||||
// Set up headers, including API key
|
// Set up headers, including API key
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
|||||||
+2
-1
@@ -205,7 +205,8 @@ class PipelineProcessorTest {
|
|||||||
});
|
});
|
||||||
})) {
|
})) {
|
||||||
ResponseEntity<Resource> response =
|
ResponseEntity<Resource> response =
|
||||||
pipelineProcessor.sendWebRequest("http://localhost/api", body);
|
pipelineProcessor.sendWebRequest(
|
||||||
|
"http://localhost/api/v1/general/merge-pdfs", body);
|
||||||
|
|
||||||
assertNotNull(response);
|
assertNotNull(response);
|
||||||
assertEquals(HttpStatus.OK, response.getStatusCode());
|
assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
+9
@@ -198,6 +198,15 @@ public class UserService implements UserServiceInterface {
|
|||||||
return user.getApiKey();
|
return user.getApiKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentUserApiKey() {
|
||||||
|
String username = getCurrentUsername();
|
||||||
|
if (username == null || username.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Cannot determine calling user for API key lookup");
|
||||||
|
}
|
||||||
|
return getApiKeyForUser(username);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValidApiKey(String apiKey) {
|
public boolean isValidApiKey(String apiKey) {
|
||||||
return userRepository.findByApiKey(apiKey).isPresent();
|
return userRepository.findByApiKey(apiKey).isPresent();
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ ext {
|
|||||||
springSecuritySamlVersion = "7.0.2"
|
springSecuritySamlVersion = "7.0.2"
|
||||||
openSamlVersion = "5.2.1"
|
openSamlVersion = "5.2.1"
|
||||||
commonmarkVersion = "0.27.1"
|
commonmarkVersion = "0.27.1"
|
||||||
googleJavaFormatVersion = "1.35.0"
|
googleJavaFormatVersion = "1.28.0"
|
||||||
logback = "1.5.32"
|
logback = "1.5.32"
|
||||||
junitPlatformVersion = "1.12.2"
|
junitPlatformVersion = "1.12.2"
|
||||||
modernJavaVersion = 21
|
modernJavaVersion = 21
|
||||||
@@ -78,7 +78,7 @@ springBoot {
|
|||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
group = 'stirling.software'
|
group = 'stirling.software'
|
||||||
version = '2.8.0'
|
version = '2.9.0'
|
||||||
|
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
|
exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||||
"productName": "Stirling-PDF",
|
"productName": "Stirling-PDF",
|
||||||
"version": "2.8.0",
|
"version": "2.9.0",
|
||||||
"identifier": "stirling.pdf.dev",
|
"identifier": "stirling.pdf.dev",
|
||||||
"build": {
|
"build": {
|
||||||
"frontendDist": "../dist",
|
"frontendDist": "../dist",
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
|
|||||||
|
|
||||||
const BASE_NO_LOGIN_CONFIG: AppConfig = {
|
const BASE_NO_LOGIN_CONFIG: AppConfig = {
|
||||||
enableAnalytics: true,
|
enableAnalytics: true,
|
||||||
appVersion: '2.8.0',
|
appVersion: '2.9.0',
|
||||||
serverCertificateEnabled: false,
|
serverCertificateEnabled: false,
|
||||||
enableAlphaFunctionality: false,
|
enableAlphaFunctionality: false,
|
||||||
serverPort: 8080,
|
serverPort: 8080,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const FREE_LICENSE_INFO: LicenseInfo = {
|
|||||||
|
|
||||||
const BASE_NO_LOGIN_CONFIG: AppConfig = {
|
const BASE_NO_LOGIN_CONFIG: AppConfig = {
|
||||||
enableAnalytics: true,
|
enableAnalytics: true,
|
||||||
appVersion: '2.8.0',
|
appVersion: '2.9.0',
|
||||||
serverCertificateEnabled: false,
|
serverCertificateEnabled: false,
|
||||||
enableAlphaFunctionality: false,
|
enableAlphaFunctionality: false,
|
||||||
enableDesktopInstallSlide: true,
|
enableDesktopInstallSlide: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user