-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
bin/ | ||
tmp/ | ||
*.tmp | ||
*.bak | ||
*.exe | ||
*.swp | ||
*~.nib | ||
local.properties | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package stirling.software.SPDF.controller.web; | ||
|
||
import java.io.IOException; | ||
|
||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
|
||
import stirling.software.SPDF.service.SignatureService; | ||
|
||
@Controller | ||
@RequestMapping("/api/v1/general/") | ||
public class SignatureController { | ||
|
||
@Autowired private SignatureService signatureService; | ||
|
||
@GetMapping("/sign/{fileName}") | ||
public ResponseEntity<byte[]> getSignature( | ||
@PathVariable(name = "fileName") String fileName, Authentication authentication) | ||
throws IOException { | ||
String username = authentication.getName(); | ||
|
||
// Verify access permission | ||
if (!signatureService.hasAccessToFile(username, fileName)) { | ||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); | ||
} | ||
|
||
byte[] imageBytes = signatureService.getSignatureBytes(username, fileName); | ||
return ResponseEntity.ok() | ||
.contentType(MediaType.IMAGE_JPEG) // Adjust based on file type | ||
.body(imageBytes); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package stirling.software.SPDF.model; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
|
||
@Data | ||
@AllArgsConstructor | ||
public class SignatureFile { | ||
private String fileName; | ||
private String category; // "Personal" or "Shared" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package stirling.software.SPDF.service; | ||
|
||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.thymeleaf.util.StringUtils; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
import stirling.software.SPDF.model.SignatureFile; | ||
|
||
@Service | ||
@Slf4j | ||
public class SignatureService { | ||
|
||
private static final String SIGNATURE_BASE_PATH = "customFiles/static/signatures/"; | ||
private static final String ALL_USERS_FOLDER = "ALL_USERS"; | ||
|
||
public boolean hasAccessToFile(String username, String fileName) throws IOException { | ||
// Check if file exists in user's personal folder or ALL_USERS folder | ||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName); | ||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName); | ||
|
||
return Files.exists(userPath) || Files.exists(allUsersPath); | ||
Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading |
||
} | ||
|
||
public List<SignatureFile> getAvailableSignatures(String username) { | ||
List<SignatureFile> signatures = new ArrayList<>(); | ||
|
||
// Get signatures from user's personal folder | ||
if (!StringUtils.isEmptyOrWhitespace(username)) { | ||
Path userFolder = Paths.get(SIGNATURE_BASE_PATH, username); | ||
if (Files.exists(userFolder)) { | ||
try { | ||
signatures.addAll(getSignaturesFromFolder(userFolder, "Personal")); | ||
} catch (IOException e) { | ||
log.error("Error reading user signatures folder", e); | ||
} | ||
} | ||
} | ||
|
||
// Get signatures from ALL_USERS folder | ||
Path allUsersFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER); | ||
if (Files.exists(allUsersFolder)) { | ||
try { | ||
signatures.addAll(getSignaturesFromFolder(allUsersFolder, "Shared")); | ||
} catch (IOException e) { | ||
log.error("Error reading shared signatures folder", e); | ||
} | ||
} | ||
|
||
return signatures; | ||
} | ||
|
||
private List<SignatureFile> getSignaturesFromFolder(Path folder, String category) | ||
throws IOException { | ||
return Files.list(folder) | ||
.filter(path -> isImageFile(path)) | ||
.map(path -> new SignatureFile(path.getFileName().toString(), category)) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
public byte[] getSignatureBytes(String username, String fileName) throws IOException { | ||
// First try user's personal folder | ||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName); | ||
if (Files.exists(userPath)) { | ||
Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading |
||
return Files.readAllBytes(userPath); | ||
Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading |
||
} | ||
|
||
// Then try ALL_USERS folder | ||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName); | ||
if (Files.exists(allUsersPath)) { | ||
Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading |
||
return Files.readAllBytes(allUsersPath); | ||
Check failure Code scanning / CodeQL Uncontrolled data used in path expression High
This path depends on a
user-provided value Error loading related location Loading |
||
} | ||
|
||
throw new FileNotFoundException("Signature file not found"); | ||
} | ||
|
||
private boolean isImageFile(Path path) { | ||
String fileName = path.getFileName().toString().toLowerCase(); | ||
return fileName.endsWith(".jpg") | ||
|| fileName.endsWith(".jpeg") | ||
|| fileName.endsWith(".png") | ||
|| fileName.endsWith(".gif"); | ||
} | ||
} |