diff --git a/api/pom.xml b/api/pom.xml
index 15ad8d70..71c4c786 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Account.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Account.java
index b24dca26..0ee73fe5 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Account.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Account.java
@@ -14,8 +14,8 @@
@DTOStyle
@JsonSerialize(as = AccountDTO.class)
@JsonDeserialize(as = AccountDTO.class)
-public interface Account {
- long getId();
+public interface Account extends DomainScoped {
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
@@ -28,7 +28,6 @@ public interface Account {
String getMiddleName();
String getLastName();
String getFullName();
- String getDomain();
List getPermissions();
List getRoles();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/AccountLock.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/AccountLock.java
index 6e1351a8..842524cd 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/AccountLock.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/AccountLock.java
@@ -8,6 +8,6 @@
@Value.Immutable
@DTOStyle
public interface AccountLock {
- long getAccountId();
+ String getAccountId();
Instant getExpiresAt();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ActionToken.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ActionToken.java
index 1539ac4e..5191b0c8 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ActionToken.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ActionToken.java
@@ -12,6 +12,6 @@
public interface ActionToken {
String getToken();
String getAction();
- Long getAccountId();
+ String getAccountId();
long getValidFor();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ApiKey.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ApiKey.java
index f3a5f44e..376e1326 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ApiKey.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ApiKey.java
@@ -12,12 +12,13 @@
@JsonSerialize(as = ApiKeyDTO.class)
@JsonDeserialize(as = ApiKeyDTO.class)
public interface ApiKey {
- long getId();
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
- Long getAppId();
+ String getAppId();
String getKey();
String getType();
+ String getName();
boolean isForClient();
Instant getExpiresAt();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/App.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/App.java
index 63dd52a2..b35f85b8 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/App.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/App.java
@@ -12,14 +12,13 @@
@DTOStyle
@JsonSerialize(as = AppDTO.class)
@JsonDeserialize(as = AppDTO.class)
-public interface App {
- long getId();
+public interface App extends DomainScoped {
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
String getExternalId();
String getName();
- Long getAccountId();
- String getDomain();
+ String getAccountId();
String getBaseUrl();
List getPermissions();
List getRoles();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Client.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Client.java
index 6558ccd9..91ba0e49 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Client.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Client.java
@@ -11,14 +11,13 @@
@DTOStyle
@JsonSerialize(as = ClientDTO.class)
@JsonDeserialize(as = ClientDTO.class)
-public interface Client {
- long getId();
+public interface Client extends DomainScoped {
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
String getExternalId();
String getName();
- Long getAccountId();
- String getDomain();
+ String getAccountId();
String getBaseUrl();
String getClientType();
boolean isActive();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Credentials.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Credentials.java
index 36add5df..401dab9a 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Credentials.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Credentials.java
@@ -11,7 +11,7 @@
@DTOStyle
@JsonDeserialize(as = CredentialsDTO.class)
public interface Credentials {
- long getId();
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
Instant getPasswordUpdatedAt();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/DomainScoped.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/DomainScoped.java
new file mode 100644
index 00000000..87ce936b
--- /dev/null
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/DomainScoped.java
@@ -0,0 +1,5 @@
+package com.nexblocks.authguard.api.dto.entities;
+
+public interface DomainScoped {
+ String getDomain();
+}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ExchangeAttempt.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ExchangeAttempt.java
index 69460c73..115c15f5 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ExchangeAttempt.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/ExchangeAttempt.java
@@ -8,10 +8,10 @@
@Value.Immutable
@DTOStyle
public interface ExchangeAttempt {
- long getId();
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
- Long getEntityId();
+ String getEntityId();
String getExchangeFrom();
String getExchangeTo();
boolean isSuccessful();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Permission.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Permission.java
index 27941bc0..29d08f87 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Permission.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Permission.java
@@ -11,11 +11,10 @@
@DTOStyle
@JsonSerialize(as = PermissionDTO.class)
@JsonDeserialize(as = PermissionDTO.class)
-public interface Permission {
- long getId();
+public interface Permission extends DomainScoped {
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
String getGroup();
String getName();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Role.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Role.java
index 82603953..31c0671f 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Role.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/Role.java
@@ -11,10 +11,9 @@
@DTOStyle
@JsonDeserialize(as = RoleDTO.class)
@JsonSerialize(as = RoleDTO.class)
-public interface Role {
- long getId();
+public interface Role extends DomainScoped {
+ String getId();
Instant getCreatedAt();
Instant getLastModified();
String getName();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/UserIdentifier.java b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/UserIdentifier.java
index 31b60c27..9fd973c5 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/entities/UserIdentifier.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/entities/UserIdentifier.java
@@ -9,10 +9,9 @@
@DTOStyle
@JsonSerialize(as = UserIdentifierDTO.class)
@JsonDeserialize(as = UserIdentifierDTO.class)
-public interface UserIdentifier {
+public interface UserIdentifier extends DomainScoped {
Type getType();
String getIdentifier();
- String getDomain();
@Value.Default
default boolean isActive() {
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/ApiKeyRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/ApiKeyRequest.java
index ca80417b..ee55bc50 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/ApiKeyRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/ApiKeyRequest.java
@@ -14,7 +14,8 @@
public interface ApiKeyRequest {
boolean isForClient();
String getKeyType();
- Long getAppId();
+ String getAppId();
+ String getName();
Instant getExpiresAt();
DurationRequestDTO getValidFor();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAccountRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAccountRequest.java
index e62a9869..9655f1dc 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAccountRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAccountRequest.java
@@ -2,10 +2,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
-import com.nexblocks.authguard.api.dto.entities.AccountEmailDTO;
-import com.nexblocks.authguard.api.dto.entities.PermissionDTO;
-import com.nexblocks.authguard.api.dto.entities.PhoneNumberDTO;
-import com.nexblocks.authguard.api.dto.entities.UserIdentifierDTO;
+import com.nexblocks.authguard.api.dto.entities.*;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import org.immutables.value.Value;
@@ -16,14 +13,13 @@
@DTOStyle
@JsonDeserialize(as = CreateAccountRequestDTO.class)
@JsonSerialize(as = CreateAccountRequestDTO.class)
-public interface CreateAccountRequest {
+public interface CreateAccountRequest extends DomainScoped {
String getExternalId();
String getFirstName();
String getMiddleName();
String getLastName();
String getFullName();
- String getDomain();
AccountEmailDTO getEmail();
AccountEmailDTO getBackupEmail();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAppRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAppRequest.java
index 9dcf8d41..dcd22d6b 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAppRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateAppRequest.java
@@ -1,5 +1,6 @@
package com.nexblocks.authguard.api.dto.requests;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.entities.PermissionDTO;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -12,11 +13,10 @@
@DTOStyle
@JsonDeserialize(as = CreateAppRequestDTO.class)
@JsonSerialize(as = CreateAppRequestDTO.class)
-public interface CreateAppRequest {
+public interface CreateAppRequest extends DomainScoped {
String getExternalId();
String getName();
- Long getAccountId();
- String getDomain();
+ String getAccountId();
List getPermissions();
List getScopes();
List getRoles();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateClientRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateClientRequest.java
index 99498f31..b94ef3a0 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateClientRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateClientRequest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import org.immutables.value.Value;
@@ -10,11 +11,10 @@
@DTOStyle
@JsonDeserialize(as = CreateClientRequestDTO.class)
@JsonSerialize(as = CreateClientRequestDTO.class)
-public interface CreateClientRequest {
+public interface CreateClientRequest extends DomainScoped {
String getExternalId();
String getName();
Long getAccountId();
- String getDomain();
String getBaseUrl();
ClientType getClientType();
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreatePermissionRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreatePermissionRequest.java
index 34e2b062..d871d89c 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreatePermissionRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreatePermissionRequest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import org.immutables.value.Value;
@@ -9,8 +10,7 @@
@DTOStyle
@JsonSerialize(as = CreatePermissionRequestDTO.class)
@JsonDeserialize(as = CreatePermissionRequestDTO.class)
-public interface CreatePermissionRequest {
+public interface CreatePermissionRequest extends DomainScoped {
String getGroup();
String getName();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateRoleRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateRoleRequest.java
index 1accc872..3531972e 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateRoleRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/CreateRoleRequest.java
@@ -1,5 +1,6 @@
package com.nexblocks.authguard.api.dto.requests;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@@ -9,7 +10,6 @@
@DTOStyle
@JsonDeserialize(as = CreateRoleRequestDTO.class)
@JsonSerialize(as = CreateRoleRequestDTO.class)
-public interface CreateRoleRequest {
+public interface CreateRoleRequest extends DomainScoped {
String getName();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/OtpRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/OtpRequest.java
index 3ce6e272..01430e89 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/OtpRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/OtpRequest.java
@@ -10,6 +10,6 @@
@JsonDeserialize(as = OtpRequestDTO.class)
@JsonSerialize(as = OtpRequestDTO.class)
public interface OtpRequest {
- Long getPasswordId();
+ String getPasswordId();
String getPassword();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetRequest.java
index dd1fdb91..ad306f8b 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetRequest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import org.immutables.value.Value;
@@ -9,11 +10,10 @@
@DTOStyle
@JsonSerialize(as = PasswordResetRequestDTO.class)
@JsonDeserialize(as = PasswordResetRequestDTO.class)
-public interface PasswordResetRequest {
+public interface PasswordResetRequest extends DomainScoped {
boolean isByToken();
String getResetToken();
String getIdentifier();
String getOldPassword();
String getNewPassword();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetTokenRequest.java b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetTokenRequest.java
index db41cbe9..ac24e8a2 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetTokenRequest.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/requests/PasswordResetTokenRequest.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.style.DTOStyle;
import org.immutables.value.Value;
@@ -9,7 +10,6 @@
@DTOStyle
@JsonSerialize(as = PasswordResetTokenRequestDTO.class)
@JsonDeserialize(as = PasswordResetTokenRequestDTO.class)
-public interface PasswordResetTokenRequest {
+public interface PasswordResetTokenRequest extends DomainScoped {
String getIdentifier();
- String getDomain();
}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/validation/IdParser.java b/api/src/main/java/com/nexblocks/authguard/api/dto/validation/IdParser.java
new file mode 100644
index 00000000..74b02a0d
--- /dev/null
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/validation/IdParser.java
@@ -0,0 +1,14 @@
+package com.nexblocks.authguard.api.dto.validation;
+
+import com.nexblocks.authguard.service.exceptions.ServiceException;
+import com.nexblocks.authguard.service.exceptions.codes.ErrorCode;
+
+public class IdParser {
+ public static Long from(final String idString) {
+ try {
+ return Long.parseLong(idString);
+ } catch (NumberFormatException ex) {
+ throw new ServiceException(ErrorCode.INVALID_REQUEST_VALUE, "Value '" + idString + "' is not a valid ID");
+ }
+ }
+}
diff --git a/api/src/main/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidator.java b/api/src/main/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidator.java
index 82fddf2a..0670d682 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidator.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidator.java
@@ -13,6 +13,7 @@ public class PasswordResetRequestValidator implements Validator validate(final PasswordResetRequestDTO obj) {
return FluentValidator.begin()
+ .validate("domain", obj.getDomain(), Constraints.required)
.validate("identifier", obj.getIdentifier(), identifier -> {
if (!obj.isByToken() && identifier == null) {
return Collections.singletonList(
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/AccountsApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/AccountsApi.java
index 6bba3a28..5d25047b 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/AccountsApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/AccountsApi.java
@@ -9,7 +9,7 @@ public abstract class AccountsApi implements ApiRoute {
@Override
public String getPath() {
- return "accounts";
+ return "/domains/:domain/accounts";
}
public void addEndpoints() {
@@ -18,12 +18,12 @@ public void addEndpoints() {
get("/:id", this::getById, ActorRoles.adminClient());
delete("/:id", this::deleteAccount, ActorRoles.adminClient());
patch("/:id", this::patchAccount, ActorRoles.adminClient());
- get("/domain/:domain/identifier/:identifier", this::getByIdentifier, ActorRoles.adminClient());
- get("/domain/:domain/identifier/:identifier/exists", this::identifierExists, ActorRoles.adminOrAuthClient());
+ get("/identifier/:identifier", this::getByIdentifier, ActorRoles.adminClient());
+ get("/identifier/:identifier/exists", this::identifierExists, ActorRoles.adminOrAuthClient());
get("/externalId/:id", this::getByExternalId, ActorRoles.adminClient());
- get("/domain/:domain/email/:email", this::getByEmail, ActorRoles.adminClient());
- get("/domain/:domain/email/:email/exists", this::emailExists, ActorRoles.adminOrAuthClient());
+ get("/email/:email", this::getByEmail, ActorRoles.adminClient());
+ get("/email/:email/exists", this::emailExists, ActorRoles.adminOrAuthClient());
patch("/:id/permissions", this::updatePermissions, ActorRoles.adminClient());
patch("/:id/roles", this::updateRoles, ActorRoles.adminClient());
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/ActionTokensApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/ActionTokensApi.java
index 4eba95c8..2d5a7a10 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/ActionTokensApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/ActionTokensApi.java
@@ -8,7 +8,7 @@
public abstract class ActionTokensApi implements ApiRoute {
@Override
public String getPath() {
- return "actions";
+ return "/domains/:domain/actions";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/ApiKeysApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/ApiKeysApi.java
index e06aa2ca..9f69f9a2 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/ApiKeysApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/ApiKeysApi.java
@@ -9,7 +9,7 @@ public abstract class ApiKeysApi implements ApiRoute {
@Override
public String getPath() {
- return "keys";
+ return "/domains/:domain/keys";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/ApplicationsApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/ApplicationsApi.java
index fda77c32..05a1d311 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/ApplicationsApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/ApplicationsApi.java
@@ -9,7 +9,7 @@ public abstract class ApplicationsApi implements ApiRoute {
@Override
public String getPath() {
- return "apps";
+ return "/domains/:domain/apps";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/AuthApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/AuthApi.java
index a1ab05e0..2e90bdc2 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/AuthApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/AuthApi.java
@@ -10,7 +10,7 @@ public abstract class AuthApi implements ApiRoute {
@Override
public String getPath() {
- return "auth";
+ return "/domains/:domain/auth";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/ClientsApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/ClientsApi.java
index 3d367334..9b4418a2 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/ClientsApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/ClientsApi.java
@@ -8,7 +8,7 @@
public abstract class ClientsApi implements ApiRoute {
@Override
public String getPath() {
- return "clients";
+ return "/domains/:domain/clients";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/CredentialsApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/CredentialsApi.java
index 9141803c..5ac64ab1 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/CredentialsApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/CredentialsApi.java
@@ -9,7 +9,7 @@ public abstract class CredentialsApi implements ApiRoute {
@Override
public String getPath() {
- return "credentials";
+ return "/domains/:domain/credentials";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/OtpApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/OtpApi.java
index a8edcfb5..3057a3b5 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/OtpApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/OtpApi.java
@@ -9,7 +9,7 @@ public abstract class OtpApi implements ApiRoute {
@Override
public String getPath() {
- return "otp";
+ return "/domains/:domain/otp";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/PasswordlessApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/PasswordlessApi.java
index 0a0f946d..493a6fbd 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/PasswordlessApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/PasswordlessApi.java
@@ -9,7 +9,7 @@ public abstract class PasswordlessApi implements ApiRoute {
@Override
public String getPath() {
- return "passwordless";
+ return "/domains/:domain/passwordless";
}
@Override
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/PermissionsApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/PermissionsApi.java
index 047d9d38..c2fbc301 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/PermissionsApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/PermissionsApi.java
@@ -9,7 +9,7 @@ public abstract class PermissionsApi implements ApiRoute {
@Override
public String getPath() {
- return "permissions";
+ return "/domains/:domain/permissions";
}
@Override
@@ -17,8 +17,8 @@ public void addEndpoints() {
post("/", this::create, ActorRoles.adminClient());
get("/:id", this::getById, ActorRoles.adminClient());
delete("/:id", this::getById, ActorRoles.adminClient());
- get("/domain/:domain/group/:group", this::getByGroup, ActorRoles.adminClient());
- get("/domain/:domain", this::getAll, ActorRoles.adminClient());
+ get("/group/:group", this::getByGroup, ActorRoles.adminClient());
+ get("", this::getAll, ActorRoles.adminClient());
}
public abstract void create(final Context context);
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/RolesApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/RolesApi.java
index dd6d9382..c2daa7b4 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/RolesApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/RolesApi.java
@@ -9,7 +9,7 @@ public abstract class RolesApi implements ApiRoute {
@Override
public String getPath() {
- return "roles";
+ return "/domains/:domain/roles";
}
@Override
@@ -17,8 +17,8 @@ public void addEndpoints() {
post("/", this::create, ActorRoles.adminClient());
get("/:id", this::getById, ActorRoles.adminClient());;
delete("/:id", this::deleteById, ActorRoles.adminClient());;
- get("/domain/:domain/name/:name", this::getByName, ActorRoles.adminClient());
- get("/domain/:domain", this::getAll, ActorRoles.adminClient());
+ get("/name/:name", this::getByName, ActorRoles.adminClient());
+ get("", this::getAll, ActorRoles.adminClient());
}
public abstract void create(final Context context);
diff --git a/api/src/main/java/com/nexblocks/authguard/api/routes/VerificationApi.java b/api/src/main/java/com/nexblocks/authguard/api/routes/VerificationApi.java
index abf28d81..00d46663 100644
--- a/api/src/main/java/com/nexblocks/authguard/api/routes/VerificationApi.java
+++ b/api/src/main/java/com/nexblocks/authguard/api/routes/VerificationApi.java
@@ -9,7 +9,7 @@ public abstract class VerificationApi implements ApiRoute {
@Override
public String getPath() {
- return "verification";
+ return "/domains/:domain/verification";
}
@Override
diff --git a/api/src/main/resources/openapi.yml b/api/src/main/resources/openapi.yml
index b669f8fe..decb3de8 100644
--- a/api/src/main/resources/openapi.yml
+++ b/api/src/main/resources/openapi.yml
@@ -2,20 +2,21 @@ openapi: 3.0.3
info:
title: AuthGuard API
- version: 0.13.0
+ version: 0.22.0
security:
- apiKey: []
paths:
# ----------------- accounts -----------------
- /accounts:
+ /domains/{domain}/accounts:
post:
operationId: createAccount
description: Create an account
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdempotentKeyHeader"
requestBody:
content:
@@ -33,13 +34,14 @@ paths:
description: Conflict - if the idempotent key header was used to create an account before
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}:
+ /domains/{domain}/accounts/{id}:
get:
operationId: getAccountById
description: Get an account by ID
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -55,6 +57,7 @@ paths:
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
requestBody:
content:
@@ -78,6 +81,7 @@ paths:
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -87,13 +91,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/identifier/{id}:
+ /domains/{domain}/accounts/identifier/{id}:
get:
operationId: getAccountByCredentialsIdentifier
description: Get an account by credentials identifier
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdentifierParameter"
responses:
200:
@@ -103,13 +108,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/externalId/{id}:
+ /domains/{domain}/accounts/externalId/{id}:
get:
operationId: getAccountByExternalId
description: Get an account by external ID
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -119,13 +125,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/email/{email}:
+ /domains/{domain}/accounts/email/{email}:
get:
operationId: getAccountByEmail
description: Get an account by email, regardless of whether it's the primary email or not
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/EmailParameter"
responses:
200:
@@ -135,13 +142,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/email/{email}/exists:
+ /domains/{domain}/accounts/email/{email}/exists:
get:
operationId: emailExists
description: Checks whether an account with that email exists
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/EmailParameter"
responses:
200:
@@ -149,19 +157,20 @@ paths:
404:
description: Not found
- /accounts/{id}/permissions:
+ /domains/{domain}/accounts/{id}/permissions:
patch:
operationId: updateAccountPermissions
description: Update the permissions of an account
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/PermissionsRequest"
+ $ref: "#/components/schemas/PermissionsRequest"
responses:
200:
description: Success
@@ -170,13 +179,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}/roles:
+ /domains/{domain}/accounts/{id}/roles:
patch:
operationId: updateAccountRoles
description: Update the roles of an account
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
requestBody:
content:
@@ -191,13 +201,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}/activate:
+ /domains/{domain}/accounts/{id}/activate:
patch:
operationId: activateAnAccount
description: Activate an account if not already active
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -207,13 +218,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}/deactivate:
+ /domains/{domain}/accounts/{id}/deactivate:
patch:
operationId: deactivateAnAccount
description: Deactivate an account if it's active
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -223,13 +235,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}/apps:
+ /domains/{domain}/accounts/{id}/apps:
get:
operationId: getApplicationsByAccountId
description: Get a list of applications associated with an account
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -239,13 +252,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/{id}/locks:
+ /domains/{domain}/accounts/{id}/locks:
get:
operationId: getLocksByAccountId
description: Get a list of active locks placed on an account
tags:
- Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -255,108 +269,31 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /accounts/complete:
- post:
- operationId: createAccountWithCredentials
- description: Create an account as well as its credentials
- tags:
- - Accounts
- parameters:
- - $ref: "#/components/parameters/IdempotentKeyHeader"
- requestBody:
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/CreateCompleteAccountRequest"
- responses:
- 201:
- description: Success
- $ref: "#/components/responses/CompleteAccountResponse"
- 400:
- description: Bad request
- $ref: "#/components/responses/ErrorResponse"
- 409:
- description: Conflict - if the idempotent key header was used to create an account before
- $ref: "#/components/responses/ErrorResponse"
-
- # ----------------- credentials -----------------
- /credentials:
- post:
- operationId: createCredentials
- description: Create credentials
- tags:
- - Credentials
- parameters:
- - $ref: "#/components/parameters/IdempotentKeyHeader"
- requestBody:
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/CreateCredentialsRequest"
- responses:
- 201:
- description: Success
- $ref: "#/components/responses/CredentialsResponse"
- 400:
- description: Bad request
- $ref: "#/components/responses/ErrorResponse"
- 409:
- description: Conflict - if the idempotent key header was used to create credentials before
- $ref: "#/components/responses/ErrorResponse"
-
- /credentials/{id}:
- get:
- operationId: getCredentialsById
- description: Get credentials by ID
- tags:
- - Credentials
- parameters:
- - $ref: "#/components/parameters/IdParameter"
- responses:
- 200:
- description: Success
- $ref: "#/components/responses/CredentialsResponse"
- 404:
- description: Not found
- $ref: "#/components/responses/ErrorResponse"
- delete:
- operationId: deleteCredentials
- description: Delete credentials by ID
- tags:
- - Credentials
- parameters:
- - $ref: "#/components/parameters/IdParameter"
- responses:
- 200:
- description: Success
- $ref: "#/components/responses/CredentialsResponse"
- 404:
- description: Not found
- $ref: "#/components/responses/ErrorResponse"
-
- /credentials/identifier/{identifier}:
+ /domains/{domain}/accounts/identifier/{identifier}:
get:
- operationId: getCredentialsByIdentifier
- description: Get credentials by identifier
+ operationId: getAccountByIdentifier
+ description: Get account by identifier
tags:
- - Credentials
+ - Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdentifierParameter"
responses:
200:
description: Success
- $ref: "#/components/responses/CredentialsResponse"
+ $ref: "#/components/responses/AccountResponse"
404:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /credentials/identifier/{identifier}/exists:
+ /domains/{domain}/accounts/identifier/{identifier}/exists:
get:
operationId: identifierExists
description: Check whether an identifier exists or not
tags:
- - Credentials
+ - Accounts
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdentifierParameter"
responses:
200:
@@ -364,7 +301,8 @@ paths:
404:
description: Not found
- /credentials/{id}/password:
+ # ----------------- credentials -----------------
+ /domains/{domain}/credentials/{id}/password:
patch:
operationId: updatePassword
description: Update the password in a credentials entity
@@ -376,22 +314,24 @@ paths:
schema:
$ref: "#/components/schemas/UpdateCredentialsPasswordRequest"
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
description: Success
- $ref: "#/components/responses/CredentialsResponse"
+ $ref: "#/components/responses/AccountResponse"
404:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /credentials/{id}/identifiers:
+ /domains/{domain}/credentials/{id}/identifiers:
patch:
operationId: addIdentifier
description: Add new identifiers to credentials
tags:
- Credentials
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
requestBody:
content:
@@ -401,7 +341,7 @@ paths:
responses:
200:
description: Success
- $ref: "#/components/responses/CredentialsResponse"
+ $ref: "#/components/responses/AccountResponse"
404:
description: Not found
$ref: "#/components/responses/ErrorResponse"
@@ -415,6 +355,7 @@ paths:
tags:
- Credentials
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
requestBody:
content:
@@ -424,7 +365,7 @@ paths:
responses:
200:
description: Success
- $ref: "#/components/responses/CredentialsResponse"
+ $ref: "#/components/responses/AccountResponse"
404:
description: Not found
$ref: "#/components/responses/ErrorResponse"
@@ -432,12 +373,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /credentials/reset_token:
+ /domains/{domain}/credentials/reset_token:
post:
operationId: generateResetToken
description: Generates a new reset token which can be used by the user to set a new password
tags:
- Credentials
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -454,12 +397,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /credentials/reset:
+ /domains/{domain}/credentials/reset:
post:
operationId: resetPassword
description: Set a new password using a reset token or by using an identifier and its current password
tags:
- Credentials
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -468,7 +413,7 @@ paths:
responses:
200:
description: Success
- $ref: "#/components/responses/CredentialsResponse"
+ $ref: "#/components/responses/AccountResponse"
404:
description: Not found
$ref: "#/components/responses/ErrorResponse"
@@ -477,17 +422,19 @@ paths:
$ref: "#/components/responses/ErrorResponse"
# ----------------- applications -----------------
- /apps:
+ /domains/{domain}/apps:
post:
operationId: createApp
description: Create an application
tags:
- Applications
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/CreateApplicationRequest"
+ $ref: "#/components/schemas/CreateApplicationRequest"
responses:
201:
description: Success
@@ -496,13 +443,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /apps/{id}:
+ /domains/{domain}/apps/{id}:
get:
operationId: getAppById
description: Get an application by ID
tags:
- Applications
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -514,10 +462,11 @@ paths:
delete:
operationId: deleteApp
- description: Delet an application
+ description: Delete an application
tags:
- Applications
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -527,7 +476,7 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /apps/{id}/keys:
+ /domains/{domain}/apps/{id}/keys:
get:
operationId: getApiKeysByAppId
description: Get all API keys associated with an application
@@ -535,6 +484,7 @@ paths:
- Applications
- API Keys
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -544,13 +494,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /apps/externalId/{id}:
+ /domains/{domain}/apps/externalId/{id}:
get:
operationId: getAppsByExternalId
description: Get an application by an external ID
tags:
- Applications
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -560,13 +511,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /apps/{id}/activate:
+ /domains/{domain}/apps/{id}/activate:
patch:
operationId: activateAnApp
description: Activate an application if not already active
tags:
- Applications
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -576,13 +528,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /apps/{id}/deactivate:
+ /domains/{domain}/apps/{id}/deactivate:
patch:
operationId: deactivateAnApp
description: Deactivate an application if it's active
tags:
- Applications
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -593,17 +546,19 @@ paths:
$ref: "#/components/responses/ErrorResponse"
# ----------------- clients -----------------
- /clients:
+ /domains/{domain}/clients:
post:
operationId: createClient
description: Create an AuthGuard client
tags:
- Clients
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/CreateClientRequest"
+ $ref: "#/components/schemas/CreateClientRequest"
responses:
201:
description: Success
@@ -612,13 +567,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /clients/{id}:
+ /domains/{domain}/clients/{id}:
get:
operationId: getClientById
description: Get an client by ID
tags:
- Clients
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -634,6 +590,7 @@ paths:
tags:
- Clients
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -643,7 +600,7 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /clients/{id}/keys:
+ /domains/{domain}/clients/{id}/keys:
get:
operationId: getApiKeysByClientId
description: Get all API keys associated with a client
@@ -651,6 +608,7 @@ paths:
- Clients
- API Keys
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -660,13 +618,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /clients/externalId/{id}:
+ /domains/{domain}/clients/externalId/{id}:
get:
operationId: getClientsByExternalId
description: Get an application by an external ID
tags:
- Clients
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -676,13 +635,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /clients/{id}/activate:
+ /domains/{domain}/clients/{id}/activate:
patch:
operationId: activateClient
description: Activate a client if not already active
tags:
- Clients
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -692,13 +652,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /clients/{id}/deactivate:
+ /domains/{domain}/clients/{id}/deactivate:
patch:
operationId: deactivateClient
description: Deactivate a client if it's active
tags:
- Clients
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- $ref: "#/components/parameters/IdParameter"
responses:
200:
@@ -709,17 +670,19 @@ paths:
$ref: "#/components/responses/ErrorResponse"
# ---------------- API keys ---------------
- /keys:
+ /domains/{domain}/keys:
post:
operationId: generateApiKey
description: Generate a new API key for an application
tags:
- API Keys
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/ApiKeyRequest"
+ $ref: "#/components/schemas/ApiKeyRequest"
responses:
200:
description: Success
@@ -728,12 +691,14 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /keys/verify:
+ /domains/{domain}/keys/verify:
post:
operationId: verifyKey
description: Verify an API key
tags:
- API Keys
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -747,12 +712,15 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /keys/{id}:
+ /domains/{domain}/keys/{id}:
get:
operationId: getApiKeyById
description: Get an API key by ID
tags:
- API Keys
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/IdParameter"
requestBody:
content:
application/json:
@@ -770,6 +738,9 @@ paths:
description: Delete an API key by ID
tags:
- API Keys
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/IdParameter"
requestBody:
content:
application/json:
@@ -784,17 +755,19 @@ paths:
$ref: "#/components/responses/ErrorResponse"
# ----------------- roles -----------------
- /roles:
+ /domains/{domain}/roles:
post:
operationId: createRole
description: Create a role
tags:
- Roles
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/CreateRoleRequest"
+ $ref: "#/components/schemas/CreateRoleRequest"
responses:
201:
description: Success
@@ -802,26 +775,16 @@ paths:
400:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
-
- get:
- operationId: getAllRoles
- description: Get all roles
- tags:
- - Roles
- responses:
- 201:
- description: Success
- $ref: "#/components/responses/RolesArrayResponse"
- 400:
- description: Bad request
- $ref: "#/components/responses/ErrorResponse"
- /roles/{id}:
+ /domains/{domain}/roles/{id}:
get:
operationId: getRoleById
description: Get role by ID
tags:
- Roles
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/IdParameter"
responses:
200:
description: Success
@@ -835,6 +798,9 @@ paths:
description: Delete a role
tags:
- Roles
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/IdParameter"
responses:
200:
description: Success
@@ -843,12 +809,31 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /roles/name/{name}:
+ /domains/{domain}/roles/:
+ get:
+ operationId: getAllRoles
+ description: Get all roles
+ tags:
+ - Roles
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ responses:
+ 201:
+ description: Success
+ $ref: "#/components/responses/domains/{domain}/rolesArrayResponse"
+ 400:
+ description: Bad request
+ $ref: "#/components/responses/ErrorResponse"
+
+ /domains/{domain}/roles/domain/name/{name}:
get:
operationId: getRoleByName
description: Get a role by its name
tags:
- Roles
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/NameParameter"
responses:
200:
description: Success
@@ -858,17 +843,19 @@ paths:
$ref: "#/components/responses/ErrorResponse"
# ----------------- permissions -----------------
- /permissions:
+ /domains/{domain}/permissions:
post:
operationId: createPermission
description: Create a permission
tags:
- Permissions
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
schema:
- $ref: "#/components/schemas/CreatePermissionRequest"
+ $ref: "#/components/schemas/CreatePermissionRequest"
responses:
201:
description: Success
@@ -876,27 +863,16 @@ paths:
400:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- get:
- operationId: getPermissions
- description: Get all permissions
- tags:
- - Permissions
- parameters:
- - name: group
- in: query
- schema:
- type: string
- responses:
- 200:
- description: Success
- $ref: "#/components/responses/PermissionsArrayResponse"
- /permissions/{id}:
+ /domains/{domain}/permissions/{id}:
get:
operationId: getPermissionById
description: Get a permission by ID
tags:
- Permissions
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/IdParameter"
responses:
200:
description: Success
@@ -909,6 +885,8 @@ paths:
description: Delete a permission by ID
tags:
- Permissions
+ parameters:
+ - $ref: "#/components/parameters/IdParameter"
responses:
200:
description: Success
@@ -917,25 +895,42 @@ paths:
description: Not found
$ref: "#/components/responses/ErrorResponse"
- /permissions/group/{group}:
+ /domains/{domain}/permissions/:
+ get:
+ operationId: getAllPermissions
+ description: Get all permissions
+ tags:
+ - Permissions
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ responses:
+ 200:
+ description: Success
+ $ref: "#/components/responses/domains/{domain}/permissionsArrayResponse"
+
+ /domains/{domain}/permissions/group/{group}:
get:
operationId: getPermissionsByGroupName
description: Get a permissions by group name
tags:
- Permissions
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
+ - $ref: "#/components/parameters/GroupParameter"
responses:
200:
description: Success
- $ref: "#/components/responses/PermissionsArrayResponse"
+ $ref: "#/components/responses/domains/{domain}/permissionsArrayResponse"
# ----------------- auth -----------------
- /auth/exchange:
+ /domains/{domain}/auth/exchange:
post:
operationId: exchange
description: Perform an auth exchange
tags:
- Auth
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: from
in: query
required: true
@@ -959,13 +954,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /auth/exchange/clear:
+ /domains/{domain}/auth/exchange/clear:
post:
operationId: clear
description: Clear (delete) a token
tags:
- Auth
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: tokenType
in: query
required: true
@@ -984,12 +980,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /auth/authenticate:
+ /domains/{domain}/auth/authenticate:
post:
operationId: authenticate
description: Perform an auth exchange from 'basic' to what is specified in the configuration
tags:
- Auth
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1003,12 +1001,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /auth/refresh:
+ /domains/{domain}/auth/refresh:
post:
operationId: refresh
description: Perform an auth exchange from 'refresh' to what is specified in the configuration
tags:
- Auth
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1022,12 +1022,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /auth/logout:
+ /domains/{domain}/auth/logout:
post:
operationId: logout
description: Clear (delete) a token based on whatever is specified in the configuration
tags:
- Auth
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1041,13 +1043,14 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /auth/exchange/attempts:
+ /domains/{domain}/auth/exchange/attempts:
get:
operationId: getExchangeAttempts
description: Get a list of attempts performed for an entity
tags:
- Auth
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: entityId
in: query
required: true
@@ -1070,11 +1073,13 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /passwordless/verify:
+ /domains/{domain}/passwordless/verify:
post:
operationId: Verify a passwordless token
tags:
- Auth
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1088,11 +1093,13 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /otp/verify:
+ /domains/{domain}/otp/verify:
post:
operationId: Verify a one-time password
tags:
- Auth
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1112,6 +1119,7 @@ paths:
tags:
- Verification
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: token
in: query
required: true
@@ -1124,12 +1132,13 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /actions/otp:
+ /domains/{domain}/actions/otp:
post:
operationId: Generate a one-time password for an action
tags:
- Action tokens
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: accountId
in: query
required: true
@@ -1143,11 +1152,13 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /actions/token:
+ /domains/{domain}/actions/token:
post:
- operationId: Generate an action token either from an OTP generated by /actions/otp or by a user identifier and password
+ operationId: Generate an action token either from an OTP generated by /actions/domains/{domain}/otp or by a user identifier and password
tags:
- Action tokens
+ parameters:
+ - $ref: "#/components/parameters/DomainParameter"
requestBody:
content:
application/json:
@@ -1161,12 +1172,13 @@ paths:
description: Bad request
$ref: "#/components/responses/ErrorResponse"
- /actions/verify:
+ /domains/{domain}/actions/verify:
post:
operationId: Verify that an action token is valid for the specified action
tags:
- Action tokens
parameters:
+ - $ref: "#/components/parameters/DomainParameter"
- name: token
in: query
required: true
@@ -1200,6 +1212,13 @@ components:
schema:
type: string
+ DomainParameter:
+ name: domain
+ in: path
+ required: true
+ schema:
+ type: string
+
IdentifierParameter:
name: identifier
in: path
@@ -1207,6 +1226,20 @@ components:
schema:
type: string
+ NameParameter:
+ name: name
+ in: path
+ required: true
+ schema:
+ type: string
+
+ GroupParameter:
+ name: group
+ in: path
+ required: true
+ schema:
+ type: string
+
EmailParameter:
name: email
in: path
@@ -1243,20 +1276,6 @@ components:
schema:
$ref: "#/components/schemas/Account"
- CredentialsResponse:
- description: _
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/Credentials"
-
- CompleteAccountResponse:
- description: _
- content:
- application/json:
- schema:
- $ref: "#/components/schemas/AccountWithCredentials"
-
ApplicationResponse:
description: _
content:
@@ -1361,16 +1380,6 @@ components:
$ref: "#/components/schemas/ActionToken"
schemas:
- AccountWithCredentials:
- type: object
- properties:
- account:
- type: object
- $ref: "#/components/schemas/Account"
- credentials:
- type: object
- $ref: "#/components/schemas/Credentials"
-
Account:
type: object
properties:
@@ -1412,18 +1421,6 @@ components:
description: A collection of custom information to be attached to the account
type: object
- Credentials:
- type: object
- properties:
- accountId:
- type: string
- domain:
- type: string
- identifiers:
- type: array
- items:
- $ref: "#/components/schemas/UserIdentifier"
-
UserIdentifier:
type: object
properties:
@@ -1435,8 +1432,8 @@ components:
- PHONE_NUMBER
identifier:
type: string
- domain:
- type: string
+ active:
+ type: boolean
Application:
type: object
@@ -1503,6 +1500,8 @@ components:
Permission:
type: object
properties:
+ id:
+ type: string
group:
type: string
name:
@@ -1522,6 +1521,8 @@ components:
Role:
type: object
properties:
+ id:
+ type: string
name:
type: string
domain:
@@ -1554,10 +1555,20 @@ components:
type: string
key:
type: string
+ type:
+ type: string
+ forClient:
+ type: boolean
+ createdAt:
+ type: date-time
+ expiresAt:
+ type: date-time
ExchangeAttempt:
type: object
properties:
+ createdAt:
+ type: date-time
entityId:
type: string
fromExchange:
@@ -1574,6 +1585,8 @@ components:
type: string
sourceIp:
type: string
+ userAgent:
+ type: string
AuthRequest:
type: object
@@ -1627,6 +1640,7 @@ components:
type: object
required:
- domain
+ - identifiers
properties:
externalId:
type: string
@@ -1640,6 +1654,12 @@ components:
type: string
fullName:
type: string
+ identifiers:
+ type: array
+ items:
+ $ref: "#/components/schemas/UserIdentifier"
+ plainPassword:
+ type: string
email:
type: object
$ref: "#/components/schemas/Email"
@@ -1689,9 +1709,12 @@ components:
type: object
required:
- domain
+ - name
properties:
externalId:
type: string
+ name:
+ type: string
domain:
type: string
accountId:
@@ -1731,49 +1754,31 @@ components:
- AUTH
- ADMIN
- CreateCredentialsRequest:
- type: object
- required:
- - domain
- - identifiers
- properties:
- accountId:
- type: string
- domain:
- type: string
- identifiers:
- type: array
- items:
- $ref: "#/components/schemas/UserIdentifier"
- plainPassword:
- type: string
-
UpdateCredentialsPasswordRequest:
type: object
properties:
plainPassword:
type: string
- CreateCompleteAccountRequest:
- type: object
- properties:
- account:
- type: object
- $ref: "#/components/schemas/CreateAccountRequest"
- credentials:
- type: object
- $ref: "#/components/schemas/CreateCredentialsRequest"
-
ApiKeyRequest:
type: object
required:
- appId
- keyType
+ - name
+ - forClient
properties:
appId:
type: string
keyType:
type: string
+ name:
+ type: string
+ validFor:
+ type: object
+ $ref: "#/components/schemas/DurationRequest"
+ forClient:
+ type: boolean
ApiKeyVerificationRequest:
type: object
@@ -1961,6 +1966,16 @@ components:
action:
type: string
+ DurationRequest:
+ type: object
+ properties:
+ days:
+ type: number
+ hours:
+ type: number
+ minutes:
+ type: number
+
Error:
type: object
properties:
diff --git a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/ApiKeysRequestValidatorTest.java b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/ApiKeysRequestValidatorTest.java
index 5459f088..5fa42a81 100644
--- a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/ApiKeysRequestValidatorTest.java
+++ b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/ApiKeysRequestValidatorTest.java
@@ -17,7 +17,7 @@ class ApiKeysRequestValidatorTest {
@Test
void validate() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.build();
@@ -44,7 +44,7 @@ void validateMissingValues() {
@Test
void validateWithZeroValidity() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.validFor(DurationRequestDTO.builder()
.build())
@@ -59,7 +59,7 @@ void validateWithZeroValidity() {
@Test
void validateWithNonZeroValidity() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.validFor(DurationRequestDTO.builder()
.days(1)
@@ -77,7 +77,7 @@ void validateWithNonZeroValidity() {
@Test
void validateWithNegativeDaysValidity() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.validFor(DurationRequestDTO.builder()
.days(-1)
@@ -95,7 +95,7 @@ void validateWithNegativeDaysValidity() {
@Test
void validateWithNegativeHoursValidity() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.validFor(DurationRequestDTO.builder()
.hours(-1)
@@ -113,7 +113,7 @@ void validateWithNegativeHoursValidity() {
@Test
void validateWithNegativeMinutesValidity() {
final ApiKeyRequestDTO request = ApiKeyRequestDTO.builder()
- .appId(1L)
+ .appId("1")
.keyType("default")
.validFor(DurationRequestDTO.builder()
.minutes(-1)
diff --git a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/OtpRequestValidatorTest.java b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/OtpRequestValidatorTest.java
index bf350faf..c905c085 100644
--- a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/OtpRequestValidatorTest.java
+++ b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/OtpRequestValidatorTest.java
@@ -15,7 +15,7 @@ class OtpRequestValidatorTest {
@Test
void validateValid() {
final OtpRequestDTO request = OtpRequestDTO.builder()
- .passwordId(1L)
+ .passwordId("1")
.password("password")
.build();
diff --git a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidatorTest.java b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidatorTest.java
index 10e95771..65f9b13f 100644
--- a/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidatorTest.java
+++ b/api/src/test/java/com/nexblocks/authguard/api/dto/validation/validators/PasswordResetRequestValidatorTest.java
@@ -18,6 +18,7 @@ void validateValidByToken() {
.byToken(true)
.resetToken("token")
.newPassword("newPassword")
+ .domain("main")
.build();
final Validator validator = Validators.getForClass(PasswordResetRequestDTO.class);
@@ -58,22 +59,6 @@ void validateValidByPassword() {
assertThat(violations).isEmpty();
}
- @Test
- void validateValidByPasswordWithoutDomain() {
- final PasswordResetRequestDTO request = PasswordResetRequestDTO.builder()
- .byToken(false)
- .identifier("identifier")
- .oldPassword("oldPassword")
- .newPassword("newPassword")
- .build();
-
- final Validator validator = Validators.getForClass(PasswordResetRequestDTO.class);
-
- final List violations = validator.validate(request);
-
- assertThat(violations).containsExactly(new Violation("domain", ViolationType.MISSING_REQUIRED_VALUE));
- }
-
@Test
void validateMissingIdentifierAndOldPassword() {
final PasswordResetRequestDTO request = PasswordResetRequestDTO.builder()
diff --git a/basic-auth/pom.xml b/basic-auth/pom.xml
index afeafb78..61041fe6 100644
--- a/basic-auth/pom.xml
+++ b/basic-auth/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
index c8774bab..d8f25a7c 100644
--- a/benchmarks/pom.xml
+++ b/benchmarks/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/bindings/pom.xml b/bindings/pom.xml
index 04fe8010..9d2361f5 100644
--- a/bindings/pom.xml
+++ b/bindings/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/bom/pom.xml b/bom/pom.xml
index 8fbd1e84..433694a4 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/bootstrap-steps/pom.xml b/bootstrap-steps/pom.xml
index d138d3c3..ff68a933 100644
--- a/bootstrap-steps/pom.xml
+++ b/bootstrap-steps/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml
index 27d72704..0eaaf134 100644
--- a/bootstrap/pom.xml
+++ b/bootstrap/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/config/pom.xml b/config/pom.xml
index b7b2fd87..77377671 100644
--- a/config/pom.xml
+++ b/config/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/dal/cache/pom.xml b/dal/cache/pom.xml
index 02e08020..f84f9cc7 100644
--- a/dal/cache/pom.xml
+++ b/dal/cache/pom.xml
@@ -5,7 +5,7 @@
dal
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/dal/dal-common/pom.xml b/dal/dal-common/pom.xml
index 8ca7e5ae..13abc02b 100644
--- a/dal/dal-common/pom.xml
+++ b/dal/dal-common/pom.xml
@@ -5,7 +5,7 @@
dal
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/dal/dal-common/src/main/java/com/nexblocks/authguard/dal/model/ApiKeyDO.java b/dal/dal-common/src/main/java/com/nexblocks/authguard/dal/model/ApiKeyDO.java
index c2e6169f..8e37d8de 100644
--- a/dal/dal-common/src/main/java/com/nexblocks/authguard/dal/model/ApiKeyDO.java
+++ b/dal/dal-common/src/main/java/com/nexblocks/authguard/dal/model/ApiKeyDO.java
@@ -41,6 +41,7 @@ public class ApiKeyDO extends AbstractDO {
private String key;
private long appId;
private String type;
+ private String name;
private boolean forClient;
private Instant expiresAt;
}
diff --git a/dal/persistence/pom.xml b/dal/persistence/pom.xml
index 303dcc72..b445417d 100644
--- a/dal/persistence/pom.xml
+++ b/dal/persistence/pom.xml
@@ -5,7 +5,7 @@
dal
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/dal/pom.xml b/dal/pom.xml
index 4d4180da..6a980d84 100644
--- a/dal/pom.xml
+++ b/dal/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/emb/pom.xml b/emb/pom.xml
index 1c752c4d..fcf9bb87 100644
--- a/emb/pom.xml
+++ b/emb/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/external/email/pom.xml b/external/email/pom.xml
index 7ad907a3..bdf762fc 100644
--- a/external/email/pom.xml
+++ b/external/email/pom.xml
@@ -5,7 +5,7 @@
external
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
4.0.0
diff --git a/external/pom.xml b/external/pom.xml
index 668eb97f..76f5d851 100644
--- a/external/pom.xml
+++ b/external/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/external/sms/pom.xml b/external/sms/pom.xml
index 4cd3b256..354df590 100644
--- a/external/sms/pom.xml
+++ b/external/sms/pom.xml
@@ -5,7 +5,7 @@
external
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
4.0.0
diff --git a/injection/pom.xml b/injection/pom.xml
index 9a6590b4..b957c51b 100644
--- a/injection/pom.xml
+++ b/injection/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/jwt/pom.xml b/jwt/pom.xml
index f99c4009..36a6cd9b 100644
--- a/jwt/pom.xml
+++ b/jwt/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/AccountsServiceAdapter.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/AccountsServiceAdapter.java
index 797a6bc1..ebac67f0 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/AccountsServiceAdapter.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/AccountsServiceAdapter.java
@@ -22,7 +22,7 @@ public AccountsServiceAdapter(final AccountsService accountsService) {
}
public CompletableFuture getAccount(final long accountId) {
- return accountsService.getById(accountId)
+ return accountsService.getByIdUnchecked(accountId)
.thenCompose(opt -> opt.map(CompletableFuture::completedFuture)
.orElseGet(() -> CompletableFuture.failedFuture(new ServiceAuthorizationException(ErrorCode.ACCOUNT_DOES_NOT_EXIST,
"Account does not exist"))));
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToAccessToken.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToAccessToken.java
index 33e0b6c6..cbfa278e 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToAccessToken.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToAccessToken.java
@@ -32,7 +32,7 @@ public OtpToAccessToken(final AccountsService accountsService, final OtpVerifier
@Override
public CompletableFuture exchange(final AuthRequestBO request) {
return otpVerifier.verifyAccountTokenAsync(request.getToken())
- .thenCompose(accountsService::getById)
+ .thenCompose(id -> accountsService.getById(id, request.getDomain()))
.thenCompose(opt -> {
if (opt.isEmpty()) {
return CompletableFuture.failedFuture(new ServiceAuthorizationException(ErrorCode.GENERIC_AUTH_FAILURE,
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToOidc.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToOidc.java
index 29fd988a..a8fb3a3c 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToOidc.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/OtpToOidc.java
@@ -32,7 +32,7 @@ public OtpToOidc(final AccountsService accountsService, final OtpVerifier otpVer
@Override
public CompletableFuture exchange(final AuthRequestBO request) {
return otpVerifier.verifyAccountTokenAsync(request.getToken())
- .thenCompose(accountsService::getById)
+ .thenCompose(id -> accountsService.getById(id, request.getDomain()))
.thenCompose(opt -> {
if (opt.isEmpty()) {
return CompletableFuture.failedFuture(new ServiceAuthorizationException(ErrorCode.ACCOUNT_DOES_NOT_EXIST,
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToAccessToken.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToAccessToken.java
index 2e26f4da..6407f096 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToAccessToken.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToAccessToken.java
@@ -33,7 +33,7 @@ public PasswordlessToAccessToken(final AccountsService accountsService,
@Override
public CompletableFuture exchange(final AuthRequestBO request) {
return passwordlessVerifier.verifyAccountTokenAsync(request.getToken())
- .thenCompose(accountsService::getById)
+ .thenCompose(id -> accountsService.getById(id, request.getDomain()))
.thenCompose(opt -> {
if (opt.isEmpty()) {
return CompletableFuture.failedFuture(
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToOidc.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToOidc.java
index 2caa4a32..e891e0a3 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToOidc.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/PasswordlessToOidc.java
@@ -33,7 +33,7 @@ public PasswordlessToOidc(final AccountsService accountsService,
@Override
public CompletableFuture exchange(final AuthRequestBO request) {
return passwordlessVerifier.verifyAccountTokenAsync(request.getToken())
- .thenCompose(accountsService::getById)
+ .thenCompose(id -> accountsService.getById(id, request.getDomain()))
.thenCompose(opt -> {
if (opt.isEmpty()) {
return CompletableFuture.failedFuture(
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessToken.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessToken.java
index d7891fd0..bd8280b7 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessToken.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessToken.java
@@ -120,7 +120,7 @@ private CompletableFuture generateNewTokens(final AccountTokenDO
}
private CompletableFuture getAccount(final long accountId, final AccountTokenDO accountToken) {
- return accountsService.getById(accountId)
+ return accountsService.getByIdUnchecked(accountId)
.thenCompose(opt -> {
if (opt.isEmpty()) {
return CompletableFuture.failedFuture(new ServiceAuthorizationException(ErrorCode.ACCOUNT_DOES_NOT_EXIST,
diff --git a/jwt/src/main/java/com/nexblocks/authguard/jwt/oauth/service/OAuthService.java b/jwt/src/main/java/com/nexblocks/authguard/jwt/oauth/service/OAuthService.java
index 9ae3a316..368f4947 100644
--- a/jwt/src/main/java/com/nexblocks/authguard/jwt/oauth/service/OAuthService.java
+++ b/jwt/src/main/java/com/nexblocks/authguard/jwt/oauth/service/OAuthService.java
@@ -138,7 +138,7 @@ private CompletableFuture getOrCreateAccount(final OAuthServiceClient
DecodedJWT decoded = JWT.decode(idToken);
String externalId = decoded.getSubject();
- return accountsService.getByExternalId(externalId)
+ return accountsService.getByExternalIdUnchecked(externalId)
.thenCompose(account -> {
if (account.isPresent()) {
return CompletableFuture.completedFuture(account.get());
diff --git a/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/AuthorizationCodeToOidcTest.java b/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/AuthorizationCodeToOidcTest.java
index b1618c87..31dd4dee 100644
--- a/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/AuthorizationCodeToOidcTest.java
+++ b/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/AuthorizationCodeToOidcTest.java
@@ -67,7 +67,7 @@ void exchange() {
Mockito.when(authorizationCodeVerifier.verifyAndGetAccountTokenAsync(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(accountToken));
- Mockito.when(accountsService.getById(accountToken.getAssociatedAccountId()))
+ Mockito.when(accountsService.getByIdUnchecked(accountToken.getAssociatedAccountId()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
Mockito.when(openIdConnectTokenProvider.generateToken(account, (TokenRestrictionsBO) null))
@@ -103,7 +103,7 @@ void exchangeWithRestrictions() {
Mockito.when(authorizationCodeVerifier.verifyAndGetAccountTokenAsync(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(accountToken));
- Mockito.when(accountsService.getById(accountToken.getAssociatedAccountId()))
+ Mockito.when(accountsService.getByIdUnchecked(accountToken.getAssociatedAccountId()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
Mockito.when(openIdConnectTokenProvider.generateToken(account, serviceMapper.toBO(accountToken.getTokenRestrictions())))
diff --git a/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessTokenTest.java b/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessTokenTest.java
index ccab265c..525d5772 100644
--- a/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessTokenTest.java
+++ b/jwt/src/test/java/com/nexblocks/authguard/jwt/exchange/RefreshToAccessTokenTest.java
@@ -71,7 +71,7 @@ void exchange() throws InterruptedException {
Mockito.when(accountTokensRepository.getByToken(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(accountToken)));
- Mockito.when(accountsService.getById(accountId))
+ Mockito.when(accountsService.getByIdUnchecked(accountId))
.thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
Mockito.when(accessTokenProvider.generateToken(account, null, TokenOptionsBO.builder().build()))
@@ -125,7 +125,7 @@ void exchangeWithRestrictions() throws InterruptedException {
Mockito.when(accountTokensRepository.getByToken(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(accountToken)));
- Mockito.when(accountsService.getById(accountId))
+ Mockito.when(accountsService.getByIdUnchecked(accountId))
.thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
Mockito.when(accessTokenProvider.generateToken(account, restrictions, TokenOptionsBO.builder().build()))
@@ -189,7 +189,7 @@ void exchangeNoAccount() {
Mockito.when(accountTokensRepository.getByToken(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(accountToken)));
- Mockito.when(accountsService.getById(accountId))
+ Mockito.when(accountsService.getByIdUnchecked(accountId))
.thenReturn(CompletableFuture.completedFuture(Optional.empty()));
// do
@@ -262,7 +262,7 @@ void exchangeWithTokenOptionChecks() throws InterruptedException {
Mockito.when(accountTokensRepository.getByToken(authRequest.getToken()))
.thenReturn(CompletableFuture.completedFuture(Optional.of(accountToken)));
- Mockito.when(accountsService.getById(accountId))
+ Mockito.when(accountsService.getByIdUnchecked(accountId))
.thenReturn(CompletableFuture.completedFuture(Optional.of(account)));
Mockito.when(accessTokenProvider.generateToken(account, null, tokenOptions))
diff --git a/jwt/src/test/java/com/nexblocks/authguard/jwt/oauth/service/OAuthServiceTest.java b/jwt/src/test/java/com/nexblocks/authguard/jwt/oauth/service/OAuthServiceTest.java
index 1a7477d2..52b539e3 100644
--- a/jwt/src/test/java/com/nexblocks/authguard/jwt/oauth/service/OAuthServiceTest.java
+++ b/jwt/src/test/java/com/nexblocks/authguard/jwt/oauth/service/OAuthServiceTest.java
@@ -186,7 +186,7 @@ void exchangeAuthorizationCodeAndCreateAccount() {
return CompletableFuture.completedFuture(argWithId);
});
- Mockito.when(accountsService.getByExternalId(Mockito.any()))
+ Mockito.when(accountsService.getByExternalIdUnchecked(Mockito.any()))
.thenReturn(CompletableFuture.completedFuture(Optional.empty()));
TokensResponse actual = oAuthService.exchangeAuthorizationCode("account_test", "random", "code")
@@ -210,7 +210,7 @@ void exchangeAuthorizationCodeAndGetAccount() {
return CompletableFuture.completedFuture(Optional.of(session));
});
- Mockito.when(accountsService.getByExternalId("1"))
+ Mockito.when(accountsService.getByExternalIdUnchecked("1"))
.thenReturn(CompletableFuture.completedFuture(Optional.of(AccountBO.builder().id(1).build())));
TokensResponse actual = oAuthService.exchangeAuthorizationCode("account_test", "random", "code")
diff --git a/ldap/pom.xml b/ldap/pom.xml
index 8f0930a6..0ea9d6c6 100644
--- a/ldap/pom.xml
+++ b/ldap/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/plugins/account-lock/pom.xml b/plugins/account-lock/pom.xml
index 41e4150f..8ede7144 100644
--- a/plugins/account-lock/pom.xml
+++ b/plugins/account-lock/pom.xml
@@ -5,7 +5,7 @@
plugins
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
4.0.0
diff --git a/plugins/pom.xml b/plugins/pom.xml
index fa20e29d..c76c7244 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/plugins/verification-plugin/pom.xml b/plugins/verification-plugin/pom.xml
index 3b65fad8..098281a2 100644
--- a/plugins/verification-plugin/pom.xml
+++ b/plugins/verification-plugin/pom.xml
@@ -5,7 +5,7 @@
plugins
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
4.0.0
diff --git a/pom.xml b/pom.xml
index fd707af3..5d0fe245 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
com.nexblocks.authguard
authguard
pom
- 0.21.0
+ 0.22.0
diff --git a/rest/pom.xml b/rest/pom.xml
index 45ba0cb1..5aacdae5 100644
--- a/rest/pom.xml
+++ b/rest/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/access/DomainAuthorizationHandler.java b/rest/src/main/java/com/nexblocks/authguard/rest/access/DomainAuthorizationHandler.java
new file mode 100644
index 00000000..ad76c5c3
--- /dev/null
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/access/DomainAuthorizationHandler.java
@@ -0,0 +1,40 @@
+package com.nexblocks.authguard.rest.access;
+
+import com.nexblocks.authguard.api.dto.entities.Error;
+import com.nexblocks.authguard.service.Domains;
+import com.nexblocks.authguard.service.model.AccountBO;
+import com.nexblocks.authguard.service.model.ClientBO;
+import io.javalin.http.Context;
+import io.javalin.http.Handler;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Objects;
+
+public class DomainAuthorizationHandler implements Handler {
+ @Override
+ public void handle(@NotNull Context ctx) throws Exception {
+ Object actor = ctx.attribute("actor");
+
+ if (actor == null) {
+ return;
+ }
+
+ String domain = ctx.pathParam("domain");
+
+ if (actor instanceof AccountBO) {
+ String actorDomain = ((AccountBO) actor).getDomain();
+
+ if (Objects.equals(actorDomain, domain) || Objects.equals(actorDomain, Domains.GLOBAL_RESERVED_DOMAIN)) {
+ return;
+ }
+ } else if (actor instanceof ClientBO) {
+ String actorDomain = ((ClientBO) actor).getDomain();
+
+ if (Objects.equals(actorDomain, domain) || Objects.equals(actorDomain, Domains.GLOBAL_RESERVED_DOMAIN)) {
+ return;
+ }
+ }
+
+ ctx.status(403).json(new Error("401", "Domain is outside the scope of the actor"));
+ }
+}
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/access/EntityDomainChecker.java b/rest/src/main/java/com/nexblocks/authguard/rest/access/EntityDomainChecker.java
new file mode 100644
index 00000000..efa2a67e
--- /dev/null
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/access/EntityDomainChecker.java
@@ -0,0 +1,40 @@
+package com.nexblocks.authguard.rest.access;
+
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
+import com.nexblocks.authguard.service.Domains;
+import com.nexblocks.authguard.service.exceptions.ServiceAuthorizationException;
+import com.nexblocks.authguard.service.exceptions.codes.ErrorCode;
+import io.javalin.http.Context;
+
+import java.util.Objects;
+
+public class EntityDomainChecker {
+ public static T checkActorAuthorized(final T entity, final Context actor) {
+ String actorDomain = ((DomainScoped) actor).getDomain();
+
+ boolean isAuthorized = Objects.equals(actorDomain, Domains.GLOBAL_RESERVED_DOMAIN) ||
+ Objects.equals(actorDomain, entity.getDomain());
+
+ if (isAuthorized) {
+ return entity;
+ }
+
+ throw new ServiceAuthorizationException(ErrorCode.ENTITY_OUT_OF_SCOPE,
+ "Entity is out of the scope of the actor", true);
+ }
+
+ public static void checkEntityDomainOrFail(final T entity, final Context context) {
+ String domain = context.pathParam("domain");
+
+ if (domain == null || domain.isBlank()) {
+ return;
+ }
+
+ if (Objects.equals(entity.getDomain(), domain)) {
+ return;
+ }
+
+ throw new ServiceAuthorizationException(ErrorCode.ENTITY_OUT_OF_SCOPE,
+ "Request does not match the domain", true);
+ }
+}
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/AccountsRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/AccountsRoute.java
index ba4b76d0..d8239fef 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/AccountsRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/AccountsRoute.java
@@ -12,6 +12,7 @@
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.rest.util.IdempotencyHeader;
import com.nexblocks.authguard.service.AccountLocksService;
import com.nexblocks.authguard.service.AccountsService;
@@ -99,7 +100,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture account = accountsService.getById(accountId.get())
+ CompletableFuture account = accountsService.getById(accountId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
@@ -147,7 +148,7 @@ public void deleteAccount(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture account = accountsService.delete(accountId.get())
+ CompletableFuture account = accountsService.delete(accountId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
@@ -164,7 +165,7 @@ public void patchAccount(final Context context) {
UpdateAccountRequestDTO request = updateAccountRequestBodyHandler.getValidated(context);
- CompletableFuture account = accountsService.patch(accountId.get(), restMapper.toBO(request))
+ CompletableFuture account = accountsService.patch(accountId.get(), restMapper.toBO(request), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
@@ -175,7 +176,7 @@ public void patchAccount(final Context context) {
public void getByExternalId(final Context context) {
String accountId = context.pathParam("id");
- CompletableFuture account = accountsService.getByExternalId(accountId)
+ CompletableFuture account = accountsService.getByExternalId(accountId, Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
@@ -229,9 +230,9 @@ public void updatePermissions(final Context context) {
CompletableFuture> updatedAccount;
if (request.getAction() == PermissionsRequest.Action.GRANT) {
- updatedAccount = accountsService.grantPermissions(accountId.get(), permissions);
+ updatedAccount = accountsService.grantPermissions(accountId.get(), permissions, Domain.fromContext(context));
} else {
- updatedAccount = accountsService.revokePermissions(accountId.get(), permissions);
+ updatedAccount = accountsService.revokePermissions(accountId.get(), permissions, Domain.fromContext(context));
}
context.json(updatedAccount.thenCompose(AsyncUtils::fromAccountOptional).thenApply(restMapper::toDTO));
@@ -250,9 +251,9 @@ public void updateRoles(final Context context) {
CompletableFuture> updatedAccount;
if (request.getAction() == RolesRequest.Action.GRANT) {
- updatedAccount = accountsService.grantRoles(accountId.get(), request.getRoles());
+ updatedAccount = accountsService.grantRoles(accountId.get(), request.getRoles(), Domain.fromContext(context));
} else {
- updatedAccount = accountsService.revokeRoles(accountId.get(), request.getRoles());
+ updatedAccount = accountsService.revokeRoles(accountId.get(), request.getRoles(), Domain.fromContext(context));
}
context.json(updatedAccount.thenCompose(AsyncUtils::fromAccountOptional).thenApply(restMapper::toDTO));
@@ -266,7 +267,7 @@ public void getApps(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture> apps = applicationsService.getByAccountId(accountId.get())
+ CompletableFuture> apps = applicationsService.getByAccountId(accountId.get(), Domain.fromContext(context))
.thenApply(list -> list.stream()
.map(restMapper::toDTO)
.collect(Collectors.toList()));
@@ -282,7 +283,7 @@ public void activate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture account = accountsService.activate(accountId.get())
+ CompletableFuture account = accountsService.activate(accountId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
@@ -297,7 +298,7 @@ public void deactivate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture account = accountsService.deactivate(accountId.get())
+ CompletableFuture account = accountsService.deactivate(accountId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAccountOptional)
.thenApply(restMapper::toDTO);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ActionTokensRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ActionTokensRoute.java
index a8ca38b5..35fa41c0 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ActionTokensRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ActionTokensRoute.java
@@ -6,12 +6,14 @@
import com.nexblocks.authguard.api.dto.entities.ActionTokenRequestType;
import com.nexblocks.authguard.api.dto.entities.AuthResponseDTO;
import com.nexblocks.authguard.api.dto.requests.ActionTokenRequestDTO;
+import com.nexblocks.authguard.api.dto.validation.IdParser;
import com.nexblocks.authguard.api.dto.validation.violations.Violation;
import com.nexblocks.authguard.api.dto.validation.violations.ViolationType;
import com.nexblocks.authguard.api.routes.ActionTokensApi;
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.ActionTokenService;
import com.nexblocks.authguard.service.model.ActionTokenBO;
import com.nexblocks.authguard.service.model.AuthRequestBO;
@@ -51,7 +53,7 @@ public void createOtp(final Context context) {
));
}
- CompletableFuture result = actionTokenService.generateOtp(accountId.get())
+ CompletableFuture result = actionTokenService.generateOtp(accountId.get(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.status(201).json(result);
@@ -64,8 +66,8 @@ public void createToken(final Context context) {
CompletableFuture result;
if (request.getType() == ActionTokenRequestType.OTP) {
- result = actionTokenService.generateFromOtp(request.getOtp().getPasswordId(),
- request.getOtp().getPassword(), request.getAction());
+ result = actionTokenService.generateFromOtp(IdParser.from(request.getOtp().getPasswordId()),
+ Domain.fromContext(context), request.getOtp().getPassword(), request.getAction());
} else {
AuthRequestBO authRequest = restMapper.toBO(request.getBasic());
result = actionTokenService.generateFromBasicAuth(authRequest, request.getAction());
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApiKeysRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApiKeysRoute.java
index 5cf52c73..04055b68 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApiKeysRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApiKeysRoute.java
@@ -2,18 +2,20 @@
import com.google.inject.Inject;
import com.nexblocks.authguard.api.dto.entities.ApiKeyDTO;
+import com.nexblocks.authguard.api.dto.entities.AppDTO;
import com.nexblocks.authguard.api.dto.requests.ApiKeyRequestDTO;
import com.nexblocks.authguard.api.dto.requests.ApiKeyVerificationRequestDTO;
+import com.nexblocks.authguard.api.dto.validation.IdParser;
import com.nexblocks.authguard.api.dto.validation.violations.Violation;
import com.nexblocks.authguard.api.dto.validation.violations.ViolationType;
import com.nexblocks.authguard.api.routes.ApiKeysApi;
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.ApiKeysService;
import com.nexblocks.authguard.service.exceptions.codes.ErrorCode;
import com.nexblocks.authguard.service.model.ApiKeyBO;
-import com.nexblocks.authguard.service.model.AppBO;
import com.nexblocks.authguard.service.util.AsyncUtils;
import io.javalin.core.validation.Validator;
import io.javalin.http.Context;
@@ -44,10 +46,13 @@ public ApiKeysRoute(final ApiKeysService apiKeysService, final RestMapper restMa
public void generate(final Context context) {
ApiKeyRequestDTO request = apiKeyRequestBodyHandler.getValidated(context);
Duration validFor = request.getValidFor() == null ? Duration.ZERO : request.getValidFor().toDuration();
+ String domain = Domain.fromContext(context);
CompletableFuture key = request.isForClient() ?
- apiKeysService.generateClientApiKey(request.getAppId(), request.getKeyType(), validFor) :
- apiKeysService.generateApiKey(request.getAppId(), request.getKeyType(), validFor);
+ apiKeysService.generateClientApiKey(IdParser.from(request.getAppId()), domain, request.getKeyType(),
+ request.getName(), validFor) :
+ apiKeysService.generateApiKey(IdParser.from(request.getAppId()), domain, request.getKeyType(),
+ request.getName(), validFor);
context.status(201).json(key.thenApply(restMapper::toDTO));
}
@@ -60,7 +65,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture apiKey = apiKeysService.getById(apiKeyId.get())
+ CompletableFuture apiKey = apiKeysService.getById(apiKeyId.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.API_KEY_DOES_NOT_EXIST, "API key does not exist"))
.thenApply(restMapper::toDTO);
@@ -71,7 +76,8 @@ public void getById(final Context context) {
public void verify(final Context context) {
ApiKeyVerificationRequestDTO verificationRequest = verificationRequestBodyHandler.getValidated(context);
- CompletableFuture app = apiKeysService.validateApiKey(verificationRequest.getKey(), verificationRequest.getKeyType());
+ CompletableFuture app = apiKeysService.validateApiKey(verificationRequest.getKey(), Domain.fromContext(context),
+ verificationRequest.getKeyType()).thenApply(restMapper::toDTO);
context.json(app);
}
@@ -84,7 +90,7 @@ public void deleteById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture apiKey = apiKeysService.delete(apiKeyId.get())
+ CompletableFuture apiKey = apiKeysService.delete(apiKeyId.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.API_KEY_DOES_NOT_EXIST, "API key does not exist"))
.thenApply(restMapper::toDTO);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApplicationsRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApplicationsRoute.java
index 29623ae6..23b12e7f 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApplicationsRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ApplicationsRoute.java
@@ -3,19 +3,19 @@
import com.google.inject.Inject;
import com.nexblocks.authguard.api.dto.entities.ApiKeyDTO;
import com.nexblocks.authguard.api.dto.entities.AppDTO;
-import com.nexblocks.authguard.api.dto.entities.Error;
import com.nexblocks.authguard.api.dto.requests.CreateAppRequestDTO;
import com.nexblocks.authguard.api.dto.validation.violations.Violation;
import com.nexblocks.authguard.api.dto.validation.violations.ViolationType;
import com.nexblocks.authguard.api.routes.ApplicationsApi;
+import com.nexblocks.authguard.rest.access.EntityDomainChecker;
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestJsonMapper;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.rest.util.IdempotencyHeader;
import com.nexblocks.authguard.service.ApiKeysService;
import com.nexblocks.authguard.service.ApplicationsService;
-import com.nexblocks.authguard.service.model.AppBO;
import com.nexblocks.authguard.service.model.RequestContextBO;
import com.nexblocks.authguard.service.util.AsyncUtils;
import io.javalin.core.validation.Validator;
@@ -23,7 +23,6 @@
import java.util.Collections;
import java.util.List;
-import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@@ -68,7 +67,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture application = applicationsService.getById(applicationId.get())
+ CompletableFuture application = applicationsService.getById(applicationId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAppOptional)
.thenApply(restMapper::toDTO);
@@ -82,7 +81,7 @@ public void getByExternalId(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture application = applicationsService.getByExternalId(applicationId.get())
+ CompletableFuture application = applicationsService.getByExternalId(applicationId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAppOptional)
.thenApply(restMapper::toDTO);
@@ -92,7 +91,9 @@ public void getByExternalId(final Context context) {
public void update(final Context context) {
AppDTO app = RestJsonMapper.asClass(context.body(), AppDTO.class);
- CompletableFuture application = applicationsService.update(restMapper.toBO(app))
+ EntityDomainChecker.checkEntityDomainOrFail(app, context);
+
+ CompletableFuture application = applicationsService.update(restMapper.toBO(app), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAppOptional)
.thenApply(restMapper::toDTO);
@@ -106,7 +107,7 @@ public void deleteById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture application = applicationsService.delete(applicationId.get())
+ CompletableFuture application = applicationsService.delete(applicationId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromAppOptional)
.thenApply(restMapper::toDTO);
@@ -120,7 +121,7 @@ public void activate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture application = applicationsService.activate(applicationId.get())
+ CompletableFuture application = applicationsService.activate(applicationId.get(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(application);
@@ -133,7 +134,7 @@ public void deactivate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture application = applicationsService.deactivate(applicationId.get())
+ CompletableFuture application = applicationsService.deactivate(applicationId.get(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(application);
@@ -147,7 +148,7 @@ public void getApiKeys(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture> keys = apiKeysService.getByAppId(applicationId.get())
+ CompletableFuture> keys = apiKeysService.getByAppId(applicationId.get(), Domain.fromContext(context))
.thenApply(list -> list
.stream()
.map(restMapper::toDTO)
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ClientsRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ClientsRoute.java
index b7f35cfb..036aba9e 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/ClientsRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/ClientsRoute.java
@@ -10,6 +10,7 @@
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.rest.util.IdempotencyHeader;
import com.nexblocks.authguard.service.ApiKeysService;
import com.nexblocks.authguard.service.ClientsService;
@@ -66,7 +67,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture client = clientsService.getById(clientId.get())
+ CompletableFuture client = clientsService.getById(clientId.get(), Domain.fromContext(context))
.thenApply(opt -> opt.map(restMapper::toDTO)
.orElseThrow(() -> new ServiceNotFoundException(ErrorCode.APP_DOES_NOT_EXIST, "Client does not exist")));
@@ -80,7 +81,7 @@ public void getByExternalId(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture client = clientsService.getById(clientId.get())
+ CompletableFuture client = clientsService.getById(clientId.get(), Domain.fromContext(context))
.thenApply(opt -> opt.map(restMapper::toDTO)
.orElseThrow(() -> new ServiceNotFoundException(ErrorCode.APP_DOES_NOT_EXIST, "Client does not exist")));
@@ -94,7 +95,7 @@ public void deleteById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture client = clientsService.delete(clientId.get())
+ CompletableFuture client = clientsService.delete(clientId.get(), Domain.fromContext(context))
.thenCompose(AsyncUtils::fromClientOptional)
.thenApply(restMapper::toDTO);
@@ -108,7 +109,7 @@ public void activate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture client = clientsService.activate(clientId.get())
+ CompletableFuture client = clientsService.activate(clientId.get(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(client);
@@ -121,7 +122,7 @@ public void deactivate(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture client = clientsService.deactivate(clientId.get())
+ CompletableFuture client = clientsService.deactivate(clientId.get(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(client);
@@ -135,7 +136,7 @@ public void getApiKeys(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture> keys = apiKeysService.getByAppId(clientId.get())
+ CompletableFuture> keys = apiKeysService.getByAppId(clientId.get(), Domain.fromContext(context))
.thenApply(list -> list
.stream()
.map(restMapper::toDTO)
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/CredentialsRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/CredentialsRoute.java
index 912fba95..d943c275 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/CredentialsRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/CredentialsRoute.java
@@ -16,6 +16,7 @@
import com.nexblocks.authguard.rest.mappers.RestJsonMapper;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.AccountCredentialsService;
import com.nexblocks.authguard.service.model.AccountBO;
import com.nexblocks.authguard.service.model.Client;
@@ -58,7 +59,8 @@ public void updatePassword(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture result = credentialsService.updatePassword(credentialsId.get(), credentials.getPlainPassword())
+ CompletableFuture result = credentialsService.updatePassword(credentialsId.get(),
+ credentials.getPlainPassword(), Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(result);
@@ -86,9 +88,10 @@ public void addIdentifiers(final Context context) {
CompletableFuture result;
if (request.getOldIdentifier() != null) {
- result = credentialsService.replaceIdentifier(credentialsId.get(), request.getOldIdentifier(), identifiers.get(0));
+ result = credentialsService.replaceIdentifier(credentialsId.get(), request.getOldIdentifier(),
+ identifiers.get(0), Domain.fromContext(context));
} else {
- result = credentialsService.addIdentifiers(credentialsId.get(), identifiers);
+ result = credentialsService.addIdentifiers(credentialsId.get(), identifiers, Domain.fromContext(context));
}
context.json(result.thenApply(restMapper::toDTO));
@@ -106,7 +109,8 @@ public void removeIdentifiers(final Context context) {
.map(UserIdentifierDTO::getIdentifier)
.collect(Collectors.toList());
- CompletableFuture result = credentialsService.removeIdentifiers(credentialsId.get(), identifiers)
+ CompletableFuture result = credentialsService.removeIdentifiers(credentialsId.get(), identifiers,
+ Domain.fromContext(context))
.thenApply(restMapper::toDTO);
context.json(result);
@@ -142,7 +146,8 @@ public void resetPassword(final Context context) {
CompletableFuture result;
if (request.isByToken()) {
- result = credentialsService.resetPasswordByToken(request.getResetToken(), request.getNewPassword());
+ result = credentialsService.resetPasswordByToken(request.getResetToken(), request.getNewPassword(),
+ Domain.fromContext(context));
} else {
result = credentialsService.replacePassword(request.getIdentifier(), request.getOldPassword(),
request.getNewPassword(), request.getDomain());
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/OtpRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/OtpRoute.java
index 77dbc2d9..ef89f3db 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/OtpRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/OtpRoute.java
@@ -4,6 +4,7 @@
import com.nexblocks.authguard.api.annotations.DependsOnConfiguration;
import com.nexblocks.authguard.api.dto.entities.AuthResponseDTO;
import com.nexblocks.authguard.api.dto.requests.OtpRequestDTO;
+import com.nexblocks.authguard.api.dto.validation.IdParser;
import com.nexblocks.authguard.api.routes.OtpApi;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
@@ -32,7 +33,7 @@ public void verify(final Context context) {
OtpRequestDTO body = otpRequestBodyHandler.getValidated(context);
RequestContextBO requestContext = RequestContextExtractor.extractWithoutIdempotentKey(context);
- CompletableFuture tokens = otpService.authenticate(body.getPasswordId(), body.getPassword(), requestContext)
+ CompletableFuture tokens = otpService.authenticate(IdParser.from(body.getPasswordId()), body.getPassword(), requestContext)
.thenApply(restMapper::toDTO);
context.json(tokens);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/PermissionsRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/PermissionsRoute.java
index 980f189e..8ae946ef 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/PermissionsRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/PermissionsRoute.java
@@ -9,6 +9,7 @@
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.PermissionsService;
import com.nexblocks.authguard.service.exceptions.codes.ErrorCode;
import com.nexblocks.authguard.service.util.AsyncUtils;
@@ -51,7 +52,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture permission = permissionsService.getById(id.get())
+ CompletableFuture permission = permissionsService.getById(id.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.PERMISSION_DOES_NOT_EXIST, "Permission does not exist"))
.thenApply(restMapper::toDTO);
@@ -66,7 +67,7 @@ public void deleteById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture permission = permissionsService.delete(id.get())
+ CompletableFuture permission = permissionsService.delete(id.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.PERMISSION_DOES_NOT_EXIST, "Permission does not exist"))
.thenApply(restMapper::toDTO);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/RolesRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/RolesRoute.java
index 95a9c584..ea1a5780 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/RolesRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/RolesRoute.java
@@ -9,6 +9,7 @@
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestMapper;
import com.nexblocks.authguard.rest.util.BodyHandler;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.RolesService;
import com.nexblocks.authguard.service.exceptions.codes.ErrorCode;
import com.nexblocks.authguard.service.util.AsyncUtils;
@@ -52,7 +53,7 @@ public void getById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture role = rolesService.getById(id.get())
+ CompletableFuture role = rolesService.getById(id.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.ROLE_DOES_NOT_EXIST, "Role does not exist"))
.thenApply(restMapper::toDTO);
@@ -67,7 +68,7 @@ public void deleteById(final Context context) {
throw new RequestValidationException(Collections.singletonList(new Violation("id", ViolationType.INVALID_VALUE)));
}
- CompletableFuture role = rolesService.delete(id.get())
+ CompletableFuture role = rolesService.delete(id.get(), Domain.fromContext(context))
.thenCompose(opt -> AsyncUtils.fromOptional(opt, ErrorCode.ROLE_DOES_NOT_EXIST, "Role does not exist"))
.thenApply(restMapper::toDTO);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/routes/VerificationRoute.java b/rest/src/main/java/com/nexblocks/authguard/rest/routes/VerificationRoute.java
index bf2d6024..5cb459e6 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/routes/VerificationRoute.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/routes/VerificationRoute.java
@@ -5,6 +5,7 @@
import com.nexblocks.authguard.api.dto.validation.violations.Violation;
import com.nexblocks.authguard.api.dto.validation.violations.ViolationType;
import com.nexblocks.authguard.api.routes.VerificationApi;
+import com.nexblocks.authguard.rest.util.Domain;
import com.nexblocks.authguard.service.VerificationService;
import com.google.inject.Inject;
import io.javalin.http.Context;
@@ -29,7 +30,7 @@ public void verifyEmail(final Context context) {
)));
}
- verificationService.verifyEmail(token);
+ verificationService.verifyEmail(token, Domain.fromContext(context));
context.status(200);
}
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/server/ServerMiddlewareHandlers.java b/rest/src/main/java/com/nexblocks/authguard/rest/server/ServerMiddlewareHandlers.java
index 62fcdf0d..aad81024 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/server/ServerMiddlewareHandlers.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/server/ServerMiddlewareHandlers.java
@@ -2,6 +2,7 @@
import com.nexblocks.authguard.rest.access.AuthorizationHandler;
import com.google.inject.Injector;
+import com.nexblocks.authguard.rest.access.DomainAuthorizationHandler;
import io.javalin.Javalin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,6 +21,8 @@ public void configure(final Javalin app) {
app.before(context -> context.attribute("time", System.currentTimeMillis()));
app.before(injector.getInstance(AuthorizationHandler.class));
+ app.before("/domain/:domain", new DomainAuthorizationHandler());
+
app.after(context -> {
final Long now = System.currentTimeMillis();
final Long start = context.attribute("time");
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/util/BodyHandler.java b/rest/src/main/java/com/nexblocks/authguard/rest/util/BodyHandler.java
index 756ff3dc..f3155acd 100644
--- a/rest/src/main/java/com/nexblocks/authguard/rest/util/BodyHandler.java
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/util/BodyHandler.java
@@ -1,8 +1,10 @@
package com.nexblocks.authguard.rest.util;
+import com.nexblocks.authguard.api.dto.entities.DomainScoped;
import com.nexblocks.authguard.api.dto.validation.Validator;
import com.nexblocks.authguard.api.dto.validation.validators.Validators;
import com.nexblocks.authguard.api.dto.validation.violations.Violation;
+import com.nexblocks.authguard.rest.access.EntityDomainChecker;
import com.nexblocks.authguard.rest.exceptions.RequestValidationException;
import com.nexblocks.authguard.rest.mappers.RestJsonMapper;
import io.javalin.http.Context;
@@ -23,8 +25,13 @@ public T get(final Context context) {
}
public T getValidated(final Context context) {
- final T body = RestJsonMapper.asClass(context.body(), bodyClass);
- final List violations = validator.validate(body);
+ T body = RestJsonMapper.asClass(context.body(), bodyClass);
+
+ if (DomainScoped.class.isAssignableFrom(body.getClass())) {
+ EntityDomainChecker.checkEntityDomainOrFail((DomainScoped) body, context);
+ }
+
+ List violations = validator.validate(body);
if (!violations.isEmpty()) {
throw new RequestValidationException(violations);
@@ -46,7 +53,7 @@ public Builder bodyClass(final Class bodyClass) {
}
public BodyHandler build() {
- final Validator validator = Validators.getForClass(bodyClass);
+ Validator validator = Validators.getForClass(bodyClass);
if (validator == null) {
throw new IllegalStateException("No validator was found for class " + bodyClass);
diff --git a/rest/src/main/java/com/nexblocks/authguard/rest/util/Domain.java b/rest/src/main/java/com/nexblocks/authguard/rest/util/Domain.java
new file mode 100644
index 00000000..6be5c7d7
--- /dev/null
+++ b/rest/src/main/java/com/nexblocks/authguard/rest/util/Domain.java
@@ -0,0 +1,9 @@
+package com.nexblocks.authguard.rest.util;
+
+import io.javalin.http.Context;
+
+public class Domain {
+ public static String fromContext(final Context context) {
+ return context.pathParam("domain");
+ }
+}
diff --git a/rest/src/test/java/com/nexblocks/authguard/rest/AccountsApiTest.java b/rest/src/test/java/com/nexblocks/authguard/rest/AccountsApiTest.java
index 9382fc5d..6c5d9045 100644
--- a/rest/src/test/java/com/nexblocks/authguard/rest/AccountsApiTest.java
+++ b/rest/src/test/java/com/nexblocks/authguard/rest/AccountsApiTest.java
@@ -30,7 +30,7 @@
class AccountsApiTest extends AbstractRouteTest {
private static final Logger LOG = LoggerFactory.getLogger(AccountsApiTest.class);
- private static final String ENDPOINT = "accounts";
+ private static final String ENDPOINT = "domains/main/accounts";
AccountsApiTest() {
super(ENDPOINT);
@@ -50,7 +50,7 @@ void reset() {
@Test
void create() {
- final CreateAccountRequestDTO requestDTO = CreateAccountRequestDTO.builder()
+ CreateAccountRequestDTO requestDTO = CreateAccountRequestDTO.builder()
.externalId("external")
.email(AccountEmailDTO.builder()
.email("email@server.com")
@@ -65,19 +65,19 @@ void create() {
))
.plainPassword("password")
.build();
- final RequestContextBO requestContext = RequestContextBO.builder()
+ RequestContextBO requestContext = RequestContextBO.builder()
.idempotentKey(UUID.randomUUID().toString())
.build();
- final AccountBO accountBO = mapper().toBO(requestDTO);
- final AccountBO serviceResponse = accountBO.withId(UUID.randomUUID().getMostSignificantBits());
+ AccountBO accountBO = mapper().toBO(requestDTO);
+ AccountBO serviceResponse = accountBO.withId(UUID.randomUUID().getMostSignificantBits());
Mockito.when(accountsService.create(Mockito.eq(accountBO), Mockito.any()))
.thenReturn(CompletableFuture.completedFuture(serviceResponse));
LOG.info("Request {}", requestDTO);
- final ValidatableResponse httpResponse = given().body(requestDTO)
+ ValidatableResponse httpResponse = given().body(requestDTO)
.contentType(ContentType.JSON)
.header(IdempotencyHeader.HEADER_NAME, requestContext.getIdempotentKey())
.post(url())
@@ -85,7 +85,7 @@ void create() {
.statusCode(201)
.contentType(ContentType.JSON);
- final AccountDTO response = httpResponse
+ AccountDTO response = httpResponse
.extract()
.response()
.getBody()
@@ -94,6 +94,6 @@ void create() {
assertThat(response).isEqualToIgnoringGivenFields(requestDTO,
"id", "deleted", "createdAt", "lastModified", "passwordUpdatedAt",
"social", "identityProvider", "passwordVersion");
- assertThat(response.getId()).isEqualTo(serviceResponse.getId());
+ assertThat(response.getId()).isEqualTo(String.valueOf(serviceResponse.getId()));
}
}
\ No newline at end of file
diff --git a/rest/src/test/java/com/nexblocks/authguard/rest/AuthRouteTest.java b/rest/src/test/java/com/nexblocks/authguard/rest/AuthRouteTest.java
index 8d5638a2..f6317a1d 100644
--- a/rest/src/test/java/com/nexblocks/authguard/rest/AuthRouteTest.java
+++ b/rest/src/test/java/com/nexblocks/authguard/rest/AuthRouteTest.java
@@ -26,7 +26,7 @@
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class AuthRouteTest extends AbstractRouteTest {
- private static String ENDPOINT = "auth";
+ private static String ENDPOINT = "domains/main/auth";
AuthRouteTest() {
super(ENDPOINT);
diff --git a/rest/src/test/java/com/nexblocks/authguard/rest/mappers/RestMapperTest.java b/rest/src/test/java/com/nexblocks/authguard/rest/mappers/RestMapperTest.java
index 8e7ab655..ec1a9b48 100644
--- a/rest/src/test/java/com/nexblocks/authguard/rest/mappers/RestMapperTest.java
+++ b/rest/src/test/java/com/nexblocks/authguard/rest/mappers/RestMapperTest.java
@@ -6,8 +6,8 @@
import com.nexblocks.authguard.service.model.*;
import org.jeasy.random.EasyRandom;
import org.jeasy.random.EasyRandomParameters;
-import org.jeasy.random.api.Randomizer;
import org.jeasy.random.randomizers.misc.BooleanRandomizer;
+import org.jeasy.random.randomizers.number.NumberRandomizer;
import org.jeasy.random.randomizers.text.StringRandomizer;
import org.junit.jupiter.api.Test;
@@ -16,25 +16,37 @@
import static org.assertj.core.api.Assertions.assertThat;
class RestMapperTest {
- private final EasyRandom easyRandom = new EasyRandom(new EasyRandomParameters()
+ private final EasyRandom boRandomizer = new EasyRandom(new EasyRandomParameters()
.collectionSizeRange(1, 3)
- .randomize(UserIdentifierBO.class, new Randomizer() {
- @Override
- public UserIdentifierBO getRandomValue() {
- return UserIdentifierBO.builder()
- .identifier(new StringRandomizer().getRandomValue())
- .active(new BooleanRandomizer().getRandomValue())
- .build();
- }
- })
+ .randomize(UserIdentifierBO.class, () -> UserIdentifierBO.builder()
+ .identifier(new StringRandomizer().getRandomValue())
+ .active(new BooleanRandomizer().getRandomValue())
+ .build())
);
+
+ private final EasyRandom dtoRandomizer = new EasyRandom(new EasyRandomParameters()
+ .collectionSizeRange(1, 3)
+ .randomize(field -> field.getName().equals("id") || field.getName().endsWith("Id"), () -> String.valueOf(new NumberRandomizer().getRandomValue()))
+ );
+
private final RestMapper restMapper = new RestMapperImpl();
- private void convertAndBack(final Class fromClass, final Function map,
+ private void boToDtoAndBack(final Class fromClass, final Function map,
final Function inverse, final String... ignoreFields) {
- final T original = easyRandom.nextObject(fromClass);
- final R converted = map.apply(original);
- final T back = inverse.apply(converted);
+ T original = boRandomizer.nextObject(fromClass);
+ R converted = map.apply(original);
+ T back = inverse.apply(converted);
+
+ assertThat(back).usingRecursiveComparison()
+ .ignoringFieldsMatchingRegexes(ignoreFields)
+ .isEqualTo(original);
+ }
+
+ private void dtoToBoAndBack(final Class fromClass, final Function map,
+ final Function inverse, final String... ignoreFields) {
+ T original = dtoRandomizer.nextObject(fromClass);
+ R converted = map.apply(original);
+ T back = inverse.apply(converted);
assertThat(back).usingRecursiveComparison()
.ignoringFieldsMatchingRegexes(ignoreFields)
@@ -43,99 +55,99 @@ private void convertAndBack(final Class fromClass, final Function
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/AccountCredentialsService.java b/service-api/src/main/java/com/nexblocks/authguard/service/AccountCredentialsService.java
index 7a8b7bdc..532611b0 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/AccountCredentialsService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/AccountCredentialsService.java
@@ -8,12 +8,12 @@
import java.util.concurrent.CompletableFuture;
public interface AccountCredentialsService {
- CompletableFuture updatePassword(long id, String plainPassword);
- CompletableFuture addIdentifiers(long id, List identifiers);
- CompletableFuture removeIdentifiers(long id, List identifiers);
- CompletableFuture replaceIdentifier(long id, String oldIdentifier, UserIdentifierBO newIdentifier);
+ CompletableFuture updatePassword(long id, String plainPassword, String domain);
+ CompletableFuture addIdentifiers(long id, List identifiers, String domain);
+ CompletableFuture removeIdentifiers(long id, List identifiers, String domain);
+ CompletableFuture replaceIdentifier(long id, String oldIdentifier, UserIdentifierBO newIdentifier, String domain);
CompletableFuture generateResetToken(String identifier, boolean returnToken, String domain);
- CompletableFuture resetPasswordByToken(String token, String plainPassword);
+ CompletableFuture resetPasswordByToken(String token, String plainPassword, String domain);
CompletableFuture replacePassword(String identifier, String oldPassword, String newPassword, String domain);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/AccountsService.java b/service-api/src/main/java/com/nexblocks/authguard/service/AccountsService.java
index 4d514201..6937a563 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/AccountsService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/AccountsService.java
@@ -12,20 +12,24 @@
* AccountDO service interface.
*/
public interface AccountsService extends IdempotentCrudService {
- CompletableFuture getByIdUnsafe(long id);
+ CompletableFuture getByIdUnsafe(long id, String domain);
- CompletableFuture> getByExternalId(String externalId);
+ CompletableFuture> getByIdUnchecked(long id);
+
+ CompletableFuture> getByExternalId(String externalId, String domain);
+
+ CompletableFuture> getByExternalIdUnchecked(String externalId);
CompletableFuture> getByEmail(String email, String domain);
CompletableFuture> getByIdentifier(String identifier, String domain);
CompletableFuture> getByIdentifierUnsafe(String identifier, String domain);
- CompletableFuture> activate(long accountId);
+ CompletableFuture> activate(long accountId, String domain);
- CompletableFuture> deactivate(long accountId);
+ CompletableFuture> deactivate(long accountId, String domain);
- CompletableFuture> patch(long accountId, AccountBO account);
+ CompletableFuture> patch(long accountId, AccountBO account, String domain);
/**
* Grant permissions to an account. This should only updatePatch
@@ -33,7 +37,7 @@ public interface AccountsService extends IdempotentCrudService {
*
* @throws ServiceNotFoundException if no account was found.
*/
- CompletableFuture> grantPermissions(long accountId, List permissions);
+ CompletableFuture> grantPermissions(long accountId, List permissions, String domain);
/**
* Revoke permissions of an account. This should only updatePatch
@@ -41,7 +45,7 @@ public interface AccountsService extends IdempotentCrudService {
*
* @throws ServiceNotFoundException if no account was found.
*/
- CompletableFuture> revokePermissions(long accountId, List permissions);
+ CompletableFuture> revokePermissions(long accountId, List permissions, String domain);
/**
* Grant roles to an account. This should only updatePatch the roles
@@ -49,7 +53,7 @@ public interface AccountsService extends IdempotentCrudService {
*
* @throws ServiceNotFoundException if no account was found.
*/
- CompletableFuture> grantRoles(long accountId, List roles);
+ CompletableFuture> grantRoles(long accountId, List roles, String domain);
/**
* Revoke roles of an account. This should only updatePatch the roles
@@ -57,7 +61,7 @@ public interface AccountsService extends IdempotentCrudService {
*
* @throws ServiceNotFoundException if no account was found.
*/
- CompletableFuture> revokeRoles(long accountId, List roles);
+ CompletableFuture> revokeRoles(long accountId, List roles, String domain);
/**
* Finds a list of all admins. This is useful only when deciding
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/ActionTokenService.java b/service-api/src/main/java/com/nexblocks/authguard/service/ActionTokenService.java
index 3bb3c48b..ddf6dbf0 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/ActionTokenService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/ActionTokenService.java
@@ -7,8 +7,8 @@
import java.util.concurrent.CompletableFuture;
public interface ActionTokenService {
- CompletableFuture generateOtp(long accountId);
+ CompletableFuture generateOtp(long accountId, String domain);
CompletableFuture generateFromBasicAuth(AuthRequestBO authRequest, String action);
- CompletableFuture generateFromOtp(long passwordId, String otp, String action);
+ CompletableFuture generateFromOtp(long passwordId, String domain, String otp, String action);
CompletableFuture verifyToken(String token, String action);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/ApiKeysService.java b/service-api/src/main/java/com/nexblocks/authguard/service/ApiKeysService.java
index 6ef5e84b..9fb43ae3 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/ApiKeysService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/ApiKeysService.java
@@ -9,15 +9,15 @@
import java.util.concurrent.CompletableFuture;
public interface ApiKeysService extends CrudService {
- CompletableFuture generateApiKey(long appId, String type, Duration duration);
- CompletableFuture generateClientApiKey(long clientId, String type, Duration duration);
+ CompletableFuture generateApiKey(long appId, String domain, String type, String name, Duration duration);
+ CompletableFuture generateClientApiKey(long clientId, String domain, String type, String name, Duration duration);
- CompletableFuture generateApiKey(AppBO app, String type, Duration duration);
- CompletableFuture generateClientApiKey(ClientBO client, String type, Duration duration);
+ CompletableFuture generateApiKey(AppBO app, String type, String name, Duration duration);
+ CompletableFuture generateClientApiKey(ClientBO client, String type, String name, Duration duration);
- CompletableFuture> getByAppId(long appId);
+ CompletableFuture> getByAppId(long appId, String domain);
- CompletableFuture validateApiKey(String key, String type);
+ CompletableFuture validateApiKey(String key, String domain, String type);
CompletableFuture validateClientApiKey(String key, String type);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/ApplicationsService.java b/service-api/src/main/java/com/nexblocks/authguard/service/ApplicationsService.java
index 13511cde..599016e9 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/ApplicationsService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/ApplicationsService.java
@@ -7,8 +7,8 @@
import java.util.concurrent.CompletableFuture;
public interface ApplicationsService extends IdempotentCrudService {
- CompletableFuture> getByExternalId(long externalId);
- CompletableFuture activate(long id);
- CompletableFuture deactivate(long id);
- CompletableFuture> getByAccountId(long accountId);
+ CompletableFuture> getByExternalId(long externalId, String domain);
+ CompletableFuture activate(long id, String domain);
+ CompletableFuture deactivate(long id, String domain);
+ CompletableFuture> getByAccountId(long accountId, String domain);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/ClientsService.java b/service-api/src/main/java/com/nexblocks/authguard/service/ClientsService.java
index f8b9bc2e..6527aa9c 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/ClientsService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/ClientsService.java
@@ -7,8 +7,9 @@
import java.util.concurrent.CompletableFuture;
public interface ClientsService extends IdempotentCrudService {
- CompletableFuture> getByExternalId(String externalId);
- CompletableFuture activate(long id);
- CompletableFuture deactivate(long id);
- CompletableFuture> getByAccountId(long accountId);
+ CompletableFuture> getByIdUnchecked(long id);
+ CompletableFuture> getByExternalId(String externalId, String domain);
+ CompletableFuture activate(long id, String domain);
+ CompletableFuture deactivate(long id, String domain);
+ CompletableFuture> getByAccountId(long accountId, String domain);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/CrudService.java b/service-api/src/main/java/com/nexblocks/authguard/service/CrudService.java
index c4d51c5c..45fe288a 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/CrudService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/CrudService.java
@@ -8,9 +8,9 @@
public interface CrudService {
CompletableFuture create(T entity);
- CompletableFuture> getById(long id);
+ CompletableFuture> getById(long id, String domain);
- CompletableFuture> update(T entity);
+ CompletableFuture> update(T entity, String domain);
- CompletableFuture> delete(long id);
+ CompletableFuture> delete(long id, String domain);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/Domains.java b/service-api/src/main/java/com/nexblocks/authguard/service/Domains.java
new file mode 100644
index 00000000..ff9ec833
--- /dev/null
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/Domains.java
@@ -0,0 +1,5 @@
+package com.nexblocks.authguard.service;
+
+public class Domains {
+ public static String GLOBAL_RESERVED_DOMAIN = "global";
+}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/VerificationService.java b/service-api/src/main/java/com/nexblocks/authguard/service/VerificationService.java
index 467c27f9..bd9a18cd 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/VerificationService.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/VerificationService.java
@@ -3,8 +3,8 @@
import com.nexblocks.authguard.service.model.AuthResponseBO;
public interface VerificationService {
- void verifyEmail(String verificationToken);
- AuthResponseBO sendPhoneNumberVerification(long accountId);
+ void verifyEmail(String verificationToken, String domain);
+ AuthResponseBO sendPhoneNumberVerification(long accountId, String domain);
AuthResponseBO sendPhoneNumberVerificationByIdentifier(String identifier, String domain);
- void verifyPhoneNumber(long passwordId, String otp, String phoneNumber);
+ void verifyPhoneNumber(long passwordId, String domain, String otp, String phoneNumber);
}
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/ServiceAuthorizationException.java b/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/ServiceAuthorizationException.java
index 83a58f3b..20443a37 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/ServiceAuthorizationException.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/ServiceAuthorizationException.java
@@ -6,11 +6,20 @@
public class ServiceAuthorizationException extends ServiceException {
private final EntityType entityType;
private final Long entityId;
+ private final boolean isForbidden;
public ServiceAuthorizationException(final ErrorCode errorCode, final String message) {
super(errorCode, message);
this.entityType = null;
this.entityId = null;
+ this.isForbidden = false;
+ }
+
+ public ServiceAuthorizationException(final ErrorCode errorCode, final String message, final boolean isForbidden) {
+ super(errorCode, message);
+ this.entityType = null;
+ this.entityId = null;
+ this.isForbidden = isForbidden;
}
public ServiceAuthorizationException(final ErrorCode errorCode, final String message,
@@ -18,6 +27,7 @@ public ServiceAuthorizationException(final ErrorCode errorCode, final String mes
super(errorCode, message);
this.entityType = entityType;
this.entityId = entityId;
+ this.isForbidden = false;
}
public EntityType getEntityType() {
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/codes/ErrorCode.java b/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/codes/ErrorCode.java
index 7f214f16..e46d8083 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/codes/ErrorCode.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/exceptions/codes/ErrorCode.java
@@ -49,7 +49,9 @@ public enum ErrorCode {
LDAP_ERROR("LD.031"),
MISSING_REQUEST_QUERY("RQ.011"),
- INVALID_REQUEST_QUERY("RQ.012");
+ INVALID_REQUEST_QUERY("RQ.012"),
+ INVALID_REQUEST_VALUE("RQ.013"),
+ ENTITY_OUT_OF_SCOPE("RQ.0.014");
private final String code;
diff --git a/service-api/src/main/java/com/nexblocks/authguard/service/model/ApiKey.java b/service-api/src/main/java/com/nexblocks/authguard/service/model/ApiKey.java
index 5ac8c62d..2ecd35e0 100644
--- a/service-api/src/main/java/com/nexblocks/authguard/service/model/ApiKey.java
+++ b/service-api/src/main/java/com/nexblocks/authguard/service/model/ApiKey.java
@@ -10,6 +10,7 @@ public interface ApiKey extends Entity {
long getAppId();
String getKey();
String getType();
+ String getName();
boolean isForClient();
Instant getExpiresAt();
diff --git a/service/pom.xml b/service/pom.xml
index b0db1b4e..89af9a1c 100644
--- a/service/pom.xml
+++ b/service/pom.xml
@@ -5,7 +5,7 @@
authguard
com.nexblocks.authguard
- 0.21.0
+ 0.22.0
../pom.xml
4.0.0
diff --git a/service/src/main/java/com/nexblocks/authguard/service/impl/AccountCredentialsServiceImpl.java b/service/src/main/java/com/nexblocks/authguard/service/impl/AccountCredentialsServiceImpl.java
index a51c994c..4896b4aa 100644
--- a/service/src/main/java/com/nexblocks/authguard/service/impl/AccountCredentialsServiceImpl.java
+++ b/service/src/main/java/com/nexblocks/authguard/service/impl/AccountCredentialsServiceImpl.java
@@ -70,15 +70,15 @@ public AccountCredentialsServiceImpl(final AccountsService accountsService,
}
@Override
- public CompletableFuture updatePassword(final long id, final String plainPassword) {
- return accountsService.getByIdUnsafe(id)
+ public CompletableFuture updatePassword(final long id, final String plainPassword, final String domain) {
+ return accountsService.getByIdUnsafe(id, domain)
.thenCompose(existing -> {
HashedPasswordBO newPassword = credentialsManager.verifyAndHashPassword(plainPassword);
AccountBO update = existing
.withHashedPassword(newPassword)
.withPasswordUpdatedAt(Instant.now());
- return doUpdate(existing, update)
+ return doUpdate(existing, update, domain)
.thenApply(result -> {
storePasswordUpdateRecord(existing);
@@ -90,8 +90,9 @@ public CompletableFuture updatePassword(final long id, final String p
}
@Override
- public CompletableFuture addIdentifiers(final long id, final List identifiers) {
- return accountsService.getByIdUnsafe(id)
+ public CompletableFuture addIdentifiers(final long id, final List identifiers,
+ final String domain) {
+ return accountsService.getByIdUnsafe(id, domain)
.thenCompose(existing -> {
LOG.info("Add identifiers request. accountId={}, domain={}", id, existing.getDomain());
@@ -116,13 +117,13 @@ public CompletableFuture addIdentifiers(final long id, final List