diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d7a8bcc..e18558b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -## [5.0.0] - 2023-11-29 +## [6.0.0] - 2024-03-04 - Replace `TotpNotEnabledException` with `UnknownUserTotpIdException` - ActiveUsersSQLStorage interface changes @@ -26,6 +26,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - This enables smooth switching between `useDynamicAccessTokenSigningKey` settings by allowing refresh calls to change the signing key type of a session +## [5.0.0] - 2024-03-05 + +- Removes types `AppIdentifierWithStorage` and `TenantIdentifierWithStorage` +- Adds `deleteAllUserRoleAssociationsForRole` function to `UserRolesStorage` + ## [4.0.5] - 2023-12-05 - Adds `InvalidConfigException` to throws list of `canBeUsed` function diff --git a/jar/plugin-interface-4.0.5.jar b/jar/plugin-interface-5.0.0.jar similarity index 72% rename from jar/plugin-interface-4.0.5.jar rename to jar/plugin-interface-5.0.0.jar index 5d03cb99..629363a2 100644 Binary files a/jar/plugin-interface-4.0.5.jar and b/jar/plugin-interface-5.0.0.jar differ diff --git a/src/main/java/io/supertokens/pluginInterface/StorageUtils.java b/src/main/java/io/supertokens/pluginInterface/StorageUtils.java new file mode 100644 index 00000000..a5edd1ac --- /dev/null +++ b/src/main/java/io/supertokens/pluginInterface/StorageUtils.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024, VRAI Labs and/or its affiliates. All rights reserved. + * + * This software is licensed under the Apache License, Version 2.0 (the + * "License") as published by the Apache Software Foundation. + * + * You may not use this file except in compliance with the License. You may + * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package io.supertokens.pluginInterface; + +import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; +import io.supertokens.pluginInterface.authRecipe.sqlStorage.AuthRecipeSQLStorage; +import io.supertokens.pluginInterface.dashboard.sqlStorage.DashboardSQLStorage; +import io.supertokens.pluginInterface.emailpassword.sqlStorage.EmailPasswordSQLStorage; +import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; +import io.supertokens.pluginInterface.multitenancy.MultitenancyStorage; +import io.supertokens.pluginInterface.passwordless.sqlStorage.PasswordlessSQLStorage; +import io.supertokens.pluginInterface.session.SessionStorage; +import io.supertokens.pluginInterface.thirdparty.sqlStorage.ThirdPartySQLStorage; +import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage; +import io.supertokens.pluginInterface.useridmapping.UserIdMappingStorage; +import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; +import io.supertokens.pluginInterface.userroles.sqlStorage.UserRolesSQLStorage; + +public class StorageUtils { + public static AuthRecipeSQLStorage getAuthRecipeStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + + return (AuthRecipeSQLStorage) storage; + } + + public static EmailPasswordSQLStorage getEmailPasswordStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (EmailPasswordSQLStorage) storage; + } + + public static PasswordlessSQLStorage getPasswordlessStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (PasswordlessSQLStorage) storage; + } + + public static ThirdPartySQLStorage getThirdPartyStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (ThirdPartySQLStorage) storage; + } + + public static EmailVerificationSQLStorage getEmailVerificationStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (EmailVerificationSQLStorage) storage; + } + + public static SessionStorage getSessionStorage(Storage storage) { + return (SessionStorage) storage; + } + + public static UserMetadataSQLStorage getUserMetadataStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + + return (UserMetadataSQLStorage) storage; + } + + public static UserIdMappingStorage getUserIdMappingStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + + return (UserIdMappingStorage) storage; + } + + public static UserRolesSQLStorage getUserRolesStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (UserRolesSQLStorage) storage; + } + + public static DashboardSQLStorage getDashboardStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (DashboardSQLStorage) storage; + } + + public static TOTPSQLStorage getTOTPStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (TOTPSQLStorage) storage; + } + + public static ActiveUsersStorage getActiveUsersStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (ActiveUsersStorage) storage; + } + + public static MultitenancyStorage getMultitenancyStorage(Storage storage) { + if (storage.getType() != STORAGE_TYPE.SQL) { + // we only support SQL for now + throw new UnsupportedOperationException(""); + } + return (MultitenancyStorage) storage; + } +} diff --git a/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java index eacc4aa2..4da3ffed 100644 --- a/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/authRecipe/sqlStorage/AuthRecipeSQLStorage.java @@ -20,7 +20,6 @@ import io.supertokens.pluginInterface.authRecipe.AuthRecipeUserInfo; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.sqlStorage.SQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; diff --git a/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifier.java b/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifier.java index 0aa4aedf..9241ccf3 100644 --- a/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifier.java +++ b/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifier.java @@ -80,8 +80,4 @@ public int hashCode() { public TenantIdentifier getAsPublicTenantIdentifier() { return new TenantIdentifier(this.getConnectionUriDomain(), this.getAppId(), null); } - - public AppIdentifierWithStorage withStorage(Storage storage) { - return new AppIdentifierWithStorage(this.getConnectionUriDomain(), this.getAppId(), storage); - } } diff --git a/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifierWithStorage.java b/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifierWithStorage.java deleted file mode 100644 index b3c14185..00000000 --- a/src/main/java/io/supertokens/pluginInterface/multitenancy/AppIdentifierWithStorage.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.pluginInterface.multitenancy; - -import io.supertokens.pluginInterface.ActiveUsersSQLStorage; -import io.supertokens.pluginInterface.STORAGE_TYPE; -import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; -import io.supertokens.pluginInterface.dashboard.sqlStorage.DashboardSQLStorage; -import io.supertokens.pluginInterface.emailpassword.sqlStorage.EmailPasswordSQLStorage; -import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; -import io.supertokens.pluginInterface.passwordless.sqlStorage.PasswordlessSQLStorage; -import io.supertokens.pluginInterface.session.SessionStorage; -import io.supertokens.pluginInterface.thirdparty.sqlStorage.ThirdPartySQLStorage; -import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage; -import io.supertokens.pluginInterface.useridmapping.UserIdMappingStorage; -import io.supertokens.pluginInterface.usermetadata.sqlStorage.UserMetadataSQLStorage; -import io.supertokens.pluginInterface.userroles.sqlStorage.UserRolesSQLStorage; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class AppIdentifierWithStorage extends AppIdentifier { - - @Nonnull - private final Storage storage; - - private final Storage[] storages; - - public AppIdentifierWithStorage(@Nullable String connectionUriDomain, @Nullable String appId, @Nonnull - Storage storage) { - super(connectionUriDomain, appId); - this.storage = storage; - this.storages = new Storage[]{storage}; - } - - public AppIdentifierWithStorage(@Nullable String connectionUriDomain, @Nullable String appId, @Nonnull - Storage storage, @Nonnull Storage[] storages) { - super(connectionUriDomain, appId); - this.storage = storage; - this.storages = storages; - } - - @Nonnull - public Storage getStorage() { - return storage; - } - - @Nonnull - public Storage[] getStorages() { - return storages; - } - - public AuthRecipeStorage getAuthRecipeStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (AuthRecipeStorage) this.storage; - } - - public EmailPasswordSQLStorage getEmailPasswordStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (EmailPasswordSQLStorage) this.storage; - } - - public PasswordlessSQLStorage getPasswordlessStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (PasswordlessSQLStorage) this.storage; - } - - public ThirdPartySQLStorage getThirdPartyStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (ThirdPartySQLStorage) this.storage; - } - - public EmailVerificationSQLStorage getEmailVerificationStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (EmailVerificationSQLStorage) this.storage; - } - - public SessionStorage getSessionStorage() { - return (SessionStorage) this.storage; - } - - public UserMetadataSQLStorage getUserMetadataStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (UserMetadataSQLStorage) this.storage; - } - - public UserIdMappingStorage getUserIdMappingStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (UserIdMappingStorage) this.storage; - } - - public UserRolesSQLStorage getUserRolesStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (UserRolesSQLStorage) this.storage; - } - - public DashboardSQLStorage getDashboardStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (DashboardSQLStorage) this.storage; - } - - public TOTPSQLStorage getTOTPStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (TOTPSQLStorage) this.storage; - } - - public ActiveUsersSQLStorage getActiveUsersStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (ActiveUsersSQLStorage) this.storage; - } -} diff --git a/src/main/java/io/supertokens/pluginInterface/multitenancy/MultitenancyStorage.java b/src/main/java/io/supertokens/pluginInterface/multitenancy/MultitenancyStorage.java index d8363133..3fe7eccf 100644 --- a/src/main/java/io/supertokens/pluginInterface/multitenancy/MultitenancyStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/multitenancy/MultitenancyStorage.java @@ -17,16 +17,11 @@ package io.supertokens.pluginInterface.multitenancy; import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.emailpassword.exceptions.DuplicateEmailException; -import io.supertokens.pluginInterface.emailpassword.exceptions.UnknownUserIdException; import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateClientTypeException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateTenantException; import io.supertokens.pluginInterface.multitenancy.exceptions.DuplicateThirdPartyIdException; import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; -import io.supertokens.pluginInterface.passwordless.exception.DuplicatePhoneNumberException; -import io.supertokens.pluginInterface.thirdparty.exception.DuplicateThirdPartyUserException; -import io.supertokens.pluginInterface.userroles.exception.UnknownRoleException; public interface MultitenancyStorage extends Storage { diff --git a/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifier.java b/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifier.java index 9abac35a..ad782b1d 100644 --- a/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifier.java +++ b/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifier.java @@ -87,9 +87,4 @@ public int hashCode() { public AppIdentifier toAppIdentifier() { return new AppIdentifier(this.getConnectionUriDomain(), this.getAppId()); } - - public TenantIdentifierWithStorage withStorage(Storage storage) { - return new TenantIdentifierWithStorage(this.getConnectionUriDomain(), this.getAppId(), this.getTenantId(), - storage); - } } diff --git a/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifierWithStorage.java b/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifierWithStorage.java deleted file mode 100644 index a422f87b..00000000 --- a/src/main/java/io/supertokens/pluginInterface/multitenancy/TenantIdentifierWithStorage.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved. - * - * This software is licensed under the Apache License, Version 2.0 (the - * "License") as published by the Apache Software Foundation. - * - * You may not use this file except in compliance with the License. You may - * obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package io.supertokens.pluginInterface.multitenancy; - -import io.supertokens.pluginInterface.STORAGE_TYPE; -import io.supertokens.pluginInterface.Storage; -import io.supertokens.pluginInterface.authRecipe.AuthRecipeStorage; -import io.supertokens.pluginInterface.emailpassword.sqlStorage.EmailPasswordSQLStorage; -import io.supertokens.pluginInterface.emailverification.sqlStorage.EmailVerificationSQLStorage; -import io.supertokens.pluginInterface.passwordless.sqlStorage.PasswordlessSQLStorage; -import io.supertokens.pluginInterface.session.SessionStorage; -import io.supertokens.pluginInterface.thirdparty.sqlStorage.ThirdPartySQLStorage; -import io.supertokens.pluginInterface.totp.sqlStorage.TOTPSQLStorage; -import io.supertokens.pluginInterface.useridmapping.UserIdMappingStorage; -import io.supertokens.pluginInterface.userroles.sqlStorage.UserRolesSQLStorage; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class TenantIdentifierWithStorage extends TenantIdentifier { - - @Nonnull - private final Storage storage; - - public TenantIdentifierWithStorage(@Nullable String connectionUriDomain, @Nullable String appId, - @Nullable String tenantId, @Nonnull - Storage storage) { - super(connectionUriDomain, appId, tenantId); - this.storage = storage; - } - - @Nonnull - public Storage getStorage() { - return storage; - } - - public AppIdentifierWithStorage toAppIdentifierWithStorage() { - return new AppIdentifierWithStorage(this.getConnectionUriDomain(), this.getAppId(), this.getStorage()); - } - - public AuthRecipeStorage getAuthRecipeStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (AuthRecipeStorage) this.storage; - } - - public UserIdMappingStorage getUserIdMappingStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (UserIdMappingStorage) this.storage; - } - - public EmailPasswordSQLStorage getEmailPasswordStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - - return (EmailPasswordSQLStorage) this.storage; - } - - public PasswordlessSQLStorage getPasswordlessStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (PasswordlessSQLStorage) this.storage; - } - - public ThirdPartySQLStorage getThirdPartyStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (ThirdPartySQLStorage) this.storage; - } - - public EmailVerificationSQLStorage getEmailVerificationStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (EmailVerificationSQLStorage) this.storage; - } - - public SessionStorage getSessionStorage() { - return (SessionStorage) this.storage; - } - - public UserRolesSQLStorage getUserRolesStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (UserRolesSQLStorage) this.storage; - } - - public TOTPSQLStorage getTOTPStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (TOTPSQLStorage) this.storage; - } - - public MultitenancyStorage getMultitenancyStorageWithTargetStorage() { - if (this.storage.getType() != STORAGE_TYPE.SQL) { - // we only support SQL for now - throw new UnsupportedOperationException(""); - } - return (MultitenancyStorage) this.storage; - } -} diff --git a/src/main/java/io/supertokens/pluginInterface/useridmapping/sqlStorage/UserIdMappingSQLStorage.java b/src/main/java/io/supertokens/pluginInterface/useridmapping/sqlStorage/UserIdMappingSQLStorage.java index 4d8ab903..445ef9b0 100644 --- a/src/main/java/io/supertokens/pluginInterface/useridmapping/sqlStorage/UserIdMappingSQLStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/useridmapping/sqlStorage/UserIdMappingSQLStorage.java @@ -18,7 +18,6 @@ import io.supertokens.pluginInterface.exceptions.StorageQueryException; import io.supertokens.pluginInterface.multitenancy.AppIdentifier; -import io.supertokens.pluginInterface.multitenancy.AppIdentifierWithStorage; import io.supertokens.pluginInterface.sqlStorage.SQLStorage; import io.supertokens.pluginInterface.sqlStorage.TransactionConnection; import io.supertokens.pluginInterface.useridmapping.UserIdMapping; diff --git a/src/main/java/io/supertokens/pluginInterface/userroles/UserRolesStorage.java b/src/main/java/io/supertokens/pluginInterface/userroles/UserRolesStorage.java index 0f26d768..3928ed5f 100644 --- a/src/main/java/io/supertokens/pluginInterface/userroles/UserRolesStorage.java +++ b/src/main/java/io/supertokens/pluginInterface/userroles/UserRolesStorage.java @@ -22,13 +22,12 @@ import io.supertokens.pluginInterface.multitenancy.exceptions.TenantOrAppNotFoundException; import io.supertokens.pluginInterface.nonAuthRecipe.NonAuthRecipeStorage; import io.supertokens.pluginInterface.userroles.exception.DuplicateUserRoleMappingException; -import io.supertokens.pluginInterface.userroles.exception.UnknownRoleException; public interface UserRolesStorage extends NonAuthRecipeStorage { // associate a userId with a role that exists void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, String role) - throws StorageQueryException, UnknownRoleException, DuplicateUserRoleMappingException, + throws StorageQueryException, DuplicateUserRoleMappingException, TenantOrAppNotFoundException; // get all roles associated with the input userId @@ -54,4 +53,8 @@ void addRoleToUser(TenantIdentifier tenantIdentifier, String userId, String role // delete all roles for the input userId int deleteAllRolesForUser(TenantIdentifier tenantIdentifier, String userId) throws StorageQueryException; + + // delete all user association with a role (this is called before deleting the role) + boolean deleteAllUserRoleAssociationsForRole(AppIdentifier appIdentifier, + String role) throws StorageQueryException; }