added login logic excl refresh call

This commit is contained in:
2026-04-06 05:02:46 +02:00
parent 9c3e1469c7
commit 240a366ce8
13 changed files with 589 additions and 46 deletions
@@ -0,0 +1,28 @@
package com.vaessl.app.connection;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "connections")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "service_type")
@Getter
@Setter
@NoArgsConstructor
public abstract class ConnectionEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String appUrl;
}
@@ -6,6 +6,10 @@ import com.vaessl.app.dto.ConnectionResponse;
public interface ConnectionProvider {
String getServiceType();
ConnectionResponse authenticate (ConnectionRequest connectionRequest);
ConnectionResponse authenticate(ConnectionRequest request);
ConnectionEntity connectionToEntity(ConnectionRequest request, ConnectionResponse response);
void updateToRepository(ConnectionEntity existing, ConnectionResponse response);
}
@@ -0,0 +1,10 @@
package com.vaessl.app.connection;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ConnectionRepository extends JpaRepository<ConnectionEntity, Long> {
ConnectionEntity findByAppUrl(String appUrl);
}
@@ -8,24 +8,40 @@ import org.springframework.stereotype.Service;
import com.vaessl.app.dto.ConnectionRequest;
import com.vaessl.app.dto.ConnectionResponse;
import com.vaessl.app.exception.ProviderNotFoundException;
@Service
public class ConnectionService {
private final Map<String, ConnectionProvider> providerRegistry;
public ConnectionService(List<ConnectionProvider> providers) {
private final ConnectionRepository cRepository;
public ConnectionService(List<ConnectionProvider> providers, ConnectionRepository cRepository) {
this.providerRegistry = providers.stream()
.collect(Collectors.toMap(ConnectionProvider::getServiceType, p -> p));
this.cRepository = cRepository;
}
public ConnectionResponse login(ConnectionRequest request) {
ConnectionProvider provider = providerRegistry.get(request.serviceType().toUpperCase());
ConnectionProvider provider = providerRegistry.get(request.serviceType());
if (provider == null) {
throw new IllegalArgumentException("Unknown provider: " + request.serviceType());
throw new ProviderNotFoundException();
}
return provider.authenticate(request);
ConnectionResponse response = provider.authenticate(request);
ConnectionEntity existing = cRepository.findByAppUrl(request.appUrl());
if (existing != null) {
provider.updateToRepository(existing, response);
} else {
ConnectionEntity newEntity = provider.connectionToEntity(request, response);
cRepository.save(newEntity);
}
return response;
}
}
@@ -1,5 +1,7 @@
package com.vaessl.app.connection;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Component;
@@ -8,15 +10,18 @@ import org.springframework.web.client.RestClient;
import com.vaessl.app.dto.ConnectionRequest;
import com.vaessl.app.dto.ConnectionResponse;
import static com.vaessl.app.connection.Endpoints.*;
import static com.vaessl.app.connection.Endpoint.*;
@Component
public class HomeBoxConnectionProvider implements ConnectionProvider {
private final RestClient.Builder restClientBuilder;
public HomeBoxConnectionProvider(RestClient.Builder restClientBuilder) {
private final ConnectionRepository cRepository;
public HomeBoxConnectionProvider(RestClient.Builder restClientBuilder, ConnectionRepository cRepository) {
this.restClientBuilder = restClientBuilder;
this.cRepository = cRepository;
}
@Override
@@ -25,17 +30,50 @@ public class HomeBoxConnectionProvider implements ConnectionProvider {
}
@Override
public ConnectionResponse authenticate(ConnectionRequest connectionRequest) {
Map<String, Object> homeboxPayload = Map.of("username", connectionRequest.credentials().get("username"),
"password", connectionRequest.credentials().get("password"), "stayLoggedIn",
connectionRequest.stayLoggedIn());
public ConnectionResponse authenticate(ConnectionRequest request) {
Map<String, Object> homeboxPayload = Map.of("username", request.credentials().get("username"),
"password", request.credentials().get("password"), "stayLoggedIn",
request.stayLoggedIn());
return restClientBuilder.baseUrl(connectionRequest.appUrl())
HomeboxLoginResponse hbResponse = restClientBuilder.baseUrl(request.appUrl())
.build()
.post()
.uri(HOMEBOX_LOGIN.getEndpoint())
.uri(HOMEBOX_LOGIN.getValue())
.body(homeboxPayload)
.retrieve()
.body(ConnectionResponse.class);
.body(HomeboxLoginResponse.class);
if (hbResponse == null) {
throw new IllegalStateException("Remote API returned an empty body for " + request.appUrl());
}
Map<String, Object> attachmentToken = new HashMap<>();
attachmentToken.put("attachmentToken", hbResponse.attachmentToken());
return new ConnectionResponse(hbResponse.token(), hbResponse.expiresAt(), attachmentToken);
}
@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);
}
}
private record HomeboxLoginResponse(String token, String attachmentToken, Instant expiresAt) {
}
}
@@ -0,0 +1,34 @@
package com.vaessl.app.connection;
import java.time.Instant;
import com.vaessl.app.dto.ConnectionRequest;
import com.vaessl.app.dto.ConnectionResponse;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import lombok.Getter;
import lombok.Setter;
@Entity
@DiscriminatorValue("HOMEBOX")
@Getter
@Setter
public class HomeboxEntity extends ConnectionEntity {
private String token;
private String attachmentToken;
private Instant expiresAt;
public static HomeboxEntity from(ConnectionRequest request, ConnectionResponse response) {
HomeboxEntity he = new HomeboxEntity();
he.setAppUrl(request.appUrl());
he.setToken(response.token());
he.setAttachmentToken(response.getExtraVar("attachmentToken"));
he.setExpiresAt(response.expiresAt());
return he;
}
}
@@ -0,0 +1,14 @@
package com.vaessl.app.connection;
import lombok.Getter;
@Getter
public enum ServiceType {
HOMEBOX("HOMEBOX");
private final String value;
private ServiceType(String value){
this.value = value;
}
}