Files
cameleer-saas/src/main/java/net/siegeln/cameleer/saas/license/LicenseController.java
hsiegeln db7647f7f4 refactor: remove Phase 1 auth endpoints, switch to Logto OIDC
Auth is now handled by Logto. Removed AuthController, AuthService,
and related DTOs. Integration tests use Spring Security JWT mocks.
Ed25519 JwtService retained for machine token signing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 15:12:50 +02:00

68 lines
2.5 KiB
Java

package net.siegeln.cameleer.saas.license;
import net.siegeln.cameleer.saas.license.dto.LicenseResponse;
import net.siegeln.cameleer.saas.tenant.TenantService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.Duration;
import java.util.UUID;
@RestController
@RequestMapping("/api/tenants/{tenantId}/license")
public class LicenseController {
private final LicenseService licenseService;
private final TenantService tenantService;
public LicenseController(LicenseService licenseService, TenantService tenantService) {
this.licenseService = licenseService;
this.tenantService = tenantService;
}
@PostMapping
public ResponseEntity<LicenseResponse> generate(@PathVariable UUID tenantId,
Authentication authentication) {
var tenant = tenantService.getById(tenantId).orElse(null);
if (tenant == null) return ResponseEntity.notFound().build();
// Extract actor ID from JWT subject (Logto OIDC: sub may be a non-UUID string)
String sub = authentication.getName();
UUID actorId;
try {
actorId = UUID.fromString(sub);
} catch (IllegalArgumentException e) {
actorId = UUID.nameUUIDFromBytes(sub.getBytes());
}
var license = licenseService.generateLicense(tenant, Duration.ofDays(365), actorId);
return ResponseEntity.status(HttpStatus.CREATED).body(toResponse(license));
}
@GetMapping
public ResponseEntity<LicenseResponse> getActive(@PathVariable UUID tenantId) {
return licenseService.getActiveLicense(tenantId)
.map(entity -> ResponseEntity.ok(toResponse(entity)))
.orElse(ResponseEntity.notFound().build());
}
private LicenseResponse toResponse(LicenseEntity entity) {
return new LicenseResponse(
entity.getId(),
entity.getTenantId(),
entity.getTier(),
entity.getFeatures(),
entity.getLimits(),
entity.getIssuedAt(),
entity.getExpiresAt(),
entity.getToken()
);
}
}