diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml
index e0f1f06686..23dde8d830 100644
--- a/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml
+++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/liquibase.xml
@@ -115,5 +115,6 @@
+
diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.69.0.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.69.0.xml
index aab2a816f4..5b10e1b916 100644
--- a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.69.0.xml
+++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.69.0.xml
@@ -4,9 +4,11 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
-
+
+
+
+
+
diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.79.0.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.79.0.xml
index 5ae08bc7b1..b62cc37df7 100644
--- a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.79.0.xml
+++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.79.0.xml
@@ -4,12 +4,15 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
+
+
diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.80.0.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.80.0.xml
index a44d519aa3..7607fbd8e6 100644
--- a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.80.0.xml
+++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v0.80.0.xml
@@ -7,16 +7,20 @@
+ ANY
${concordSystemWriterRoleId}
concordSystemWriter
true
+
+
+
@@ -38,6 +39,8 @@
+
+
+
+
-
+ -->
diff --git a/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.21.0.xml b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.21.0.xml
new file mode 100644
index 0000000000..2569a43642
--- /dev/null
+++ b/server/db/src/main/resources/com/walmartlabs/concord/server/db/v2.21.0.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+ create unique index IDX_API_KEYS_NAME_USER_NULL on API_KEYS (KEY_NAME) where USER_ID is null
+
+
+ create unique index IDX_API_KEYS_NAME_USER_NOT_NULL on API_KEYS (KEY_NAME, USER_ID) where USER_ID is not null
+
+
+
+
+ ANY
+
+
+
+ select count(key_id)
+ from API_KEYS
+ where KEY_NAME = 'concordAgentKey_autogenerated';
+
+
+
+ select count(key_id)
+ from API_KEYS
+ where USER_ID = 'd4f123c1-f8d4-40b2-8a12-b8947b9ce2d8';
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/server/impl/src/main/java/com/walmartlabs/concord/server/security/apikey/ApiKeyRealm.java b/server/impl/src/main/java/com/walmartlabs/concord/server/security/apikey/ApiKeyRealm.java
index 609893efc8..e3398c360c 100644
--- a/server/impl/src/main/java/com/walmartlabs/concord/server/security/apikey/ApiKeyRealm.java
+++ b/server/impl/src/main/java/com/walmartlabs/concord/server/security/apikey/ApiKeyRealm.java
@@ -62,17 +62,20 @@ public boolean supports(AuthenticationToken token) {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
ApiKey t = (ApiKey) token;
- UserEntry u = userManager.get(t.getUserId()).orElse(null);
- if (u == null) {
- return null;
- }
+ UserEntry u = null;
+ if (t.getUserId() != null) {
+ u = userManager.get(t.getUserId()).orElse(null);
+ if (u == null) {
+ return null;
+ }
- if (u.isDisabled()) {
- throw new AuthenticationException("User account '" + u.getName() + "' is disabled");
+ if (u.isDisabled()) {
+ throw new AuthenticationException("User account '" + u.getName() + "' is disabled");
+ }
}
auditLog.add(AuditObject.SYSTEM, AuditAction.ACCESS)
- .userId(u.getId())
+ .userId(u != null ? u.getId() : null)
.field("realm", REALM_NAME)
.field("apiKeyId", t.getKeyId())
.log();
diff --git a/server/liquibase-ext/src/main/java/com/walmartlabs/concord/server/liquibase/ext/ApiTokenCreator.java b/server/liquibase-ext/src/main/java/com/walmartlabs/concord/server/liquibase/ext/ApiTokenCreator.java
index 4f7d9d477a..863446832c 100644
--- a/server/liquibase-ext/src/main/java/com/walmartlabs/concord/server/liquibase/ext/ApiTokenCreator.java
+++ b/server/liquibase-ext/src/main/java/com/walmartlabs/concord/server/liquibase/ext/ApiTokenCreator.java
@@ -43,12 +43,13 @@ public class ApiTokenCreator implements CustomSqlChange, CustomSqlRollback {
private static final Logger log = LoggerFactory.getLogger(ApiTokenCreator.class);
- private static final String KEY_NAME = "autogenerated";
+ private static final String DEFAULT_KEY_NAME = "autogenerated";
private String token;
private String userId;
private String username;
private String skip;
+ private String keyName;
public void setUserId(String userId) {
this.userId = userId;
@@ -66,6 +67,10 @@ public void setSkip(String skip) {
this.skip = skip;
}
+ public void setKeyName(String keyName) {
+ this.keyName = keyName;
+ }
+
@Override
public SqlStatement[] generateStatements(Database database) {
if (this.token == null) {
@@ -77,7 +82,7 @@ public SqlStatement[] generateStatements(Database database) {
new InsertStatement(null, null, "API_KEYS")
.addColumnValue("API_KEY", hash(token))
.addColumnValue("USER_ID", userId)
- .addColumnValue("KEY_NAME", KEY_NAME)
+ .addColumnValue("KEY_NAME", getKeyName())
};
}
@@ -87,12 +92,20 @@ public SqlStatement[] generateRollbackStatements(Database database) {
return new SqlStatement[0];
}
- return new SqlStatement[]{
- new DeleteStatement(null, null, "API_KEYS")
- .setWhere("USER_ID=? and KEY_NAME=?")
- .addWhereParameter(userId)
- .addWhereParameter(KEY_NAME)
- };
+ if (userId != null) {
+ return new SqlStatement[]{
+ new DeleteStatement(null, null, "API_KEYS")
+ .setWhere("USER_ID=? and KEY_NAME=?")
+ .addWhereParameter(userId)
+ .addWhereParameter(getKeyName())
+ };
+ } else {
+ return new SqlStatement[]{
+ new DeleteStatement(null, null, "API_KEYS")
+ .setWhere("KEY_NAME=?")
+ .addWhereParameter(getKeyName())
+ };
+ }
}
@Override
@@ -137,6 +150,13 @@ public ValidationErrors validate(Database database) {
return null;
}
+ private String getKeyName() {
+ if (this.keyName != null) {
+ return this.keyName;
+ }
+ return DEFAULT_KEY_NAME;
+ }
+
private static String newApiKey() {
try {
byte[] ab = new byte[16];