mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-02 21:03:34 +03:00
refactor(api): standardize syntax and simplify type declarations across security, workflow, and controller modules (#7127)
Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com>
This commit is contained in:
co-authored by
Anthony Stirling
parent
0b7b4e02c2
commit
34694c6f5e
@@ -237,7 +237,7 @@ public class TabulaTableParser implements TableParser {
|
|||||||
score -= 0.3f;
|
score -= 0.3f;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Math.max(0f, Math.min(1f, score));
|
return Math.clamp(score, 0f, 1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bounds tableBounds(Table table) {
|
private Bounds tableBounds(Table table) {
|
||||||
|
|||||||
+2
-1
@@ -15,7 +15,8 @@ public class StringToMapPropertyEditor extends PropertyEditorSupport {
|
|||||||
@Override
|
@Override
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
try {
|
try {
|
||||||
TypeReference<HashMap<String, String>> typeRef = new TypeReference<>() {};
|
TypeReference<HashMap<String, String>> typeRef =
|
||||||
|
new TypeReference<HashMap<String, String>>() {};
|
||||||
Map<String, String> map = objectMapper.readValue(text, typeRef);
|
Map<String, String> map = objectMapper.readValue(text, typeRef);
|
||||||
setValue(map);
|
setValue(map);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
+1
-1
@@ -237,7 +237,7 @@ public class EditTextController {
|
|||||||
|
|
||||||
Matcher matcher = edit.pattern().matcher(joined);
|
Matcher matcher = edit.pattern().matcher(joined);
|
||||||
List<MatchSpan> spans = new ArrayList<>();
|
List<MatchSpan> spans = new ArrayList<>();
|
||||||
StringBuffer interpolation = new StringBuffer();
|
StringBuilder interpolation = new StringBuilder();
|
||||||
int previousAppendPosition = 0;
|
int previousAppendPosition = 0;
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
if (matcher.start() == matcher.end()) {
|
if (matcher.start() == matcher.end()) {
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ public class UIDataController {
|
|||||||
|
|
||||||
try (InputStream is = resource.getInputStream()) {
|
try (InputStream is = resource.getInputStream()) {
|
||||||
Map<String, List<Dependency>> licenseData =
|
Map<String, List<Dependency>> licenseData =
|
||||||
objectMapper.readValue(is, new TypeReference<>() {});
|
objectMapper.readValue(
|
||||||
|
is, new TypeReference<Map<String, List<Dependency>>>() {});
|
||||||
data.setDependencies(licenseData.get("dependencies"));
|
data.setDependencies(licenseData.get("dependencies"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Failed to load licenses data", e);
|
log.error("Failed to load licenses data", e);
|
||||||
|
|||||||
+6
-3
@@ -25,12 +25,15 @@ final class FormPayloadParser {
|
|||||||
private static final String KEY_VALUE = "value";
|
private static final String KEY_VALUE = "value";
|
||||||
private static final String KEY_DEFAULT_VALUE = "defaultValue";
|
private static final String KEY_DEFAULT_VALUE = "defaultValue";
|
||||||
|
|
||||||
private static final TypeReference<Map<String, Object>> MAP_TYPE = new TypeReference<>() {};
|
private static final TypeReference<Map<String, Object>> MAP_TYPE =
|
||||||
|
new TypeReference<Map<String, Object>>() {};
|
||||||
private static final TypeReference<List<FormUtils.ModifyFormFieldDefinition>>
|
private static final TypeReference<List<FormUtils.ModifyFormFieldDefinition>>
|
||||||
MODIFY_FIELD_LIST_TYPE = new TypeReference<>() {};
|
MODIFY_FIELD_LIST_TYPE =
|
||||||
|
new TypeReference<List<FormUtils.ModifyFormFieldDefinition>>() {};
|
||||||
private static final TypeReference<List<FormUtils.NewFormFieldDefinition>> NEW_FIELD_LIST_TYPE =
|
private static final TypeReference<List<FormUtils.NewFormFieldDefinition>> NEW_FIELD_LIST_TYPE =
|
||||||
new TypeReference<>() {};
|
new TypeReference<>() {};
|
||||||
private static final TypeReference<List<String>> STRING_LIST_TYPE = new TypeReference<>() {};
|
private static final TypeReference<List<String>> STRING_LIST_TYPE =
|
||||||
|
new TypeReference<List<String>>() {};
|
||||||
|
|
||||||
private FormPayloadParser() {}
|
private FormPayloadParser() {}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -96,7 +96,9 @@ public class AddCommentsController {
|
|||||||
|
|
||||||
List<CommentSpecDto> dtos;
|
List<CommentSpecDto> dtos;
|
||||||
try {
|
try {
|
||||||
dtos = objectMapper.readValue(commentsJson, new TypeReference<>() {});
|
dtos =
|
||||||
|
objectMapper.readValue(
|
||||||
|
commentsJson, new TypeReference<List<CommentSpecDto>>() {});
|
||||||
} catch (JacksonException e) {
|
} catch (JacksonException e) {
|
||||||
throw new ResponseStatusException(
|
throw new ResponseStatusException(
|
||||||
HttpStatus.BAD_REQUEST, "comments must be a JSON array of CommentSpec objects");
|
HttpStatus.BAD_REQUEST, "comments must be a JSON array of CommentSpec objects");
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public enum AuditLevel {
|
|||||||
*/
|
*/
|
||||||
public static AuditLevel fromInt(int level) {
|
public static AuditLevel fromInt(int level) {
|
||||||
// Ensure level is within valid bounds
|
// Ensure level is within valid bounds
|
||||||
int boundedLevel = Math.min(Math.max(level, 0), 3);
|
int boundedLevel = Math.clamp(level, 0, 3);
|
||||||
|
|
||||||
for (AuditLevel auditLevel : values()) {
|
for (AuditLevel auditLevel : values()) {
|
||||||
if (auditLevel.level == boundedLevel) {
|
if (auditLevel.level == boundedLevel) {
|
||||||
|
|||||||
+4
-2
@@ -44,8 +44,10 @@ public class ValkeyJobStore implements JobStore {
|
|||||||
private static final String FILE_INDEX_PREFIX = "stirling:file2job:";
|
private static final String FILE_INDEX_PREFIX = "stirling:file2job:";
|
||||||
|
|
||||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
private static final TypeReference<List<String>> LIST_STRING = new TypeReference<>() {};
|
private static final TypeReference<List<String>> LIST_STRING =
|
||||||
private static final TypeReference<Map<String, String>> MAP_STRING = new TypeReference<>() {};
|
new TypeReference<List<String>>() {};
|
||||||
|
private static final TypeReference<Map<String, String>> MAP_STRING =
|
||||||
|
new TypeReference<Map<String, String>>() {};
|
||||||
|
|
||||||
private final StringRedisTemplate template;
|
private final StringRedisTemplate template;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ public class AuditConfigurationProperties {
|
|||||||
|
|
||||||
// Ensure level is within valid bounds (0-3)
|
// Ensure level is within valid bounds (0-3)
|
||||||
int configLevel = auditConfig.getLevel();
|
int configLevel = auditConfig.getLevel();
|
||||||
this.level = Math.min(Math.max(configLevel, 0), 3);
|
this.level = Math.clamp(configLevel, 0, 3);
|
||||||
|
|
||||||
// Retention days (0 means infinite)
|
// Retention days (0 means infinite)
|
||||||
this.retentionDays = auditConfig.getRetentionDays();
|
this.retentionDays = auditConfig.getRetentionDays();
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ public class UsageRestController {
|
|||||||
@RequestParam(value = "dataType", defaultValue = "all") String dataType,
|
@RequestParam(value = "dataType", defaultValue = "all") String dataType,
|
||||||
@RequestParam(value = "days", defaultValue = "30") Integer days) {
|
@RequestParam(value = "days", defaultValue = "30") Integer days) {
|
||||||
|
|
||||||
int lookbackDays = Math.max(1, Math.min(days, 365));
|
int lookbackDays = Math.clamp(days, 1, 365);
|
||||||
|
|
||||||
// Get audit events filtered by type
|
// Get audit events filtered by type
|
||||||
List<PersistentAuditEvent> events = getEventsByDataType(dataType, lookbackDays);
|
List<PersistentAuditEvent> events = getEventsByDataType(dataType, lookbackDays);
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.model;
|
package stirling.software.proprietary.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
@@ -19,7 +20,7 @@ import lombok.*;
|
|||||||
@ToString
|
@ToString
|
||||||
public class UserLicenseSettings implements Serializable {
|
public class UserLicenseSettings implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public static final Long SINGLETON_ID = 1L;
|
public static final Long SINGLETON_ID = 1L;
|
||||||
|
|
||||||
|
|||||||
+17
-15
@@ -70,21 +70,23 @@ public class CustomLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
|
|||||||
|
|
||||||
if (!response.isCommitted()) {
|
if (!response.isCommitted()) {
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
if (authentication instanceof Saml2Authentication samlAuthentication) {
|
switch (authentication) {
|
||||||
// Handle SAML2 logout redirection
|
case Saml2Authentication samlAuthentication ->
|
||||||
getRedirect_saml2(request, response, samlAuthentication);
|
// Handle SAML2 logout redirection
|
||||||
} else if (authentication instanceof OAuth2AuthenticationToken oAuthToken) {
|
getRedirect_saml2(request, response, samlAuthentication);
|
||||||
// Handle OAuth2 logout redirection
|
case OAuth2AuthenticationToken oAuthToken ->
|
||||||
getRedirect_oauth2(request, response, oAuthToken);
|
// Handle OAuth2 logout redirection
|
||||||
} else if (authentication instanceof UsernamePasswordAuthenticationToken) {
|
getRedirect_oauth2(request, response, oAuthToken);
|
||||||
// Handle Username/Password logout
|
case UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken ->
|
||||||
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
// Handle Username/Password logout
|
||||||
} else {
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
// Handle unknown authentication types
|
default -> {
|
||||||
log.error(
|
// Handle unknown authentication types
|
||||||
"Authentication class unknown: {}",
|
log.error(
|
||||||
authentication.getClass().getSimpleName());
|
"Authentication class unknown: {}",
|
||||||
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
authentication.getClass().getSimpleName());
|
||||||
|
getRedirectStrategy().sendRedirect(request, response, LOGOUT_PATH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (jwtService != null) {
|
if (jwtService != null) {
|
||||||
|
|||||||
+34
-34
@@ -392,40 +392,40 @@ public class SecurityConfiguration {
|
|||||||
// Handle OAUTH2 Logins
|
// Handle OAUTH2 Logins
|
||||||
if (securityProperties.isOauth2Active()) {
|
if (securityProperties.isOauth2Active()) {
|
||||||
http.oauth2Login(
|
http.oauth2Login(
|
||||||
oauth2 -> {
|
oauth2 ->
|
||||||
oauth2.loginPage("/login")
|
oauth2.loginPage("/login")
|
||||||
.authorizationEndpoint(
|
.authorizationEndpoint(
|
||||||
authorizationEndpoint -> {
|
authorizationEndpoint -> {
|
||||||
if (clientRegistrationRepository != null) {
|
if (clientRegistrationRepository != null) {
|
||||||
authorizationEndpoint
|
authorizationEndpoint
|
||||||
.authorizationRequestResolver(
|
.authorizationRequestResolver(
|
||||||
new TauriAuthorizationRequestResolver(
|
new TauriAuthorizationRequestResolver(
|
||||||
clientRegistrationRepository));
|
clientRegistrationRepository));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.successHandler(
|
.successHandler(
|
||||||
new CustomOAuth2AuthenticationSuccessHandler(
|
new CustomOAuth2AuthenticationSuccessHandler(
|
||||||
loginAttemptService,
|
loginAttemptService,
|
||||||
securityProperties.getOauth2(),
|
securityProperties.getOauth2(),
|
||||||
userService,
|
userService,
|
||||||
jwtService,
|
jwtService,
|
||||||
licenseSettingsService,
|
licenseSettingsService,
|
||||||
applicationProperties))
|
applicationProperties))
|
||||||
.failureHandler(new CustomOAuth2AuthenticationFailureHandler())
|
.failureHandler(
|
||||||
// Add existing Authorities from the database
|
new CustomOAuth2AuthenticationFailureHandler())
|
||||||
.userInfoEndpoint(
|
// Add existing Authorities from the database
|
||||||
userInfoEndpoint ->
|
.userInfoEndpoint(
|
||||||
userInfoEndpoint
|
userInfoEndpoint ->
|
||||||
.oidcUserService(
|
userInfoEndpoint
|
||||||
new CustomOAuth2UserService(
|
.oidcUserService(
|
||||||
securityProperties
|
new CustomOAuth2UserService(
|
||||||
.getOauth2(),
|
securityProperties
|
||||||
userService,
|
.getOauth2(),
|
||||||
loginAttemptService))
|
userService,
|
||||||
.userAuthoritiesMapper(
|
loginAttemptService))
|
||||||
oAuth2userAuthoritiesMapper))
|
.userAuthoritiesMapper(
|
||||||
.permitAll();
|
oAuth2userAuthoritiesMapper))
|
||||||
});
|
.permitAll());
|
||||||
}
|
}
|
||||||
// Handle SAML
|
// Handle SAML
|
||||||
if (securityProperties.isSaml2Active() && runningProOrHigher) {
|
if (securityProperties.isSaml2Active() && runningProOrHigher) {
|
||||||
|
|||||||
+12
-11
@@ -703,17 +703,18 @@ public class AuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long extractEpochMillis(Object claimValue) {
|
private long extractEpochMillis(Object claimValue) {
|
||||||
if (claimValue == null) {
|
switch (claimValue) {
|
||||||
return -1L;
|
case null -> {
|
||||||
}
|
return -1L;
|
||||||
|
}
|
||||||
if (claimValue instanceof java.util.Date date) {
|
case java.util.Date date -> {
|
||||||
return date.getTime();
|
return date.getTime();
|
||||||
}
|
}
|
||||||
|
case Number number -> {
|
||||||
if (claimValue instanceof Number number) {
|
long epochSeconds = number.longValue();
|
||||||
long epochSeconds = number.longValue();
|
return epochSeconds * 1000L;
|
||||||
return epochSeconds * 1000L;
|
}
|
||||||
|
default -> {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1L;
|
return -1L;
|
||||||
|
|||||||
+8
-8
@@ -760,14 +760,14 @@ public class UserController {
|
|||||||
for (Object principal : principals) {
|
for (Object principal : principals) {
|
||||||
List<SessionInformation> sessionsInformation =
|
List<SessionInformation> sessionsInformation =
|
||||||
sessionRegistry.getAllSessions(principal, false);
|
sessionRegistry.getAllSessions(principal, false);
|
||||||
if (principal instanceof UserDetails detailsUser) {
|
switch (principal) {
|
||||||
userNameP = detailsUser.getUsername();
|
case null -> {}
|
||||||
} else if (principal instanceof OAuth2User oAuth2User) {
|
case UserDetails detailsUser -> userNameP = detailsUser.getUsername();
|
||||||
userNameP = oAuth2User.getName();
|
case OAuth2User oAuth2User -> userNameP = oAuth2User.getName();
|
||||||
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) {
|
case CustomSaml2AuthenticatedPrincipal saml2User ->
|
||||||
userNameP = saml2User.name();
|
userNameP = saml2User.name();
|
||||||
} else if (principal instanceof String stringUser) {
|
case String stringUser -> userNameP = stringUser;
|
||||||
userNameP = stringUser;
|
default -> {}
|
||||||
}
|
}
|
||||||
if (userNameP.equalsIgnoreCase(username)) {
|
if (userNameP.equalsIgnoreCase(username)) {
|
||||||
for (SessionInformation sessionInfo : sessionsInformation) {
|
for (SessionInformation sessionInfo : sessionsInformation) {
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.security.model;
|
package stirling.software.proprietary.security.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
@@ -28,7 +29,7 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class Authority implements GrantedAuthority, Serializable {
|
public class Authority implements GrantedAuthority, Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.security.model;
|
package stirling.software.proprietary.security.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class InviteToken implements Serializable {
|
public class InviteToken implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+52
-47
@@ -36,57 +36,62 @@ public class CustomOAuth2AuthenticationFailureHandler
|
|||||||
AuthenticationException exception)
|
AuthenticationException exception)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
if (exception instanceof BadCredentialsException) {
|
switch (exception) {
|
||||||
log.error("BadCredentialsException", exception);
|
case BadCredentialsException badCredentialsException -> {
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/login?error=badCredentials");
|
log.error("BadCredentialsException", exception);
|
||||||
return;
|
getRedirectStrategy()
|
||||||
}
|
.sendRedirect(request, response, "/login?error=badCredentials");
|
||||||
if (exception instanceof DisabledException) {
|
return;
|
||||||
log.error("User is deactivated: ", exception);
|
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/logout?userIsDisabled=true");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (exception instanceof LockedException) {
|
|
||||||
log.error("Account locked: ", exception);
|
|
||||||
getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (exception instanceof OAuth2AuthenticationException oAuth2Exception) {
|
|
||||||
OAuth2Error error = oAuth2Exception.getError();
|
|
||||||
|
|
||||||
String errorCode = error.getErrorCode();
|
|
||||||
|
|
||||||
if ("Password must not be null".equals(error.getErrorCode())) {
|
|
||||||
errorCode = "userAlreadyExistsWeb";
|
|
||||||
}
|
}
|
||||||
|
case DisabledException disabledException -> {
|
||||||
|
log.error("User is deactivated: ", exception);
|
||||||
|
getRedirectStrategy()
|
||||||
|
.sendRedirect(request, response, "/logout?userIsDisabled=true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case LockedException lockedException -> {
|
||||||
|
log.error("Account locked: ", exception);
|
||||||
|
getRedirectStrategy().sendRedirect(request, response, "/logout?error=locked");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case OAuth2AuthenticationException oAuth2Exception -> {
|
||||||
|
OAuth2Error error = oAuth2Exception.getError();
|
||||||
|
|
||||||
log.error(
|
String errorCode = error.getErrorCode();
|
||||||
"OAuth2 Authentication error: {}",
|
|
||||||
errorCode != null ? errorCode : exception.getMessage(),
|
if ("Password must not be null".equals(error.getErrorCode())) {
|
||||||
exception);
|
errorCode = "userAlreadyExistsWeb";
|
||||||
String errorValue = errorCode != null ? errorCode : "oauth2AuthenticationError";
|
|
||||||
clearRedirectCookie(response);
|
|
||||||
boolean tauriState = TauriOAuthUtils.isTauriState(request);
|
|
||||||
String redirectUrl;
|
|
||||||
if (tauriState) {
|
|
||||||
String basePath =
|
|
||||||
TauriOAuthUtils.defaultTauriCallbackPath(request.getContextPath());
|
|
||||||
redirectUrl = basePath;
|
|
||||||
String stateParam = request.getParameter("state");
|
|
||||||
if (stateParam != null && !stateParam.isBlank()) {
|
|
||||||
redirectUrl = appendQueryParam(redirectUrl, "state", stateParam);
|
|
||||||
// Extract and pass nonce for CSRF validation
|
|
||||||
String nonce = TauriOAuthUtils.extractNonceFromState(stateParam);
|
|
||||||
if (nonce != null) {
|
|
||||||
redirectUrl = appendQueryParam(redirectUrl, "nonce", nonce);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
redirectUrl = appendQueryParam(redirectUrl, "errorOAuth", errorValue);
|
|
||||||
} else {
|
log.error(
|
||||||
redirectUrl = buildFailureRedirectUrl(request, errorValue);
|
"OAuth2 Authentication error: {}",
|
||||||
|
errorCode != null ? errorCode : exception.getMessage(),
|
||||||
|
exception);
|
||||||
|
String errorValue = errorCode != null ? errorCode : "oauth2AuthenticationError";
|
||||||
|
clearRedirectCookie(response);
|
||||||
|
boolean tauriState = TauriOAuthUtils.isTauriState(request);
|
||||||
|
String redirectUrl;
|
||||||
|
if (tauriState) {
|
||||||
|
String basePath =
|
||||||
|
TauriOAuthUtils.defaultTauriCallbackPath(request.getContextPath());
|
||||||
|
redirectUrl = basePath;
|
||||||
|
String stateParam = request.getParameter("state");
|
||||||
|
if (stateParam != null && !stateParam.isBlank()) {
|
||||||
|
redirectUrl = appendQueryParam(redirectUrl, "state", stateParam);
|
||||||
|
// Extract and pass nonce for CSRF validation
|
||||||
|
String nonce = TauriOAuthUtils.extractNonceFromState(stateParam);
|
||||||
|
if (nonce != null) {
|
||||||
|
redirectUrl = appendQueryParam(redirectUrl, "nonce", nonce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
redirectUrl = appendQueryParam(redirectUrl, "errorOAuth", errorValue);
|
||||||
|
} else {
|
||||||
|
redirectUrl = buildFailureRedirectUrl(request, errorValue);
|
||||||
|
}
|
||||||
|
getRedirectStrategy().sendRedirect(request, response, redirectUrl);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
getRedirectStrategy().sendRedirect(request, response, redirectUrl);
|
default -> {}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
log.error("Unhandled authentication exception", exception);
|
log.error("Unhandled authentication exception", exception);
|
||||||
super.onAuthenticationFailure(request, response, exception);
|
super.onAuthenticationFailure(request, response, exception);
|
||||||
|
|||||||
+6
-1
@@ -61,7 +61,12 @@ public class CustomSaml2ResponseAuthenticationConverter
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Saml2Authentication convert(ResponseToken responseToken) {
|
public Saml2Authentication convert(ResponseToken responseToken) {
|
||||||
Assertion assertion = responseToken.getResponse().getAssertions().getFirst();
|
List<Assertion> assertions = responseToken.getResponse().getAssertions();
|
||||||
|
if (assertions == null || assertions.isEmpty()) {
|
||||||
|
log.error("SAML response contains no assertions");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Assertion assertion = assertions.getFirst();
|
||||||
Map<String, List<Object>> attributes = extractAttributes(assertion);
|
Map<String, List<Object>> attributes = extractAttributes(assertion);
|
||||||
|
|
||||||
// Debug log with actual values
|
// Debug log with actual values
|
||||||
|
|||||||
+5
-2
@@ -213,8 +213,11 @@ public class CustomOAuth2UserService implements OAuth2UserService<OidcUserReques
|
|||||||
}
|
}
|
||||||
|
|
||||||
sb.append(
|
sb.append(
|
||||||
"\nWARNING: this block contains PII. Set security.oauth2.debugLogging=false once"
|
"""
|
||||||
+ " troubleshooting is complete.\n");
|
|
||||||
|
WARNING: this block contains PII. Set security.oauth2.debugLogging=false once\
|
||||||
|
troubleshooting is complete.
|
||||||
|
""");
|
||||||
sb.append("========== [/OAUTH2 DEBUG] ==========");
|
sb.append("========== [/OAUTH2 DEBUG] ==========");
|
||||||
|
|
||||||
if (failure) {
|
if (failure) {
|
||||||
|
|||||||
+3
-1
@@ -132,7 +132,9 @@ public class KeyPersistenceService implements KeyPersistenceServiceInterface {
|
|||||||
verifyingKeyCache.put(
|
verifyingKeyCache.put(
|
||||||
key.getKeyId(), new JwtVerificationKey(key.getKeyId(), key.getVerifyingKey()));
|
key.getKeyId(), new JwtVerificationKey(key.getKeyId(), key.getVerifyingKey()));
|
||||||
}
|
}
|
||||||
activeKey = new JwtVerificationKey(keys.get(0).getKeyId(), keys.get(0).getVerifyingKey());
|
activeKey =
|
||||||
|
new JwtVerificationKey(
|
||||||
|
keys.getFirst().getKeyId(), keys.getFirst().getVerifyingKey());
|
||||||
log.info("Loaded {} JWT key(s) from DB, active key: {}", keys.size(), activeKey.getKeyId());
|
log.info("Loaded {} JWT key(s) from DB, active key: {}", keys.size(), activeKey.getKeyId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -640,14 +640,14 @@ public class UserService implements UserServiceInterface {
|
|||||||
for (Object principal : sessionRegistry.getAllPrincipals()) {
|
for (Object principal : sessionRegistry.getAllPrincipals()) {
|
||||||
for (SessionInformation sessionsInformation :
|
for (SessionInformation sessionsInformation :
|
||||||
sessionRegistry.getAllSessions(principal, false)) {
|
sessionRegistry.getAllSessions(principal, false)) {
|
||||||
if (principal instanceof UserDetails detailsUser) {
|
switch (principal) {
|
||||||
usernameP = detailsUser.getUsername();
|
case null -> {}
|
||||||
} else if (principal instanceof OAuth2User oAuth2User) {
|
case UserDetails detailsUser -> usernameP = detailsUser.getUsername();
|
||||||
usernameP = oAuth2User.getName();
|
case OAuth2User oAuth2User -> usernameP = oAuth2User.getName();
|
||||||
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) {
|
case CustomSaml2AuthenticatedPrincipal saml2User ->
|
||||||
usernameP = saml2User.name();
|
usernameP = saml2User.name();
|
||||||
} else if (principal instanceof String stringUser) {
|
case String stringUser -> usernameP = stringUser;
|
||||||
usernameP = stringUser;
|
default -> {}
|
||||||
}
|
}
|
||||||
if (usernameP.equalsIgnoreCase(username)) {
|
if (usernameP.equalsIgnoreCase(username)) {
|
||||||
sessionRegistry.expireSession(sessionsInformation.getSessionId());
|
sessionRegistry.expireSession(sessionsInformation.getSessionId());
|
||||||
|
|||||||
+14
-16
@@ -47,14 +47,13 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
|||||||
List<SessionInformation> sessionInformations = new ArrayList<>();
|
List<SessionInformation> sessionInformations = new ArrayList<>();
|
||||||
String principalName = null;
|
String principalName = null;
|
||||||
|
|
||||||
if (principal instanceof UserDetails detailsUser) {
|
switch (principal) {
|
||||||
principalName = detailsUser.getUsername();
|
case null -> {}
|
||||||
} else if (principal instanceof OAuth2User oAuth2User) {
|
case UserDetails detailsUser -> principalName = detailsUser.getUsername();
|
||||||
principalName = oAuth2User.getName();
|
case OAuth2User oAuth2User -> principalName = oAuth2User.getName();
|
||||||
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) {
|
case CustomSaml2AuthenticatedPrincipal saml2User -> principalName = saml2User.name();
|
||||||
principalName = saml2User.name();
|
case String stringUser -> principalName = stringUser;
|
||||||
} else if (principal instanceof String stringUser) {
|
default -> {}
|
||||||
principalName = stringUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (principalName != null) {
|
if (principalName != null) {
|
||||||
@@ -78,14 +77,13 @@ public class SessionPersistentRegistry implements SessionRegistry {
|
|||||||
public void registerNewSession(String sessionId, Object principal) {
|
public void registerNewSession(String sessionId, Object principal) {
|
||||||
String principalName = null;
|
String principalName = null;
|
||||||
|
|
||||||
if (principal instanceof UserDetails detailsUser) {
|
switch (principal) {
|
||||||
principalName = detailsUser.getUsername();
|
case null -> {}
|
||||||
} else if (principal instanceof OAuth2User oAuth2User) {
|
case UserDetails detailsUser -> principalName = detailsUser.getUsername();
|
||||||
principalName = oAuth2User.getName();
|
case OAuth2User oAuth2User -> principalName = oAuth2User.getName();
|
||||||
} else if (principal instanceof CustomSaml2AuthenticatedPrincipal saml2User) {
|
case CustomSaml2AuthenticatedPrincipal saml2User -> principalName = saml2User.name();
|
||||||
principalName = saml2User.name();
|
case String stringUser -> principalName = stringUser;
|
||||||
} else if (principal instanceof String stringUser) {
|
default -> {}
|
||||||
principalName = stringUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (principalName != null) {
|
if (principalName != null) {
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.storage.model;
|
package stirling.software.proprietary.storage.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ import stirling.software.proprietary.security.model.User;
|
|||||||
@Setter
|
@Setter
|
||||||
public class FileShare implements Serializable {
|
public class FileShare implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.storage.model;
|
package stirling.software.proprietary.storage.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ import stirling.software.proprietary.security.model.User;
|
|||||||
@Setter
|
@Setter
|
||||||
public class FileShareAccess implements Serializable {
|
public class FileShareAccess implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.storage.model;
|
package stirling.software.proprietary.storage.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class StorageCleanupEntry implements Serializable {
|
public class StorageCleanupEntry implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.storage.model;
|
package stirling.software.proprietary.storage.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -45,7 +46,7 @@ import stirling.software.proprietary.workflow.model.WorkflowSession;
|
|||||||
@Setter
|
@Setter
|
||||||
public class StoredFile implements Serializable {
|
public class StoredFile implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.storage.model;
|
package stirling.software.proprietary.storage.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
@@ -19,7 +20,7 @@ import lombok.Setter;
|
|||||||
@Setter
|
@Setter
|
||||||
public class StoredFileBlob implements Serializable {
|
public class StoredFileBlob implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@Column(name = "storage_key", nullable = false, length = 128)
|
@Column(name = "storage_key", nullable = false, length = 128)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.slf4j.MDC;
|
|||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.filter.OncePerRequestFilter;
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
@@ -64,7 +65,7 @@ public class AuditWebFilter extends OncePerRequestFilter {
|
|||||||
if (auth != null && auth.getAuthorities() != null) {
|
if (auth != null && auth.getAuthorities() != null) {
|
||||||
String roles =
|
String roles =
|
||||||
auth.getAuthorities().stream()
|
auth.getAuthorities().stream()
|
||||||
.map(a -> a.getAuthority())
|
.map(GrantedAuthority::getAuthority)
|
||||||
.reduce((a, b) -> a + "," + b)
|
.reduce((a, b) -> a + "," + b)
|
||||||
.orElse("");
|
.orElse("");
|
||||||
MDC.put("userRoles", roles);
|
MDC.put("userRoles", roles);
|
||||||
|
|||||||
+4
-1
@@ -37,6 +37,7 @@ import stirling.software.proprietary.workflow.dto.CertificateInfo;
|
|||||||
import stirling.software.proprietary.workflow.dto.CertificateValidationResponse;
|
import stirling.software.proprietary.workflow.dto.CertificateValidationResponse;
|
||||||
import stirling.software.proprietary.workflow.dto.ParticipantRequest;
|
import stirling.software.proprietary.workflow.dto.ParticipantRequest;
|
||||||
import stirling.software.proprietary.workflow.dto.WorkflowCreationRequest;
|
import stirling.software.proprietary.workflow.dto.WorkflowCreationRequest;
|
||||||
|
import stirling.software.proprietary.workflow.model.WorkflowParticipant;
|
||||||
import stirling.software.proprietary.workflow.model.WorkflowSession;
|
import stirling.software.proprietary.workflow.model.WorkflowSession;
|
||||||
import stirling.software.proprietary.workflow.service.CertificateSubmissionValidator;
|
import stirling.software.proprietary.workflow.service.CertificateSubmissionValidator;
|
||||||
import stirling.software.proprietary.workflow.service.SigningFinalizationService;
|
import stirling.software.proprietary.workflow.service.SigningFinalizationService;
|
||||||
@@ -259,7 +260,9 @@ public class SigningSessionController {
|
|||||||
+ "database until manual cleanup.",
|
+ "database until manual cleanup.",
|
||||||
sessionId,
|
sessionId,
|
||||||
session.getParticipants() != null
|
session.getParticipants() != null
|
||||||
? session.getParticipants().stream().map(p -> p.getEmail()).toList()
|
? session.getParticipants().stream()
|
||||||
|
.map(WorkflowParticipant::getEmail)
|
||||||
|
.toList()
|
||||||
: "unknown",
|
: "unknown",
|
||||||
e);
|
e);
|
||||||
throw new ResponseStatusException(
|
throw new ResponseStatusException(
|
||||||
|
|||||||
+2
-1
@@ -5,6 +5,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.http.ContentDisposition;
|
import org.springframework.http.ContentDisposition;
|
||||||
@@ -429,7 +430,7 @@ public class WorkflowParticipantController {
|
|||||||
java.util.List<Map<String, Object>> wetSigs =
|
java.util.List<Map<String, Object>> wetSigs =
|
||||||
objectMapper.readValue(
|
objectMapper.readValue(
|
||||||
request.getWetSignaturesData(),
|
request.getWetSignaturesData(),
|
||||||
new TypeReference<java.util.List<Map<String, Object>>>() {});
|
new TypeReference<List<Map<String, Object>>>() {});
|
||||||
if (wetSigs.size() > WetSignatureMetadata.MAX_SIGNATURES_PER_PARTICIPANT) {
|
if (wetSigs.size() > WetSignatureMetadata.MAX_SIGNATURES_PER_PARTICIPANT) {
|
||||||
throw new ResponseStatusException(
|
throw new ResponseStatusException(
|
||||||
HttpStatus.BAD_REQUEST, "Too many wet signatures submitted");
|
HttpStatus.BAD_REQUEST, "Too many wet signatures submitted");
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.workflow.model;
|
package stirling.software.proprietary.workflow.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -51,7 +52,7 @@ import stirling.software.proprietary.storage.model.ShareAccessRole;
|
|||||||
@Setter
|
@Setter
|
||||||
public class WorkflowParticipant implements Serializable {
|
public class WorkflowParticipant implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
package stirling.software.proprietary.workflow.model;
|
package stirling.software.proprietary.workflow.model;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -53,7 +54,7 @@ import stirling.software.proprietary.storage.model.StoredFile;
|
|||||||
@Setter
|
@Setter
|
||||||
public class WorkflowSession implements Serializable {
|
public class WorkflowSession implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
@Serial private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
|||||||
+4
-10
@@ -217,16 +217,13 @@ public class SigningFinalizationService {
|
|||||||
wetSignatures.size(),
|
wetSignatures.size(),
|
||||||
session.getSessionId());
|
session.getSessionId());
|
||||||
|
|
||||||
PDDocument document = pdfDocumentFactory.load(new ByteArrayInputStream(pdfBytes));
|
try (PDDocument document = pdfDocumentFactory.load(new ByteArrayInputStream(pdfBytes))) {
|
||||||
try {
|
|
||||||
for (WetSignatureMetadata wetSig : wetSignatures) {
|
for (WetSignatureMetadata wetSig : wetSignatures) {
|
||||||
applyWetSignatureToPage(document, wetSig);
|
applyWetSignatureToPage(document, wetSig);
|
||||||
}
|
}
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
document.save(baos);
|
document.save(baos);
|
||||||
return baos.toByteArray();
|
return baos.toByteArray();
|
||||||
} finally {
|
|
||||||
document.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,11 +239,10 @@ public class SigningFinalizationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PDPage page = document.getPage(pageIndex);
|
PDPage page = document.getPage(pageIndex);
|
||||||
PDPageContentStream contentStream =
|
|
||||||
new PDPageContentStream(
|
|
||||||
document, page, PDPageContentStream.AppendMode.APPEND, true, true);
|
|
||||||
|
|
||||||
try {
|
try (PDPageContentStream contentStream =
|
||||||
|
new PDPageContentStream(
|
||||||
|
document, page, PDPageContentStream.AppendMode.APPEND, true, true)) {
|
||||||
// Use WetSignatureMetadata.extractBase64Data() to strip data URL prefix
|
// Use WetSignatureMetadata.extractBase64Data() to strip data URL prefix
|
||||||
String base64Data = wetSig.extractBase64Data();
|
String base64Data = wetSig.extractBase64Data();
|
||||||
if (base64Data == null || base64Data.isBlank()) {
|
if (base64Data == null || base64Data.isBlank()) {
|
||||||
@@ -279,8 +275,6 @@ public class SigningFinalizationService {
|
|||||||
pdfY,
|
pdfY,
|
||||||
width,
|
width,
|
||||||
height);
|
height);
|
||||||
} finally {
|
|
||||||
contentStream.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-15
@@ -954,21 +954,22 @@ public class WorkflowSessionService {
|
|||||||
Object pemObject = pemParser.readObject();
|
Object pemObject = pemParser.readObject();
|
||||||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||||
PrivateKeyInfo keyInfo;
|
PrivateKeyInfo keyInfo;
|
||||||
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo encrypted) {
|
switch (pemObject) {
|
||||||
InputDecryptorProvider decryptor =
|
case PKCS8EncryptedPrivateKeyInfo encrypted -> {
|
||||||
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password);
|
InputDecryptorProvider decryptor =
|
||||||
keyInfo = encrypted.decryptPrivateKeyInfo(decryptor);
|
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password);
|
||||||
} else if (pemObject instanceof PEMEncryptedKeyPair encryptedKeyPair) {
|
keyInfo = encrypted.decryptPrivateKeyInfo(decryptor);
|
||||||
PEMDecryptorProvider decryptor =
|
}
|
||||||
new JcePEMDecryptorProviderBuilder().build(password);
|
case PEMEncryptedKeyPair encryptedKeyPair -> {
|
||||||
keyInfo = encryptedKeyPair.decryptKeyPair(decryptor).getPrivateKeyInfo();
|
PEMDecryptorProvider decryptor =
|
||||||
} else if (pemObject instanceof PEMKeyPair keyPair) {
|
new JcePEMDecryptorProviderBuilder().build(password);
|
||||||
keyInfo = keyPair.getPrivateKeyInfo();
|
keyInfo = encryptedKeyPair.decryptKeyPair(decryptor).getPrivateKeyInfo();
|
||||||
} else if (pemObject instanceof PrivateKeyInfo info) {
|
}
|
||||||
keyInfo = info;
|
case PEMKeyPair keyPair -> keyInfo = keyPair.getPrivateKeyInfo();
|
||||||
} else {
|
case PrivateKeyInfo info -> keyInfo = info;
|
||||||
throw new ResponseStatusException(
|
case null, default ->
|
||||||
HttpStatus.BAD_REQUEST, "Unsupported PEM private key format");
|
throw new ResponseStatusException(
|
||||||
|
HttpStatus.BAD_REQUEST, "Unsupported PEM private key format");
|
||||||
}
|
}
|
||||||
return converter.getPrivateKey(keyInfo);
|
return converter.getPrivateKey(keyInfo);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user