package com.heaerie.server.auth201.Auth201Server.service;
import com.heaerie.server.auth201.Auth201Server.dto.ClientRegistrationRequest;
import com.heaerie.server.auth201.Auth201Server.dto.ClientRegistrationResponse;
import com.heaerie.server.auth201.Auth201Server.entity.RegisteredClientEntity;
import com.heaerie.server.auth201.Auth201Server.repository.RegisteredClientRepository;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.UUID;
@Service
public class ClientRegistrationService {
private final RegisteredClientRepository clientRepository;
private final PasswordEncoder passwordEncoder;
public ClientRegistrationService(RegisteredClientRepository clientRepository,
PasswordEncoder passwordEncoder) {
this.clientRepository = clientRepository;
this.passwordEncoder = passwordEncoder;
}
@Transactional
public ClientRegistrationResponse registerClient(ClientRegistrationRequest request) {
// Validate request
if (request.getClientName() == null || request.getClientName().trim().isEmpty()) {
throw new IllegalArgumentException("Client name is required");
}
if (request.getRedirectUris() == null || request.getRedirectUris().isEmpty()) {
throw new IllegalArgumentException("At least one redirect URI is required");
}
// Generate unique client ID
String clientId;
do {
clientId = generateClientId(request.getClientName());
} while (clientRepository.existsByClientId(clientId));
// Generate client secret for confidential clients
String clientSecret = null;
String encodedSecret = null;
if ("confidential".equals(request.getClientType())) {
clientSecret = generateClientSecret();
encodedSecret = passwordEncoder.encode(clientSecret);
}
// Create entity
RegisteredClientEntity entity = new RegisteredClientEntity();
entity.setClientId(clientId);
entity.setClientSecret(encodedSecret);
entity.setClientName(request.getClientName());
entity.setClientType(request.getClientType());
entity.setDescription(request.getDescription());
entity.setRedirectUris(String.join(",", request.getRedirectUris()));
if (request.getLogoutRedirectUris() != null && !request.getLogoutRedirectUris().isEmpty()) {
entity.setLogoutRedirectUris(String.join(",", request.getLogoutRedirectUris()));
}
entity.setGrantTypes(String.join(",", request.getGrantTypes()));
entity.setScopes(String.join(",", request.getScopes()));
entity.setRequireConsent(request.isRequireConsent());
entity.setRequirePkce(request.isRequirePkce());
entity.setAccessTokenValidity(request.getAccessTokenValidity());
entity.setRefreshTokenValidity(request.getRefreshTokenValidity());
entity.setReuseRefreshTokens(request.isReuseRefreshTokens());
// Save to database
clientRepository.save(entity);
// Build response
ClientRegistrationResponse response = new ClientRegistrationResponse();
response.setClientId(clientId);
response.setClientSecret(clientSecret); // Return plain text secret (only shown once)
response.setClientType(request.getClientType());
response.setMessage("Client registered successfully");
return response;
}
private String generateClientId(String clientName) {
String sanitized = clientName.toLowerCase()
.replaceAll("[^a-z0-9-]", "-")
.replaceAll("-+", "-")
.replaceAll("^-|-$", "");
String shortUuid = UUID.randomUUID().toString().substring(0, 8);
return sanitized + "-" + shortUuid;
}
private String generateClientSecret() {
return UUID.randomUUID().toString().replace("-", "") +
UUID.randomUUID().toString().replace("-", "");
}
}