From 72d2aae412fb35647d92bcbcab227e3aa4f80e70 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Wed, 26 Jul 2023 17:14:53 +0200 Subject: [PATCH] refactored audit event vault unlock to vault key retrieve --- .../cryptomator/hub/api/AuditLogResource.java | 16 ++++---- .../cryptomator/hub/api/VaultResource.java | 14 +++---- ...k.java => AuditEventVaultKeyRetrieve.java} | 29 ++++++-------- .../V12__Update_Audit_Event_Vault_Unlock.sql | 3 ++ .../hub/flyway/V9999__Test_Data.sql | 10 ++--- frontend/src/common/auditlog.ts | 39 +++++++++---------- frontend/src/components/AuditLog.vue | 6 +-- ...ue => AuditLogDetailsVaultKeyRetrieve.vue} | 29 +++++--------- frontend/src/i18n/de-DE.json | 2 +- frontend/src/i18n/en-US.json | 2 +- 10 files changed, 68 insertions(+), 82 deletions(-) rename backend/src/main/java/org/cryptomator/hub/entities/{AuditEventVaultUnlock.java => AuditEventVaultKeyRetrieve.java} (56%) create mode 100644 backend/src/main/resources/org/cryptomator/hub/flyway/V12__Update_Audit_Event_Vault_Unlock.sql rename frontend/src/components/{AuditLogDetailsVaultUnlock.vue => AuditLogDetailsVaultKeyRetrieve.vue} (60%) diff --git a/backend/src/main/java/org/cryptomator/hub/api/AuditLogResource.java b/backend/src/main/java/org/cryptomator/hub/api/AuditLogResource.java index 7660d79f..1d041b22 100644 --- a/backend/src/main/java/org/cryptomator/hub/api/AuditLogResource.java +++ b/backend/src/main/java/org/cryptomator/hub/api/AuditLogResource.java @@ -16,9 +16,9 @@ import org.cryptomator.hub.entities.AuditEventDeviceRemove; import org.cryptomator.hub.entities.AuditEventVaultAccessGrant; import org.cryptomator.hub.entities.AuditEventVaultCreate; +import org.cryptomator.hub.entities.AuditEventVaultKeyRetrieve; import org.cryptomator.hub.entities.AuditEventVaultMemberAdd; import org.cryptomator.hub.entities.AuditEventVaultMemberRemove; -import org.cryptomator.hub.entities.AuditEventVaultUnlock; import org.cryptomator.hub.entities.AuditEventVaultUpdate; import org.cryptomator.hub.entities.Device; import org.eclipse.microprofile.openapi.annotations.Operation; @@ -66,9 +66,9 @@ public List getAllEvents(@QueryParam("startDate") Instant startDa @JsonSubTypes.Type(value = AuditEventDeviceRegisterDto.class, name = AuditEventDeviceRegister.TYPE), // @JsonSubTypes.Type(value = AuditEventDeviceRemoveDto.class, name = AuditEventDeviceRemove.TYPE), // @JsonSubTypes.Type(value = AuditEventVaultCreateDto.class, name = AuditEventVaultCreate.TYPE), // - @JsonSubTypes.Type(value = AuditEventVaultUnlockDto.class, name = AuditEventVaultUnlock.TYPE), // @JsonSubTypes.Type(value = AuditEventVaultUpdateDto.class, name = AuditEventVaultUpdate.TYPE), // @JsonSubTypes.Type(value = AuditEventVaultAccessGrantDto.class, name = AuditEventVaultAccessGrant.TYPE), // + @JsonSubTypes.Type(value = AuditEventVaultKeyRetrieveDto.class, name = AuditEventVaultKeyRetrieve.TYPE), // @JsonSubTypes.Type(value = AuditEventVaultMemberAddDto.class, name = AuditEventVaultMemberAdd.TYPE), // @JsonSubTypes.Type(value = AuditEventVaultMemberRemoveDto.class, name = AuditEventVaultMemberRemove.TYPE) // }) @@ -88,12 +88,12 @@ static AuditEventDto fromEntity(AuditEvent entity) { return new AuditEventDeviceRemoveDto(aedr.id, aedr.timestamp, AuditEventDeviceRemove.TYPE, aedr.removedBy, aedr.deviceId); } else if (entity instanceof AuditEventVaultCreate aevc) { return new AuditEventVaultCreateDto(aevc.id, aevc.timestamp, AuditEventVaultCreate.TYPE, aevc.createdBy, aevc.vaultId, aevc.vaultName, aevc.vaultDescription); - } else if (entity instanceof AuditEventVaultUnlock aevu) { - return new AuditEventVaultUnlockDto(aevu.id, aevu.timestamp, AuditEventVaultUnlock.TYPE, aevu.unlockedBy, aevu.vaultId, aevu.deviceId, aevu.result); } else if (entity instanceof AuditEventVaultUpdate aevu) { return new AuditEventVaultUpdateDto(aevu.id, aevu.timestamp, AuditEventVaultUpdate.TYPE, aevu.updatedBy, aevu.vaultId, aevu.vaultName, aevu.vaultDescription, aevu.vaultArchived); } else if (entity instanceof AuditEventVaultAccessGrant aevag) { return new AuditEventVaultAccessGrantDto(aevag.id, aevag.timestamp, AuditEventVaultAccessGrant.TYPE, aevag.grantedBy, aevag.vaultId, aevag.authorityId); + } else if (entity instanceof AuditEventVaultKeyRetrieve aevkr) { + return new AuditEventVaultKeyRetrieveDto(aevkr.id, aevkr.timestamp, AuditEventVaultKeyRetrieve.TYPE, aevkr.retrievedBy, aevkr.vaultId, aevkr.result); } else if (entity instanceof AuditEventVaultMemberAdd aevma) { return new AuditEventVaultMemberAddDto(aevma.id, aevma.timestamp, AuditEventVaultMemberAdd.TYPE, aevma.addedBy, aevma.vaultId, aevma.authorityId); } else if (entity instanceof AuditEventVaultMemberRemove aevmr) { @@ -115,10 +115,6 @@ record AuditEventVaultCreateDto(long id, Instant timestamp, String type, @JsonPr @JsonProperty("vaultDescription") String vaultDescription) implements AuditEventDto { } - record AuditEventVaultUnlockDto(long id, Instant timestamp, String type, @JsonProperty("unlockedBy") String unlockedBy, @JsonProperty("vaultId") UUID vaultId, @JsonProperty("deviceId") String deviceId, - @JsonProperty("result") AuditEventVaultUnlock.Result result) implements AuditEventDto { - } - record AuditEventVaultUpdateDto(long id, Instant timestamp, String type, @JsonProperty("updatedBy") String updatedBy, @JsonProperty("vaultId") UUID vaultId, @JsonProperty("vaultName") String vaultName, @JsonProperty("vaultDescription") String vaultDescription, @JsonProperty("vaultArchived") boolean vaultArchived) implements AuditEventDto { } @@ -127,6 +123,10 @@ record AuditEventVaultAccessGrantDto(long id, Instant timestamp, String type, @J @JsonProperty("authorityId") String authorityId) implements AuditEventDto { } + record AuditEventVaultKeyRetrieveDto(long id, Instant timestamp, String type, @JsonProperty("retrievedBy") String retrievedBy, @JsonProperty("vaultId") UUID vaultId, + @JsonProperty("result") AuditEventVaultKeyRetrieve.Result result) implements AuditEventDto { + } + record AuditEventVaultMemberAddDto(long id, Instant timestamp, String type, @JsonProperty("addedBy") String addedBy, @JsonProperty("vaultId") UUID vaultId, @JsonProperty("authorityId") String authorityId) implements AuditEventDto { } diff --git a/backend/src/main/java/org/cryptomator/hub/api/VaultResource.java b/backend/src/main/java/org/cryptomator/hub/api/VaultResource.java index 1df516dc..74c56bb3 100644 --- a/backend/src/main/java/org/cryptomator/hub/api/VaultResource.java +++ b/backend/src/main/java/org/cryptomator/hub/api/VaultResource.java @@ -24,16 +24,16 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.cryptomator.hub.entities.AccessToken; -import org.cryptomator.hub.entities.AuditEventVaultMemberAdd; +import org.cryptomator.hub.entities.AuditEventVaultAccessGrant; import org.cryptomator.hub.entities.AuditEventVaultCreate; +import org.cryptomator.hub.entities.AuditEventVaultKeyRetrieve; +import org.cryptomator.hub.entities.AuditEventVaultMemberAdd; +import org.cryptomator.hub.entities.AuditEventVaultMemberRemove; +import org.cryptomator.hub.entities.AuditEventVaultUpdate; import org.cryptomator.hub.entities.Device; import org.cryptomator.hub.entities.EffectiveGroupMembership; import org.cryptomator.hub.entities.EffectiveVaultAccess; -import org.cryptomator.hub.entities.AuditEventVaultAccessGrant; import org.cryptomator.hub.entities.Group; -import org.cryptomator.hub.entities.AuditEventVaultMemberRemove; -import org.cryptomator.hub.entities.AuditEventVaultUnlock; -import org.cryptomator.hub.entities.AuditEventVaultUpdate; import org.cryptomator.hub.entities.User; import org.cryptomator.hub.entities.Vault; import org.cryptomator.hub.filters.ActiveLicense; @@ -268,14 +268,14 @@ public Response unlock(@PathParam("vaultId") UUID vaultId, @PathParam("deviceId" var access = AccessToken.unlock(vaultId, deviceId, jwt.getSubject()); if (access != null) { - AuditEventVaultUnlock.log(jwt.getSubject(), vaultId, deviceId, AuditEventVaultUnlock.Result.SUCCESS); + AuditEventVaultKeyRetrieve.log(jwt.getSubject(), vaultId, AuditEventVaultKeyRetrieve.Result.SUCCESS); var subscriptionStateHeaderName = "Hub-Subscription-State"; var subscriptionStateHeaderValue = license.isSet() ? "ACTIVE" : "INACTIVE"; // license expiration is not checked here, because it is checked in the ActiveLicense filter return Response.ok(access.jwe).header(subscriptionStateHeaderName, subscriptionStateHeaderValue).build(); } else if (Device.findById(deviceId) == null) { throw new NotFoundException("No such device."); } else { - AuditEventVaultUnlock.log(jwt.getSubject(), vaultId, deviceId, AuditEventVaultUnlock.Result.UNAUTHORIZED); + AuditEventVaultKeyRetrieve.log(jwt.getSubject(), vaultId, AuditEventVaultKeyRetrieve.Result.UNAUTHORIZED); throw new ForbiddenException("Access to this device not granted."); } } diff --git a/backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultUnlock.java b/backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultKeyRetrieve.java similarity index 56% rename from backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultUnlock.java rename to backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultKeyRetrieve.java index 6f2c92fe..a1daf8ad 100644 --- a/backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultUnlock.java +++ b/backend/src/main/java/org/cryptomator/hub/entities/AuditEventVaultKeyRetrieve.java @@ -12,21 +12,18 @@ import java.util.UUID; @Entity -@Table(name = "audit_event_vault_unlock") -@DiscriminatorValue(AuditEventVaultUnlock.TYPE) -public class AuditEventVaultUnlock extends AuditEvent { +@Table(name = "audit_event_vault_key_retrieve") +@DiscriminatorValue(AuditEventVaultKeyRetrieve.TYPE) +public class AuditEventVaultKeyRetrieve extends AuditEvent { - public static final String TYPE = "VAULT_UNLOCK"; + public static final String TYPE = "VAULT_KEY_RETRIEVE"; - @Column(name = "unlocked_by") - public String unlockedBy; + @Column(name = "retrieved_by") + public String retrievedBy; @Column(name = "vault_id") public UUID vaultId; - @Column(name = "device_id") - public String deviceId; - @Column(name = "result") @Enumerated(EnumType.STRING) public Result result; @@ -35,25 +32,23 @@ public class AuditEventVaultUnlock extends AuditEvent { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - AuditEventVaultUnlock that = (AuditEventVaultUnlock) o; + AuditEventVaultKeyRetrieve that = (AuditEventVaultKeyRetrieve) o; return super.equals(that) // - && Objects.equals(unlockedBy, that.unlockedBy) // + && Objects.equals(retrievedBy, that.retrievedBy) // && Objects.equals(vaultId, that.vaultId) // - && Objects.equals(deviceId, that.deviceId) // && Objects.equals(result, that.result); } @Override public int hashCode() { - return Objects.hash(id, unlockedBy, vaultId, deviceId, result); + return Objects.hash(id, retrievedBy, vaultId, result); } - public static void log(String unlockedBy, UUID vaultId, String deviceId, Result result) { - var event = new AuditEventVaultUnlock(); + public static void log(String retrievedBy, UUID vaultId, Result result) { + var event = new AuditEventVaultKeyRetrieve(); event.timestamp = Instant.now(); - event.unlockedBy = unlockedBy; + event.retrievedBy = retrievedBy; event.vaultId = vaultId; - event.deviceId = deviceId; event.result = result; event.persist(); } diff --git a/backend/src/main/resources/org/cryptomator/hub/flyway/V12__Update_Audit_Event_Vault_Unlock.sql b/backend/src/main/resources/org/cryptomator/hub/flyway/V12__Update_Audit_Event_Vault_Unlock.sql new file mode 100644 index 00000000..0e103ccd --- /dev/null +++ b/backend/src/main/resources/org/cryptomator/hub/flyway/V12__Update_Audit_Event_Vault_Unlock.sql @@ -0,0 +1,3 @@ +ALTER TABLE "audit_event_vault_unlock" RENAME TO "audit_event_vault_key_retrieve"; +ALTER TABLE "audit_event_vault_key_retrieve" RENAME COLUMN "unlocked_by" TO "retrieved_by"; +ALTER TABLE "audit_event_vault_key_retrieve" DROP COLUMN "device_id"; diff --git a/backend/src/test/resources/org/cryptomator/hub/flyway/V9999__Test_Data.sql b/backend/src/test/resources/org/cryptomator/hub/flyway/V9999__Test_Data.sql index 73114ba3..1e106f0f 100644 --- a/backend/src/test/resources/org/cryptomator/hub/flyway/V9999__Test_Data.sql +++ b/backend/src/test/resources/org/cryptomator/hub/flyway/V9999__Test_Data.sql @@ -79,13 +79,13 @@ VALUES (102, '2020-02-20T20:20:20.102Z', 'DEVICE_REGISTER'), (200, '2020-02-20T20:20:20.200Z', 'DEVICE_REGISTER'), (201, '2020-02-20T20:20:20.201Z', 'DEVICE_REMOVE'), - (1111, '2020-02-20T20:20:21.111Z', 'VAULT_UNLOCK'), + (1111, '2020-02-20T20:20:21.111Z', 'VAULT_KEY_RETRIEVE'), (2000, '2020-02-20T20:20:22.000Z', 'VAULT_ACCESS_GRANT'), (2001, '2020-02-20T20:20:22.001Z', 'VAULT_ACCESS_GRANT'), (2002, '2020-02-20T20:20:22.002Z', 'VAULT_ACCESS_GRANT'), (2003, '2020-02-20T20:20:22.003Z', 'VAULT_ACCESS_GRANT'), (3000, '2020-02-20T20:20:23.000Z', 'VAULT_UPDATE'), - (4242, '2020-02-20T20:20:24.242Z', 'VAULT_UNLOCK'); + (4242, '2020-02-20T20:20:24.242Z', 'VAULT_KEY_RETRIEVE'); SELECT SETVAL('audit_event_id_seq', (SELECT MAX(id) FROM audit_event), true); @@ -118,10 +118,10 @@ INSERT INTO "audit_event_device_remove" ("id", "removed_by", "device_id") VALUES (201, 'user2', 'device4'); -INSERT INTO "audit_event_vault_unlock" ("id", "unlocked_by", "vault_id", "device_id", "result") +INSERT INTO "audit_event_vault_key_retrieve" ("id", "retrieved_by", "vault_id", "result") VALUES - (1111, 'user2', '7E57C0DE-0000-4000-8000-000100001111', 'device3', 'UNAUTHORIZED'), - (4242, 'user1', '7E57C0DE-0000-4000-8000-000100001111', 'device1', 'SUCCESS'); + (1111, 'user2', '7E57C0DE-0000-4000-8000-000100001111', 'UNAUTHORIZED'), + (4242, 'user1', '7E57C0DE-0000-4000-8000-000100001111', 'SUCCESS'); INSERT INTO "audit_event_vault_access_grant" ("id", "granted_by", "vault_id", "authority_id") VALUES diff --git a/frontend/src/common/auditlog.ts b/frontend/src/common/auditlog.ts index de5d44e3..accf7efc 100644 --- a/frontend/src/common/auditlog.ts +++ b/frontend/src/common/auditlog.ts @@ -6,7 +6,7 @@ import { Deferred, debounce } from './util'; export type AuditEventDto = { id: number; timestamp: Date; - type: 'DEVICE_REGISTER' | 'DEVICE_REMOVE' | 'VAULT_ACCESS_GRANT' | 'VAULT_CREATE' | 'VAULT_MEMBER_ADD' | 'VAULT_MEMBER_REMOVE' | 'VAULT_UNLOCK' | 'VAULT_UPDATE'; + type: 'DEVICE_REGISTER' | 'DEVICE_REMOVE' | 'VAULT_CREATE' | 'VAULT_UPDATE' | 'VAULT_ACCESS_GRANT' | 'VAULT_KEY_RETRIEVE' | 'VAULT_MEMBER_ADD' | 'VAULT_MEMBER_REMOVE'; } export type AuditEventDeviceRegisterDto = AuditEventDto & { @@ -21,12 +21,6 @@ export type AuditEventDeviceRemoveDto = AuditEventDto & { deviceId: string; } -export type AuditEventVaultAccessGrantDto = AuditEventDto & { - grantedBy: string; - vaultId: string; - authorityId: string; -} - export type AuditEventVaultCreateDto = AuditEventDto & { createdBy: string; vaultId: string; @@ -34,31 +28,36 @@ export type AuditEventVaultCreateDto = AuditEventDto & { vaultDescription: string; } -export type AuditEventVaultMemberAddDto = AuditEventDto & { - addedBy: string; +export type AuditEventVaultUpdateDto = AuditEventDto & { + updatedBy: string; vaultId: string; - authorityId: string; + vaultName: string; + vaultDescription: string; + vaultArchived: boolean; } -export type AuditEventVaultMemberRemoveDto = AuditEventDto & { - removedBy: string; +export type AuditEventVaultAccessGrantDto = AuditEventDto & { + grantedBy: string; vaultId: string; authorityId: string; } -export type AuditEventVaultUnlockDto = AuditEventDto & { - unlockedBy: string; +export type AuditEventVaultKeyRetrieveDto = AuditEventDto & { + retrievedBy: string; vaultId: string; - deviceId: string; result: 'SUCCESS' | 'UNAUTHORIZED'; } -export type AuditEventVaultUpdateDto = AuditEventDto & { - updatedBy: string; +export type AuditEventVaultMemberAddDto = AuditEventDto & { + addedBy: string; vaultId: string; - vaultName: string; - vaultDescription: string; - vaultArchived: boolean; + authorityId: string; +} + +export type AuditEventVaultMemberRemoveDto = AuditEventDto & { + removedBy: string; + vaultId: string; + authorityId: string; } /* Entity Cache */ diff --git a/frontend/src/components/AuditLog.vue b/frontend/src/components/AuditLog.vue index df9da0dd..7daff2fc 100644 --- a/frontend/src/components/AuditLog.vue +++ b/frontend/src/components/AuditLog.vue @@ -94,9 +94,9 @@ - + @@ -137,14 +137,14 @@ import { ChevronDownIcon } from '@heroicons/vue/20/solid'; import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/24/solid'; import { computed, onMounted, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; -import auditlog, { AuditEventDeviceRegisterDto, AuditEventDeviceRemoveDto, AuditEventDto, AuditEventVaultAccessGrantDto, AuditEventVaultCreateDto, AuditEventVaultMemberAddDto, AuditEventVaultMemberRemoveDto, AuditEventVaultUnlockDto, AuditEventVaultUpdateDto } from '../common/auditlog'; +import auditlog, { AuditEventDeviceRegisterDto, AuditEventDeviceRemoveDto, AuditEventDto, AuditEventVaultAccessGrantDto, AuditEventVaultCreateDto, AuditEventVaultKeyRetrieveDto, AuditEventVaultMemberAddDto, AuditEventVaultMemberRemoveDto, AuditEventVaultUpdateDto } from '../common/auditlog'; import AuditLogDetailsDeviceRegister from './AuditLogDetailsDeviceRegister.vue'; import AuditLogDetailsDeviceRemove from './AuditLogDetailsDeviceRemove.vue'; import AuditLogDetailsVaultAccessGrant from './AuditLogDetailsVaultAccessGrant.vue'; import AuditLogDetailsVaultCreate from './AuditLogDetailsVaultCreate.vue'; +import AuditLogDetailsVaultKeyRetrieve from './AuditLogDetailsVaultKeyRetrieve.vue'; import AuditLogDetailsVaultMemberAdd from './AuditLogDetailsVaultMemberAdd.vue'; import AuditLogDetailsVaultMemberRemove from './AuditLogDetailsVaultMemberRemove.vue'; -import AuditLogDetailsVaultUnlock from './AuditLogDetailsVaultUnlock.vue'; import AuditLogDetailsVaultUpdate from './AuditLogDetailsVaultUpdate.vue'; const { t } = useI18n({ useScope: 'global' }); diff --git a/frontend/src/components/AuditLogDetailsVaultUnlock.vue b/frontend/src/components/AuditLogDetailsVaultKeyRetrieve.vue similarity index 60% rename from frontend/src/components/AuditLogDetailsVaultUnlock.vue rename to frontend/src/components/AuditLogDetailsVaultKeyRetrieve.vue index 839567db..96f92bb6 100644 --- a/frontend/src/components/AuditLogDetailsVaultUnlock.vue +++ b/frontend/src/components/AuditLogDetailsVaultKeyRetrieve.vue @@ -1,16 +1,16 @@