Skip to content

Commit f7d9bbe

Browse files
committed
add admin setting enableEmergencyAccess
1 parent 004997f commit f7d9bbe

File tree

18 files changed

+313
-207
lines changed

18 files changed

+313
-207
lines changed

backend/src/main/java/org/cryptomator/hub/api/AuditLogResource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static AuditEventDto fromEntity(AuditEvent entity) {
128128
case VaultMemberUpdatedEvent evt -> new VaultMemberUpdatedEventDto(evt.getId(), evt.getTimestamp(), VaultMemberUpdatedEvent.TYPE, evt.getUpdatedBy(), evt.getVaultId(), evt.getAuthorityId(), evt.getRole());
129129
case VaultOwnershipClaimedEvent evt -> new VaultOwnershipClaimedEventDto(evt.getId(), evt.getTimestamp(), VaultOwnershipClaimedEvent.TYPE, evt.getClaimedBy(), evt.getVaultId());
130130
case EmergencyAccessSetupEvent evt -> new EmergencyAccessSetupEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessSetupEvent.TYPE, evt.getVaultId() ,evt.getOwnerId(), evt.getSettings(), evt.getIpAddress());
131-
case EmergencyAccessSettingsUpdatedEvent evt -> new EmergencyAccessSettingsUpdatedEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessSettingsUpdatedEvent.TYPE, evt.getAdminId(), evt.getCouncilMemberIds(), evt.getRequiredKeyShares(), evt.getMinMembers(), evt.isAllowChoosingCouncil());
131+
case EmergencyAccessSettingsUpdatedEvent evt -> new EmergencyAccessSettingsUpdatedEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessSettingsUpdatedEvent.TYPE, evt.getAdminId(), evt.isEmergencyAcessEnabled(), evt.getCouncilMemberIds(), evt.getRequiredKeyShares(), evt.getMinMembers(), evt.isAllowChoosingCouncil());
132132
case EmergencyAccessRecoveryStartedEvent evt -> new EmergencyAccessRecoveryStartedEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessRecoveryStartedEvent.TYPE, evt.getVaultId(), evt.getProcessId(), evt.getCouncilMemberId(), evt.getProcessType(), evt.getDetails());
133133
case EmergencyAccessRecoveryApprovedEvent evt -> new EmergencyAccessRecoveryApprovedEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessRecoveryApprovedEvent.TYPE, evt.getProcessId(), evt.getCouncilMemberId(), evt.getIpAddress());
134134
case EmergencyAccessRecoveryCompletedEvent evt -> new EmergencyAccessRecoveryCompletedEventDto(evt.getId(), evt.getTimestamp(), EmergencyAccessRecoveryCompletedEvent.TYPE, evt.getProcessId(), evt.getCouncilMemberId(), evt.getIpAddress());
@@ -197,7 +197,7 @@ record EmergencyAccessSetupEventDto(long id, Instant timestamp, String type, @Js
197197
@JsonProperty("ipAddress") String ipAddress) implements AuditEventDto {
198198
}
199199

