package com.vaessl.app.connection; import java.time.Instant; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Component; import org.springframework.web.client.RestClient; import com.vaessl.app.exception.EmptyCredentialsException; import com.vaessl.app.exception.RemoteApiException; import static com.vaessl.app.connection.Endpoint.*; @Component public class HomeboxConnectionProvider implements ConnectionProvider { private final RestClient.Builder restClientBuilder; private final ConnectionRepository cRepository; public HomeboxConnectionProvider(RestClient.Builder restClientBuilder, ConnectionRepository cRepository) { this.restClientBuilder = restClientBuilder; this.cRepository = cRepository; } @Override public void checkCredentials(ConnectionRequest request) { if (request.username() == null || request.password() == null) { List missingFields = new ArrayList<>(); if (request.username() == null) { missingFields.add("username"); } if (request.password() == null) { missingFields.add("password"); } throw new EmptyCredentialsException(List.copyOf(missingFields)); } } @Override public String getServiceType() { return "HOMEBOX"; } @Override public ConnectionResponse authenticate(ConnectionRequest request) { Map homeboxPayload = Map.of("username", request.username(), "password", request.password(), "stayLoggedIn", request.stayLoggedIn()); HomeboxLoginResponse hbResponse = restClientBuilder.baseUrl(request.appUrl()).build().post() .uri(HOMEBOX_LOGIN.getValue()).body(homeboxPayload).retrieve() .body(HomeboxLoginResponse.class); if (hbResponse == null) { throw new RemoteApiException(request.appUrl()); } Map attachmentToken = new HashMap<>(); attachmentToken.put("attachmentToken", hbResponse.attachmentToken()); String hbRawToken = hbResponse.token(); String token = hbRawToken.startsWith("Bearer ") ? hbRawToken.substring(7) : hbRawToken; return new ConnectionResponse(token, hbResponse.expiresAt(), attachmentToken); } @Override public ConnectionEntity findUniqueConnectionEntry(ConnectionRequest request) { return cRepository.findByAppUrlAndUsername(request.appUrl(), request.username()); } @Override public ConnectionEntity connectionToEntity(ConnectionRequest request, ConnectionResponse response) { return HomeboxEntity.from(request, response); } @Override public void updateToRepository(ConnectionEntity existing, ConnectionResponse response) { if (existing instanceof HomeboxEntity hbE) { hbE.setToken(response.token()); hbE.setExpiresAt(response.expiresAt()); hbE.setAttachmentToken(response.getExtraVar("attachmentToken")); cRepository.save(hbE); } } @Override public Instant getTokenExpiry(ConnectionEntity entity) { return (entity instanceof HomeboxEntity he) ? he.getExpiresAt() : null; } private record HomeboxLoginResponse(String token, String attachmentToken, Instant expiresAt) { } }