-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OKAPI-1081: Reject invalid tenant ids
https://folio-org.atlassian.net/browse/OKAPI-1081 Implement https://folio-org.atlassian.net/wiki/display/TC/ADR-000002+-+Tenant+Id+and+Module+Name+Restrictions so that creating a new tenant via POST /_/proxy/tenants API is rejected unless the tenant id matches ^[a-z][a-z0-9]{0,30}$ Legacy tenant ids still work when used in any other API.
- Loading branch information
1 parent
7101d6f
commit 490ef9b
Showing
6 changed files
with
114 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
okapi-core/src/main/java/org/folio/okapi/util/TenantValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.folio.okapi.util; | ||
|
||
import java.util.regex.Pattern; | ||
|
||
import org.folio.okapi.common.ErrorType; | ||
import org.folio.okapi.common.Messages; | ||
|
||
import io.vertx.core.Future; | ||
|
||
public final class TenantValidator { | ||
|
||
// multi-byte sequences forbidden in pattern, so char length = byte length | ||
private static final String TENANT_PATTERN_STRING = "^[a-z][a-z0-9]{0,30}$"; | ||
private static final Pattern TENANT_PATTERN = Pattern.compile(TENANT_PATTERN_STRING); | ||
private static final Pattern STARTS_WITH_DIGIT = Pattern.compile("^[0-9]"); | ||
private static final Messages MESSAGES = Messages.getInstance(); | ||
|
||
private TenantValidator() { | ||
throw new UnsupportedOperationException("Cannot instantiate utility class."); | ||
} | ||
|
||
public static Future<Void> validate(String tenantId) { | ||
if (TENANT_PATTERN.matcher(tenantId).matches()) { | ||
return Future.succeededFuture(); | ||
} | ||
|
||
if (tenantId.contains("_")) { | ||
return failure("11609", tenantId); | ||
} | ||
|
||
if (tenantId.contains("-")) { | ||
return failure("11610", tenantId); | ||
} | ||
|
||
if (tenantId.length() > 31) { | ||
return failure("11611", tenantId); | ||
} | ||
|
||
if (STARTS_WITH_DIGIT.matcher(tenantId).matches()) { | ||
return failure("11612", tenantId); | ||
} | ||
|
||
return failure("11601", tenantId); | ||
} | ||
|
||
private static Future<Void> failure(String errorMessage, String tenantId) { | ||
return Future.failedFuture(new OkapiError(ErrorType.USER, | ||
MESSAGES.getMessage(errorMessage, tenantId))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
okapi-core/src/test/java/org/folio/okapi/util/TenantValidatorTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.folio.okapi.util; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import org.folio.okapi.testing.UtilityClassTester; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.CsvSource; | ||
|
||
class TenantValidatorTest { | ||
|
||
@Test | ||
void utilityClass() { | ||
UtilityClassTester.assertUtilityClass(TenantValidator.class); | ||
} | ||
|
||
@ParameterizedTest | ||
@CsvSource({ | ||
"a, ", | ||
"a1, ", | ||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, ", | ||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, Tenant id must not exceed 31 characters: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", | ||
"1, Tenant id must not start with a digit: 1", | ||
"foo_bar, Tenant id must not contain underscore: foo_bar", | ||
"a-z, Tenant id must not contain minus: a-z", | ||
"universität, 'Invalid tenant id, may only contain a-z and 0-9 and must match [a-z][a-z0-9]{0,30} but it is universität'", | ||
}) | ||
void validate(String tenantId, String errorMessage) { | ||
var result = TenantValidator.validate(tenantId); | ||
if (errorMessage == null) { | ||
assertThat(result.succeeded()).isTrue(); | ||
} else { | ||
assertThat(result.cause().getMessage()).isEqualTo(errorMessage); | ||
} | ||
} | ||
} |