200-
record EmergencyAccessSettingsUpdatedEventDto(long id, Instant timestamp, String type, @JsonProperty("adminId") String adminId, @JsonProperty("councilMemberIds") String councilMemberIds,
200+
record EmergencyAccessSettingsUpdatedEventDto(long id, Instant timestamp, String type, @JsonProperty("adminId") String adminId,@JsonProperty("enableEmergencyAccess") boolean enableEmergencyAccess, @JsonProperty("councilMemberIds") String councilMemberIds,
201201
@JsonProperty("requiredKeyShares") int requiredKeyShares, @JsonProperty("minMembers") int minMembers, @JsonProperty("allowChoosingCouncil") boolean allowChoosingCouncil) implements AuditEventDto {
202202
}
203203

backend/src/main/java/org/cryptomator/hub/api/SettingsResource.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,34 +61,41 @@ public Response put(@NotNull @Valid SettingsDto dto) {
6161
var oldRequiredEmergencyKeyShares = settings.getDefaultRequiredEmergencyKeyShares();
6262
var oldMinMembers = settings.getDefaultMinMembers();
6363
var oldAllowChoosingEmergencyCouncil = settings.isAllowChoosingEmergencyCouncil();
64+
var oldEmergencyAccessEnabled = settings.isEmergencyAcessEnabled();
6465
settings.setWotMaxDepth(dto.wotMaxDepth);
6566
settings.setWotIdVerifyLen(dto.wotIdVerifyLen);
6667
settings.setDefaultRequiredEmergencyKeyShares(dto.defaultRequiredEmergencyKeyShares);
6768
settings.setDefaultMinMembers(dto.defaultMinMembers);
6869
settings.setAllowChoosingEmergencyCouncil(dto.allowChoosingEmergencyCouncil);
6970
settings.setEmergencyCouncilMemberIds(dto.emergencyCouncilMemberIds);
71+
settings.setEmergencyAcessEnabled(dto.enableEmergencyAccess);
7072
settingsRepo.persist(settings);
7173
if (oldWotMaxDepth != dto.wotMaxDepth || oldWotIdVerifyLen != dto.wotIdVerifyLen) {
7274
eventLogger.logWotSettingUpdated(jwt.getSubject(), dto.wotIdVerifyLen, dto.wotMaxDepth);
7375
}
74-
if (!oldEmergencyCouncilMemberIds.containsAll(dto.emergencyCouncilMemberIds) || !dto.emergencyCouncilMemberIds.containsAll(oldEmergencyCouncilMemberIds)
75-
|| oldRequiredEmergencyKeyShares != dto.defaultRequiredEmergencyKeyShares || oldAllowChoosingEmergencyCouncil != dto.allowChoosingEmergencyCouncil || oldMinMembers != dto.defaultMinMembers) {
76+
if (!oldEmergencyCouncilMemberIds.containsAll(dto.emergencyCouncilMemberIds)
77+
|| !dto.emergencyCouncilMemberIds.containsAll(oldEmergencyCouncilMemberIds)
78+
|| oldRequiredEmergencyKeyShares != dto.defaultRequiredEmergencyKeyShares
79+
|| oldAllowChoosingEmergencyCouncil != dto.allowChoosingEmergencyCouncil
80+
|| oldMinMembers != dto.defaultMinMembers
81+
|| oldEmergencyAccessEnabled != dto.enableEmergencyAccess) {
7682
var councilMemberIds = "[\"" + String.join("\", \"", dto.emergencyCouncilMemberIds) + "\"]";
77-
eventLogger.logEmergencyAccessSettingsUpdated(jwt.getSubject(), councilMemberIds, dto.defaultRequiredEmergencyKeyShares, dto.defaultMinMembers, dto.allowChoosingEmergencyCouncil);
83+
eventLogger.logEmergencyAccessSettingsUpdated(jwt.getSubject(), dto.enableEmergencyAccess, councilMemberIds, dto.defaultRequiredEmergencyKeyShares, dto.defaultMinMembers, dto.allowChoosingEmergencyCouncil);
7884
}
7985
return Response.status(Response.Status.NO_CONTENT).build();
8086
}
8187

8288
public record SettingsDto(@JsonProperty("hubId") String hubId,
8389
@JsonProperty("wotMaxDepth") @Min(0) @Max(9) int wotMaxDepth,
8490
@JsonProperty("wotIdVerifyLen") @Min(0) int wotIdVerifyLen,
91+
@JsonProperty("enableEmergencyAccess") boolean enableEmergencyAccess,
8592
@JsonProperty("defaultRequiredEmergencyKeyShares") @Min(0) int defaultRequiredEmergencyKeyShares,
8693
@JsonProperty("defaultMinMembers") @Min(0) int defaultMinMembers,
8794
@JsonProperty("allowChoosingEmergencyCouncil") boolean allowChoosingEmergencyCouncil,
8895
@JsonProperty("emergencyCouncilMemberIds") Set<String> emergencyCouncilMemberIds) {
8996

9097
public static SettingsDto fromEntity(Settings entity) {
91-
return new SettingsDto(entity.getHubId(), entity.getWotMaxDepth(), entity.getWotIdVerifyLen(), entity.getDefaultRequiredEmergencyKeyShares(), entity.getDefaultMinMembers(), entity.isAllowChoosingEmergencyCouncil(), entity.getEmergencyCouncilMemberIds());
98+
return new SettingsDto(entity.getHubId(), entity.getWotMaxDepth(), entity.getWotIdVerifyLen(), entity.isEmergencyAcessEnabled(), entity.getDefaultRequiredEmergencyKeyShares(), entity.getDefaultMinMembers(), entity.isAllowChoosingEmergencyCouncil(), entity.getEmergencyCouncilMemberIds());
9299
}
93100

94101
}

backend/src/main/java/org/cryptomator/hub/entities/Settings.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public class Settings {
3838
@Column(name = "wot_id_verify_len", nullable = false)
3939
private int wotIdVerifyLen;
4040

41+
@Column(name = "enable_emergency_access", nullable = false)
42+
private boolean enableEmergencyAccess;
43+
4144
@Column(name = "default_required_emergency_key_shares", nullable = false)
4245
private int defaultRequiredEmergencyKeyShares;
4346

@@ -95,6 +98,14 @@ public void setWotIdVerifyLen(int wotIdVerifyLen) {
9598
this.wotIdVerifyLen = wotIdVerifyLen;
9699
}
97100

101+
public boolean isEmergencyAcessEnabled() {
102+
return enableEmergencyAccess;
103+
}
104+
105+
public void setEmergencyAcessEnabled(boolean enableEmergencyAccess) {
106+
this.enableEmergencyAccess = enableEmergencyAccess;
107+
}
108+
98109
public int getDefaultRequiredEmergencyKeyShares() {
99110
return defaultRequiredEmergencyKeyShares;
100111
}
@@ -136,6 +147,7 @@ public String toString() {
136147
", licenseKey='" + licenseKey + '\'' +
137148
", wotMaxDepth='" + wotMaxDepth + '\'' +
138149
", wotIdVerifyLen='" + wotIdVerifyLen + '\'' +
150+
", enableEmergencyAccess=" + enableEmergencyAccess + '\'' +
139151
", defaultRequiredEmergencyKeyShares=" + defaultRequiredEmergencyKeyShares +
140152
", defaultMinMembers=" + defaultMinMembers +
141153
", allowChoosingEmergencyCouncil=" + allowChoosingEmergencyCouncil +
@@ -153,6 +165,7 @@ public boolean equals(Object o) {
153165
&& Objects.equals(licenseKey, settings.licenseKey)
154166
&& Objects.equals(wotMaxDepth, settings.wotMaxDepth)
155167
&& Objects.equals(wotIdVerifyLen, settings.wotIdVerifyLen)
168+
&& enableEmergencyAccess == settings.enableEmergencyAccess
156169
&& defaultRequiredEmergencyKeyShares == settings.defaultRequiredEmergencyKeyShares
157170
&& defaultMinMembers == settings.defaultMinMembers
158171
&& allowChoosingEmergencyCouncil == settings.allowChoosingEmergencyCouncil
@@ -161,7 +174,7 @@ public boolean equals(Object o) {
161174

162175
@Override
163176
public int hashCode() {
164-
return Objects.hash(id, hubId, licenseKey, wotMaxDepth, wotIdVerifyLen, defaultRequiredEmergencyKeyShares, defaultMinMembers, allowChoosingEmergencyCouncil, emergencyCouncilMemberIds);
177+
return Objects.hash(id, hubId, licenseKey, wotMaxDepth, wotIdVerifyLen, enableEmergencyAccess, defaultRequiredEmergencyKeyShares, defaultMinMembers, allowChoosingEmergencyCouncil, emergencyCouncilMemberIds);
165178
}
166179

167180
@ApplicationScoped

backend/src/main/java/org/cryptomator/hub/entities/events/EmergencyAccessSettingsUpdatedEvent.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public class EmergencyAccessSettingsUpdatedEvent extends AuditEvent {
1717
@Column(name = "admin_id", nullable = false)
1818
private String adminId;
1919

20+
@Column(name = "enable_emergency_access", nullable = false)
21+
private boolean enableEmergencyAccess;
22+
2023
@Column(name = "council_member_ids", nullable = false)
2124
private String councilMemberIds;
2225

@@ -37,6 +40,14 @@ public void setAdminId(String adminId) {
3740
this.adminId = adminId;
3841
}
3942

43+
public boolean isEmergencyAcessEnabled() {
44+
return enableEmergencyAccess;
45+
}
46+
47+
public void setEmergencyAcessEnabled(boolean enableEmergencyAccess) {
48+
this.enableEmergencyAccess = enableEmergencyAccess;
49+
}
50+
4051
public String getCouncilMemberIds() {
4152
return councilMemberIds;
4253
}

backend/src/main/java/org/cryptomator/hub/entities/events/EventLogger.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,14 +155,15 @@ public void logEmergencyAccessSetup(UUID vaultId, String ownerId, String setting
155155
auditEventRepository.persist(event);
156156
}
157157

158-
public void logEmergencyAccessSettingsUpdated(String adminId, String councilMemberIds, int requiredKeyShares, int minMembers, boolean allowChoosingCouncil) {
158+
public void logEmergencyAccessSettingsUpdated(String adminId, boolean enableEmergencyAccess, String councilMemberIds, int requiredKeyShares, int minMembers, boolean allowChoosingCouncil) {
159159
var event = new EmergencyAccessSettingsUpdatedEvent();
160160
event.setTimestamp(Instant.now());
161161
event.setAdminId(adminId);
162162
event.setCouncilMemberIds(councilMemberIds);
163163
event.setRequiredKeyShares(requiredKeyShares);
164164
event.setMinMembers(minMembers);
165165
event.setAllowChoosingCouncil(allowChoosingCouncil);
166+
event.setEmergencyAcessEnabled(enableEmergencyAccess);
166167
auditEventRepository.persist(event);
167168
}
168169

backend/src/main/resources/org/cryptomator/hub/flyway/V23__Emergency_Access.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ALTER TABLE "settings" ADD "default_required_emergency_key_shares" INTEGER NOT NULL DEFAULT 2;
22
ALTER TABLE "settings" ADD "default_min_members" INTEGER NOT NULL DEFAULT 3;
33
ALTER TABLE "settings" ADD "allow_choosing_emergency_council" BOOLEAN NOT NULL DEFAULT TRUE;
4+
ALTER TABLE "settings" ADD "enable_emergency_access" BOOLEAN NOT NULL DEFAULT FALSE;
45

56
ALTER TABLE "vault" ADD "requried_emergency_key_shares" INTEGER NOT NULL DEFAULT 0;
67

@@ -56,6 +57,7 @@ CREATE TABLE "audit_event_emergaccess_settings_updated"
5657
(
5758
"id" BIGINT NOT NULL,
5859
"admin_id" VARCHAR(255) COLLATE "C" NOT NULL,
60+
"enable_emergency_access" BOOLEAN NOT NULL,
5961
"council_member_ids" TEXT NOT NULL,
6062
"required_key_shares" INTEGER NOT NULL,
6163
"min_members" INTEGER NOT NULL,

backend/src/test/resources/org/cryptomator/hub/flyway/V9999__Test_Data.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ SET "hub_id" = '42',
77
"license_key" = 'eyJhbGciOiJFUzUxMiJ9.eyJqdGkiOiI0MiIsImlhdCI6MTY0ODA0OTM2MCwiaXNzIjoiU2t5bWF0aWMiLCJhdWQiOiJDcnlwdG9tYXRvciBIdWIiLCJzdWIiOiJodWJAY3J5cHRvbWF0b3Iub3JnIiwic2VhdHMiOjUsImV4cCI6MjUzNDAyMjE0NDAwLCJyZWZyZXNoVXJsIjoiaHR0cDovL2xvY2FsaG9zdDo4Nzg3L2h1Yi9zdWJzY3JpcHRpb24_aHViX2lkPTQyIn0.AKyoZ0WQ8xhs8vPymWPHCsc6ch6pZpfxBcrF5QjVLSQVnYz2s5QF3nnkwn4AGR7V14TuhkJMZLUZxMdQAYLyL95sAV2Fu0E4-e1v3IVKlNKtze89eqYvEs6Ak9jWjtecOgPWNWjz2itI4MfJBDmbFtTnehOtqRqUdsDoC9NFik2C7tHm',
88
"default_required_emergency_key_shares" = 2,
99
"default_min_members" = 3,
10-
"allow_choosing_emergency_council" = FALSE
10+
"allow_choosing_emergency_council" = FALSE,
11+
"enable_emergency_access" = FALSE
1112
WHERE "id" = 0;
1213

1314
INSERT INTO "authority" ("id", "type", "name")

frontend/src/common/auditlog.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ export type AuditEventEmergencyAccessSetupDto = AuditEventDtoBase & {
125125
export type AuditEventEmergencyAccessSettingsChangedDto = AuditEventDtoBase & {
126126
type: 'EMERGENCY_ACCESS_SETTINGS_UPDATED',
127127
adminId: string;
128+
enableEmergencyAccess: boolean;
128129
councilMemberIds: string;
129130
requiredKeyShares: number;
130131
minMembers: number;

frontend/src/common/backend.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ export type SettingsDto = {
141141
defaultRequiredEmergencyKeyShares: number,
142142
defaultMinMembers: number,
143143
allowChoosingEmergencyCouncil: boolean,
144-
emergencyCouncilMemberIds: string[]
144+
emergencyCouncilMemberIds: string[],
145+
enableEmergencyAccess: boolean
145146
}
146147

147148
export type RecoveryProcessSetNewOwner = {

0 commit comments

Comments
 (0)