test(04-01): add failing tests for security services

- JwtService: 7 tests for access/refresh token creation and validation
- Ed25519SigningService: 5 tests for keypair, signing, verification
- BootstrapTokenValidator: 6 tests for token matching and rotation
- Core interfaces and stub implementations (all throw UnsupportedOperationException)
- Added nimbus-jose-jwt and spring-boot-starter-security dependencies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-11 19:58:59 +01:00
parent b7c35037e6
commit 51a02700dd
11 changed files with 482 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
package com.cameleer3.server.app.security;
/**
* Validates bootstrap tokens used for initial agent registration.
* Stub — to be implemented in GREEN phase.
*/
public class BootstrapTokenValidator {
private final SecurityProperties properties;
public BootstrapTokenValidator(SecurityProperties properties) {
this.properties = properties;
}
/**
* Validates the provided token against the configured bootstrap token(s).
*
* @param provided the token to validate
* @return true if the token matches the current or previous bootstrap token
*/
public boolean validate(String provided) {
throw new UnsupportedOperationException("Not yet implemented");
}
}

View File

@@ -0,0 +1,24 @@
package com.cameleer3.server.app.security;
import com.cameleer3.server.core.security.Ed25519SigningService;
/**
* JDK 17 Ed25519 signing implementation.
* Stub — to be implemented in GREEN phase.
*/
public class Ed25519SigningServiceImpl implements Ed25519SigningService {
public Ed25519SigningServiceImpl() {
// KeyPair generation will go here
}
@Override
public String sign(String payload) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getPublicKeyBase64() {
throw new UnsupportedOperationException("Not yet implemented");
}
}

View File

@@ -0,0 +1,37 @@
package com.cameleer3.server.app.security;
import com.cameleer3.server.core.security.InvalidTokenException;
import com.cameleer3.server.core.security.JwtService;
/**
* HMAC-SHA256 JWT implementation using Nimbus JOSE+JWT.
* Stub — to be implemented in GREEN phase.
*/
public class JwtServiceImpl implements JwtService {
private final SecurityProperties properties;
public JwtServiceImpl(SecurityProperties properties) {
this.properties = properties;
}
@Override
public String createAccessToken(String agentId, String group) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String createRefreshToken(String agentId, String group) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String validateAndExtractAgentId(String token) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String validateRefreshToken(String token) {
throw new UnsupportedOperationException("Not yet implemented");
}
}

View File

@@ -0,0 +1,48 @@
package com.cameleer3.server.app.security;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for security settings.
* Bound from the {@code security.*} namespace in application.yml.
*/
@ConfigurationProperties(prefix = "security")
public class SecurityProperties {
private long accessTokenExpiryMs = 3_600_000;
private long refreshTokenExpiryMs = 604_800_000;
private String bootstrapToken;
private String bootstrapTokenPrevious;
public long getAccessTokenExpiryMs() {
return accessTokenExpiryMs;
}
public void setAccessTokenExpiryMs(long accessTokenExpiryMs) {
this.accessTokenExpiryMs = accessTokenExpiryMs;
}
public long getRefreshTokenExpiryMs() {
return refreshTokenExpiryMs;
}
public void setRefreshTokenExpiryMs(long refreshTokenExpiryMs) {
this.refreshTokenExpiryMs = refreshTokenExpiryMs;
}
public String getBootstrapToken() {
return bootstrapToken;
}
public void setBootstrapToken(String bootstrapToken) {
this.bootstrapToken = bootstrapToken;
}
public String getBootstrapTokenPrevious() {
return bootstrapTokenPrevious;
}
public void setBootstrapTokenPrevious(String bootstrapTokenPrevious) {
this.bootstrapTokenPrevious = bootstrapTokenPrevious;
}
}