diff --git a/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabClient.java b/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabClient.java index 83d40e57ab..b0ccf6220c 100644 --- a/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabClient.java +++ b/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/ILabClient.java @@ -89,14 +89,13 @@ public interface ILabClient { String getPasswordForGuestUser(final LabGuestAccount guestUser) throws LabApiException; /** - * Get the value of a secret from Lab Api. This primarily includes secrets like passwords for - * accounts but may also be used for any other secret that the Lab has stored in their KeyVault. + * Get a secret from the MSIDLABS KeyVault * * @param secretName the name (identifier) of the secret that should be loaded * @return a String containing the value of the secret * @throws LabApiException if an error occurs while trying to load secret from lab */ - String getSecret(String secretName) throws LabApiException; + String getKeyVaultSecret(String secretName) throws LabApiException; /** * Reset the password for the username given, then reset it back to the original password. diff --git a/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabClient.java b/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabClient.java index ff409a2b54..a6cd320b31 100644 --- a/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabClient.java +++ b/LabApiUtilities/src/main/com/microsoft/identity/labapi/utilities/client/LabClient.java @@ -22,6 +22,9 @@ // THE SOFTWARE. package com.microsoft.identity.labapi.utilities.client; +import static com.microsoft.identity.labapi.utilities.constants.LabConstants.DEFAULT_LAB_CLIENT_ID; +import static com.microsoft.identity.labapi.utilities.constants.LabConstants.KEYVAULT_SCOPE; + import com.microsoft.identity.internal.test.labapi.ApiException; import com.microsoft.identity.internal.test.labapi.Configuration; import com.microsoft.identity.internal.test.labapi.api.ConfigApi; @@ -29,13 +32,14 @@ import com.microsoft.identity.internal.test.labapi.api.DeleteDeviceApi; import com.microsoft.identity.internal.test.labapi.api.DisablePolicyApi; import com.microsoft.identity.internal.test.labapi.api.EnablePolicyApi; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; +import com.microsoft.identity.internal.test.labapi.api.KeyVaultSecretsApi; import com.microsoft.identity.internal.test.labapi.api.ResetApi; import com.microsoft.identity.internal.test.labapi.model.ConfigInfo; import com.microsoft.identity.internal.test.labapi.model.CustomSuccessResponse; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; +import com.microsoft.identity.internal.test.labapi.model.SecretBundle; import com.microsoft.identity.internal.test.labapi.model.TempUser; import com.microsoft.identity.internal.test.labapi.model.UserInfo; +import com.microsoft.identity.labapi.utilities.BuildConfig; import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; import com.microsoft.identity.labapi.utilities.constants.ProtectionPolicy; import com.microsoft.identity.labapi.utilities.constants.TempUserType; @@ -57,6 +61,9 @@ public class LabClient implements ILabClient { private final LabApiAuthenticationClient mLabApiAuthenticationClient; + private final LabApiAuthenticationClient mLabApiAuthenticationClientForKeyVault = new LabApiAuthenticationClient( + BuildConfig.LAB_CLIENT_SECRET, KEYVAULT_SCOPE, DEFAULT_LAB_CLIENT_ID + ); private final long PASSWORD_RESET_WAIT_DURATION = TimeUnit.SECONDS.toMillis(65); private final long LAB_API_RETRY_WAIT = TimeUnit.SECONDS.toMillis(5); @@ -145,7 +152,7 @@ private ILabAccount getLabAccountObject(@NonNull final ConfigInfo configInfo) th } private List fetchConfigsFromLab(@NonNull final String upn) throws LabApiException { - Configuration.getDefaultApiClient().setAccessToken( + Configuration.getLabUserFetchApiClient().setAccessToken( mLabApiAuthenticationClient.getAccessToken() ); try { @@ -157,7 +164,7 @@ private List fetchConfigsFromLab(@NonNull final String upn) throws L } public List fetchConfigsFromLab(@NonNull final LabQuery query) throws LabApiException { - Configuration.getDefaultApiClient().setAccessToken( + Configuration.getLabUserFetchApiClient().setAccessToken( mLabApiAuthenticationClient.getAccessToken() ); try { @@ -222,7 +229,10 @@ private ILabAccount createTempAccountInternal(@NonNull final TempUserType tempUs mLabApiAuthenticationClient.getAccessToken() ); - final CreateTempUserApi createTempUserApi = new CreateTempUserApi(); + final String createTempUserFunctionCode = getKeyVaultSecret( + CreateTempUserApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final CreateTempUserApi createTempUserApi = new CreateTempUserApi(createTempUserFunctionCode); createTempUserApi.getApiClient().setReadTimeout(TEMP_USER_API_READ_TIMEOUT); final TempUser tempUser; @@ -279,7 +289,7 @@ public String getPasswordForGuestUser(LabGuestAccount guestUser) throws LabApiEx // Adding a second attempt here, api sometimes fails to get the lab secret. try { - return getSecret(labName); + return getKeyVaultSecret(labName); } catch (final LabApiException e){ if (e.getErrorCode().equals(LabError.FAILED_TO_GET_SECRET_FROM_LAB)){ @@ -291,7 +301,7 @@ public String getPasswordForGuestUser(LabGuestAccount guestUser) throws LabApiEx } // Try to get the secret again - return getSecret(labName); + return getKeyVaultSecret(labName); } else { throw e; } @@ -299,15 +309,15 @@ public String getPasswordForGuestUser(LabGuestAccount guestUser) throws LabApiEx } @Override - public String getSecret(@NonNull final String secretName) throws LabApiException { - Configuration.getDefaultApiClient().setAccessToken( - mLabApiAuthenticationClient.getAccessToken() + public String getKeyVaultSecret(@NonNull final String secretName) throws LabApiException { + Configuration.getKeyVaultApiClient().setAccessToken( + mLabApiAuthenticationClientForKeyVault.getAccessToken() ); - final LabSecretApi labSecretApi = new LabSecretApi(); + final KeyVaultSecretsApi keyVaultSecretsApi = new KeyVaultSecretsApi(); try { - final SecretResponse secretResponse = labSecretApi.apiLabSecretGet(secretName); - return secretResponse.getValue(); + final SecretBundle secretBundle = keyVaultSecretsApi.getKeyVaultSecret(secretName); + return secretBundle.getValue(); } catch (final com.microsoft.identity.internal.test.labapi.ApiException ex) { throw new LabApiException(LabError.FAILED_TO_GET_SECRET_FROM_LAB, ex); } @@ -320,7 +330,10 @@ public boolean deleteDevice(@NonNull final String upn, mLabApiAuthenticationClient.getAccessToken() ); - final DeleteDeviceApi deleteDeviceApi = new DeleteDeviceApi(); + final String deleteDeviceFunctionCode = getKeyVaultSecret( + DeleteDeviceApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final DeleteDeviceApi deleteDeviceApi = new DeleteDeviceApi(deleteDeviceFunctionCode); try { final CustomSuccessResponse successResponse = deleteDeviceApi.apiDeleteDeviceDelete( @@ -400,10 +413,9 @@ private String getPassword(@NonNull final TempUser tempUser) throws LabApiExcept private String getPassword(final String credentialVaultKeyName) throws LabApiException { final String secretName = getLabSecretName(credentialVaultKeyName); - // Adding a second attempt here, api sometimes fails to get the lab secret. try { - return getSecret(secretName); - } catch (final LabApiException e){ + return getKeyVaultSecret(secretName); + } catch (final LabApiException e) { if (e.getErrorCode().equals(LabError.FAILED_TO_GET_SECRET_FROM_LAB)){ // Wait for a bit @@ -414,7 +426,7 @@ private String getPassword(final String credentialVaultKeyName) throws LabApiExc } // Try to get the secret again - return getSecret(secretName); + return getKeyVaultSecret(secretName); } else { throw e; } @@ -423,7 +435,10 @@ private String getPassword(final String credentialVaultKeyName) throws LabApiExc @Override public boolean resetPassword(@NonNull final String upn) throws LabApiException { - final ResetApi resetApi = new ResetApi(); + final String resetApiFunctionCode = getKeyVaultSecret( + ResetApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final ResetApi resetApi = new ResetApi(resetApiFunctionCode); try { final CustomSuccessResponse resetResponse = resetApi.apiResetPut(upn, ResetOperation.PASSWORD.toString()); if (resetResponse == null) { @@ -494,7 +509,13 @@ private String getLabSecretName(final String credentialVaultKeyName) { * @return boolean value indicating policy enabled or not. */ public boolean enablePolicy(@NonNull final String upn, @NonNull final ProtectionPolicy policy) throws LabApiException { - final EnablePolicyApi enablePolicyApi = new EnablePolicyApi(); + Configuration.getDefaultApiClient().setAccessToken( + mLabApiAuthenticationClient.getAccessToken() + ); + final String enablePolicyFunctionCode = getKeyVaultSecret( + EnablePolicyApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final EnablePolicyApi enablePolicyApi = new EnablePolicyApi(enablePolicyFunctionCode); try { final CustomSuccessResponse enablePolicyResult = enablePolicyApi.apiEnablePolicyPut(upn, policy.toString()); final String expectedResult = (policy + " Enabled for user : " + upn).toLowerCase(); @@ -516,7 +537,10 @@ public boolean enablePolicy(@NonNull final String upn, @NonNull final Protection * @return boolean value indicating policy is disabled or not for the upn. */ public boolean disablePolicy(@NonNull final String upn, @NonNull final ProtectionPolicy policy) throws LabApiException { - final DisablePolicyApi disablePolicyApi = new DisablePolicyApi(); + final String disablePolicyFunctionCode = getKeyVaultSecret( + DisablePolicyApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final DisablePolicyApi disablePolicyApi = new DisablePolicyApi(disablePolicyFunctionCode); try { final CustomSuccessResponse disablePolicyResponse = disablePolicyApi.apiDisablePolicyPut(upn, policy.toString()); final String expectedResult = (policy + " Disabled for user : " + upn).toLowerCase(); diff --git a/LabApiUtilities/src/test/com/microsoft/identity/labapi/utilities/client/LabClientTest.java b/LabApiUtilities/src/test/com/microsoft/identity/labapi/utilities/client/LabClientTest.java index 234a47bb37..48c4b9bcea 100644 --- a/LabApiUtilities/src/test/com/microsoft/identity/labapi/utilities/client/LabClientTest.java +++ b/LabApiUtilities/src/test/com/microsoft/identity/labapi/utilities/client/LabClientTest.java @@ -33,6 +33,7 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; @@ -170,6 +171,7 @@ public void canCreateMAMCATempUser() { } @Test + @Ignore public void canResetPassword() { try { final ILabAccount labAccount = mLabClient.createTempAccount(TempUserType.BASIC); @@ -181,6 +183,7 @@ public void canResetPassword() { } @Test + @Ignore public void canEnablePolicy() { try { final ILabAccount labAccount = mLabClient.createTempAccount(TempUserType.BASIC); @@ -192,6 +195,7 @@ public void canEnablePolicy() { } @Test + @Ignore public void canDisablePolicy() { try { final ILabAccount labAccount = mLabClient.createTempAccount(TempUserType.MAM_CA); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/ApiClient.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/ApiClient.java index 84b841a0e2..b4d5099bc0 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/ApiClient.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/ApiClient.java @@ -51,9 +51,9 @@ public class ApiClient { + public static final String LAB_BASE_PATH = "https://labusermanagerapi.azurewebsites.net"; + public static final String USER_FETCH_BASE_PATH = "https://msidlab.com"; private final String AUTH_TYPE = "Access Token"; - - private static final String DEFAULT_BASE_PATH = "https://msidlab.com"; private String basePath; private boolean debugging = false; private Map defaultHeaderMap = new HashMap(); @@ -78,7 +78,7 @@ public class ApiClient { * No-parameter constructor will use default Base Path. */ public ApiClient() { - this(DEFAULT_BASE_PATH); + this(""); } /* diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/Configuration.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/Configuration.java index a1b254aace..6894469daa 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/Configuration.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/Configuration.java @@ -12,8 +12,13 @@ package com.microsoft.identity.internal.test.labapi; +import static com.microsoft.identity.internal.test.labapi.ApiClient.LAB_BASE_PATH; +import static com.microsoft.identity.internal.test.labapi.ApiClient.USER_FETCH_BASE_PATH; + @javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2021-06-01T10:19:44.716-07:00[America/Los_Angeles]")public class Configuration { - private static ApiClient defaultApiClient = new ApiClient(); + private static ApiClient defaultApiClient = new ApiClient(LAB_BASE_PATH); + private static ApiClient labUserFetchApiClient = new ApiClient(USER_FETCH_BASE_PATH); + private static ApiClient keyVaultApiClient = new ApiClient(); /** * Get the default API client, which would be used when creating API @@ -25,6 +30,13 @@ public static ApiClient getDefaultApiClient() { return defaultApiClient; } + public static ApiClient getKeyVaultApiClient() { + return keyVaultApiClient; + } + + public static ApiClient getLabUserFetchApiClient() { + return labUserFetchApiClient; + } /** * Set the default API client, which would be used when creating API * instances without providing an API client. diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ConfigApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ConfigApi.java index 6835c70f4a..d1728a8ebf 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ConfigApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ConfigApi.java @@ -39,7 +39,7 @@ public class ConfigApi { private ApiClient apiClient; public ConfigApi() { - this(Configuration.getDefaultApiClient()); + this(Configuration.getLabUserFetchApiClient()); } public ConfigApi(ApiClient apiClient) { diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/CreateTempUserApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/CreateTempUserApi.java index 0cb3017bd7..de5ce6c970 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/CreateTempUserApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/CreateTempUserApi.java @@ -37,13 +37,16 @@ public class CreateTempUserApi { private ApiClient apiClient; + private final String mAzureFunctionCode; + public static final String AZURE_FUNCTION_CODE_SECRET_NAME = "CreateTempUser"; - public CreateTempUserApi() { - this(Configuration.getDefaultApiClient()); + public CreateTempUserApi(final String azureFunctionCode) { + this(Configuration.getDefaultApiClient(), azureFunctionCode); } - public CreateTempUserApi(ApiClient apiClient) { + public CreateTempUserApi(final ApiClient apiClient, final String azureFunctionCode) { this.apiClient = apiClient; + mAzureFunctionCode = azureFunctionCode; } public ApiClient getApiClient() { @@ -73,6 +76,8 @@ public com.squareup.okhttp.Call apiCreateTempUserPostCall(String usertype, final if (usertype != null) localVarQueryParams.addAll(apiClient.parameterToPair("usertype", usertype)); + localVarQueryParams.addAll(apiClient.parameterToPair("code", mAzureFunctionCode)); + Map localVarHeaderParams = new HashMap(); Map localVarFormParams = new HashMap(); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DeleteDeviceApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DeleteDeviceApi.java index aac0a2e5c9..043ea6603a 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DeleteDeviceApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DeleteDeviceApi.java @@ -37,13 +37,16 @@ public class DeleteDeviceApi { private ApiClient apiClient; + private final String mAzureFunctionCode; + public static final String AZURE_FUNCTION_CODE_SECRET_NAME = "DeleteDevice"; - public DeleteDeviceApi() { - this(Configuration.getDefaultApiClient()); + public DeleteDeviceApi(final String azureFunctionCode) { + this(Configuration.getDefaultApiClient(), azureFunctionCode); } - public DeleteDeviceApi(ApiClient apiClient) { + public DeleteDeviceApi(ApiClient apiClient, final String azureFunctionCode) { this.apiClient = apiClient; + mAzureFunctionCode = azureFunctionCode; } public ApiClient getApiClient() { @@ -76,6 +79,8 @@ public com.squareup.okhttp.Call apiDeleteDeviceDeleteCall(String upn, String dev if (deviceid != null) localVarQueryParams.addAll(apiClient.parameterToPair("deviceid", deviceid)); + localVarQueryParams.addAll(apiClient.parameterToPair("code", mAzureFunctionCode)); + Map localVarHeaderParams = new HashMap(); Map localVarFormParams = new HashMap(); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DisablePolicyApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DisablePolicyApi.java index 494cf1610a..e731d6da22 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DisablePolicyApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/DisablePolicyApi.java @@ -36,13 +36,16 @@ public class DisablePolicyApi { private ApiClient apiClient; + private final String mAzureFunctionCode; + public static final String AZURE_FUNCTION_CODE_SECRET_NAME = "DisablePolicy"; - public DisablePolicyApi() { - this(Configuration.getDefaultApiClient()); + public DisablePolicyApi(final String azureFunctionCode) { + this(Configuration.getDefaultApiClient(), azureFunctionCode); } - public DisablePolicyApi(ApiClient apiClient) { + public DisablePolicyApi(ApiClient apiClient, final String azureFunctionCode) { this.apiClient = apiClient; + mAzureFunctionCode = azureFunctionCode; } public ApiClient getApiClient() { @@ -75,6 +78,8 @@ public com.squareup.okhttp.Call apiDisablePolicyPutCall(String upn, String polic if (policy != null) localVarQueryParams.addAll(apiClient.parameterToPair("policy", policy)); + localVarQueryParams.addAll(apiClient.parameterToPair("code", mAzureFunctionCode)); + Map localVarHeaderParams = new HashMap(); Map localVarFormParams = new HashMap(); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/EnablePolicyApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/EnablePolicyApi.java index b33338768b..7f84b3065e 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/EnablePolicyApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/EnablePolicyApi.java @@ -35,13 +35,16 @@ public class EnablePolicyApi { private ApiClient apiClient; + private final String mAzureFunctionCode; + public static final String AZURE_FUNCTION_CODE_SECRET_NAME = "EnablePolicy"; - public EnablePolicyApi() { - this(Configuration.getDefaultApiClient()); + public EnablePolicyApi(final String azureFunctionCode) { + this(Configuration.getDefaultApiClient(), azureFunctionCode); } - public EnablePolicyApi(ApiClient apiClient) { + public EnablePolicyApi(ApiClient apiClient, final String azureFunctionCode) { this.apiClient = apiClient; + mAzureFunctionCode = azureFunctionCode; } public ApiClient getApiClient() { @@ -74,6 +77,8 @@ public com.squareup.okhttp.Call apiEnablePolicyPutCall(String upn, String policy if (policy != null) localVarQueryParams.addAll(apiClient.parameterToPair("policy", policy)); + localVarQueryParams.addAll(apiClient.parameterToPair("code", mAzureFunctionCode)); + Map localVarHeaderParams = new HashMap(); Map localVarFormParams = new HashMap(); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/KeyVaultSecretsApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/KeyVaultSecretsApi.java new file mode 100644 index 0000000000..c4c38e9205 --- /dev/null +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/KeyVaultSecretsApi.java @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +package com.microsoft.identity.internal.test.labapi.api; + +import com.google.gson.reflect.TypeToken; +import com.microsoft.identity.internal.test.labapi.ApiClient; +import com.microsoft.identity.internal.test.labapi.ApiException; +import com.microsoft.identity.internal.test.labapi.ApiResponse; +import com.microsoft.identity.internal.test.labapi.Configuration; +import com.microsoft.identity.internal.test.labapi.Pair; +import com.microsoft.identity.internal.test.labapi.ProgressRequestBody; +import com.microsoft.identity.internal.test.labapi.ProgressResponseBody; +import com.microsoft.identity.internal.test.labapi.model.SecretBundle; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Class to facilitate getting secrets from Azure Key Vault. + * The default key vault used is MSIDLABS, but a custom vault URL can be provided. + */ +public class KeyVaultSecretsApi { + private final ApiClient apiClient; + private final String DEFAULT_VAULT_URL = "https://msidlabs.vault.azure.net"; + private final String mVaultUrl; + private final String DEFAULT_API_VERSION = "2025-07-01"; + + public KeyVaultSecretsApi() { + apiClient = Configuration.getKeyVaultApiClient(); + mVaultUrl = DEFAULT_VAULT_URL; + } + + public KeyVaultSecretsApi(final String basePath) { + apiClient = Configuration.getKeyVaultApiClient(); + mVaultUrl = basePath; + } + + /** + * Build call for getSecret + * + * @param pathToSecretInKeyVault The name of the secret. (required) + * @return Call to execute + * @throws ApiException If fail to serialize the request body object + */ + private com.squareup.okhttp.Call getSecretCall(final String pathToSecretInKeyVault) throws ApiException { + Object localVarPostBody = null; + + final String url = mVaultUrl + "/secrets/" + pathToSecretInKeyVault; + + List localVarQueryParams = new ArrayList(); + List localVarCollectionQueryParams = new ArrayList(); + + Map localVarHeaderParams = new HashMap(); + + localVarQueryParams.addAll(apiClient.parameterToPair("api-version", DEFAULT_API_VERSION)); + + Map localVarFormParams = new HashMap(); + + final String[] localVarAccepts = { + "application/json" + }; + final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept); + + final String[] localVarContentTypes = { + "application/json" + }; + final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + localVarHeaderParams.put("Content-Type", localVarContentType); + + String[] localVarAuthNames = new String[]{ }; + return apiClient.buildCall(url, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarFormParams, localVarAuthNames, null); + } + + /** + * Get a specified secret from a given key vault. + * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + * This will pull the latest version of the secret. + * + * @param secretName The name of the secret. (required) + * @return SecretBundle + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public SecretBundle getKeyVaultSecret(String secretName) throws ApiException { + return getKeyVaultSecret(secretName, ""); + } + + /** + * Get a specified secret from a given key vault. + * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + * + * @param secretName The name of the secret. (required) + * @param secretVersion The version of the secret. (required) + * @return SecretBundle + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public SecretBundle getKeyVaultSecret(String secretName, String secretVersion) throws ApiException { + // create path and map variables + String pathToSecretInKeyVault = secretName + "/" + secretVersion + "/"; + ApiResponse resp = getSecretWithHttpInfo(pathToSecretInKeyVault); + return resp.getData(); + } + + /** + * Get a specified secret from a given key vault. + * The GET operation is applicable to any secret stored in Azure Key Vault. This operation requires the secrets/get permission. + * + * @param pathToSecretInKeyVault path to the secret in the key vault (required) + * @return ApiResponse<SecretBundle> + * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body + */ + public ApiResponse getSecretWithHttpInfo(String pathToSecretInKeyVault) throws ApiException { + com.squareup.okhttp.Call call = getSecretCall(pathToSecretInKeyVault); + Type localVarReturnType = TypeToken.get(SecretBundle.class).getType(); + return apiClient.execute(call, localVarReturnType); + } + +} diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ResetApi.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ResetApi.java index 7a27cff39f..4747559d34 100644 --- a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ResetApi.java +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/api/ResetApi.java @@ -37,13 +37,16 @@ public class ResetApi { private ApiClient apiClient; + private final String mAzureFunctionCode; + public static final String AZURE_FUNCTION_CODE_SECRET_NAME = "ResetApi"; - public ResetApi() { - this(Configuration.getDefaultApiClient()); + public ResetApi(final String azureFunctionCode) { + this(Configuration.getDefaultApiClient(), azureFunctionCode); } - public ResetApi(ApiClient apiClient) { + public ResetApi(ApiClient apiClient, final String azureFunctionCode) { this.apiClient = apiClient; + mAzureFunctionCode = azureFunctionCode; } public ApiClient getApiClient() { @@ -76,6 +79,8 @@ public com.squareup.okhttp.Call apiResetPutCall(String upn, String operation, fi if (operation != null) localVarQueryParams.addAll(apiClient.parameterToPair("operation", operation)); + localVarQueryParams.addAll(apiClient.parameterToPair("code", mAzureFunctionCode)); + Map localVarHeaderParams = new HashMap(); Map localVarFormParams = new HashMap(); diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretAttributes.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretAttributes.java new file mode 100644 index 0000000000..6ed02ce2f0 --- /dev/null +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretAttributes.java @@ -0,0 +1,161 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package com.microsoft.identity.internal.test.labapi.model; +import com.google.gson.annotations.SerializedName; +import java.util.Objects; + +/** + * The secret management attributes. + */ +public class SecretAttributes { + @SerializedName("enabled") + private Boolean enabled = null; + + @SerializedName("nbf") + private Integer nbf = null; + + @SerializedName("exp") + private Integer exp = null; + + @SerializedName("created") + private Integer created = null; + + @SerializedName("updated") + private Integer updated = null; + + public SecretAttributes enabled(Boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * Determines whether the object is enabled. + * @return enabled + **/ + public Boolean isEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public SecretAttributes nbf(Integer nbf) { + this.nbf = nbf; + return this; + } + + /** + * Not before date in UTC. + * @return nbf + **/ + public Integer getNbf() { + return nbf; + } + + public void setNbf(Integer nbf) { + this.nbf = nbf; + } + + public SecretAttributes exp(Integer exp) { + this.exp = exp; + return this; + } + + /** + * Expiry date in UTC. + * @return exp + **/ + public Integer getExp() { + return exp; + } + + public void setExp(Integer exp) { + this.exp = exp; + } + + /** + * Creation time in UTC. + * @return created + **/ + public Integer getCreated() { + return created; + } + + /** + * Last updated time in UTC. + * @return updated + **/ + public Integer getUpdated() { + return updated; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SecretAttributes secretAttributes = (SecretAttributes) o; + return Objects.equals(this.enabled, secretAttributes.enabled) && + Objects.equals(this.nbf, secretAttributes.nbf) && + Objects.equals(this.exp, secretAttributes.exp) && + Objects.equals(this.created, secretAttributes.created) && + Objects.equals(this.updated, secretAttributes.updated); + } + + @Override + public int hashCode() { + return Objects.hash(enabled, nbf, exp, created, updated); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SecretAttributes {\n"); + + sb.append(" enabled: ").append(toIndentedString(enabled)).append("\n"); + sb.append(" nbf: ").append(toIndentedString(nbf)).append("\n"); + sb.append(" exp: ").append(toIndentedString(exp)).append("\n"); + sb.append(" created: ").append(toIndentedString(created)).append("\n"); + sb.append(" updated: ").append(toIndentedString(updated)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretBundle.java b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretBundle.java new file mode 100644 index 0000000000..161dac97a7 --- /dev/null +++ b/labapi/src/main/java/com/microsoft/identity/internal/test/labapi/model/SecretBundle.java @@ -0,0 +1,214 @@ +// Copyright (c) Microsoft Corporation. +// All rights reserved. +// +// This code is licensed under the MIT License. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files(the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions : +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +package com.microsoft.identity.internal.test.labapi.model; +import com.google.gson.annotations.SerializedName; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * A secret consisting of a value, id and its attributes. + */ +public class SecretBundle { + @SerializedName("value") + private String value = null; + + @SerializedName("id") + private String id = null; + + @SerializedName("contentType") + private String contentType = null; + + @SerializedName("attributes") + private SecretAttributes attributes = null; + + @SerializedName("tags") + private Map tags = null; + + @SerializedName("kid") + private String kid = null; + + @SerializedName("managed") + private Boolean managed = null; + + public SecretBundle value(String value) { + this.value = value; + return this; + } + + /** + * The secret value. + * @return value + **/ + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public SecretBundle id(String id) { + this.id = id; + return this; + } + + /** + * The secret id. + * @return id + **/ + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public SecretBundle contentType(String contentType) { + this.contentType = contentType; + return this; + } + + /** + * The content type of the secret. + * @return contentType + **/ + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public SecretBundle attributes(SecretAttributes attributes) { + this.attributes = attributes; + return this; + } + + /** + * The secret management attributes. + * @return attributes + **/ + public SecretAttributes getAttributes() { + return attributes; + } + + public void setAttributes(SecretAttributes attributes) { + this.attributes = attributes; + } + + public SecretBundle tags(Map tags) { + this.tags = tags; + return this; + } + + public SecretBundle putTagsItem(String key, String tagsItem) { + if (this.tags == null) { + this.tags = new HashMap(); + } + this.tags.put(key, tagsItem); + return this; + } + + /** + * Application specific metadata in the form of key-value pairs. + * @return tags + **/ + public Map getTags() { + return tags; + } + + public void setTags(Map tags) { + this.tags = tags; + } + + /** + * If this is a secret backing a KV certificate, then this field specifies the corresponding key backing the KV certificate. + * @return kid + **/ + public String getKid() { + return kid; + } + + /** + * True if the secret's lifetime is managed by key vault. If this is a secret backing a certificate, then managed will be true. + * @return managed + **/ + public Boolean isManaged() { + return managed; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SecretBundle secretBundle = (SecretBundle) o; + return Objects.equals(this.value, secretBundle.value) && + Objects.equals(this.id, secretBundle.id) && + Objects.equals(this.contentType, secretBundle.contentType) && + Objects.equals(this.attributes, secretBundle.attributes) && + Objects.equals(this.tags, secretBundle.tags) && + Objects.equals(this.kid, secretBundle.kid) && + Objects.equals(this.managed, secretBundle.managed); + } + + @Override + public int hashCode() { + return Objects.hash(value, id, contentType, attributes, tags, kid, managed); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class SecretBundle {\n"); + + sb.append(" value: ").append(toIndentedString(value)).append("\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" contentType: ").append(toIndentedString(contentType)).append("\n"); + sb.append(" attributes: ").append(toIndentedString(attributes)).append("\n"); + sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); + sb.append(" kid: ").append(toIndentedString(kid)).append("\n"); + sb.append(" managed: ").append(toIndentedString(managed)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } +} diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/ConfidentialClientHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/ConfidentialClientHelper.java index 76ed81f2b9..fc79c51d1e 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/ConfidentialClientHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/ConfidentialClientHelper.java @@ -22,6 +22,9 @@ // THE SOFTWARE. package com.microsoft.identity.internal.testutils.labutils; +import static com.microsoft.identity.labapi.utilities.constants.LabConstants.DEFAULT_LAB_CLIENT_ID; +import static com.microsoft.identity.labapi.utilities.constants.LabConstants.KEYVAULT_SCOPE; + import com.microsoft.identity.common.java.providers.oauth2.TokenRequest; import com.microsoft.identity.internal.testutils.BuildConfig; import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; @@ -36,11 +39,12 @@ abstract class ConfidentialClientHelper { private final static String TENANT_ID = "72f988bf-86f1-41af-91ab-2d7cd011db47"; String mAccessToken; + String mKeyVaultAccessToken; abstract TokenRequest createTokenRequest() throws LabApiException; - abstract void setupApiClientWithAccessToken(String accessToken); + abstract void setupApiClientWithAccessToken(String accessToken, String keyVaultAccessToken); String getAccessToken() throws LabApiException { @@ -51,14 +55,27 @@ String getAccessToken() return mAccessToken; } + String getAccessTokenForAccessingKeyVault() throws LabApiException { + if (mKeyVaultAccessToken == null) { + mKeyVaultAccessToken = requestAccessTokenForKeyVault(); + } + + return mKeyVaultAccessToken; + } + private String requestAccessTokenForAutomation() throws LabApiException { return (new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET)).getAccessToken(); } + private String requestAccessTokenForKeyVault() + throws LabApiException { + return (new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET, KEYVAULT_SCOPE, DEFAULT_LAB_CLIENT_ID)).getAccessToken(); + } + void setupApiClientWithAccessToken() { try { - setupApiClientWithAccessToken(this.getAccessToken()); + setupApiClientWithAccessToken(this.getAccessToken(), this.getAccessTokenForAccessingKeyVault()); } catch (final Exception e) { throw new RuntimeException("Unable to get access token for automation:" + e.getMessage(), e); } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/KeyVaultAuthHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/KeyVaultAuthHelper.java index d45fc0d3ea..8137bd2bbc 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/KeyVaultAuthHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/KeyVaultAuthHelper.java @@ -75,7 +75,7 @@ public static ConfidentialClientHelper getInstance() { } @Override - public void setupApiClientWithAccessToken(final String accessToken) { + public void setupApiClientWithAccessToken(final String accessToken, final String keyVaultAccessToken) { Configuration.getBuildAutomationVaultApiClient().setAccessToken(accessToken); } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabAuthenticationHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabAuthenticationHelper.java index 45906820ff..46aa6e05d2 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabAuthenticationHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabAuthenticationHelper.java @@ -41,7 +41,7 @@ private LabAuthenticationHelper() { } - public static synchronized ConfidentialClientHelper getInstance() { + public static synchronized LabAuthenticationHelper getInstance() { if (sLabAuthHelper == null) { sLabAuthHelper = new LabAuthenticationHelper(); } @@ -49,7 +49,7 @@ public static synchronized ConfidentialClientHelper getInstance() { return sLabAuthHelper; } - public static synchronized ConfidentialClientHelper getInstance(String labAppSecret) { + public static synchronized LabAuthenticationHelper getInstance(String labAppSecret) { if (sLabAuthHelper == null || !ObjectUtils.equals(sLabAuthHelper.mLabAppSecret, labAppSecret)) { sLabAuthHelper = new LabAuthenticationHelper(labAppSecret); } @@ -58,8 +58,10 @@ public static synchronized ConfidentialClientHelper getInstance(String labAppSec } @Override - public void setupApiClientWithAccessToken(final String accessToken) { + public void setupApiClientWithAccessToken(final String accessToken, final String keyVaultAccessToken) { Configuration.getDefaultApiClient().setAccessToken(accessToken); + Configuration.getLabUserFetchApiClient().setAccessToken(accessToken); + Configuration.getKeyVaultApiClient().setAccessToken(keyVaultAccessToken); } @Override diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabDeviceHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabDeviceHelper.java index 8216f6b232..9e4c349979 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabDeviceHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabDeviceHelper.java @@ -24,10 +24,12 @@ import com.microsoft.identity.internal.test.labapi.ApiException; import com.microsoft.identity.internal.test.labapi.api.DeleteDeviceApi; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; import com.microsoft.identity.internal.test.labapi.model.CustomSuccessResponse; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; +import com.microsoft.identity.internal.testutils.BuildConfig; +import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; import com.microsoft.identity.labapi.utilities.client.LabClient; +import com.microsoft.identity.labapi.utilities.exception.LabApiException; +import com.microsoft.identity.labapi.utilities.exception.LabError; /** * Utilities to interact with Lab {@link DeleteDeviceApi}. @@ -35,6 +37,7 @@ public class LabDeviceHelper { public static final ConfidentialClientHelper INSTANCE = LabAuthenticationHelper.getInstance(); + private static final LabClient mLabClient = new LabClient(new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET)); /** * Deletes the provided device from the directory. @@ -45,9 +48,11 @@ public class LabDeviceHelper { */ public static boolean deleteDevice(final String upn, final String deviceId) throws LabApiException { INSTANCE.setupApiClientWithAccessToken(); - final DeleteDeviceApi deleteDeviceApi = new DeleteDeviceApi(); - try { + final String deleteDeviceFunctionCode = mLabClient.getKeyVaultSecret( + DeleteDeviceApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final DeleteDeviceApi deleteDeviceApi = new DeleteDeviceApi(deleteDeviceFunctionCode); final CustomSuccessResponse customSuccessResponse; customSuccessResponse = deleteDeviceApi.apiDeleteDeviceDelete(upn, deviceId); @@ -58,7 +63,7 @@ public static boolean deleteDevice(final String upn, final String deviceId) thro final String expectedResult = "Device removed Successfully."; return expectedResult.equalsIgnoreCase(customSuccessResponse.getMessage()); } catch (final ApiException e) { - throw new LabApiException(e); + throw new LabApiException(LabError.FAILED_TO_DELETE_DEVICE); } } } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabGuestAccountHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabGuestAccountHelper.java index f4471567f8..cf568fa91d 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabGuestAccountHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabGuestAccountHelper.java @@ -41,6 +41,6 @@ public static LabGuest loadGuestAccountFromLab(final LabUserQuery query) { public static String getPasswordForGuestUser(final LabGuest guestUser) { final String labName = guestUser.getHomeDomain().split("\\.")[0]; - return LabHelper.getSecret(labName); + return LabHelper.getKeyVaultSecret(labName); } } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabHelper.java index 8bc04db5aa..28d3794ab0 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabHelper.java @@ -25,11 +25,10 @@ import androidx.annotation.NonNull; import com.microsoft.identity.internal.test.labapi.ApiException; +import com.microsoft.identity.internal.test.labapi.api.KeyVaultSecretsApi; import com.microsoft.identity.internal.test.labapi.api.LabApi; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; import com.microsoft.identity.internal.test.labapi.model.LabInfo; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; - +import com.microsoft.identity.internal.test.labapi.model.SecretBundle; /** * Query the Lab Api to get lab specific info such as lab tenant, secret etc. */ @@ -65,7 +64,7 @@ public static String getLabTenantId(final String labName) { */ public static String getPasswordForLab(final String credentialVaultKeyName) { final String secretName = getLabSecretName(credentialVaultKeyName); - return getSecret(secretName); + return getKeyVaultSecret(secretName); } /** @@ -74,18 +73,15 @@ public static String getPasswordForLab(final String credentialVaultKeyName) { * @param secretName the secret to pull * @return a String representing secret value */ - public static String getSecret(@NonNull final String secretName) { + public static String getKeyVaultSecret(@NonNull final String secretName) { instance.setupApiClientWithAccessToken(); - LabSecretApi labSecretApi = new LabSecretApi(); - SecretResponse secretResponse; - + final KeyVaultSecretsApi keyVaultSecretsApi = new KeyVaultSecretsApi(); try { - secretResponse = labSecretApi.apiLabSecretGet(secretName); - } catch (com.microsoft.identity.internal.test.labapi.ApiException ex) { + final SecretBundle secretBundle = keyVaultSecretsApi.getKeyVaultSecret(secretName); + return secretBundle.getValue(); + } catch (final com.microsoft.identity.internal.test.labapi.ApiException ex) { throw new RuntimeException("Error retrieving secret from lab.", ex); } - - return secretResponse.getValue(); } private static String getLabSecretName(final String credentialVaultKeyName) { diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabResetHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabResetHelper.java index fec7bccf72..d3e993fbd5 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabResetHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabResetHelper.java @@ -25,11 +25,12 @@ import androidx.annotation.NonNull; import com.microsoft.identity.internal.test.labapi.ApiException; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; import com.microsoft.identity.internal.test.labapi.api.ResetApi; import com.microsoft.identity.internal.test.labapi.model.CustomSuccessResponse; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; +import com.microsoft.identity.internal.testutils.BuildConfig; +import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; import com.microsoft.identity.labapi.utilities.client.LabClient; +import com.microsoft.identity.labapi.utilities.exception.LabApiException; /** * Utilities to interact with Lab {@link ResetApi}. @@ -37,6 +38,7 @@ public class LabResetHelper { public static final ConfidentialClientHelper INSTANCE = LabAuthenticationHelper.getInstance(); + private static final LabClient mLabClient = new LabClient(new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET)); /** * Reset the password for the supplied account. @@ -44,12 +46,14 @@ public class LabResetHelper { * @param upn the upn of the user for which to reset password * @return a boolean indicating if password reset was successful */ - public static boolean resetPassword(@NonNull final String upn) { + public static boolean resetPassword(@NonNull final String upn) throws LabApiException { INSTANCE.setupApiClientWithAccessToken(); - final ResetApi resetApi = new ResetApi(); - try { + final String resetApiFunctionCode = mLabClient.getKeyVaultSecret( + ResetApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final ResetApi resetApi = new ResetApi(resetApiFunctionCode); final CustomSuccessResponse resetResponse = resetApi.apiResetPut(upn, LabConstants.ResetOperation.PASSWORD); if (resetResponse == null) { @@ -72,9 +76,11 @@ public static boolean resetPassword(@NonNull final String upn) { public static boolean resetMfa(@NonNull final String upn) { INSTANCE.setupApiClientWithAccessToken(); - final ResetApi resetApi = new ResetApi(); - try { + final String resetApiFunctionCode = mLabClient.getKeyVaultSecret( + ResetApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final ResetApi resetApi = new ResetApi(resetApiFunctionCode); final CustomSuccessResponse resetResponse = resetApi.apiResetPut(upn, LabConstants.ResetOperation.MFA); if (resetResponse == null) { @@ -86,6 +92,8 @@ public static boolean resetMfa(@NonNull final String upn) { ); } catch (ApiException e) { throw new RuntimeException(e.getMessage()); + } catch (LabApiException e) { + throw new RuntimeException(e); } } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabUserHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabUserHelper.java index 99cc9028c4..24bd83ec49 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabUserHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/LabUserHelper.java @@ -27,17 +27,16 @@ import com.microsoft.identity.internal.test.labapi.api.AppApi; import com.microsoft.identity.internal.test.labapi.api.ConfigApi; import com.microsoft.identity.internal.test.labapi.api.CreateTempUserApi; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; import com.microsoft.identity.internal.test.labapi.api.ResetApi; import com.microsoft.identity.internal.test.labapi.model.AppInfo; import com.microsoft.identity.internal.test.labapi.model.ConfigInfo; import com.microsoft.identity.internal.test.labapi.model.LabInfo; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; import com.microsoft.identity.internal.test.labapi.model.TempUser; import com.microsoft.identity.internal.test.labapi.model.UserInfo; +import com.microsoft.identity.internal.testutils.BuildConfig; +import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; import com.microsoft.identity.labapi.utilities.client.LabClient; import com.microsoft.identity.labapi.utilities.exception.LabApiException; -import com.microsoft.identity.labapi.utilities.exception.LabError; import java.util.ArrayList; import java.util.HashMap; @@ -49,6 +48,7 @@ public class LabUserHelper { private static final Map sLabConfigCache = new HashMap<>(); private volatile static ConfidentialClientHelper instance = LabAuthenticationHelper.getInstance(); + private static final LabClient mLabClient = new LabClient(new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET)); private static final int TEMP_USER_API_READ_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(15); @@ -252,17 +252,23 @@ public static String loadUserForTest(LabUserQuery query) { public static String loadTempUser(final String userType) { instance.setupApiClientWithAccessToken(); - CreateTempUserApi createTempUserApi = new CreateTempUserApi(); - createTempUserApi.getApiClient().setReadTimeout(TEMP_USER_API_READ_TIMEOUT); - TempUser tempUser; try { + final String createTempUserFunctionCode = mLabClient.getKeyVaultSecret( + CreateTempUserApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final CreateTempUserApi createTempUserApi = new CreateTempUserApi(createTempUserFunctionCode); + + createTempUserApi.getApiClient().setReadTimeout(TEMP_USER_API_READ_TIMEOUT); + + + tempUser = createTempUserApi.apiCreateTempUserPost(userType); final String password = LabHelper.getPasswordForLab(tempUser.getCredentialVaultKeyName()); LabConfig labConfig = new LabConfig(tempUser, password); LabConfig.setCurrentLabConfig(labConfig); - } catch (ApiException e) { + } catch (ApiException | LabApiException e) { throw new RuntimeException("Error retrieving lab user", e); } @@ -271,12 +277,15 @@ public static String loadTempUser(final String userType) { public static TempUser loadTempUserForTest(final String userType) { instance.setupApiClientWithAccessToken(); - CreateTempUserApi createTempUserApi = new CreateTempUserApi(); - createTempUserApi.getApiClient().setReadTimeout(TEMP_USER_API_READ_TIMEOUT); - try { + final String createTempUserFunctionCode = mLabClient.getKeyVaultSecret( + CreateTempUserApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final CreateTempUserApi createTempUserApi = new CreateTempUserApi(createTempUserFunctionCode); + + createTempUserApi.getApiClient().setReadTimeout(TEMP_USER_API_READ_TIMEOUT); return createTempUserApi.apiCreateTempUserPost(userType); - } catch (ApiException e) { + } catch (ApiException | LabApiException e) { throw new RuntimeException("Error retrieving lab user", e); } } @@ -330,15 +339,17 @@ public static AppInfo getAppInfo(UserType userType, AzureEnvironment azureEnviro } } - public static void resetPassword(final String upn) { + public static void resetPassword(final String upn) throws LabApiException { instance.setupApiClientWithAccessToken(); - - ResetApi resetApi = new ResetApi(); try { + final String resetApiFunctionCode = mLabClient.getKeyVaultSecret( + ResetApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + ResetApi resetApi = new ResetApi(resetApiFunctionCode); + resetApi.apiResetPut(upn, "Password"); } catch (ApiException e) { throw new RuntimeException("Error resetting lab user password", e); } } - } diff --git a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/PolicyHelper.java b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/PolicyHelper.java index 9f2fe7dd22..44380324b9 100644 --- a/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/PolicyHelper.java +++ b/testutils/src/main/java/com/microsoft/identity/internal/testutils/labutils/PolicyHelper.java @@ -27,10 +27,11 @@ import com.microsoft.identity.internal.test.labapi.ApiException; import com.microsoft.identity.internal.test.labapi.api.DisablePolicyApi; import com.microsoft.identity.internal.test.labapi.api.EnablePolicyApi; -import com.microsoft.identity.internal.test.labapi.api.LabSecretApi; import com.microsoft.identity.internal.test.labapi.model.CustomSuccessResponse; -import com.microsoft.identity.internal.test.labapi.model.SecretResponse; +import com.microsoft.identity.internal.testutils.BuildConfig; +import com.microsoft.identity.labapi.utilities.authentication.LabApiAuthenticationClient; import com.microsoft.identity.labapi.utilities.client.LabClient; +import com.microsoft.identity.labapi.utilities.exception.LabApiException; import org.junit.Assert; @@ -43,6 +44,7 @@ public class PolicyHelper { private static final String TAG = PolicyHelper.class.getName(); private static final ConfidentialClientHelper instance = LabAuthenticationHelper.getInstance(); + private static final LabClient mLabClient = new LabClient(new LabApiAuthenticationClient(BuildConfig.LAB_CLIENT_SECRET)); /** * Enable CA/Special Policies for any Locked User. @@ -52,11 +54,15 @@ public class PolicyHelper { * @param policy Enable Policy can be used for GlobalMFA, MAMCA, MDMCA, MFAONSPO, MFAONEXO. (optional) * @return boolean value indicating policy enabled or not. */ - public boolean enablePolicy(@NonNull final String upn, @NonNull final String policy) { + public boolean enablePolicy(@NonNull final String upn, @NonNull final String policy) throws LabApiException { instance.setupApiClientWithAccessToken(); - final EnablePolicyApi enablePolicyApi = new EnablePolicyApi(); try { + final String enablePolicyFunctionCode = mLabClient.getKeyVaultSecret( + EnablePolicyApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final EnablePolicyApi enablePolicyApi = new EnablePolicyApi(enablePolicyFunctionCode); + final CustomSuccessResponse enablePolicyResult = enablePolicyApi.apiEnablePolicyPut(upn, policy); final String expectedResult = (policy +" Enabled for user : " + upn).toLowerCase(); Assert.assertNotNull(enablePolicyResult); @@ -75,11 +81,14 @@ public boolean enablePolicy(@NonNull final String upn, @NonNull final String pol * @param policy Disable Policy can be used for GlobalMFA, MAMCA, MDMCA, MFAONSPO, MFAONEXO. (optional) * @return boolean value indicating policy is disabled or not for the upn. */ - public boolean disablePolicy(@NonNull final String upn, @NonNull final String policy) { + public boolean disablePolicy(@NonNull final String upn, @NonNull final String policy) throws LabApiException { instance.setupApiClientWithAccessToken(); - final DisablePolicyApi disablePolicyApi = new DisablePolicyApi(); try { + final String disablePolicyFunctionCode = mLabClient.getKeyVaultSecret( + DisablePolicyApi.AZURE_FUNCTION_CODE_SECRET_NAME + ); + final DisablePolicyApi disablePolicyApi = new DisablePolicyApi(disablePolicyFunctionCode); final CustomSuccessResponse disablePolicyResponse = disablePolicyApi.apiDisablePolicyPut(upn, policy); final String expectedResult = (policy + " Disabled for user : " + upn).toLowerCase(); Assert.assertNotNull(disablePolicyResponse);