feature/credentials-schema-updates (#180)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/180 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
package net.hostsharing.hsadminng.credentials;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import io.micrometer.core.annotation.Timed;
|
||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||
@@ -24,6 +28,8 @@ import jakarta.persistence.EntityNotFoundException;
|
||||
@SecurityRequirement(name = "casTicket")
|
||||
public class HsCredentialsController implements CredentialsApi {
|
||||
|
||||
private static DateTimeFormatter FULL_TIMESTAMP_FORMAT = DateTimeFormatter.BASIC_ISO_DATE;
|
||||
|
||||
@Autowired
|
||||
private Context context;
|
||||
|
||||
@@ -67,7 +73,7 @@ public class HsCredentialsController implements CredentialsApi {
|
||||
messageTranslator.translate("{0} \"{1}\" not found or not accessible", "personUuid", personUuid)
|
||||
)
|
||||
|
||||
); // FIXME: use proper exception
|
||||
);
|
||||
final var credentials = credentialsRepo.findByPerson(person);
|
||||
final var result = mapper.mapList(credentials, CredentialsResource.class);
|
||||
return ResponseEntity.ok(result);
|
||||
@@ -113,4 +119,25 @@ public class HsCredentialsController implements CredentialsApi {
|
||||
final var mapped = mapper.map(saved, CredentialsResource.class);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Timed("app.credentials.credentials.credentialsUsed")
|
||||
public ResponseEntity<CredentialsResource> credentialsUsed(
|
||||
final String assumedRoles,
|
||||
final UUID credentialsUuid) {
|
||||
context.assumeRoles(assumedRoles);
|
||||
|
||||
final var current = credentialsRepo.findByUuid(credentialsUuid).orElseThrow();
|
||||
|
||||
current.setOnboardingToken(null);
|
||||
current.setLastUsed(LocalDateTime.now());
|
||||
|
||||
final var saved = credentialsRepo.save(current);
|
||||
final var mapped = mapper.map(saved, CredentialsResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
final BiConsumer<HsCredentialsEntity, CredentialsResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
|
||||
resource.setLastUsed(entity.getLastUsed().atOffset(ZoneOffset.UTC));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.hostsharing.hsadminng.repr.Stringify;
|
||||
import net.hostsharing.hsadminng.repr.Stringifyable;
|
||||
// import net.hostsharing.hsadminng.rbac.RbacSubjectEntity; // Assuming RbacSubjectEntity exists for the FK relationship
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -29,7 +30,7 @@ public class HsCredentialsEntity implements BaseEntity<HsCredentialsEntity>, Str
|
||||
protected static Stringify<HsCredentialsEntity> stringify = stringify(HsCredentialsEntity.class, "credentials")
|
||||
.withProp(HsCredentialsEntity::isActive)
|
||||
.withProp(HsCredentialsEntity::getEmailAddress)
|
||||
.withProp(HsCredentialsEntity::getTwoFactorAuth)
|
||||
.withProp(HsCredentialsEntity::getTotpSecret)
|
||||
.withProp(HsCredentialsEntity::getPhonePassword)
|
||||
.withProp(HsCredentialsEntity::getSmsNumber)
|
||||
.quotedValues(false);
|
||||
@@ -49,6 +50,9 @@ public class HsCredentialsEntity implements BaseEntity<HsCredentialsEntity>, Str
|
||||
@Version
|
||||
private int version;
|
||||
|
||||
@Column
|
||||
private LocalDateTime lastUsed;
|
||||
|
||||
@Column
|
||||
private boolean active;
|
||||
|
||||
@@ -62,7 +66,7 @@ public class HsCredentialsEntity implements BaseEntity<HsCredentialsEntity>, Str
|
||||
private String onboardingToken;
|
||||
|
||||
@Column
|
||||
private String twoFactorAuth;
|
||||
private String totpSecret;
|
||||
|
||||
@Column
|
||||
private String phonePassword;
|
||||
|
||||
@@ -31,8 +31,8 @@ public class HsCredentialsEntityPatcher implements EntityPatcher<CredentialsPatc
|
||||
}
|
||||
OptionalFromJson.of(resource.getEmailAddress())
|
||||
.ifPresent(entity::setEmailAddress);
|
||||
OptionalFromJson.of(resource.getTwoFactorAuth())
|
||||
.ifPresent(entity::setTwoFactorAuth);
|
||||
OptionalFromJson.of(resource.getTotpSecret())
|
||||
.ifPresent(entity::setTotpSecret);
|
||||
OptionalFromJson.of(resource.getSmsNumber())
|
||||
.ifPresent(entity::setSmsNumber);
|
||||
OptionalFromJson.of(resource.getPhonePassword())
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingDebitorRepository extends Repository<HsBookingDebitorEntity, UUID> {
|
||||
|
||||
@Timed("app.booking.debitor.repo.findByUuid")
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import org.springframework.data.repository.Repository;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface BookingItemCreatedEventRepository extends Repository<BookingItemCreatedEventEntity, UUID> {
|
||||
|
||||
@Timed("app.booking.items.repo.save")
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||
|
||||
@RestController
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
@SecurityRequirement(name = "casTicket")
|
||||
public class HsBookingItemController implements HsBookingItemsApi {
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingItemRbacRepository extends HsBookingItemRepository<HsBookingItemRbacEntity>,
|
||||
Repository<HsBookingItemRbacEntity, UUID> {
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingItemRealRepository extends HsBookingItemRepository<HsBookingItemRealEntity>,
|
||||
Repository<HsBookingItemRealEntity, UUID> {
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingItemRepository<E extends HsBookingItem> {
|
||||
|
||||
Optional<E> findByUuid(final UUID bookingItemUuid);
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@RestController
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
@SecurityRequirement(name = "casTicket")
|
||||
public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingProjectRbacRepository extends HsBookingProjectRepository<HsBookingProjectRbacEntity>,
|
||||
Repository<HsBookingProjectRbacEntity, UUID> {
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingProjectRealRepository extends HsBookingProjectRepository<HsBookingProjectRealEntity>,
|
||||
Repository<HsBookingProjectRealEntity, UUID> {
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsBookingProjectRepository<E extends HsBookingProject> {
|
||||
|
||||
@Timed("app.booking.projects.repo.findByUuid")
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@RestController
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
@SecurityRequirement(name = "casTicket")
|
||||
public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import java.util.Map;
|
||||
|
||||
|
||||
@RestController
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
@NoSecurityRequirement
|
||||
public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsHostingAssetRbacRepository extends HsHostingAssetRepository<HsHostingAssetRbacEntity>, Repository<HsHostingAssetRbacEntity, UUID> {
|
||||
|
||||
@Timed("app.hostingAsset.repo.findByUuid.rbac")
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsHostingAssetRealRepository extends HsHostingAssetRepository<HsHostingAssetRealEntity>, Repository<HsHostingAssetRealEntity, UUID> {
|
||||
|
||||
@Timed("app.hostingAsset.repo.findByUuid.real")
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public interface HsHostingAssetRepository<E extends HsHostingAsset> {
|
||||
|
||||
@Timed("app.hosting.assets.repo.findByUuid")
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@Profile("!only-office")
|
||||
@Profile("!only-prod-schema")
|
||||
public class HsBookingItemCreatedListener implements ApplicationListener<BookingItemCreatedAppEvent> {
|
||||
|
||||
@Autowired
|
||||
|
||||
Reference in New Issue
Block a user