From 03cabad7c0e5d9fc7e5d53602c22be1a654bd81a Mon Sep 17 00:00:00 2001 From: Arvind Krishnakumar <61501885+arvindkrishnakumar-okta@users.noreply.github.com> Date: Tue, 7 Jul 2020 13:02:41 -0700 Subject: [PATCH] OKTA-302317: Release Java Mgmt SDK v2.0.0 (#422) * upgrade to openapi v2.0.0 (#380) * openapi spec update - remove 200 response from generateCsrForApplication * Update OktaOrgCleaner.groovy * Fix flaky GroupsIT#groupUserOperationsTest test * Update GroupsIT.groovy * OKTA-279039: Fix flaky ApplicationsIT associateUserWithApplication test * Update GroupsIT.groovy * Addressed review comment * OKTA-289656: Add Applications API Integration Tests * OKTA-289655: Add Admin role API Integration Tests * Open API Csr rename update (#394) * openapi csr rename update * Merge pull request #396 * revert csr model rename (#398) * revert csr model rename * open api spec update (#401) * open api spec update * Open API spec - fix binding enum value for ProtocolEndpoint model (#406) * OKTA-289662: Add SMS Templates API Integration Tests (#395) * OKTA-289665: Add Linked Objects Integration Tests (#404) * Updated Licence Header in LinkedObjectsIT (#410) * OKTA-289668: Add User Type Integration Tests (#405) * Open API Update - Sync with #238 #239 (#411) * sync with open api pr #240 (#413) * Open API Update - Sync with #241 (#412) * Open API Update - Sync with #242 (#414) * Open API Update - Sync with Open API PR 243 (#416) * OKTA-289657: Add Factors API Integration Tests (#391) * OKTA-289659: Add Event Hooks Integration Tests (#399) * OKTA-289659: Add Authorization Server Integration Tests (#402) * OKTA-289660: Add Inline Hooks Integration Tests (#400) * Open API Update - Sync with Open API PR 244 (#418) * fixed copy paste error * OKTA-289661: Add Feature API Integration Tests (#397) * Open API Update - Sync with Open API PR 249 (#420) * OKTA-289663: Add IdP Integration Tests (#409) * resolved merge conflicts with master changes * removed Default prefix from few Idp builders * added swagger code gen check for backward compatibility requirements per review comments * fixed findbugs error * updates per swagger regen code and one other update to Idp builder * fixed expiresAt param type in spec * deprecated old classes * refactored InlineHooksIT - deactivate created hooks so it can be cleaned up after test * Remove deprecated code (#426) * Remove deprecated code * fix typo * fixed PMD violation - unused inports * Update integration-tests/src/test/groovy/com/okta/sdk/tests/it/CrudTestSupport.groovy Co-authored-by: Brian Demers * Update integration-tests/src/test/groovy/com/okta/sdk/tests/it/FactorsIT.groovy Co-authored-by: Brian Demers * Update integration-tests/src/test/groovy/com/okta/sdk/tests/it/UsersIT.groovy Co-authored-by: Brian Demers * Update integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupsIT.groovy Co-authored-by: Brian Demers * minor improvements (#427) * OKTA-308935: Create Migration Guide for Java Mgmt SDK v2.0.0 (#423) Co-authored-by: Ivan Ezeigbo <56391095+ivanezeigbo-okta@users.noreply.github.com> Co-authored-by: Brian Demers --- MIGRATING.md | 143 + api/pom.xml | 2 +- .../ClientCredentialsProvider.java | 28 - .../com/okta/sdk/client/ClientBuilder.java | 18 +- .../main/java/com/okta/sdk/client/Proxy.java | 35 - .../java/com/okta/sdk/http/HttpMethod.java | 48 - .../java/com/okta/sdk/http/HttpRequest.java | 84 - .../com/okta/sdk/http/HttpRequestBuilder.java | 90 - .../java/com/okta/sdk/http/HttpRequests.java | 58 - .../com/okta/sdk/http/UserAgentProvider.java | 34 - .../java/com/okta/sdk/http/package-info.java | 25 - .../main/java/com/okta/sdk/lang/Assert.java | 374 - .../main/java/com/okta/sdk/lang/Classes.java | 262 - .../java/com/okta/sdk/lang/Collections.java | 478 - .../main/java/com/okta/sdk/lang/Duration.java | 101 - .../okta/sdk/lang/InstantiationException.java | 29 - .../main/java/com/okta/sdk/lang/Instants.java | 267 - .../main/java/com/okta/sdk/lang/Locales.java | 204 - .../main/java/com/okta/sdk/lang/Objects.java | 951 -- .../main/java/com/okta/sdk/lang/Strings.java | 1366 --- .../okta/sdk/lang/UnknownClassException.java | 64 - .../resource/event/hook/EventHookBuilder.java | 35 + .../resource/group/rule/GroupRuleBuilder.java | 2 - .../provider/IdentityProviderBuilder.java | 44 + .../provider/IdentityProviderBuilders.java | 41 + .../provider/OIDCIdentityProviderBuilder.java | 57 + .../inline/hook/InlineHookBuilder.java | 40 + .../policy/rule/PolicyRuleBuilder.java | 2 - .../com/okta/sdk/lang/CollectionsTest.java | 258 - .../java/com/okta/sdk/lang/LocalesTest.java | 302 - .../java/com/okta/sdk/lang/ObjectsTest.java | 679 - .../java/com/okta/sdk/lang/StringsTest.java | 735 -- coverage/pom.xml | 2 +- examples/pom.xml | 2 +- examples/quickstart/pom.xml | 2 +- .../main/java/quickstart/ReadmeSnippets.java | 27 +- httpclients/httpclient/pom.xml | 2 +- httpclients/okhttp/pom.xml | 2 +- impl/pom.xml | 7 +- .../sdk/impl/cache/CacheConfiguration.java | 2 +- .../com/okta/sdk/impl/cache/DefaultCache.java | 35 +- .../impl/cache/DefaultCacheConfiguration.java | 7 +- .../DefaultCacheConfigurationBuilder.java | 2 +- .../sdk/impl/cache/DefaultCacheManager.java | 30 +- .../cache/DefaultCacheManagerBuilder.java | 2 +- .../okta/sdk/impl/client/AbstractClient.java | 45 - .../sdk/impl/client/DefaultClientBuilder.java | 7 +- .../sdk/impl/ds/DiscriminatorRegistry.java | 2 +- .../sdk/impl/http/DefaultHttpRequest.java | 147 - .../impl/http/DefaultHttpRequestBuilder.java | 90 - .../resource/DefaultGroupRuleBuilder.java | 12 +- .../DefaultPasswordPolicyRuleBuilder.java | 4 +- .../resource/DefaultPolicyRuleBuilder.java | 17 +- .../DefaultSignOnPolicyRuleBuilder.java | 6 +- .../resource/OktaResourceHrefResolver.java | 8 + .../event/hook/DefaultEventHookBuilder.java | 115 + .../DefaultIdentityProviderBuilder.java | 99 + .../FacebookIdentityProviderBuilder.java | 70 + .../GoogleIdentityProviderBuilder.java | 68 + .../LinkedInIdentityProviderBuilder.java | 68 + .../MicrosoftIdentityProviderBuilder.java | 68 + .../provider/OidcIdentityProviderBuilder.java | 229 + .../inline/hook/DefaultInlineHookBuilder.java | 118 + .../com/okta/sdk/impl/cache/CachesTest.groovy | 17 +- .../impl/cache/DefaultCacheManagerTest.groovy | 16 +- .../sdk/impl/cache/DefaultCacheTest.groovy | 22 +- .../sdk/impl/ds/DefaultCacheKeyTest.groovy | 16 + .../impl/ds/DefaultResourceFactoryTest.groovy | 8 +- .../impl/http/DefaultHttpRequestTest.groovy | 173 - .../okta/sdk/impl/lang/DurationTest.groovy | 26 +- .../DefaultGroupRuleBuilderTest.groovy | 4 +- ...efaultPasswordPolicyRuleBuilderTest.groovy | 4 +- .../DefaultPolicyRuleBuilderTest.groovy | 4 +- .../DefaultSignOnPolicyRuleBuilderTest.groovy | 5 +- .../sdk/impl/resource/log/LogsTest.groovy | 64 +- .../impl/resource/session/FeaturesTest.groovy | 66 + .../impl/resource/session/SessionsTest.groovy | 2 +- integration-tests/pom.xml | 2 +- .../okta/sdk/tests/it/ApplicationsIT.groovy | 109 +- .../sdk/tests/it/AuthorizationServerIT.groovy | 507 + .../okta/sdk/tests/it/CrudTestSupport.groovy | 2 +- .../com/okta/sdk/tests/it/EventHooksIT.groovy | 190 + .../com/okta/sdk/tests/it/FactorsIT.groovy | 194 +- .../com/okta/sdk/tests/it/FeaturesIT.groovy | 49 + .../com/okta/sdk/tests/it/GroupRolesIT.groovy | 195 + .../com/okta/sdk/tests/it/GroupRulesIT.groovy | 15 +- .../com/okta/sdk/tests/it/GroupsIT.groovy | 6 +- .../groovy/com/okta/sdk/tests/it/IdpIT.groovy | 441 + .../okta/sdk/tests/it/InlineHooksIT.groovy | 195 + .../okta/sdk/tests/it/LinkedObjectsIT.groovy | 201 + .../okta/sdk/tests/it/PolicyRulesIT.groovy | 8 +- .../okta/sdk/tests/it/SmsTemplateIT.groovy | 98 + .../com/okta/sdk/tests/it/UserRolesIT.groovy | 126 + .../com/okta/sdk/tests/it/UserTypesIT.groovy | 127 + .../com/okta/sdk/tests/it/UsersIT.groovy | 67 +- .../sdk/tests/it/util/ClientProvider.groovy | 4 +- .../sdk/tests/it/util/OktaOrgCleaner.groovy | 6 +- .../com/okta/sdk/tests/it/util/Util.groovy | 42 +- pom.xml | 24 +- src/swagger/api.yaml | 10224 +++++++++++++--- swagger-templates/pom.xml | 2 +- .../AbstractOktaJavaClientCodegen.java | 16 +- .../codegen/OktaJavaClientImplCodegen.java | 20 - .../main/resources/OktaJava/Factor.mustache | 44 - .../src/main/resources/OktaJava/User.mustache | 62 - .../resources/OktaJava/licenseInfo.mustache | 2 +- .../resources/OktaJavaImpl/Factor.mustache | 24 - .../main/resources/OktaJavaImpl/User.mustache | 29 - .../main/resources/OktaJavaImpl/api.mustache | 4 +- .../OktaJavaImpl/licenseInfo.mustache | 2 +- 110 files changed, 12375 insertions(+), 9240 deletions(-) create mode 100644 MIGRATING.md delete mode 100644 api/src/main/java/com/okta/sdk/authc/credentials/ClientCredentialsProvider.java delete mode 100644 api/src/main/java/com/okta/sdk/client/Proxy.java delete mode 100644 api/src/main/java/com/okta/sdk/http/HttpMethod.java delete mode 100644 api/src/main/java/com/okta/sdk/http/HttpRequest.java delete mode 100644 api/src/main/java/com/okta/sdk/http/HttpRequestBuilder.java delete mode 100644 api/src/main/java/com/okta/sdk/http/HttpRequests.java delete mode 100644 api/src/main/java/com/okta/sdk/http/UserAgentProvider.java delete mode 100644 api/src/main/java/com/okta/sdk/http/package-info.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Assert.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Classes.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Collections.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Duration.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/InstantiationException.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Instants.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Locales.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Objects.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/Strings.java delete mode 100644 api/src/main/java/com/okta/sdk/lang/UnknownClassException.java create mode 100644 api/src/main/java/com/okta/sdk/resource/event/hook/EventHookBuilder.java create mode 100644 api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilder.java create mode 100644 api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilders.java create mode 100644 api/src/main/java/com/okta/sdk/resource/identity/provider/OIDCIdentityProviderBuilder.java create mode 100644 api/src/main/java/com/okta/sdk/resource/inline/hook/InlineHookBuilder.java delete mode 100644 api/src/test/java/com/okta/sdk/lang/CollectionsTest.java delete mode 100644 api/src/test/java/com/okta/sdk/lang/LocalesTest.java delete mode 100644 api/src/test/java/com/okta/sdk/lang/ObjectsTest.java delete mode 100644 api/src/test/java/com/okta/sdk/lang/StringsTest.java delete mode 100644 impl/src/main/java/com/okta/sdk/impl/client/AbstractClient.java delete mode 100644 impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequest.java delete mode 100644 impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequestBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/event/hook/DefaultEventHookBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/DefaultIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/FacebookIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/GoogleIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/LinkedInIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/MicrosoftIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/OidcIdentityProviderBuilder.java create mode 100644 impl/src/main/java/com/okta/sdk/impl/resource/inline/hook/DefaultInlineHookBuilder.java delete mode 100644 impl/src/test/groovy/com/okta/sdk/impl/http/DefaultHttpRequestTest.groovy create mode 100644 impl/src/test/groovy/com/okta/sdk/impl/resource/session/FeaturesTest.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/AuthorizationServerIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/EventHooksIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/FeaturesIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRolesIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/IdpIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/InlineHooksIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/LinkedObjectsIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/SmsTemplateIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserRolesIT.groovy create mode 100644 integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserTypesIT.groovy delete mode 100644 swagger-templates/src/main/resources/OktaJava/Factor.mustache delete mode 100644 swagger-templates/src/main/resources/OktaJava/User.mustache delete mode 100644 swagger-templates/src/main/resources/OktaJavaImpl/Factor.mustache delete mode 100644 swagger-templates/src/main/resources/OktaJavaImpl/User.mustache diff --git a/MIGRATING.md b/MIGRATING.md new file mode 100644 index 00000000000..7d6cfce988c --- /dev/null +++ b/MIGRATING.md @@ -0,0 +1,143 @@ +# Okta Java Management SDK Migration Guide + +This SDK uses semantic versioning and follows Okta's [library version policy](https://developer.okta.com/code/library-versions/). In short, we do not make breaking changes unless the major version changes! + +## Migrating from 1.x.x to 2.0.0 + +Version 2.0.0 of this SDK introduces a number of breaking changes from previous versions. +In addition to many new classes/interfaces, some existing classes/interfaces are no longer backward compatible due to method renaming and signature changes. + +#### All `*Factor` classes Renamed to `*UserFactor` +This means that you will now have to start using the new `*UserFactor` objects instead. + +### Package `com.okta.sdk.client.Client` + +Below methods have been renamed for the sake of clarity. + - Renamed `createRule` to `createGroupRule` + - Renamed `getRule` to `getGroupRule` + - Renamed `listRules` to `listGroupRules` + +### Package `com.okta.sdk.resource.log.LogEventList` + +The API used to get log info has undergone a signature change (note the order swap of `until` and `since` parameters). + - `getLogs(String until, String since, String filter, String q, String sortOrder)` + Signature changed to `getLogs(Date since, Date until, String filter, String q, String sortOrder)` + +### Package `com.okta.sdk.resource.group.GroupList` + +The API used to list the groups to which a user belongs, has undergone a signature change. +There is no need for supplying the `expand` parameter anymore. + - `listGroups(String q, String filter, String expand)` + Signature changed to `listGroups(String q, String filter)` + + - With this removal of `expand` parameter, the caller has two options of achieving the previous result: + - Make a second API call to the Group API and fetch the results. + - You can call the Groups API endpoint (or any Okta management API endpoint) using a syntax like below example: + ``` + // List Groups API, see: https://developer.okta.com/docs/reference/api/groups/#list-groups + GroupsList result = client.http() + .addQueryParameter("expand", true) + .get("/api/v1/groups", GroupsList.class); + ``` +- Note that the support for `expand` parameter might go away anytime in the future. + +### Package `com.okta.sdk.resource.application.SwaThreeFieldApplicationSettingsApplication` + +Below APIs have undergone a name change. + - `getTargetUrl` Renamed to `getTargetURL` + - `setTargetUrl` Renamed to `setTargetURL` + +### Package `com.okta.sdk.resource.group.Group` + +With the introduction of enum type `com.okta.sdk.resource.group.GroupType`, the get group type operation will now make +use of this new enum type instead of the `String` type used earlier. + - `getType` Return type changed from `String` to an enum `com.okta.sdk.resource.group.GroupType` + +### Package `com.okta.sdk.resource.group.rule.GroupRule` + +The properties `allGroupsValid` & `_embedded` were not used by the backend earlier and were always set to `null`. +As part of this upgrade, we will remove it from the method signatures. + - Removed `getAllGroupsValid` and `setAllGroupsValid` (property `allGroupsValid` is being removed; + this option would be removed from future versions of Okta API) + - Removed `getEmbedded` (property `_embedded` is removed; this property is undocumented in Okta API and hence being removed) + - `delete(Boolean removeUsers)` Signature changed to `delete()` + +### Package `com.okta.sdk.resource.log.LogAuthenticationContext` + +The API to get log credential provider used to return a list of objects of type `LogCredentialProvider` earlier. +This is now fixed to return a single object of type `LogCredentialProvider`. + - `getCredentialProvider` Return type changed from `List` to `com.okta.sdk.resource.log.LogCredentialProvider` + +The API to get log credential type used to return a list of objects of type `LogCredentialType` earlier. +This is now fixed to return a single object of type `LogCredentialType`. +- `getCredentialType` Return type changed from `List` to `com.okta.sdk.resource.log.LogCredentialType` + +### Package `com.okta.sdk.resource.policy.PolicyRule` + +There is no need of exposing setter for the `read-only` property `id`. + - Removed `setId` (property `id` is `read-only`) + +### Package `com.okta.sdk.resource.user.factor.VerifyFactorRequest` + +The property `tokenLifetimeSeconds` will not used by the backend going forward. + - Removed `getTokenLifetimeSeconds` & `setTokenLifetimeSeconds` (property `tokenLifetimeSeconds` is removed) + +### Package `com.okta.sdk.resource.user.Role` + +With the introduction of enum type `com.okta.sdk.resource.role.RoleType`, the getter/setter for role type operation will now make +use of this new enum type instead of the `String` type used earlier. + - `getType` Return type changed from `String` to an enum `com.okta.sdk.resource.role.RoleType` + - `setType` Param type changed from `String` to an enum `com.okta.sdk.resource.role.RoleType` + +### Package `com.okta.sdk.resource.user.User` + +The below method names have been refactored to be more apt: + - Renamed `addGroupTarget` to `addGroupTargetToRole` + - Renamed `addRole` to `assignRole` + - Renamed `listGroupTargetsForRole` to `listGroupTargets` + - Renamed `removeGroupTargetFromRole` to `removeGroupTarget` + - Renamed `addFactor` to `enrollFactor` + - Renamed `listRoles`to `listAssignedRoles` + +The `forgotPassword` method has been removed. Use `resetPassword` instead to achieve the same functionality. + +The `endAllSessions` method has been removed. Use `clearSessions` instead to achieve the same functionality. + +Following methods have undergone a return type change inline with the refactoring of `UserFactor*` objects as mentioned above. + - `listSupportedFactors` Return type changed from `com.okta.sdk.resource.user.factor.FactorList` to `com.okta.sdk.resource.user.factor.UserFactorList` + - `getFactor` Return type changed from `com.okta.sdk.resource.user.factor.Factor` to `com.okta.sdk.resource.user.factor.UserFactor` + - `listFactors` Return type changed from `com.okta.sdk.resource.user.factor.FactorList` to `com.okta.sdk.resource.user.factor.UserFactorList` + +The `expirePassword` Return type changed from `com.okta.sdk.resource.user.TempPassword` to `com.okta.sdk.resource.user.User` + +The reset password method will no longer need a provider argument. + - `resetPassword(String provider, Boolean sendEmail)` Signature changed to `resetPassword(Boolean sendEmail)` + +### Package `com.okta.sdk.resource.user.UserCredentials` + +The property `emails` was not used by the backend and was always `null` hitherto. + - Removed `getEmails` & `setEmails` (property `emails` was removed) + +Below SDK classes/interfaces are **deprecated** and will be removed from this project. + +These SDK classes were previously moved to [okta-commons-java](https://github.com/okta/okta-commons-java)). + +``` +- com.okta.sdk.authc.credentials.ClientCredentialsProvider +- com.okta.sdk.client.Proxy +- com.okta.sdk.http.HttpMethod +- com.okta.sdk.http.HttpRequest +- com.okta.sdk.http.HttpRequestBuilder +- com.okta.sdk.http.HttpRequests +- com.okta.sdk.http.UserAgentProvider +- com.okta.sdk.lang.Assert +- com.okta.sdk.lang.Classes +- com.okta.sdk.lang.Collections +- com.okta.sdk.lang.Duration +- com.okta.sdk.lang.InstantiationException +- com.okta.sdk.lang.Instants +- com.okta.sdk.lang.Locales +- com.okta.sdk.lang.Objects +- com.okta.sdk.lang.Strings +- com.okta.sdk.lang.UnknownClassException +``` diff --git a/api/pom.xml b/api/pom.xml index c2f0bb9db96..8bd2be16f5b 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT okta-sdk-api diff --git a/api/src/main/java/com/okta/sdk/authc/credentials/ClientCredentialsProvider.java b/api/src/main/java/com/okta/sdk/authc/credentials/ClientCredentialsProvider.java deleted file mode 100644 index 8c13f975ee5..00000000000 --- a/api/src/main/java/com/okta/sdk/authc/credentials/ClientCredentialsProvider.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.authc.credentials; - -/** - * @since 0.5.0 - * @deprecated Use ClientCredentialsResolver - */ -@Deprecated -public interface ClientCredentialsProvider { - - ClientCredentials getClientCredentials(); - -} diff --git a/api/src/main/java/com/okta/sdk/client/ClientBuilder.java b/api/src/main/java/com/okta/sdk/client/ClientBuilder.java index ba5f5f07bf6..2cc2c5bd238 100644 --- a/api/src/main/java/com/okta/sdk/client/ClientBuilder.java +++ b/api/src/main/java/com/okta/sdk/client/ClientBuilder.java @@ -16,6 +16,7 @@ */ package com.okta.sdk.client; +import com.okta.commons.http.config.Proxy; import com.okta.sdk.authc.credentials.ClientCredentials; import com.okta.sdk.cache.CacheManager; @@ -294,28 +295,13 @@ public interface ClientBuilder { * Okta SSWS Digest * Authentication Scheme used to authenticate every request sent to the Okta API server. * - *

It is not recommended that you override this setting unless your application is deployed in an - * environment that - outside of your application's control - manipulates request headers on outgoing HTTP requests. - * Google App Engine is one such environment, for example.

- * *
      * Client client = Clients.builder()...
      *    // setApiKey, etc...
-     *    .setAuthenticationScheme(AuthenticationScheme.SSWS) //set the SSWS authentication scheme
+     *    .setAuthorizationMode(AuthorizationMode.SSWS) //set the SSWS authentication mode
      *    .build(); //build the Client
      * 
* - * @param authenticationScheme the type of authentication to be used for communication with the Okta API server. - * @return the ClientBuilder instance for method chaining - * - * @deprecated since 1.6.0 use {@link #setAuthorizationMode(AuthorizationMode)} to indicate the authentication scheme. - */ - @Deprecated - ClientBuilder setAuthenticationScheme(AuthenticationScheme authenticationScheme); - - /** - * Allows specifying an authorization mode. - * * @param authorizationMode mode of authorization for requests to the Okta API server. * @return the ClientBuilder instance for method chaining. * diff --git a/api/src/main/java/com/okta/sdk/client/Proxy.java b/api/src/main/java/com/okta/sdk/client/Proxy.java deleted file mode 100644 index 1be587ab429..00000000000 --- a/api/src/main/java/com/okta/sdk/client/Proxy.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.client; - -/** - * HTTP proxy server communication settings, used if the Okta SDK Client must communicate through an HTTP Proxy. - * - * @since 0.5.0 - * @deprecated use com.okta.commons.http.config.Proxy directly - */ -@Deprecated -public class Proxy extends com.okta.commons.http.config.Proxy { - - public Proxy(String host, int port) { - super(host, port); - } - - public Proxy(String host, int port, String username, String password) { - super(host, port, username, password); - } -} diff --git a/api/src/main/java/com/okta/sdk/http/HttpMethod.java b/api/src/main/java/com/okta/sdk/http/HttpMethod.java deleted file mode 100644 index 83e62aa72a1..00000000000 --- a/api/src/main/java/com/okta/sdk/http/HttpMethod.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.http; - -/** - * An enum representing the HTTP methods defined in the - * Hypertext Transfer Protocol -- HTTP/1.1 - * specification. - * - * @since 0.5.0 - * @deprecated use {@link com.okta.commons.http.HttpMethod} - */ -@Deprecated -public enum HttpMethod { - - GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE, CONNECT; - - /** - * Returns the {@code HttpMethod} instance associated with the specified String name. - * - * @param name The name of the {@code HttpMethod} instance to retrieve. - * @return the {@code HttpMethod} instance associated with the specified String name. - * @throws IllegalArgumentException if {@code name} is null or does not match (case insensitive) an HttpMethod - * value. - */ - public static HttpMethod fromName(String name) { - for (HttpMethod method : values()) { - if (method.name().equalsIgnoreCase(name)) { - return method; - } - } - throw new IllegalArgumentException("Unrecognized method name: " + name); - } -} diff --git a/api/src/main/java/com/okta/sdk/http/HttpRequest.java b/api/src/main/java/com/okta/sdk/http/HttpRequest.java deleted file mode 100644 index ed0cb284f0a..00000000000 --- a/api/src/main/java/com/okta/sdk/http/HttpRequest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.http; - -import java.util.Map; - -/** - * Users not depending on the Servlet API will need to construct {@link HttpRequestBuilder HttpRequest objects} to be - * able to use this SDK's request mechanism. - * - * @see HttpRequestBuilder - * @since 0.5.0 - * @deprecated not used - */ -@Deprecated -public interface HttpRequest { - - /** - * Returns the request's headers. Never null. - * - * @return the request's headers. Never null. - * @see #getHeader(String) - */ - Map getHeaders(); - - /** - * Returns the first available value for the request header with the specified name, or {@code null} if the header - * does not exist. - * - *

If there is more than one value, only the first will be returned and any subsequent values will be omitted. - * If you believe a header will have multiple values, use {@link #getHeaders() getHeaders()} instead. - * - * @param headerName the name of the header to inspect - * @return the first available value for the request header with the specified name, or {@code null} if the header - * does not exist. - */ - String getHeader(String headerName); - - /** - * Returns the request method. - * - * @return the request method. - */ - HttpMethod getMethod(); - - /** - * Returns the request parameters. - * - * @return the request parameters. - */ - Map getParameters(); - - /** - * Returns the first available value of the request parameter with the specified name or {@code null} if the - * parameter does not exist. - * - * @param parameterName the name of the parameter to look up - * @return the first available value of the request parameter with the specified name or {@code null} if the - * parameter does not exist. - */ - String getParameter(String parameterName); - - /** - * Returns the request query parameter String, or {@code null} if there is no URI query parameter component. - * - * @return the request query parameter String, or {@code null} if there is no URI query parameter component. - */ - String getQueryParameters(); - -} diff --git a/api/src/main/java/com/okta/sdk/http/HttpRequestBuilder.java b/api/src/main/java/com/okta/sdk/http/HttpRequestBuilder.java deleted file mode 100644 index 9b251308711..00000000000 --- a/api/src/main/java/com/okta/sdk/http/HttpRequestBuilder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.http; - -import java.util.Map; - -/** - * A Builder design pattern used to - * construct {@link HttpRequest} instances. - * - *

The {@link HttpRequestBuilder} is useful to build {@link HttpRequest} instances for developers that don't - * have access to the Servlet container, and therefore, cannot execute operations using implementations - * of the {@code javax.servlet.HttpServlet} api.

- * - * @see HttpRequest - * @see HttpRequests - * @since 0.5.0 - * @deprecated Not used - */ -@Deprecated -public interface HttpRequestBuilder { - - /** - * Sets the HTTP Headers that will be present in the resulting request instance. - * - * @param headers the HTTP Headers that will be present in the resulting built request instance. - * @return the builder instance for method chaining. - * @throws IllegalArgumentException if the method argument is {@code null}. - */ - HttpRequestBuilder headers(Map headers); - - /** - * Sets the request parameters that will be present in the resulting request instance. - * - * @param parameters the request parameters that will be present in the resulting request instance. - * @return the builder instance for method chaining. - */ - HttpRequestBuilder parameters(Map parameters); - - /** - * Adds a request header that will be part of the headers map in the resulting request instance. - * - * @param name the name of the HTTP header that will be present in the resulting HTTP request instance. - * @param value the value of the HTTP header that will be present in the resulting HTTP request instance. - * @return the builder instance for method chaining. - * @throws IllegalArgumentException if the name or value arguments are {@code null}. - * - */ - HttpRequestBuilder addHeader(String name, String[] value); - - /** - * Adds a request parameter that will be part of the parameters map in the resulting request instance. - * - * @param name the name of the HTTP parameter that will be present in the resulting HTTP request instance. - * @param value the value of the HTTP parameter that will be present in the resulting HTTP request instance. - * @return the builder instance for method chaining. - * @throws IllegalArgumentException if the name or value arguments are {@code null}. - * - */ - HttpRequestBuilder addParameter(String name, String[] value); - - /** - * Sets the query parameters that will be present in the resulting request instance. - * - * @param queryParameters the query parameters that will be present in the resulting request instance. - * @return the builder instance for method chaining. - */ - HttpRequestBuilder queryParameters(String queryParameters); - - /** - * Returns a new {@code HttpRequest} instance reflecting the current builder state. - * - * @return a new {@code HttpRequest} instance reflecting the current builder state. - */ - HttpRequest build(); -} diff --git a/api/src/main/java/com/okta/sdk/http/HttpRequests.java b/api/src/main/java/com/okta/sdk/http/HttpRequests.java deleted file mode 100644 index 4cfe7e3e304..00000000000 --- a/api/src/main/java/com/okta/sdk/http/HttpRequests.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.http; - -import com.okta.commons.lang.Assert; -import com.okta.commons.lang.Classes; - -import java.lang.reflect.Constructor; - -/** - * Utility factory class for creating {@link HttpRequest} instances for SDK users that do not already depend on the - * {@code HttpServletRequest} API. - * - *

Once you obtain either a {@code HttpServletRequest} or construct a {@link HttpRequest}, either may be - * authenticated (presumably to assert an identity for calls to your REST API) - *

- * - * @since 0.5.0 - * @deprecated not used - */ -@Deprecated -public final class HttpRequests { - - private static final Class HTTP_REQUEST_BUILDER = - Classes.forName("com.okta.sdk.impl.http.DefaultHttpRequestBuilder"); - - /** - * Creates and returns a new {@link HttpRequestBuilder} that builds request instances that will be used for request - * authentication. - * - *

This method is only useful for SDK users that do not depend on the {@code HttpServletRequest} API, as - * the {@code application.authenticate*} methods accept that type natively.

- * - * @param method the source request's http method. - * @return a new HttpRequestBuilder that can be used to construct a new {@link HttpRequest} instance. - * @throws IllegalArgumentException if the method argument is {@code null}. - */ - public static HttpRequestBuilder method(HttpMethod method) { - Assert.notNull(method, "method argument is required."); - - Constructor ctor = Classes.getConstructor(HTTP_REQUEST_BUILDER, HttpMethod.class); - return Classes.instantiate(ctor, method); - } -} diff --git a/api/src/main/java/com/okta/sdk/http/UserAgentProvider.java b/api/src/main/java/com/okta/sdk/http/UserAgentProvider.java deleted file mode 100644 index 1ca6120c187..00000000000 --- a/api/src/main/java/com/okta/sdk/http/UserAgentProvider.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.http; - -/** - * Provides a portion of a User Agent string. - * - * @since 1.1.0 - * @deprecated instead create a file named META-INF/okta/version.properties with a format of name=version - */ -@Deprecated -public interface UserAgentProvider { - - /** - * Returns a portion of a User-Agent string used when making HTTP requests. It is recomended the result be in - * the format of <lib-identifier>/<version>. - * - * @return a portion of a User-Agent string - */ - String getUserAgent(); -} diff --git a/api/src/main/java/com/okta/sdk/http/package-info.java b/api/src/main/java/com/okta/sdk/http/package-info.java deleted file mode 100644 index e8a786f3d70..00000000000 --- a/api/src/main/java/com/okta/sdk/http/package-info.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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. - */ -/** - * HTTP Request API for SDK users that do not depend on the {@code HttpServletRequest} API. The - * {@link com.okta.sdk.http.HttpRequests HttpRequests} factory class helps constructs relevant instances. - * - * @see com.okta.sdk.http.HttpRequests HttpRequests - * - * @since 0.5.0 - */ -package com.okta.sdk.http; diff --git a/api/src/main/java/com/okta/sdk/lang/Assert.java b/api/src/main/java/com/okta/sdk/lang/Assert.java deleted file mode 100644 index fd73aa4abb8..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Assert.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.util.Collection; -import java.util.Map; - -/** - * @deprecated use com.okta.commons.lang.Assert - */ -@Deprecated -public abstract class Assert { - - /** - * Assert a boolean expression, throwing {@code IllegalArgumentException} - * if the test result is {@code false}. - *
Assert.isTrue(i > 0, "The value must be greater than zero");
- * @param expression a boolean expression - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if expression is {@code false} - */ - public static void isTrue(boolean expression, String message) { - if (!expression) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert a boolean expression, throwing {@code IllegalArgumentException} - * if the test result is {@code false}. - *
Assert.isTrue(i > 0);
- * @param expression a boolean expression - * @throws IllegalArgumentException if expression is {@code false} - */ - public static void isTrue(boolean expression) { - isTrue(expression, "[Assertion failed] - this expression must be true"); - } - - /** - * Assert that an object is {@code null} . - *
Assert.isNull(value, "The value must be null");
- * @param object the object to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the object is not {@code null} - */ - public static void isNull(Object object, String message) { - if (object != null) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an object is {@code null} . - *
Assert.isNull(value);
- * @param object the object to check - * @throws IllegalArgumentException if the object is not {@code null} - */ - public static void isNull(Object object) { - isNull(object, "[Assertion failed] - the object argument must be null"); - } - - /** - * Assert that an object is not {@code null} . - *
Assert.notNull(clazz, "The class must not be null");
- * @param object the object to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the object is {@code null} - */ - public static void notNull(Object object, String message) { - if (object == null) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an object is not {@code null} . - *
Assert.notNull(clazz);
- * @param object the object to check - * @throws IllegalArgumentException if the object is {@code null} - */ - public static void notNull(Object object) { - notNull(object, "[Assertion failed] - this argument is required; it must not be null"); - } - - /** - * Assert that the given String is not empty; that is, - * it must not be {@code null} and not the empty String. - *
Assert.hasLength(name, "Name must not be empty");
- * @param text the String to check - * @param message the exception message to use if the assertion fails - * @see Strings#hasLength - */ - public static void hasLength(String text, String message) { - if (!Strings.hasLength(text)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given String is not empty; that is, - * it must not be {@code null} and not the empty String. - *
Assert.hasLength(name);
- * @param text the String to check - * @see Strings#hasLength - */ - public static void hasLength(String text) { - hasLength(text, - "[Assertion failed] - this String argument must have length; it must not be null or empty"); - } - - /** - * Assert that the given String has valid text content; that is, it must not - * be {@code null} and must contain at least one non-whitespace character. - *
Assert.hasText(name, "'name' must not be empty");
- * @param text the String to check - * @param message the exception message to use if the assertion fails - * @see Strings#hasText - */ - public static void hasText(String text, String message) { - if (!Strings.hasText(text)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given String has valid text content; that is, it must not - * be {@code null} and must contain at least one non-whitespace character. - *
Assert.hasText(name, "'name' must not be empty");
- * @param text the String to check - * @see Strings#hasText - */ - public static void hasText(String text) { - hasText(text, - "[Assertion failed] - this String argument must have text; it must not be null, empty, or blank"); - } - - /** - * Assert that the given text does not contain the given substring. - *
Assert.doesNotContain(name, "rod", "Name must not contain 'rod'");
- * @param textToSearch the text to search - * @param substring the substring to find within the text - * @param message the exception message to use if the assertion fails - */ - public static void doesNotContain(String textToSearch, String substring, String message) { - if (Strings.hasLength(textToSearch) && Strings.hasLength(substring) && - textToSearch.indexOf(substring) != -1) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that the given text does not contain the given substring. - *
Assert.doesNotContain(name, "rod");
- * @param textToSearch the text to search - * @param substring the substring to find within the text - */ - public static void doesNotContain(String textToSearch, String substring) { - doesNotContain(textToSearch, substring, - "[Assertion failed] - this String argument must not contain the substring [" + substring + "]"); - } - - - /** - * Assert that an array has elements; that is, it must not be - * {@code null} and must have at least one element. - *
Assert.notEmpty(array, "The array must have elements");
- * @param array the array to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the object array is {@code null} or has no elements - */ - public static void notEmpty(Object[] array, String message) { - if (Objects.isEmpty(array)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that an array has elements; that is, it must not be - * {@code null} and must have at least one element. - *
Assert.notEmpty(array);
- * @param array the array to check - * @throws IllegalArgumentException if the object array is {@code null} or has no elements - */ - public static void notEmpty(Object[] array) { - notEmpty(array, "[Assertion failed] - this array must not be empty: it must contain at least 1 element"); - } - - /** - * Assert that an array has no null elements. - * Note: Does not complain if the array is empty! - *
Assert.noNullElements(array, "The array must have non-null elements");
- * @param array the array to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the object array contains a {@code null} element - */ - public static void noNullElements(Object[] array, String message) { - if (array != null) { - for (int i = 0; i < array.length; i++) { - if (array[i] == null) { - throw new IllegalArgumentException(message); - } - } - } - } - - /** - * Assert that an array has no null elements. - * Note: Does not complain if the array is empty! - *
Assert.noNullElements(array);
- * @param array the array to check - * @throws IllegalArgumentException if the object array contains a {@code null} element - */ - public static void noNullElements(Object[] array) { - noNullElements(array, "[Assertion failed] - this array must not contain any null elements"); - } - - /** - * Assert that a collection has elements; that is, it must not be - * {@code null} and must have at least one element. - *
Assert.notEmpty(collection, "Collection must have elements");
- * @param collection the collection to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the collection is {@code null} or has no elements - */ - public static void notEmpty(Collection collection, String message) { - if (Collections.isEmpty(collection)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that a collection has elements; that is, it must not be - * {@code null} and must have at least one element. - *
Assert.notEmpty(collection, "Collection must have elements");
- * @param collection the collection to check - * @throws IllegalArgumentException if the collection is {@code null} or has no elements - */ - public static void notEmpty(Collection collection) { - notEmpty(collection, - "[Assertion failed] - this collection must not be empty: it must contain at least 1 element"); - } - - /** - * Assert that a Map has entries; that is, it must not be {@code null} - * and must have at least one entry. - *
Assert.notEmpty(map, "Map must have entries");
- * @param map the map to check - * @param message the exception message to use if the assertion fails - * @throws IllegalArgumentException if the map is {@code null} or has no entries - */ - public static void notEmpty(Map map, String message) { - if (Collections.isEmpty(map)) { - throw new IllegalArgumentException(message); - } - } - - /** - * Assert that a Map has entries; that is, it must not be {@code null} - * and must have at least one entry. - *
Assert.notEmpty(map);
- * @param map the map to check - * @throws IllegalArgumentException if the map is {@code null} or has no entries - */ - public static void notEmpty(Map map) { - notEmpty(map, "[Assertion failed] - this map must not be empty; it must contain at least one entry"); - } - - - /** - * Assert that the provided object is an instance of the provided class. - *
Assert.instanceOf(Foo.class, foo);
- * @param clazz the required class - * @param obj the object to check - * @throws IllegalArgumentException if the object is not an instance of clazz - * @see Class#isInstance - */ - public static void isInstanceOf(Class clazz, Object obj) { - isInstanceOf(clazz, obj, ""); - } - - /** - * Assert that the provided object is an instance of the provided class. - *
Assert.instanceOf(Foo.class, foo);
- * @param type the type to check against - * @param obj the object to check - * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. - * @throws IllegalArgumentException if the object is not an instance of clazz - * @see Class#isInstance - */ - public static void isInstanceOf(Class type, Object obj, String message) { - notNull(type, "Type to check against must not be null"); - if (!type.isInstance(obj)) { - throw new IllegalArgumentException(message + - "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + - "] must be an instance of " + type); - } - } - - /** - * Assert that {@code superType.isAssignableFrom(subType)} is true. - *
Assert.isAssignable(Number.class, myClass);
- * @param superType the super type to check - * @param subType the sub type to check - * @throws IllegalArgumentException if the classes are not assignable - */ - public static void isAssignable(Class superType, Class subType) { - isAssignable(superType, subType, ""); - } - - /** - * Assert that {@code superType.isAssignableFrom(subType)} is true. - *
Assert.isAssignable(Number.class, myClass);
- * @param superType the super type to check against - * @param subType the sub type to check - * @param message a message which will be prepended to the message produced by - * the function itself, and which may be used to provide context. It should - * normally end in a ": " or ". " so that the function generate message looks - * ok when prepended to it. - * @throws IllegalArgumentException if the classes are not assignable - */ - public static void isAssignable(Class superType, Class subType, String message) { - notNull(superType, "Type to check against must not be null"); - if (subType == null || !superType.isAssignableFrom(subType)) { - throw new IllegalArgumentException(message + subType + " is not assignable to " + superType); - } - } - - - /** - * Assert a boolean expression, throwing {@code IllegalStateException} - * if the test result is {@code false}. Call isTrue if you wish to - * throw IllegalArgumentException on an assertion failure. - *
Assert.state(id == null, "The id property must not already be initialized");
- * @param expression a boolean expression - * @param message the exception message to use if the assertion fails - * @throws IllegalStateException if expression is {@code false} - */ - public static void state(boolean expression, String message) { - if (!expression) { - throw new IllegalStateException(message); - } - } - - /** - * Assert a boolean expression, throwing {@link IllegalStateException} - * if the test result is {@code false}. - *

Call {@link #isTrue(boolean)} if you wish to - * throw {@link IllegalArgumentException} on an assertion failure. - *

Assert.state(id == null);
- * @param expression a boolean expression - * @throws IllegalStateException if the supplied expression is {@code false} - */ - public static void state(boolean expression) { - state(expression, "[Assertion failed] - this state invariant must be true"); - } - -} diff --git a/api/src/main/java/com/okta/sdk/lang/Classes.java b/api/src/main/java/com/okta/sdk/lang/Classes.java deleted file mode 100644 index 7e8868cb623..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Classes.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.InputStream; -import java.lang.reflect.Constructor; -import java.util.Optional; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; -import java.util.stream.StreamSupport; - -/** - * @since 0.5.0 - * @deprecated use com.okta.commons.lang.Classes - */ -@Deprecated -public class Classes { - - /** - * Private internal log instance. - */ - private static final Logger log = LoggerFactory.getLogger(Classes.class); - - /** - */ - private static final ClassLoaderAccessor THREAD_CL_ACCESSOR = new ExceptionIgnoringAccessor() { - @Override - protected ClassLoader doGetClassLoader() { - return Thread.currentThread().getContextClassLoader(); - } - }; - - /** - */ - private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() { - @Override - protected ClassLoader doGetClassLoader() { - return Classes.class.getClassLoader(); - } - }; - - /** - */ - private static final ClassLoaderAccessor SYSTEM_CL_ACCESSOR = new ExceptionIgnoringAccessor() { - @Override - protected ClassLoader doGetClassLoader() { - return ClassLoader.getSystemClassLoader(); - } - }; - - /** - * Attempts to load the specified class name from the current thread's - * {@link Thread#getContextClassLoader() context class loader}, then the - * current ClassLoader ({@code Classes.class.getClassLoader()}), then the system/application - * ClassLoader ({@code ClassLoader.getSystemClassLoader()}, in that order. If any of them cannot locate - * the specified class, an {@code UnknownClassException} is thrown (our RuntimeException equivalent of - * the JRE's {@code ClassNotFoundException}. - * - * @param fqcn the fully qualified class name to load - * @param type of class - * @return the located class - * @throws UnknownClassException if the class cannot be found. - */ - public static Class forName(String fqcn) throws UnknownClassException { - - Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn); - - if (clazz == null) { - if (log.isTraceEnabled()) { - log.trace("Unable to load class named [" + fqcn + - "] from the thread context ClassLoader. Trying the current ClassLoader..."); - } - clazz = CLASS_CL_ACCESSOR.loadClass(fqcn); - } - - if (clazz == null) { - if (log.isTraceEnabled()) { - log.trace("Unable to load class named [" + fqcn + "] from the current ClassLoader. " + - "Trying the system/application ClassLoader..."); - } - clazz = SYSTEM_CL_ACCESSOR.loadClass(fqcn); - } - - if (clazz == null) { - String msg = "Unable to load class named [" + fqcn + "] from the thread context, current, or " + - "system/application ClassLoaders. All heuristics have been exhausted. Class could not be found."; - - if (fqcn != null && fqcn.startsWith("com.okta.sdk.impl")) { - msg += " Have you remembered to include the okta-sdk-impl .jar in your runtime classpath?"; - } - - throw new UnknownClassException(msg); - } - - return clazz; - } - - /** - * Returns the specified resource by checking the current thread's - * {@link Thread#getContextClassLoader() context class loader}, then the - * current ClassLoader ({@code Classes.class.getClassLoader()}), then the system/application - * ClassLoader ({@code ClassLoader.getSystemClassLoader()}, in that order, using - * {@link ClassLoader#getResourceAsStream(String) getResourceAsStream(name)}. - * - * @param name the name of the resource to acquire from the classloader(s). - * @return the InputStream of the resource found, or {@code null} if the resource cannot be found from any - * of the three mentioned ClassLoaders. - */ - public static InputStream getResourceAsStream(String name) { - - InputStream is = THREAD_CL_ACCESSOR.getResourceStream(name); - - if (is == null) { - is = CLASS_CL_ACCESSOR.getResourceStream(name); - } - - if (is == null) { - is = SYSTEM_CL_ACCESSOR.getResourceStream(name); - } - - return is; - } - - public static boolean isAvailable(String fullyQualifiedClassName) { - try { - forName(fullyQualifiedClassName); - return true; - } catch (UnknownClassException e) { - return false; - } - } - - public static T newInstance(String fqcn) { - Class clazz = forName(fqcn); - return newInstance(clazz); - } - - public static T newInstance(String fqcn, Object... args) { - Class clazz = forName(fqcn); - return newInstance(clazz, args); - } - - public static T newInstance(Class clazz) { - if (clazz == null) { - String msg = "Class method parameter cannot be null."; - throw new IllegalArgumentException(msg); - } - try { - return clazz.newInstance(); - } catch (Exception e) { - throw new InstantiationException("Unable to instantiate class [" + clazz.getName() + "]", e); - } - } - - public static T newInstance(Class clazz, Object... args) { - Class[] argTypes = new Class[args.length]; - for (int i = 0; i < args.length; i++) { - argTypes[i] = args[i].getClass(); - } - Constructor ctor = getConstructor(clazz, argTypes); - return instantiate(ctor, args); - } - - public static Constructor getConstructor(Class clazz, Class... argTypes) { - try { - return clazz.getConstructor(argTypes); - } catch (NoSuchMethodException e) { - throw new IllegalStateException(e); - } - - } - - public static T instantiate(Constructor ctor, Object... args) { - try { - return ctor.newInstance(args); - } catch (Exception e) { - String msg = "Unable to instantiate instance with constructor [" + ctor + "]"; - throw new InstantiationException(msg, e); - } - } - - public static T loadFromService(Class clazz) { - return loadFromService(clazz, "ServiceLoader failed to find implementation for class: " + clazz); - } - - public static T loadFromService(Class clazz, String errorMessage) { - try { - ServiceLoader serviceLoader = ServiceLoader.load(clazz); - Optional result = StreamSupport.stream(serviceLoader.spliterator(), false).findFirst(); - return result.orElseThrow(() -> new IllegalStateException(errorMessage)); - } catch(ServiceConfigurationError e) { - throw new IllegalStateException(errorMessage, e); - } - } - - /** - */ - private interface ClassLoaderAccessor { - Class loadClass(String fqcn); - InputStream getResourceStream(String name); - } - - /** - */ - private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor { - - @SuppressWarnings("unchecked") - public Class loadClass(String fqcn) { - Class clazz = null; - ClassLoader cl = getClassLoader(); - if (cl != null) { - try { - clazz = (Class)cl.loadClass(fqcn); - } catch (ClassNotFoundException e) { - if (log.isTraceEnabled()) { - log.trace("Unable to load clazz named [" + fqcn + "] from class loader [" + cl + "]"); - } - } - } - return clazz; - } - - public InputStream getResourceStream(String name) { - InputStream is = null; - ClassLoader cl = getClassLoader(); - if (cl != null) { - is = cl.getResourceAsStream(name); - } - return is; - } - - protected final ClassLoader getClassLoader() { - try { - return doGetClassLoader(); - } catch (Throwable t) { - if (log.isDebugEnabled()) { - log.debug("Unable to acquire ClassLoader.", t); - } - } - return null; - } - - protected abstract ClassLoader doGetClassLoader() throws Throwable; - } -} diff --git a/api/src/main/java/com/okta/sdk/lang/Collections.java b/api/src/main/java/com/okta/sdk/lang/Collections.java deleted file mode 100644 index 57bf5f25735..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Collections.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -/** - * @deprecated use com.okta.commons.lang.Collections - */ -@Deprecated -public abstract class Collections { - - /** - * Return {@code true} if the supplied Collection is {@code null} - * or empty. Otherwise, return {@code false}. - * - * @param collection the Collection to check - * @return whether the given Collection is empty - */ - public static boolean isEmpty(Collection collection) { - return (collection == null || collection.isEmpty()); - } - - /** - * Returns the collection's size or {@code 0} if the collection is {@code null}. - * - * @param collection the collection to check. - * @return the collection's size or {@code 0} if the collection is {@code null}. - */ - public static int size(Collection collection) { - return collection == null ? 0 : collection.size(); - } - - /** - * Returns the map's size or {@code 0} if the map is {@code null}. - * - * @param map the map to check - * @return the map's size or {@code 0} if the map is {@code null}. - */ - public static int size(Map map) { - return map == null ? 0 : map.size(); - } - - /** - * Return {@code true} if the supplied Map is {@code null} - * or empty. Otherwise, return {@code false}. - * - * @param map the Map to check - * @return whether the given Map is empty - */ - public static boolean isEmpty(Map map) { - return (map == null || map.isEmpty()); - } - - /** - * Convert the supplied array into a List. A primitive array gets - * converted into a List of the appropriate wrapper type. - *

A {@code null} source value will be converted to an - * empty List. - * - * @param source the (potentially primitive) array - * @return the converted List result - * @see Objects#toObjectArray(Object) - */ - public static List arrayToList(Object source) { - return Arrays.asList(Objects.toObjectArray(source)); - } - - /** - * a new List that contains the specified elements or an empty collection if the elements are null or empty. - * - * @param elements the elements to put in the list. - * @param the type of elements in the collection - * @return a new List that contains the specified elements or an empty collection if the elements are null or empty. - */ - public static List toList(T... elements) { - if (elements == null || elements.length == 0) { - return java.util.Collections.emptyList(); - } - // Avoid integer overflow when a large array is passed in - int capacity = computeListCapacity(elements.length); - ArrayList list = new ArrayList<>(capacity); - java.util.Collections.addAll(list, elements); - return list; - } - - /** - * a new List that contains the specified elements or an empty collection if the elements are null or empty. - * - * @param elements the elements to put in the list. - * @param the type of elements in the collection - * @return a new List that contains the specified elements or an empty collection if the elements are null or empty. - */ - public static List toList(Collection elements) { - if (elements instanceof List) { - return (List) elements; - } - if (isEmpty(elements)) { - return java.util.Collections.emptyList(); - } - // Avoid integer overflow when a large array is passed in - int capacity = computeListCapacity(elements.size()); - ArrayList list = new ArrayList<>(capacity); - list.addAll(elements); - return list; - } - - /** - * Returns a new {@link Set} that contains the specified elements or an empty Set if the elements are null or empty. - * - * @param elements elements to add to the new set - * @param the type of elements in the set - * @return a new {@link Set} that contains the specified elements or an empty Set if the elements are null or empty. - */ - public static Set toSet(E... elements) { - if (elements == null || elements.length == 0) { - return java.util.Collections.emptySet(); - } - LinkedHashSet set = new LinkedHashSet<>(elements.length * 4 / 3 + 1); - java.util.Collections.addAll(set, elements); - return set; - } - - //since 1.0 - private static int computeListCapacity(int arraySize) { - return (int) Math.min(5L + arraySize + (arraySize / 10), Integer.MAX_VALUE); - } - - /** - * Merge the given array into the given Collection. - * - * @param array the array to merge (may be {@code null}) - * @param collection the target Collection to merge the array into - */ - @SuppressWarnings("unchecked") - public static void mergeArrayIntoCollection(Object array, Collection collection) { - if (collection == null) { - throw new IllegalArgumentException("Collection must not be null"); - } - Object[] arr = Objects.toObjectArray(array); - java.util.Collections.addAll(collection, arr); - } - - /** - * Merge the given Properties instance into the given Map, - * copying all properties (key-value pairs) over. - *

Uses {@code Properties.propertyNames()} to even catch - * default properties linked into the original Properties instance. - * - * @param props the Properties instance to merge (may be {@code null}) - * @param map the target Map to merge the properties into - */ - @SuppressWarnings("unchecked") - public static void mergePropertiesIntoMap(Properties props, Map map) { - if (map == null) { - throw new IllegalArgumentException("Map must not be null"); - } - if (props != null) { - for (Enumeration en = props.propertyNames(); en.hasMoreElements(); ) { - String key = (String) en.nextElement(); - Object value = props.getProperty(key); - if (value == null) { - // Potentially a non-String value... - value = props.get(key); - } - map.put(key, value); - } - } - } - - - /** - * Check whether the given Iterator contains the given element. - * - * @param iterator the Iterator to check - * @param element the element to look for - * @return {@code true} if found, {@code false} else - */ - public static boolean contains(Iterator iterator, Object element) { - if (iterator != null) { - while (iterator.hasNext()) { - Object candidate = iterator.next(); - if (Objects.nullSafeEquals(candidate, element)) { - return true; - } - } - } - return false; - } - - /** - * Check whether the given Enumeration contains the given element. - * - * @param enumeration the Enumeration to check - * @param element the element to look for - * @return {@code true} if found, {@code false} else - */ - public static boolean contains(Enumeration enumeration, Object element) { - if (enumeration != null) { - while (enumeration.hasMoreElements()) { - Object candidate = enumeration.nextElement(); - if (Objects.nullSafeEquals(candidate, element)) { - return true; - } - } - } - return false; - } - - /** - * Check whether the given Collection contains the given element instance. - *

Enforces the given instance to be present, rather than returning - * {@code true} for an equal element as well. - * - * @param collection the Collection to check - * @param element the element to look for - * @return {@code true} if found, {@code false} else - */ - public static boolean containsInstance(Collection collection, Object element) { - if (collection != null) { - for (Object candidate : collection) { - if (candidate == element) { - return true; - } - } - } - return false; - } - - /** - * Return {@code true} if any element in '{@code candidates}' is - * contained in '{@code source}'; otherwise returns {@code false}. - * - * @param source the source Collection - * @param candidates the candidates to search for - * @return whether any of the candidates has been found - */ - public static boolean containsAny(Collection source, Collection candidates) { - if (isEmpty(source) || isEmpty(candidates)) { - return false; - } - for (Object candidate : candidates) { - if (source.contains(candidate)) { - return true; - } - } - return false; - } - - /** - * Return the first element in '{@code candidates}' that is contained in - * '{@code source}'. If no element in '{@code candidates}' is present in - * '{@code source}' returns {@code null}. Iteration order is - * {@link Collection} implementation specific. - * - * @param source the source Collection - * @param candidates the candidates to search for - * @return the first present object, or {@code null} if not found - */ - public static Object findFirstMatch(Collection source, Collection candidates) { - if (isEmpty(source) || isEmpty(candidates)) { - return null; - } - for (Object candidate : candidates) { - if (source.contains(candidate)) { - return candidate; - } - } - return null; - } - - /** - * Find a single value of the given type in the given Collection. - * - * @param collection the Collection to search - * @param type the type to look for - * @param type type of object to find - * @return a value of the given type found if there is a clear match, - * or {@code null} if none or more than one such value found - */ - @SuppressWarnings("unchecked") - private static T findValueOfType(Collection collection, Class type) { - if (isEmpty(collection)) { - return null; - } - T value = null; - for (Object element : collection) { - if (type == null || type.isInstance(element)) { - if (value != null) { - // More than one value found... no clear single value. - return null; - } - value = (T) element; - } - } - return value; - } - - /** - * Find the first single value of the given type in the given Collection or {@code null} if none was found - * - * @param collection the Collection to search - * @param type the type to look for - * @param type type of object to find - * @return a value of the given type found or {@code null} if none found. - */ - @SuppressWarnings("unchecked") - public static T findFirstValueOfType(Collection collection, Class type) { - - Assert.notNull(type, "type argument cannot be null."); - - if (!isEmpty(collection)) { - for (Object element : collection) { - if (element != null && type.isInstance(element)) { - return (T) element; - } - } - } - - return null; - } - - /** - * Find a single value of one of the given types in the given Collection: - * searching the Collection for a value of the first type, then - * searching for a value of the second type, etc. - * - * @param collection the collection to search - * @param types the types to look for, in prioritized order - * @return a value of one of the given types found if there is a clear match, - * or {@code null} if none or more than one such value found - */ - public static Object findValueOfType(Collection collection, Class[] types) { - if (isEmpty(collection) || Objects.isEmpty(types)) { - return null; - } - for (Class type : types) { - Object value = findValueOfType(collection, type); - if (value != null) { - return value; - } - } - return null; - } - - /** - * Determine whether the given Collection only contains a single unique object. - * - * @param collection the Collection to check - * @return {@code true} if the collection contains a single reference or - * multiple references to the same instance, {@code false} else - */ - public static boolean hasUniqueObject(Collection collection) { - if (isEmpty(collection)) { - return false; - } - boolean hasCandidate = false; - Object candidate = null; - for (Object elem : collection) { - if (!hasCandidate) { - hasCandidate = true; - candidate = elem; - } else if (candidate != elem) { - return false; - } - } - return true; - } - - /** - * Find the common element type of the given Collection, if any. - * - * @param collection the Collection to check - * @return the common element type, or {@code null} if no clear - * common type has been found (or the collection was empty) - */ - public static Class findCommonElementType(Collection collection) { - if (isEmpty(collection)) { - return null; - } - Class candidate = null; - for (Object val : collection) { - if (val != null) { - if (candidate == null) { - candidate = val.getClass(); - } else if (candidate != val.getClass()) { - return null; - } - } - } - return candidate; - } - - /** - * Marshal the elements from the given enumeration into an array of the given type. - * Enumeration elements must be assignable to the type of the given array. The array - * returned will be a different instance than the array given. - * @param enumeration source enumeration - * @param array the array into which the elements of the list are to - * be stored, if it is big enough; otherwise, a new array of the - * same runtime type is allocated for this purpose. - * @param type of array - * @param type of enumeration - * @return an array with the contents of the enumeration - */ - public static A[] toArray(Enumeration enumeration, A[] array) { - ArrayList elements = new ArrayList<>(); - while (enumeration.hasMoreElements()) { - elements.add(enumeration.nextElement()); - } - return elements.toArray(array); - } - - @SuppressWarnings("unchecked") - public static T[] toArray(Collection c, Class type) { - T[] array = (T[])Array.newInstance(type, size(c)); - return c.toArray(array); - } - - /** - * Adapt an enumeration to an iterator. - * - * @param enumeration the enumeration - * @param type of enumeration - * @return the iterator - */ - public static Iterator toIterator(Enumeration enumeration) { - return new EnumerationIterator<>(enumeration); - } - - /** - * Iterator wrapping an Enumeration. - */ - private static class EnumerationIterator implements Iterator { - - private final Enumeration enumeration; - - EnumerationIterator(Enumeration enumeration) { - this.enumeration = enumeration; - } - - public boolean hasNext() { - return this.enumeration.hasMoreElements(); - } - - public E next() { - return this.enumeration.nextElement(); - } - - public void remove() { - throw new UnsupportedOperationException("Not supported"); - } - } -} diff --git a/api/src/main/java/com/okta/sdk/lang/Duration.java b/api/src/main/java/com/okta/sdk/lang/Duration.java deleted file mode 100644 index a08a8c029fd..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Duration.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import com.okta.commons.lang.Assert; - -import java.util.Locale; -import java.util.concurrent.TimeUnit; - -/** - * A duration is a scalar value paired with a unit of time. For example, 10 milliseconds and 50 minutes are both - * durations (scalar + unit of time). - * - * @since 0.5.0 - * @deprecated user java.time.Duration - */ -@Deprecated -public class Duration implements Comparable, Cloneable { - - private final long value; - - private final TimeUnit timeUnit; - - public Duration(long value, TimeUnit timeUnit) { - Assert.notNull(timeUnit, "TimeUnit argument cannot be null."); - this.value = value; - this.timeUnit = timeUnit; - } - - public long getValue() { - return value; - } - - public TimeUnit getTimeUnit() { - return timeUnit; - } - - @Override - public int compareTo(Duration duration) { - long converted = timeUnit.convert(duration.getValue(), duration.getTimeUnit()); - return Long.compare(this.value, converted); - } - - public boolean isLessThan(Duration duration) { - return compareTo(duration) < 0; - } - - public boolean isGreaterThan(Duration duration) { - return compareTo(duration) > 0; - } - - public boolean isEquivalentTo(Duration duration) { - return compareTo(duration) == 0; - } - - public String toString() { - return value + " " + this.timeUnit.name().toLowerCase(Locale.ENGLISH); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Duration duration = (Duration) o; - - return value == duration.value - && timeUnit == duration.timeUnit; - } - - @Override - public int hashCode() { - int result = (int) (value ^ (value >>> 32)); - result = 31 * result + (timeUnit != null ? timeUnit.hashCode() : 0); - return result; - } - - @SuppressWarnings("CloneDoesntDeclareCloneNotSupportedException") - public Duration clone() { - try { - return (Duration) super.clone(); - } catch (CloneNotSupportedException e) { - //should never happen since we subclass Object directly: - throw new InternalError("Unable to clone Object direct subclass! " + e.getMessage()); - } - } -} diff --git a/api/src/main/java/com/okta/sdk/lang/InstantiationException.java b/api/src/main/java/com/okta/sdk/lang/InstantiationException.java deleted file mode 100644 index 3096eb23daf..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/InstantiationException.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -/** - * @since 0.5.0 - * @deprecated use com.okta.commons.lang.InstantiationException - */ -@Deprecated -public class InstantiationException extends RuntimeException { - - public InstantiationException(String s, Throwable t) { - super(s, t); - } -} diff --git a/api/src/main/java/com/okta/sdk/lang/Instants.java b/api/src/main/java/com/okta/sdk/lang/Instants.java deleted file mode 100644 index 502f7279bb7..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Instants.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; - -/** - * Utility class to create UTC-based dates and perform time conversions from UTC to other {@link TimeZone timezones} and vice versa - * - * @since 0.5.0 - * @deprecated use com.okta.commons.lang.Instants - */ -@Deprecated -public abstract class Instants { - - public static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("UTC"); - - private static final ThreadLocal DATE_FORMAT = ThreadLocal.withInitial(() -> { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - df.setTimeZone(UTC_TIMEZONE); - return df; - }); - - /** - * Returns the UTC-normalized ISO 8601 representation of the specified date instance. - * - * @param date the date to format. - * @return the UTC-normalized ISO 8601 representation of the specified date instance. - */ - public static String toUtcIso8601(Date date) { - return DATE_FORMAT.get().format(date); - } - - /** - * Converts a given time from UTC (Coordinated Universal Time) to the corresponding time in the specified {@link TimeZone} - * - * @param time the UTC instant to convert, represented as the number of milliseconds that have elapsed since midnight, January 1, 1970 - * @param to the target {@link TimeZone} for the conversion - * @return the long representation of the instant converted to the specified {@link TimeZone} - */ - public static long convertDateToLocalTime(long time, TimeZone to) { - return convertDate(time, UTC_TIMEZONE, to); - } - - /** - * Converts a given time from the specified {@link TimeZone} to the corresponding UTC (Coordinated Universal Time) time - * - * @param time the instant to convert, represented as the number of milliseconds that have elapsed since midnight, January 1, 1970 - * @param from the original {@link TimeZone} - * @return the UTC instant, represented as the number of milliseconds that have elapsed since midnight, January 1, 1970 - */ - public static long convertDateToUTC(long time, TimeZone from) { - return convertDate(time, from, UTC_TIMEZONE); - } - - /** - * Converts a given time from a {@link TimeZone} to another - * - * @param time the instant to convert, represented as the number of milliseconds that have elapsed since midnight, January 1, 1970 in the {@code from} {@link TimeZone} - * @param from the original {@link TimeZone} - * @param to the target {@link TimeZone} for the conversion - * @return the long representation of the instant converted to the specified {@code to} {@link TimeZone} - */ - public static long convertDate(long time, TimeZone from, TimeZone to) { - return time + getTimeZoneOffset(time, from, to); - } - - /** - * Creates an UTC-based {@link Date} using the provided {@code year}. - * Uses the current date and time, sets the specified {@code year} and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @return the UTC-based {@link Date} - */ - public static Date of(int year) { - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year} and {@code month}. - * Uses the current date and time, sets the specified {@code year} and {@code month}, and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @param month the month-of-year to represent, from 0 (January) to 11 (December) - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year}, {@code month} and {@code day} - * Uses the current date and time, sets the specified {@code year}, {@code month} and {@code day}, and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @param month the month-of-year to represent, from 0 (January) to 11 (December) - * @param day the day-of-month to represent, from 1 to 31 - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month, int day) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - Assert.isTrue(1 <= day && day <= 31, "day param must be a value from 1 to 31"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year}, {@code month}, {@code day} and {@code hour}. - * Uses the current date and time, sets the specified {@code year}, {@code month}, {@code day} and {@code hour}, and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @param month the month-of-year to represent, from 0 (January) to 11 (December) - * @param day the day-of-month to represent, from 1 to 31 - * @param hour the hour-of-day to represent, from 0 to 23 - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month, int day, int hour) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - Assert.isTrue(1 <= day && day <= 31, "day param must be a value from 1 to 31"); - Assert.isTrue(0 <= hour && hour <= 23, "hour param must be a value from 0 to 23"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - cal.set(Calendar.HOUR_OF_DAY, hour); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year}, {@code month}, {@code day}, {@code hour} and {@code minute}. - * Uses the current date and time, sets the specified {@code year}, {@code month}, {@code day}, {@code hour} and {@code minute}, and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @param month the month-of-year to represent, from 0 (January) to 11 (December) - * @param day the day-of-month to represent, from 1 to 31 - * @param hour the hour-of-day to represent, from 0 to 23 - * @param minute the minute-of-hour to represent, from 0 to 59 - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month, int day, int hour, int minute) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - Assert.isTrue(1 <= day && day <= 31, "day param must be a value from 1 to 31"); - Assert.isTrue(0 <= hour && hour <= 23, "hour param must be a value from 0 to 23"); - Assert.isTrue(0 <= minute && minute <= 59, "minute param must be a value from 0 to 59"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - cal.set(Calendar.HOUR_OF_DAY, hour); - cal.set(Calendar.MINUTE, minute); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year}, {@code month}, {@code day}, {@code hour}, {@code minute} and {@code second}. - * Uses the current date and time, sets the specified {@code year}, {@code month}, {@code day}, {@code hour}, {@code minute} and {@code second}, and returns the Date converted to a UTC timestamp. - * - * @param year the year to represent - * @param month the month-of-year to represent, from 0 (January) to 11 (December) - * @param day the day-of-month to represent, from 1 to 31 - * @param hour the hour-of-day to represent, from 0 to 23 - * @param minute the minute-of-hour to represent, from 0 to 59 - * @param second the second-of-hour to represent, from 0 to 59 - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month, int day, int hour, int minute, int second) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - Assert.isTrue(1 <= day && day <= 31, "day param must be a value from 1 to 31"); - Assert.isTrue(0 <= hour && hour <= 23, "hour param must be a value from 1 to 23"); - Assert.isTrue(0 <= minute && minute <= 59, "minute param must be a value from 0 to 59"); - Assert.isTrue(0 <= second && second <= 59, "second param must be a value from 0 to 59"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - cal.set(Calendar.HOUR_OF_DAY, hour); - cal.set(Calendar.MINUTE, minute); - cal.set(Calendar.SECOND, second); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - /** - * Creates an UTC-based {@link Date} from the provided {@code year}, {@code month}, {@code day}, {@code hour}, {@code minute} and {@code second}. - * Uses the current date and time, sets the specified {@code year}, {@code month}, {@code day}, {@code hour}, {@code minute} and {@code second}, and returns the Date converted to a UTC timestamp. - * - * @param year the YEAR to represent - * @param month the MONTH to represent, from 0 (January) to 11 (December) - * @param day the DAY_OF_MONTH to represent, from 1 to 31 - * @param hour the HOUR_OF_DAY to represent, from 0 to 23 - * @param minute the MINUTE to represent, from 0 to 59 - * @param second the SECOND to represent, from 0 to 59 - * @param millisecond the MILLISECOND to represent, from 0 to 59 - * @return the UTC-based {@link Date} - */ - public static Date of(int year, int month, int day, int hour, int minute, int second, int millisecond) { - Assert.isTrue(0 <= month && month <= 11, "month param must be a value from 0 (January) to 11 (December)"); - Assert.isTrue(1 <= day && day <= 31, "day param must be a value from 1 to 31"); - Assert.isTrue(0 <= hour && hour <= 23, "hour param must be a value from 1 to 23"); - Assert.isTrue(0 <= minute && minute <= 59, "minute param must be a value from 0 to 59"); - Assert.isTrue(0 <= second && second <= 59, "second param must be a value from 0 to 59"); - GregorianCalendar cal = new GregorianCalendar(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DAY_OF_MONTH, day); - cal.set(Calendar.HOUR_OF_DAY, hour); - cal.set(Calendar.MINUTE, minute); - cal.set(Calendar.SECOND, second); - cal.set(Calendar.MILLISECOND, millisecond); - TimeZone fromTimeZone = cal.getTimeZone(); - return new Date(convertDate(cal.getTimeInMillis(), fromTimeZone, UTC_TIMEZONE)); - } - - private static long getTimeZoneOffset(long time, TimeZone from, TimeZone to) { - int fromOffset = from.getOffset(time); - int toOffset = to.getOffset(time); - int diff; - - if (fromOffset >= 0) { - if (toOffset > 0) { - toOffset = -1 * toOffset; - } else { - toOffset = Math.abs(toOffset); - } - diff = (fromOffset + toOffset) * -1; - } else { - if (toOffset <= 0) { - toOffset = -1 * Math.abs(toOffset); - } - diff = (Math.abs(fromOffset) + toOffset); - } - return diff; - } - -} diff --git a/api/src/main/java/com/okta/sdk/lang/Locales.java b/api/src/main/java/com/okta/sdk/lang/Locales.java deleted file mode 100644 index ec21a7208a5..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Locales.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2005-2018 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); 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 com.okta.sdk.lang; - -import java.util.Locale; - -/** - * Imported from Apache Commons Lang. - * - * LocaleUtils.java - * @deprecated use com.okta.commons.lang.Locales - */ -@Deprecated -public final class Locales { - - private Locales() {} - - /** - *

Converts a String to a Locale.

- * - *

This method takes the string format of a locale and creates the - * locale object from it.

- * - *
-     *   LocaleUtils.toLocale("")           = new Locale("", "")
-     *   LocaleUtils.toLocale("en")         = new Locale("en", "")
-     *   LocaleUtils.toLocale("en_GB")      = new Locale("en", "GB")
-     *   LocaleUtils.toLocale("en_001")     = new Locale("en", "001")
-     *   LocaleUtils.toLocale("en_GB_xxx")  = new Locale("en", "GB", "xxx")   (#)
-     * 
- * - *

(#) The behaviour of the JDK variant constructor changed between JDK1.3 and JDK1.4. - * In JDK1.3, the constructor upper cases the variant, in JDK1.4, it doesn't. - * Thus, the result from getVariant() may vary depending on your JDK.

- * - *

This method validates the input strictly. - * The language code must be lowercase. - * The country code must be uppercase. - * The separator must be an underscore. - * The length must be correct. - *

- * - * @param str the locale String to convert, null returns null - * @return a Locale, null if null input - * @throws IllegalArgumentException if the string is an invalid format - * @see Locale#forLanguageTag(String) - */ - public static Locale toLocale(final String str) { - if (str == null) { - return null; - } - if (str.isEmpty()) { // LANG-941 - JDK 8 introduced an empty locale where all fields are blank - return new Locale("", ""); - } - if (str.contains("#")) { // LANG-879 - Cannot handle Java 7 script & extensions - throw new IllegalArgumentException("Invalid locale format: " + str); - } - final int len = str.length(); - if (len < 2) { - throw new IllegalArgumentException("Invalid locale format: " + str); - } - final char ch0 = str.charAt(0); - if (ch0 == '_') { - if (len < 3) { - throw new IllegalArgumentException("Invalid locale format: " + str); - } - final char ch1 = str.charAt(1); - final char ch2 = str.charAt(2); - if (!Character.isUpperCase(ch1) || !Character.isUpperCase(ch2)) { - throw new IllegalArgumentException("Invalid locale format: " + str); - } - if (len == 3) { - return new Locale("", str.substring(1, 3)); - } - if (len < 5) { - throw new IllegalArgumentException("Invalid locale format: " + str); - } - if (str.charAt(3) != '_') { - throw new IllegalArgumentException("Invalid locale format: " + str); - } - return new Locale("", str.substring(1, 3), str.substring(4)); - } - - return parseLocale(str); - } - - /** - * Tries to parse a locale from the given String. - * - * @param str the String to parse a locale from. - * @return a Locale instance parsed from the given String. - * @throws IllegalArgumentException if the given String can not be parsed. - */ - private static Locale parseLocale(final String str) { - if (isISO639LanguageCode(str)) { - return new Locale(str); - } - - final String[] segments = str.split("_", -1); - final String language = segments[0]; - if (segments.length == 2) { - final String country = segments[1]; - if (isISO639LanguageCode(language) && isISO3166CountryCode(country) || - isNumericAreaCode(country)) { - return new Locale(language, country); - } - } else if (segments.length == 3) { - final String country = segments[1]; - final String variant = segments[2]; - if (isISO639LanguageCode(language) && - (country.length() == 0 || isISO3166CountryCode(country) || isNumericAreaCode(country)) && - variant.length() > 0) { - return new Locale(language, country, variant); - } - } - throw new IllegalArgumentException("Invalid locale format: " + str); - } - - /** - * Checks whether the given String is a ISO 639 compliant language code. - * - * @param str the String to check. - * @return true, if the given String is a ISO 639 compliant language code. - */ - private static boolean isISO639LanguageCode(final String str) { - return isAllLowerCase(str) && (str.length() == 2 || str.length() == 3); - } - - /** - * Checks whether the given String is a ISO 3166 alpha-2 country code. - * - * @param str the String to check - * @return true, is the given String is a ISO 3166 compliant country code. - */ - private static boolean isISO3166CountryCode(final String str) { - return isAllUpperCase(str) && str.length() == 2; - } - - /** - * Checks whether the given String is a UN M.49 numeric area code. - * - * @param str the String to check - * @return true, is the given String is a UN M.49 numeric area code. - */ - private static boolean isNumericAreaCode(final String str) { - return isNumeric(str) && str.length() == 3; - } - - private static boolean isAllLowerCase(final CharSequence cs) { - if (cs == null || Strings.isEmpty(cs)) { - return false; - } - final int sz = cs.length(); - for (int i = 0; i < sz; i++) { - if (!Character.isLowerCase(cs.charAt(i))) { - return false; - } - } - return true; - } - - private static boolean isAllUpperCase(final CharSequence cs) { - if (cs == null || Strings.isEmpty(cs)) { - return false; - } - final int sz = cs.length(); - for (int i = 0; i < sz; i++) { - if (!Character.isUpperCase(cs.charAt(i))) { - return false; - } - } - return true; - } - - private static boolean isNumeric(final CharSequence cs) { - if (Strings.isEmpty(cs)) { - return false; - } - final int sz = cs.length(); - for (int i = 0; i < sz; i++) { - if (!Character.isDigit(cs.charAt(i))) { - return false; - } - } - return true; - } -} diff --git a/api/src/main/java/com/okta/sdk/lang/Objects.java b/api/src/main/java/com/okta/sdk/lang/Objects.java deleted file mode 100644 index 5da755e1fc3..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Objects.java +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.lang.reflect.Array; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; - -/** - * Miscellaneous object utility methods. - * - *

Mainly for internal use within the framework. - * - *

Thanks to Alex Ruiz for contributing several enhancements to this class! - * - * Borrowed from the Spring-Framework - * - * @author Juergen Hoeller - * @author Keith Donald - * @author Rod Johnson - * @author Rob Harrop - * @author Chris Beams - * @author Sam Brannen - * @since 19.03.2004 - * @see Classes - * @see Collections - * @see Strings - * @deprecated use com.okta.commons.lang.Objects - */ -@Deprecated -public abstract class Objects { - - private static final int INITIAL_HASH = 7; - private static final int MULTIPLIER = 31; - - private static final String EMPTY_STRING = ""; - private static final String NULL_STRING = "null"; - private static final String ARRAY_START = "{"; - private static final String ARRAY_END = "}"; - private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; - private static final String ARRAY_ELEMENT_SEPARATOR = ", "; - - - /** - * Return whether the given throwable is a checked exception: - * that is, neither a RuntimeException nor an Error. - * @param ex the throwable to check - * @return whether the throwable is a checked exception - * @see java.lang.Exception - * @see java.lang.RuntimeException - * @see java.lang.Error - */ - public static boolean isCheckedException(Throwable ex) { - return !(ex instanceof RuntimeException || ex instanceof Error); - } - - /** - * Check whether the given exception is compatible with the specified - * exception types, as declared in a throws clause. - * @param ex the exception to check - * @param declaredExceptions the exception types declared in the throws clause - * @return whether the given exception is compatible - */ - public static boolean isCompatibleWithThrowsClause(Throwable ex, Class... declaredExceptions) { - if (!isCheckedException(ex)) { - return true; - } - if (declaredExceptions != null) { - for (Class declaredException : declaredExceptions) { - if (declaredException.isInstance(ex)) { - return true; - } - } - } - return false; - } - - /** - * Determine whether the given object is an array: - * either an Object array or a primitive array. - * @param obj the object to check - */ - public static boolean isArray(Object obj) { - return (obj != null && obj.getClass().isArray()); - } - - /** - * Determine whether the given array is empty: - * i.e. {@code null} or of zero length. - * @param array the array to check - * @see #isEmpty(Object) - */ - public static boolean isEmpty(Object[] array) { - return (array == null || array.length == 0); - } - - /** - * Determine whether the given object is empty. - *

This method supports the following object types. - *

    - *
  • {@code Array}: considered empty if its length is zero
  • - *
  • {@link CharSequence}: considered empty if its length is zero
  • - *
  • {@link Collection}: delegates to {@link Collection#isEmpty()}
  • - *
  • {@link Map}: delegates to {@link Map#isEmpty()}
  • - *
- *

If the given object is non-null and not one of the aforementioned - * supported types, this method returns {@code false}. - * @param obj the object to check - * @return {@code true} if the object is {@code null} or empty - * @since 4.2 - * @see Objects#isEmpty(Object[]) - * @see Strings#hasLength(CharSequence) - * @see Strings#isEmpty(Object) - * @see Collections#isEmpty(java.util.Collection) - * @see Collections#isEmpty(java.util.Map) - */ - @SuppressWarnings("rawtypes") - public static boolean isEmpty(Object obj) { - if (obj == null) { - return true; - } - - if (obj instanceof CharSequence) { - return ((CharSequence) obj).length() == 0; - } - if (obj.getClass().isArray()) { - return Array.getLength(obj) == 0; - } - if (obj instanceof Collection) { - return ((Collection) obj).isEmpty(); - } - if (obj instanceof Map) { - return ((Map) obj).isEmpty(); - } - - // else - return false; - } - - /** - * Check whether the given array contains the given element. - * @param array the array to check (may be {@code null}, - * in which case the return value will always be {@code false}) - * @param element the element to check for - * @return whether the element has been found in the given array - */ - public static boolean containsElement(Object[] array, Object element) { - if (array == null) { - return false; - } - for (Object arrayEle : array) { - if (nullSafeEquals(arrayEle, element)) { - return true; - } - } - return false; - } - - /** - * Check whether the given array of enum constants contains a constant with the given name, - * ignoring case when determining a match. - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values() - * @param constant the constant name to find (must not be null or empty string) - * @return whether the constant has been found in the given array - */ - public static boolean containsConstant(Enum[] enumValues, String constant) { - return containsConstant(enumValues, constant, false); - } - - /** - * Check whether the given array of enum constants contains a constant with the given name. - * @param enumValues the enum values to check, typically the product of a call to MyEnum.values() - * @param constant the constant name to find (must not be null or empty string) - * @param caseSensitive whether case is significant in determining a match - * @return whether the constant has been found in the given array - */ - public static boolean containsConstant(Enum[] enumValues, String constant, boolean caseSensitive) { - for (Enum candidate : enumValues) { - if (caseSensitive ? - candidate.toString().equals(constant) : - candidate.toString().equalsIgnoreCase(constant)) { - return true; - } - } - return false; - } - - /** - * Case insensitive alternative to {@link Enum#valueOf(Class, String)}. - * @param the concrete Enum type - * @param enumValues the array of all Enum constants in question, usually per Enum.values() - * @param constant the constant to get the enum value of - * @throws IllegalArgumentException if the given constant is not found in the given array - * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to avoid this exception. - */ - public static > E caseInsensitiveValueOf(E[] enumValues, String constant) { - for (E candidate : enumValues) { - if (candidate.toString().equalsIgnoreCase(constant)) { - return candidate; - } - } - throw new IllegalArgumentException( - String.format("constant [%s] does not exist in enum type %s", - constant, enumValues.getClass().getComponentType().getName())); - } - - /** - * Append the given object to the given array, returning a new array - * consisting of the input array contents plus the given object. - * @param array the array to append to (can be {@code null}) - * @param obj the object to append - * @return the new array (of the same component type; never {@code null}) - */ - public static A[] addObjectToArray(A[] array, O obj) { - Class compType = Object.class; - if (array != null) { - compType = array.getClass().getComponentType(); - } - else if (obj != null) { - compType = obj.getClass(); - } - int newArrLength = (array != null ? array.length + 1 : 1); - @SuppressWarnings("unchecked") - A[] newArr = (A[]) Array.newInstance(compType, newArrLength); - if (array != null) { - System.arraycopy(array, 0, newArr, 0, array.length); - } - newArr[newArr.length - 1] = obj; - return newArr; - } - - /** - * Convert the given array (which may be a primitive array) to an - * object array (if necessary of primitive wrapper objects). - *

A {@code null} source value will be converted to an - * empty Object array. - * @param source the (potentially primitive) array - * @return the corresponding object array (never {@code null}) - * @throws IllegalArgumentException if the parameter is not an array - */ - public static Object[] toObjectArray(Object source) { - if (source instanceof Object[]) { - return (Object[]) source; - } - if (source == null) { - return new Object[0]; - } - if (!source.getClass().isArray()) { - throw new IllegalArgumentException("Source is not an array: " + source); - } - int length = Array.getLength(source); - if (length == 0) { - return new Object[0]; - } - Class wrapperType = Array.get(source, 0).getClass(); - Object[] newArray = (Object[]) Array.newInstance(wrapperType, length); - for (int i = 0; i < length; i++) { - newArray[i] = Array.get(source, i); - } - return newArray; - } - - - //--------------------------------------------------------------------- - // Convenience methods for content-based equality/hash-code handling - //--------------------------------------------------------------------- - - /** - * Determine if the given objects are equal, returning {@code true} if - * both are {@code null} or {@code false} if only one is {@code null}. - *

Compares arrays with {@code Arrays.equals}, performing an equality - * check based on the array elements rather than the array reference. - * @param o1 first Object to compare - * @param o2 second Object to compare - * @return whether the given objects are equal - * @see Object#equals(Object) - * @see java.util.Arrays#equals - */ - public static boolean nullSafeEquals(Object o1, Object o2) { - if (o1 == o2) { - return true; - } - if (o1 == null || o2 == null) { - return false; - } - if (o1.equals(o2)) { - return true; - } - if (o1.getClass().isArray() && o2.getClass().isArray()) { - return arrayEquals(o1, o2); - } - return false; - } - - /** - * Compare the given arrays with {@code Arrays.equals}, performing an equality - * check based on the array elements rather than the array reference. - * @param o1 first array to compare - * @param o2 second array to compare - * @return whether the given objects are equal - * @see #nullSafeEquals(Object, Object) - * @see java.util.Arrays#equals - */ - private static boolean arrayEquals(Object o1, Object o2) { - if (o1 instanceof Object[] && o2 instanceof Object[]) { - return Arrays.equals((Object[]) o1, (Object[]) o2); - } - if (o1 instanceof boolean[] && o2 instanceof boolean[]) { - return Arrays.equals((boolean[]) o1, (boolean[]) o2); - } - if (o1 instanceof byte[] && o2 instanceof byte[]) { - return Arrays.equals((byte[]) o1, (byte[]) o2); - } - if (o1 instanceof char[] && o2 instanceof char[]) { - return Arrays.equals((char[]) o1, (char[]) o2); - } - if (o1 instanceof double[] && o2 instanceof double[]) { - return Arrays.equals((double[]) o1, (double[]) o2); - } - if (o1 instanceof float[] && o2 instanceof float[]) { - return Arrays.equals((float[]) o1, (float[]) o2); - } - if (o1 instanceof int[] && o2 instanceof int[]) { - return Arrays.equals((int[]) o1, (int[]) o2); - } - if (o1 instanceof long[] && o2 instanceof long[]) { - return Arrays.equals((long[]) o1, (long[]) o2); - } - if (o1 instanceof short[] && o2 instanceof short[]) { - return Arrays.equals((short[]) o1, (short[]) o2); - } - return false; - } - - /** - * Return as hash code for the given object; typically the value of - * {@code Object#hashCode()}}. If the object is an array, - * this method will delegate to any of the {@code nullSafeHashCode} - * methods for arrays in this class. If the object is {@code null}, - * this method returns 0. - * @see Object#hashCode() - * @see #nullSafeHashCode(Object[]) - * @see #nullSafeHashCode(boolean[]) - * @see #nullSafeHashCode(byte[]) - * @see #nullSafeHashCode(char[]) - * @see #nullSafeHashCode(double[]) - * @see #nullSafeHashCode(float[]) - * @see #nullSafeHashCode(int[]) - * @see #nullSafeHashCode(long[]) - * @see #nullSafeHashCode(short[]) - */ - public static int nullSafeHashCode(Object obj) { - if (obj == null) { - return 0; - } - if (obj.getClass().isArray()) { - if (obj instanceof Object[]) { - return nullSafeHashCode((Object[]) obj); - } - if (obj instanceof boolean[]) { - return nullSafeHashCode((boolean[]) obj); - } - if (obj instanceof byte[]) { - return nullSafeHashCode((byte[]) obj); - } - if (obj instanceof char[]) { - return nullSafeHashCode((char[]) obj); - } - if (obj instanceof double[]) { - return nullSafeHashCode((double[]) obj); - } - if (obj instanceof float[]) { - return nullSafeHashCode((float[]) obj); - } - if (obj instanceof int[]) { - return nullSafeHashCode((int[]) obj); - } - if (obj instanceof long[]) { - return nullSafeHashCode((long[]) obj); - } - if (obj instanceof short[]) { - return nullSafeHashCode((short[]) obj); - } - } - return obj.hashCode(); - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(Object[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (Object element : array) { - hash = MULTIPLIER * hash + nullSafeHashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(boolean[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (boolean element : array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(byte[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (byte element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(char[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (char element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(double[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (double element : array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(float[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (float element : array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(int[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (int element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(long[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (long element : array) { - hash = MULTIPLIER * hash + hashCode(element); - } - return hash; - } - - /** - * Return a hash code based on the contents of the specified array. - * If {@code array} is {@code null}, this method returns 0. - */ - public static int nullSafeHashCode(short[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (short element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; - } - - /** - * Return the same value as {@link Boolean#hashCode()}}. - * @see Boolean#hashCode() - */ - public static int hashCode(boolean bool) { - return (bool ? 1231 : 1237); - } - - /** - * Return the same value as {@link Double#hashCode()}}. - * @see Double#hashCode() - */ - public static int hashCode(double dbl) { - return hashCode(Double.doubleToLongBits(dbl)); - } - - /** - * Return the same value as {@link Float#hashCode()}}. - * @see Float#hashCode() - */ - public static int hashCode(float flt) { - return Float.floatToIntBits(flt); - } - - /** - * Return the same value as {@link Long#hashCode()}}. - * @see Long#hashCode() - */ - public static int hashCode(long lng) { - return (int) (lng ^ (lng >>> 32)); - } - - - //--------------------------------------------------------------------- - // Convenience methods for toString output - //--------------------------------------------------------------------- - - /** - * Return a String representation of an object's overall identity. - * @param obj the object (may be {@code null}) - * @return the object's identity as String representation, - * or an empty String if the object was {@code null} - */ - public static String identityToString(Object obj) { - if (obj == null) { - return EMPTY_STRING; - } - return obj.getClass().getName() + "@" + getIdentityHexString(obj); - } - - /** - * Return a hex String form of an object's identity hash code. - * @param obj the object - * @return the object's identity code in hex notation - */ - public static String getIdentityHexString(Object obj) { - return Integer.toHexString(System.identityHashCode(obj)); - } - - /** - * Return a content-based String representation if {@code obj} is - * not {@code null}; otherwise returns an empty String. - *

Differs from {@link #nullSafeToString(Object)} in that it returns - * an empty String rather than "null" for a {@code null} value. - * @param obj the object to build a display String for - * @return a display String representation of {@code obj} - * @see #nullSafeToString(Object) - */ - public static String getDisplayString(Object obj) { - if (obj == null) { - return EMPTY_STRING; - } - return nullSafeToString(obj); - } - - /** - * Determine the class name for the given object. - *

Returns {@code "null"} if {@code obj} is {@code null}. - * @param obj the object to introspect (may be {@code null}) - * @return the corresponding class name - */ - public static String nullSafeClassName(Object obj) { - return (obj != null ? obj.getClass().getName() : NULL_STRING); - } - - /** - * Return a String representation of the specified Object. - *

Builds a String representation of the contents in case of an array. - * Returns {@code "null"} if {@code obj} is {@code null}. - * @param obj the object to build a String representation for - * @return a String representation of {@code obj} - */ - public static String nullSafeToString(Object obj) { - if (obj == null) { - return NULL_STRING; - } - if (obj instanceof String) { - return (String) obj; - } - if (obj instanceof Object[]) { - return nullSafeToString((Object[]) obj); - } - if (obj instanceof boolean[]) { - return nullSafeToString((boolean[]) obj); - } - if (obj instanceof byte[]) { - return nullSafeToString((byte[]) obj); - } - if (obj instanceof char[]) { - return nullSafeToString((char[]) obj); - } - if (obj instanceof double[]) { - return nullSafeToString((double[]) obj); - } - if (obj instanceof float[]) { - return nullSafeToString((float[]) obj); - } - if (obj instanceof int[]) { - return nullSafeToString((int[]) obj); - } - if (obj instanceof long[]) { - return nullSafeToString((long[]) obj); - } - if (obj instanceof short[]) { - return nullSafeToString((short[]) obj); - } - String str = obj.toString(); - return (str != null ? str : EMPTY_STRING); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(Object[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(String.valueOf(array[i])); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(boolean[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(byte[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(char[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append("'").append(array[i]).append("'"); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(double[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(float[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(int[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(long[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - - /** - * Return a String representation of the contents of the specified array. - *

The String representation consists of a list of the array's elements, - * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated - * by the characters {@code ", "} (a comma followed by a space). Returns - * {@code "null"} if {@code array} is {@code null}. - * @param array the array to build a String representation for - * @return a String representation of {@code array} - */ - public static String nullSafeToString(short[] array) { - if (array == null) { - return NULL_STRING; - } - int length = array.length; - if (length == 0) { - return EMPTY_ARRAY; - } - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < length; i++) { - if (i == 0) { - sb.append(ARRAY_START); - } - else { - sb.append(ARRAY_ELEMENT_SEPARATOR); - } - sb.append(array[i]); - } - sb.append(ARRAY_END); - return sb.toString(); - } - -} \ No newline at end of file diff --git a/api/src/main/java/com/okta/sdk/lang/Strings.java b/api/src/main/java/com/okta/sdk/lang/Strings.java deleted file mode 100644 index a754a033d5f..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/Strings.java +++ /dev/null @@ -1,1366 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.io.ByteArrayOutputStream; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import java.util.Set; -import java.util.StringTokenizer; -import java.util.TimeZone; - -/** - * Miscellaneous {@link String} utility methods. - * - *

Mainly for internal use within the framework; consider - * Apache's Commons Lang - * for a more comprehensive suite of {@code String} utilities. - * - *

This class delivers some simple functionality that should really be - * provided by the core Java {@link String} and {@link StringBuilder} - * classes. It also provides easy-to-use methods to convert between - * delimited strings, such as CSV strings, and collections and arrays. - * - * Borrowed from the Spring Framework - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Keith Donald - * @author Rob Harrop - * @author Rick Evans - * @author Arjen Poutsma - * @author Sam Brannen - * @author Brian Clozel - * @since 16 April 2001 - * @deprecated use com.okta.commons.lang.Strings - */ -@Deprecated -public abstract class Strings { - - private static final String FOLDER_SEPARATOR = "/"; - - private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; - - private static final String TOP_PATH = ".."; - - private static final String CURRENT_PATH = "."; - - private static final char EXTENSION_SEPARATOR = '.'; - - - //--------------------------------------------------------------------- - // General convenience methods for working with Strings - //--------------------------------------------------------------------- - - /** - * Check whether the given {@code String} is empty. - *

This method accepts any Object as an argument, comparing it to - * {@code null} and the empty String. As a consequence, this method - * will never return {@code true} for a non-null non-String object. - *

The Object signature is useful for general attribute handling code - * that commonly deals with Strings but generally has to iterate over - * Objects since attributes may e.g. be primitive value objects as well. - * @param str the candidate String - * @since 3.2.1 - * @return true if string is empty or null; - */ - public static boolean isEmpty(Object str) { - return (str == null || "".equals(str)); - } - - /** - * Check that the given {@code CharSequence} is neither {@code null} nor - * of length 0. - *

Note: this method returns {@code true} for a {@code CharSequence} - * that purely consists of whitespace. - *

-     * StringUtils.hasLength(null) = false
-     * StringUtils.hasLength("") = false
-     * StringUtils.hasLength(" ") = true
-     * StringUtils.hasLength("Hello") = true
-     * 
- * @param str the {@code CharSequence} to check (may be {@code null}) - * @return {@code true} if the {@code CharSequence} is not {@code null} and has length - * @see #hasText(String) - */ - public static boolean hasLength(CharSequence str) { - return (str != null && str.length() > 0); - } - - /** - * Check that the given {@code String} is neither {@code null} nor of length 0. - *

Note: this method returns {@code true} for a {@code String} that - * purely consists of whitespace. - * @param str the {@code String} to check (may be {@code null}) - * @return {@code true} if the {@code String} is not {@code null} and has length - * @see #hasLength(CharSequence) - * @see #hasText(String) - */ - public static boolean hasLength(String str) { - return hasLength((CharSequence) str); - } - - /** - * Check whether the given {@code CharSequence} contains actual text. - *

More specifically, this method returns {@code true} if the - * {@code CharSequence} is not {@code null}, its length is greater than - * 0, and it contains at least one non-whitespace character. - *

-     * StringUtils.hasText(null) = false
-     * StringUtils.hasText("") = false
-     * StringUtils.hasText(" ") = false
-     * StringUtils.hasText("12345") = true
-     * StringUtils.hasText(" 12345 ") = true
-     * 
- * @param str the {@code CharSequence} to check (may be {@code null}) - * @return {@code true} if the {@code CharSequence} is not {@code null}, - * its length is greater than 0, and it does not contain whitespace only - * @see Character#isWhitespace - */ - public static boolean hasText(CharSequence str) { - if (!hasLength(str)) { - return false; - } - - int strLen = str.length(); - for (int i = 0; i < strLen; i++) { - if (!Character.isWhitespace(str.charAt(i))) { - return true; - } - } - return false; - } - - /** - * Check whether the given {@code String} contains actual text. - *

More specifically, this method returns {@code true} if the - * {@code String} is not {@code null}, its length is greater than 0, - * and it contains at least one non-whitespace character. - * @param str the {@code String} to check (may be {@code null}) - * @return {@code true} if the {@code String} is not {@code null}, its - * length is greater than 0, and it does not contain whitespace only - * @see #hasText(CharSequence) - */ - public static boolean hasText(String str) { - return hasText((CharSequence) str); - } - - /** - * Check whether the given {@code CharSequence} contains any whitespace characters. - * @param str the {@code CharSequence} to check (may be {@code null}) - * @return {@code true} if the {@code CharSequence} is not empty and - * contains at least 1 whitespace character - * @see Character#isWhitespace - */ - public static boolean containsWhitespace(CharSequence str) { - if (!hasLength(str)) { - return false; - } - - int strLen = str.length(); - for (int i = 0; i < strLen; i++) { - if (Character.isWhitespace(str.charAt(i))) { - return true; - } - } - return false; - } - - /** - * Check whether the given {@code String} contains any whitespace characters. - * @param str the {@code String} to check (may be {@code null}) - * @return {@code true} if the {@code String} is not empty and - * contains at least 1 whitespace character - * @see #containsWhitespace(CharSequence) - */ - public static boolean containsWhitespace(String str) { - return containsWhitespace((CharSequence) str); - } - - /** - * Trim leading and trailing whitespace from the given {@code String}. - * @param str the {@code String} to check - * @return the trimmed {@code String} - * @see java.lang.Character#isWhitespace - */ - public static String trimWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { - sb.deleteCharAt(0); - } - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - /** - * Trim all whitespace from the given {@code String}: - * leading, trailing, and in between characters. - * @param str the {@code String} to check - * @return the trimmed {@code String} - * @see java.lang.Character#isWhitespace - */ - public static String trimAllWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - int len = str.length(); - StringBuilder sb = new StringBuilder(str.length()); - for (int i = 0; i < len; i++) { - char c = str.charAt(i); - if (!Character.isWhitespace(c)) { - sb.append(c); - } - } - return sb.toString(); - } - - /** - * Trim leading whitespace from the given {@code String}. - * @param str the {@code String} to check - * @return the trimmed {@code String} - * @see java.lang.Character#isWhitespace - */ - public static String trimLeadingWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { - sb.deleteCharAt(0); - } - return sb.toString(); - } - - /** - * Trim trailing whitespace from the given {@code String}. - * @param str the {@code String} to check - * @return the trimmed {@code String} - * @see java.lang.Character#isWhitespace - */ - public static String trimTrailingWhitespace(String str) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - /** - * Trim all occurrences of the supplied leading character from the given {@code String}. - * @param str the {@code String} to check - * @param leadingCharacter the leading character to be trimmed - * @return the trimmed {@code String} - */ - public static String trimLeadingCharacter(String str, char leadingCharacter) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) { - sb.deleteCharAt(0); - } - return sb.toString(); - } - - /** - * Trim all occurrences of the supplied trailing character from the given {@code String}. - * @param str the {@code String} to check - * @param trailingCharacter the trailing character to be trimmed - * @return the trimmed {@code String} - */ - public static String trimTrailingCharacter(String str, char trailingCharacter) { - if (!hasLength(str)) { - return str; - } - - StringBuilder sb = new StringBuilder(str); - while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) { - sb.deleteCharAt(sb.length() - 1); - } - return sb.toString(); - } - - - /** - * Test if the given {@code String} starts with the specified prefix, - * ignoring upper/lower case. - * @param str the {@code String} to check - * @param prefix the prefix to look for - * @see java.lang.String#startsWith - * @return true if {@code str} stars with {@code prefix} - */ - public static boolean startsWithIgnoreCase(String str, String prefix) { - if (str == null || prefix == null) { - return false; - } - if (str.startsWith(prefix)) { - return true; - } - if (str.length() < prefix.length()) { - return false; - } - - String lcStr = str.substring(0, prefix.length()).toLowerCase(); - String lcPrefix = prefix.toLowerCase(); - return lcStr.equals(lcPrefix); - } - - /** - * Test if the given {@code String} ends with the specified suffix, - * ignoring upper/lower case. - * @param str the {@code String} to check - * @param suffix the suffix to look for - * @see java.lang.String#endsWith - * @return true if {@code str} ends with @{suffix} - */ - public static boolean endsWithIgnoreCase(String str, String suffix) { - if (str == null || suffix == null) { - return false; - } - if (str.endsWith(suffix)) { - return true; - } - if (str.length() < suffix.length()) { - return false; - } - - String lcStr = str.substring(str.length() - suffix.length()).toLowerCase(); - String lcSuffix = suffix.toLowerCase(); - return lcStr.equals(lcSuffix); - } - - /** - * Test whether the given string matches the given substring - * at the given index. - * @param str the original string (or StringBuilder) - * @param index the index in the original string to start matching against - * @param substring the substring to match at the given index - * @return true if substring matches, otherwise false - */ - public static boolean substringMatch(CharSequence str, int index, CharSequence substring) { - for (int j = 0; j < substring.length(); j++) { - int i = index + j; - if (i >= str.length() || str.charAt(i) != substring.charAt(j)) { - return false; - } - } - return true; - } - - /** - * Count the occurrences of the substring {@code sub} in string {@code str}. - * @param str string to search in. Return 0 if this is {@code null}. - * @param sub string to search for. Return 0 if this is {@code null}. - * @return count of {@code sub} - */ - public static int countOccurrencesOf(String str, String sub) { - if (!hasLength(str) || !hasLength(sub)) { - return 0; - } - - int count = 0; - int pos = 0; - int idx; - while ((idx = str.indexOf(sub, pos)) != -1) { - ++count; - pos = idx + sub.length(); - } - return count; - } - - /** - * Replace all occurrences of a substring within a string with - * another string. - * @param inString {@code String} to examine - * @param oldPattern {@code String} to replace - * @param newPattern {@code String} to insert - * @return a {@code String} with the replacements - */ - public static String replace(String inString, String oldPattern, String newPattern) { - if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) { - return inString; - } - int index = inString.indexOf(oldPattern); - if (index == -1) { - // no occurrence -> can return input as-is - return inString; - } - - int capacity = inString.length(); - if (newPattern.length() > oldPattern.length()) { - capacity += 16; - } - StringBuilder sb = new StringBuilder(capacity); - - int pos = 0; // our position in the old string - int patLen = oldPattern.length(); - while (index >= 0) { - sb.append(inString.substring(pos, index)); - sb.append(newPattern); - pos = index + patLen; - index = inString.indexOf(oldPattern, pos); - } - - // append any characters to the right of a match - sb.append(inString.substring(pos)); - return sb.toString(); - } - - /** - * Delete all occurrences of the given substring. - * @param inString the original {@code String} - * @param pattern the pattern to delete all occurrences of - * @return the resulting {@code String} - */ - public static String delete(String inString, String pattern) { - return replace(inString, pattern, ""); - } - - /** - * Delete any character in a given {@code String}. - * @param inString the original {@code String} - * @param charsToDelete a set of characters to delete. - * E.g. "az\n" will delete 'a's, 'z's and new lines. - * @return the resulting {@code String} - */ - public static String deleteAny(String inString, String charsToDelete) { - if (!hasLength(inString) || !hasLength(charsToDelete)) { - return inString; - } - - StringBuilder sb = new StringBuilder(inString.length()); - for (int i = 0; i < inString.length(); i++) { - char c = inString.charAt(i); - if (charsToDelete.indexOf(c) == -1) { - sb.append(c); - } - } - return sb.toString(); - } - - - //--------------------------------------------------------------------- - // Convenience methods for working with formatted Strings - //--------------------------------------------------------------------- - - /** - * Quote the given {@code String} with single quotes. - * @param str the input {@code String} (e.g. "myString") - * @return the quoted {@code String} (e.g. "'myString'"), - * or {@code null} if the input was {@code null} - */ - public static String quote(String str) { - return (str != null ? "'" + str + "'" : null); - } - - /** - * Turn the given Object into a {@code String} with single quotes - * if it is a {@code String}; keeping the Object as-is else. - * @param obj the input Object (e.g. "myString") - * @return the quoted {@code String} (e.g. "'myString'"), - * or the input object as-is if not a {@code String} - */ - public static Object quoteIfString(Object obj) { - return (obj instanceof String ? quote((String) obj) : obj); - } - - /** - * Unqualify a string qualified by a '.' dot character. For example, - * "this.name.is.qualified", returns "qualified". - * @param qualifiedName the qualified name - * @return unqualified string - */ - public static String unqualify(String qualifiedName) { - return unqualify(qualifiedName, '.'); - } - - /** - * Unqualify a string qualified by a separator character. For example, - * "this:name:is:qualified" returns "qualified" if using a ':' separator. - * @param qualifiedName the qualified name - * @param separator the separator - * @return unqualified string - */ - public static String unqualify(String qualifiedName, char separator) { - return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1); - } - - /** - * Capitalize a {@code String}, changing the first letter to - * upper case as per {@link Character#toUpperCase(char)}. - * No other letters are changed. - * @param str the {@code String} to capitalize, may be {@code null} - * @return the capitalized {@code String}, or {@code null} if the supplied - * string is {@code null} - */ - public static String capitalize(String str) { - return changeFirstCharacterCase(str, true); - } - - /** - * Uncapitalize a {@code String}, changing the first letter to - * lower case as per {@link Character#toLowerCase(char)}. - * No other letters are changed. - * @param str the {@code String} to uncapitalize, may be {@code null} - * @return the uncapitalized {@code String}, or {@code null} if the supplied - * string is {@code null} - */ - public static String uncapitalize(String str) { - return changeFirstCharacterCase(str, false); - } - - private static String changeFirstCharacterCase(String str, boolean capitalize) { - if (!hasLength(str)) { - return str; - } - - char baseChar = str.charAt(0); - char updatedChar; - if (capitalize) { - updatedChar = Character.toUpperCase(baseChar); - } - else { - updatedChar = Character.toLowerCase(baseChar); - } - if (baseChar == updatedChar) { - return str; - } - - char[] chars = str.toCharArray(); - chars[0] = updatedChar; - return new String(chars, 0, chars.length); - } - - /** - * Extract the filename from the given Java resource path, - * e.g. {@code "mypath/myfile.txt" -> "myfile.txt"}. - * @param path the file path (may be {@code null}) - * @return the extracted filename, or {@code null} if none - */ - public static String getFilename(String path) { - if (path == null) { - return null; - } - - int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); - return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path); - } - - /** - * Extract the filename extension from the given Java resource path, - * e.g. "mypath/myfile.txt" -> "txt". - * @param path the file path (may be {@code null}) - * @return the extracted filename extension, or {@code null} if none - */ - public static String getFilenameExtension(String path) { - if (path == null) { - return null; - } - - int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR); - if (extIndex == -1) { - return null; - } - - int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (folderIndex > extIndex) { - return null; - } - - return path.substring(extIndex + 1); - } - - /** - * Strip the filename extension from the given Java resource path, - * e.g. "mypath/myfile.txt" -> "mypath/myfile". - * @param path the file path (may be {@code null}) - * @return the path with stripped filename extension, - * or {@code null} if none - */ - public static String stripFilenameExtension(String path) { - if (path == null) { - return null; - } - - int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR); - if (extIndex == -1) { - return path; - } - - int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (folderIndex > extIndex) { - return path; - } - - return path.substring(0, extIndex); - } - - /** - * Apply the given relative path to the given Java resource path, - * assuming standard Java folder separation (i.e. "/" separators). - * @param path the path to start from (usually a full file path) - * @param relativePath the relative path to apply - * (relative to the full file path above) - * @return the full file path that results from applying the relative path - */ - public static String applyRelativePath(String path, String relativePath) { - int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR); - if (separatorIndex != -1) { - String newPath = path.substring(0, separatorIndex); - if (!relativePath.startsWith(FOLDER_SEPARATOR)) { - newPath += FOLDER_SEPARATOR; - } - return newPath + relativePath; - } - else { - return relativePath; - } - } - - /** - * Normalize the path by suppressing sequences like "path/.." and - * inner simple dots. - *

The result is convenient for path comparison. For other uses, - * notice that Windows separators ("\") are replaced by simple slashes. - * @param path the original path - * @return the normalized path - */ - public static String cleanPath(String path) { - if (path == null) { - return null; - } - String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR); - - // Strip prefix from path to analyze, to not treat it as part of the - // first path element. This is necessary to correctly parse paths like - // "file:core/../core/io/Resource.class", where the ".." should just - // strip the first "core" directory while keeping the "file:" prefix. - int prefixIndex = pathToUse.indexOf(":"); - String prefix = ""; - if (prefixIndex != -1) { - prefix = pathToUse.substring(0, prefixIndex + 1); - if (prefix.contains("/")) { - prefix = ""; - } - else { - pathToUse = pathToUse.substring(prefixIndex + 1); - } - } - if (pathToUse.startsWith(FOLDER_SEPARATOR)) { - prefix = prefix + FOLDER_SEPARATOR; - pathToUse = pathToUse.substring(1); - } - - String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR); - List pathElements = new LinkedList<>(); - int tops = 0; - - for (int i = pathArray.length - 1; i >= 0; i--) { - String element = pathArray[i]; - if (CURRENT_PATH.equals(element)) { - // Points to current directory - drop it. - } - else if (TOP_PATH.equals(element)) { - // Registering top path found. - tops++; - } - else { - if (tops > 0) { - // Merging path element with element corresponding to top path. - tops--; - } - else { - // Normal path element found. - pathElements.add(0, element); - } - } - } - - // Remaining top paths need to be retained. - for (int i = 0; i < tops; i++) { - pathElements.add(0, TOP_PATH); - } - - return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR); - } - - /** - * Compare two paths after normalization of them. - * @param path1 first path for comparison - * @param path2 second path for comparison - * @return whether the two paths are equivalent after normalization - */ - public static boolean pathEquals(String path1, String path2) { - return cleanPath(path1).equals(cleanPath(path2)); - } - - /** - * Decode the given encoded URI component value. Based on the following rules: - *

    - *
  • Alphanumeric characters {@code "a"} through {@code "z"}, {@code "A"} through {@code "Z"}, - * and {@code "0"} through {@code "9"} stay the same.
  • - *
  • Special characters {@code "-"}, {@code "_"}, {@code "."}, and {@code "*"} stay the same.
  • - *
  • A sequence "{@code %xy}" is interpreted as a hexadecimal representation of the character.
  • - *
- * @param source the encoded String (may be {@code null}) - * @param charset the character set - * @return the decoded value - * @throws IllegalArgumentException when the given source contains invalid encoded sequences - * @since 5.0 - * @see java.net.URLDecoder#decode(String, String) - */ - public static String uriDecode(String source, Charset charset) { - if (source == null) { - return null; - } - int length = source.length(); - if (length == 0) { - return source; - } - Assert.notNull(charset, "Charset must not be null"); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(length); - boolean changed = false; - for (int i = 0; i < length; i++) { - int ch = source.charAt(i); - if (ch == '%') { - if (i + 2 < length) { - char hex1 = source.charAt(i + 1); - char hex2 = source.charAt(i + 2); - int u = Character.digit(hex1, 16); - int l = Character.digit(hex2, 16); - if (u == -1 || l == -1) { - throw new IllegalArgumentException("Invalid encoded sequence \"" + source.substring(i) + "\""); - } - bos.write((char) ((u << 4) + l)); - i += 2; - changed = true; - } - else { - throw new IllegalArgumentException("Invalid encoded sequence \"" + source.substring(i) + "\""); - } - } - else { - bos.write(ch); - } - } - return (changed ? new String(bos.toByteArray(), charset) : source); - } - - /** - * Parse the given {@code localeString} value into a {@link Locale}. - *

This is the inverse operation of {@link Locale#toString Locale's toString}. - * @param localeString the locale {@code String}, following {@code Locale's} - * {@code toString()} format ("en", "en_UK", etc); - * also accepts spaces as separators, as an alternative to underscores - * @return a corresponding {@code Locale} instance - * @throws IllegalArgumentException in case of an invalid locale specification - */ - public static Locale parseLocaleString(String localeString) { - String[] parts = tokenizeToStringArray(localeString, "_ ", false, false); - String language = (parts.length > 0 ? parts[0] : ""); - String country = (parts.length > 1 ? parts[1] : ""); - - validateLocalePart(language); - validateLocalePart(country); - - String variant = ""; - if (parts.length > 2) { - // There is definitely a variant, and it is everything after the country - // code sans the separator between the country code and the variant. - int endIndexOfCountryCode = localeString.indexOf(country, language.length()) + country.length(); - // Strip off any leading '_' and whitespace, what's left is the variant. - variant = trimLeadingWhitespace(localeString.substring(endIndexOfCountryCode)); - if (variant.startsWith("_")) { - variant = trimLeadingCharacter(variant, '_'); - } - } - return (language.length() > 0 ? new Locale(language, country, variant) : null); - } - - private static void validateLocalePart(String localePart) { - for (int i = 0; i < localePart.length(); i++) { - char ch = localePart.charAt(i); - if (ch != ' ' && ch != '_' && ch != '#' && !Character.isLetterOrDigit(ch)) { - throw new IllegalArgumentException( - "Locale part \"" + localePart + "\" contains invalid characters"); - } - } - } - - /** - * Determine the RFC 3066 compliant language tag, - * as used for the HTTP "Accept-Language" header. - * @param locale the Locale to transform to a language tag - * @return the RFC 3066 compliant language tag as {@code String} - */ - public static String toLanguageTag(Locale locale) { - return locale.getLanguage() + (hasText(locale.getCountry()) ? "-" + locale.getCountry() : ""); - } - - /** - * Parse the given {@code timeZoneString} value into a {@link TimeZone}. - * @param timeZoneString the time zone {@code String}, following {@link TimeZone#getTimeZone(String)} - * but throwing {@link IllegalArgumentException} in case of an invalid time zone specification - * @return a corresponding {@link TimeZone} instance - * @throws IllegalArgumentException in case of an invalid time zone specification - */ - public static TimeZone parseTimeZoneString(String timeZoneString) { - TimeZone timeZone = TimeZone.getTimeZone(timeZoneString); - if ("GMT".equals(timeZone.getID()) && !timeZoneString.startsWith("GMT")) { - // We don't want that GMT fallback... - throw new IllegalArgumentException("Invalid time zone specification '" + timeZoneString + "'"); - } - return timeZone; - } - - - //--------------------------------------------------------------------- - // Convenience methods for working with String arrays - //--------------------------------------------------------------------- - - /** - * Append the given {@code String} to the given {@code String} array, - * returning a new array consisting of the input array contents plus - * the given {@code String}. - * @param array the array to append to (can be {@code null}) - * @param str the {@code String} to append - * @return the new array (never {@code null}) - */ - public static String[] addStringToArray(String[] array, String str) { - if (Objects.isEmpty(array)) { - return new String[] {str}; - } - - String[] newArr = new String[array.length + 1]; - System.arraycopy(array, 0, newArr, 0, array.length); - newArr[array.length] = str; - return newArr; - } - - /** - * Concatenate the given {@code String} arrays into one, - * with overlapping array elements included twice. - *

The order of elements in the original arrays is preserved. - * @param array1 the first array (can be {@code null}) - * @param array2 the second array (can be {@code null}) - * @return the new array ({@code null} if both given arrays were {@code null}) - */ - public static String[] concatenateStringArrays(String[] array1, String[] array2) { - if (Objects.isEmpty(array1)) { - return array2; - } - if (Objects.isEmpty(array2)) { - return array1; - } - - String[] newArr = new String[array1.length + array2.length]; - System.arraycopy(array1, 0, newArr, 0, array1.length); - System.arraycopy(array2, 0, newArr, array1.length, array2.length); - return newArr; - } - - /** - * Merge the given {@code String} arrays into one, with overlapping - * array elements only included once. - *

The order of elements in the original arrays is preserved - * (with the exception of overlapping elements, which are only - * included on their first occurrence). - * @param array1 the first array (can be {@code null}) - * @param array2 the second array (can be {@code null}) - * @return the new array ({@code null} if both given arrays were {@code null}) - */ - public static String[] mergeStringArrays(String[] array1, String[] array2) { - if (Objects.isEmpty(array1)) { - return array2; - } - if (Objects.isEmpty(array2)) { - return array1; - } - - List result = new ArrayList<>(); - result.addAll(Arrays.asList(array1)); - for (String str : array2) { - if (!result.contains(str)) { - result.add(str); - } - } - return toStringArray(result); - } - - /** - * Turn given source {@code String} array into sorted array. - * @param array the source array - * @return the sorted array (never {@code null}) - */ - public static String[] sortStringArray(String[] array) { - if (Objects.isEmpty(array)) { - return new String[0]; - } - - Arrays.sort(array); - return array; - } - - /** - * Copy the given {@code Collection} into a {@code String} array. - *

The {@code Collection} must contain {@code String} elements only. - * @param collection the {@code Collection} to copy - * @return the {@code String} array ({@code null} if the supplied - * {@code Collection} was {@code null}) - */ - public static String[] toStringArray(Collection collection) { - if (collection == null) { - return null; - } - - return collection.toArray(new String[collection.size()]); - } - - /** - * Copy the given Enumeration into a {@code String} array. - * The Enumeration must contain {@code String} elements only. - * @param enumeration the Enumeration to copy - * @return the {@code String} array ({@code null} if the passed-in - * Enumeration was {@code null}) - */ - public static String[] toStringArray(Enumeration enumeration) { - if (enumeration == null) { - return null; - } - - List list = Collections.list(enumeration); - return list.toArray(new String[list.size()]); - } - - /** - * Trim the elements of the given {@code String} array, - * calling {@code String.trim()} on each of them. - * @param array the original {@code String} array - * @return the resulting array (of the same size) with trimmed elements - */ - public static String[] trimArrayElements(String[] array) { - if (Objects.isEmpty(array)) { - return new String[0]; - } - - String[] result = new String[array.length]; - for (int i = 0; i < array.length; i++) { - String element = array[i]; - result[i] = (element != null ? element.trim() : null); - } - return result; - } - - /** - * Remove duplicate strings from the given array. - *

As of 4.2, it preserves the original order, as it uses a {@link LinkedHashSet}. - * @param array the {@code String} array - * @return an array without duplicates, in natural sort order - */ - public static String[] removeDuplicateStrings(String[] array) { - if (Objects.isEmpty(array)) { - return array; - } - - Set set = new LinkedHashSet<>(); - Collections.addAll(set, array); - return toStringArray(set); - } - - /** - * Split a {@code String} at the first occurrence of the delimiter. - * Does not include the delimiter in the result. - * @param toSplit the string to split - * @param delimiter to split the string up with - * @return a two element array with index 0 being before the delimiter, and - * index 1 being after the delimiter (neither element includes the delimiter); - * or {@code null} if the delimiter wasn't found in the given input {@code String} - */ - public static String[] split(String toSplit, String delimiter) { - if (!hasLength(toSplit) || !hasLength(delimiter)) { - return null; - } - int offset = toSplit.indexOf(delimiter); - if (offset < 0) { - return null; - } - - String beforeDelimiter = toSplit.substring(0, offset); - String afterDelimiter = toSplit.substring(offset + delimiter.length()); - return new String[] {beforeDelimiter, afterDelimiter}; - } - - /** - * Take an array of strings and split each element based on the given delimiter. - * A {@code Properties} instance is then generated, with the left of the - * delimiter providing the key, and the right of the delimiter providing the value. - *

Will trim both the key and value before adding them to the - * {@code Properties} instance. - * @param array the array to process - * @param delimiter to split each element using (typically the equals symbol) - * @return a {@code Properties} instance representing the array contents, - * or {@code null} if the array to process was {@code null} or empty - */ - public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) { - return splitArrayElementsIntoProperties(array, delimiter, null); - } - - /** - * Take an array of strings and split each element based on the given delimiter. - * A {@code Properties} instance is then generated, with the left of the - * delimiter providing the key, and the right of the delimiter providing the value. - *

Will trim both the key and value before adding them to the - * {@code Properties} instance. - * @param array the array to process - * @param delimiter to split each element using (typically the equals symbol) - * @param charsToDelete one or more characters to remove from each element - * prior to attempting the split operation (typically the quotation mark - * symbol), or {@code null} if no removal should occur - * @return a {@code Properties} instance representing the array contents, - * or {@code null} if the array to process was {@code null} or empty - */ - public static Properties splitArrayElementsIntoProperties( - String[] array, String delimiter, String charsToDelete) { - - if (Objects.isEmpty(array)) { - return null; - } - - Properties result = new Properties(); - for (String element : array) { - if (charsToDelete != null) { - element = deleteAny(element, charsToDelete); - } - String[] splittedElement = split(element, delimiter); - if (splittedElement == null) { - continue; - } - result.setProperty(splittedElement[0].trim(), splittedElement[1].trim()); - } - return result; - } - - /** - * Tokenize the given {@code String} into a {@code String} array via a - * {@link StringTokenizer}. - *

Trims tokens and omits empty tokens. - *

The given {@code delimiters} string can consist of any number of - * delimiter characters. Each of those characters can be used to separate - * tokens. A delimiter is always a single character; for multi-character - * delimiters, consider using {@link #delimitedListToStringArray}. - * @param str the {@code String} to tokenize - * @param delimiters the delimiter characters, assembled as a {@code String} - * (each of the characters is individually considered as a delimiter) - * @return an array of the tokens - * @see java.util.StringTokenizer - * @see String#trim() - * @see #delimitedListToStringArray - */ - public static String[] tokenizeToStringArray(String str, String delimiters) { - return tokenizeToStringArray(str, delimiters, true, true); - } - - /** - * Tokenize the given {@code String} into a {@code String} array via a - * {@link StringTokenizer}. - *

The given {@code delimiters} string can consist of any number of - * delimiter characters. Each of those characters can be used to separate - * tokens. A delimiter is always a single character; for multi-character - * delimiters, consider using {@link #delimitedListToStringArray}. - * @param str the {@code String} to tokenize - * @param delimiters the delimiter characters, assembled as a {@code String} - * (each of the characters is individually considered as a delimiter) - * @param trimTokens trim the tokens via {@link String#trim()} - * @param ignoreEmptyTokens omit empty tokens from the result array - * (only applies to tokens that are empty after trimming; StringTokenizer - * will not consider subsequent delimiters as token in the first place). - * @return an array of the tokens ({@code null} if the input {@code String} - * was {@code null}) - * @see java.util.StringTokenizer - * @see String#trim() - * @see #delimitedListToStringArray - */ - public static String[] tokenizeToStringArray( - String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) { - - if (str == null) { - return null; - } - - StringTokenizer st = new StringTokenizer(str, delimiters); - List tokens = new ArrayList<>(); - while (st.hasMoreTokens()) { - String token = st.nextToken(); - if (trimTokens) { - token = token.trim(); - } - if (!ignoreEmptyTokens || token.length() > 0) { - tokens.add(token); - } - } - return toStringArray(tokens); - } - - /** - * Take a {@code String} that is a delimited list and convert it into a - * {@code String} array. - *

A single {@code delimiter} may consist of more than one character, - * but it will still be considered as a single delimiter string, rather - * than as bunch of potential delimiter characters, in contrast to - * {@link #tokenizeToStringArray}. - * @param str the input {@code String} - * @param delimiter the delimiter between elements (this is a single delimiter, - * rather than a bunch individual delimiter characters) - * @return an array of the tokens in the list - * @see #tokenizeToStringArray - */ - public static String[] delimitedListToStringArray(String str, String delimiter) { - return delimitedListToStringArray(str, delimiter, null); - } - - /** - * Take a {@code String} that is a delimited list and convert it into - * a {@code String} array. - *

A single {@code delimiter} may consist of more than one character, - * but it will still be considered as a single delimiter string, rather - * than as bunch of potential delimiter characters, in contrast to - * {@link #tokenizeToStringArray}. - * @param str the input {@code String} - * @param delimiter the delimiter between elements (this is a single delimiter, - * rather than a bunch individual delimiter characters) - * @param charsToDelete a set of characters to delete; useful for deleting unwanted - * line breaks: e.g. "\r\n\f" will delete all new lines and line feeds in a {@code String} - * @return an array of the tokens in the list - * @see #tokenizeToStringArray - */ - public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) { - if (str == null) { - return new String[0]; - } - if (delimiter == null) { - return new String[] {str}; - } - - List result = new ArrayList<>(); - if ("".equals(delimiter)) { - for (int i = 0; i < str.length(); i++) { - result.add(deleteAny(str.substring(i, i + 1), charsToDelete)); - } - } - else { - int pos = 0; - int delPos; - while ((delPos = str.indexOf(delimiter, pos)) != -1) { - result.add(deleteAny(str.substring(pos, delPos), charsToDelete)); - pos = delPos + delimiter.length(); - } - if (str.length() > 0 && pos <= str.length()) { - // Add rest of String, but not in case of empty input. - result.add(deleteAny(str.substring(pos), charsToDelete)); - } - } - return toStringArray(result); - } - - /** - * Convert a comma delimited list (e.g., a row from a CSV file) into an - * array of strings. - * @param str the input {@code String} - * @return an array of strings, or the empty array in case of empty input - */ - public static String[] commaDelimitedListToStringArray(String str) { - return delimitedListToStringArray(str, ","); - } - - /** - * Convert a comma delimited list (e.g., a row from a CSV file) into a set. - *

Note that this will suppress duplicates, and as of 4.2, the elements in - * the returned set will preserve the original order in a {@link LinkedHashSet}. - * @param str the input {@code String} - * @return a set of {@code String} entries in the list - * @see #removeDuplicateStrings(String[]) - */ - public static Set commaDelimitedListToSet(String str) { - Set set = new LinkedHashSet<>(); - String[] tokens = commaDelimitedListToStringArray(str); - Collections.addAll(set, tokens); - return set; - } - - /** - * Convert a {@link Collection} to a delimited {@code String} (e.g. CSV). - *

Useful for {@code toString()} implementations. - * @param coll the {@code Collection} to convert - * @param delim the delimiter to use (typically a ",") - * @param prefix the {@code String} to start each element with - * @param suffix the {@code String} to end each element with - * @return the delimited {@code String} - */ - public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) { - if (com.okta.sdk.lang.Collections.isEmpty(coll)) { - return ""; - } - - StringBuilder sb = new StringBuilder(); - Iterator it = coll.iterator(); - while (it.hasNext()) { - sb.append(prefix).append(it.next()).append(suffix); - if (it.hasNext()) { - sb.append(delim); - } - } - return sb.toString(); - } - - /** - * Convert a {@code Collection} into a delimited {@code String} (e.g. CSV). - *

Useful for {@code toString()} implementations. - * @param coll the {@code Collection} to convert - * @param delim the delimiter to use (typically a ",") - * @return the delimited {@code String} - */ - public static String collectionToDelimitedString(Collection coll, String delim) { - return collectionToDelimitedString(coll, delim, "", ""); - } - - /** - * Convert a {@code Collection} into a delimited {@code String} (e.g., CSV). - *

Useful for {@code toString()} implementations. - * @param coll the {@code Collection} to convert - * @return the delimited {@code String} - */ - public static String collectionToCommaDelimitedString(Collection coll) { - return collectionToDelimitedString(coll, ","); - } - - /** - * Convert a {@code String} array into a delimited {@code String} (e.g. CSV). - *

Useful for {@code toString()} implementations. - * @param arr the array to display - * @param delim the delimiter to use (typically a ",") - * @return the delimited {@code String} - */ - public static String arrayToDelimitedString(Object[] arr, String delim) { - if (Objects.isEmpty(arr)) { - return ""; - } - if (arr.length == 1) { - return Objects.nullSafeToString(arr[0]); - } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < arr.length; i++) { - if (i > 0) { - sb.append(delim); - } - sb.append(arr[i]); - } - return sb.toString(); - } - - /** - * Convert a {@code String} array into a comma delimited {@code String} - * (i.e., CSV). - *

Useful for {@code toString()} implementations. - * @param arr the array to display - * @return the delimited {@code String} - */ - public static String arrayToCommaDelimitedString(Object[] arr) { - return arrayToDelimitedString(arr, ","); - } - - /** - * Returns a 'cleaned' representation of the specified argument. 'Cleaned' is defined as the following: - *

    - *
  1. If the specified {@code String} is null, return null
  2. - *
  3. If not {@code null}, {@link String#trim() trim()} it.
  4. - *
  5. If the trimmed string is equal to the empty String (i.e. ""), return {@code null}
  6. - *
  7. If the trimmed string is not the empty string, return the trimmed version
  8. - *
- *

- * Therefore this method always ensures that any given string has trimmed text, and if it doesn't, {@code null} - * is returned. - * - * @param s the input String to clean. - * @return a populated-but-trimmed String or {@code null} otherwise - */ - public static String clean(String s) { - if (s == null) { - return null; - } - String value = trimWhitespace(s); - if (value == null || "".equals(value)) { - return null; - } - return value; - } - - /** - * Calls {@link String#getBytes(Charset)} - * - * @param string The string to encode (if null, return null). - * @param charset The {@link Charset} to encode the {@code String} - * @return the encoded bytes - */ - private static byte[] getBytes(final String string, final Charset charset) { - if (string == null) { - return null; - } - return string.getBytes(charset); - } - - /** - * Encodes the given string into a sequence of bytes using the UTF-8 charset, storing the result into a new byte - * array. - * - * @param string the String to encode, may be {@code null} - * @return encoded bytes, or {@code null} if the input string was null - * @throws NullPointerException Thrown if {@link StandardCharsets#UTF_8} is not initialized, which should never happen since it is - * required by the Java platform specification. - * @see Standard charsets - */ - public static byte[] getBytesUtf8(final String string) { - return getBytes(string, StandardCharsets.UTF_8); - } - -} diff --git a/api/src/main/java/com/okta/sdk/lang/UnknownClassException.java b/api/src/main/java/com/okta/sdk/lang/UnknownClassException.java deleted file mode 100644 index 13244c2e1ae..00000000000 --- a/api/src/main/java/com/okta/sdk/lang/UnknownClassException.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -/** - * A {@code RuntimeException} equivalent of the JDK's - * {@code ClassNotFoundException}, to maintain a RuntimeException paradigm. - * - * @since 0.5.0 - * @deprecated use com.okta.commons.lang.UnknownClassException - */ -@Deprecated -public class UnknownClassException extends com.okta.commons.lang.UnknownClassException { - - /** - * Creates a new UnknownClassException. - */ - public UnknownClassException() { - super(); - } - - /** - * Constructs a new UnknownClassException. - * - * @param message the reason for the exception - */ - public UnknownClassException(String message) { - super(message); - } - - /** - * Constructs a new UnknownClassException. - * - * @param cause the underlying Throwable that caused this exception to be thrown. - */ - public UnknownClassException(Throwable cause) { - super(cause); - } - - /** - * Constructs a new UnknownClassException. - * - * @param message the reason for the exception - * @param cause the underlying Throwable that caused this exception to be thrown. - */ - public UnknownClassException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/api/src/main/java/com/okta/sdk/resource/event/hook/EventHookBuilder.java b/api/src/main/java/com/okta/sdk/resource/event/hook/EventHookBuilder.java new file mode 100644 index 00000000000..74f5fab16c6 --- /dev/null +++ b/api/src/main/java/com/okta/sdk/resource/event/hook/EventHookBuilder.java @@ -0,0 +1,35 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.resource.event.hook; + +import com.okta.commons.lang.Classes; +import com.okta.sdk.client.Client; + +public interface EventHookBuilder { + EventHookBuilder setName(String name); + + EventHookBuilder setUrl(String url); + + EventHookBuilder setAuthorizationHeaderValue(String authorizationHeaderValue); + + EventHookBuilder addHeader(String name, String value); + + EventHook buildAndCreate(Client client); + + static EventHookBuilder instance() { + return Classes.newInstance("com.okta.sdk.impl.resource.event.hook.DefaultEventHookBuilder"); + } +} diff --git a/api/src/main/java/com/okta/sdk/resource/group/rule/GroupRuleBuilder.java b/api/src/main/java/com/okta/sdk/resource/group/rule/GroupRuleBuilder.java index 28a02d8ad09..3e6bccbc47d 100644 --- a/api/src/main/java/com/okta/sdk/resource/group/rule/GroupRuleBuilder.java +++ b/api/src/main/java/com/okta/sdk/resource/group/rule/GroupRuleBuilder.java @@ -30,8 +30,6 @@ public interface GroupRuleBuilder { GroupRuleBuilder setType(String type); - GroupRuleBuilder setAllGroupsValid(Boolean allGroupsValid); - GroupRuleBuilder setAssignUserToGroups(List assignUserToGroups); default GroupRuleBuilder setGroups(String... groupIds) { diff --git a/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilder.java b/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilder.java new file mode 100644 index 00000000000..effc8378ece --- /dev/null +++ b/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.policy.PolicySubjectMatchType; + +import java.util.List; + +public interface IdentityProviderBuilder { + + T setName(String name); + + T setClientId(String clientId); + + T setClientSecret(String clientSecret); + + T setScopes(List scopes); + + T setMaxClockSkew(Integer maxClockSkew); + + T setUserName(String userName); + + T setMatchType(PolicySubjectMatchType policySubjectMatchType); + + T setIsProfileMaster(Boolean isProfileMaster); + + T isProfileMaster(Boolean isProfileMaster); + + IdentityProvider buildAndCreate(Client client); +} diff --git a/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilders.java b/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilders.java new file mode 100644 index 00000000000..4441b8c1dc0 --- /dev/null +++ b/api/src/main/java/com/okta/sdk/resource/identity/provider/IdentityProviderBuilders.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.resource.identity.provider; + +import com.okta.commons.lang.Classes; + +public class IdentityProviderBuilders { + + public static OIDCIdentityProviderBuilder oidc() { + return Classes.newInstance("com.okta.sdk.impl.resource.identity.provider.OidcIdentityProviderBuilder"); + } + + public static IdentityProviderBuilder google() { + return Classes.newInstance("com.okta.sdk.impl.resource.identity.provider.GoogleIdentityProviderBuilder"); + } + + public static IdentityProviderBuilder facebook() { + return Classes.newInstance("com.okta.sdk.impl.resource.identity.provider.FacebookIdentityProviderBuilder"); + } + + public static IdentityProviderBuilder microsoft() { + return Classes.newInstance("com.okta.sdk.impl.resource.identity.provider.MicrosoftIdentityProviderBuilder"); + } + + public static IdentityProviderBuilder linkedin() { + return Classes.newInstance("com.okta.sdk.impl.resource.identity.provider.LinkedInIdentityProviderBuilder"); + } +} diff --git a/api/src/main/java/com/okta/sdk/resource/identity/provider/OIDCIdentityProviderBuilder.java b/api/src/main/java/com/okta/sdk/resource/identity/provider/OIDCIdentityProviderBuilder.java new file mode 100644 index 00000000000..d17a97a0dd7 --- /dev/null +++ b/api/src/main/java/com/okta/sdk/resource/identity/provider/OIDCIdentityProviderBuilder.java @@ -0,0 +1,57 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.resource.identity.provider; + +import com.okta.sdk.resource.policy.PolicySubjectMatchType; + +public interface OIDCIdentityProviderBuilder extends IdentityProviderBuilder { + + OIDCIdentityProviderBuilder setIssuerMode(IdentityProvider.IssuerModeEnum issuerMode); + + OIDCIdentityProviderBuilder setRequestSignatureAlgorithm(String requestSignatureAlgorithm); + + OIDCIdentityProviderBuilder setRequestSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum requestSignatureScope); + + OIDCIdentityProviderBuilder setResponseSignatureAlgorithm(String responseSignatureAlgorithm); + + OIDCIdentityProviderBuilder setResponseSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum responseSignatureScope); + + OIDCIdentityProviderBuilder setAcsEndpointBinding(ProtocolEndpoint.BindingEnum acsEndpointBinding); + + OIDCIdentityProviderBuilder setAcsEndpointType(ProtocolEndpoint.TypeEnum acsEndpointType); + + OIDCIdentityProviderBuilder setAuthorizationEndpointBinding(ProtocolEndpoint.BindingEnum authorizationEndpointBinding); + + OIDCIdentityProviderBuilder setAuthorizationEndpointUrl(String authorizationEndpointUrl); + + OIDCIdentityProviderBuilder setTokenEndpointBinding(ProtocolEndpoint.BindingEnum tokenEndpointBinding); + + OIDCIdentityProviderBuilder setTokenEndpointUrl(String tokenEndpointUrl); + + OIDCIdentityProviderBuilder setUserInfoEndpointBinding(ProtocolEndpoint.BindingEnum userInfoEndpointBinding); + + OIDCIdentityProviderBuilder setUserInfoEndpointUrl(String userInfoEndpointUrl); + + OIDCIdentityProviderBuilder setJwksEndpointBinding(ProtocolEndpoint.BindingEnum jwksEndpointBinding); + + OIDCIdentityProviderBuilder setJwksEndpointUrl(String jwksEndpointUrl); + + OIDCIdentityProviderBuilder setIssuerUrl(String issuerUrl); + + OIDCIdentityProviderBuilder setUserName(String userName); + + OIDCIdentityProviderBuilder setMatchType(PolicySubjectMatchType matchType); +} diff --git a/api/src/main/java/com/okta/sdk/resource/inline/hook/InlineHookBuilder.java b/api/src/main/java/com/okta/sdk/resource/inline/hook/InlineHookBuilder.java new file mode 100644 index 00000000000..1ff51c9045d --- /dev/null +++ b/api/src/main/java/com/okta/sdk/resource/inline/hook/InlineHookBuilder.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.resource.inline.hook; + +import com.okta.commons.lang.Classes; +import com.okta.sdk.client.Client; + +public interface InlineHookBuilder { + + InlineHookBuilder setName(String name); + + InlineHookBuilder setHookType(InlineHookType hookType); + + InlineHookBuilder setChannelType(InlineHookChannel.TypeEnum channelType); + + InlineHookBuilder setUrl(String url); + + InlineHookBuilder setAuthorizationHeaderValue(String authorizationHeaderValue); + + InlineHookBuilder addHeader(String name, String value); + + InlineHook buildAndCreate(Client client); + + static InlineHookBuilder instance() { + return Classes.newInstance("com.okta.sdk.impl.resource.inline.hook.DefaultInlineHookBuilder"); + } +} \ No newline at end of file diff --git a/api/src/main/java/com/okta/sdk/resource/policy/rule/PolicyRuleBuilder.java b/api/src/main/java/com/okta/sdk/resource/policy/rule/PolicyRuleBuilder.java index 905934a870a..9be864a906d 100644 --- a/api/src/main/java/com/okta/sdk/resource/policy/rule/PolicyRuleBuilder.java +++ b/api/src/main/java/com/okta/sdk/resource/policy/rule/PolicyRuleBuilder.java @@ -26,8 +26,6 @@ static PolicyRuleBuilder instance(){ return Classes.newInstance("com.okta.sdk.impl.resource.DefaultPolicyRuleBuilder"); } - T setId(String id); - T setPriority(Integer priority); T setStatus(PolicyRule.StatusEnum status); diff --git a/api/src/test/java/com/okta/sdk/lang/CollectionsTest.java b/api/src/test/java/com/okta/sdk/lang/CollectionsTest.java deleted file mode 100644 index 65164f116d8..00000000000 --- a/api/src/test/java/com/okta/sdk/lang/CollectionsTest.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2002-2016 the original author or authors. - * Modifications Copyright 2017 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import org.testng.annotations.Test; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import static org.testng.AssertJUnit.*; - -/** - * @author Rob Harrop - * @author Juergen Hoeller - * @author Rick Evans - */ -public class CollectionsTest { - - @Test - public void testIsEmpty() { - assertTrue(Collections.isEmpty((Set) null)); - assertTrue(Collections.isEmpty((Map) null)); - assertTrue(Collections.isEmpty(new HashMap())); - assertTrue(Collections.isEmpty(new HashSet<>())); - - List list = new LinkedList<>(); - list.add(new Object()); - assertFalse(Collections.isEmpty(list)); - - Map map = new HashMap<>(); - map.put("foo", "bar"); - assertFalse(Collections.isEmpty(map)); - } - - @Test - public void testMergeArrayIntoCollection() { - Object[] arr = new Object[] {"value1", "value2"}; - List> list = new LinkedList<>(); - list.add("value3"); - - Collections.mergeArrayIntoCollection(arr, list); - assertEquals("value3", list.get(0)); - assertEquals("value1", list.get(1)); - assertEquals("value2", list.get(2)); - } - - @Test - public void testMergePrimitiveArrayIntoCollection() { - int[] arr = new int[] {1, 2}; - List> list = new LinkedList<>(); - list.add(new Integer(3)); - - Collections.mergeArrayIntoCollection(arr, list); - assertEquals(new Integer(3), list.get(0)); - assertEquals(new Integer(1), list.get(1)); - assertEquals(new Integer(2), list.get(2)); - } - - @Test - public void testMergePropertiesIntoMap() { - Properties defaults = new Properties(); - defaults.setProperty("prop1", "value1"); - Properties props = new Properties(defaults); - props.setProperty("prop2", "value2"); - props.put("prop3", new Integer(3)); - - Map map = new HashMap<>(); - map.put("prop4", "value4"); - - Collections.mergePropertiesIntoMap(props, map); - assertEquals("value1", map.get("prop1")); - assertEquals("value2", map.get("prop2")); - assertEquals(new Integer(3), map.get("prop3")); - assertEquals("value4", map.get("prop4")); - } - - @Test - public void testContains() { - assertFalse(Collections.contains((Iterator) null, "myElement")); - assertFalse(Collections.contains((Enumeration) null, "myElement")); - assertFalse(Collections.contains(new LinkedList().iterator(), "myElement")); - assertFalse(Collections.contains(new Hashtable().keys(), "myElement")); - - List list = new LinkedList<>(); - list.add("myElement"); - assertTrue(Collections.contains(list.iterator(), "myElement")); - - Hashtable ht = new Hashtable<>(); - ht.put("myElement", "myValue"); - assertTrue(Collections.contains(ht.keys(), "myElement")); - } - - @Test - public void testContainsAny() throws Exception { - List source = new ArrayList<>(); - source.add("abc"); - source.add("def"); - source.add("ghi"); - - List candidates = new ArrayList<>(); - candidates.add("xyz"); - candidates.add("def"); - candidates.add("abc"); - - assertTrue(Collections.containsAny(source, candidates)); - candidates.remove("def"); - assertTrue(Collections.containsAny(source, candidates)); - candidates.remove("abc"); - assertFalse(Collections.containsAny(source, candidates)); - } - - @Test - public void testContainsInstanceWithNullCollection() throws Exception { - assertFalse("Must return false if supplied Collection argument is null", - Collections.containsInstance(null, this)); - } - - @Test - public void testContainsInstanceWithInstancesThatAreEqualButDistinct() throws Exception { - List list = new ArrayList<>(); - list.add(new Instance("fiona")); - assertFalse("Must return false if instance is not in the supplied Collection argument", - Collections.containsInstance(list, new Instance("fiona"))); - } - - @Test - public void testContainsInstanceWithSameInstance() throws Exception { - List list = new ArrayList<>(); - list.add(new Instance("apple")); - Instance instance = new Instance("fiona"); - list.add(instance); - assertTrue("Must return true if instance is in the supplied Collection argument", - Collections.containsInstance(list, instance)); - } - - @Test - public void testContainsInstanceWithNullInstance() throws Exception { - List list = new ArrayList<>(); - list.add(new Instance("apple")); - list.add(new Instance("fiona")); - assertFalse("Must return false if null instance is supplied", - Collections.containsInstance(list, null)); - } - - @Test - public void testFindFirstMatch() throws Exception { - List source = new ArrayList<>(); - source.add("abc"); - source.add("def"); - source.add("ghi"); - - List candidates = new ArrayList<>(); - candidates.add("xyz"); - candidates.add("def"); - candidates.add("abc"); - - assertEquals("def", Collections.findFirstMatch(source, candidates)); - } - - @Test - public void testHasUniqueObject() { - List list = new LinkedList<>(); - list.add("myElement"); - list.add("myOtherElement"); - assertFalse(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - list.add("myElement"); - assertTrue(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - list.add("myElement"); - list.add(null); - assertFalse(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - list.add(null); - list.add("myElement"); - assertFalse(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - list.add(null); - list.add(null); - assertTrue(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - list.add(null); - assertTrue(Collections.hasUniqueObject(list)); - - list = new LinkedList<>(); - assertFalse(Collections.hasUniqueObject(list)); - } - - - private static final class Instance { - - private final String name; - - public Instance(String name) { - this.name = name; - } - - @Override - public boolean equals(Object rhs) { - if (this == rhs) { - return true; - } - if (rhs == null || this.getClass() != rhs.getClass()) { - return false; - } - Instance instance = (Instance) rhs; - return this.name.equals(instance.name); - } - - @Override - public int hashCode() { - return this.name.hashCode(); - } - } - - @Test - public void testEmptyList() { - - List list1 = Collections.toList((Collection)null); - assertTrue(list1 instanceof List); - assertTrue(list1.size() == 0); - - List list2 = Collections.toList(); - assertTrue(list2 instanceof List); - assertTrue(list2.size() == 0); - - } - -} \ No newline at end of file diff --git a/api/src/test/java/com/okta/sdk/lang/LocalesTest.java b/api/src/test/java/com/okta/sdk/lang/LocalesTest.java deleted file mode 100644 index 2f093fd8025..00000000000 --- a/api/src/test/java/com/okta/sdk/lang/LocalesTest.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2005-2018 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); 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 com.okta.sdk.lang; - -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.AssertJUnit.fail; - -import java.util.Arrays; -import java.util.Locale; - -/** - * Unit tests for {@link Locales}. - */ -public class LocalesTest { - - //----------------------------------------------------------------------- - /** - * Pass in a valid language, test toLocale. - * - * @param language the language string - */ - private static void assertValidToLocale(final String language) { - final Locale locale = Locales.toLocale(language); - assertNotNull("valid locale", locale); - assertEquals(language, locale.getLanguage()); - //country and variant are empty - assertTrue(locale.getCountry() == null || locale.getCountry().isEmpty()); - assertTrue(locale.getVariant() == null || locale.getVariant().isEmpty()); - } - - /** - * Pass in a valid language, test toLocale. - * - * @param localeString to pass to toLocale() - * @param language of the resulting Locale - * @param country of the resulting Locale - */ - private static void assertValidToLocale(final String localeString, final String language, final String country) { - final Locale locale = Locales.toLocale(localeString); - assertNotNull("valid locale", locale); - assertEquals(language, locale.getLanguage()); - assertEquals(country, locale.getCountry()); - //variant is empty - assertTrue(locale.getVariant() == null || locale.getVariant().isEmpty()); - } - - /** - * Pass in a valid language, test toLocale. - * - * @param localeString to pass to toLocale() - * @param language of the resulting Locale - * @param country of the resulting Locale - * @param variant of the resulting Locale - */ - private static void assertValidToLocale( - final String localeString, final String language, - final String country, final String variant) { - final Locale locale = Locales.toLocale(localeString); - assertNotNull("valid locale", locale); - assertEquals(language, locale.getLanguage()); - assertEquals(country, locale.getCountry()); - assertEquals(variant, locale.getVariant()); - } - - /** - * Test toLocale() method. - */ - @Test - public void testToLocale_1Part() { - assertNull(Locales.toLocale(null)); - - assertValidToLocale("us"); - assertValidToLocale("fr"); - assertValidToLocale("de"); - assertValidToLocale("zh"); - // Valid format but lang doesn't exist, should make instance anyway - assertValidToLocale("qq"); - // LANG-941: JDK 8 introduced the empty locale as one of the default locales - assertValidToLocale(""); - - try { - Locales.toLocale("Us"); - fail("Should fail if not lowercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("US"); - fail("Should fail if not lowercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("uS"); - fail("Should fail if not lowercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("u#"); - fail("Should fail if not lowercase"); - } catch (final IllegalArgumentException iae) {} - - try { - Locales.toLocale("u"); - fail("Must be 2 chars if less than 5"); - } catch (final IllegalArgumentException iae) {} - - try { - Locales.toLocale("uu_U"); - fail("Must be 2 chars if less than 5"); - } catch (final IllegalArgumentException iae) {} - } - - /** - * Test toLocale() method. - */ - @Test - public void testToLocale_2Part() { - assertValidToLocale("us_EN", "us", "EN"); - //valid though doesn't exist - assertValidToLocale("us_ZH", "us", "ZH"); - - try { - Locales.toLocale("us-EN"); - fail("Should fail as not underscore"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("us_En"); - fail("Should fail second part not uppercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("us_en"); - fail("Should fail second part not uppercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("us_eN"); - fail("Should fail second part not uppercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("uS_EN"); - fail("Should fail first part not lowercase"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("us_E3"); - fail("Should fail second part not uppercase"); - } catch (final IllegalArgumentException iae) {} - } - - /** - * Test toLocale() method. - */ - @Test - public void testToLocale_3Part() { - assertValidToLocale("us_EN_A", "us", "EN", "A"); - assertValidToLocale("us_EN_a", "us", "EN", "a"); - assertValidToLocale("us_EN_SFsafdFDsdfF", "us", "EN", "SFsafdFDsdfF"); - - try { - Locales.toLocale("us_EN-a"); - fail("Should fail as not underscore"); - } catch (final IllegalArgumentException iae) {} - try { - Locales.toLocale("uu_UU_"); - fail("Must be 3, 5 or 7+ in length"); - } catch (final IllegalArgumentException iae) {} - } - - /** - * Test for 3-chars locale, further details at LANG-915 - * - */ - @Test - public void testThreeCharsLocale() { - for (final String str : Arrays.asList("udm", "tet")) { - final Locale locale = Locales.toLocale(str); - assertNotNull(locale); - assertEquals(str, locale.getLanguage()); - assertTrue(Strings.isEmpty(locale.getCountry())); - assertEquals(new Locale(str), locale); - } - } - - /** - * Tests #LANG-328 - only language+variant - */ - @Test - public void testLang328() { - assertValidToLocale("fr__P", "fr", "", "P"); - assertValidToLocale("fr__POSIX", "fr", "", "POSIX"); - } - - @Test - public void testLanguageAndUNM49Numeric3AreaCodeLang1312() { - assertValidToLocale("en_001", "en", "001"); - assertValidToLocale("en_150", "en", "150"); - assertValidToLocale("ar_001", "ar", "001"); - - // LANG-1312 - assertValidToLocale("en_001_GB", "en", "001", "GB"); - assertValidToLocale("en_150_US", "en", "150", "US"); - } - - /** - * Tests #LANG-865, strings starting with an underscore. - */ - @Test - public void testLang865() { - assertValidToLocale("_GB", "", "GB", ""); - assertValidToLocale("_GB_P", "", "GB", "P"); - assertValidToLocale("_GB_POSIX", "", "GB", "POSIX"); - try { - Locales.toLocale("_G"); - fail("Must be at least 3 chars if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_Gb"); - fail("Must be uppercase if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_gB"); - fail("Must be uppercase if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_1B"); - fail("Must be letter if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_G1"); - fail("Must be letter if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_GB_"); - fail("Must be at least 5 chars if starts with underscore"); - } catch (final IllegalArgumentException iae) { - } - try { - Locales.toLocale("_GBAP"); - fail("Must have underscore after the country if starts with underscore and is at least 5 chars"); - } catch (final IllegalArgumentException iae) { - } - } - - @Test - public void testParseAllLocales() { - final Locale[] locales = Locale.getAvailableLocales(); - int failures = 0; - for (final Locale l : locales) { - // Check if it's possible to recreate the Locale using just the standard constructor - final Locale locale = new Locale(l.getLanguage(), l.getCountry(), l.getVariant()); - if (l.equals(locale)) { // it is possible for LocaleUtils.toLocale to handle these Locales - String str = l.toString(); - // Look for the script/extension suffix - int suff = str.indexOf("_#"); - if (suff == - 1) { - suff = str.indexOf("#"); - } - if (suff >= 0) { // we have a suffix - try { - Locales.toLocale(str); // should cause IAE - System.out.println("Should not have parsed: " + str); - failures++; - continue; // try next Locale - } catch (final IllegalArgumentException iae) { - // expected; try without suffix - str = str.substring(0, suff); - } - } - final Locale loc = Locales.toLocale(str); - if (!l.equals(loc)) { - System.out.println("Failed to parse: " + str); - failures++; - } - } - } - if (failures > 0) { - fail("Failed "+failures+" test(s)"); - } - } - -} \ No newline at end of file diff --git a/api/src/test/java/com/okta/sdk/lang/ObjectsTest.java b/api/src/test/java/com/okta/sdk/lang/ObjectsTest.java deleted file mode 100644 index b265c2d59c9..00000000000 --- a/api/src/test/java/com/okta/sdk/lang/ObjectsTest.java +++ /dev/null @@ -1,679 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * Modifications Copyright 2017 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import org.testng.annotations.Test; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import static org.hamcrest.Matchers.*; -import static org.hamcrest.MatcherAssert.*; -import static org.testng.AssertJUnit.*; -import static com.okta.sdk.lang.Objects.*; - -/** - * Unit tests for {@link Objects}. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Rick Evans - * @author Sam Brannen - */ -public class ObjectsTest { - - @Test - public void isCheckedException() { - assertTrue(Objects.isCheckedException(new Exception())); - assertTrue(Objects.isCheckedException(new SQLException())); - - assertFalse(Objects.isCheckedException(new RuntimeException())); - assertFalse(Objects.isCheckedException(new IllegalArgumentException(""))); - - // Any Throwable other than RuntimeException and Error - // has to be considered checked according to the JLS. - assertTrue(Objects.isCheckedException(new Throwable())); - } - - @Test - public void isCompatibleWithThrowsClause() { - Class[] empty = new Class[0]; - Class[] exception = new Class[] {Exception.class}; - Class[] sqlAndIO = new Class[] {SQLException.class, IOException.class}; - Class[] throwable = new Class[] {Throwable.class}; - - assertTrue(Objects.isCompatibleWithThrowsClause(new RuntimeException())); - assertTrue(Objects.isCompatibleWithThrowsClause(new RuntimeException(), empty)); - assertTrue(Objects.isCompatibleWithThrowsClause(new RuntimeException(), exception)); - assertTrue(Objects.isCompatibleWithThrowsClause(new RuntimeException(), sqlAndIO)); - assertTrue(Objects.isCompatibleWithThrowsClause(new RuntimeException(), throwable)); - - assertFalse(Objects.isCompatibleWithThrowsClause(new Exception())); - assertFalse(Objects.isCompatibleWithThrowsClause(new Exception(), empty)); - assertTrue(Objects.isCompatibleWithThrowsClause(new Exception(), exception)); - assertFalse(Objects.isCompatibleWithThrowsClause(new Exception(), sqlAndIO)); - assertTrue(Objects.isCompatibleWithThrowsClause(new Exception(), throwable)); - - assertFalse(Objects.isCompatibleWithThrowsClause(new SQLException())); - assertFalse(Objects.isCompatibleWithThrowsClause(new SQLException(), empty)); - assertTrue(Objects.isCompatibleWithThrowsClause(new SQLException(), exception)); - assertTrue(Objects.isCompatibleWithThrowsClause(new SQLException(), sqlAndIO)); - assertTrue(Objects.isCompatibleWithThrowsClause(new SQLException(), throwable)); - - assertFalse(Objects.isCompatibleWithThrowsClause(new Throwable())); - assertFalse(Objects.isCompatibleWithThrowsClause(new Throwable(), empty)); - assertFalse(Objects.isCompatibleWithThrowsClause(new Throwable(), exception)); - assertFalse(Objects.isCompatibleWithThrowsClause(new Throwable(), sqlAndIO)); - assertTrue(Objects.isCompatibleWithThrowsClause(new Throwable(), throwable)); - } - - @Test - public void isEmptyNull() { - assertTrue(isEmpty(null)); - } - - @Test - public void isEmptyArray() { - assertTrue(isEmpty(new char[0])); - assertTrue(isEmpty(new Object[0])); - assertTrue(isEmpty(new Integer[0])); - - assertFalse(isEmpty(new int[] { 42 })); - assertFalse(isEmpty(new Integer[] { new Integer(42) })); - } - - @Test - public void isEmptyCollection() { - assertTrue(isEmpty(Collections.emptyList())); - assertTrue(isEmpty(Collections.emptySet())); - - Set set = new HashSet<>(); - set.add("foo"); - assertFalse(isEmpty(set)); - assertFalse(isEmpty(Arrays.asList("foo"))); - } - - @Test - public void isEmptyMap() { - assertTrue(isEmpty(Collections.emptyMap())); - - HashMap map = new HashMap<>(); - map.put("foo", 42L); - assertFalse(isEmpty(map)); - } - - @Test - public void isEmptyCharSequence() { - assertTrue(isEmpty(new StringBuilder())); - assertTrue(isEmpty("")); - - assertFalse(isEmpty(new StringBuilder("foo"))); - assertFalse(isEmpty(" ")); - assertFalse(isEmpty("\t")); - assertFalse(isEmpty("foo")); - } - - @Test - public void isEmptyUnsupportedObjectType() { - assertFalse(isEmpty(42L)); - assertFalse(isEmpty(new Object())); - } - - @Test - public void toObjectArray() { - int[] a = new int[] {1, 2, 3, 4, 5}; - Integer[] wrapper = (Integer[]) Objects.toObjectArray(a); - assertTrue(wrapper.length == 5); - for (int i = 0; i < wrapper.length; i++) { - assertEquals(a[i], wrapper[i].intValue()); - } - } - - @Test - public void toObjectArrayWithNull() { - Object[] objects = Objects.toObjectArray(null); - assertNotNull(objects); - assertEquals(0, objects.length); - } - - @Test - public void toObjectArrayWithEmptyPrimitiveArray() { - Object[] objects = Objects.toObjectArray(new byte[] {}); - assertNotNull(objects); - assertEquals(0, objects.length); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void toObjectArrayWithNonArrayType() { - Objects.toObjectArray("Not an []"); - } - - @Test - public void toObjectArrayWithNonPrimitiveArray() { - String[] source = new String[] {"Bingo"}; - assertArrayEquals(source, Objects.toObjectArray(source)); - } - - @Test - public void addObjectToArraySunnyDay() { - String[] array = new String[] {"foo", "bar"}; - String newElement = "baz"; - Object[] newArray = Objects.addObjectToArray(array, newElement); - assertEquals(3, newArray.length); - assertEquals(newElement, newArray[2]); - } - - @Test - public void addObjectToArrayWhenEmpty() { - String[] array = new String[0]; - String newElement = "foo"; - String[] newArray = Objects.addObjectToArray(array, newElement); - assertEquals(1, newArray.length); - assertEquals(newElement, newArray[0]); - } - - @Test - public void addObjectToSingleNonNullElementArray() { - String existingElement = "foo"; - String[] array = new String[] {existingElement}; - String newElement = "bar"; - String[] newArray = Objects.addObjectToArray(array, newElement); - assertEquals(2, newArray.length); - assertEquals(existingElement, newArray[0]); - assertEquals(newElement, newArray[1]); - } - - @Test - public void addObjectToSingleNullElementArray() { - String[] array = new String[] {null}; - String newElement = "bar"; - String[] newArray = Objects.addObjectToArray(array, newElement); - assertEquals(2, newArray.length); - assertEquals(null, newArray[0]); - assertEquals(newElement, newArray[1]); - } - - @Test - public void addObjectToNullArray() throws Exception { - String newElement = "foo"; - String[] newArray = Objects.addObjectToArray(null, newElement); - assertEquals(1, newArray.length); - assertEquals(newElement, newArray[0]); - } - - @Test - public void addNullObjectToNullArray() throws Exception { - Object[] newArray = Objects.addObjectToArray(null, null); - assertEquals(1, newArray.length); - assertEquals(null, newArray[0]); - } - - @Test - public void nullSafeEqualsWithArrays() throws Exception { - assertTrue(Objects.nullSafeEquals(new String[] {"a", "b", "c"}, new String[] {"a", "b", "c"})); - assertTrue(Objects.nullSafeEquals(new int[] {1, 2, 3}, new int[] {1, 2, 3})); - } - - @Test - public void identityToString() { - Object obj = new Object(); - String expected = obj.getClass().getName() + "@" + Objects.getIdentityHexString(obj); - String actual = Objects.identityToString(obj); - assertEquals(expected, actual); - } - - @Test - public void identityToStringWithNullObject() { - assertEquals("", Objects.identityToString(null)); - } - - @Test - public void nullSafeHashCodeWithBooleanArray() { - int expected = 31 * 7 + Boolean.TRUE.hashCode(); - expected = 31 * expected + Boolean.FALSE.hashCode(); - - boolean[] array = {true, false}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithBooleanArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((boolean[]) null)); - } - - @Test - public void nullSafeHashCodeWithByteArray() { - int expected = 31 * 7 + 8; - expected = 31 * expected + 10; - - byte[] array = {8, 10}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithByteArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((byte[]) null)); - } - - @Test - public void nullSafeHashCodeWithCharArray() { - int expected = 31 * 7 + 'a'; - expected = 31 * expected + 'E'; - - char[] array = {'a', 'E'}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithCharArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((char[]) null)); - } - - @Test - public void nullSafeHashCodeWithDoubleArray() { - long bits = Double.doubleToLongBits(8449.65); - int expected = 31 * 7 + (int) (bits ^ (bits >>> 32)); - bits = Double.doubleToLongBits(9944.923); - expected = 31 * expected + (int) (bits ^ (bits >>> 32)); - - double[] array = {8449.65, 9944.923}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithDoubleArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((double[]) null)); - } - - @Test - public void nullSafeHashCodeWithFloatArray() { - int expected = 31 * 7 + Float.floatToIntBits(9.6f); - expected = 31 * expected + Float.floatToIntBits(7.4f); - - float[] array = {9.6f, 7.4f}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithFloatArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((float[]) null)); - } - - @Test - public void nullSafeHashCodeWithIntArray() { - int expected = 31 * 7 + 884; - expected = 31 * expected + 340; - - int[] array = {884, 340}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithIntArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((int[]) null)); - } - - @Test - public void nullSafeHashCodeWithLongArray() { - long lng = 7993l; - int expected = 31 * 7 + (int) (lng ^ (lng >>> 32)); - lng = 84320l; - expected = 31 * expected + (int) (lng ^ (lng >>> 32)); - - long[] array = {7993l, 84320l}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithLongArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((long[]) null)); - } - - @Test - public void nullSafeHashCodeWithObject() { - String str = "Luke"; - assertEquals(str.hashCode(), Objects.nullSafeHashCode(str)); - } - - @Test - public void nullSafeHashCodeWithObjectArray() { - int expected = 31 * 7 + "Leia".hashCode(); - expected = 31 * expected + "Han".hashCode(); - - Object[] array = {"Leia", "Han"}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithObjectArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((Object[]) null)); - } - - @Test - public void nullSafeHashCodeWithObjectBeingBooleanArray() { - Object array = new boolean[] {true, false}; - int expected = Objects.nullSafeHashCode((boolean[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingByteArray() { - Object array = new byte[] {6, 39}; - int expected = Objects.nullSafeHashCode((byte[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingCharArray() { - Object array = new char[] {'l', 'M'}; - int expected = Objects.nullSafeHashCode((char[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingDoubleArray() { - Object array = new double[] {68930.993, 9022.009}; - int expected = Objects.nullSafeHashCode((double[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingFloatArray() { - Object array = new float[] {9.9f, 9.54f}; - int expected = Objects.nullSafeHashCode((float[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingIntArray() { - Object array = new int[] {89, 32}; - int expected = Objects.nullSafeHashCode((int[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingLongArray() { - Object array = new long[] {4389, 320}; - int expected = Objects.nullSafeHashCode((long[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingObjectArray() { - Object array = new Object[] {"Luke", "Anakin"}; - int expected = Objects.nullSafeHashCode((Object[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectBeingShortArray() { - Object array = new short[] {5, 3}; - int expected = Objects.nullSafeHashCode((short[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - public void nullSafeHashCodeWithObjectEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((Object) null)); - } - - @Test - public void nullSafeHashCodeWithShortArray() { - int expected = 31 * 7 + 70; - expected = 31 * expected + 8; - - short[] array = {70, 8}; - int actual = Objects.nullSafeHashCode(array); - - assertEquals(expected, actual); - } - - @Test - public void nullSafeHashCodeWithShortArrayEqualToNull() { - assertEquals(0, Objects.nullSafeHashCode((short[]) null)); - } - - @Test - public void nullSafeToStringWithBooleanArray() { - boolean[] array = {true, false}; - assertEquals("{true, false}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithBooleanArrayBeingEmpty() { - boolean[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithBooleanArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((boolean[]) null)); - } - - @Test - public void nullSafeToStringWithByteArray() { - byte[] array = {5, 8}; - assertEquals("{5, 8}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithByteArrayBeingEmpty() { - byte[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithByteArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((byte[]) null)); - } - - @Test - public void nullSafeToStringWithCharArray() { - char[] array = {'A', 'B'}; - assertEquals("{'A', 'B'}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithCharArrayBeingEmpty() { - char[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithCharArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((char[]) null)); - } - - @Test - public void nullSafeToStringWithDoubleArray() { - double[] array = {8594.93, 8594023.95}; - assertEquals("{8594.93, 8594023.95}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithDoubleArrayBeingEmpty() { - double[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithDoubleArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((double[]) null)); - } - - @Test - public void nullSafeToStringWithFloatArray() { - float[] array = {8.6f, 43.8f}; - assertEquals("{8.6, 43.8}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithFloatArrayBeingEmpty() { - float[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithFloatArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((float[]) null)); - } - - @Test - public void nullSafeToStringWithIntArray() { - int[] array = {9, 64}; - assertEquals("{9, 64}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithIntArrayBeingEmpty() { - int[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithIntArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((int[]) null)); - } - - @Test - public void nullSafeToStringWithLongArray() { - long[] array = {434l, 23423l}; - assertEquals("{434, 23423}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithLongArrayBeingEmpty() { - long[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithLongArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((long[]) null)); - } - - @Test - public void nullSafeToStringWithPlainOldString() { - assertEquals("I shoh love tha taste of mangoes", Objects.nullSafeToString("I shoh love tha taste of mangoes")); - } - - @Test - public void nullSafeToStringWithObjectArray() { - Object[] array = {"Han", new Long(43)}; - assertEquals("{Han, 43}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithObjectArrayBeingEmpty() { - Object[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithObjectArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((Object[]) null)); - } - - @Test - public void nullSafeToStringWithShortArray() { - short[] array = {7, 9}; - assertEquals("{7, 9}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithShortArrayBeingEmpty() { - short[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithShortArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((short[]) null)); - } - - @Test - public void nullSafeToStringWithStringArray() { - String[] array = {"Luke", "Anakin"}; - assertEquals("{Luke, Anakin}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithStringArrayBeingEmpty() { - String[] array = {}; - assertEquals("{}", Objects.nullSafeToString(array)); - } - - @Test - public void nullSafeToStringWithStringArrayEqualToNull() { - assertEquals("null", Objects.nullSafeToString((String[]) null)); - } - - @Test - public void containsConstant() { - assertThat(Objects.containsConstant(Tropes.values(), "FOO"), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "foo"), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "BaR"), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "bar"), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "BAZ"), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "baz"), is(true)); - - assertThat(Objects.containsConstant(Tropes.values(), "BOGUS"), is(false)); - - assertThat(Objects.containsConstant(Tropes.values(), "FOO", true), is(true)); - assertThat(Objects.containsConstant(Tropes.values(), "foo", true), is(false)); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void caseInsensitiveValueOf() { - assertThat(Objects.caseInsensitiveValueOf(Tropes.values(), "foo"), is(Tropes.FOO)); - assertThat(Objects.caseInsensitiveValueOf(Tropes.values(), "BAR"), is(Tropes.BAR)); - - Objects.caseInsensitiveValueOf(Tropes.values(), "bogus"); - } - - private void assertEqualHashCodes(int expected, Object array) { - int actual = Objects.nullSafeHashCode(array); - assertEquals(expected, actual); - assertTrue(array.hashCode() != actual); - } - - - enum Tropes { FOO, BAR, baz } - -} \ No newline at end of file diff --git a/api/src/test/java/com/okta/sdk/lang/StringsTest.java b/api/src/test/java/com/okta/sdk/lang/StringsTest.java deleted file mode 100644 index ce19453a041..00000000000 --- a/api/src/test/java/com/okta/sdk/lang/StringsTest.java +++ /dev/null @@ -1,735 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.lang; - -import java.util.Arrays; -import java.util.Locale; -import java.util.Properties; - -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.*; - -/** - * @author Rod Johnson - * @author Juergen Hoeller - * @author Rick Evans - */ -public class StringsTest { - - @Test - public void testHasTextBlank() { - String blank = " "; - assertEquals(false, Strings.hasText(blank)); - } - - @Test - public void testHasTextNullEmpty() { - assertEquals(false, Strings.hasText(null)); - assertEquals(false, Strings.hasText("")); - } - - @Test - public void testHasTextValid() { - assertEquals(true, Strings.hasText("t")); - } - - @Test - public void testContainsWhitespace() { - assertFalse(Strings.containsWhitespace(null)); - assertFalse(Strings.containsWhitespace("")); - assertFalse(Strings.containsWhitespace("a")); - assertFalse(Strings.containsWhitespace("abc")); - assertTrue(Strings.containsWhitespace(" ")); - assertTrue(Strings.containsWhitespace(" a")); - assertTrue(Strings.containsWhitespace("abc ")); - assertTrue(Strings.containsWhitespace("a b")); - assertTrue(Strings.containsWhitespace("a b")); - } - - @Test - public void testTrimWhitespace() { - assertEquals(null, Strings.trimWhitespace(null)); - assertEquals("", Strings.trimWhitespace("")); - assertEquals("", Strings.trimWhitespace(" ")); - assertEquals("", Strings.trimWhitespace("\t")); - assertEquals("a", Strings.trimWhitespace(" a")); - assertEquals("a", Strings.trimWhitespace("a ")); - assertEquals("a", Strings.trimWhitespace(" a ")); - assertEquals("a b", Strings.trimWhitespace(" a b ")); - assertEquals("a b c", Strings.trimWhitespace(" a b c ")); - } - - @Test - public void testTrimAllWhitespace() { - assertEquals("", Strings.trimAllWhitespace("")); - assertEquals("", Strings.trimAllWhitespace(" ")); - assertEquals("", Strings.trimAllWhitespace("\t")); - assertEquals("a", Strings.trimAllWhitespace(" a")); - assertEquals("a", Strings.trimAllWhitespace("a ")); - assertEquals("a", Strings.trimAllWhitespace(" a ")); - assertEquals("ab", Strings.trimAllWhitespace(" a b ")); - assertEquals("abc", Strings.trimAllWhitespace(" a b c ")); - } - - @Test - public void testTrimLeadingWhitespace() { - assertEquals(null, Strings.trimLeadingWhitespace(null)); - assertEquals("", Strings.trimLeadingWhitespace("")); - assertEquals("", Strings.trimLeadingWhitespace(" ")); - assertEquals("", Strings.trimLeadingWhitespace("\t")); - assertEquals("a", Strings.trimLeadingWhitespace(" a")); - assertEquals("a ", Strings.trimLeadingWhitespace("a ")); - assertEquals("a ", Strings.trimLeadingWhitespace(" a ")); - assertEquals("a b ", Strings.trimLeadingWhitespace(" a b ")); - assertEquals("a b c ", Strings.trimLeadingWhitespace(" a b c ")); - } - - @Test - public void testTrimTrailingWhitespace() { - assertEquals(null, Strings.trimTrailingWhitespace(null)); - assertEquals("", Strings.trimTrailingWhitespace("")); - assertEquals("", Strings.trimTrailingWhitespace(" ")); - assertEquals("", Strings.trimTrailingWhitespace("\t")); - assertEquals("a", Strings.trimTrailingWhitespace("a ")); - assertEquals(" a", Strings.trimTrailingWhitespace(" a")); - assertEquals(" a", Strings.trimTrailingWhitespace(" a ")); - assertEquals(" a b", Strings.trimTrailingWhitespace(" a b ")); - assertEquals(" a b c", Strings.trimTrailingWhitespace(" a b c ")); - } - - @Test - public void testTrimLeadingCharacter() { - assertEquals(null, Strings.trimLeadingCharacter(null, ' ')); - assertEquals("", Strings.trimLeadingCharacter("", ' ')); - assertEquals("", Strings.trimLeadingCharacter(" ", ' ')); - assertEquals("\t", Strings.trimLeadingCharacter("\t", ' ')); - assertEquals("a", Strings.trimLeadingCharacter(" a", ' ')); - assertEquals("a ", Strings.trimLeadingCharacter("a ", ' ')); - assertEquals("a ", Strings.trimLeadingCharacter(" a ", ' ')); - assertEquals("a b ", Strings.trimLeadingCharacter(" a b ", ' ')); - assertEquals("a b c ", Strings.trimLeadingCharacter(" a b c ", ' ')); - } - - @Test - public void testTrimTrailingCharacter() { - assertEquals(null, Strings.trimTrailingCharacter(null, ' ')); - assertEquals("", Strings.trimTrailingCharacter("", ' ')); - assertEquals("", Strings.trimTrailingCharacter(" ", ' ')); - assertEquals("\t", Strings.trimTrailingCharacter("\t", ' ')); - assertEquals("a", Strings.trimTrailingCharacter("a ", ' ')); - assertEquals(" a", Strings.trimTrailingCharacter(" a", ' ')); - assertEquals(" a", Strings.trimTrailingCharacter(" a ", ' ')); - assertEquals(" a b", Strings.trimTrailingCharacter(" a b ", ' ')); - assertEquals(" a b c", Strings.trimTrailingCharacter(" a b c ", ' ')); - } - - @Test - public void testStartsWithIgnoreCase() { - String prefix = "fOo"; - assertTrue(Strings.startsWithIgnoreCase("foo", prefix)); - assertTrue(Strings.startsWithIgnoreCase("Foo", prefix)); - assertTrue(Strings.startsWithIgnoreCase("foobar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("foobarbar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("Foobar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("FoobarBar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("foObar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("FOObar", prefix)); - assertTrue(Strings.startsWithIgnoreCase("fOobar", prefix)); - assertFalse(Strings.startsWithIgnoreCase(null, prefix)); - assertFalse(Strings.startsWithIgnoreCase("fOobar", null)); - assertFalse(Strings.startsWithIgnoreCase("b", prefix)); - assertFalse(Strings.startsWithIgnoreCase("barfoo", prefix)); - assertFalse(Strings.startsWithIgnoreCase("barfoobar", prefix)); - } - - @Test - public void testEndsWithIgnoreCase() { - String suffix = "fOo"; - assertTrue(Strings.endsWithIgnoreCase("foo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("Foo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barfoo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barbarfoo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barFoo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barBarFoo", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barfoO", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barFOO", suffix)); - assertTrue(Strings.endsWithIgnoreCase("barfOo", suffix)); - assertFalse(Strings.endsWithIgnoreCase(null, suffix)); - assertFalse(Strings.endsWithIgnoreCase("barfOo", null)); - assertFalse(Strings.endsWithIgnoreCase("b", suffix)); - assertFalse(Strings.endsWithIgnoreCase("foobar", suffix)); - assertFalse(Strings.endsWithIgnoreCase("barfoobar", suffix)); - } - - @Test - public void testSubstringMatch() { - assertTrue(Strings.substringMatch("foo", 0, "foo")); - assertTrue(Strings.substringMatch("foo", 1, "oo")); - assertTrue(Strings.substringMatch("foo", 2, "o")); - assertFalse(Strings.substringMatch("foo", 0, "fOo")); - assertFalse(Strings.substringMatch("foo", 1, "fOo")); - assertFalse(Strings.substringMatch("foo", 2, "fOo")); - assertFalse(Strings.substringMatch("foo", 3, "fOo")); - assertFalse(Strings.substringMatch("foo", 1, "Oo")); - assertFalse(Strings.substringMatch("foo", 2, "Oo")); - assertFalse(Strings.substringMatch("foo", 3, "Oo")); - assertFalse(Strings.substringMatch("foo", 2, "O")); - assertFalse(Strings.substringMatch("foo", 3, "O")); - } - - @Test - public void testCountOccurrencesOf() { - assertTrue("nullx2 = 0", - Strings.countOccurrencesOf(null, null) == 0); - assertTrue("null string = 0", - Strings.countOccurrencesOf("s", null) == 0); - assertTrue("null substring = 0", - Strings.countOccurrencesOf(null, "s") == 0); - String s = "erowoiueoiur"; - assertTrue("not found = 0", - Strings.countOccurrencesOf(s, "WERWER") == 0); - assertTrue("not found char = 0", - Strings.countOccurrencesOf(s, "x") == 0); - assertTrue("not found ws = 0", - Strings.countOccurrencesOf(s, " ") == 0); - assertTrue("not found empty string = 0", - Strings.countOccurrencesOf(s, "") == 0); - assertTrue("found char=2", Strings.countOccurrencesOf(s, "e") == 2); - assertTrue("found substring=2", - Strings.countOccurrencesOf(s, "oi") == 2); - assertTrue("found substring=2", - Strings.countOccurrencesOf(s, "oiu") == 2); - assertTrue("found substring=3", - Strings.countOccurrencesOf(s, "oiur") == 1); - assertTrue("test last", Strings.countOccurrencesOf(s, "r") == 2); - } - - @Test - public void testReplace() { - String inString = "a6AazAaa77abaa"; - String oldPattern = "aa"; - String newPattern = "foo"; - - // Simple replace - String s = Strings.replace(inString, oldPattern, newPattern); - assertTrue("Replace 1 worked", s.equals("a6AazAfoo77abfoo")); - - // Non match: no change - s = Strings.replace(inString, "qwoeiruqopwieurpoqwieur", newPattern); - assertSame("Replace non-matched is returned as-is", inString, s); - - // Null new pattern: should ignore - s = Strings.replace(inString, oldPattern, null); - assertSame("Replace non-matched is returned as-is", inString, s); - - // Null old pattern: should ignore - s = Strings.replace(inString, null, newPattern); - assertSame("Replace non-matched is returned as-is", inString, s); - } - - @Test - public void testDelete() { - String inString = "The quick brown fox jumped over the lazy dog"; - - String noThe = Strings.delete(inString, "the"); - assertTrue("Result has no the [" + noThe + "]", - noThe.equals("The quick brown fox jumped over lazy dog")); - - String nohe = Strings.delete(inString, "he"); - assertTrue("Result has no he [" + nohe + "]", - nohe.equals("T quick brown fox jumped over t lazy dog")); - - String nosp = Strings.delete(inString, " "); - assertTrue("Result has no spaces", - nosp.equals("Thequickbrownfoxjumpedoverthelazydog")); - - String killEnd = Strings.delete(inString, "dog"); - assertTrue("Result has no dog", - killEnd.equals("The quick brown fox jumped over the lazy ")); - - String mismatch = Strings.delete(inString, "dxxcxcxog"); - assertTrue("Result is unchanged", mismatch.equals(inString)); - - String nochange = Strings.delete(inString, ""); - assertTrue("Result is unchanged", nochange.equals(inString)); - } - - @Test - public void testDeleteAny() { - String inString = "Able was I ere I saw Elba"; - - String res = Strings.deleteAny(inString, "I"); - assertTrue("Result has no Is [" + res + "]", res.equals("Able was ere saw Elba")); - - res = Strings.deleteAny(inString, "AeEba!"); - assertTrue("Result has no Is [" + res + "]", res.equals("l ws I r I sw l")); - - String mismatch = Strings.deleteAny(inString, "#@$#$^"); - assertTrue("Result is unchanged", mismatch.equals(inString)); - - String whitespace = "This is\n\n\n \t a messagy string with whitespace\n"; - assertTrue("Has CR", whitespace.contains("\n")); - assertTrue("Has tab", whitespace.contains("\t")); - assertTrue("Has sp", whitespace.contains(" ")); - String cleaned = Strings.deleteAny(whitespace, "\n\t "); - assertTrue("Has no CR", !cleaned.contains("\n")); - assertTrue("Has no tab", !cleaned.contains("\t")); - assertTrue("Has no sp", !cleaned.contains(" ")); - assertTrue("Still has chars", cleaned.length() > 10); - } - - - @Test - public void testQuote() { - assertEquals("'myString'", Strings.quote("myString")); - assertEquals("''", Strings.quote("")); - assertNull(Strings.quote(null)); - } - - @Test - public void testQuoteIfString() { - assertEquals("'myString'", Strings.quoteIfString("myString")); - assertEquals("''", Strings.quoteIfString("")); - assertEquals(new Integer(5), Strings.quoteIfString(5)); - assertNull(Strings.quoteIfString(null)); - } - - @Test - public void testUnqualify() { - String qualified = "i.am.not.unqualified"; - assertEquals("unqualified", Strings.unqualify(qualified)); - } - - @Test - public void testCapitalize() { - String capitalized = "i am not capitalized"; - assertEquals("I am not capitalized", Strings.capitalize(capitalized)); - } - - @Test - public void testUncapitalize() { - String capitalized = "I am capitalized"; - assertEquals("i am capitalized", Strings.uncapitalize(capitalized)); - } - - @Test - public void testGetFilename() { - assertEquals(null, Strings.getFilename(null)); - assertEquals("", Strings.getFilename("")); - assertEquals("myfile", Strings.getFilename("myfile")); - assertEquals("myfile", Strings.getFilename("mypath/myfile")); - assertEquals("myfile.", Strings.getFilename("myfile.")); - assertEquals("myfile.", Strings.getFilename("mypath/myfile.")); - assertEquals("myfile.txt", Strings.getFilename("myfile.txt")); - assertEquals("myfile.txt", Strings.getFilename("mypath/myfile.txt")); - } - - @Test - public void testGetFilenameExtension() { - assertEquals(null, Strings.getFilenameExtension(null)); - assertEquals(null, Strings.getFilenameExtension("")); - assertEquals(null, Strings.getFilenameExtension("myfile")); - assertEquals(null, Strings.getFilenameExtension("myPath/myfile")); - assertEquals(null, Strings.getFilenameExtension("/home/user/.m2/settings/myfile")); - assertEquals("", Strings.getFilenameExtension("myfile.")); - assertEquals("", Strings.getFilenameExtension("myPath/myfile.")); - assertEquals("txt", Strings.getFilenameExtension("myfile.txt")); - assertEquals("txt", Strings.getFilenameExtension("mypath/myfile.txt")); - assertEquals("txt", Strings.getFilenameExtension("/home/user/.m2/settings/myfile.txt")); - } - - @Test - public void testStripFilenameExtension() { - assertEquals("", Strings.stripFilenameExtension("")); - assertEquals("myfile", Strings.stripFilenameExtension("myfile")); - assertEquals("myfile", Strings.stripFilenameExtension("myfile.")); - assertEquals("myfile", Strings.stripFilenameExtension("myfile.txt")); - assertEquals("mypath/myfile", Strings.stripFilenameExtension("mypath/myfile")); - assertEquals("mypath/myfile", Strings.stripFilenameExtension("mypath/myfile.")); - assertEquals("mypath/myfile", Strings.stripFilenameExtension("mypath/myfile.txt")); - assertEquals("/home/user/.m2/settings/myfile", Strings.stripFilenameExtension("/home/user/.m2/settings/myfile")); - assertEquals("/home/user/.m2/settings/myfile", Strings.stripFilenameExtension("/home/user/.m2/settings/myfile.")); - assertEquals("/home/user/.m2/settings/myfile", Strings.stripFilenameExtension("/home/user/.m2/settings/myfile.txt")); - } - - @Test - public void testCleanPath() { - assertEquals("mypath/myfile", Strings.cleanPath("mypath/myfile")); - assertEquals("mypath/myfile", Strings.cleanPath("mypath\\myfile")); - assertEquals("mypath/myfile", Strings.cleanPath("mypath/../mypath/myfile")); - assertEquals("mypath/myfile", Strings.cleanPath("mypath/myfile/../../mypath/myfile")); - assertEquals("../mypath/myfile", Strings.cleanPath("../mypath/myfile")); - assertEquals("../mypath/myfile", Strings.cleanPath("../mypath/../mypath/myfile")); - assertEquals("../mypath/myfile", Strings.cleanPath("mypath/../../mypath/myfile")); - assertEquals("/../mypath/myfile", Strings.cleanPath("/../mypath/myfile")); - assertEquals("/mypath/myfile", Strings.cleanPath("/a/:b/../../mypath/myfile")); - assertEquals("file:///c:/path/to/the%20file.txt", Strings.cleanPath("file:///c:/some/../path/to/the%20file.txt")); - } - - @Test - public void testPathEquals() { - assertTrue("Must be true for the same strings", - Strings.pathEquals("/dummy1/dummy2/dummy3", - "/dummy1/dummy2/dummy3")); - assertTrue("Must be true for the same win strings", - Strings.pathEquals("C:\\dummy1\\dummy2\\dummy3", - "C:\\dummy1\\dummy2\\dummy3")); - assertTrue("Must be true for one top path on 1", - Strings.pathEquals("/dummy1/bin/../dummy2/dummy3", - "/dummy1/dummy2/dummy3")); - assertTrue("Must be true for one win top path on 2", - Strings.pathEquals("C:\\dummy1\\dummy2\\dummy3", - "C:\\dummy1\\bin\\..\\dummy2\\dummy3")); - assertTrue("Must be true for two top paths on 1", - Strings.pathEquals("/dummy1/bin/../dummy2/bin/../dummy3", - "/dummy1/dummy2/dummy3")); - assertTrue("Must be true for two win top paths on 2", - Strings.pathEquals("C:\\dummy1\\dummy2\\dummy3", - "C:\\dummy1\\bin\\..\\dummy2\\bin\\..\\dummy3")); - assertTrue("Must be true for double top paths on 1", - Strings.pathEquals("/dummy1/bin/tmp/../../dummy2/dummy3", - "/dummy1/dummy2/dummy3")); - assertTrue("Must be true for double top paths on 2 with similarity", - Strings.pathEquals("/dummy1/dummy2/dummy3", - "/dummy1/dum/dum/../../dummy2/dummy3")); - assertTrue("Must be true for current paths", - Strings.pathEquals("./dummy1/dummy2/dummy3", - "dummy1/dum/./dum/../../dummy2/dummy3")); - assertFalse("Must be false for relative/absolute paths", - Strings.pathEquals("./dummy1/dummy2/dummy3", - "/dummy1/dum/./dum/../../dummy2/dummy3")); - assertFalse("Must be false for different strings", - Strings.pathEquals("/dummy1/dummy2/dummy3", - "/dummy1/dummy4/dummy3")); - assertFalse("Must be false for one false path on 1", - Strings.pathEquals("/dummy1/bin/tmp/../dummy2/dummy3", - "/dummy1/dummy2/dummy3")); - assertFalse("Must be false for one false win top path on 2", - Strings.pathEquals("C:\\dummy1\\dummy2\\dummy3", - "C:\\dummy1\\bin\\tmp\\..\\dummy2\\dummy3")); - assertFalse("Must be false for top path on 1 + difference", - Strings.pathEquals("/dummy1/bin/../dummy2/dummy3", - "/dummy1/dummy2/dummy4")); - } - - @Test - public void testConcatenateStringArrays() { - String[] input1 = new String[] {"myString2"}; - String[] input2 = new String[] {"myString1", "myString2"}; - String[] result = Strings.concatenateStringArrays(input1, input2); - assertEquals(3, result.length); - assertEquals("myString2", result[0]); - assertEquals("myString1", result[1]); - assertEquals("myString2", result[2]); - - assertArrayEquals(input1, Strings.concatenateStringArrays(input1, null)); - assertArrayEquals(input2, Strings.concatenateStringArrays(null, input2)); - assertNull(Strings.concatenateStringArrays(null, null)); - } - - @Test - public void testMergeStringArrays() { - String[] input1 = new String[] {"myString2"}; - String[] input2 = new String[] {"myString1", "myString2"}; - String[] result = Strings.mergeStringArrays(input1, input2); - assertEquals(2, result.length); - assertEquals("myString2", result[0]); - assertEquals("myString1", result[1]); - - assertArrayEquals(input1, Strings.mergeStringArrays(input1, null)); - assertArrayEquals(input2, Strings.mergeStringArrays(null, input2)); - assertNull(Strings.mergeStringArrays(null, null)); - } - - @Test - public void testSortStringArray() { - String[] input = new String[] {"myString2"}; - input = Strings.addStringToArray(input, "myString1"); - assertEquals("myString2", input[0]); - assertEquals("myString1", input[1]); - - Strings.sortStringArray(input); - assertEquals("myString1", input[0]); - assertEquals("myString2", input[1]); - } - - @Test - public void testRemoveDuplicateStrings() { - String[] input = new String[] {"myString2", "myString1", "myString2"}; - input = Strings.removeDuplicateStrings(input); - assertEquals("myString2", input[0]); - assertEquals("myString1", input[1]); - } - - @Test - public void testSplitArrayElementsIntoProperties() { - String[] input = new String[] {"key1=value1 ", "key2 =\"value2\""}; - Properties result = Strings.splitArrayElementsIntoProperties(input, "="); - assertEquals("value1", result.getProperty("key1")); - assertEquals("\"value2\"", result.getProperty("key2")); - } - - @Test - public void testSplitArrayElementsIntoPropertiesAndDeletedChars() { - String[] input = new String[] {"key1=value1 ", "key2 =\"value2\""}; - Properties result = Strings.splitArrayElementsIntoProperties(input, "=", "\""); - assertEquals("value1", result.getProperty("key1")); - assertEquals("value2", result.getProperty("key2")); - } - - @Test - public void testTokenizeToStringArray() { - String[] sa = Strings.tokenizeToStringArray("a,b , ,c", ","); - assertEquals(3, sa.length); - assertTrue("components are correct", - sa[0].equals("a") && sa[1].equals("b") && sa[2].equals("c")); - } - - @Test - public void testTokenizeToStringArrayWithNotIgnoreEmptyTokens() { - String[] sa = Strings.tokenizeToStringArray("a,b , ,c", ",", true, false); - assertEquals(4, sa.length); - assertTrue("components are correct", - sa[0].equals("a") && sa[1].equals("b") && sa[2].equals("") && sa[3].equals("c")); - } - - @Test - public void testTokenizeToStringArrayWithNotTrimTokens() { - String[] sa = Strings.tokenizeToStringArray("a,b ,c", ",", false, true); - assertEquals(3, sa.length); - assertTrue("components are correct", - sa[0].equals("a") && sa[1].equals("b ") && sa[2].equals("c")); - } - - @Test - public void testCommaDelimitedListToStringArrayWithNullProducesEmptyArray() { - String[] sa = Strings.commaDelimitedListToStringArray(null); - assertTrue("String array isn't null with null input", sa != null); - assertTrue("String array length == 0 with null input", sa.length == 0); - } - - @Test - public void testCommaDelimitedListToStringArrayWithEmptyStringProducesEmptyArray() { - String[] sa = Strings.commaDelimitedListToStringArray(""); - assertTrue("String array isn't null with null input", sa != null); - assertTrue("String array length == 0 with null input", sa.length == 0); - } - - @Test - public void testDelimitedListToStringArrayWithComma() { - String[] sa = Strings.delimitedListToStringArray("a,b", ","); - assertEquals(2, sa.length); - assertEquals("a", sa[0]); - assertEquals("b", sa[1]); - } - - @Test - public void testDelimitedListToStringArrayWithSemicolon() { - String[] sa = Strings.delimitedListToStringArray("a;b", ";"); - assertEquals(2, sa.length); - assertEquals("a", sa[0]); - assertEquals("b", sa[1]); - } - - @Test - public void testDelimitedListToStringArrayWithEmptyString() { - String[] sa = Strings.delimitedListToStringArray("a,b", ""); - assertEquals(3, sa.length); - assertEquals("a", sa[0]); - assertEquals(",", sa[1]); - assertEquals("b", sa[2]); - } - - @Test - public void testDelimitedListToStringArrayWithNullDelimiter() { - String[] sa = Strings.delimitedListToStringArray("a,b", null); - assertEquals(1, sa.length); - assertEquals("a,b", sa[0]); - } - - @Test - public void testCommaDelimitedListToStringArrayMatchWords() { - // Could read these from files - String[] sa = new String[] {"foo", "bar", "big"}; - doTestCommaDelimitedListToStringArrayLegalMatch(sa); - doTestStringArrayReverseTransformationMatches(sa); - - sa = new String[] {"a", "b", "c"}; - doTestCommaDelimitedListToStringArrayLegalMatch(sa); - doTestStringArrayReverseTransformationMatches(sa); - - // Test same words - sa = new String[] {"AA", "AA", "AA", "AA", "AA"}; - doTestCommaDelimitedListToStringArrayLegalMatch(sa); - doTestStringArrayReverseTransformationMatches(sa); - } - - private void doTestStringArrayReverseTransformationMatches(String[] sa) { - String[] reverse = - Strings.commaDelimitedListToStringArray(Strings.arrayToCommaDelimitedString(sa)); - assertEquals("Reverse transformation is equal", - Arrays.asList(sa), - Arrays.asList(reverse)); - } - - @Test - public void testCommaDelimitedListToStringArraySingleString() { - // Could read these from files - String s = "woeirqupoiewuropqiewuorpqiwueopriquwopeiurqopwieur"; - String[] sa = Strings.commaDelimitedListToStringArray(s); - assertTrue("Found one String with no delimiters", sa.length == 1); - assertTrue("Single array entry matches input String with no delimiters", - sa[0].equals(s)); - } - - @Test - public void testCommaDelimitedListToStringArrayWithOtherPunctuation() { - // Could read these from files - String[] sa = new String[] {"xcvwert4456346&*.", "///", ".!", ".", ";"}; - doTestCommaDelimitedListToStringArrayLegalMatch(sa); - } - - /** - * We expect to see the empty Strings in the output. - */ - @Test - public void testCommaDelimitedListToStringArrayEmptyStrings() { - // Could read these from files - String[] sa = Strings.commaDelimitedListToStringArray("a,,b"); - assertEquals("a,,b produces array length 3", 3, sa.length); - assertTrue("components are correct", - sa[0].equals("a") && sa[1].equals("") && sa[2].equals("b")); - - sa = new String[] {"", "", "a", ""}; - doTestCommaDelimitedListToStringArrayLegalMatch(sa); - } - - private void doTestCommaDelimitedListToStringArrayLegalMatch(String[] components) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < components.length; i++) { - if (i != 0) { - sb.append(","); - } - sb.append(components[i]); - } - String[] sa = Strings.commaDelimitedListToStringArray(sb.toString()); - assertTrue("String array isn't null with legal match", sa != null); - assertEquals("String array length is correct with legal match", components.length, sa.length); - assertTrue("Output equals input", Arrays.equals(sa, components)); - } - - - @Test - public void testParseLocaleStringSunnyDay() { - Locale expectedLocale = Locale.UK; - Locale locale = Strings.parseLocaleString(expectedLocale.toString()); - assertNotNull("When given a bona-fide Locale string, must not return null.", locale); - assertEquals(expectedLocale, locale); - } - - @Test - public void testParseLocaleStringWithMalformedLocaleString() { - Locale locale = Strings.parseLocaleString("_banjo_on_my_knee"); - assertNotNull("When given a malformed Locale string, must not return null.", locale); - } - - @Test - public void testParseLocaleStringWithEmptyLocaleStringYieldsNullLocale() { - Locale locale = Strings.parseLocaleString(""); - assertNull("When given an empty Locale string, must return null.", locale); - } - - @Test // SPR-8637 - public void testParseLocaleWithMultiSpecialCharactersInVariant() { - String variant = "proper-northern"; - String localeString = "en_GB_" + variant; - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-3671 - public void testParseLocaleWithMultiValuedVariant() { - String variant = "proper_northern"; - String localeString = "en_GB_" + variant; - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-3671 - public void testParseLocaleWithMultiValuedVariantUsingSpacesAsSeparators() { - String variant = "proper northern"; - String localeString = "en GB " + variant; - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-3671 - public void testParseLocaleWithMultiValuedVariantUsingMixtureOfUnderscoresAndSpacesAsSeparators() { - String variant = "proper northern"; - String localeString = "en_GB_" + variant; - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-3671 - public void testParseLocaleWithMultiValuedVariantUsingSpacesAsSeparatorsWithLotsOfLeadingWhitespace() { - String variant = "proper northern"; - String localeString = "en GB " + variant; // lots of whitespace - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-3671 - public void testParseLocaleWithMultiValuedVariantUsingUnderscoresAsSeparatorsWithLotsOfLeadingWhitespace() { - String variant = "proper_northern"; - String localeString = "en_GB_____" + variant; // lots of underscores - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Multi-valued variant portion of the Locale not extracted correctly.", variant, locale.getVariant()); - } - - @Test // SPR-7779 - public void testParseLocaleWithInvalidCharacters() { - try { - Strings.parseLocaleString("%0D%0AContent-length:30%0D%0A%0D%0A%3Cscript%3Ealert%28123%29%3C/script%3E"); - fail("Should have thrown IllegalArgumentException"); - } - catch (IllegalArgumentException ex) { - // expected - } - } - - @Test // SPR-9420 - public void testParseLocaleWithSameLowercaseTokenForLanguageAndCountry() { - assertEquals("tr_TR", Strings.parseLocaleString("tr_tr").toString()); - assertEquals("bg_BG_vnt", Strings.parseLocaleString("bg_bg_vnt").toString()); - } - - @Test // SPR-11806 - public void testParseLocaleWithVariantContainingCountryCode() { - String variant = "GBtest"; - String localeString = "en_GB_" + variant; - Locale locale = Strings.parseLocaleString(localeString); - assertEquals("Variant containing country code not extracted correctly", variant, locale.getVariant()); - } - - @Test // SPR-14718 - public void testParseJava7Variant() { - assertEquals("sr_#LATN", Strings.parseLocaleString("sr_#LATN").toString()); - } - -} \ No newline at end of file diff --git a/coverage/pom.xml b/coverage/pom.xml index 37d0b3cc6af..7e1f3904332 100644 --- a/coverage/pom.xml +++ b/coverage/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT okta-sdk-coverage diff --git a/examples/pom.xml b/examples/pom.xml index d6fe4fd00ba..84083235827 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT okta-sdk-examples diff --git a/examples/quickstart/pom.xml b/examples/quickstart/pom.xml index d8c0ab4533c..a33767f3f76 100644 --- a/examples/quickstart/pom.xml +++ b/examples/quickstart/pom.xml @@ -20,7 +20,7 @@ com.okta.sdk okta-sdk-examples - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT ../pom.xml diff --git a/examples/quickstart/src/main/java/quickstart/ReadmeSnippets.java b/examples/quickstart/src/main/java/quickstart/ReadmeSnippets.java index 9bc6e015dba..e0c685fac37 100644 --- a/examples/quickstart/src/main/java/quickstart/ReadmeSnippets.java +++ b/examples/quickstart/src/main/java/quickstart/ReadmeSnippets.java @@ -33,11 +33,12 @@ import com.okta.sdk.resource.user.User; import com.okta.sdk.resource.user.UserBuilder; import com.okta.sdk.resource.user.UserList; -import com.okta.sdk.resource.user.factor.Factor; -import com.okta.sdk.resource.user.factor.FactorList; -import com.okta.sdk.resource.user.factor.SmsFactor; +import com.okta.sdk.resource.user.factor.ActivateFactorRequest; +import com.okta.sdk.resource.user.factor.UserFactor; +import com.okta.sdk.resource.user.factor.UserFactorList; +import com.okta.sdk.resource.user.factor.SmsUserFactor; import com.okta.sdk.resource.user.factor.VerifyFactorRequest; -import com.okta.sdk.resource.user.factor.VerifyFactorResponse; +import com.okta.sdk.resource.user.factor.VerifyUserFactorResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -137,27 +138,27 @@ private void addUserToGroup() { } private void listUserFactors() { - FactorList factors = user.listFactors(); + UserFactorList factors = user.listFactors(); } private void enrollUserInFactor() { - SmsFactor smsFactor = client.instantiate(SmsFactor.class); + SmsUserFactor smsFactor = client.instantiate(SmsUserFactor.class); smsFactor.getProfile().setPhoneNumber("555 867 5309"); - user.addFactor(smsFactor); + user.enrollFactor(smsFactor); } private void activateFactor() { - Factor factor = user.getFactor("factorId"); - VerifyFactorRequest verifyFactorRequest = client.instantiate(VerifyFactorRequest.class); - verifyFactorRequest.setPassCode("123456"); - factor.activate(verifyFactorRequest); + UserFactor factor = user.getFactor("factorId"); + ActivateFactorRequest activateFactorRequest = client.instantiate(ActivateFactorRequest.class); + activateFactorRequest.setPassCode("123456"); + factor.activate(activateFactorRequest); } private void verifyFactor() { - Factor factor = user.getFactor("factorId"); + UserFactor factor = user.getFactor("factorId"); VerifyFactorRequest verifyFactorRequest = client.instantiate(VerifyFactorRequest.class); verifyFactorRequest.setPassCode("123456"); - VerifyFactorResponse response = factor.verify(verifyFactorRequest); + VerifyUserFactorResponse verifyUserFactorResponse = factor.setVerify(verifyFactorRequest).verify(); } private void listApplication() { diff --git a/httpclients/httpclient/pom.xml b/httpclients/httpclient/pom.xml index 27fb7510210..4890078d5bd 100644 --- a/httpclients/httpclient/pom.xml +++ b/httpclients/httpclient/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT ../.. diff --git a/httpclients/okhttp/pom.xml b/httpclients/okhttp/pom.xml index 15882b4113b..3d9ca2f4aa9 100644 --- a/httpclients/okhttp/pom.xml +++ b/httpclients/okhttp/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT ../.. diff --git a/impl/pom.xml b/impl/pom.xml index 74a66e0e3f2..3a9a6b9c94d 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT okta-sdk-impl @@ -121,6 +121,11 @@ slf4j-simple test + + com.okta.sdk + okta-sdk-api + 2.0.0-SNAPSHOT + diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/CacheConfiguration.java b/impl/src/main/java/com/okta/sdk/impl/cache/CacheConfiguration.java index 1234f2f3d63..13e8e14163d 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/CacheConfiguration.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/CacheConfiguration.java @@ -16,7 +16,7 @@ */ package com.okta.sdk.impl.cache; -import com.okta.sdk.lang.Duration; +import java.time.Duration; /** * Represents configuration settings for a particular {@link com.okta.sdk.cache.Cache Cache} region. diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCache.java b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCache.java index 8dd07bf47a2..d70c0d60531 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCache.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCache.java @@ -19,12 +19,11 @@ import com.okta.sdk.cache.Cache; import com.okta.sdk.impl.util.SoftHashMap; import com.okta.commons.lang.Assert; -import com.okta.sdk.lang.Duration; +import java.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; /** @@ -72,16 +71,16 @@ public class DefaultCache implements Cache { * This constructor uses a {@link SoftHashMap} instance as the cache's backing map, which is thread-safe and * auto-sizes itself based on the application's memory constraints. *

- * Finally, the {@link #setTimeToIdle(com.okta.sdk.lang.Duration) timeToIdle} and - * {@link #setTimeToLive(com.okta.sdk.lang.Duration) timeToLive} settings are both {@code null}, + * Finally, the {@link #setTimeToIdle(java.time.Duration) timeToIdle} and + * {@link #setTimeToLive(java.time.Duration) timeToLive} settings are both {@code null}, * indicating that cache entries will live indefinitely (except due to memory constraints as managed by the * {@code SoftHashMap}). * * @param name the name to assign to this instance, expected to be unique among all other caches in the parent * {@code CacheManager}. * @see SoftHashMap - * @see #setTimeToIdle(com.okta.sdk.lang.Duration) - * @see #setTimeToLive(com.okta.sdk.lang.Duration) + * @see #setTimeToIdle(java.time.Duration) + * @see #setTimeToLive(java.time.Duration) */ public DefaultCache(String name) { this(name, new SoftHashMap>()); @@ -92,8 +91,8 @@ public DefaultCache(String name) { * {@code backingMap}. It is expected that the {@code backingMap} implementation be thread-safe and preferrably * auto-sizing based on memory constraints (see {@link SoftHashMap} for such an implementation). *

- * The {@link #setTimeToIdle(com.okta.sdk.lang.Duration) timeToIdle} and - * {@link #setTimeToLive(com.okta.sdk.lang.Duration) timeToLive} settings are both {@code null}, + * The {@link #setTimeToIdle(java.time.Duration) timeToIdle} and + * {@link #setTimeToLive(java.time.Duration) timeToLive} settings are both {@code null}, * indicating that cache entries will live indefinitely (except due to memory constraints as managed by the * {@code backingMap} instance). * @@ -101,8 +100,8 @@ public DefaultCache(String name) { * {@code CacheManager}. * @param backingMap the (ideally thread-safe) map instance to store the Cache entries. * @see SoftHashMap - * @see #setTimeToIdle(com.okta.sdk.lang.Duration) - * @see #setTimeToLive(com.okta.sdk.lang.Duration) + * @see #setTimeToIdle(java.time.Duration) + * @see #setTimeToLive(java.time.Duration) */ public DefaultCache(String name, Map> backingMap) { this(name, backingMap, null, null); @@ -123,8 +122,8 @@ public DefaultCache(String name, Map> backingMap) { * @throws IllegalArgumentException if either {@code timeToLive} or {@code timeToIdle} are non-null and * represent a non-positive (zero or negative) value. This is only enforced for * non-null values - {@code null} values are allowed for either argument. - * @see #setTimeToIdle(com.okta.sdk.lang.Duration) - * @see #setTimeToLive(com.okta.sdk.lang.Duration) + * @see #setTimeToIdle(java.time.Duration) + * @see #setTimeToLive(java.time.Duration) */ public DefaultCache(String name, Map> backingMap, Duration timeToLive, Duration timeToIdle) { Assert.notNull(name, "Cache name cannot be null."); @@ -142,13 +141,13 @@ public DefaultCache(String name, Map> backingMap, Duration timeToLiv protected static void assertTtl(Duration ttl) { if (ttl != null) { - Assert.isTrue(ttl.getValue() > 0, "timeToLive duration must be greater than zero"); + Assert.isTrue(!ttl.isZero() && !ttl.isNegative(), "timeToLive duration must be greater than zero"); } } protected static void assertTti(Duration tti) { if (tti != null) { - Assert.isTrue(tti.getValue() > 0, "timeToIdle duration must be greater than zero"); + Assert.isTrue(!tti.isZero() && !tti.isNegative(), "timeToIdle duration must be greater than zero"); } } @@ -169,8 +168,8 @@ public V get(K key) { Duration tti = this.timeToIdle; if (ttl != null) { - Duration sinceCreation = new Duration(nowMillis - entry.getCreationTimeMillis(), TimeUnit.MILLISECONDS); - if (sinceCreation.isGreaterThan(ttl)) { + Duration sinceCreation = Duration.ofMillis(nowMillis - entry.getCreationTimeMillis()); + if (sinceCreation.compareTo(ttl) > 0) { map.remove(key); missCount.incrementAndGet(); //count an expired TTL as a miss logger.trace("Removing {} from cache due to TTL, sinceCreation: {}", key, sinceCreation); @@ -179,8 +178,8 @@ public V get(K key) { } if (tti != null) { - Duration sinceLastAccess = new Duration(nowMillis - entry.getLastAccessTimeMillis(), TimeUnit.MILLISECONDS); - if (sinceLastAccess.isGreaterThan(tti)) { + Duration sinceLastAccess = Duration.ofMillis(nowMillis - entry.getLastAccessTimeMillis()); + if (sinceLastAccess.compareTo(tti) > 0) { map.remove(key); missCount.incrementAndGet(); //count an expired TTI as a miss logger.trace("Removing {} from cache due to TTI, sinceLastAccess: {}", key, sinceLastAccess); diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfiguration.java b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfiguration.java index 97f445397b1..d1d8d65fcf8 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfiguration.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfiguration.java @@ -17,7 +17,7 @@ package com.okta.sdk.impl.cache; import com.okta.commons.lang.Assert; -import com.okta.sdk.lang.Duration; +import java.time.Duration; import java.util.concurrent.TimeUnit; @@ -38,8 +38,9 @@ public DefaultCacheConfiguration(String name, Duration timeToLive, Duration time } static Duration toDuration(long value, TimeUnit tu) { - if (value > 0) { - return new Duration(value, tu); + long timeInMillis = TimeUnit.MILLISECONDS.convert(value, tu); + if (timeInMillis > 0) { + return Duration.ofMillis(timeInMillis); } return null; } diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfigurationBuilder.java b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfigurationBuilder.java index ac5adb00b17..689d56dc113 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfigurationBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheConfigurationBuilder.java @@ -18,7 +18,7 @@ import com.okta.commons.lang.Assert; import com.okta.sdk.cache.CacheConfigurationBuilder; -import com.okta.sdk.lang.Duration; +import java.time.Duration; import java.util.concurrent.TimeUnit; diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManager.java b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManager.java index 54bc1348dae..572285f0e25 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManager.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManager.java @@ -20,7 +20,7 @@ import com.okta.sdk.cache.Cache; import com.okta.sdk.cache.CacheManager; import com.okta.sdk.impl.util.SoftHashMap; -import com.okta.sdk.lang.Duration; +import java.time.Duration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,29 +49,29 @@ * no longer be available. If a cache entry is not accessed at all after this amount of time, it will be * removed from the cache as soon as possible. *

- * This implementation's {@link #setDefaultTimeToIdle(com.okta.sdk.lang.Duration) defaultTimeToIdle} + * This implementation's {@link #setDefaultTimeToIdle(java.time.Duration) defaultTimeToIdle} * is {@code null}, which means that cache entries can potentially remain idle indefinitely. Note however that a * cache entry can still be expunged due to other conditions (e.g. memory constraints, Time to Live setting, etc). *

- * The {@link #setDefaultTimeToIdle(com.okta.sdk.lang.Duration) defaultTimeToIdle} setting is only + * The {@link #setDefaultTimeToIdle(java.time.Duration) defaultTimeToIdle} setting is only * applied to newly created {@code Cache} instances. It does not affect already existing {@code Cache}s. *

Time to Live

* Time to Live is the amount of time a cache entry may exist after first being created before it will expire and no * longer be available. If a cache entry ever becomes older than this amount of time (regardless of how often * it is accessed), it will be removed from the cache as soon as possible. *

- * This implementation's {@link #setDefaultTimeToLive(com.okta.sdk.lang.Duration) defaultTimeToLive} + * This implementation's {@link #setDefaultTimeToLive(java.time.Duration) defaultTimeToLive} * is {@code null}, which means that cache entries could potentially live indefinitely. Note however that a * cache entry can still be expunged due to other conditions (e.g. memory constraints, Time to Idle setting, etc). *

- * The {@link #setDefaultTimeToLive(com.okta.sdk.lang.Duration) defaultTimeToLive} setting is only + * The {@link #setDefaultTimeToLive(java.time.Duration) defaultTimeToLive} setting is only * applied to newly created {@code Cache} instances. It does not affect already existing {@code Cache}s. *

Thread Safety

* This implementation and the cache instances it creates are thread-safe and usable in concurrent environments. * - * @see #setDefaultTimeToIdle(com.okta.sdk.lang.Duration) + * @see #setDefaultTimeToIdle(java.time.Duration) * @see #setDefaultTimeToIdleSeconds(long) - * @see #setDefaultTimeToLive(com.okta.sdk.lang.Duration) + * @see #setDefaultTimeToLive(java.time.Duration) * @see #setDefaultTimeToLiveSeconds(long) * @since 0.5.0 */ @@ -127,13 +127,13 @@ public void setDefaultTimeToLive(Duration defaultTimeToLive) { } /** - * Convenience method that sets the {@link #setDefaultTimeToLive(com.okta.sdk.lang.Duration) defaultTimeToLive} + * Convenience method that sets the {@link #setDefaultTimeToLive(java.time.Duration) defaultTimeToLive} * value using a {@code TimeUnit} of {@link TimeUnit#SECONDS}. * - * @param seconds the {@link #setDefaultTimeToLive(com.okta.sdk.lang.Duration) defaultTimeToLive} value in seconds. + * @param seconds the {@link #setDefaultTimeToLive(java.time.Duration) defaultTimeToLive} value in seconds. */ public void setDefaultTimeToLiveSeconds(long seconds) { - setDefaultTimeToLive(new Duration(seconds, TimeUnit.SECONDS)); + setDefaultTimeToLive(Duration.ofSeconds(seconds)); } /** @@ -162,13 +162,13 @@ public void setDefaultTimeToIdle(Duration defaultTimeToIdle) { } /** - * Convenience method that sets the {@link #setDefaultTimeToIdle(com.okta.sdk.lang.Duration) defaultTimeToIdle} + * Convenience method that sets the {@link #setDefaultTimeToIdle(java.time.Duration) defaultTimeToIdle} * value using a {@code TimeUnit} of {@link TimeUnit#SECONDS}. * - * @param seconds the {@link #setDefaultTimeToIdle(com.okta.sdk.lang.Duration) defaultTimeToIdle} value in seconds. + * @param seconds the {@link #setDefaultTimeToIdle(java.time.Duration) defaultTimeToIdle} value in seconds. */ public void setDefaultTimeToIdleSeconds(long seconds) { - setDefaultTimeToIdle(new Duration(seconds, TimeUnit.SECONDS)); + setDefaultTimeToIdle(Duration.ofSeconds(seconds)); } /** @@ -221,8 +221,8 @@ public Cache getCache(String name) throws IllegalArgumentException */ @SuppressWarnings("unchecked") protected Cache createCache(String name) { - Duration ttl = this.defaultTimeToLive != null ? this.defaultTimeToLive.clone() : null; - Duration tti = this.defaultTimeToIdle != null ? this.defaultTimeToIdle.clone() : null; + Duration ttl = this.defaultTimeToLive != null ? Duration.from(this.defaultTimeToLive) : null; + Duration tti = this.defaultTimeToIdle != null ? Duration.from(this.defaultTimeToIdle) : null; CacheConfiguration config = this.configs.get(name); if (config != null) { diff --git a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManagerBuilder.java b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManagerBuilder.java index 6334948257d..5a5a0053134 100644 --- a/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManagerBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/cache/DefaultCacheManagerBuilder.java @@ -21,7 +21,7 @@ import com.okta.sdk.cache.CacheConfigurationBuilder; import com.okta.sdk.cache.CacheManager; import com.okta.sdk.cache.CacheManagerBuilder; -import com.okta.sdk.lang.Duration; +import java.time.Duration; import java.util.LinkedHashSet; import java.util.Set; diff --git a/impl/src/main/java/com/okta/sdk/impl/client/AbstractClient.java b/impl/src/main/java/com/okta/sdk/impl/client/AbstractClient.java deleted file mode 100644 index 50aeb0fd47e..00000000000 --- a/impl/src/main/java/com/okta/sdk/impl/client/AbstractClient.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.impl.client; - -import com.okta.sdk.cache.CacheManager; -import com.okta.sdk.client.Client; -import com.okta.sdk.impl.config.ClientConfiguration; -import com.okta.sdk.impl.ds.InternalDataStore; - -/** - * Abstract client implementation, use BaseClient instead. Kept only for backwards compatibility, this class will - * be removed in future versions. - * - * @deprecated see {@link BaseClient} - * @see Communicating with Okta: Get your API Token - * @since 0.5.0 - */ -@Deprecated -public abstract class AbstractClient extends BaseClient implements Client { - - - public AbstractClient(ClientConfiguration clientConfiguration, CacheManager cacheManager) { - super(clientConfiguration, cacheManager); - } - - @Override - @SuppressWarnings("PMD.UselessOverridingMethod") - public InternalDataStore getDataStore() { - return super.getDataStore(); - } -} diff --git a/impl/src/main/java/com/okta/sdk/impl/client/DefaultClientBuilder.java b/impl/src/main/java/com/okta/sdk/impl/client/DefaultClientBuilder.java index dbf8defa788..10144e5b7ed 100644 --- a/impl/src/main/java/com/okta/sdk/impl/client/DefaultClientBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/client/DefaultClientBuilder.java @@ -30,7 +30,7 @@ import com.okta.sdk.client.AuthorizationMode; import com.okta.sdk.client.Client; import com.okta.sdk.client.ClientBuilder; -import com.okta.sdk.client.Proxy; +import com.okta.commons.http.config.Proxy; import com.okta.sdk.impl.api.ClientCredentialsResolver; import com.okta.sdk.impl.api.DefaultClientCredentialsResolver; import com.okta.sdk.impl.config.ClientConfiguration; @@ -266,11 +266,6 @@ public ClientBuilder setCacheManager(CacheManager cacheManager) { return this; } - @Override - public ClientBuilder setAuthenticationScheme(AuthenticationScheme authenticationScheme) { - return setAuthorizationMode(AuthorizationMode.get(authenticationScheme)); - } - @Override public ClientBuilder setConnectionTimeout(int timeout) { Assert.isTrue(timeout >= 0, "Timeout cannot be a negative number."); diff --git a/impl/src/main/java/com/okta/sdk/impl/ds/DiscriminatorRegistry.java b/impl/src/main/java/com/okta/sdk/impl/ds/DiscriminatorRegistry.java index 87af2b2a77a..a242174cd8b 100644 --- a/impl/src/main/java/com/okta/sdk/impl/ds/DiscriminatorRegistry.java +++ b/impl/src/main/java/com/okta/sdk/impl/ds/DiscriminatorRegistry.java @@ -19,7 +19,7 @@ /** * A DiscriminatorRegistry allows for the resolution of a specific type, based on the data of the object. - * For example, the Factors API return a collection of {@link com.okta.sdk.resource.user.factor.Factor Factor} objects, + * For example, the Factors API return a collection of {@link com.okta.sdk.resource.user.factor.UserFactor UserFactor} objects, * The actual type is dependent on a property of the data map 'factorType'. * * @since 0.8.0 diff --git a/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequest.java b/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequest.java deleted file mode 100644 index 42cd6037a07..00000000000 --- a/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.impl.http; - -import com.okta.sdk.http.HttpMethod; -import com.okta.sdk.http.HttpRequest; -import com.okta.commons.lang.Assert; -import com.okta.commons.lang.Collections; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.StringTokenizer; - -/** - * This is the default implementation for {@link HttpRequest} interface. - * - * @since 0.5.0 - * @deprecated not used - */ -@Deprecated -public class DefaultHttpRequest implements HttpRequest { - - private final Map headers; - private final HttpMethod method; - private final String queryParameters; - private Map parameters; - - public DefaultHttpRequest(Map headers, HttpMethod method, Map parameters, String queryParameters) { - Assert.notNull(method, "method cannot be null."); - Assert.notNull(headers, "headers cannot be null."); - - this.headers = headers; - this.method = method; - this.parameters = parameters; - this.queryParameters = queryParameters; - } - - @Override - public Map getHeaders() { - return headers; - } - - @Override - public String getHeader(String headerName) { - if (Collections.isEmpty(headers)) { - return null; - } - - for (Map.Entry entry : headers.entrySet()) { - if (entry.getKey().equalsIgnoreCase(headerName)) { - String[] values = entry.getValue(); - if (values == null || values.length == 0) { - return null; - } - return values[0]; - } - } - return null; - } - - @Override - public HttpMethod getMethod() { - return method; - } - - @Override - public Map getParameters() { - if (parameters == null || parameters.isEmpty()) { - parseParameters(); - } - return parameters; - } - - @Override - public String getParameter(String parameterName) { - - Map httpParameters = getParameters(); - - if (httpParameters == null) { - return null; - } - - String[] values = httpParameters.get(parameterName); - - if (values == null || values.length == 0) { - return null; - } - - return values[0]; - } - - @Override - public String getQueryParameters() { - return queryParameters; - } - - private void parseParameters() { - if (queryParameters == null || queryParameters.isEmpty()) { - return; - } - - Map> tempParameters = new HashMap>(); - - for (StringTokenizer tokenizer = new StringTokenizer(queryParameters, "&"); tokenizer.hasMoreElements(); ) { - String token = tokenizer.nextToken(); - - String[] pair = token.split("="); - - Assert.isTrue(pair.length == 2, "this query parameter is invalid."); - - List values; - if (tempParameters.containsKey(pair[0])) { - values = tempParameters.get(pair[0]); - } else { - values = new ArrayList(); - tempParameters.put(pair[0], values); - } - values.add(pair[1]); - } - - parameters = new HashMap(); - - for (Map.Entry> entry : tempParameters.entrySet()) { - List valuesList = entry.getValue(); - String[] valuesArray = new String[valuesList.size()]; - valuesList.toArray(valuesArray); - parameters.put(entry.getKey(), valuesArray); - } - } - -} diff --git a/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequestBuilder.java b/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequestBuilder.java deleted file mode 100644 index 660209b010a..00000000000 --- a/impl/src/main/java/com/okta/sdk/impl/http/DefaultHttpRequestBuilder.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.impl.http; - -import com.okta.sdk.http.HttpMethod; -import com.okta.sdk.http.HttpRequest; -import com.okta.sdk.http.HttpRequestBuilder; -import com.okta.commons.lang.Assert; - -import java.util.HashMap; -import java.util.Map; - -/** - * DefaultHttpRequestBuilder - * - * @since 0.5.0 - * @deprecated not used - */ -@Deprecated -public class DefaultHttpRequestBuilder implements HttpRequestBuilder { - - private HttpMethod method; - private Map headers; - private Map parameters; - private String queryParameters; - - public DefaultHttpRequestBuilder(HttpMethod method) { - Assert.notNull(method); - this.method = method; - this.headers = new HashMap<>(); - this.parameters = new HashMap<>(); - } - - @Override - public HttpRequestBuilder headers(Map headers) { - Assert.notNull(headers, "headers cannot be null"); - this.headers = headers; - return this; - } - - @Override - public HttpRequestBuilder parameters(Map parameters) { - Assert.notNull(parameters, "parameters cannot be null"); - this.parameters = parameters; - return this; - } - - @Override - public HttpRequestBuilder addHeader(String key, String[] value) { - Assert.notNull(key, "key argument is required."); - Assert.notNull(value, "value argument is required."); - - this.headers.put(key, value); - return this; - } - - @Override - public HttpRequestBuilder addParameter(String key, String[] value) { - Assert.notNull(key, "key argument is required."); - Assert.notNull(value, "value argument is required."); - - this.parameters.put(key, value); - return this; - } - - @Override - public HttpRequestBuilder queryParameters(String queryParameters) { - this.queryParameters = queryParameters; - return this; - } - - @Override - public HttpRequest build() { - return new DefaultHttpRequest(headers, method, parameters, queryParameters); - } -} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultGroupRuleBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultGroupRuleBuilder.java index 41e0b973cc9..afdbca58270 100644 --- a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultGroupRuleBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultGroupRuleBuilder.java @@ -22,13 +22,11 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; public class DefaultGroupRuleBuilder implements GroupRuleBuilder { private String name; private String type; - private Boolean allGroupsValid; private List assignUserToGroups = new ArrayList<>(); private List groupIds = new ArrayList<>(); private List userIds = new ArrayList<>(); @@ -47,12 +45,6 @@ public GroupRuleBuilder setType(String type) { return this; } - @Override - public GroupRuleBuilder setAllGroupsValid(Boolean allGroupsValid) { - this.allGroupsValid = allGroupsValid; - return this; - } - @Override public GroupRuleBuilder setAssignUserToGroups(List assignUserToGroups) { this.assignUserToGroups = assignUserToGroups; @@ -97,7 +89,7 @@ public GroupRuleBuilder setGroupRuleExpressionValue(String groupRuleExpressionVa @Override public GroupRule buildAndCreate(Client client) { - return client.createRule(build(client)); + return client.createGroupRule(build(client)); } private GroupRule build(Client client){ @@ -107,8 +99,6 @@ private GroupRule build(Client client){ if (Strings.hasText(type)) groupRule.setType(type); - if (Objects.nonNull(allGroupsValid)) groupRule.setAllGroupsValid(allGroupsValid); - // Actions groupRule.setActions(client.instantiate(GroupRuleAction.class)); GroupRuleAction groupRuleActions = groupRule.getActions(); diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilder.java index 333f12d2e23..a44abab0bdd 100644 --- a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilder.java @@ -93,14 +93,12 @@ public PasswordPolicyRuleBuilder setPasswordChangeAccess(PasswordPolicyRuleActio @Override public PasswordPolicyRule buildAndCreate(Client client, Policy policy){ - return (PasswordPolicyRule) policy.createRule(build(client), isActive); + return (PasswordPolicyRule) policy.createRule(build(client)); } private PasswordPolicyRule build(Client client){ PasswordPolicyRule policyRule = client.instantiate(PasswordPolicyRule.class); - if (Strings.hasText(id)) policyRule.setId(id); - if (Objects.nonNull(priority)) policyRule.setPriority(priority); if (Objects.nonNull(status)) policyRule.setStatus(status); diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilder.java index 4ccde484ab4..437a4322d3e 100644 --- a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilder.java @@ -15,7 +15,6 @@ */ package com.okta.sdk.impl.resource; -import com.okta.commons.lang.Strings; import com.okta.sdk.client.Client; import com.okta.sdk.resource.policy.Policy; import com.okta.sdk.resource.policy.PolicyRule; @@ -25,20 +24,12 @@ public class DefaultPolicyRuleBuilder implements PolicyRuleBuilder { - protected String id; protected Integer priority; protected PolicyRule.TypeEnum type; protected PolicyRule.StatusEnum status; - protected Boolean isActive = true; DefaultPolicyRuleBuilder(){ this.type = PolicyRule.TypeEnum.SIGN_ON; } - @Override - public T setId(String id) { - this.id = id; - return self(); - } - @Override public T setPriority(Integer priority) { this.priority = priority; @@ -48,10 +39,6 @@ public T setPriority(Integer priority) { @Override public T setStatus(PolicyRule.StatusEnum status) { this.status = status; - if (PolicyRule.StatusEnum.ACTIVE.equals(status)) - isActive = true; - else - isActive = false; return self(); } @@ -63,7 +50,7 @@ public T setType(PolicyRule.TypeEnum type) { @Override public PolicyRule buildAndCreate(Client client, Policy policy) { - return (PolicyRule)policy.createRule(build(client), isActive); + return (PolicyRule) policy.createRule(build(client)); } @SuppressWarnings("unchecked") @@ -74,8 +61,6 @@ protected T self() { private PolicyRule build(Client client){ PolicyRule policyRule = client.instantiate(PolicyRule.class); - if (Strings.hasText(id)) policyRule.setId(id); - if (Objects.nonNull(priority)) policyRule.setPriority(priority); if (Objects.nonNull(status)) policyRule.setStatus(status); diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilder.java index 36acafeddb1..c2e99420f98 100644 --- a/impl/src/main/java/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilder.java +++ b/impl/src/main/java/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilder.java @@ -41,8 +41,6 @@ public class DefaultSignOnPolicyRuleBuilder extends DefaultPolicyRuleBuilder String fixSelfHref(Map properties, Class return href.substring(0, href.lastIndexOf("/users")); } } + if (Role.class.isAssignableFrom(clazz)) { + Map assignee = getMapValue(links, "assignee"); + if (!Collections.isEmpty(assignee)) { + String href = assignee.get("href").toString(); + return href + "/roles/" + properties.get("id"); + } + } } if (Group.class.isAssignableFrom(clazz)) { diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/event/hook/DefaultEventHookBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/event/hook/DefaultEventHookBuilder.java new file mode 100644 index 00000000000..c6728089516 --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/event/hook/DefaultEventHookBuilder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.event.hook; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.net.HttpHeaders; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.event.hook.EventHook; +import com.okta.sdk.resource.event.hook.EventHookBuilder; +import com.okta.sdk.resource.event.hook.EventHookChannel; +import com.okta.sdk.resource.event.hook.EventHookChannelConfig; +import com.okta.sdk.resource.event.hook.EventHookChannelConfigHeader; +import com.okta.sdk.resource.event.hook.EventHookChannelConfigAuthScheme; +import com.okta.sdk.resource.event.hook.EventHookChannelConfigAuthSchemeType; +import com.okta.sdk.resource.event.hook.EventSubscriptions; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * Builder for {@link EventHook}. + * @since 2.0.0 + */ +public class DefaultEventHookBuilder implements EventHookBuilder { + + private static final String LIFECYCLE_EVENT_CREATE = "user.lifecycle.create"; + private static final String LIFECYCLE_EVENT_ACTIVATE = "user.lifecycle.activate"; + + private static final String VERSION = "1.0.0"; + + private String name; + private String url; + private String authorizationHeaderValue; + private Map headerMap = Maps.newHashMap(); + + @Override + public EventHookBuilder setName(String name) { + this.name = name; + return this; + } + + @Override + public EventHookBuilder setUrl(String url) { + this.url = url; + return this; + } + + @Override + public EventHookBuilder setAuthorizationHeaderValue(String authorizationHeaderValue) { + this.authorizationHeaderValue = authorizationHeaderValue; + return this; + } + + @Override + public EventHookBuilder addHeader(String name, String value) { + headerMap.put(name, value); + return this; + } + + @Override + public EventHook buildAndCreate(Client client) { + + EventSubscriptions eventSubscriptions = client.instantiate(EventSubscriptions.class) + .setType(EventSubscriptions.TypeEnum.EVENT_TYPE) + .setItems(Arrays.asList(LIFECYCLE_EVENT_CREATE, LIFECYCLE_EVENT_ACTIVATE)); + + EventHookChannelConfigAuthScheme eventHookChannelConfigAuthScheme = + client.instantiate(EventHookChannelConfigAuthScheme.class) + .setType(EventHookChannelConfigAuthSchemeType.HEADER) + .setKey(HttpHeaders.AUTHORIZATION) + .setValue(authorizationHeaderValue); + + List headers = Lists.newArrayList(); + + for (Map.Entry entry : headerMap.entrySet()) { + headers.add(client.instantiate(EventHookChannelConfigHeader.class) + .setKey(entry.getKey()) + .setValue(entry.getValue())); + } + + EventHookChannelConfig eventHookChannelConfig = client.instantiate(EventHookChannelConfig.class) + .setUri(url) + .setHeaders(headers) + .setAuthScheme(eventHookChannelConfigAuthScheme); + + EventHookChannel eventHookChannel = client.instantiate(EventHookChannel.class) + .setType(EventHookChannel.TypeEnum.HTTP) + .setVersion(VERSION) + .setConfig(eventHookChannelConfig); + + EventHook createdEventHook = client.createEventHook(client.instantiate(EventHook.class) + .setName(name) + .setEvents(eventSubscriptions) + .setChannel(eventHookChannel)); + + return createdEventHook; + } + +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/DefaultIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/DefaultIdentityProviderBuilder.java new file mode 100644 index 00000000000..11b14cf7fcd --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/DefaultIdentityProviderBuilder.java @@ -0,0 +1,99 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderBuilder; +import com.okta.sdk.resource.policy.PolicySubjectMatchType; + +import java.util.List; + +@SuppressWarnings("rawtypes") +public class DefaultIdentityProviderBuilder implements IdentityProviderBuilder { + + protected String name; + protected String clientId; + protected String clientSecret; + protected List scopes; + protected Integer maxClockSkew; + protected String userName; + protected PolicySubjectMatchType matchType; + protected Boolean isProfileMaster; + + @Override + public T setName(String name) { + this.name = name; + return self(); + } + + @Override + public T setClientId(String clientId) { + this.clientId = clientId; + return self(); + } + + @Override + public T setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return self(); + } + + @Override + public T setScopes(List scopes) { + this.scopes = scopes; + return self(); + } + + @Override + public T setMaxClockSkew(Integer maxClockSkew) { + this.maxClockSkew = maxClockSkew; + return self(); + } + + @Override + public T setUserName(String userName) { + this.userName = userName; + return self(); + } + + @Override + public T setMatchType(PolicySubjectMatchType matchType) { + this.matchType = matchType; + return self(); + } + + @Override + public T setIsProfileMaster(Boolean isProfileMaster) { + this.isProfileMaster = isProfileMaster; + return self(); + } + + @Override + public T isProfileMaster(Boolean isProfileMaster) { + return setIsProfileMaster(isProfileMaster); + } + + @Override + public IdentityProvider buildAndCreate(Client client) { + return client.createIdentityProvider(client.instantiate(IdentityProvider.class)); + } + + @SuppressWarnings("unchecked") + protected T self() { + return (T) this; + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/FacebookIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/FacebookIdentityProviderBuilder.java new file mode 100644 index 00000000000..e98be7ae611 --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/FacebookIdentityProviderBuilder.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentials; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentialsClient; +import com.okta.sdk.resource.identity.provider.Protocol; +import com.okta.sdk.resource.identity.provider.Provisioning; +import com.okta.sdk.resource.identity.provider.ProvisioningConditions; +import com.okta.sdk.resource.identity.provider.ProvisioningDeprovisionedCondition; +import com.okta.sdk.resource.identity.provider.ProvisioningGroups; +import com.okta.sdk.resource.identity.provider.ProvisioningSuspendedCondition; +import com.okta.sdk.resource.policy.IdentityProviderPolicy; +import com.okta.sdk.resource.policy.PolicyAccountLink; +import com.okta.sdk.resource.policy.PolicySubject; +import com.okta.sdk.resource.policy.PolicyUserNameTemplate; + +public class FacebookIdentityProviderBuilder extends DefaultIdentityProviderBuilder { + + @Override + public IdentityProvider buildAndCreate(Client client) { + + IdentityProvider createdIdp = client.createIdentityProvider(client.instantiate(IdentityProvider.class) + .setType(IdentityProvider.TypeEnum.FACEBOOK) + .setName(name) + .setProtocol(client.instantiate(Protocol.class) + .setType(Protocol.TypeEnum.OAUTH2) + .setScopes(scopes) + .setCredentials(client.instantiate(IdentityProviderCredentials.class) + .setClient(client.instantiate(IdentityProviderCredentialsClient.class) + .setClientId(clientId) + .setClientSecret(clientSecret)))) + .setPolicy(client.instantiate(IdentityProviderPolicy.class) + .setProvisioning(client.instantiate(Provisioning.class) + .setAction(Provisioning.ActionEnum.AUTO) + .setProfileMaster(isProfileMaster) + .setGroups(client.instantiate(ProvisioningGroups.class) + .setAction(ProvisioningGroups.ActionEnum.NONE)) + .setConditions(client.instantiate(ProvisioningConditions.class) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition.class) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition.class) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE)))) + .setAccountLink(client.instantiate(PolicyAccountLink.class) + .setFilter(null) + .setAction(PolicyAccountLink.ActionEnum.AUTO)) + .setSubject(client.instantiate(PolicySubject.class) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate.class) + .setTemplate(userName)) + .setMatchType(matchType)) + .setMaxClockSkew(maxClockSkew))); + + return createdIdp; + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/GoogleIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/GoogleIdentityProviderBuilder.java new file mode 100644 index 00000000000..7ab435bd42d --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/GoogleIdentityProviderBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentials; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentialsClient; +import com.okta.sdk.resource.identity.provider.Protocol; +import com.okta.sdk.resource.identity.provider.Provisioning; +import com.okta.sdk.resource.identity.provider.ProvisioningConditions; +import com.okta.sdk.resource.identity.provider.ProvisioningDeprovisionedCondition; +import com.okta.sdk.resource.identity.provider.ProvisioningGroups; +import com.okta.sdk.resource.identity.provider.ProvisioningSuspendedCondition; +import com.okta.sdk.resource.policy.IdentityProviderPolicy; +import com.okta.sdk.resource.policy.PolicyAccountLink; +import com.okta.sdk.resource.policy.PolicySubject; +import com.okta.sdk.resource.policy.PolicyUserNameTemplate; + +public class GoogleIdentityProviderBuilder extends DefaultIdentityProviderBuilder { + + @Override + public IdentityProvider buildAndCreate(Client client) { + + return client.createIdentityProvider(client.instantiate(IdentityProvider.class) + .setType(IdentityProvider.TypeEnum.GOOGLE) + .setName(name) + .setProtocol(client.instantiate(Protocol.class) + .setType(Protocol.TypeEnum.OIDC) + .setScopes(scopes) + .setCredentials(client.instantiate(IdentityProviderCredentials.class) + .setClient(client.instantiate(IdentityProviderCredentialsClient.class) + .setClientId(clientId) + .setClientSecret(clientSecret)))) + .setPolicy(client.instantiate(IdentityProviderPolicy.class) + .setProvisioning(client.instantiate(Provisioning.class) + .setAction(Provisioning.ActionEnum.AUTO) + .setProfileMaster(isProfileMaster) + .setGroups(client.instantiate(ProvisioningGroups.class) + .setAction(ProvisioningGroups.ActionEnum.NONE)) + .setConditions(client.instantiate(ProvisioningConditions.class) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition.class) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition.class) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE)))) + .setAccountLink(client.instantiate(PolicyAccountLink.class) + .setFilter(null) + .setAction(PolicyAccountLink.ActionEnum.AUTO)) + .setSubject(client.instantiate(PolicySubject.class) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate.class) + .setTemplate(userName)) + .setMatchType(matchType)) + .setMaxClockSkew(maxClockSkew))); + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/LinkedInIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/LinkedInIdentityProviderBuilder.java new file mode 100644 index 00000000000..c75baedfed2 --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/LinkedInIdentityProviderBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentials; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentialsClient; +import com.okta.sdk.resource.identity.provider.Protocol; +import com.okta.sdk.resource.identity.provider.Provisioning; +import com.okta.sdk.resource.identity.provider.ProvisioningConditions; +import com.okta.sdk.resource.identity.provider.ProvisioningDeprovisionedCondition; +import com.okta.sdk.resource.identity.provider.ProvisioningGroups; +import com.okta.sdk.resource.identity.provider.ProvisioningSuspendedCondition; +import com.okta.sdk.resource.policy.IdentityProviderPolicy; +import com.okta.sdk.resource.policy.PolicyAccountLink; +import com.okta.sdk.resource.policy.PolicySubject; +import com.okta.sdk.resource.policy.PolicyUserNameTemplate; + +public class LinkedInIdentityProviderBuilder extends DefaultIdentityProviderBuilder { + + @Override + public IdentityProvider buildAndCreate(Client client) { + + return client.createIdentityProvider(client.instantiate(IdentityProvider.class) + .setType(IdentityProvider.TypeEnum.LINKEDIN) + .setName(name) + .setProtocol(client.instantiate(Protocol.class) + .setType(Protocol.TypeEnum.OAUTH2) + .setScopes(scopes) + .setCredentials(client.instantiate(IdentityProviderCredentials.class) + .setClient(client.instantiate(IdentityProviderCredentialsClient.class) + .setClientId(clientId) + .setClientSecret(clientSecret)))) + .setPolicy(client.instantiate(IdentityProviderPolicy.class) + .setProvisioning(client.instantiate(Provisioning.class) + .setAction(Provisioning.ActionEnum.AUTO) + .setProfileMaster(isProfileMaster) + .setGroups(client.instantiate(ProvisioningGroups.class) + .setAction(ProvisioningGroups.ActionEnum.NONE)) + .setConditions(client.instantiate(ProvisioningConditions.class) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition.class) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition.class) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE)))) + .setAccountLink(client.instantiate(PolicyAccountLink.class) + .setFilter(null) + .setAction(PolicyAccountLink.ActionEnum.AUTO)) + .setSubject(client.instantiate(PolicySubject.class) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate.class) + .setTemplate(userName)) + .setMatchType(matchType)) + .setMaxClockSkew(maxClockSkew))); + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/MicrosoftIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/MicrosoftIdentityProviderBuilder.java new file mode 100644 index 00000000000..8dcf563e0cf --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/MicrosoftIdentityProviderBuilder.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentials; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentialsClient; +import com.okta.sdk.resource.identity.provider.Protocol; +import com.okta.sdk.resource.identity.provider.Provisioning; +import com.okta.sdk.resource.identity.provider.ProvisioningConditions; +import com.okta.sdk.resource.identity.provider.ProvisioningDeprovisionedCondition; +import com.okta.sdk.resource.identity.provider.ProvisioningGroups; +import com.okta.sdk.resource.identity.provider.ProvisioningSuspendedCondition; +import com.okta.sdk.resource.policy.IdentityProviderPolicy; +import com.okta.sdk.resource.policy.PolicyAccountLink; +import com.okta.sdk.resource.policy.PolicySubject; +import com.okta.sdk.resource.policy.PolicyUserNameTemplate; + +public class MicrosoftIdentityProviderBuilder extends DefaultIdentityProviderBuilder { + + @Override + public IdentityProvider buildAndCreate(Client client) { + + return client.createIdentityProvider(client.instantiate(IdentityProvider.class) + .setType(IdentityProvider.TypeEnum.MICROSOFT) + .setName(name) + .setProtocol(client.instantiate(Protocol.class) + .setType(Protocol.TypeEnum.OIDC) + .setScopes(scopes) + .setCredentials(client.instantiate(IdentityProviderCredentials.class) + .setClient(client.instantiate(IdentityProviderCredentialsClient.class) + .setClientId(clientId) + .setClientSecret(clientSecret)))) + .setPolicy(client.instantiate(IdentityProviderPolicy.class) + .setProvisioning(client.instantiate(Provisioning.class) + .setAction(Provisioning.ActionEnum.AUTO) + .setProfileMaster(isProfileMaster) + .setGroups(client.instantiate(ProvisioningGroups.class) + .setAction(ProvisioningGroups.ActionEnum.NONE)) + .setConditions(client.instantiate(ProvisioningConditions.class) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition.class) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition.class) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE)))) + .setAccountLink(client.instantiate(PolicyAccountLink.class) + .setFilter(null) + .setAction(PolicyAccountLink.ActionEnum.AUTO)) + .setSubject(client.instantiate(PolicySubject.class) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate.class) + .setTemplate(userName)) + .setMatchType(matchType)) + .setMaxClockSkew(maxClockSkew))); + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/OidcIdentityProviderBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/OidcIdentityProviderBuilder.java new file mode 100644 index 00000000000..0330280b66a --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/identity/provider/OidcIdentityProviderBuilder.java @@ -0,0 +1,229 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.identity.provider; + +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.identity.provider.IdentityProvider; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentials; +import com.okta.sdk.resource.identity.provider.IdentityProviderCredentialsClient; +import com.okta.sdk.resource.identity.provider.OIDCIdentityProviderBuilder; +import com.okta.sdk.resource.identity.provider.Protocol; +import com.okta.sdk.resource.identity.provider.ProtocolAlgorithmType; +import com.okta.sdk.resource.identity.provider.ProtocolAlgorithmTypeSignature; +import com.okta.sdk.resource.identity.provider.ProtocolAlgorithms; +import com.okta.sdk.resource.identity.provider.ProtocolEndpoint; +import com.okta.sdk.resource.identity.provider.ProtocolEndpoints; +import com.okta.sdk.resource.identity.provider.Provisioning; +import com.okta.sdk.resource.identity.provider.ProvisioningConditions; +import com.okta.sdk.resource.identity.provider.ProvisioningDeprovisionedCondition; +import com.okta.sdk.resource.identity.provider.ProvisioningGroups; +import com.okta.sdk.resource.identity.provider.ProvisioningSuspendedCondition; +import com.okta.sdk.resource.policy.IdentityProviderPolicy; +import com.okta.sdk.resource.policy.PolicyAccountLink; +import com.okta.sdk.resource.policy.PolicySubject; +import com.okta.sdk.resource.policy.PolicySubjectMatchType; +import com.okta.sdk.resource.policy.PolicyUserNameTemplate; + +public class OidcIdentityProviderBuilder extends DefaultIdentityProviderBuilder + implements OIDCIdentityProviderBuilder { + + private IdentityProvider.IssuerModeEnum issuerMode; + private String requestSignatureAlgorithm; + private ProtocolAlgorithmTypeSignature.ScopeEnum requestSignatureScope; + private String responseSignatureAlgorithm; + private ProtocolAlgorithmTypeSignature.ScopeEnum responseSignatureScope; + private ProtocolEndpoint.BindingEnum acsEndpointBinding; + private ProtocolEndpoint.TypeEnum acsEndpointType; + private ProtocolEndpoint.BindingEnum authorizationEndpointBinding; + private String authorizationEndpointUrl; + private ProtocolEndpoint.BindingEnum tokenEndpointBinding; + private String tokenEndpointUrl; + private ProtocolEndpoint.BindingEnum userInfoEndpointBinding; + private String userInfoEndpointUrl; + private ProtocolEndpoint.BindingEnum jwksEndpointBinding; + private String jwksEndpointUrl; + private String issuerUrl; + private String userName; + private PolicySubjectMatchType matchType; + + @Override + public OidcIdentityProviderBuilder setIssuerMode(IdentityProvider.IssuerModeEnum issuerMode) { + this.issuerMode = issuerMode; + return this; + } + + @Override + public OidcIdentityProviderBuilder setRequestSignatureAlgorithm(String requestSignatureAlgorithm) { + this.requestSignatureAlgorithm = requestSignatureAlgorithm; + return this; + } + + @Override + public OidcIdentityProviderBuilder setRequestSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum requestSignatureScope) { + this.requestSignatureScope = requestSignatureScope; + return this; + } + + @Override + public OidcIdentityProviderBuilder setResponseSignatureAlgorithm(String responseSignatureAlgorithm) { + this.responseSignatureAlgorithm = responseSignatureAlgorithm; + return this; + } + + @Override + public OidcIdentityProviderBuilder setResponseSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum responseSignatureScope) { + this.responseSignatureScope = responseSignatureScope; + return this; + } + + @Override + public OidcIdentityProviderBuilder setAcsEndpointBinding(ProtocolEndpoint.BindingEnum acsEndpointBinding) { + this.acsEndpointBinding = acsEndpointBinding; + return this; + } + + @Override + public OidcIdentityProviderBuilder setAcsEndpointType(ProtocolEndpoint.TypeEnum acsEndpointType) { + this.acsEndpointType = acsEndpointType; + return this; + } + + @Override + public OidcIdentityProviderBuilder setAuthorizationEndpointBinding(ProtocolEndpoint.BindingEnum authorizationEndpointBinding) { + this.authorizationEndpointBinding = authorizationEndpointBinding; + return this; + } + + @Override + public OidcIdentityProviderBuilder setAuthorizationEndpointUrl(String authorizationEndpointUrl) { + this.authorizationEndpointUrl = authorizationEndpointUrl; + return this; + } + + @Override + public OidcIdentityProviderBuilder setTokenEndpointBinding(ProtocolEndpoint.BindingEnum tokenEndpointBinding) { + this.tokenEndpointBinding = tokenEndpointBinding; + return this; + } + + @Override + public OidcIdentityProviderBuilder setTokenEndpointUrl(String tokenEndpointUrl) { + this.tokenEndpointUrl = tokenEndpointUrl; + return this; + } + + @Override + public OidcIdentityProviderBuilder setUserInfoEndpointBinding(ProtocolEndpoint.BindingEnum userInfoEndpointBinding) { + this.userInfoEndpointBinding = userInfoEndpointBinding; + return this; + } + + @Override + public OidcIdentityProviderBuilder setUserInfoEndpointUrl(String userInfoEndpointUrl) { + this.userInfoEndpointUrl = userInfoEndpointUrl; + return this; + } + + @Override + public OidcIdentityProviderBuilder setJwksEndpointBinding(ProtocolEndpoint.BindingEnum jwksEndpointBinding) { + this.jwksEndpointBinding = jwksEndpointBinding; + return this; + } + + @Override + public OidcIdentityProviderBuilder setJwksEndpointUrl(String jwksEndpointUrl) { + this.jwksEndpointUrl = jwksEndpointUrl; + return this; + } + + @Override + public OidcIdentityProviderBuilder setIssuerUrl(String issuerUrl) { + this.issuerUrl = issuerUrl; + return this; + } + + @Override + public OidcIdentityProviderBuilder setUserName(String userName) { + this.userName = userName; + return this; + } + + @Override + public OidcIdentityProviderBuilder setMatchType(PolicySubjectMatchType matchType) { + this.matchType = matchType; + return this; + } + + @Override + public IdentityProvider buildAndCreate(Client client) { + return client.createIdentityProvider(client.instantiate(IdentityProvider.class) + .setType(IdentityProvider.TypeEnum.OIDC) + .setName(name) + .setIssuerMode(issuerMode) + .setProtocol(client.instantiate(Protocol.class) + .setAlgorithms(client.instantiate(ProtocolAlgorithms.class) + .setRequest(client.instantiate(ProtocolAlgorithmType.class) + .setSignature(client.instantiate(ProtocolAlgorithmTypeSignature.class) + .setAlgorithm(requestSignatureAlgorithm) + .setScope(requestSignatureScope))) + .setResponse(client.instantiate(ProtocolAlgorithmType.class) + .setSignature(client.instantiate(ProtocolAlgorithmTypeSignature.class) + .setAlgorithm(responseSignatureAlgorithm) + .setScope(responseSignatureScope)))) + .setEndpoints(client.instantiate(ProtocolEndpoints.class) + .setAcs(client.instantiate(ProtocolEndpoint.class) + .setBinding(acsEndpointBinding) + .setType(acsEndpointType)) + .setAuthorization(client.instantiate(ProtocolEndpoint.class) + .setBinding(authorizationEndpointBinding) + .setUrl(authorizationEndpointUrl)) + .setToken(client.instantiate(ProtocolEndpoint.class) + .setBinding(tokenEndpointBinding) + .setUrl(tokenEndpointUrl)) + .setUserInfo(client.instantiate(ProtocolEndpoint.class) + .setBinding(userInfoEndpointBinding) + .setUrl(userInfoEndpointUrl)) + .setJwks(client.instantiate(ProtocolEndpoint.class) + .setBinding(jwksEndpointBinding) + .setUrl(jwksEndpointUrl))) + .setScopes(scopes) + .setType(Protocol.TypeEnum.OIDC) + .setCredentials(client.instantiate(IdentityProviderCredentials.class) + .setClient(client.instantiate(IdentityProviderCredentialsClient.class) + .setClientId(clientId) + .setClientSecret(clientSecret))) + .setIssuer(client.instantiate(ProtocolEndpoint.class) + .setUrl(issuerUrl))) + .setPolicy(client.instantiate(IdentityProviderPolicy.class) + .setAccountLink(client.instantiate(PolicyAccountLink.class) + .setAction(PolicyAccountLink.ActionEnum.AUTO) + .setFilter(null)) + .setProvisioning(client.instantiate(Provisioning.class) + .setAction(Provisioning.ActionEnum.AUTO) + .setConditions(client.instantiate(ProvisioningConditions.class) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition.class) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition.class) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE))) + .setGroups(client.instantiate(ProvisioningGroups.class) + .setAction(ProvisioningGroups.ActionEnum.NONE))) + .setMaxClockSkew(maxClockSkew) + .setSubject(client.instantiate(PolicySubject.class) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate.class) + .setTemplate(userName)) + .setMatchType(matchType)))); + } +} diff --git a/impl/src/main/java/com/okta/sdk/impl/resource/inline/hook/DefaultInlineHookBuilder.java b/impl/src/main/java/com/okta/sdk/impl/resource/inline/hook/DefaultInlineHookBuilder.java new file mode 100644 index 00000000000..09c4b84f4a8 --- /dev/null +++ b/impl/src/main/java/com/okta/sdk/impl/resource/inline/hook/DefaultInlineHookBuilder.java @@ -0,0 +1,118 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.inline.hook; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.net.HttpHeaders; +import com.okta.sdk.client.Client; +import com.okta.sdk.resource.inline.hook.InlineHook; +import com.okta.sdk.resource.inline.hook.InlineHookBuilder; +import com.okta.sdk.resource.inline.hook.InlineHookChannel; +import com.okta.sdk.resource.inline.hook.InlineHookChannelConfig; +import com.okta.sdk.resource.inline.hook.InlineHookChannelConfigAuthScheme; +import com.okta.sdk.resource.inline.hook.InlineHookChannelConfigHeaders; +import com.okta.sdk.resource.inline.hook.InlineHookType; + +import java.util.List; +import java.util.Map; + +/** + * Builder for {@link InlineHook}. + * @since 2.0.0 + */ +public class DefaultInlineHookBuilder implements InlineHookBuilder { + + private static final String VERSION = "1.0.0"; + + private String name; + private InlineHookType hookType; + private InlineHookChannel.TypeEnum channelType; + private String url; + private String authorizationHeaderValue; + private Map headerMap = Maps.newHashMap(); + + @Override + public InlineHookBuilder setName(String name) { + this.name = name; + return this; + } + + @Override + public InlineHookBuilder setHookType(InlineHookType hookType) { + this.hookType = hookType; + return this; + } + + @Override + public InlineHookBuilder setChannelType(InlineHookChannel.TypeEnum channelType) { + this.channelType = channelType; + return this; + } + + @Override + public InlineHookBuilder setUrl(String url) { + this.url = url; + return this; + } + + @Override + public InlineHookBuilder setAuthorizationHeaderValue(String authorizationHeaderValue) { + this.authorizationHeaderValue = authorizationHeaderValue; + return this; + } + + @Override + public InlineHookBuilder addHeader(String name, String value) { + headerMap.put(name, value); + return this; + } + + @Override + public InlineHook buildAndCreate(Client client) { + List headers = Lists.newArrayList(); + + for (Map.Entry entry : headerMap.entrySet()) { + headers.add(client.instantiate(InlineHookChannelConfigHeaders.class) + .setKey(entry.getKey()) + .setValue(entry.getValue())); + } + + InlineHookChannelConfigAuthScheme inlineHookChannelConfigAuthScheme = + client.instantiate(InlineHookChannelConfigAuthScheme.class) + .setType("HEADER") + .setKey(HttpHeaders.AUTHORIZATION) + .setValue(authorizationHeaderValue); + + InlineHookChannelConfig inlineHookChannelConfig = client.instantiate(InlineHookChannelConfig.class) + .setUri(url) + .setHeaders(headers) + .setAuthScheme(inlineHookChannelConfigAuthScheme); + + InlineHookChannel inlineHookChannel = client.instantiate(InlineHookChannel.class) + .setType(channelType) + .setVersion(VERSION) + .setConfig(inlineHookChannelConfig); + + InlineHook createdInlineHook = client.createInlineHook(client.instantiate(InlineHook.class) + .setName(name) + .setType(hookType) + .setVersion(VERSION) + .setChannel(inlineHookChannel)); + + return createdInlineHook; + } +} diff --git a/impl/src/test/groovy/com/okta/sdk/impl/cache/CachesTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/cache/CachesTest.groovy index 5720b75e1e9..828dfbbd178 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/cache/CachesTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/cache/CachesTest.groovy @@ -17,7 +17,7 @@ package com.okta.sdk.impl.cache import com.okta.sdk.cache.CacheManager -import com.okta.sdk.lang.Duration +import java.time.Duration import org.testng.annotations.Test import java.util.concurrent.TimeUnit @@ -34,13 +34,12 @@ class CachesTest { @Test void testBuild() { - def defaultTtl = new Duration(10, TimeUnit.MINUTES) - def defaultTti = new Duration(5, TimeUnit.HOURS) + Duration defaultTtl = Duration.ofMinutes(30) + Duration defaultTti = Duration.ofHours(5) CacheManager m = newCacheManager() - .withDefaultTimeToLive(-1, defaultTtl.timeUnit) - .withDefaultTimeToLive(defaultTtl.value, defaultTtl.timeUnit) - .withDefaultTimeToIdle(defaultTti.value, defaultTti.timeUnit) + .withDefaultTimeToLive(defaultTtl.getSeconds(), TimeUnit.SECONDS) + .withDefaultTimeToIdle(defaultTti.getSeconds(), TimeUnit.SECONDS) .withCache(named('foo').withTimeToLive(20, TimeUnit.MINUTES).withTimeToIdle(15, TimeUnit.MINUTES)) .withCache(named('bar').withTimeToLive(-1, TimeUnit.HOURS).withTimeToIdle(0, TimeUnit.HOURS)) .build() @@ -57,8 +56,8 @@ class CachesTest { assertTrue c instanceof DefaultCache DefaultCache cache = (DefaultCache)c - assertEquals cache.timeToLive, new Duration(20, TimeUnit.MINUTES) - assertEquals cache.timeToIdle, new Duration(15, TimeUnit.MINUTES) + assertEquals cache.timeToLive, Duration.ofMinutes(20) + assertEquals cache.timeToIdle, Duration.ofMinutes(15) cache = (DefaultCache)manager.getCache('bar') @@ -69,7 +68,7 @@ class CachesTest { @Test void testNewDisabledCacheManager() { - CacheManager cm = newDisabledCacheManager(); + CacheManager cm = newDisabledCacheManager() assertNotNull cm assertTrue cm instanceof DisabledCacheManager diff --git a/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheManagerTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheManagerTest.groovy index 9ae4ea13769..14be3d979ef 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheManagerTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheManagerTest.groovy @@ -17,13 +17,11 @@ package com.okta.sdk.impl.cache import com.okta.sdk.cache.Cache -import com.okta.sdk.lang.Duration +import java.time.Duration import groovy.json.JsonSlurper import org.testng.annotations.BeforeTest import org.testng.annotations.Test -import java.util.concurrent.TimeUnit - import static org.testng.Assert.* /** @@ -72,32 +70,32 @@ class DefaultCacheManagerTest { @Test void testDefaultTtl() { mgr = new DefaultCacheManager() - Duration ttl = new Duration(30, TimeUnit.SECONDS) + Duration ttl = Duration.ofSeconds(30) mgr.setDefaultTimeToLive(ttl) def cache = mgr.getCache('foo') - assertEquals cache.timeToLive, new Duration(30, TimeUnit.SECONDS) + assertEquals cache.timeToLive, Duration.ofSeconds(30) } @Test void testDefaultTtlSeconds() { mgr.setDefaultTimeToLiveSeconds(30) - assertEquals mgr.defaultTimeToLive, new Duration(30, TimeUnit.SECONDS) + assertEquals mgr.defaultTimeToLive, Duration.ofSeconds(30) } @Test void testDefaultTti() { - Duration tti = new Duration(20, TimeUnit.SECONDS) + Duration tti = Duration.ofSeconds(20) mgr.setDefaultTimeToIdle(tti) def cache = mgr.getCache('foo') - assertEquals cache.timeToIdle, new Duration(20, TimeUnit.SECONDS) + assertEquals cache.timeToIdle.seconds, tti.getSeconds() } @Test void testDefaultTtiSeconds() { mgr.setDefaultTimeToIdleSeconds(30) - assertEquals new Duration(30, TimeUnit.SECONDS), mgr.defaultTimeToIdle + assertEquals Duration.ofSeconds(30), mgr.defaultTimeToIdle } @Test diff --git a/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheTest.groovy index 0b507126da6..1477c49975f 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/cache/DefaultCacheTest.groovy @@ -16,12 +16,10 @@ */ package com.okta.sdk.impl.cache -import com.okta.sdk.lang.Duration +import java.time.Duration import groovy.json.JsonSlurper import org.testng.annotations.Test -import java.util.concurrent.TimeUnit - import static org.testng.Assert.* /** @@ -44,7 +42,7 @@ class DefaultCacheTest { @Test void testSetTtl() { def cache = new DefaultCache('foo') - def ttl = new Duration(30, TimeUnit.MILLISECONDS) + def ttl = Duration.ofMillis(30) cache.setTimeToLive(ttl) assertSame cache.timeToLive, ttl } @@ -52,21 +50,21 @@ class DefaultCacheTest { @Test(expectedExceptions = IllegalArgumentException) void testSetNegativeTtl() { def cache = new DefaultCache('foo') - def ttl = new Duration(-30, TimeUnit.MILLISECONDS) + def ttl = Duration.ofMillis(-30) cache.setTimeToLive(ttl) } @Test(expectedExceptions = IllegalArgumentException) void testSetZeroTtl() { def cache = new DefaultCache('foo') - def ttl = new Duration(0, TimeUnit.MILLISECONDS) + def ttl = Duration.ofMillis(0) cache.setTimeToLive(ttl) } @Test void testSetTti() { def cache = new DefaultCache('foo') - def tti = new Duration(30, TimeUnit.MILLISECONDS) + def tti = Duration.ofMillis(30) cache.setTimeToIdle(tti) assertSame cache.timeToIdle, tti } @@ -74,14 +72,14 @@ class DefaultCacheTest { @Test(expectedExceptions = IllegalArgumentException) void testSetNegativeTti() { def cache = new DefaultCache('foo') - def tti = new Duration(-30, TimeUnit.MILLISECONDS) + def tti = Duration.ofMillis(-30) cache.setTimeToIdle(tti) } @Test(expectedExceptions = IllegalArgumentException) void testSetZeroTti() { def cache = new DefaultCache('foo') - def tti = new Duration(0, TimeUnit.MILLISECONDS) + def tti = Duration.ofMillis(0) cache.setTimeToIdle(tti) } @@ -173,7 +171,7 @@ class DefaultCacheTest { @Test void testTimeToLive() { - def cache = new DefaultCache('foo', [:], new Duration(10, TimeUnit.MILLISECONDS), null) + def cache = new DefaultCache('foo', [:], Duration.ofMillis(10), null) def key = 'key' def value = 'value' @@ -196,7 +194,7 @@ class DefaultCacheTest { @Test void testTimeToIdle() { - def cache = new DefaultCache('foo', [:], null, new Duration(50, TimeUnit.MILLISECONDS)) + def cache = new DefaultCache('foo', [:], null, Duration.ofMillis(50)) def key = 'key' def value = 'value' @@ -224,7 +222,7 @@ class DefaultCacheTest { @Test void testTimeToLiveAndTimeToIdle() { - def cache = new DefaultCache('foo', [:], new Duration(100, TimeUnit.MILLISECONDS), new Duration(40, TimeUnit.MILLISECONDS)) + def cache = new DefaultCache('foo', [:], Duration.ofMillis(100), Duration.ofMillis(40)) def key = 'key' def value = 'value' diff --git a/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultCacheKeyTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultCacheKeyTest.groovy index 5aeb4f9f6d3..99e361004b5 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultCacheKeyTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultCacheKeyTest.groovy @@ -19,6 +19,9 @@ package com.okta.sdk.impl.ds import com.okta.commons.http.QueryString import org.testng.annotations.Test +import java.time.Instant +import java.time.format.DateTimeFormatter + import static org.testng.Assert.* /** @@ -51,6 +54,19 @@ class DefaultCacheKeyTest { assertEquals cacheKey.toString(), "https://mysite.com?key_one=value_one&key_three=value_three&key_two=value_two" } + @Test + void testWithDateInQueryString() { + def isoDateString = "2017-11-30T21:15:16.838Z" + Date date = Date.from(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(isoDateString))) + + def qs = new QueryString([ + "key_one": date + ]) + def cacheKey = new DefaultCacheKey("https://mysite.com", qs) + + assertEquals cacheKey.toString(), "https://mysite.com?key_one=" + URLEncoder.encode(isoDateString, "UTF-8") + } + @Test void testHashCode() { diff --git a/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultResourceFactoryTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultResourceFactoryTest.groovy index 3bcfe858005..9f66192d0a1 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultResourceFactoryTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/ds/DefaultResourceFactoryTest.groovy @@ -15,9 +15,9 @@ */ package com.okta.sdk.impl.ds -import com.okta.sdk.resource.user.factor.Factor +import com.okta.sdk.resource.user.factor.UserFactor import com.okta.sdk.resource.user.factor.FactorType -import com.okta.sdk.resource.user.factor.TotpFactor +import com.okta.sdk.resource.user.factor.TotpUserFactor import org.testng.annotations.Test import static org.hamcrest.Matchers.equalTo @@ -39,8 +39,8 @@ class DefaultResourceFactoryTest { def map = [ factorType: "token:software:totp" ] - Factor factor = resourceFactory.instantiate(Factor, map) - assertThat factor, instanceOf(TotpFactor) + UserFactor factor = resourceFactory.instantiate(UserFactor, map) + assertThat factor, instanceOf(TotpUserFactor) assertThat factor.getFactorType(), equalTo(FactorType.TOKEN_SOFTWARE_TOTP) } } \ No newline at end of file diff --git a/impl/src/test/groovy/com/okta/sdk/impl/http/DefaultHttpRequestTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/http/DefaultHttpRequestTest.groovy deleted file mode 100644 index 5c0e716f9d2..00000000000 --- a/impl/src/test/groovy/com/okta/sdk/impl/http/DefaultHttpRequestTest.groovy +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2014 Stormpath, Inc. - * Modifications Copyright 2018 Okta, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * 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 com.okta.sdk.impl.http - -import com.okta.sdk.http.HttpMethod -import com.okta.sdk.http.HttpRequestBuilder -import com.okta.sdk.http.HttpRequests -import org.testng.annotations.Test - -import static org.testng.Assert.assertEquals -import static org.testng.Assert.assertNotNull -import static org.testng.Assert.assertNotNull -import static org.testng.Assert.assertNotNull -import static org.testng.Assert.assertNull -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.assertTrue -import static org.testng.Assert.fail -import static org.testng.Assert.fail -import static org.testng.Assert.fail -import static org.testng.Assert.fail -import static org.testng.Assert.fail - -/** - * @since 0.5.0 - */ -class DefaultHttpRequestTest { - - @Test - void testGetHeaderNoHeaders() { - - def httpRequest = new DefaultHttpRequest([:], HttpMethod.GET, null, null) - assertNull httpRequest.getHeader("My-Header") - } - - @Test - void testGetHeaderNullValue() { - - def headers = ["My-Header":null] - def httpRequest = new DefaultHttpRequest(headers, HttpMethod.GET, null, null) - assertNull httpRequest.getHeader("My-Header") - } - - @Test - void testGetHeaderNotFound() { - - def headers = ["My-Header":["My-Value"] as String[]] - def httpRequest = new DefaultHttpRequest(headers, HttpMethod.GET, null, null) - assertNull httpRequest.getHeader("My-Other-Header") - } - - @Test - void testGetHeaderFound() { - - def headers = ["My-Header":["My-Value"] as String[]] - def httpRequest = new DefaultHttpRequest(headers, HttpMethod.GET, null, null) - assertEquals httpRequest.getHeader("My-Header"), "My-Value" - } - - @Test - void testGetParameterNull() { - - def httpRequest = new DefaultHttpRequest([:], HttpMethod.GET, null, null) - assertNull httpRequest.getParameter("My-Parameter") - } - - - @Test - void TestErrors(){ - - try { - HttpRequests.method(null); - fail("Exception expected."); - } catch (IllegalArgumentException expected) { - String msg = expected.getMessage() - assertTrue msg.startsWith("method argument is required") - } - - try { - HttpRequests.method(HttpMethod.GET).addHeader("name", null); - fail("Exception expected."); - } catch (IllegalArgumentException expected) { - String msg = expected.getMessage() - assertTrue msg.startsWith("value argument is required") - } - - try { - HttpRequests.method(HttpMethod.GET).addHeader(null, "value"); - fail("Exception expected."); - } catch (IllegalArgumentException expected) { - String msg = expected.getMessage() - assertTrue msg.startsWith("key argument is required") - } - - try { - HttpRequests.method(HttpMethod.GET).addParameter("name", null); - fail("Exception expected."); - } catch (IllegalArgumentException expected) { - String msg = expected.getMessage() - assertTrue msg.startsWith("value argument is required") - } - - try { - HttpRequests.method(HttpMethod.GET).addParameter(null, "value"); - fail("Exception expected."); - } catch (IllegalArgumentException expected) { - String msg = expected.getMessage() - assertTrue msg.startsWith("key argument is required") - } - } - - @Test - void testConstructors(){ - def builder = HttpRequests.method(HttpMethod.POST) - assertTrue builder instanceof HttpRequestBuilder - - String[] value = ['test'] - builder = HttpRequests.method(HttpMethod.GET).addParameter("name", value) - assertTrue builder instanceof HttpRequestBuilder - } - - @Test - void testDefault(){ - def request = HttpRequests.method(HttpMethod.POST).build() - assertNotNull request - assert request.getMethod().equals(HttpMethod.POST) - - String[] headerValue = ['testHeader'] - request = HttpRequests - .method(HttpMethod.POST) - .addHeader("name", headerValue).build() - assertNotNull request - assertEquals request.headers.size(), 1 - assertEquals request.headers.get("name").getAt(0), 'testHeader' - - String[] paramValue = ['testParam'] - request = HttpRequests - .method(HttpMethod.POST) - .addParameter("paramName", paramValue).build() - assertNotNull request - assertEquals request.parameters.size(), 1 - assertEquals request.parameters.get("paramName").getAt(0), 'testParam' - - request = HttpRequests - .method(HttpMethod.POST) - .addHeader("addHeader", headerValue) - .addParameter("param", paramValue) - .build() - - assertEquals request.parameters.size(), 1 - assertEquals request.headers.size(), 1 - assertEquals request.headers.get("addHeader").getAt(0), 'testHeader' - assertEquals request.parameters.get("param").getAt(0), 'testParam' - } -} diff --git a/impl/src/test/groovy/com/okta/sdk/impl/lang/DurationTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/lang/DurationTest.groovy index 62794ed0ce0..dc9ffa20fa7 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/lang/DurationTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/lang/DurationTest.groovy @@ -16,12 +16,9 @@ */ package com.okta.sdk.impl.lang -import com.okta.sdk.lang.Duration +import java.time.Duration import org.testng.annotations.Test -import java.util.concurrent.TimeUnit - -import static org.testng.Assert.assertEquals import static org.testng.Assert.assertTrue /** @@ -33,33 +30,30 @@ class DurationTest { void testGreaterThan() { //1,800,801 millis = 30 minutes + 1 millis - def duration = new Duration(1800001, TimeUnit.MILLISECONDS); - def thirtyMin = new Duration(30, TimeUnit.MINUTES); + def duration = Duration.ofMillis(1800001) + def thirtyMin = Duration.ofMinutes(30) - assertEquals duration.compareTo(thirtyMin), 1 - assertTrue duration.isGreaterThan(thirtyMin) + assertTrue duration.compareTo(thirtyMin) > 0 } @Test void testLessThan() { //1,799,999 millis = 30 minutes - 1 millis - def duration = new Duration(1799999, TimeUnit.MILLISECONDS); - def thirtyMin = new Duration(30, TimeUnit.MINUTES); + def duration = Duration.ofMillis(1799999) + def thirtyMin = Duration.ofMinutes(30) - assertEquals duration.compareTo(thirtyMin), -1 - assertTrue duration.isLessThan(thirtyMin); + assertTrue duration.compareTo(thirtyMin) < 0 } @Test void testEqualTo() { //1,800,000 millis = 30 minutes - def duration = new Duration(1800000, TimeUnit.MILLISECONDS); - def thirtyMin = new Duration(30, TimeUnit.MINUTES); + def duration = Duration.ofMillis(1800000) + def thirtyMin = Duration.ofMinutes(30) - assertEquals duration.compareTo(thirtyMin), 0 - assertTrue duration.isEquivalentTo(thirtyMin) + assertTrue duration.compareTo(thirtyMin) == 0 } } diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultGroupRuleBuilderTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultGroupRuleBuilderTest.groovy index 197c85ad7fb..ca14bbe514a 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultGroupRuleBuilderTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultGroupRuleBuilderTest.groovy @@ -51,14 +51,12 @@ class DefaultGroupRuleBuilderTest { .setName("dummy rule") .setType("group_rule") .addGroup("ajhd1234kak") - .setAllGroupsValid(false) .buildAndCreate(client) - verify(client).createRule(eq(groupRule)) + verify(client).createGroupRule(eq(groupRule)) verify(groupRule).setName("dummy rule") verify(groupRule).setType("group_rule") verify(groupRuleGroupCondition).setInclude(Arrays.asList("ajhd1234kak")) - verify(groupRule).setAllGroupsValid(false) } } diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilderTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilderTest.groovy index 257f55a8f68..bd413b5662c 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilderTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPasswordPolicyRuleBuilderTest.groovy @@ -38,7 +38,6 @@ class DefaultPasswordPolicyRuleBuilderTest { def groupCondition = mock(GroupCondition) def userCondition = mock(UserCondition) - when(client.instantiate(PasswordPolicyRule.class)).thenReturn(passwordPolicyRule) when(client.instantiate(PasswordPolicyRuleActions.class)).thenReturn(passwordPolicyRuleActions) when(passwordPolicyRule.getActions()).thenReturn(passwordPolicyRuleActions) @@ -51,7 +50,6 @@ class DefaultPasswordPolicyRuleBuilderTest { when(client.instantiate(UserCondition.class)).thenReturn(userCondition) new DefaultPasswordPolicyRuleBuilder() - .setId("id here") .setName("name here") .setStatus(PolicyRule.StatusEnum.ACTIVE) .setType(PolicyRule.TypeEnum.PASSWORD) @@ -63,7 +61,7 @@ class DefaultPasswordPolicyRuleBuilderTest { .setSelfServiceUnlockAccess(PasswordPolicyRuleAction.AccessEnum.DENY) .buildAndCreate(client, policy) - verify(policy).createRule(eq(passwordPolicyRule), eq(true)) + verify(policy).createRule(eq(passwordPolicyRule)) verify(passwordPolicyRule).setName("name here") verify(passwordPolicyRule).setType(PolicyRule.TypeEnum.PASSWORD) verify(passwordPolicyRuleActions).setSelfServicePasswordReset(passwordPolicyRuleAction.setAccess(PasswordPolicyRuleAction.AccessEnum.ALLOW)) diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilderTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilderTest.groovy index 7f1612be99c..2fec3b2e24b 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilderTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultPolicyRuleBuilderTest.groovy @@ -35,15 +35,13 @@ class DefaultPolicyRuleBuilderTest { when(client.instantiate(PolicyRule.class)).thenReturn(policyRule) new DefaultPolicyRuleBuilder() - .setId("dummy_id") .setStatus(PolicyRule.StatusEnum.ACTIVE) .setPriority(1) .buildAndCreate(client, policy) - verify(policy).createRule(eq(policyRule), eq(true)) + verify(policy).createRule(eq(policyRule)) verify(policyRule).setPriority(1) verify(policyRule).setStatus(PolicyRule.StatusEnum.ACTIVE) - verify(policyRule).setId("dummy_id") } } diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilderTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilderTest.groovy index 6260a05b986..ae6f5d6869d 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilderTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/DefaultSignOnPolicyRuleBuilderTest.groovy @@ -54,7 +54,6 @@ class DefaultSignOnPolicyRuleBuilderTest { when(client.instantiate(PolicyRuleAuthContextCondition.class)).thenReturn(policyRuleAuthContextCondition) new DefaultSignOnPolicyRuleBuilder() - .setId("id here") .setName("name here") .setStatus(PolicyRule.StatusEnum.ACTIVE) .setType(PolicyRule.TypeEnum.SIGN_ON) @@ -72,7 +71,7 @@ class DefaultSignOnPolicyRuleBuilderTest { .setMaxSessionIdleMinutes(5) .buildAndCreate(client, policy) - verify(policy).createRule(eq(signOnPolicyRule), eq(true)) + verify(policy).createRule(eq(signOnPolicyRule)) verify(signOnPolicyRule).setName("name here") verify(signOnPolicyRule).setType(PolicyRule.TypeEnum.SIGN_ON) verify(oktaSignOnPolicyRuleSignonActions).setFactorLifetime(1) @@ -97,7 +96,7 @@ class DefaultSignOnPolicyRuleBuilderTest { .setName("test name") .setStatus(PolicyRule.StatusEnum.ACTIVE) .setType(PolicyRule.TypeEnum.PASSWORD) - .buildAndCreate(client, policy); + .buildAndCreate(client, policy) } } diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/log/LogsTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/log/LogsTest.groovy index 841d2b60bb4..48121b3008d 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/log/LogsTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/log/LogsTest.groovy @@ -31,7 +31,11 @@ import com.okta.sdk.resource.log.LogSecurityContext import com.okta.sdk.resource.log.LogSeverity import com.okta.sdk.resource.log.LogTransaction import com.okta.sdk.resource.log.LogUserAgent +import org.mockito.ArgumentCaptor import org.mockito.Mockito +import static org.mockito.Mockito.verify + +import org.testng.annotations.BeforeMethod import org.testng.annotations.Test import java.time.Instant @@ -42,14 +46,18 @@ import static org.hamcrest.Matchers.* import static org.hamcrest.MatcherAssert.* class LogsTest { + MockClient client + + @BeforeMethod + void setup() { + // mock the response objects in the client + client = new MockClient() + .withMockResponse(Mockito.any(Request), '/stubs/logs.json') + } @Test void testGetLogs() { - // Mock the response objects in the client - MockClient client = new MockClient() - .withMockResponse(Mockito.any(Request), '/stubs/logs.json') - // get the list of logs List logs = client.getLogs().stream().collect(Collectors.toList()) assertThat logs, hasSize(100) @@ -145,4 +153,50 @@ class LogsTest { assertThat log.getRequest().getIpChain().get(0).getGeographicalContext().getGeolocation().lat, equalTo(43.3091d) assertThat log.getRequest().getIpChain().get(0).getGeographicalContext().getGeolocation().lon, equalTo(-71.6861d) } -} \ No newline at end of file + + @Test + void testGetLogsBetweenDates() { + + Date sinceDate = Date.from(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2017-11-30T21:15:16.838Z"))) + Date untilDate = Date.from(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2017-11-30T21:16:00.081Z"))) + + // get log events between dates + List logs = client.getLogs(sinceDate, untilDate, null, null, null).stream().collect(Collectors.toList()) + logs.forEach { assertThat it, instanceOf(LogEvent) } + + ArgumentCaptor argument = ArgumentCaptor.forClass(Request.class) + verify(client.mockRequestExecutor).executeRequest(argument.capture()) + assertThat argument.getValue().queryString.since, equalTo("2017-11-30T21:15:16.838Z") + assertThat argument.getValue().queryString.until, equalTo("2017-11-30T21:16:00.081Z") + } + + @Test + void testGetLogsSinceDate() { + + Date sinceDate = Date.from(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2017-11-30T21:15:16.838Z"))) + + // get log events since given date + List logs = client.getLogs(sinceDate, null, null, null, null).stream().collect(Collectors.toList()) + assertThat logs, hasSize(100) + logs.forEach { assertThat it, instanceOf(LogEvent) } + + ArgumentCaptor argument = ArgumentCaptor.forClass(Request.class) + verify(client.mockRequestExecutor).executeRequest(argument.capture()) + assertThat argument.getValue().queryString.since, equalTo("2017-11-30T21:15:16.838Z") + } + + @Test + void testGetLogsUntilDate() { + + Date untilDate = Date.from(Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse("2017-11-30T21:16:00.081Z"))) + + // get log events until given date + List logs = client.getLogs(null, untilDate, null, null, null).stream().collect(Collectors.toList()) + assertThat logs, hasSize(100) + logs.forEach { assertThat it, instanceOf(LogEvent) } + + ArgumentCaptor argument = ArgumentCaptor.forClass(Request.class) + verify(client.mockRequestExecutor).executeRequest(argument.capture()) + assertThat argument.getValue().queryString.until, equalTo("2017-11-30T21:16:00.081Z") + } +} diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/session/FeaturesTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/session/FeaturesTest.groovy new file mode 100644 index 00000000000..212fdce90e4 --- /dev/null +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/session/FeaturesTest.groovy @@ -0,0 +1,66 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.impl.resource.session + +import com.okta.sdk.impl.ds.InternalDataStore +import com.okta.sdk.impl.resource.feature.DefaultFeature +import com.okta.sdk.resource.feature.Feature +import org.testng.annotations.Test + +import static org.mockito.ArgumentMatchers.any +import static org.mockito.ArgumentMatchers.eq +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.verify + +/** + * Tests for the Features API. + * + * @since 2.0.0 + */ +class FeaturesTest { + + @Test + void toggleFeatureTest() { + + InternalDataStore dataStore = mock(InternalDataStore) + + Feature featureToEnable = new DefaultFeature(dataStore, [id: "test_feature_id", name: "test feature", status: "DISABLED"]) + + // enable + featureToEnable.updateLifecycle("enable", "force") + + verify(dataStore).create( + (String) eq("/api/v1/features/test_feature_id/enable".toString()), + any(), + any(), + (Class) eq(Feature.class), + eq(Collections.singletonMap("mode", "force")), + eq(Collections.emptyMap())) + + Feature featureToDisable = new DefaultFeature(dataStore, [id: "test_feature_id", name: "test feature", status: "ENABLED"]) + + // disable + featureToDisable.updateLifecycle("disable", "force") + + verify(dataStore).create( + (String) eq("/api/v1/features/test_feature_id/disable".toString()), + any(), + any(), + (Class) eq(Feature.class), + eq(Collections.singletonMap("mode", "force")), + eq(Collections.emptyMap())) + } +} \ No newline at end of file diff --git a/impl/src/test/groovy/com/okta/sdk/impl/resource/session/SessionsTest.groovy b/impl/src/test/groovy/com/okta/sdk/impl/resource/session/SessionsTest.groovy index 07ec6572e03..ca2fd6107cc 100644 --- a/impl/src/test/groovy/com/okta/sdk/impl/resource/session/SessionsTest.groovy +++ b/impl/src/test/groovy/com/okta/sdk/impl/resource/session/SessionsTest.groovy @@ -147,7 +147,7 @@ class SessionsTest { InternalDataStore dataStore = mock(InternalDataStore) - new DefaultUser(dataStore, [id: "test_user_id"]).endAllSessions() + new DefaultUser(dataStore, [id: "test_user_id"]).clearSessions() verify(dataStore).delete("/api/v1/users/test_user_id/sessions", Collections.emptyMap(), Collections.emptyMap()) } diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index ffc0b58d9b0..c6c2f9ffab5 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -20,7 +20,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT ../pom.xml diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/ApplicationsIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/ApplicationsIT.groovy index 2c22eda3940..3c657662c06 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/ApplicationsIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/ApplicationsIT.groovy @@ -15,9 +15,9 @@ */ package com.okta.sdk.tests.it - import com.okta.sdk.client.Client import com.okta.sdk.resource.ResourceException + import com.okta.sdk.resource.application.* import com.okta.sdk.resource.group.Group import com.okta.sdk.resource.group.GroupBuilder @@ -26,11 +26,14 @@ import com.okta.sdk.tests.it.util.ITSupport import org.testng.Assert import org.testng.annotations.Test +import static com.okta.sdk.tests.it.util.Util.assertPresent +import static com.okta.sdk.tests.it.util.Util.assertNotPresent + import static org.hamcrest.MatcherAssert.assertThat import static org.hamcrest.Matchers.* /** - * Tests for /api/v1/apps. + * Tests for {@code /api/v1/apps}. * @since 0.9.0 */ class ApplicationsIT extends ITSupport { @@ -478,4 +481,106 @@ class ApplicationsIT extends ITSupport { AppUser readAppUser = app.getApplicationUser(appUser2.getId()) assertThat readAppUser.getCredentials().getUserName(), equalTo("updated-"+user2.getProfile().getEmail()) } + + @Test + void csrTest() { + Client client = getClient() + + String label = "app-${uniqueTestName}" + Application app = client.instantiate(OpenIdConnectApplication) + .setLabel(label) + .setSettings(client.instantiate(OpenIdConnectApplicationSettings) + .setOAuthClient(client.instantiate(OpenIdConnectApplicationSettingsClient) + .setClientUri("https://example.com/client") + .setLogoUri("https://example.com/assets/images/logo-new.png") + .setRedirectUris(["https://example.com/oauth2/callback", + "myapp://callback"]) + .setResponseTypes([OAuthResponseType.TOKEN, + OAuthResponseType.ID_TOKEN, + OAuthResponseType.CODE]) + .setGrantTypes([OAuthGrantType.IMPLICIT, + OAuthGrantType.AUTHORIZATION_CODE]) + .setApplicationType(OpenIdConnectApplicationType.NATIVE) + .setTosUri("https://example.com/client/tos") + .setPolicyUri("https://example.com/client/policy"))) + .setCredentials(client.instantiate(OAuthApplicationCredentials) + .setOAuthClient(client.instantiate(ApplicationCredentialsOAuthClient) + .setClientId(UUID.randomUUID().toString()) + .setAutoKeyRotation(true) + .setTokenEndpointAuthMethod(OAuthEndpointAuthenticationMethod.CLIENT_SECRET_POST))) + client.createApplication(app) + registerForCleanup(app) + + assertThat(app.getStatus(), equalTo(Application.StatusEnum.ACTIVE)) + + // create csr metadata + CsrMetadata csrMetadata = client.instantiate(CsrMetadata) + .setSubject(client.instantiate(CsrMetadataSubject) + .setCountryName("US") + .setStateOrProvinceName("California") + .setLocalityName("San Francisco") + .setOrganizationName("Okta, Inc.") + .setOrganizationalUnitName("Dev") + .setCommonName("SP Issuer")) + .setSubjectAltNames(client.instantiate(CsrMetadataSubjectAltNames) + .setDnsNames(["dev.okta.com"])) + + // generate csr with metadata + Csr csr = app.generateCsr(csrMetadata) + + // verify + assertPresent(app.listCsrs(), csr) + + // revoke csr + app.revokeCsr(csr.getId()) + + // verify + assertNotPresent(app.listCsrs(), csr) + } + + @Test + void oAuth2ScopeConsentGrantTest() { + Client client = getClient() + + String label = "app-${uniqueTestName}" + Application app = client.instantiate(OpenIdConnectApplication) + .setLabel(label) + .setSettings(client.instantiate(OpenIdConnectApplicationSettings) + .setOAuthClient(client.instantiate(OpenIdConnectApplicationSettingsClient) + .setClientUri("https://example.com/client") + .setLogoUri("https://example.com/assets/images/logo-new.png") + .setRedirectUris(["https://example.com/oauth2/callback", + "myapp://callback"]) + .setResponseTypes([OAuthResponseType.TOKEN, + OAuthResponseType.ID_TOKEN, + OAuthResponseType.CODE]) + .setGrantTypes([OAuthGrantType.IMPLICIT, + OAuthGrantType.AUTHORIZATION_CODE]) + .setApplicationType(OpenIdConnectApplicationType.NATIVE) + .setTosUri("https://example.com/client/tos") + .setPolicyUri("https://example.com/client/policy"))) + .setCredentials(client.instantiate(OAuthApplicationCredentials) + .setOAuthClient(client.instantiate(ApplicationCredentialsOAuthClient) + .setClientId(UUID.randomUUID().toString()) + .setAutoKeyRotation(true) + .setTokenEndpointAuthMethod(OAuthEndpointAuthenticationMethod.CLIENT_SECRET_POST))) + client.createApplication(app) + registerForCleanup(app) + + assertThat(app.getStatus(), equalTo(Application.StatusEnum.ACTIVE)) + + // grant consent + OAuth2ScopeConsentGrant oAuth2ScopeConsentGrant = app.grantConsentToScope(client.instantiate(OAuth2ScopeConsentGrant) + .setIssuer(client.dataStore.baseUrlResolver.baseUrl) + .setScopeId("okta.apps.manage")) + + // verify + assertPresent(app.listScopeConsentGrants(), app.getScopeConsentGrant(oAuth2ScopeConsentGrant.getId())) + + // revoke consent + app.revokeScopeConsentGrant(oAuth2ScopeConsentGrant.getId()) + + // verify + assertNotPresent(app.listScopeConsentGrants(), app.getScopeConsentGrant(oAuth2ScopeConsentGrant.getId())) + } } diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/AuthorizationServerIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/AuthorizationServerIT.groovy new file mode 100644 index 00000000000..0f112ba68d4 --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/AuthorizationServerIT.groovy @@ -0,0 +1,507 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.policy.ClientPolicyCondition +import com.okta.sdk.resource.application.OAuth2Claim +import com.okta.sdk.resource.application.OAuth2Scope +import com.okta.sdk.resource.authorization.server.AuthorizationServer +import com.okta.sdk.resource.policy.Policy +import com.okta.sdk.resource.policy.PolicyRuleConditions +import com.okta.sdk.resource.policy.PolicyType +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test +import wiremock.org.apache.commons.lang3.RandomStringUtils + +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.contains +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.hasSize +import static org.hamcrest.Matchers.notNullValue + +import static com.okta.sdk.tests.it.util.Util.assertPresent +import static com.okta.sdk.tests.it.util.Util.assertNotPresent + +/** + * Tests for {@code /api/v1/authorizationServers}. + * @since 2.0.0 + */ +class AuthorizationServerIT extends ITSupport { + + // Authorization server operations + + @Test + void createAuthorizationServerTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + assertThat(createdAuthorizationServer.getId(), notNullValue()) + assertThat(createdAuthorizationServer.getName(), equalTo(name)) + assertThat(createdAuthorizationServer.getDescription(), equalTo("Test Authorization Server")) + assertThat(createdAuthorizationServer.getAudiences(), hasSize(1)) + assertThat(createdAuthorizationServer.getAudiences(), contains("api://example")) + } + + @Test + void listCreatedAuthorizationServerTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + assertPresent(client.listAuthorizationServers(), createdAuthorizationServer) + } + + @Test + void getAuthorizationServerTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + AuthorizationServer retrievedAuthorizationServer = client.getAuthorizationServer(createdAuthorizationServer.getId()) + assertThat(retrievedAuthorizationServer.getId(), equalTo(createdAuthorizationServer.getId())) + } + + @Test + void updateAuthorizationServerTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + createdAuthorizationServer.setDescription("Updated Test Authorization Server") + + AuthorizationServer updatedAuthorizationServer = createdAuthorizationServer.update() + assertThat(updatedAuthorizationServer.getId(), equalTo(createdAuthorizationServer.getId())) + assertThat(updatedAuthorizationServer.getDescription(), equalTo("Updated Test Authorization Server")) + } + + @Test + void deleteAuthorizationServerTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + assertThat(client.getAuthorizationServer(createdAuthorizationServer.getId()), notNullValue()) + + createdAuthorizationServer.deactivate() + createdAuthorizationServer.delete() + + // delete operation may not effect immediately in the backend + sleep(2000) + + assertNotPresent(client.listAuthorizationServers(), createdAuthorizationServer) + } + + // Policy operations + + @Test + void listAuthorizationServerPoliciesTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + Policy policy = client.instantiate(Policy) + .setType(PolicyType.OAUTH_AUTHORIZATION_POLICY) + .setName("Test Policy") + .setDescription("Test Policy") + .setPriority(1) + .setConditions(client.instantiate(PolicyRuleConditions) + .setClients(client.instantiate(ClientPolicyCondition) + .setInclude([OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS.name()]))) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + Policy createdPolicy = createdAuthorizationServer.createPolicy(policy) + registerForCleanup(createdPolicy) + + assertPresent(createdAuthorizationServer.listPolicies(), createdPolicy) + } + + @Test + void getAuthorizationServerPolicyTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + Policy policy = client.instantiate(Policy) + .setType(PolicyType.OAUTH_AUTHORIZATION_POLICY) + .setName("Test Policy") + .setDescription("Test Policy") + .setPriority(1) + .setConditions(client.instantiate(PolicyRuleConditions) + .setClients(client.instantiate(ClientPolicyCondition) + .setInclude([OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS.name()]))) + registerForCleanup(policy) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + Policy createdPolicy = createdAuthorizationServer.createPolicy(policy) + registerForCleanup(createdPolicy) + + Policy retrievedPolicy = createdAuthorizationServer.getPolicy(createdPolicy.getId()) + assertThat(retrievedPolicy.getId(), equalTo(createdPolicy.getId())) + assertThat(retrievedPolicy.getDescription(), equalTo(createdPolicy.getDescription())) + assertThat(retrievedPolicy.getName(), equalTo(createdPolicy.getName())) + } + + @Test + void updateAuthorizationServerPolicyTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + Policy policy = client.instantiate(Policy) + .setType(PolicyType.OAUTH_AUTHORIZATION_POLICY) + .setName("Test Policy") + .setDescription("Test Policy") + .setPriority(1) + .setConditions(client.instantiate(PolicyRuleConditions) + .setClients(client.instantiate(ClientPolicyCondition) + .setInclude([OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS.name()]))) + registerForCleanup(policy) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + Policy createdPolicy = createdAuthorizationServer.createPolicy(policy) + registerForCleanup(createdPolicy) + + assertThat(createdPolicy, notNullValue()) + + createdPolicy.setName("Test Policy Updated") + createdPolicy.setDescription("Test Policy Updated") + + Policy updatedPolicy = createdAuthorizationServer.updatePolicy(createdPolicy.getId(), createdPolicy) + assertThat(updatedPolicy, notNullValue()) + assertThat(updatedPolicy.getId(), equalTo(createdPolicy.getId())) + assertThat(updatedPolicy.getName(), equalTo(createdPolicy.getName())) + assertThat(updatedPolicy.getDescription(), equalTo(createdPolicy.getDescription())) + } + + @Test + void deleteAuthorizationServerPolicyTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + Policy policy = client.instantiate(Policy) + .setType(PolicyType.OAUTH_AUTHORIZATION_POLICY) + .setName("Test Policy") + .setDescription("Test Policy") + .setPriority(1) + .setConditions(client.instantiate(PolicyRuleConditions) + .setClients(client.instantiate(ClientPolicyCondition).setInclude([OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS.name()]))) + registerForCleanup(policy) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + Policy createdPolicy = createdAuthorizationServer.createPolicy(policy) + registerForCleanup(createdPolicy) + + assertThat(createdPolicy, notNullValue()) + + createdAuthorizationServer.deletePolicy(createdPolicy.getId()) + + // delete may not effect immediately in the backend + sleep(2000) + + assertNotPresent(createdAuthorizationServer.listPolicies(), createdPolicy) + } + + // Scope operations + + @Test + void listOAuth2ScopesTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Scope oAuth2Scope = client.instantiate(OAuth2Scope) + .setName("java-sdk-authorization-server-scope" + RandomStringUtils.randomAlphanumeric(10)) + + OAuth2Scope createdOAuth2Scope = createdAuthorizationServer.createOAuth2Scope(oAuth2Scope) + + assertThat(createdOAuth2Scope, notNullValue()) + assertPresent(createdAuthorizationServer.listOAuth2Scopes(), createdOAuth2Scope) + } + + @Test + void getOAuth2ScopesTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Scope oAuth2Scope = client.instantiate(OAuth2Scope) + .setName("java-sdk-authorization-server-scope" + RandomStringUtils.randomAlphanumeric(10)) + + OAuth2Scope createdOAuth2Scope = createdAuthorizationServer.createOAuth2Scope(oAuth2Scope) + + assertThat(createdOAuth2Scope, notNullValue()) + + OAuth2Scope retrievedOAuth2Scope = createdAuthorizationServer.getOAuth2Scope(createdOAuth2Scope.getId()) + + assertThat(retrievedOAuth2Scope.getId(), equalTo(createdOAuth2Scope.getId())) + } + + @Test + void updateOAuth2ScopesTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Scope oAuth2Scope = client.instantiate(OAuth2Scope) + .setName("java-sdk-authorization-server-scope" + RandomStringUtils.randomAlphanumeric(10)) + .setConsent(OAuth2Scope.ConsentEnum.REQUIRED) + .setMetadataPublish(OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS) + + OAuth2Scope createdOAuth2Scope = createdAuthorizationServer.createOAuth2Scope(oAuth2Scope) + + assertThat(createdOAuth2Scope, notNullValue()) + + OAuth2Scope tobeUpdatedOAuth2Scope = client.instantiate(OAuth2Scope) + .setName("java-sdk-authorization-server-scope" + RandomStringUtils.randomAlphanumeric(10) + "-updated") + .setConsent(OAuth2Scope.ConsentEnum.REQUIRED) + .setMetadataPublish(OAuth2Scope.MetadataPublishEnum.ALL_CLIENTS) + + OAuth2Scope updatedOAuth2Scope = createdAuthorizationServer.updateOAuth2Scope(createdOAuth2Scope.getId(), tobeUpdatedOAuth2Scope) + + assertThat(updatedOAuth2Scope.getId(), equalTo(tobeUpdatedOAuth2Scope.getId())) + assertThat(updatedOAuth2Scope.getName(), equalTo(tobeUpdatedOAuth2Scope.getName())) + } + + @Test + void deleteOAuth2ScopesTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Scope oAuth2Scope = client.instantiate(OAuth2Scope) + .setName("java-sdk-authorization-server-scope" + RandomStringUtils.randomAlphanumeric(10)) + + OAuth2Scope createdOAuth2Scope = createdAuthorizationServer.createOAuth2Scope(oAuth2Scope) + + assertThat(createdOAuth2Scope, notNullValue()) + + createdAuthorizationServer.deleteOAuth2Scope(createdOAuth2Scope.getId()) + + // delete may not effect immediately in the backend + sleep(2000) + + assertNotPresent(createdAuthorizationServer.listOAuth2Scopes(), createdOAuth2Scope) + } + + // Claim operations + + @Test + void listOAuth2ClaimsTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Claim oAuth2Claim = client.instantiate(OAuth2Claim) + .setName("java-sdk-authorization-server-claims" + RandomStringUtils.randomAlphanumeric(10)) + .setStatus(OAuth2Claim.StatusEnum.INACTIVE) + .setClaimType(OAuth2Claim.ClaimTypeEnum.RESOURCE) + .setValueType(OAuth2Claim.ValueTypeEnum.EXPRESSION) + .setValue("\"driving!\"") // value must be an Okta EL expression if valueType is EXPRESSION + + OAuth2Claim createdOAuth2Claim = createdAuthorizationServer.createOAuth2Claim(oAuth2Claim) + assertThat(createdOAuth2Claim, notNullValue()) + + assertPresent(createdAuthorizationServer.listOAuth2Claims(), createdOAuth2Claim) + } + + @Test + void getOAuth2ClaimTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Claim oAuth2Claim = client.instantiate(OAuth2Claim) + .setName("java-sdk-authorization-server-claims" + RandomStringUtils.randomAlphanumeric(10)) + .setStatus(OAuth2Claim.StatusEnum.INACTIVE) + .setClaimType(OAuth2Claim.ClaimTypeEnum.RESOURCE) + .setValueType(OAuth2Claim.ValueTypeEnum.EXPRESSION) + .setValue("\"driving!\"") + + OAuth2Claim createdOAuth2Claim = createdAuthorizationServer.createOAuth2Claim(oAuth2Claim) + assertThat(createdOAuth2Claim, notNullValue()) + + OAuth2Claim retrievedOAuth2Claim = createdAuthorizationServer.getOAuth2Claim(createdOAuth2Claim.getId()) + assertThat(retrievedOAuth2Claim, notNullValue()) + assertThat(retrievedOAuth2Claim.getId(), equalTo(createdOAuth2Claim.getId())) + } + + @Test + void updateOAuth2ClaimTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Claim oAuth2Claim = client.instantiate(OAuth2Claim) + .setName("java-sdk-authorization-server-claims" + RandomStringUtils.randomAlphanumeric(10)) + .setStatus(OAuth2Claim.StatusEnum.INACTIVE) + .setClaimType(OAuth2Claim.ClaimTypeEnum.RESOURCE) + .setValueType(OAuth2Claim.ValueTypeEnum.EXPRESSION) + .setValue("\"driving!\"") + + OAuth2Claim createdOAuth2Claim = createdAuthorizationServer.createOAuth2Claim(oAuth2Claim) + assertThat(createdOAuth2Claim, notNullValue()) + + OAuth2Claim tobeUpdatedOAuth2Claim = client.instantiate(OAuth2Claim) + .setName("java-sdk-authorization-server-claims" + RandomStringUtils.randomAlphanumeric(10) + "-updated") + .setStatus(OAuth2Claim.StatusEnum.INACTIVE) + .setClaimType(OAuth2Claim.ClaimTypeEnum.RESOURCE) + .setValueType(OAuth2Claim.ValueTypeEnum.EXPRESSION) + .setValue("\"driving!\"") + + OAuth2Claim updatedOAuth2Claim = createdAuthorizationServer.updateOAuth2Claim(createdOAuth2Claim.getId(), tobeUpdatedOAuth2Claim) + + assertThat(updatedOAuth2Claim.getId(), equalTo(tobeUpdatedOAuth2Claim.getId())) + assertThat(updatedOAuth2Claim.getName(), equalTo(tobeUpdatedOAuth2Claim.getName())) + } + + @Test + void deleteOAuth2ClaimTest() { + String name = "java-sdk-authorization-server-" + RandomStringUtils.randomAlphanumeric(15) + + AuthorizationServer createdAuthorizationServer = client.createAuthorizationServer( + client.instantiate(AuthorizationServer) + .setName(name) + .setDescription("Test Authorization Server") + .setAudiences(["api://example"])) + registerForCleanup(createdAuthorizationServer) + + assertThat(createdAuthorizationServer, notNullValue()) + + OAuth2Claim oAuth2Claim = client.instantiate(OAuth2Claim) + .setName("java-sdk-authorization-server-claims" + RandomStringUtils.randomAlphanumeric(10)) + .setStatus(OAuth2Claim.StatusEnum.INACTIVE) + .setClaimType(OAuth2Claim.ClaimTypeEnum.RESOURCE) + .setValueType(OAuth2Claim.ValueTypeEnum.EXPRESSION) + .setValue("\"driving!\"") + + OAuth2Claim createdOAuth2Claim = createdAuthorizationServer.createOAuth2Claim(oAuth2Claim) + assertThat(createdOAuth2Claim, notNullValue()) + + createdAuthorizationServer.deleteOAuth2Claim(createdOAuth2Claim.getId()) + + // delete may not effect immediately in the backend + sleep(2000) + + assertNotPresent(createdAuthorizationServer.listOAuth2Claims(), createdOAuth2Claim) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/CrudTestSupport.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/CrudTestSupport.groovy index df0ee2f66f8..10b482c9159 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/CrudTestSupport.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/CrudTestSupport.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2017 Okta + * Copyright 2017-Present Okta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/EventHooksIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/EventHooksIT.groovy new file mode 100644 index 00000000000..fdf17b0ab8a --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/EventHooksIT.groovy @@ -0,0 +1,190 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.ResourceException +import com.okta.sdk.resource.event.hook.EventHook +import com.okta.sdk.resource.event.hook.EventHookBuilder +import com.okta.sdk.resource.event.hook.EventHookChannelConfigAuthScheme +import com.okta.sdk.resource.event.hook.EventHookChannelConfigAuthSchemeType + +import com.okta.sdk.tests.it.util.ITSupport + +import org.testng.annotations.Test + +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.iterableWithSize +import static org.hamcrest.Matchers.notNullValue + +import static com.okta.sdk.tests.it.util.Util.assertPresent + +/** + * Tests for {@code /api/v1/eventHooks}. + * @since 2.0.0 + */ +class EventHooksIT extends ITSupport { + + @Test + void createEventHookTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + assertThat(createdEventHook.getName(), equalTo(name)) + assertThat(createdEventHook.getStatus(), equalTo(EventHook.StatusEnum.ACTIVE)) + assertThat(createdEventHook.getEvents().getItems(), iterableWithSize(2)) + assertThat(createdEventHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/eventHooks")) + + createdEventHook.deactivate() + } + + @Test + void getEventHookTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + + EventHook retrievedEventHook = client.getEventHook(createdEventHook.getId()) + + assertThat(retrievedEventHook.getId(), notNullValue()) + assertThat(retrievedEventHook.getName(), equalTo(name)) + assertThat(createdEventHook.getStatus(), equalTo(EventHook.StatusEnum.ACTIVE)) + assertThat(retrievedEventHook.getEvents().getItems(), iterableWithSize(2)) + assertThat(retrievedEventHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/eventHooks")) + + createdEventHook.deactivate() + } + + @Test + void updateEventHookTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + + EventHook toBeUpdatedEventHook = createdEventHook.setName("updated-" + name) + createdEventHook.getEvents().getItems().add("user.lifecycle.deactivate") + createdEventHook.getChannel().getConfig().setAuthScheme(client.instantiate(EventHookChannelConfigAuthScheme) + .setType(EventHookChannelConfigAuthSchemeType.HEADER) + .setKey("Authorization") + .setValue("Test-Api-Key-Updated")) + .setUri("https://www.example.com/eventHooksUpdated") + + EventHook updatedEventHook = toBeUpdatedEventHook.update() + + assertThat(updatedEventHook.getId(), notNullValue()) + assertThat(updatedEventHook.getId(), equalTo(createdEventHook.getId())) + assertThat(createdEventHook.getStatus(), equalTo(EventHook.StatusEnum.ACTIVE)) + assertThat(updatedEventHook.getName(), equalTo("updated-" + name)) + assertThat(updatedEventHook.getEvents().getItems(), iterableWithSize(3)) + assertThat(updatedEventHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/eventHooksUpdated")) + + createdEventHook.deactivate() + } + + @Test + void deleteEventHookTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + + EventHook retrievedEventHook = client.getEventHook(createdEventHook.getId()) + assertThat(retrievedEventHook.getId(), equalTo(createdEventHook.getId())) + assertThat(retrievedEventHook.getStatus(), equalTo(EventHook.StatusEnum.ACTIVE)) + + createdEventHook.deactivate() + createdEventHook.delete() + + try { + client.getEventHook(createdEventHook.getId()) + } + catch (ResourceException e) { + assertThat(e.status, equalTo(404)) + } + } + + @Test + void listAllEventHooksTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + + assertPresent(client.listEventHooks(), createdEventHook) + + createdEventHook.deactivate() + } + + @Test + void activateDeactivateEventHookTest() { + String name = "event-hook-java-sdk-${UUID.randomUUID().toString()}" + + EventHook createdEventHook = EventHookBuilder.instance() + .setName(name) + .setUrl("https://www.example.com/eventHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client); + registerForCleanup(createdEventHook) + + assertThat(createdEventHook.getId(), notNullValue()) + assertThat(createdEventHook.getStatus(), equalTo(EventHook.StatusEnum.ACTIVE)) + + createdEventHook.deactivate() + + EventHook retrievedEventHook = client.getEventHook(createdEventHook.getId()) + + assertThat(retrievedEventHook.getStatus(), equalTo(EventHook.StatusEnum.INACTIVE)) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FactorsIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FactorsIT.groovy index f1b2db19868..0cf090578c7 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FactorsIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FactorsIT.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2017 Okta + * Copyright 2017-Present Okta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,26 +15,36 @@ */ package com.okta.sdk.tests.it -import com.google.common.collect.Lists; +import com.google.common.collect.Lists + import com.okta.sdk.client.Client import com.okta.sdk.resource.user.User -import com.okta.sdk.resource.user.UserBuilder -import com.okta.sdk.resource.user.factor.CallFactor -import com.okta.sdk.resource.user.factor.Factor -import com.okta.sdk.resource.user.factor.FactorList -import com.okta.sdk.resource.user.factor.FactorResultType +import com.okta.sdk.resource.user.factor.ActivateFactorRequest +import com.okta.sdk.resource.user.factor.CallUserFactor +import com.okta.sdk.resource.user.factor.EmailUserFactor +import com.okta.sdk.resource.user.factor.EmailUserFactorProfile +import com.okta.sdk.resource.user.factor.FactorProvider import com.okta.sdk.resource.user.factor.FactorStatus -import com.okta.sdk.resource.user.factor.PushFactor -import com.okta.sdk.resource.user.factor.SecurityQuestionFactor +import com.okta.sdk.resource.user.factor.FactorType +import com.okta.sdk.resource.user.factor.HardwareUserFactor +import com.okta.sdk.resource.user.factor.HardwareUserFactorProfile +import com.okta.sdk.resource.user.factor.PushUserFactor +import com.okta.sdk.resource.user.factor.SecurityQuestionUserFactor import com.okta.sdk.resource.user.factor.SecurityQuestionList -import com.okta.sdk.resource.user.factor.SmsFactor -import com.okta.sdk.resource.user.factor.SmsFactorProfile -import com.okta.sdk.resource.user.factor.TotpFactor +import com.okta.sdk.resource.user.factor.SmsUserFactor +import com.okta.sdk.resource.user.factor.TokenUserFactor +import com.okta.sdk.resource.user.factor.TokenUserFactorProfile +import com.okta.sdk.resource.user.factor.TotpUserFactor +import com.okta.sdk.resource.user.factor.U2fUserFactor +import com.okta.sdk.resource.user.factor.U2fUserFactorProfile +import com.okta.sdk.resource.user.factor.UserFactor +import com.okta.sdk.resource.user.factor.UserFactorList import com.okta.sdk.resource.user.factor.VerifyFactorRequest -import com.okta.sdk.resource.user.factor.VerifyFactorResponse +import com.okta.sdk.resource.user.factor.VerifyUserFactorResponse +import com.okta.sdk.resource.user.factor.WebUserFactor +import com.okta.sdk.resource.user.factor.WebUserFactorProfile import com.okta.sdk.tests.it.util.ITSupport import org.jboss.aerogear.security.otp.Totp -import org.jboss.aerogear.security.otp.api.Base32 import org.testng.annotations.Test import static org.hamcrest.Matchers.* @@ -42,7 +52,6 @@ import static org.hamcrest.MatcherAssert.assertThat class FactorsIT extends ITSupport { - private String smsTestNumber = "162 840 01133" @Test @@ -53,25 +62,25 @@ class FactorsIT extends ITSupport { assertThat user.listFactors(), emptyIterable() - SmsFactor smsFactor = client.instantiate(SmsFactor) - smsFactor.getProfile().phoneNumber = smsTestNumber - user.addFactor(smsFactor) + SmsUserFactor smsUserFactor = client.instantiate(SmsUserFactor) + smsUserFactor.getProfile().setPhoneNumber(smsTestNumber) + user.enrollFactor(smsUserFactor) - SecurityQuestionFactor securityQuestionFactor = client.instantiate(SecurityQuestionFactor) - securityQuestionFactor.getProfile() - .setQuestion("disliked_food") - .setAnswer("pizza") - user.addFactor(securityQuestionFactor) + SecurityQuestionUserFactor securityQuestionUserFactor = client.instantiate(SecurityQuestionUserFactor) + securityQuestionUserFactor.getProfile() + .setQuestion("disliked_food") + .setAnswer("pizza") + user.enrollFactor(securityQuestionUserFactor) - FactorList factorsList = user.listFactors() - List factorsArrayList = Lists.newArrayList(factorsList) + UserFactorList factorsList = user.listFactors() + List factorsArrayList = Lists.newArrayList(factorsList) assertThat factorsArrayList, allOf(hasSize(2), containsInAnyOrder( - allOf( - instanceOf(SmsFactor), - hasProperty("id", is(smsFactor.getId()))), - allOf( - instanceOf(SecurityQuestionFactor), - hasProperty("id", is(securityQuestionFactor.getId()))))) + allOf( + instanceOf(SmsUserFactor), + hasProperty("id", is(smsUserFactor.getId()))), + allOf( + instanceOf(SecurityQuestionUserFactor), + hasProperty("id", is(securityQuestionUserFactor.getId()))))) } @Test @@ -81,14 +90,14 @@ class FactorsIT extends ITSupport { assertThat user.listFactors(), emptyIterable() - SecurityQuestionFactor securityQuestionFactor = client.instantiate(SecurityQuestionFactor) - securityQuestionFactor.getProfile() - .setQuestion("disliked_food") - .setAnswer("pizza") + SecurityQuestionUserFactor securityQuestionUserFactor = client.instantiate(SecurityQuestionUserFactor) + securityQuestionUserFactor.getProfile() + .setQuestion("disliked_food") + .setAnswer("pizza") - assertThat securityQuestionFactor.id, nullValue() - assertThat securityQuestionFactor, sameInstance(user.addFactor(securityQuestionFactor)) - assertThat securityQuestionFactor.id, notNullValue() + assertThat securityQuestionUserFactor.id, nullValue() + assertThat securityQuestionUserFactor, sameInstance(user.enrollFactor(securityQuestionUserFactor)) + assertThat securityQuestionUserFactor.id, notNullValue() } @Test @@ -98,12 +107,12 @@ class FactorsIT extends ITSupport { assertThat user.listFactors(), emptyIterable() - CallFactor callFactor = client.instantiate(CallFactor) - callFactor.getProfile().phoneNumber = smsTestNumber + CallUserFactor callUserFactor = client.instantiate(CallUserFactor) + callUserFactor.getProfile().setPhoneNumber(smsTestNumber) - assertThat callFactor.id, nullValue() - assertThat callFactor, sameInstance(user.addFactor(callFactor)) - assertThat callFactor.id, notNullValue() + assertThat callUserFactor.id, nullValue() + assertThat callUserFactor, sameInstance(user.enrollFactor(callUserFactor)) + assertThat callUserFactor.id, notNullValue() } @Test @@ -113,12 +122,12 @@ class FactorsIT extends ITSupport { assertThat user.listFactors(), emptyIterable() - SmsFactor smsFactor = client.instantiate(SmsFactor) - smsFactor.getProfile().phoneNumber = smsTestNumber + SmsUserFactor smsUserFactor = client.instantiate(SmsUserFactor) + smsUserFactor.getProfile().setPhoneNumber(smsTestNumber) - assertThat smsFactor.id, nullValue() - assertThat smsFactor, sameInstance(user.addFactor(smsFactor)) - assertThat smsFactor.id, notNullValue() + assertThat smsUserFactor.id, nullValue() + assertThat smsUserFactor, sameInstance(user.enrollFactor(smsUserFactor)) + assertThat smsUserFactor.id, notNullValue() } @Test @@ -127,10 +136,10 @@ class FactorsIT extends ITSupport { User user = randomUser() assertThat user.listFactors(), emptyIterable() - PushFactor pushFactor = client.instantiate(PushFactor) - assertThat pushFactor.id, nullValue() - assertThat pushFactor, sameInstance(user.addFactor(pushFactor)) - assertThat pushFactor.id, notNullValue() + PushUserFactor pushUserFactor = client.instantiate(PushUserFactor) + assertThat pushUserFactor.id, nullValue() + assertThat pushUserFactor, sameInstance(user.enrollFactor(pushUserFactor)) + assertThat pushUserFactor.id, notNullValue() } @Test @@ -143,7 +152,7 @@ class FactorsIT extends ITSupport { @Test void testAvailableFactorsNotEmpty() { User user = randomUser() - FactorList factors = user.listSupportedFactors() + UserFactorList factors = user.listSupportedFactors() assertThat factors, iterableWithSize(greaterThan(1)) } @@ -151,33 +160,72 @@ class FactorsIT extends ITSupport { void activateTotpFactor() { User user = randomUser() assertThat user.listFactors(), emptyIterable() - TotpFactor totpFactor = client.instantiate(TotpFactor) - user.addFactor(totpFactor) + TotpUserFactor totpUserFactor = client.instantiate(TotpUserFactor) + user.enrollFactor(totpUserFactor) - assertThat totpFactor.getStatus(), is(FactorStatus.PENDING_ACTIVATION) - Totp totp = new Totp(totpFactor.getEmbedded().get("activation").get("sharedSecret")) + assertThat totpUserFactor.getStatus(), is(FactorStatus.PENDING_ACTIVATION) + Totp totp = new Totp(totpUserFactor.getEmbedded().get("activation").get("sharedSecret")) - VerifyFactorRequest verifyFactorRequest = client.instantiate(VerifyFactorRequest) - verifyFactorRequest.passCode = totp.now() - Factor factorResult = totpFactor.activate(verifyFactorRequest) + ActivateFactorRequest activateFactorRequest = client.instantiate(ActivateFactorRequest) + activateFactorRequest.setPassCode(totp.now()) + UserFactor factorResult = totpUserFactor.activate(activateFactorRequest) assertThat factorResult.getStatus(), is(FactorStatus.ACTIVE) - assertThat factorResult, instanceOf(TotpFactor) + assertThat factorResult, instanceOf(TotpUserFactor) } @Test void verifyQuestionFactor() { User user = randomUser() - SecurityQuestionFactor securityQuestionFactor = client.instantiate(SecurityQuestionFactor) - securityQuestionFactor.getProfile() - .setQuestion("disliked_food") - .setAnswer("pizza") - user.addFactor(securityQuestionFactor) + SecurityQuestionUserFactor securityQuestionUserFactor = client.instantiate(SecurityQuestionUserFactor) + securityQuestionUserFactor.getProfile() + .setQuestion("disliked_food") + .setAnswer("pizza") + user.enrollFactor(securityQuestionUserFactor) + + VerifyFactorRequest request = client.instantiate(VerifyFactorRequest) + request.setAnswer("pizza") + VerifyUserFactorResponse response = + securityQuestionUserFactor.verify(request, null, null, null, null, null) + assertThat response.getFactorResult(), is(VerifyUserFactorResponse.FactorResultEnum.SUCCESS) + } + + @Test + void testEmailUserFactor() { + User user = randomUser() + assertThat user.listFactors(), emptyIterable() + + EmailUserFactor emailUserFactor = client.instantiate(EmailUserFactor) + .setFactorType(FactorType.EMAIL) + .setProvider(FactorProvider.OKTA) + .setProfile(client.instantiate(EmailUserFactorProfile) + .setEmail(user.getProfile().getEmail())) + + assertThat emailUserFactor.id, nullValue() + // enroll and activate + assertThat emailUserFactor, sameInstance(user.enrollFactor(emailUserFactor, false, null, null, true)) + assertThat emailUserFactor.getStatus(), is(FactorStatus.ACTIVE) + assertThat emailUserFactor.id, notNullValue() VerifyFactorRequest request = client.instantiate(VerifyFactorRequest) - request.answer = "pizza" - VerifyFactorResponse response = securityQuestionFactor.verify(request) - assertThat response.getFactorResult(), is(FactorResultType.SUCCESS) + VerifyUserFactorResponse response = + emailUserFactor.verify(request, null, null, null, null, null) + assertThat response.getFactorResult(), is(VerifyUserFactorResponse.FactorResultEnum.CHALLENGE) + } + + @Test + void testGoogleTotpUserFactorCreation() { + User user = randomUser() + assertThat user.listFactors(), emptyIterable() + + TokenUserFactor tokenUserFactor = client.instantiate(TokenUserFactor) + .setFactorType(FactorType.TOKEN_SOFTWARE_TOTP) + .setProvider(FactorProvider.GOOGLE) + + assertThat tokenUserFactor.id, nullValue() + assertThat tokenUserFactor, sameInstance(user.enrollFactor(tokenUserFactor)) + assertThat tokenUserFactor.id, notNullValue() + assertThat tokenUserFactor.getStatus(), is(FactorStatus.PENDING_ACTIVATION) } @Test @@ -185,9 +233,9 @@ class FactorsIT extends ITSupport { User user = randomUser() assertThat user.listFactors(), emptyIterable() - TotpFactor totpFactor = client.instantiate(TotpFactor) - totpFactor.provider = "OKTA" - user.addFactor(totpFactor) - totpFactor.delete() + TotpUserFactor totpUserFactor = client.instantiate(TotpUserFactor) + totpUserFactor.setProvider(FactorProvider.OKTA) + user.enrollFactor(totpUserFactor) + totpUserFactor.delete() } } diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FeaturesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FeaturesIT.groovy new file mode 100644 index 00000000000..6a1a8912965 --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/FeaturesIT.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.feature.Feature +import com.okta.sdk.resource.feature.FeatureList +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.* + +/** + * Tests for {@code /api/v1/features}. + * @since 2.0.0 + */ +class FeaturesIT extends ITSupport { + + @Test + void featureOperationsTest() { + // list features + FeatureList featureList = client.listFeatures() + assertThat(featureList, iterableWithSize(greaterThan(0))) + + // pick first one from the list + Feature feature = featureList.getAt(0) + assertThat(feature, notNullValue()) + + // get feature by id + Feature retrievedFeature = client.getFeature(feature.getId()) + assertThat(retrievedFeature, notNullValue()) + assertThat(retrievedFeature.getId(), equalTo(feature.getId())) + assertThat(retrievedFeature.getName(), equalTo(feature.getName())) + assertThat(retrievedFeature.getDescription(), equalTo(feature.getDescription())) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRolesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRolesIT.groovy new file mode 100644 index 00000000000..7d841c788ee --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRolesIT.groovy @@ -0,0 +1,195 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.group.GroupBuilder +import com.okta.sdk.resource.group.Group +import com.okta.sdk.resource.role.AssignRoleRequest +import com.okta.sdk.resource.role.RoleType +import com.okta.sdk.resource.user.Role +import com.okta.sdk.resource.user.RoleList +import com.okta.sdk.tests.Scenario +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static com.okta.sdk.tests.it.util.Util.assertGroupPresent +import static com.okta.sdk.tests.it.util.Util.assertGroupAbsent +import static com.okta.sdk.tests.it.util.Util.assertRolePresent +import static com.okta.sdk.tests.it.util.Util.assertRoleAbsent +import static com.okta.sdk.tests.it.util.Util.validateGroup + +/** + * Tests for {@code /api/v1/groups/roles}. + * @since 2.0.0 + */ +class GroupRolesIT extends ITSupport { + + @Test + @Scenario("list-roles-assigned-to-group") + void listRolesAssignedToGroupTest() { + + String groupName = "sdk-java List Test Group ${uniqueTestName}" + + // 1. Create a new group + Group createdGroup = GroupBuilder.instance() + .setName(groupName) + .buildAndCreate(client) + registerForCleanup(createdGroup) + + validateGroup(createdGroup, groupName) + + // 2. List all groups and find the group created + assertGroupPresent(client.listGroups(), createdGroup) + + // 3. Create assign role requests + AssignRoleRequest userAdminRoleRequest = client.instantiate(AssignRoleRequest) + userAdminRoleRequest.setType(RoleType.USER_ADMIN) + + AssignRoleRequest appAdminRoleRequest = client.instantiate(AssignRoleRequest) + appAdminRoleRequest.setType(RoleType.APP_ADMIN) + + // 4. Assign USER_ADMIN & APP_ADMIN roles + Role userAdminRole = createdGroup.assignRole(userAdminRoleRequest) + Role appAdminRole = createdGroup.assignRole(appAdminRoleRequest) + + // 5. List assigned group roles and check the assignments + RoleList roles = client.listGroupAssignedRoles(createdGroup.getId()) + + assertRolePresent(roles, userAdminRole) + assertRolePresent(roles, appAdminRole) + } + + @Test + @Scenario("unassigned-roles-for-group") + void unassignRoleForGroupTest() { + + String groupName = "sdk-java List Test Group ${uniqueTestName}" + + // 1. Create a new group + Group createdGroup = GroupBuilder.instance() + .setName(groupName) + .buildAndCreate(client) + registerForCleanup(createdGroup) + + validateGroup(createdGroup, groupName) + + // 2. List all groups and find the group created + assertGroupPresent(client.listGroups(), createdGroup) + + // 3. Create a USER_ADMIN role request + AssignRoleRequest userAdminRoleRequest = client.instantiate(AssignRoleRequest) + userAdminRoleRequest.setType(RoleType.USER_ADMIN) + + // 4. Assign the above role + Role userAdminRole = createdGroup.assignRole(userAdminRoleRequest) + + // 5. List assigned group roles and check the assignments + assertRolePresent(client.listGroupAssignedRoles(createdGroup.getId()), userAdminRole) + + // 6. Remove the role from group + client.removeRoleFromGroup(createdGroup.getId(), userAdminRole.getId()) + + // 7. List assigned group roles and check the assignments + assertRoleAbsent(client.listGroupAssignedRoles(createdGroup.getId()), userAdminRole) + } + + @Test + @Scenario("list-group-targets-for-group") + void listGroupTargetsForGroupTest() { + + String groupName1 = "sdk-java List Test Group ${uniqueTestName}-1" + String groupName2 = "sdk-java List Test Group ${uniqueTestName}-2" + + // 1. Create two groups + Group createdGroup1 = GroupBuilder.instance() + .setName(groupName1) + .buildAndCreate(client) + Group createdGroup2 = GroupBuilder.instance() + .setName(groupName2) + .buildAndCreate(client) + registerForCleanup(createdGroup1) + registerForCleanup(createdGroup2) + + validateGroup(createdGroup1, groupName1) + validateGroup(createdGroup2, groupName2) + + // 2. List all groups and find the groups created + assertGroupPresent(client.listGroups(), createdGroup1) + assertGroupPresent(client.listGroups(), createdGroup2) + + // 3. Create a USER_ADMIN role & assign it to the first group + Role userAdminRole = createdGroup1.assignRole(client.instantiate(AssignRoleRequest) + .setType(RoleType.USER_ADMIN)) + + // 4. Add second group as the admin target for the user admin role + userAdminRole.addAdminGroupTarget(createdGroup2.getId()) + + // 5. Verify the same + assertGroupPresent(client.listGroupTargetsForGroupRole(createdGroup1.getId(), userAdminRole.getId()), createdGroup2) + } + + @Test + @Scenario("list-group-targets-for-group") + void removeGroupTargetFromGroupAdministratorRoleGivenToGroupTest() { + + String groupName1 = "sdk-java List Test Group ${uniqueTestName}-1" + String groupName2 = "sdk-java List Test Group ${uniqueTestName}-2" + String groupName3 = "sdk-java List Test Group ${uniqueTestName}-3" + + // 1. Create three groups + Group createdGroup1 = GroupBuilder.instance() + .setName(groupName1) + .buildAndCreate(client) + Group createdGroup2 = GroupBuilder.instance() + .setName(groupName2) + .buildAndCreate(client) + Group createdGroup3 = GroupBuilder.instance() + .setName(groupName3) + .buildAndCreate(client) + registerForCleanup(createdGroup1) + registerForCleanup(createdGroup2) + registerForCleanup(createdGroup3) + + validateGroup(createdGroup1, groupName1) + validateGroup(createdGroup2, groupName2) + validateGroup(createdGroup3, groupName3) + + // 2. List all groups and find the groups created + assertGroupPresent(client.listGroups(), createdGroup1) + assertGroupPresent(client.listGroups(), createdGroup2) + assertGroupPresent(client.listGroups(), createdGroup3) + + // 3. Create a USER_ADMIN role & assign it to the first group + Role userAdminRole = createdGroup1.assignRole(client.instantiate(AssignRoleRequest) + .setType(RoleType.USER_ADMIN)) + + // 4. Add second group as the admin target for the user admin role + userAdminRole.addAdminGroupTarget(createdGroup2.getId()) + + // 5. Add third group as the admin target for the user admin role + userAdminRole.addAdminGroupTarget(createdGroup3.getId()) + + // 6. Verify if both the above targets (group 2 & group 3) are added + assertGroupPresent(client.listGroupTargetsForGroupRole(createdGroup1.getId(), userAdminRole.getId()), createdGroup2) + assertGroupPresent(client.listGroupTargetsForGroupRole(createdGroup1.getId(), userAdminRole.getId()), createdGroup3) + + // 7. Remove group 2 from the target + client.removeGroupTargetFromGroupAdministratorRoleGivenToGroup(createdGroup1.getId(), userAdminRole.getId(), createdGroup2.getId()) + + // 8. Verify that group 2 is removed from the target + assertGroupAbsent(client.listGroupTargetsForGroupRole(createdGroup1.getId(), userAdminRole.getId()), createdGroup2) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRulesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRulesIT.groovy index c7b568b6589..2ca80103725 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRulesIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupRulesIT.groovy @@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.equalTo import static org.hamcrest.Matchers.matchesPattern /** - * Tests for /api/v1/groups/rules + * Tests for {@code /api/v1/groups/rules}. * @since 0.5.0 */ class GroupRulesIT implements CrudTestSupport { @@ -61,7 +61,7 @@ class GroupRulesIT implements CrudTestSupport { rule.getActions().setAssignUserToGroups(client.instantiate(GroupRuleGroupAssignment)) rule.getActions().getAssignUserToGroups().setGroupIds(Collections.singletonList(group.getId())) - rule = client.createRule(rule) + rule = client.createGroupRule(rule) registerForCleanup(rule) return rule @@ -69,7 +69,7 @@ class GroupRulesIT implements CrudTestSupport { @Override def read(Client client, String id) { - return client.getRule(id) + return client.getGroupRule(id) } @Override @@ -85,7 +85,7 @@ class GroupRulesIT implements CrudTestSupport { @Override Iterator getResourceCollectionIterator(Client client) { - return client.listRules().iterator() + return client.listGroupRules().iterator() } @Test @@ -124,15 +124,14 @@ class GroupRulesIT implements CrudTestSupport { .setGroupRuleExpressionValue("user.lastName==\"${user.getProfile().lastName}\"".toString()) .setAssignUserToGroups(Collections.singletonList(group.getId())) .buildAndCreate(client) - registerForCleanup(rule) rule.activate() - GroupRule readRule = client.getRule(rule.getId()) + GroupRule readRule = client.getGroupRule(rule.getId()) assertThat readRule.getStatus(), equalTo(GroupRuleStatus.ACTIVE) // 3. List group rules - assertPresent(client.listRules(), rule) + assertPresent(client.listGroupRules(), rule) // 4. Deactivate the rule and update it rule.deactivate() @@ -142,7 +141,7 @@ class GroupRulesIT implements CrudTestSupport { rule.update() rule.activate() - readRule = client.getRule(rule.getId()) + readRule = client.getGroupRule(rule.getId()) assertThat readRule.getStatus(), equalTo(GroupRuleStatus.ACTIVE) // 5. delete rule diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupsIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupsIT.groovy index 6b1970bfb65..6f4f02d81bf 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupsIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/GroupsIT.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2017 Okta + * Copyright 2017-Present Okta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,7 @@ import static org.hamcrest.MatcherAssert.assertThat import static org.hamcrest.Matchers.* /** - * Tests for /api/v1/groups + * Tests for {@code /api/v1/groups}. * @since 0.5.0 */ class GroupsIT implements CrudTestSupport { @@ -98,7 +98,7 @@ class GroupsIT implements CrudTestSupport { validateGroup(group, groupName) // 2. Search the group by name - assertPresent(client.listGroups(groupName, null, null), group) + assertPresent(client.listGroups(groupName, null), group) } @Test diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/IdpIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/IdpIT.groovy new file mode 100644 index 00000000000..cb0d34420c1 --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/IdpIT.groovy @@ -0,0 +1,441 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.identity.provider.* +import com.okta.sdk.resource.policy.* +import com.okta.sdk.resource.user.User +import com.okta.sdk.resource.user.UserBuilder +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static com.okta.sdk.tests.it.util.Util.* +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.* + +/** + * Tests for {@code /api/v1/idps}. + * @since 2.0.0 + */ +class IdpIT extends ITSupport { + + @Test + void oidcIdpLifecycleTest() { + + // create idp + IdentityProvider createdIdp = IdentityProviderBuilders.oidc() + .setName("Mock OpenID Connect Id") + .setIssuerMode(IdentityProvider.IssuerModeEnum.ORG_URL) + .setRequestSignatureAlgorithm("SHA-256") + .setRequestSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum.REQUEST) + .setResponseSignatureAlgorithm("SHA-256") + .setResponseSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum.ANY) + .setAcsEndpointBinding(ProtocolEndpoint.BindingEnum.POST) + .setAcsEndpointType(ProtocolEndpoint.TypeEnum.INSTANCE) + .setAuthorizationEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setAuthorizationEndpointUrl("https://idp.example.com/authorize") + .setTokenEndpointBinding(ProtocolEndpoint.BindingEnum.POST) + .setTokenEndpointUrl("https://idp.example.com/token") + .setUserInfoEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setUserInfoEndpointUrl("https://idp.example.com/userinfo") + .setJwksEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setJwksEndpointUrl("https://idp.example.com/keys") + .setScopes(["openid", "profile", "email"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .setIssuerUrl("https://idp.example.com") + .setMaxClockSkew(120000) + .setUserName("idpuser.email") + .setMatchType(PolicySubjectMatchType.USERNAME) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + assertThat(createdIdp, notNullValue()) + assertThat(createdIdp.getId(), notNullValue()) + assertThat(createdIdp.getStatus(), equalTo(IdentityProvider.StatusEnum.ACTIVE)) + + // get + IdentityProvider retrievedIdp = client.getIdentityProvider(createdIdp.getId()) + assertThat(retrievedIdp.getId(), equalTo(createdIdp.getId())) + + // update + IdentityProvider updatedIdp = createdIdp.update(client.instantiate(IdentityProvider) + .setType(IdentityProvider.TypeEnum.OIDC) + .setName("Mock OpenID Connect Id - NEW") + .setIssuerMode(IdentityProvider.IssuerModeEnum.ORG_URL) + .setProtocol(client.instantiate(Protocol) + .setAlgorithms(client.instantiate(ProtocolAlgorithms) + .setRequest(client.instantiate(ProtocolAlgorithmType) + .setSignature(client.instantiate(ProtocolAlgorithmTypeSignature) + .setAlgorithm("SHA-256") + .setScope(ProtocolAlgorithmTypeSignature.ScopeEnum.REQUEST))) + .setResponse(client.instantiate(ProtocolAlgorithmType) + .setSignature(client.instantiate(ProtocolAlgorithmTypeSignature) + .setAlgorithm("SHA-256") + .setScope(ProtocolAlgorithmTypeSignature.ScopeEnum.ANY)))) + .setEndpoints(client.instantiate(ProtocolEndpoints) + .setAcs(client.instantiate(ProtocolEndpoint) + .setBinding(ProtocolEndpoint.BindingEnum.POST) + .setType(ProtocolEndpoint.TypeEnum.INSTANCE)) + .setAuthorization(client.instantiate(ProtocolEndpoint) + .setBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setUrl("https://idp.example.com/authorize_new")) + .setToken(client.instantiate(ProtocolEndpoint) + .setBinding(ProtocolEndpoint.BindingEnum.POST) + .setUrl("https://idp.example.com/token_new")) + .setUserInfo(client.instantiate(ProtocolEndpoint) + .setBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setUrl("https://idp.example.com/userinfo_new")) + .setJwks(client.instantiate(ProtocolEndpoint) + .setBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setUrl("https://idp.example.com/keys_new"))) + .setScopes(["openid", "profile", "email"]) + .setType(Protocol.TypeEnum.OIDC) + .setCredentials(client.instantiate(IdentityProviderCredentials) + .setClient(client.instantiate(IdentityProviderCredentialsClient) + .setClientId("your-new-client-id") + .setClientSecret("your-new-client-secret"))) + .setIssuer(client.instantiate(ProtocolEndpoint) + .setUrl("https://idp.example.com/new"))) + .setPolicy(client.instantiate(IdentityProviderPolicy) + .setAccountLink(client.instantiate(PolicyAccountLink) + .setAction(PolicyAccountLink.ActionEnum.AUTO) + .setFilter(null)) + .setProvisioning(client.instantiate(Provisioning) + .setAction(Provisioning.ActionEnum.AUTO) + .setConditions(client.instantiate(ProvisioningConditions) + .setDeprovisioned(client.instantiate(ProvisioningDeprovisionedCondition) + .setAction(ProvisioningDeprovisionedCondition.ActionEnum.NONE)) + .setSuspended(client.instantiate(ProvisioningSuspendedCondition) + .setAction(ProvisioningSuspendedCondition.ActionEnum.NONE))) + .setGroups(client.instantiate(ProvisioningGroups) + .setAction(ProvisioningGroups.ActionEnum.NONE))) + .setMaxClockSkew(120000) + .setSubject(client.instantiate(PolicySubject) + .setUserNameTemplate(client.instantiate(PolicyUserNameTemplate) + .setTemplate("idpuser.email")) + .setMatchType(PolicySubjectMatchType.USERNAME)))) + registerForCleanup(updatedIdp) + + IdentityProvider retrievedUpdatedIdp = client.getIdentityProvider(updatedIdp.getId()) + assertThat(retrievedUpdatedIdp.getId(), equalTo(createdIdp.getId())) + assertThat(retrievedUpdatedIdp.getName(), equalTo("Mock OpenID Connect Id - NEW")) + assertThat(retrievedUpdatedIdp.getProtocol().getEndpoints().getAuthorization().getUrl(), + equalTo("https://idp.example.com/authorize_new")) + assertThat(retrievedUpdatedIdp.getProtocol().getEndpoints().getToken().getUrl(), + equalTo("https://idp.example.com/token_new")) + assertThat(retrievedUpdatedIdp.getProtocol().getEndpoints().getUserInfo().getUrl(), + equalTo("https://idp.example.com/userinfo_new")) + assertThat(retrievedUpdatedIdp.getProtocol().getEndpoints().getJwks().getUrl(), + equalTo("https://idp.example.com/keys_new")) + assertThat(retrievedUpdatedIdp.getProtocol().getCredentials().getClient().getClientId(), + equalTo("your-new-client-id")) + assertThat(retrievedUpdatedIdp.getProtocol().getCredentials().getClient().getClientSecret(), + equalTo("your-new-client-secret")) + assertThat(retrievedUpdatedIdp.getProtocol().getIssuer().getUrl(), + equalTo("https://idp.example.com/new")) + + assertPresent(client.listIdentityProviders(), updatedIdp) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + + // earlier operation may not complete immediately + sleep(2000) + + assertNotPresent(client.listIdentityProviders(), createdIdp) + } + + @Test + void oidcIdpUserTest() { + + // create user + def email = "joe.coder+${uniqueTestName}@example.com" + User createdUser = UserBuilder.instance() + .setEmail(email) + .setFirstName("Joe") + .setLastName("Code") + .setPassword("Password1".toCharArray()) + .buildAndCreate(client) + registerForCleanup(createdUser) + + // create idp + IdentityProvider createdIdp = IdentityProviderBuilders.oidc() + .setName("Mock OpenID Connect Id") + .setIssuerMode(IdentityProvider.IssuerModeEnum.ORG_URL) + .setRequestSignatureAlgorithm("SHA-256") + .setRequestSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum.REQUEST) + .setResponseSignatureAlgorithm("SHA-256") + .setResponseSignatureScope(ProtocolAlgorithmTypeSignature.ScopeEnum.ANY) + .setAcsEndpointBinding(ProtocolEndpoint.BindingEnum.POST) + .setAcsEndpointType(ProtocolEndpoint.TypeEnum.INSTANCE) + .setAuthorizationEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setAuthorizationEndpointUrl("https://idp.example.com/authorize") + .setTokenEndpointBinding(ProtocolEndpoint.BindingEnum.POST) + .setTokenEndpointUrl("https://idp.example.com/token") + .setUserInfoEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setUserInfoEndpointUrl("https://idp.example.com/userinfo") + .setJwksEndpointBinding(ProtocolEndpoint.BindingEnum.REDIRECT) + .setJwksEndpointUrl("https://idp.example.com/keys") + .setScopes(["openid", "profile", "email"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .setIssuerUrl("https://idp.example.com") + .setMaxClockSkew(120000) + .setUserName("idpuser.email") + .setMatchType(PolicySubjectMatchType.USERNAME) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // link user + IdentityProviderApplicationUser idpAppUser = createdIdp.linkUser(createdUser.getId(), + client.instantiate(UserIdentityProviderLinkRequest) + .setExternalId("externalId")) + + assertThat(createdIdp.listUsers(), iterableWithSize(1)) + assertPresent(createdIdp.listUsers(), idpAppUser) + + // unlink user + createdIdp.unlinkUser(createdUser.getId()) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // list social auth tokens + SocialAuthTokenList socialAuthTokenList = createdIdp.listSocialAuthTokens(createdUser.getId()) + assertThat(socialAuthTokenList, iterableWithSize(0)) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + } + + @Test + void googleIdpTest() { + + // create user + def email = "joe.coder+${uniqueTestName}@example.com" + User createdUser = UserBuilder.instance() + .setEmail(email) + .setFirstName("Joe") + .setLastName("Code") + .setPassword("Password1".toCharArray()) + .buildAndCreate(client) + registerForCleanup(createdUser) + + // create Google idp + IdentityProvider createdIdp = IdentityProviderBuilders.google() + .setName("Mock Google IdP") + .setScopes(["openid", "profile", "email"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .isProfileMaster(true) + .setMaxClockSkew(120000) + .setUserName("idpuser.email") + .setMatchType(PolicySubjectMatchType.USERNAME) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // link user + IdentityProviderApplicationUser idpAppUser = createdIdp.linkUser(createdUser.getId(), + client.instantiate(UserIdentityProviderLinkRequest) + .setExternalId("externalId")) + + assertThat(createdIdp.listUsers(), iterableWithSize(1)) + assertPresent(createdIdp.listUsers(), idpAppUser) + + // unlink user + createdIdp.unlinkUser(createdUser.getId()) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + + assertNotPresent(client.listIdentityProviders(), createdIdp) + } + + @Test + void facebookIdpTest() { + + // create user + def email = "joe.coder+${uniqueTestName}@example.com" + User createdUser = UserBuilder.instance() + .setEmail(email) + .setFirstName("Joe") + .setLastName("Code") + .setPassword("Password1".toCharArray()) + .buildAndCreate(client) + registerForCleanup(createdUser) + + // create Facebook idp + IdentityProvider createdIdp = IdentityProviderBuilders.facebook() + .setName("Mock Facebook IdP") + .setScopes(["public_profile", "email"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .isProfileMaster(true) + .setMaxClockSkew(120000) + .setUserName("idpuser.email") + .setMatchType(PolicySubjectMatchType.USERNAME) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // link user + IdentityProviderApplicationUser idpAppUser = createdIdp.linkUser(createdUser.getId(), + client.instantiate(UserIdentityProviderLinkRequest) + .setExternalId("externalId")) + + assertThat(createdIdp.listUsers(), iterableWithSize(1)) + assertPresent(createdIdp.listUsers(), idpAppUser) + + // unlink user + createdIdp.unlinkUser(createdUser.getId()) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + + assertNotPresent(client.listIdentityProviders(), createdIdp) + } + + @Test + void microsoftIdpTest() { + + // create user + def email = "joe.coder+${uniqueTestName}@example.com" + User createdUser = UserBuilder.instance() + .setEmail(email) + .setFirstName("Joe") + .setLastName("Code") + .setPassword("Password1".toCharArray()) + .buildAndCreate(client) + registerForCleanup(createdUser) + + // create Microsoft idp + IdentityProvider createdIdp = IdentityProviderBuilders.microsoft() + .setName("Mock Microsoft IdP") + .setScopes(["openid", "email", "profile", "https://graph.microsoft.com/User.Read"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .isProfileMaster(true) + .setMaxClockSkew(120000) + .setUserName("idpuser.userPrincipalName") + .setMatchType(PolicySubjectMatchType.USERNAME) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // link user + IdentityProviderApplicationUser idpAppUser = createdIdp.linkUser(createdUser.getId(), + client.instantiate(UserIdentityProviderLinkRequest) + .setExternalId("externalId")) + + assertThat(createdIdp.listUsers(), iterableWithSize(1)) + assertPresent(createdIdp.listUsers(), idpAppUser) + + // unlink user + createdIdp.unlinkUser(createdUser.getId()) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + + assertNotPresent(client.listIdentityProviders(), createdIdp) + } + + @Test + void linkedInIdpTest() { + + // create user + def email = "joe.coder+${uniqueTestName}@example.com" + User createdUser = UserBuilder.instance() + .setEmail(email) + .setFirstName("Joe") + .setLastName("Code") + .setPassword("Password1".toCharArray()) + .buildAndCreate(client) + registerForCleanup(createdUser) + + // create Linkedin idp + IdentityProvider createdIdp = IdentityProviderBuilders.linkedin() + .setName("Mock LinkedIn IdP") + .setScopes(["r_basicprofile", "r_emailaddress"]) + .setClientId("your-client-id") + .setClientSecret("your-client-secret") + .isProfileMaster(true) + .setMaxClockSkew(120000) + .setUserName("idpuser.email") + .setMatchType(PolicySubjectMatchType.EMAIL) + .buildAndCreate(client) + registerForCleanup(createdIdp) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // link user + IdentityProviderApplicationUser idpAppUser = createdIdp.linkUser(createdUser.getId(), + client.instantiate(UserIdentityProviderLinkRequest) + .setExternalId("externalId")) + + assertThat(createdIdp.listUsers(), iterableWithSize(1)) + assertPresent(createdIdp.listUsers(), idpAppUser) + + // unlink user + createdIdp.unlinkUser(createdUser.getId()) + + // list linked idp users + assertThat(createdIdp.listUsers(), iterableWithSize(0)) + + // deactivate + createdIdp.deactivate() + + // delete + createdIdp.delete() + + assertNotPresent(client.listIdentityProviders(), createdIdp) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/InlineHooksIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/InlineHooksIT.groovy new file mode 100644 index 00000000000..0d27d81b87a --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/InlineHooksIT.groovy @@ -0,0 +1,195 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.inline.hook.InlineHook +import com.okta.sdk.resource.inline.hook.InlineHookBuilder +import com.okta.sdk.resource.inline.hook.InlineHookChannelConfigAuthScheme +import com.okta.sdk.resource.inline.hook.InlineHookChannelConfigHeaders +import com.okta.sdk.resource.inline.hook.InlineHookChannel +import com.okta.sdk.resource.inline.hook.InlineHookStatus +import com.okta.sdk.resource.inline.hook.InlineHookType +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.notNullValue + +import static com.okta.sdk.tests.it.util.Util.assertPresent +import static com.okta.sdk.tests.it.util.Util.assertNotPresent + +/** + * Tests for {@code /api/v1/inlineHooks}. + * @since 2.0.0 + */ +class InlineHooksIT extends ITSupport { + + @Test + void createInlineHookTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + assertThat(createdInlineHook.getName(), equalTo(name)) + assertThat(createdInlineHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/inlineHooks")) + + createdInlineHook.deactivate() + } + + @Test + void getInlineHookTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + + InlineHook retrievedInlineHook = client.getInlineHook(createdInlineHook.getId()) + + assertThat(retrievedInlineHook.getId(), notNullValue()) + assertThat(retrievedInlineHook.getName(), equalTo(name)) + assertThat(retrievedInlineHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/inlineHooks")) + + createdInlineHook.deactivate() + } + + @Test + void updateInlineHookTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + + InlineHook toBeUpdatedInlineHook = createdInlineHook.setName("updated-" + name) + toBeUpdatedInlineHook.getChannel().getConfig().setHeaders([ + client.instantiate(InlineHookChannelConfigHeaders) + .setKey("X-Test-Header") + .setValue("Test header value updated")]) + toBeUpdatedInlineHook.getChannel().getConfig().setAuthScheme(client.instantiate(InlineHookChannelConfigAuthScheme) + .setType("HEADER") + .setKey("Authorization") + .setValue("Test-Api-Key-Updated")) + .setUri("https://www.example.com/inlineHooksUpdated") + + InlineHook updatedInlineHook = toBeUpdatedInlineHook.update() + + assertThat(updatedInlineHook.getId(), notNullValue()) + assertThat(updatedInlineHook.getId(), equalTo(createdInlineHook.getId())) + assertThat(updatedInlineHook.getName(), equalTo("updated-" + name)) + assertThat(updatedInlineHook.getType(), equalTo(InlineHookType.OAUTH2_TOKENS_TRANSFORM)) + assertThat(updatedInlineHook.getChannel().getConfig().getUri(), equalTo("https://www.example.com/inlineHooksUpdated")) + + updatedInlineHook.deactivate() + } + + @Test + void deleteInlineHookTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + + InlineHook retrievedInlineHook = client.getInlineHook(createdInlineHook.getId()) + assertThat(retrievedInlineHook.getId(), equalTo(createdInlineHook.getId())) + + createdInlineHook.deactivate() + createdInlineHook.delete() + + assertNotPresent(client.listInlineHooks(), createdInlineHook) + } + + @Test + void listAllInlineHooksTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + assertPresent(client.listInlineHooks(), createdInlineHook) + + createdInlineHook.deactivate() + } + + @Test + void activateDeactivateInlineHookTest() { + String name = "inline-hook-java-sdk-${UUID.randomUUID().toString()}" + + InlineHook createdInlineHook = InlineHookBuilder.instance() + .setName(name) + .setHookType(InlineHookType.OAUTH2_TOKENS_TRANSFORM) + .setChannelType(InlineHookChannel.TypeEnum.HTTP) + .setUrl("https://www.example.com/inlineHooks") + .setAuthorizationHeaderValue("Test-Api-Key") + .addHeader("X-Test-Header", "Test header value") + .buildAndCreate(client) + registerForCleanup(createdInlineHook) + + assertThat(createdInlineHook.getId(), notNullValue()) + assertThat(createdInlineHook.getStatus(), equalTo(InlineHookStatus.ACTIVE)) + + createdInlineHook.deactivate() + + InlineHook retrievedInlineHook = client.getInlineHook(createdInlineHook.getId()) + + assertThat(retrievedInlineHook.getStatus(), equalTo(InlineHookStatus.INACTIVE)) + + retrievedInlineHook.delete() + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/LinkedObjectsIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/LinkedObjectsIT.groovy new file mode 100644 index 00000000000..98d5288bf7e --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/LinkedObjectsIT.groovy @@ -0,0 +1,201 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.linked.object.LinkedObject +import com.okta.sdk.resource.linked.object.LinkedObjectDetailsType +import com.okta.sdk.resource.linked.object.LinkedObjectDetails +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test +import wiremock.org.apache.commons.lang3.RandomStringUtils + +import static com.okta.sdk.tests.it.util.Util.assertLinkedObjectPresent +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.notNullValue + +/** + * Tests for {@code /api/v1/meta/schemas/user/linkedObjects}. + * @since 2.0.0 + */ +class LinkedObjectsIT extends ITSupport { + + @Test + void addLinkedObjectDefinitionTest() { + String primaryName = "manager" + RandomStringUtils.randomAlphanumeric(25) + String associatedName = "subordinate" + RandomStringUtils.randomAlphanumeric(25) + + LinkedObjectDetails primary = client.instantiate(LinkedObjectDetails) + .setName(primaryName) + .setTitle("Manager") + .setDescription("Manager link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObjectDetails associated = client.instantiate(LinkedObjectDetails) + .setName(associatedName) + .setTitle("Subordinate") + .setDescription("Subordinate link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObject linkedObject = client.instantiate(LinkedObject) + .setPrimary(primary) + .setAssociated(associated) + registerForCleanup(linkedObject) + + LinkedObject createdLinkedObjectDefinition = client.addLinkedObjectDefinition(linkedObject) + + assertThat(createdLinkedObjectDefinition.getPrimary(), notNullValue()) + assertThat(createdLinkedObjectDefinition.getPrimary().getName(), equalTo(primaryName)) + assertThat(createdLinkedObjectDefinition.getPrimary().getTitle(), equalTo("Manager")) + assertThat(createdLinkedObjectDefinition.getPrimary().getDescription(), equalTo("Manager link property")) + assertThat(createdLinkedObjectDefinition.getPrimary().getType(), equalTo(LinkedObjectDetailsType.USER)) + assertThat(createdLinkedObjectDefinition.getAssociated(), notNullValue()) + assertThat(createdLinkedObjectDefinition.getAssociated().getName(), equalTo(associatedName)) + assertThat(createdLinkedObjectDefinition.getAssociated().getTitle(), equalTo("Subordinate")) + assertThat(createdLinkedObjectDefinition.getAssociated().getDescription(), equalTo("Subordinate link property")) + assertThat(createdLinkedObjectDefinition.getAssociated().getType(), equalTo(LinkedObjectDetailsType.USER)) + } + + @Test + void getLinkedObjectDefinitionByPrimaryNameTest() { + String primaryName = "manager" + RandomStringUtils.randomAlphanumeric(25) + String associatedName = "subordinate" + RandomStringUtils.randomAlphanumeric(25) + + LinkedObjectDetails primary = client.instantiate(LinkedObjectDetails) + .setName(primaryName) + .setTitle("Primary") + .setDescription("Primary link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObjectDetails associated = client.instantiate(LinkedObjectDetails) + .setName(associatedName) + .setTitle("Associated") + .setDescription("Associated link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObject linkedObject = client.instantiate(LinkedObject) + .setPrimary(primary) + .setAssociated(associated) + registerForCleanup(linkedObject) + + client.addLinkedObjectDefinition(linkedObject) + + LinkedObject retrievedLinkedObject = client.getLinkedObjectDefinition(primaryName) + + assertThat(retrievedLinkedObject.getPrimary(), notNullValue()) + assertThat(retrievedLinkedObject.getPrimary().getName(), equalTo(primaryName)) + assertThat(retrievedLinkedObject.getPrimary().getTitle(), equalTo("Primary")) + assertThat(retrievedLinkedObject.getPrimary().getDescription(), equalTo("Primary link property")) + assertThat(retrievedLinkedObject.getPrimary().getType(), equalTo(LinkedObjectDetailsType.USER)) + assertThat(retrievedLinkedObject.getAssociated(), notNullValue()) + assertThat(retrievedLinkedObject.getAssociated().getName(), equalTo(associatedName)) + assertThat(retrievedLinkedObject.getAssociated().getTitle(), equalTo("Associated")) + assertThat(retrievedLinkedObject.getAssociated().getDescription(), equalTo("Associated link property")) + assertThat(retrievedLinkedObject.getAssociated().getType(), equalTo(LinkedObjectDetailsType.USER)) + } + + @Test + void getLinkedObjectDefinitionByAssociatedNameTest() { + String primaryName = "manager" + RandomStringUtils.randomAlphanumeric(25) + String associatedName = "subordinate" + RandomStringUtils.randomAlphanumeric(25) + + LinkedObjectDetails primary = client.instantiate(LinkedObjectDetails) + .setName(primaryName) + .setTitle("Primary") + .setDescription("Primary link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObjectDetails associated = client.instantiate(LinkedObjectDetails) + .setName(associatedName) + .setTitle("Associated") + .setDescription("Associated link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObject linkedObject = client.instantiate(LinkedObject) + .setPrimary(primary) + .setAssociated(associated) + registerForCleanup(linkedObject) + + client.addLinkedObjectDefinition(linkedObject) + + LinkedObject retrievedLinkedObject = client.getLinkedObjectDefinition(associatedName) + + assertThat(retrievedLinkedObject.getPrimary(), notNullValue()) + assertThat(retrievedLinkedObject.getPrimary().getName(), equalTo(primaryName)) + assertThat(retrievedLinkedObject.getPrimary().getTitle(), equalTo("Primary")) + assertThat(retrievedLinkedObject.getPrimary().getDescription(), equalTo("Primary link property")) + assertThat(retrievedLinkedObject.getPrimary().getType(), equalTo(LinkedObjectDetailsType.USER)) + assertThat(retrievedLinkedObject.getAssociated(), notNullValue()) + assertThat(retrievedLinkedObject.getAssociated().getName(), equalTo(associatedName)) + assertThat(retrievedLinkedObject.getAssociated().getTitle(), equalTo("Associated")) + assertThat(retrievedLinkedObject.getAssociated().getDescription(), equalTo("Associated link property")) + assertThat(retrievedLinkedObject.getAssociated().getType(), equalTo(LinkedObjectDetailsType.USER)) + } + + @Test + void getAllLinkedObjectDefinitionsTest() { + // create first linked object definition + + String primaryName1 = "manager" + RandomStringUtils.randomAlphanumeric(25) + String associatedName1 = "subordinate" + RandomStringUtils.randomAlphanumeric(25) + + LinkedObjectDetails primary1 = client.instantiate(LinkedObjectDetails) + .setName(primaryName1) + .setTitle("Primary") + .setDescription("Primary link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObjectDetails associated1 = client.instantiate(LinkedObjectDetails) + .setName(associatedName1) + .setTitle("Associated") + .setDescription("Associated link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObject linkedObject1 = client.instantiate(LinkedObject) + .setPrimary(primary1) + .setAssociated(associated1) + registerForCleanup(linkedObject1) + + LinkedObject createdLinkedObjectDefinition1 = client.addLinkedObjectDefinition(linkedObject1) + + // create second linked object definition + + String primaryName2 = "manager" + RandomStringUtils.randomAlphanumeric(25) + String associatedName2 = "subordinate" + RandomStringUtils.randomAlphanumeric(25) + + LinkedObjectDetails primary2 = client.instantiate(LinkedObjectDetails) + .setName(primaryName2) + .setTitle("Primary") + .setDescription("Primary link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObjectDetails associated2 = client.instantiate(LinkedObjectDetails) + .setName(associatedName2) + .setTitle("Associated") + .setDescription("Associated link property") + .setType(LinkedObjectDetailsType.USER) + + LinkedObject linkedObject2 = client.instantiate(LinkedObject) + .setPrimary(primary2) + .setAssociated(associated2) + registerForCleanup(linkedObject2) + + LinkedObject createdLinkedObjectDefinition2 = client.addLinkedObjectDefinition(linkedObject2) + + assertLinkedObjectPresent(client.listLinkedObjectDefinitions(), createdLinkedObjectDefinition1) + assertLinkedObjectPresent(client.listLinkedObjectDefinitions(), createdLinkedObjectDefinition2) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/PolicyRulesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/PolicyRulesIT.groovy index 6a13c334496..11ca9004139 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/PolicyRulesIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/PolicyRulesIT.groovy @@ -69,7 +69,7 @@ class PolicyRulesIT extends ITSupport implements CrudTestSupport { } @Test - void activateDeactivateTest() { + void deactivateTest() { def group = randomGroup() def policy = randomSignOnPolicy(group.getId()) @@ -81,13 +81,9 @@ class PolicyRulesIT extends ITSupport implements CrudTestSupport { .setRequireFactor(false) .setStatus(PolicyRule.StatusEnum.INACTIVE) .buildAndCreate(client, policy); - registerForCleanup(policyRule) - assertThat(policyRule.getStatus(), is(PolicyRule.StatusEnum.INACTIVE)) - // activate - policyRule.activate() - policyRule = policy.getPolicyRule(policyRule.getId()) + // policy rule is ACTIVE by default assertThat(policyRule.getStatus(), is(PolicyRule.StatusEnum.ACTIVE)) // deactivate diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/SmsTemplateIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/SmsTemplateIT.groovy new file mode 100644 index 00000000000..547f5adceea --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/SmsTemplateIT.groovy @@ -0,0 +1,98 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.template.SmsTemplateTranslations +import com.okta.sdk.resource.template.SmsTemplate +import com.okta.sdk.resource.template.SmsTemplateType +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static com.okta.sdk.tests.it.util.Util.assertPresent +import static com.okta.sdk.tests.it.util.Util.assertNotPresent +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.* + +/** + * Tests for {@code /api/v1/templates/sms}. + * @since 2.0.0 + */ +class SmsTemplateIT extends ITSupport { + + @Test + void customTemplatesCrudTest() { + def templateName = "template-" + UUID.randomUUID().toString() + + // create translations + SmsTemplateTranslations smsTemplateTranslations = client.instantiate(SmsTemplateTranslations) + smsTemplateTranslations.put("de", "\${org.name}: ihre bestätigungscode ist \${code}") + smsTemplateTranslations.put("it", "\${org.name}: il codice di verifica è \${code}") + + // create template + SmsTemplate smsTemplate = client.createSmsTemplate(client.instantiate(SmsTemplate) + .setName(templateName) + .setType(SmsTemplateType.CODE) + .setTemplate("\${org.name}: your verification code is \${code}") + .setTranslations(smsTemplateTranslations)) + registerForCleanup(smsTemplate) + + assertThat(smsTemplate.getId(), notNullValue()) + + // list templates + assertPresent(client.listSmsTemplates(), smsTemplate) + + // retrieve template + SmsTemplate retrievedSmsTemplate = client.getSmsTemplate(smsTemplate.getId()) + assertThat(retrievedSmsTemplate, notNullValue()) + assertThat(retrievedSmsTemplate.getTranslations().keySet(), hasSize(2)) + + // partial update template with 1 empty translation + SmsTemplateTranslations partialUpdateTranslations = client.instantiate(SmsTemplateTranslations) + partialUpdateTranslations.put("de", "") // supplying empty value here so it gets removed by partial update operation (by design) + + smsTemplate.setTranslations(partialUpdateTranslations) + + smsTemplate.partialUpdate() + assertThat(smsTemplate.getTranslations().keySet(), hasSize(1)) + + // partial update again with 2 new translations + smsTemplate.getTranslations().put("es", "\${org.name}: su código de inscripción es \${code}") + smsTemplate.getTranslations().put("fr", "\${org.name}: votre code d'inscription est \${code}",) + + smsTemplate.partialUpdate() + assertThat(smsTemplate.getTranslations().keySet(), hasSize(3)) + + // full update template + SmsTemplateTranslations fullUpdateTranslations = client.instantiate(SmsTemplateTranslations) + fullUpdateTranslations.put("de", "\${org.name}: Hier ist Ihr Registrierungscode: \${code}") + + smsTemplate.setName("new-" + templateName) + smsTemplate.setType(SmsTemplateType.CODE) + smsTemplate.setTemplate("\${org.name}: Here is your enrollment code: \${code}") + smsTemplate.setTranslations(fullUpdateTranslations) + + smsTemplate.update() + assertThat(smsTemplate.getName(), is("new-" + templateName)) + assertThat(smsTemplate.getTranslations().keySet(), hasSize(1)) + + // list templates + assertPresent(client.listSmsTemplates(), smsTemplate) + + // delete template + smsTemplate.delete() + assertNotPresent(client.listSmsTemplates(), smsTemplate) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserRolesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserRolesIT.groovy new file mode 100644 index 00000000000..47b0fb09541 --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserRolesIT.groovy @@ -0,0 +1,126 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.group.GroupBuilder +import com.okta.sdk.resource.group.Group +import com.okta.sdk.resource.role.AssignRoleRequest +import com.okta.sdk.resource.role.RoleType +import com.okta.sdk.resource.user.Role +import com.okta.sdk.resource.user.User +import com.okta.sdk.resource.user.UserBuilder +import com.okta.sdk.tests.Scenario +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test + +import static com.okta.sdk.tests.it.util.Util.assertGroupPresent +import static com.okta.sdk.tests.it.util.Util.assertGroupAbsent +import static com.okta.sdk.tests.it.util.Util.validateGroup +import static com.okta.sdk.tests.it.util.Util.validateUser +import static org.hamcrest.MatcherAssert.assertThat + +/** + * Tests for {@code /api/v1/users/roles}. + * @since 2.0.0 + */ +class UserRolesIT extends ITSupport { + + @Test + @Scenario("assign-super-admin-role-to-user") + void assignSuperAdminRoleToUserTest() { + + def password = 'Passw0rd!2@3#' + def firstName = 'John' + def lastName = 'Role' + def email = "john-${uniqueTestName}@example.com" + + // 1. Create a user + User user = UserBuilder.instance() + .setEmail(email) + .setFirstName(firstName) + .setLastName(lastName) + .setPassword(password.toCharArray()) + .setActive(true) + .buildAndCreate(client) + registerForCleanup(user) + validateUser(user, firstName, lastName, email) + + // 2. Assign SUPER_ADMIN role + AssignRoleRequest assignRoleRequest = client.instantiate(AssignRoleRequest) + assignRoleRequest.setType(RoleType.SUPER_ADMIN) + + Role assignedRole = user.assignRole(assignRoleRequest) + assertThat("Incorrect RoleType", assignedRole.getType() == RoleType.SUPER_ADMIN) + } + + @Test + @Scenario("group-targets-for-role") + void groupTargetsForRoleTest() { + + def password = 'Passw0rd!2@3#' + def firstName = 'John' + def lastName = 'Role' + def email = "john-${uniqueTestName}@example.com" + + // 1. Create a user + User user = UserBuilder.instance() + .setEmail(email) + .setFirstName(firstName) + .setLastName(lastName) + .setPassword(password.toCharArray()) + .setActive(true) + .buildAndCreate(client) + registerForCleanup(user) + validateUser(user, firstName, lastName, email) + + // 2. Create two groups + String groupName1 = "Group-Member API Test Group ${uniqueTestName}-1" + String groupName2 = "Group-Member API Test Group ${uniqueTestName}-2" + + Group group1 = GroupBuilder.instance() + .setName(groupName1) + .buildAndCreate(client) + Group group2 = GroupBuilder.instance() + .setName(groupName2) + .buildAndCreate(client) + registerForCleanup(group1) + registerForCleanup(group2) + + validateGroup(group1, groupName1) + validateGroup(group2, groupName2) + + // 3. Assign a role + AssignRoleRequest assignRoleRequest = client.instantiate(AssignRoleRequest) + assignRoleRequest.setType(RoleType.USER_ADMIN) + + Role superAdminRole = user.assignRole(assignRoleRequest) + + // 4. Add the created groups as role targets + // Need 2 groups, because if you remove the last one it throws an (expected) exception. + user.addGroupTarget(superAdminRole.getId(), group1.getId()) + user.addGroupTarget(superAdminRole.getId(), group2.getId()) + + assertGroupPresent(user.listGroupTargets(superAdminRole.getId()), group1) + assertGroupPresent(user.listGroupTargets(superAdminRole.getId()), group2) + + // 5. Remove the target + user.removeGroupTarget(superAdminRole.getId(), group1.getId()) + + assertGroupAbsent(user.listGroupTargets(superAdminRole.getId()), group1) + } +} + + diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserTypesIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserTypesIT.groovy new file mode 100644 index 00000000000..2661c260b1d --- /dev/null +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UserTypesIT.groovy @@ -0,0 +1,127 @@ +/* + * Copyright 2020-Present Okta, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * 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 com.okta.sdk.tests.it + +import com.okta.sdk.resource.user.UserType +import com.okta.sdk.tests.it.util.ITSupport +import org.testng.annotations.Test +import wiremock.org.apache.commons.lang3.RandomStringUtils + +import static com.okta.sdk.tests.it.util.Util.assertNotPresent +import static com.okta.sdk.tests.it.util.Util.assertPresent +import static org.hamcrest.MatcherAssert.assertThat +import static org.hamcrest.Matchers.equalTo +import static org.hamcrest.Matchers.notNullValue + +/** + * Tests for {@code /api/v1/meta/types/user}. + * @since 2.0.0 + */ +class UserTypesIT extends ITSupport { + + @Test + void createUserTypeTest() { + String name = "java_sdk_user_type_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType = client.createUserType(client.instantiate(UserType) + .setName(name) + .setDisplayName(name) + .setDescription(name + "_test_description")) + registerForCleanup(createdUserType) + + assertThat(createdUserType.getId(), notNullValue()) + assertThat(createdUserType.getName(), equalTo(name)) + } + + @Test + void getUserTypeTest() { + String name = "java_sdk_user_type_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType = client.createUserType(client.instantiate(UserType) + .setName(name) + .setDisplayName(name) + .setDescription(name + "_test_description")) + registerForCleanup(createdUserType) + + assertThat(createdUserType.getId(), notNullValue()) + + UserType retrievedUserType = client.getUserType(createdUserType.getId()) + assertThat(retrievedUserType.getId(), equalTo(createdUserType.getId())) + assertThat(retrievedUserType.getName(), equalTo(createdUserType.getName())) + } + + @Test + void updateUserTypeTest() { + String name = "java_sdk_user_type_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType = client.createUserType(client.instantiate(UserType) + .setName(name) + .setDisplayName(name) + .setDescription(name + "_test_description")) + registerForCleanup(createdUserType) + + assertThat(createdUserType.getId(), notNullValue()) + + createdUserType.setDisplayName(name + "_updated").setDescription(name + "_test_description_updated") + .update() + + assertThat(createdUserType.getId(), notNullValue()) + assertThat(createdUserType.getDisplayName(), equalTo(name + "_updated")) + assertThat(createdUserType.getDescription(), equalTo(name + "_test_description_updated")) + } + + @Test + void deleteUserTypeTest() { + String name = "java_sdk_user_type_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType = client.createUserType(client.instantiate(UserType) + .setName(name) + .setDisplayName(name) + .setDescription(name + "_test_description")) + registerForCleanup(createdUserType) + + assertThat(createdUserType.getId(), notNullValue()) + + createdUserType.delete() + + assertNotPresent(client.listUserTypes(), createdUserType) + } + + @Test + void listAllUserTypesTest() { + String name1 = "java_sdk_user_type_1_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType1 = client.createUserType(client.instantiate(UserType) + .setName(name1) + .setDisplayName(name1) + .setDescription(name1 + "_test_description")) + registerForCleanup(createdUserType1) + + assertThat(createdUserType1.getId(), notNullValue()) + + String name2 = "java_sdk_user_type_2_" + RandomStringUtils.randomAlphanumeric(15) + + UserType createdUserType2 = client.createUserType(client.instantiate(UserType) + .setName(name2) + .setDisplayName(name2) + .setDescription(name2 + "_test_description")) + registerForCleanup(createdUserType2) + + assertThat(client.listUserTypes(), notNullValue()) + assertPresent(client.listUserTypes(), createdUserType1) + assertPresent(client.listUserTypes(), createdUserType2) + } +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UsersIT.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UsersIT.groovy index af8125f998e..87007aeab9f 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UsersIT.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/UsersIT.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2017 Okta + * Copyright 2017-Present Okta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,18 +29,19 @@ import com.okta.sdk.resource.policy.PasswordPolicyRuleActions import com.okta.sdk.resource.policy.PasswordPolicyRuleConditions import com.okta.sdk.resource.policy.PasswordPolicySettings import com.okta.sdk.resource.policy.PolicyNetworkCondition +import com.okta.sdk.resource.role.AssignRoleRequest +import com.okta.sdk.resource.role.RoleType import com.okta.sdk.resource.user.AuthenticationProviderType import com.okta.sdk.resource.user.ChangePasswordRequest -import com.okta.sdk.resource.user.ForgotPasswordResponse import com.okta.sdk.resource.user.PasswordCredential import com.okta.sdk.resource.user.RecoveryQuestionCredential import com.okta.sdk.resource.user.ResetPasswordToken import com.okta.sdk.resource.user.Role -import com.okta.sdk.resource.user.TempPassword import com.okta.sdk.resource.user.User import com.okta.sdk.resource.user.UserBuilder import com.okta.sdk.resource.user.UserCredentials import com.okta.sdk.resource.user.UserList +import com.okta.sdk.resource.user.UserStatus import com.okta.sdk.tests.Scenario import com.okta.sdk.tests.it.util.ITSupport import org.testng.Assert @@ -62,7 +63,7 @@ import static org.hamcrest.MatcherAssert.assertThat import static org.hamcrest.Matchers.* /** - * Tests for /api/v1/users + * Tests for {@code /api/v1/users}. * @since 0.5.0 */ class UsersIT extends ITSupport implements CrudTestSupport { @@ -204,7 +205,7 @@ class UsersIT extends ITSupport implements CrudTestSupport { } - @Test(enabled = false) + @Test @Scenario("user-role-assign") void roleAssignTest() { @@ -225,17 +226,19 @@ class UsersIT extends ITSupport implements CrudTestSupport { validateUser(user, firstName, lastName, email) // 2. Assign USER_ADMIN role to the user - Role role = user.addRole(client.instantiate(Role) - .setType('USER_ADMIN')) + AssignRoleRequest assignRoleRequest = client.instantiate(AssignRoleRequest) + assignRoleRequest.setType(RoleType.USER_ADMIN) + + Role role = user.assignRole(assignRoleRequest) // 3. List roles for the user and verify added role - assertPresent(user.listRoles(), role) + assertPresent(user.listAssignedRoles(), role) // 4. Remove role for the user user.removeRole(role.getId()) // 5. List roles for user and verify role was removed - assertNotPresent(user.listRoles(), role) + assertNotPresent(user.listAssignedRoles(), role) } @Test @@ -328,7 +331,7 @@ class UsersIT extends ITSupport implements CrudTestSupport { client.getUser(user.getId()) } - @Test + @Test(expectedExceptions = ResourceException) @Scenario("user-change-recovery-question") void changeRecoveryQuestionTest() { @@ -339,12 +342,12 @@ class UsersIT extends ITSupport implements CrudTestSupport { // 1. Create a user with password & recovery question User user = UserBuilder.instance() - .setEmail(email) - .setFirstName(firstName) - .setLastName(lastName) - .setPassword(password.toCharArray()) - .setActive(true) - .buildAndCreate(client) + .setEmail(email) + .setFirstName(firstName) + .setLastName(lastName) + .setPassword(password.toCharArray()) + .setActive(true) + .buildAndCreate(client) registerForCleanup(user) validateUser(user, firstName, lastName, email) @@ -362,8 +365,9 @@ class UsersIT extends ITSupport implements CrudTestSupport { // 3. Update the user password through updated recovery question userCredentials.getPassword().value = '!2@3#Passw0rd'.toCharArray() userCredentials.getRecoveryQuestion().answer = 'forty two' - ForgotPasswordResponse response = user.forgotPassword(null, userCredentials) - assertThat response.getResetPasswordUrl(), nullValue() + + // below would throw HTTP 403 exception + user.changeRecoveryQuestion(userCredentials) // 4. make the test recording happy, and call a get on the user // TODO: fix har file @@ -389,8 +393,8 @@ class UsersIT extends ITSupport implements CrudTestSupport { registerForCleanup(user) validateUser(user, firstName, lastName, email) - ForgotPasswordResponse response = user.forgotPassword(false, null) - assertThat response.getResetPasswordUrl(), containsString("/reset-password/") + ResetPasswordToken response = user.resetPassword(false) + assertThat response.getResetPasswordUrl(), containsString("/reset_password/") } @Test @@ -413,9 +417,10 @@ class UsersIT extends ITSupport implements CrudTestSupport { registerForCleanup(user) validateUser(user, firstName, lastName, email) - // 2. Expire the user's password with tempPassword=true - TempPassword tempPassword = user.expirePassword(true) - assertThat tempPassword.getTempPassword(), notNullValue() + // 2. Expire the user's password + User updatedUser = user.expirePassword() + assertThat updatedUser, notNullValue() + assertThat updatedUser.getStatus(), is(UserStatus.PASSWORD_EXPIRED) } @@ -440,7 +445,7 @@ class UsersIT extends ITSupport implements CrudTestSupport { validateUser(user, firstName, lastName, email) // 2. Get the reset password link - ResetPasswordToken token = user.resetPassword(null, false) + ResetPasswordToken token = user.resetPassword(false) assertThat token.getResetPasswordUrl(), notNullValue() } @@ -482,7 +487,7 @@ class UsersIT extends ITSupport implements CrudTestSupport { } } - @Test(enabled = false) + @Test @Scenario("user-group-target-role") void groupTargetRoleTest() { @@ -510,11 +515,13 @@ class UsersIT extends ITSupport implements CrudTestSupport { validateGroup(group, groupName) // 2. Assign USER_ADMIN role to the user - Role role = user.addRole(client.instantiate(Role) - .setType('USER_ADMIN')) + AssignRoleRequest assignRoleRequest = client.instantiate(AssignRoleRequest) + assignRoleRequest.setType(RoleType.USER_ADMIN) + + Role role = user.assignRole(assignRoleRequest) // 3. Add Group Target to User Admin Role - user.addGroupTargetToRole(role.id, group.id) + user.addGroupTarget(role.id, group.id) // 4. List Group Targets for Role assertGroupTargetPresent(user, group, role) @@ -532,8 +539,8 @@ class UsersIT extends ITSupport implements CrudTestSupport { registerForCleanup(adminGroup) validateGroup(adminGroup, adminGroupName) - user.addGroupTargetToRole(role.getId(), adminGroup.getId()) - user.removeGroupTargetFromRole(role.getId(), adminGroup.getId()) + user.addGroupTarget(role.getId(), adminGroup.getId()) + user.removeGroupTarget(role.getId(), adminGroup.getId()) assertGroupTargetPresent(user, group, role) } diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/ClientProvider.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/ClientProvider.groovy index 07c15d8ba54..4a58ec6dbc0 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/ClientProvider.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/ClientProvider.groovy @@ -151,7 +151,7 @@ trait ClientProvider implements IHookable { void deleteGroup(String groupName, Client client) { Util.ignoring(ResourceException) { - GroupList groups = client.listGroups(groupName, null, null) + GroupList groups = client.listGroups(groupName, null) groups.each {group -> if (groupName.equals(group.profile.name)) { group.delete() @@ -162,7 +162,7 @@ trait ClientProvider implements IHookable { void deleteRule(String ruleName, Client client) { Util.ignoring(ResourceException) { - GroupRuleList rules = client.listRules() + GroupRuleList rules = client.listGroupRules() rules.each {rule -> if (ruleName.equals(rule.name)) { if (rule.status == GroupRuleStatus.ACTIVE) { diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/OktaOrgCleaner.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/OktaOrgCleaner.groovy index 2088de77502..40131108ae0 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/OktaOrgCleaner.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/OktaOrgCleaner.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2017 Okta + * Copyright 2017-Present Okta, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ class OktaOrgCleaner { } log.info("Deleting Group Rules:") - client.listRules().stream() + client.listGroupRules().stream() .filter { it.getName().matches("rule\\+${uuidRegex}.*")} .forEach { GroupRule rule = it @@ -85,4 +85,4 @@ class OktaOrgCleaner { it.delete() } } -} \ No newline at end of file +} diff --git a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/Util.groovy b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/Util.groovy index 7f39d47cd28..e31c234e9a9 100644 --- a/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/Util.groovy +++ b/integration-tests/src/test/groovy/com/okta/sdk/tests/it/util/Util.groovy @@ -19,7 +19,9 @@ import com.okta.sdk.resource.CollectionResource import com.okta.sdk.resource.Resource import com.okta.sdk.resource.group.Group import com.okta.sdk.resource.group.GroupList +import com.okta.sdk.resource.linked.object.LinkedObject import com.okta.sdk.resource.user.Role +import com.okta.sdk.resource.user.RoleList import com.okta.sdk.resource.user.User import org.testng.Assert @@ -71,6 +73,33 @@ class Util { assertThat(groupsFound, hasSize(1)) } + static void assertGroupAbsent(GroupList results, Group expectedGroup) { + + List groupsFound = StreamSupport.stream(results.spliterator(), false) + .filter {group -> group.id == expectedGroup.id} + .collect(Collectors.toList()) + + assertThat(groupsFound, hasSize(0)) + } + + static void assertRolePresent(RoleList results, Role expectedRole) { + + List rolesFound = StreamSupport.stream(results.spliterator(), false) + .filter {role -> role.id == expectedRole.id} + .collect(Collectors.toList()) + + assertThat(rolesFound, hasSize(1)) + } + + static void assertRoleAbsent(RoleList results, Role expectedRole) { + + List rolesFound = StreamSupport.stream(results.spliterator(), false) + .filter {role -> role.id == expectedRole.id} + .collect(Collectors.toList()) + + assertThat(rolesFound, hasSize(0)) + } + static > void assertPresent(C results, T expected) { List resourcesFound = StreamSupport.stream(results.spliterator(), false) @@ -89,8 +118,19 @@ class Util { assertThat(resourcesFound, hasSize(0)) } + static > void assertLinkedObjectPresent(C results, T expected) { + + List resourcesFound = StreamSupport.stream(results.spliterator(), false) + .filter { listItem -> + ((listItem.primary.name == expected.primary.name) && + (listItem.associated.name == expected.associated.name))} + .collect(Collectors.toList()) + + assertThat(resourcesFound, hasSize(1)) + } + static void assertGroupTargetPresent(User user, Group group, Role role) { - def groupTargets = user.listGroupTargetsForRole(role.id) + def groupTargets = user.listGroupTargets(role.id) assertThat "GroupTarget Present not found in User role", StreamSupport.stream(groupTargets.spliterator(), false) diff --git a/pom.xml b/pom.xml index 4d1a9ab66ea..e8690bec627 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT pom Okta Java SDK @@ -40,7 +40,7 @@ 1.64 0.11.1 1.5.4 - 1.2.3 + 1.2.4 okta/okta-sdk-java @@ -72,27 +72,27 @@ com.okta.sdk okta-sdk-api - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT com.okta.sdk okta-sdk-impl - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT com.okta.sdk okta-api-swagger-templates - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT com.okta.sdk okta-sdk-httpclient - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT com.okta.sdk okta-sdk-okhttp - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT @@ -131,14 +131,14 @@ com.okta.sdk okta-sdk-integration-tests - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT com.okta.sdk okta-sdk-examples-quickstart - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT @@ -315,7 +315,7 @@ com.okta.sdk okta-api-swagger-templates - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT @@ -330,7 +330,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.13.0 + 0.14.3 @@ -342,7 +342,7 @@ true - true + false true ${root.dir}/src/japicmp/postAnalysisScript.groovy diff --git a/src/swagger/api.yaml b/src/swagger/api.yaml index 07b2d084463..458a2f70b6f 100644 --- a/src/swagger/api.yaml +++ b/src/swagger/api.yaml @@ -1,5 +1,5 @@ # -# Copyright 2017 Okta +# Copyright 2020-Present Okta, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,7 +25,7 @@ info: license: name: Apache-2.0 url: 'http://www.apache.org/licenses/LICENSE-2.0.html' - version: 1.11.0 + version: 2.0.0 externalDocs: description: Find more info here url: 'http://developer.okta.com/docs/api/getting_started/design_principles.html' @@ -112,6 +112,9 @@ paths: in: query name: activate type: boolean + - in: header + name: OktaAccessGateway-Agent + type: string produces: - application/json responses: @@ -197,6 +200,177 @@ paths: summary: Update Application tags: - Application + '/api/v1/apps/{appId}/credentials/csrs': + get: + consumes: + - application/json + description: Enumerates Certificate Signing Requests for an application + operationId: listCsrsForApplication + parameters: + - in: path + name: appId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Csr' + type: array + security: + - api_token: [] + summary: List Certificate Signing Requests for Application + tags: + - Application + post: + consumes: + - application/json + description: >- + Generates a new key pair and returns the Certificate Signing Request for + it. + operationId: generateCsrForApplication + parameters: + - in: path + name: appId + required: true + type: string + - in: body + name: metadata + required: true + schema: + $ref: '#/definitions/CsrMetadata' + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/Csr' + security: + - api_token: [] + summary: Generate Certificate Signing Request for Application + tags: + - Application + '/api/v1/apps/{appId}/credentials/csrs/{csrId}': + delete: + consumes: + - application/json + operationId: revokeCsrFromApplication + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Application + get: + consumes: + - application/json + operationId: getCsrForApplication + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Csr' + security: + - api_token: [] + tags: + - Application + '/api/v1/apps/{appId}/credentials/csrs/{csrId}/lifecycle/publish': + post: + consumes: + - application/json + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + tags: + - Application + x-okta-multi-operation: + - consumes: + - application/x-x509-ca-cert + encoding: base64 + operationId: publishCerCert + parameters: + - in: body + name: certificate + required: true + type: string + - consumes: + - application/x-x509-ca-cert + operationId: publishBinaryCerCert + parameters: + - format: binary + in: body + name: certificate + required: true + type: string + - consumes: + - application/pkix-cert + encoding: base64 + operationId: publishDerCert + parameters: + - in: body + name: certificate + required: true + type: string + - consumes: + - application/pkix-cert + operationId: publishBinaryDerCert + parameters: + - format: binary + in: body + name: certificate + required: true + type: string + - consumes: + - application/x-pem-file + operationId: publishBinaryPemCert + parameters: + - format: binary + in: body + name: certificate + required: true + type: string '/api/v1/apps/{appId}/credentials/keys': get: consumes: @@ -222,13 +396,36 @@ paths: summary: List Key Credentials for Application tags: - Application + '/api/v1/apps/{appId}/credentials/keys/generate': + post: + consumes: + - application/json + description: Generates a new X.509 certificate for an application key credential + operationId: generateApplicationKey + parameters: + - in: path + name: appId + required: true + type: string + - in: query + name: validityYears + type: integer + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + tags: + - Application '/api/v1/apps/{appId}/credentials/keys/{keyId}': get: consumes: - application/json - description: >- - Gets a specific [application key - credential](#application-key-credential-model) by `kid` + description: Gets a specific application key credential by kid operationId: getApplicationKey parameters: - in: path @@ -276,8 +473,8 @@ paths: produces: - application/json responses: - '200': - description: Success + '201': + description: Created schema: $ref: '#/definitions/JsonWebKey' security: @@ -285,6 +482,111 @@ paths: summary: Clone Application Key Credential tags: - Application + '/api/v1/apps/{appId}/grants': + get: + consumes: + - application/json + description: Lists all scope consent grants for the application + operationId: listScopeConsentGrants + parameters: + - in: path + name: appId + required: true + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + type: array + security: + - api_token: [] + tags: + - Application + post: + consumes: + - application/json + description: Grants consent for the application to request an OAuth 2.0 Okta scope + operationId: grantConsentToScope + parameters: + - in: path + name: appId + required: true + type: string + - in: body + name: oAuth2ScopeConsentGrant + required: true + schema: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + security: + - api_token: [] + tags: + - Application + '/api/v1/apps/{appId}/grants/{grantId}': + delete: + consumes: + - application/json + description: Revokes permission for the application to request the given scope + operationId: revokeScopeConsentGrant + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: grantId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Application + get: + consumes: + - application/json + description: Fetches a single scope consent grant for the application + operationId: getScopeConsentGrant + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: grantId + required: true + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + security: + - api_token: [] + tags: + - Application '/api/v1/apps/{appId}/groups': get: consumes: @@ -344,8 +646,8 @@ paths: produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] summary: Remove Group from Application @@ -453,41 +755,47 @@ paths: summary: Deactivate Application tags: - Application - '/api/v1/apps/{appId}/users': + '/api/v1/apps/{appId}/tokens': + delete: + consumes: + - application/json + description: Revokes all tokens for the specified application + operationId: revokeOAuth2TokensForApplication + parameters: + - in: path + name: appId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Application get: consumes: - application/json - description: >- - Enumerates all assigned [application users](#application-user-model) for - an application. - operationId: listApplicationUsers + description: Lists all tokens for the application + operationId: listOAuth2TokensForApplication parameters: - in: path name: appId required: true type: string - in: query - name: q + name: expand type: string - in: query - name: query_scope - type: string - - description: specifies the pagination cursor for the next page of assignments - in: query name: after type: string - - default: -1 - description: specifies the number of results for a page + - default: 20 format: int32 in: query name: limit type: integer - - in: query - name: filter - type: string - - in: query - name: expand - type: string produces: - application/json responses: @@ -495,20 +803,120 @@ paths: description: Success schema: items: - $ref: '#/definitions/AppUser' + $ref: '#/definitions/OAuth2Token' type: array security: - api_token: [] - summary: List Users Assigned to Application tags: - Application - post: + '/api/v1/apps/{appId}/tokens/{tokenId}': + delete: consumes: - application/json - description: >- - Assigns an user to an application with - [credentials](#application-user-credentials-object) and an app-specific - [profile](#application-user-profile-object). Profile mappings defined + description: Revokes the specified token for the specified application + operationId: revokeOAuth2TokenForApplication + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: tokenId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Application + get: + consumes: + - application/json + description: Gets a token for the specified application + operationId: getOAuth2TokenForApplication + parameters: + - in: path + name: appId + required: true + type: string + - in: path + name: tokenId + required: true + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/OAuth2Token' + security: + - api_token: [] + tags: + - Application + '/api/v1/apps/{appId}/users': + get: + consumes: + - application/json + description: >- + Enumerates all assigned [application users](#application-user-model) for + an application. + operationId: listApplicationUsers + parameters: + - in: path + name: appId + required: true + type: string + - in: query + name: q + type: string + - in: query + name: query_scope + type: string + - description: specifies the pagination cursor for the next page of assignments + in: query + name: after + type: string + - default: -1 + description: specifies the number of results for a page + format: int32 + in: query + name: limit + type: integer + - in: query + name: filter + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/AppUser' + type: array + security: + - api_token: [] + summary: List Users Assigned to Application + tags: + - Application + post: + consumes: + - application/json + description: >- + Assigns an user to an application with + [credentials](#application-user-credentials-object) and an app-specific + [profile](#application-user-profile-object). Profile mappings defined for the application are first applied before applying any profile properties specified in the request. operationId: assignUserToApplication @@ -557,8 +965,8 @@ paths: produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] summary: Remove User from Application @@ -624,36 +1032,21 @@ paths: summary: Update Application Profile for Assigned User tags: - Application - /api/v1/groups: + /api/v1/authorizationServers: get: consumes: - application/json - description: >- - Enumerates groups in your organization with pagination. A subset of - groups can be returned that match a supported filter expression or - query. - operationId: listGroups + description: Success + operationId: listAuthorizationServers parameters: - - description: Searches the name property of groups for matching value - in: query + - in: query name: q type: string - - description: Filter expression for groups - in: query - name: filter - type: string - - description: Specifies the pagination cursor for the next page of groups - in: query - name: after - type: string - - default: -1 - description: Specifies the number of group results in a page - format: int32 - in: query + - in: query name: limit - type: integer + type: string - in: query - name: expand + name: after type: string produces: - application/json @@ -662,205 +1055,191 @@ paths: description: Success schema: items: - $ref: '#/definitions/Group' + $ref: '#/definitions/AuthorizationServer' type: array security: - api_token: [] - summary: List Groups tags: - - Group + - AuthorizationServer post: consumes: - application/json - description: Adds a new group with `OKTA_GROUP` type to your organization. - operationId: createGroup + description: Success + operationId: createAuthorizationServer parameters: - in: body - name: group + name: authorizationServer required: true schema: - $ref: '#/definitions/Group' + $ref: '#/definitions/AuthorizationServer' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Group' + $ref: '#/definitions/AuthorizationServer' + '201': + description: Created security: - api_token: [] - summary: Add Group tags: - - Group - /api/v1/groups/rules: - get: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}': + delete: consumes: - application/json - description: Lists all group rules for your organization. - operationId: listRules + description: Success + operationId: deleteAuthorizationServer parameters: - - default: -1 - description: Specifies the number of rule results in a page - format: int32 - in: query - name: limit - type: integer - - description: Specifies the pagination cursor for the next page of rules - in: query - name: after - type: string - - default: '' - in: query - name: expand + - in: path + name: authServerId + required: true type: string - x-okta-added-version: 1.3.0 produces: - application/json responses: - '200': - description: Success - schema: - items: - $ref: '#/definitions/GroupRule' - type: array + '204': + description: No Content security: - api_token: [] - summary: List Group Rules tags: - - Group - post: + - AuthorizationServer + get: consumes: - application/json - description: >- - Creates a group rule to dynamically add users to the specified group if - they match the condition - operationId: createRule + description: Success + operationId: getAuthorizationServer parameters: - - in: body - name: groupRule + - in: path + name: authServerId required: true - schema: - $ref: '#/definitions/GroupRule' + type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/GroupRule' + $ref: '#/definitions/AuthorizationServer' security: - api_token: [] - summary: Create Group Rule tags: - - Group - '/api/v1/groups/rules/{ruleId}': - delete: + - AuthorizationServer + put: consumes: - application/json - description: Removes a specific group rule by id from your organization - operationId: deleteRule + description: Success + operationId: updateAuthorizationServer parameters: - in: path - name: ruleId + name: authServerId required: true type: string - - default: false - in: query - name: removeUsers - type: boolean + - in: body + name: authorizationServer + required: true + schema: + $ref: '#/definitions/AuthorizationServer' produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/AuthorizationServer' security: - api_token: [] - summary: Delete a group Rule tags: - - Group + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/claims': get: consumes: - application/json - description: Fetches a specific group rule by id from your organization - operationId: getRule + description: Success + operationId: listOAuth2Claims parameters: - in: path - name: ruleId + name: authServerId required: true type: string - - default: '' - in: query - name: expand - type: string - x-okta-added-version: 1.3.0 produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/GroupRule' + items: + $ref: '#/definitions/OAuth2Claim' + type: array security: - api_token: [] - summary: Get Group Rule tags: - - Group - put: + - AuthorizationServer + post: consumes: - application/json description: Success - operationId: updateRule + operationId: createOAuth2Claim parameters: - in: path - name: ruleId + name: authServerId required: true type: string - in: body - name: groupRule + name: oAuth2Claim required: true schema: - $ref: '#/definitions/GroupRule' + $ref: '#/definitions/OAuth2Claim' produces: - application/json responses: '200': - description: Success + description: Created schema: - $ref: '#/definitions/GroupRule' + $ref: '#/definitions/OAuth2Claim' + '201': + description: Success security: - api_token: [] tags: - - Group - '/api/v1/groups/rules/{ruleId}/lifecycle/activate': - post: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/claims/{claimId}': + delete: consumes: - application/json - description: Activates a specific group rule by id from your organization - operationId: activateRule + description: Success + operationId: deleteOAuth2Claim parameters: - in: path - name: ruleId + name: authServerId + required: true + type: string + - in: path + name: claimId required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] - summary: Activate a group Rule tags: - - Group - '/api/v1/groups/rules/{ruleId}/lifecycle/deactivate': - post: + - AuthorizationServer + get: consumes: - application/json - description: Deactivates a specific group rule by id from your organization - operationId: deactivateRule + description: Success + operationId: getOAuth2Claim parameters: - in: path - name: ruleId + name: authServerId + required: true + type: string + - in: path + name: claimId required: true type: string produces: @@ -868,114 +1247,115 @@ paths: responses: '200': description: Success + schema: + $ref: '#/definitions/OAuth2Claim' security: - api_token: [] - summary: Deactivate a group Rule tags: - - Group - '/api/v1/groups/{groupId}': - delete: + - AuthorizationServer + put: consumes: - application/json - description: Removes a group with `OKTA_GROUP` type from your organization. - operationId: deleteGroup + description: Success + operationId: updateOAuth2Claim parameters: - in: path - name: groupId + name: authServerId + required: true + type: string + - in: path + name: claimId required: true type: string + - in: body + name: oAuth2Claim + required: true + schema: + $ref: '#/definitions/OAuth2Claim' produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/OAuth2Claim' security: - api_token: [] - summary: Remove Group tags: - - Group + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/clients': get: consumes: - application/json - description: Lists all group rules for your organization. - operationId: getGroup + description: Success + operationId: listOAuth2ClientsForAuthorizationServer parameters: - in: path - name: groupId + name: authServerId required: true type: string - - in: query - name: expand - type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Group' + items: + $ref: '#/definitions/OAuth2Client' + type: array security: - api_token: [] - summary: List Group Rules tags: - - Group - put: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/clients/{clientId}/tokens': + delete: consumes: - application/json - description: >- - Updates the profile for a group with `OKTA_GROUP` type from your - organization. - operationId: updateGroup + description: Success + operationId: revokeRefreshTokensForAuthorizationServerAndClient parameters: - in: path - name: groupId + name: authServerId required: true type: string - - in: body - name: group + - in: path + name: clientId required: true - schema: - $ref: '#/definitions/Group' + type: string produces: - application/json responses: - '200': - description: Success - schema: - $ref: '#/definitions/Group' + '204': + description: No Content security: - api_token: [] - summary: Update Group tags: - - Group - '/api/v1/groups/{groupId}/users': + - AuthorizationServer get: consumes: - application/json - description: >- - Enumerates all [users](/docs/api/resources/users.html#user-model) that - are a member of a group. - operationId: listGroupUsers + description: Success + operationId: listRefreshTokensForAuthorizationServerAndClient parameters: - in: path - name: groupId + name: authServerId required: true type: string - - description: Specifies the pagination cursor for the next page of users - in: query + - in: path + name: clientId + required: true + type: string + - in: query + name: expand + type: string + - in: query name: after type: string - default: -1 - description: Specifies the number of user results in a page format: int32 in: query name: limit type: integer - - default: all - in: query - name: managedBy - type: string - x-okta-added-version: 1.3.0 produces: - application/json responses: @@ -983,95 +1363,82 @@ paths: description: Success schema: items: - $ref: '#/definitions/User' + $ref: '#/definitions/OAuth2RefreshToken' type: array security: - api_token: [] - summary: List Group Members tags: - - Group - '/api/v1/groups/{groupId}/users/{userId}': + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/clients/{clientId}/tokens/{tokenId}': delete: consumes: - application/json - description: >- - Removes a [user](users.html#user-model) from a group with `OKTA_GROUP` - type. - operationId: removeGroupUser + description: Success + operationId: revokeRefreshTokenForAuthorizationServerAndClient parameters: - in: path - name: groupId + name: authServerId required: true type: string - in: path - name: userId + name: clientId + required: true + type: string + - in: path + name: tokenId required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] - summary: Remove User from Group tags: - - Group - put: + - AuthorizationServer + get: consumes: - application/json - description: 'Adds a [user](users.html#user-model) to a group with `OKTA_GROUP` type.' - operationId: addUserToGroup + description: Success + operationId: getRefreshTokenForAuthorizationServerAndClient parameters: - in: path - name: groupId + name: authServerId required: true type: string - in: path - name: userId + name: clientId + required: true + type: string + - in: path + name: tokenId required: true type: string + - in: query + name: expand + type: string produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/OAuth2RefreshToken' security: - api_token: [] - summary: Add User to Group tags: - - Group - /api/v1/logs: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/credentials/keys': get: consumes: - application/json - description: >- - The Okta System Log API provides read access to your organization’s - system log. This API provides more functionality than the Events API - operationId: getLogs + description: Success + operationId: listAuthorizationServerKeys parameters: - - in: query - name: until - type: string - - in: query - name: since - type: string - - in: query - name: filter - type: string - - in: query - name: q - type: string - - default: 100 - in: query - name: limit - type: integer - - default: ASCENDING - in: query - name: sortOrder - type: string - - in: query - name: after + - in: path + name: authServerId + required: true type: string produces: - application/json @@ -1080,39 +1447,28 @@ paths: description: Success schema: items: - $ref: '#/definitions/LogEvent' + $ref: '#/definitions/JsonWebKey' type: array security: - api_token: [] - summary: Fetch a list of events from your Okta organization system log. tags: - - Log - /api/v1/policies: - get: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/credentials/lifecycle/keyRotate': + post: consumes: - application/json - description: '' - operationId: listPolicies + description: Success + operationId: rotateAuthorizationServerKeys parameters: - - in: query - name: type + - in: path + name: authServerId required: true type: string - - in: query - name: status - type: string - - in: query - name: after - type: string - - default: -1 - format: int32 - in: query - name: limit - type: integer - - default: '' - in: query - name: expand - type: string + - in: body + name: use + required: true + schema: + $ref: '#/definitions/JwkUse' produces: - application/json responses: @@ -1120,47 +1476,41 @@ paths: description: Success schema: items: - $ref: '#/definitions/Policy' + $ref: '#/definitions/JsonWebKey' type: array security: - api_token: [] tags: - - Policy + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/lifecycle/activate': post: consumes: - application/json - description: '' - operationId: createPolicy + description: Success + operationId: activateAuthorizationServer parameters: - - in: body - name: policy + - in: path + name: authServerId required: true - schema: - $ref: '#/definitions/Policy' - - default: true - in: query - name: activate - type: boolean + type: string produces: - application/json responses: '200': description: Success - schema: - $ref: '#/definitions/Policy' security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}': - delete: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/lifecycle/deactivate': + post: consumes: - application/json - description: '' - operationId: deletePolicy + description: Success + operationId: deactivateAuthorizationServer parameters: - in: path - name: policyId + name: authServerId required: true type: string produces: @@ -1171,47 +1521,46 @@ paths: security: - api_token: [] tags: - - Policy + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/policies': get: consumes: - application/json - description: '' - operationId: getPolicy + description: Success + operationId: listAuthorizationServerPolicies parameters: - in: path - name: policyId + name: authServerId required: true type: string - - default: '' - in: query - name: expand - type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Policy' + items: + $ref: '#/definitions/Policy' + type: array security: - api_token: [] tags: - - Policy - put: + - AuthorizationServer + post: consumes: - application/json - description: '' - operationId: updatePolicy + description: Success + operationId: createAuthorizationServerPolicy parameters: + - in: path + name: authServerId + required: true + type: string - in: body name: policy required: true schema: $ref: '#/definitions/Policy' - - in: path - name: policyId - required: true - type: string produces: - application/json responses: @@ -1219,37 +1568,23 @@ paths: description: Success schema: $ref: '#/definitions/Policy' + '201': + description: Created security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}/lifecycle/activate': - post: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/policies/{policyId}': + delete: consumes: - application/json - description: '' - operationId: activatePolicy + description: Success + operationId: deleteAuthorizationServerPolicy parameters: - in: path - name: policyId + name: authServerId required: true type: string - produces: - - application/json - responses: - '200': - description: Success - security: - - api_token: [] - tags: - - Policy - '/api/v1/policies/{policyId}/lifecycle/deactivate': - post: - consumes: - - application/json - description: '' - operationId: deactivatePolicy - parameters: - in: path name: policyId required: true @@ -1257,19 +1592,22 @@ paths: produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}/rules': + - AuthorizationServer get: consumes: - application/json - description: '' - operationId: listPolicyRules + description: Success + operationId: getAuthorizationServerPolicy parameters: + - in: path + name: authServerId + required: true + type: string - in: path name: policyId required: true @@ -1280,135 +1618,143 @@ paths: '200': description: Success schema: - items: - $ref: '#/definitions/PolicyRule' - type: array + $ref: '#/definitions/Policy' security: - api_token: [] tags: - - Policy - post: + - AuthorizationServer + put: consumes: - application/json - description: '' - operationId: addPolicyRule + description: Success + operationId: updateAuthorizationServerPolicy parameters: + - in: path + name: authServerId + required: true + type: string - in: path name: policyId required: true type: string - in: body - name: policyRule + name: policy required: true schema: - $ref: '#/definitions/PolicyRule' - - default: true - in: query - name: activate - type: boolean + $ref: '#/definitions/Policy' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/PolicyRule' + $ref: '#/definitions/Policy' security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}/rules/{ruleId}': - delete: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/scopes': + get: consumes: - application/json - description: '' - operationId: deletePolicyRule + description: Success + operationId: listOAuth2Scopes parameters: - in: path - name: policyId + name: authServerId required: true type: string - - in: path - name: ruleId - required: true + - in: query + name: q + type: string + - in: query + name: filter + type: string + - in: query + name: cursor type: string + - default: -1 + format: int32 + in: query + name: limit + type: integer produces: - application/json responses: '200': description: Success + schema: + items: + $ref: '#/definitions/OAuth2Scope' + type: array security: - api_token: [] tags: - - Policy - get: + - AuthorizationServer + post: consumes: - application/json - description: '' - operationId: getPolicyRule + description: Success + operationId: createOAuth2Scope parameters: - in: path - name: policyId + name: authServerId required: true type: string - - in: path - name: ruleId + - in: body + name: oAuth2Scope required: true - type: string + schema: + $ref: '#/definitions/OAuth2Scope' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/PolicyRule' + $ref: '#/definitions/OAuth2Scope' + '201': + description: Success security: - api_token: [] tags: - - Policy - put: + - AuthorizationServer + '/api/v1/authorizationServers/{authServerId}/scopes/{scopeId}': + delete: consumes: - application/json - description: '' - operationId: updatePolicyRule + description: Success + operationId: deleteOAuth2Scope parameters: - in: path - name: policyId + name: authServerId required: true type: string - in: path - name: ruleId + name: scopeId required: true type: string - - in: body - name: policyRule - required: true - schema: - $ref: '#/definitions/PolicyRule' produces: - application/json responses: - '200': - description: Success - schema: - $ref: '#/definitions/PolicyRule' + '204': + description: No Content security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}/rules/{ruleId}/lifecycle/activate': - post: + - AuthorizationServer + get: consumes: - application/json - description: '' - operationId: activatePolicyRule + description: Success + operationId: getOAuth2Scope parameters: - in: path - name: policyId + name: authServerId required: true type: string - in: path - name: ruleId + name: scopeId required: true type: string produces: @@ -1416,91 +1762,112 @@ paths: responses: '200': description: Success + schema: + $ref: '#/definitions/OAuth2Scope' security: - api_token: [] tags: - - Policy - '/api/v1/policies/{policyId}/rules/{ruleId}/lifecycle/deactivate': - post: + - AuthorizationServer + put: consumes: - application/json - description: '' - operationId: deactivatePolicyRule + description: Success + operationId: updateOAuth2Scope parameters: - in: path - name: policyId + name: authServerId required: true type: string - in: path - name: ruleId + name: scopeId required: true type: string + - in: body + name: oAuth2Scope + required: true + schema: + $ref: '#/definitions/OAuth2Scope' produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/OAuth2Scope' security: - api_token: [] tags: - - Policy - /api/v1/sessions: + - AuthorizationServer + /api/v1/eventHooks: + get: + consumes: + - application/json + description: Success + operationId: listEventHooks + parameters: [] + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/EventHook' + type: array + security: + - api_token: [] + tags: + - EventHook post: consumes: - application/json - description: >- - Creates a new session for a user with a valid session token. Use this - API if, for example, you want to set the session cookie yourself instead - of allowing Okta to set it, or want to hold the session ID in order to - delete a session via the API instead of visiting the logout URL. - operationId: createSession + description: Success + operationId: createEventHook parameters: - in: body - name: createSessionRequest + name: eventHook required: true schema: - $ref: '#/definitions/CreateSessionRequest' + $ref: '#/definitions/EventHook' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Session' + $ref: '#/definitions/EventHook' security: - api_token: [] - summary: Create Session with Session Token tags: - - Session - '/api/v1/sessions/{sessionId}': + - EventHook + '/api/v1/eventHooks/{eventHookId}': delete: consumes: - application/json - description: '' - operationId: endSession + description: Success + operationId: deleteEventHook parameters: - in: path - name: sessionId + name: eventHookId required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] - summary: Close Session tags: - - Session + - EventHook get: consumes: - application/json - description: Get details about a session. - operationId: getSession + description: Success + operationId: getEventHook parameters: - in: path - name: sessionId + name: eventHookId required: true type: string produces: @@ -1509,73 +1876,47 @@ paths: '200': description: Success schema: - $ref: '#/definitions/Session' + $ref: '#/definitions/EventHook' security: - api_token: [] tags: - - Session - '/api/v1/sessions/{sessionId}/lifecycle/refresh': - post: + - EventHook + put: consumes: - application/json - description: '' - operationId: refreshSession + description: Success + operationId: updateEventHook parameters: - in: path - name: sessionId + name: eventHookId required: true type: string + - in: body + name: eventHook + required: true + schema: + $ref: '#/definitions/EventHook' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Session' + $ref: '#/definitions/EventHook' security: - api_token: [] - summary: Refresh Session tags: - - Session - /api/v1/users: - get: + - EventHook + '/api/v1/eventHooks/{eventHookId}/lifecycle/activate': + post: consumes: - application/json - description: >- - Lists users in your organization with pagination in most cases. A - subset of users can be returned that match a supported filter expression - or search criteria. - operationId: listUsers + description: Success + operationId: activateEventHook parameters: - - description: 'Finds a user that matches firstName, lastName, and email properties' - in: query - name: q - type: string - - description: Specifies the pagination cursor for the next page of users - in: query - name: after - type: string - - default: -1 - description: Specifies the number of results returned - format: int32 - in: query - name: limit - type: integer - - description: Filters users with a supported expression for a subset of properties - in: query - name: filter - type: string - - in: query - name: format - type: string - - description: >- - Searches for users with a supported filtering expression for most - properties - in: query - name: search - type: string - - in: query - name: expand + - in: path + name: eventHookId + required: true type: string produces: - application/json @@ -1583,98 +1924,84 @@ paths: '200': description: Success schema: - items: - $ref: '#/definitions/User' - type: array + $ref: '#/definitions/EventHook' security: - api_token: [] - summary: List Users tags: - - User + - EventHook + '/api/v1/eventHooks/{eventHookId}/lifecycle/deactivate': post: consumes: - application/json - description: >- - Creates a new user in your Okta organization with or without - credentials. - operationId: createUser + description: Success + operationId: deactivateEventHook parameters: - - in: body - name: body + - in: path + name: eventHookId required: true - schema: - $ref: '#/definitions/User' - - default: true - description: Executes activation lifecycle operation when creating the user - in: query - name: activate - type: boolean - - default: false - description: >- - Indicates whether to create a user with a specified authentication - provider - in: query - name: provider - type: boolean - - default: '' - description: >- - With activate=true, set nextLogin to "changePassword" to have the - password be EXPIRED, so user must change it the next time they log - in. - in: query - name: nextLogin type: string - x-okta-added-version: 0.14.0 - x-openapi-v3-schema-ref: '#/definitions/UserNextLogin' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/User' + $ref: '#/definitions/EventHook' security: - api_token: [] - summary: Create User tags: - - User - '/api/v1/users/{userId}': - delete: + - EventHook + '/api/v1/eventHooks/{eventHookId}/lifecycle/verify': + post: consumes: - application/json - description: >- - Deletes a user permanently. This operation can only be performed on - users that have a `DEPROVISIONED` status. **This action cannot be - recovered!** - operationId: deactivateOrDeleteUser + description: Success + operationId: verifyEventHook parameters: - in: path - name: userId + name: eventHookId required: true type: string - - default: false - in: query - name: sendEmail - type: boolean - x-okta-added-version: 1.5.0 produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/EventHook' security: - api_token: [] - summary: Delete User tags: - - User + - EventHook + /api/v1/features: get: consumes: - application/json - description: Fetches a user from your Okta organization. - operationId: getUser + description: Success + operationId: listFeatures + parameters: [] + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Feature' + type: array + security: + - api_token: [] + tags: + - Feature + '/api/v1/features/{featureId}': + get: + consumes: + - application/json + description: Success + operationId: getFeature parameters: - in: path - name: userId + name: featureId required: true type: string produces: @@ -1683,62 +2010,46 @@ paths: '200': description: Success schema: - $ref: '#/definitions/User' + $ref: '#/definitions/Feature' security: - api_token: [] - summary: Get User tags: - - User - put: + - Feature + '/api/v1/features/{featureId}/dependencies': + get: consumes: - application/json - description: >- - Update a user's profile and/or credentials using strict-update - semantics. - operationId: updateUser + description: Success + operationId: listFeatureDependencies parameters: - - in: body - name: user - required: true - schema: - $ref: '#/definitions/User' - in: path - name: userId + name: featureId required: true type: string - - in: query - name: strict - type: boolean - x-okta-added-version: 1.10.0 produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/User' + items: + $ref: '#/definitions/Feature' + type: array security: - api_token: [] - summary: Update User tags: - - User - '/api/v1/users/{userId}/appLinks': + - Feature + '/api/v1/features/{featureId}/dependents': get: consumes: - application/json - description: >- - Fetches appLinks for all direct or indirect (via group membership) - assigned applications. - operationId: listAppLinks + description: Success + operationId: listFeatureDependents parameters: - in: path - name: userId + name: featureId required: true type: string - - default: false - in: query - name: showAll - type: boolean produces: - application/json responses: @@ -1746,128 +2057,132 @@ paths: description: Success schema: items: - $ref: '#/definitions/AppLink' + $ref: '#/definitions/Feature' type: array security: - api_token: [] - summary: Get Assigned App Links tags: - - User - '/api/v1/users/{userId}/credentials/change_password': + - Feature + '/api/v1/features/{featureId}/{lifecycle}': post: consumes: - application/json - description: >- - Changes a user's password by validating the user's current password. - This operation can only be performed on users in `STAGED`, `ACTIVE`, - `PASSWORD_EXPIRED`, or `RECOVERY` status that have a valid [password - credential](#password-object) - operationId: changePassword + description: Success + operationId: updateFeatureLifecycle parameters: - - in: body - name: changePasswordRequest + - in: path + name: featureId required: true - schema: - $ref: '#/definitions/ChangePasswordRequest' + type: string - in: path - name: userId + name: lifecycle required: true type: string - in: query - name: strict - type: boolean - x-okta-added-version: 1.10.0 + name: mode + type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/UserCredentials' + $ref: '#/definitions/Feature' security: - api_token: [] - summary: Change Password tags: - - User - '/api/v1/users/{userId}/credentials/change_recovery_question': - post: + - Feature + /api/v1/groups: + get: consumes: - application/json description: >- - Changes a user's recovery question & answer credential by validating the - user's current password. This operation can only be performed on users - in **STAGED**, **ACTIVE** or **RECOVERY** `status` that have a valid - [password credential](#password-object) - operationId: changeRecoveryQuestion + Enumerates groups in your organization with pagination. A subset of + groups can be returned that match a supported filter expression or + query. + operationId: listGroups parameters: - - in: body - name: userCredentials - required: true - schema: - $ref: '#/definitions/UserCredentials' - - in: path - name: userId - required: true + - description: Searches the name property of groups for matching value + in: query + name: q + type: string + - description: Filter expression for groups + in: query + name: filter + type: string + - description: Specifies the pagination cursor for the next page of groups + in: query + name: after type: string + - default: 10000 + description: Specifies the number of group results in a page + format: int32 + in: query + name: limit + type: integer produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/UserCredentials' + items: + $ref: '#/definitions/Group' + type: array security: - api_token: [] - summary: Change Recovery Question + summary: List Groups tags: - - User - '/api/v1/users/{userId}/credentials/forgot_password': + - Group post: consumes: - application/json - description: >- - Generates a one-time token (OTT) that can be used to reset a user's - password. The user will be required to validate their security - question's answer when visiting the reset link. This operation can only - be performed on users with a valid [recovery question - credential](#recovery-question-object) and have an `ACTIVE` status. - operationId: forgotPassword + description: Adds a new group with `OKTA_GROUP` type to your organization. + operationId: createGroup parameters: - in: body - name: userCredentials - schema: - $ref: '#/definitions/UserCredentials' - - in: path - name: userId + name: group required: true - type: string - - default: true - in: query - name: sendEmail - type: boolean + schema: + $ref: '#/definitions/Group' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/ForgotPasswordResponse' + $ref: '#/definitions/Group' security: - api_token: [] - summary: Forgot Password + summary: Add Group tags: - - User - '/api/v1/users/{userId}/factors': + - Group + /api/v1/groups/rules: get: consumes: - application/json - description: Enumerates all the enrolled factors for the specified user - operationId: listFactors + description: Lists all group rules for your organization. + operationId: listGroupRules parameters: - - in: path - name: userId - required: true + - default: 50 + description: Specifies the number of rule results in a page + format: int32 + in: query + name: limit + type: integer + - description: Specifies the pagination cursor for the next page of rules + in: query + name: after + type: string + - description: Specifies the keyword to search fules for + in: query + name: search + type: string + - description: 'If specified as `groupIdToGroupNameMap`, then show group names' + in: query + name: expand type: string + x-okta-added-version: 1.3.0 produces: - application/json responses: @@ -1875,261 +2190,241 @@ paths: description: Success schema: items: - $ref: '#/definitions/Factor' + $ref: '#/definitions/GroupRule' type: array security: - api_token: [] + summary: List Group Rules tags: - - UserFactor + - Group post: consumes: - application/json - description: 'Enrolls a user with a supported [factor](#list-factors-to-enroll)' - operationId: addFactor + description: >- + Creates a group rule to dynamically add users to the specified group if + they match the condition + operationId: createGroupRule parameters: - - in: path - name: userId - required: true - type: string - - description: Factor - in: body - name: body + - in: body + name: groupRule required: true schema: - $ref: '#/definitions/Factor' - - default: false - in: query - name: updatePhone - type: boolean - - description: id of SMS template (only for SMS factor) - in: query - name: templateId - type: string - - default: 300 - format: int32 - in: query - name: tokenLifetimeSeconds - type: integer - x-okta-added-version: 1.3.0 - - default: false - in: query - name: activate - type: boolean - x-okta-added-version: 1.3.0 + $ref: '#/definitions/GroupRule' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Factor' + $ref: '#/definitions/GroupRule' security: - api_token: [] - summary: Enroll Factor + summary: Create Group Rule tags: - - UserFactor - '/api/v1/users/{userId}/factors/catalog': - get: + - Group + '/api/v1/groups/rules/{ruleId}': + delete: consumes: - application/json - description: >- - Enumerates all the [supported factors](#supported-factors-for-providers) - that can be enrolled for the specified user - operationId: listSupportedFactors + description: Removes a specific group rule by id from your organization + operationId: deleteGroupRule parameters: - in: path - name: userId + name: ruleId required: true type: string produces: - application/json responses: - '200': - description: Success - schema: - items: - $ref: '#/definitions/Factor' - type: array + '202': + description: Accepted security: - api_token: [] + summary: Delete a group Rule tags: - - UserFactor - '/api/v1/users/{userId}/factors/questions': + - Group get: consumes: - application/json - description: >- - Enumerates all available security questions for a user's `question` - factor - operationId: listSupportedSecurityQuestions + description: Fetches a specific group rule by id from your organization + operationId: getGroupRule parameters: - in: path - name: userId + name: ruleId required: true type: string + - in: query + name: expand + type: string produces: - application/json responses: '200': description: Success schema: - items: - $ref: '#/definitions/SecurityQuestion' - type: array + $ref: '#/definitions/GroupRule' security: - api_token: [] + summary: Get Group Rule tags: - - UserFactor - '/api/v1/users/{userId}/factors/{factorId}': - delete: + - Group + put: consumes: - application/json - description: >- - Unenrolls an existing factor for the specified user, allowing the user - to enroll a new factor. - operationId: deleteFactor + description: Updates a group rule. Only `INACTIVE` rules can be updated. + operationId: updateGroupRule parameters: - in: path - name: userId + name: ruleId required: true type: string - - in: path - name: factorId + - in: body + name: groupRule required: true - type: string + schema: + $ref: '#/definitions/GroupRule' produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/GroupRule' security: - api_token: [] tags: - - UserFactor - get: + - Group + '/api/v1/groups/rules/{ruleId}/lifecycle/activate': + post: consumes: - application/json - description: Fetches a factor for the specified user - operationId: getFactor + description: Activates a specific group rule by id from your organization + operationId: activateGroupRule parameters: - in: path - name: userId - required: true - type: string - - in: path - name: factorId + name: ruleId required: true type: string produces: - application/json responses: - '200': - description: Success - schema: - $ref: '#/definitions/Factor' + '204': + description: No Content security: - api_token: [] + summary: Activate a group Rule tags: - - UserFactor - '/api/v1/users/{userId}/factors/{factorId}/lifecycle/activate': + - Group + '/api/v1/groups/rules/{ruleId}/lifecycle/deactivate': post: consumes: - application/json - description: >- - The `sms` and `token:software:totp` [factor types](#factor-type) require - activation to complete the enrollment process. - operationId: activateFactor + description: Deactivates a specific group rule by id from your organization + operationId: deactivateGroupRule parameters: - in: path - name: userId + name: ruleId required: true type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Deactivate a group Rule + tags: + - Group + '/api/v1/groups/{groupId}': + delete: + consumes: + - application/json + description: Removes a group with `OKTA_GROUP` type from your organization. + operationId: deleteGroup + parameters: - in: path - name: factorId + name: groupId required: true type: string - - in: body - name: body + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Remove Group + tags: + - Group + get: + consumes: + - application/json + description: Lists all group rules for your organization. + operationId: getGroup + parameters: + - in: path + name: groupId required: true - schema: - $ref: '#/definitions/VerifyFactorRequest' + type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/Factor' - type: object + $ref: '#/definitions/Group' security: - api_token: [] - summary: Activate Factor + summary: List Group Rules tags: - - UserFactor - '/api/v1/users/{userId}/factors/{factorId}/verify': - post: + - Group + put: consumes: - application/json - description: 'Verifies an OTP for a `token` or `token:hardware` factor' - operationId: verifyFactor + description: >- + Updates the profile for a group with `OKTA_GROUP` type from your + organization. + operationId: updateGroup parameters: - in: path - name: userId - required: true - type: string - - in: path - name: factorId + name: groupId required: true type: string - - in: query - name: templateId - type: string - - default: 300 - format: int32 - in: query - name: tokenLifetimeSeconds - type: integer - x-okta-added-version: 1.3.0 - in: body - name: body + name: group required: true schema: - $ref: '#/definitions/VerifyFactorRequest' - - in: header - name: X-Forwarded-For - type: string - x-okta-added-version: 1.11.0 - - in: header - name: User-Agent - type: string - x-okta-added-version: 1.11.0 + $ref: '#/definitions/Group' produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/VerifyFactorResponse' + $ref: '#/definitions/Group' security: - api_token: [] - summary: Verify MFA Factor + summary: Update Group tags: - - UserFactor - '/api/v1/users/{userId}/groups': + - Group + '/api/v1/groups/{groupId}/apps': get: consumes: - application/json - description: Fetches the groups of which the user is a member. - operationId: listUserGroups + description: Enumerates all applications that are assigned to a group. + operationId: listAssignedApplicationsForGroup parameters: - in: path - name: userId + name: groupId required: true type: string - - in: query + - description: Specifies the pagination cursor for the next page of apps + in: query name: after type: string - - default: -1 + - default: 20 + description: Specifies the number of app results for a page format: int32 in: query name: limit @@ -2141,125 +2436,107 @@ paths: description: Success schema: items: - $ref: '#/definitions/Group' + $ref: '#/definitions/Application' type: array security: - api_token: [] - summary: Get Member Groups + summary: List Assigned Applications tags: - - User - '/api/v1/users/{userId}/lifecycle/activate': - post: + - Group + '/api/v1/groups/{groupId}/roles': + get: consumes: - application/json - description: >- - Activates a user. This operation can only be performed on users with a - `STAGED` status. Activation of a user is an asynchronous operation. - The user will have the `transitioningToStatus` property with a value of - `ACTIVE` during activation to indicate that the user hasn't completed - the asynchronous operation. The user will have a status of `ACTIVE` - when the activation process is complete. - operationId: activateUser + description: Success + operationId: listGroupAssignedRoles parameters: - in: path - name: userId + name: groupId required: true type: string - - default: true - description: Sends an activation email to the user if true - in: query - name: sendEmail - required: true - type: boolean + - in: query + name: expand + type: string produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/UserActivationToken' + items: + $ref: '#/definitions/Role' + type: array security: - api_token: [] - summary: Activate User tags: - - User - '/api/v1/users/{userId}/lifecycle/deactivate': + - Group post: consumes: - application/json - description: >- - Deactivates a user. This operation can only be performed on users that - do not have a `DEPROVISIONED` status. Deactivation of a user is an - asynchronous operation. The user will have the `transitioningToStatus` - property with a value of `DEPROVISIONED` during deactivation to indicate - that the user hasn't completed the asynchronous operation. The user - will have a status of `DEPROVISIONED` when the deactivation process is - complete. - operationId: deactivateUser + description: Assigns a Role to a Group + operationId: assignRoleToGroup parameters: + - in: body + name: assignRoleRequest + required: true + schema: + $ref: '#/definitions/AssignRoleRequest' - in: path - name: userId + name: groupId required: true type: string - - default: false - in: query - name: sendEmail - type: boolean - x-okta-added-version: 1.5.0 + - in: query + name: disableNotifications + type: string produces: - application/json responses: '200': description: Success + schema: + $ref: '#/definitions/Role' + '201': + description: Success security: - api_token: [] - summary: Deactivate User tags: - - User - '/api/v1/users/{userId}/lifecycle/expire_password': - post: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}': + delete: consumes: - application/json - description: >- - This operation transitions the user to the status of `PASSWORD_EXPIRED` - so that the user is required to change their password at their next - login. - operationId: expirePassword + description: Unassigns a Role from a Group + operationId: removeRoleFromGroup parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId required: true type: string - - default: false - description: 'Sets the user''s password to a temporary password, if true' - in: query - name: tempPassword - type: boolean produces: - application/json responses: - '200': - description: Success - schema: - $ref: '#/definitions/TempPassword' + '204': + description: No Content security: - api_token: [] - summary: Expire Password tags: - - User - '/api/v1/users/{userId}/lifecycle/reset_factors': - post: + - Group + get: consumes: - application/json - description: >- - This operation resets all factors for the specified user. All MFA factor - enrollments returned to the unenrolled state. The user's status remains - ACTIVE. This link is present only if the user is currently enrolled in - one or more MFA factors. - operationId: resetAllFactors + description: Success + operationId: getRole parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId required: true type: string produces: @@ -2267,79 +2544,96 @@ paths: responses: '200': description: Success + schema: + $ref: '#/definitions/Role' security: - api_token: [] - summary: Reset Factors tags: - - User - '/api/v1/users/{userId}/lifecycle/reset_password': - post: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}/targets/catalog/apps': + get: consumes: - application/json description: >- - Generates a one-time token (OTT) that can be used to reset a user's - password. The OTT link can be automatically emailed to the user or - returned to the API caller and distributed using a custom flow. - operationId: resetPassword + Lists all App targets for an `APP_ADMIN` Role assigned to a Group. This + methods return list may include full Applications or Instances. The + response for an instance will have an `ID` value, while Application will + not have an ID. + operationId: listApplicationTargetsForApplicationAdministratorRoleForGroup parameters: - in: path - name: userId + name: groupId required: true type: string - - in: query - name: provider + - in: path + name: roleId + required: true type: string - x-openapi-v3-schema-ref: '#/definitions/AuthenticationProviderType' - in: query - name: sendEmail - type: boolean + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer produces: - application/json responses: '200': description: Success schema: - $ref: '#/definitions/ResetPasswordToken' + items: + $ref: '#/definitions/CatalogApplication' + type: array security: - api_token: [] - summary: Reset Password tags: - - User - '/api/v1/users/{userId}/lifecycle/suspend': - post: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}/targets/catalog/apps/{appName}': + delete: consumes: - application/json - description: >- - Suspends a user. This operation can only be performed on users with an - `ACTIVE` status. The user will have a status of `SUSPENDED` when the - process is complete. - operationId: suspendUser + description: Success + operationId: removeApplicationTargetFromApplicationAdministratorRoleGivenToGroup parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] - summary: Suspend User tags: - - User - '/api/v1/users/{userId}/lifecycle/unlock': - post: + - Group + put: consumes: - application/json - description: >- - Unlocks a user with a `LOCKED_OUT` status and returns them to `ACTIVE` - status. Users will be able to login with their current password. - operationId: unlockUser + description: Success + operationId: addApplicationTargetToAdminRoleGivenToGroup parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName required: true type: string produces: @@ -2349,46 +2643,96 @@ paths: description: Success security: - api_token: [] - summary: Unlock User tags: - - User - '/api/v1/users/{userId}/lifecycle/unsuspend': - post: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}/targets/catalog/apps/{appName}/{applicationId}': + delete: consumes: - application/json - description: >- - Unsuspends a user and returns them to the `ACTIVE` state. This - operation can only be performed on users that have a `SUSPENDED` status. - operationId: unsuspendUser + description: Remove App Instance Target to App Administrator Role given to a Group + operationId: removeApplicationTargetFromAdministratorRoleGivenToGroup parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + - in: path + name: applicationId required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] - summary: Unsuspend User + summary: Remove App Instance Target to App Administrator Role given to a Group tags: - - User - '/api/v1/users/{userId}/roles': + - Group + put: + consumes: + - application/json + description: Add App Instance Target to App Administrator Role given to a Group + operationId: addApplicationInstanceTargetToAppAdminRoleGivenToGroup + parameters: + - in: path + name: groupId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + - in: path + name: applicationId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Add App Instance Target to App Administrator Role given to a Group + tags: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}/targets/groups': get: consumes: - application/json - description: Lists all roles assigned to a user. - operationId: listAssignedRoles + description: Success + operationId: listGroupTargetsForGroupRole parameters: - in: path - name: userId + name: groupId + required: true + type: string + - in: path + name: roleId required: true type: string - in: query - name: expand + name: after type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer produces: - application/json responses: @@ -2396,81 +2740,84 @@ paths: description: Success schema: items: - $ref: '#/definitions/Role' + $ref: '#/definitions/Group' type: array security: - api_token: [] tags: - - User - post: + - Group + '/api/v1/groups/{groupId}/roles/{roleId}/targets/groups/{targetGroupId}': + delete: consumes: - application/json - description: Assigns a role to a user. - operationId: addRoleToUser + description: '' + operationId: removeGroupTargetFromGroupAdministratorRoleGivenToGroup parameters: - - in: body - name: role + - in: path + name: groupId required: true - schema: - $ref: '#/definitions/Role' + type: string - in: path - name: userId + name: roleId + required: true + type: string + - in: path + name: targetGroupId required: true type: string produces: - application/json responses: - '201': - description: Success - schema: - $ref: '#/definitions/Role' + '204': + description: No Content security: - api_token: [] tags: - - User - '/api/v1/users/{userId}/roles/{roleId}': - delete: + - Group + put: consumes: - application/json - description: Unassigns a role from a user. - operationId: removeRoleFromUser + description: '' + operationId: addGroupTargetToGroupAdministratorRoleForGroup parameters: - in: path - name: userId + name: groupId required: true type: string - in: path name: roleId required: true type: string + - in: path + name: targetGroupId + required: true + type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] tags: - - User - '/api/v1/users/{userId}/roles/{roleId}/targets/groups': + - Group + '/api/v1/groups/{groupId}/users': get: consumes: - application/json - description: Success - operationId: listGroupTargetsForRole + description: Enumerates all users that are a member of a group. + operationId: listGroupUsers parameters: - in: path - name: userId - required: true - type: string - - in: path - name: roleId + name: groupId required: true type: string - - in: query + - description: Specifies the pagination cursor for the next page of users + in: query name: after type: string - - default: -1 + - default: 1000 + description: Specifies the number of user results in a page format: int32 in: query name: limit @@ -2482,512 +2829,5307 @@ paths: description: Success schema: items: - $ref: '#/definitions/Group' + $ref: '#/definitions/User' type: array security: - api_token: [] + summary: List Group Members tags: - - User - '/api/v1/users/{userId}/roles/{roleId}/targets/groups/{groupId}': + - Group + '/api/v1/groups/{groupId}/users/{userId}': delete: consumes: - application/json - description: Success - operationId: removeGroupTargetFromRole + description: Removes a user from a group with 'OKTA_GROUP' type. + operationId: removeUserFromGroup parameters: - in: path - name: userId - required: true - type: string - - in: path - name: roleId + name: groupId required: true type: string - in: path - name: groupId + name: userId required: true type: string produces: - application/json responses: - '200': - description: Success + '204': + description: No Content security: - api_token: [] + summary: Remove User from Group tags: - - User + - Group put: consumes: - application/json - description: Success - operationId: addGroupTargetToRole + description: Adds a user to a group with 'OKTA_GROUP' type. + operationId: addUserToGroup parameters: - in: path - name: userId + name: groupId required: true type: string - in: path - name: roleId + name: userId required: true type: string - - in: path - name: groupId - required: true + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Add User to Group + tags: + - Group + /api/v1/idps: + get: + consumes: + - application/json + description: >- + Enumerates IdPs in your organization with pagination. A subset of IdPs + can be returned that match a supported filter expression or query. + operationId: listIdentityProviders + parameters: + - description: Searches the name property of IdPs for matching value + in: query + name: q + type: string + - description: Specifies the pagination cursor for the next page of IdPs + in: query + name: after + type: string + - default: 20 + description: Specifies the number of IdP results in a page + format: int32 + in: query + name: limit + type: integer + - description: Filters IdPs by type + in: query + name: type type: string produces: - application/json responses: '200': description: Success + schema: + items: + $ref: '#/definitions/IdentityProvider' + type: array security: - api_token: [] + summary: List Identity Providers tags: - - User - '/api/v1/users/{userId}/sessions': - delete: + - IdentityProvider + post: consumes: - application/json - description: >- - Removes all active identity provider sessions. This forces the user to - authenticate on the next operation. Optionally revokes OpenID Connect - and OAuth refresh and access tokens issued to the user. - operationId: endAllUserSessions + description: Adds a new IdP to your organization. + operationId: createIdentityProvider parameters: - - in: path - name: userId + - in: body + name: identityProvider required: true + schema: + $ref: '#/definitions/IdentityProvider' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProvider' + security: + - api_token: [] + summary: Add Identity Provider + tags: + - IdentityProvider + /api/v1/idps/credentials/keys: + get: + consumes: + - application/json + description: Enumerates IdP key credentials. + operationId: listIdentityProviderKeys + parameters: + - description: Specifies the pagination cursor for the next page of keys + in: query + name: after type: string - - default: false - description: Revoke issued OpenID Connect and OAuth refresh and access tokens + - default: 20 + description: Specifies the number of key results in a page + format: int32 in: query - name: oauthTokens - type: boolean + name: limit + type: integer produces: - application/json responses: '200': description: Success + schema: + items: + $ref: '#/definitions/JsonWebKey' + type: array security: - api_token: [] + summary: List Keys tags: - - User -definitions: - AppLink: - properties: - appAssignmentId: - readOnly: true - type: string - appInstanceId: - readOnly: true - type: string - appName: - readOnly: true - type: string - credentialsSetup: - readOnly: true - type: boolean - hidden: + - IdentityProvider + post: + consumes: + - application/json + description: Adds a new X.509 certificate credential to the IdP key store. + operationId: createIdentityProviderKey + parameters: + - in: body + name: jsonWebKey + required: true + schema: + $ref: '#/definitions/JsonWebKey' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + summary: Add X.509 Certificate Public Key + tags: + - IdentityProvider + '/api/v1/idps/credentials/keys/{keyId}': + delete: + consumes: + - application/json + description: >- + Deletes a specific IdP Key Credential by `kid` if it is not currently + being used by an Active or Inactive IdP. + operationId: deleteIdentityProviderKey + parameters: + - in: path + name: keyId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Delete Key + tags: + - IdentityProvider + get: + consumes: + - application/json + description: Gets a specific IdP Key Credential by `kid` + operationId: getIdentityProviderKey + parameters: + - in: path + name: keyId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + summary: Get Key + tags: + - IdentityProvider + '/api/v1/idps/{idpId}': + delete: + consumes: + - application/json + description: Removes an IdP from your organization. + operationId: deleteIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Delete Identity Provider + tags: + - IdentityProvider + get: + consumes: + - application/json + description: Fetches an IdP by `id`. + operationId: getIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProvider' + security: + - api_token: [] + summary: Get Identity Provider + tags: + - IdentityProvider + put: + consumes: + - application/json + description: Updates the configuration for an IdP. + operationId: updateIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: body + name: identityProvider + required: true + schema: + $ref: '#/definitions/IdentityProvider' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProvider' + security: + - api_token: [] + summary: Update Identity Provider + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/csrs': + get: + consumes: + - application/json + description: Enumerates Certificate Signing Requests for an IdP + operationId: listCsrsForIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Csr' + type: array + security: + - api_token: [] + summary: List Certificate Signing Requests for IdP + tags: + - IdentityProvider + post: + consumes: + - application/json + description: >- + Generates a new key pair and returns a Certificate Signing Request for + it. + operationId: generateCsrForIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: body + name: metadata + required: true + schema: + $ref: '#/definitions/CsrMetadata' + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/Csr' + security: + - api_token: [] + summary: Generate Certificate Signing Request for IdP + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/csrs/{csrId}': + delete: + consumes: + - application/json + description: Revoke a Certificate Signing Request and delete the key pair from the IdP + operationId: revokeCsrForIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - IdentityProvider + get: + consumes: + - application/json + description: Gets a specific Certificate Signing Request model by id + operationId: getCsrForIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Csr' + security: + - api_token: [] + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/csrs/{csrId}/lifecycle/publish': + post: + consumes: + - application/json + description: >- + Update the Certificate Signing Request with a signed X.509 certificate and add it into the + signing key credentials for the IdP. + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: csrId + required: true + type: string + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + tags: + - IdentityProvider + x-okta-multi-operation: + - consumes: + - application/x-x509-ca-cert + encoding: base64 + operationId: publishCerCertForIdentityProvider + parameters: + - in: body + name: certificate + required: true + type: string + - consumes: + - application/x-x509-ca-cert + operationId: publishBinaryCerCertForIdentityProvider + parameters: + - format: binary + in: body + name: certificate + required: true + type: string + - consumes: + - application/pkix-cert + encoding: base64 + operationId: publishDerCertForIdentityProvider + parameters: + - in: body + name: certificate + required: true + type: string + - consumes: + - application/pkix-cert + operationId: publishBinaryDerCertForIdentityProvider + parameters: + - format: binary + in: body + name: certificate + required: true + type: string + - consumes: + - application/x-pem-file + operationId: publishBinaryPemCertForIdentityProvider + parameters: + - format: binary + in: body + name: certificate + required: true + type: string + '/api/v1/idps/{idpId}/credentials/keys': + get: + consumes: + - application/json + description: Enumerates signing key credentials for an IdP + operationId: listIdentityProviderSigningKeys + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/JsonWebKey' + type: array + security: + - api_token: [] + summary: List Signing Key Credentials for IdP + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/keys/generate': + post: + consumes: + - application/json + description: >- + Generates a new X.509 certificate for an IdP signing key credential to + be used for signing assertions sent to the IdP + operationId: generateIdentityProviderSigningKey + parameters: + - in: path + name: idpId + required: true + type: string + - description: expiry of the IdP Key Credential + format: int32 + in: query + name: validityYears + required: true + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + summary: Generate New IdP Signing Key Credential + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/keys/{keyId}': + get: + consumes: + - application/json + description: Gets a specific IdP Key Credential by `kid` + operationId: getIdentityProviderSigningKey + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: keyId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + summary: Get Signing Key Credential for IdP + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/credentials/keys/{keyId}/clone': + post: + consumes: + - application/json + description: >- + Clones a X.509 certificate for an IdP signing key credential from a + source IdP to target IdP + operationId: cloneIdentityProviderKey + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: keyId + required: true + type: string + - in: query + name: targetIdpId + required: true + type: string + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/JsonWebKey' + security: + - api_token: [] + summary: Clone Signing Key Credential for IdP + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/lifecycle/activate': + post: + consumes: + - application/json + description: Activates an inactive IdP. + operationId: activateIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProvider' + security: + - api_token: [] + summary: Activate Identity Provider + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: Deactivates an active IdP. + operationId: deactivateIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProvider' + security: + - api_token: [] + summary: Deactivate Identity Provider + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/users': + get: + consumes: + - application/json + description: Find all the users linked to an identity provider + operationId: listIdentityProviderApplicationUsers + parameters: + - in: path + name: idpId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/IdentityProviderApplicationUser' + type: array + security: + - api_token: [] + summary: Find Users + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/users/{userId}': + delete: + consumes: + - application/json + description: Removes the link between the Okta user and the IdP user. + operationId: unlinkUserFromIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Unlink User from IdP + tags: + - IdentityProvider + get: + consumes: + - application/json + description: Fetches a linked IdP user by ID + operationId: getIdentityProviderApplicationUser + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProviderApplicationUser' + security: + - api_token: [] + tags: + - IdentityProvider + post: + consumes: + - application/json + description: >- + Links an Okta user to an existing Social Identity Provider. This does + not support the SAML2 Identity Provider Type + operationId: linkUserToIdentityProvider + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: userId + required: true + type: string + - in: body + name: userIdentityProviderLinkRequest + required: true + schema: + $ref: '#/definitions/UserIdentityProviderLinkRequest' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/IdentityProviderApplicationUser' + security: + - api_token: [] + summary: Link a user to a Social IdP without a transaction + tags: + - IdentityProvider + '/api/v1/idps/{idpId}/users/{userId}/credentials/tokens': + get: + consumes: + - application/json + description: >- + Fetches the tokens minted by the Social Authentication Provider when the + user authenticates with Okta via Social Auth. + operationId: listSocialAuthTokens + parameters: + - in: path + name: idpId + required: true + type: string + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/SocialAuthToken' + type: array + security: + - api_token: [] + summary: Social Authentication Token Operation + tags: + - IdentityProvider + /api/v1/inlineHooks: + get: + consumes: + - application/json + description: Success + operationId: listInlineHooks + parameters: + - in: query + name: type + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/InlineHook' + type: array + security: + - api_token: [] + tags: + - InlineHook + post: + consumes: + - application/json + description: Success + operationId: createInlineHook + parameters: + - in: body + name: inlineHook + required: true + schema: + $ref: '#/definitions/InlineHook' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHook' + security: + - api_token: [] + tags: + - InlineHook + '/api/v1/inlineHooks/{inlineHookId}': + delete: + consumes: + - application/json + description: >- + Deletes the Inline Hook matching the provided id. Once deleted, the + Inline Hook is unrecoverable. As a safety precaution, only Inline Hooks + with a status of INACTIVE are eligible for deletion. + operationId: deleteInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - InlineHook + get: + consumes: + - application/json + description: Gets an inline hook by ID + operationId: getInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHook' + security: + - api_token: [] + tags: + - InlineHook + put: + consumes: + - application/json + description: Updates an inline hook by ID + operationId: updateInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + - in: body + name: inlineHook + required: true + schema: + $ref: '#/definitions/InlineHook' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHook' + security: + - api_token: [] + tags: + - InlineHook + '/api/v1/inlineHooks/{inlineHookId}/execute': + post: + consumes: + - application/json + description: >- + Executes the Inline Hook matching the provided inlineHookId using the + request body as the input. This will send the provided data through the + Channel and return a response if it matches the correct data contract. + This execution endpoint should only be used for testing purposes. + operationId: executeInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + - in: body + name: payloadData + required: true + schema: + $ref: '#/definitions/InlineHookPayload' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHookResponse' + security: + - api_token: [] + tags: + - InlineHook + '/api/v1/inlineHooks/{inlineHookId}/lifecycle/activate': + post: + consumes: + - application/json + description: Activates the Inline Hook matching the provided id + operationId: activateInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHook' + security: + - api_token: [] + tags: + - InlineHook + '/api/v1/inlineHooks/{inlineHookId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: Deactivates the Inline Hook matching the provided id + operationId: deactivateInlineHook + parameters: + - in: path + name: inlineHookId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/InlineHook' + security: + - api_token: [] + tags: + - InlineHook + /api/v1/logs: + get: + consumes: + - application/json + description: >- + The Okta System Log API provides read access to your organization’s + system log. This API provides more functionality than the Events API + operationId: getLogs + parameters: + - in: query + name: since + type: string + format: date-time + - in: query + name: until + type: string + format: date-time + - in: query + name: filter + type: string + - in: query + name: q + type: string + - default: 100 + in: query + name: limit + type: integer + - default: ASCENDING + in: query + name: sortOrder + type: string + - in: query + name: after + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/LogEvent' + type: array + security: + - api_token: [] + summary: Fetch a list of events from your Okta organization system log. + tags: + - Log + /api/v1/meta/schemas/user/linkedObjects: + get: + consumes: + - application/json + description: Success + operationId: listLinkedObjectDefinitions + parameters: [] + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/LinkedObject' + type: array + security: + - api_token: [] + tags: + - LinkedObject + post: + consumes: + - application/json + description: Success + operationId: addLinkedObjectDefinition + parameters: + - in: body + name: linkedObject + required: true + schema: + $ref: '#/definitions/LinkedObject' + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/LinkedObject' + security: + - api_token: [] + tags: + - LinkedObject + '/api/v1/meta/schemas/user/linkedObjects/{linkedObjectName}': + delete: + consumes: + - application/json + description: Success + operationId: deleteLinkedObjectDefinition + parameters: + - in: path + name: linkedObjectName + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - LinkedObject + get: + consumes: + - application/json + description: Success + operationId: getLinkedObjectDefinition + parameters: + - in: path + name: linkedObjectName + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/LinkedObject' + security: + - api_token: [] + tags: + - LinkedObject + /api/v1/meta/types/user: + get: + consumes: + - application/json + description: Fetches all User Types in your org + operationId: listUserTypes + parameters: [] + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/UserType' + type: array + security: + - api_token: [] + tags: + - UserType + post: + consumes: + - application/json + description: >- + Creates a new User Type. A default User Type is automatically created + along with your org, and you may add another 9 User Types for a maximum + of 10. + operationId: createUserType + parameters: + - in: body + name: userType + required: true + schema: + $ref: '#/definitions/UserType' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserType' + security: + - api_token: [] + tags: + - UserType + '/api/v1/meta/types/user/{typeId}': + delete: + consumes: + - application/json + description: >- + Deletes a User Type permanently. This operation is not permitted for the + default type, nor for any User Type that has existing users + operationId: deleteUserType + parameters: + - in: path + name: typeId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - UserType + get: + consumes: + - application/json + description: >- + Fetches a User Type by ID. The special identifier `default` may be used + to fetch the default User Type. + operationId: getUserType + parameters: + - in: path + name: typeId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserType' + security: + - api_token: [] + tags: + - UserType + post: + consumes: + - application/json + description: Updates an existing User Type + operationId: updateUserType + parameters: + - in: path + name: typeId + required: true + type: string + - in: body + name: userType + required: true + schema: + $ref: '#/definitions/UserType' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserType' + security: + - api_token: [] + tags: + - UserType + put: + consumes: + - application/json + description: Replace an existing User Type + operationId: replaceUserType + parameters: + - in: path + name: typeId + required: true + type: string + - in: body + name: userType + required: true + schema: + $ref: '#/definitions/UserType' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserType' + security: + - api_token: [] + tags: + - UserType + /api/v1/policies: + get: + consumes: + - application/json + description: Gets all policies with the specified type. + operationId: listPolicies + parameters: + - in: query + name: type + required: true + type: string + - in: query + name: status + type: string + - default: '' + in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Policy' + type: array + security: + - api_token: [] + tags: + - Policy + post: + consumes: + - application/json + description: Creates a policy. + operationId: createPolicy + parameters: + - in: body + name: policy + required: true + schema: + $ref: '#/definitions/Policy' + - default: true + in: query + name: activate + type: boolean + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Policy' + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}': + delete: + consumes: + - application/json + description: Removes a policy. + operationId: deletePolicy + parameters: + - in: path + name: policyId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - Policy + get: + consumes: + - application/json + description: Gets a policy. + operationId: getPolicy + parameters: + - in: path + name: policyId + required: true + type: string + - default: '' + in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Policy' + security: + - api_token: [] + tags: + - Policy + put: + consumes: + - application/json + description: Updates a policy. + operationId: updatePolicy + parameters: + - in: body + name: policy + required: true + schema: + $ref: '#/definitions/Policy' + - in: path + name: policyId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Policy' + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/lifecycle/activate': + post: + consumes: + - application/json + description: Activates a policy. + operationId: activatePolicy + parameters: + - in: path + name: policyId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: Deactivates a policy. + operationId: deactivatePolicy + parameters: + - in: path + name: policyId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/rules': + get: + consumes: + - application/json + description: Enumerates all policy rules. + operationId: listPolicyRules + parameters: + - in: path + name: policyId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/PolicyRule' + type: array + security: + - api_token: [] + tags: + - Policy + post: + consumes: + - application/json + description: Creates a policy rule. + operationId: createPolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: body + name: policyRule + required: true + schema: + $ref: '#/definitions/PolicyRule' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/PolicyRule' + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/rules/{ruleId}': + delete: + consumes: + - application/json + description: Removes a policy rule. + operationId: deletePolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: path + name: ruleId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Policy + get: + consumes: + - application/json + description: Gets a policy rule. + operationId: getPolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: path + name: ruleId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/PolicyRule' + security: + - api_token: [] + tags: + - Policy + put: + consumes: + - application/json + description: Updates a policy rule. + operationId: updatePolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: path + name: ruleId + required: true + type: string + - in: body + name: policyRule + required: true + schema: + $ref: '#/definitions/PolicyRule' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/PolicyRule' + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/rules/{ruleId}/lifecycle/activate': + post: + consumes: + - application/json + description: Activates a policy rule. + operationId: activatePolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: path + name: ruleId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - Policy + '/api/v1/policies/{policyId}/rules/{ruleId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: Deactivates a policy rule. + operationId: deactivatePolicyRule + parameters: + - in: path + name: policyId + required: true + type: string + - in: path + name: ruleId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - Policy + /api/v1/sessions: + post: + consumes: + - application/json + description: >- + Creates a new session for a user with a valid session token. Use this + API if, for example, you want to set the session cookie yourself instead + of allowing Okta to set it, or want to hold the session ID in order to + delete a session via the API instead of visiting the logout URL. + operationId: createSession + parameters: + - in: body + name: createSessionRequest + required: true + schema: + $ref: '#/definitions/CreateSessionRequest' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Session' + security: + - api_token: [] + summary: Create Session with Session Token + tags: + - Session + '/api/v1/sessions/{sessionId}': + delete: + consumes: + - application/json + description: '' + operationId: endSession + parameters: + - in: path + name: sessionId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Close Session + tags: + - Session + get: + consumes: + - application/json + description: Get details about a session. + operationId: getSession + parameters: + - in: path + name: sessionId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Session' + security: + - api_token: [] + tags: + - Session + '/api/v1/sessions/{sessionId}/lifecycle/refresh': + post: + consumes: + - application/json + description: '' + operationId: refreshSession + parameters: + - in: path + name: sessionId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/Session' + security: + - api_token: [] + summary: Refresh Session + tags: + - Session + /api/v1/templates/sms: + get: + consumes: + - application/json + description: >- + Enumerates custom SMS templates in your organization. A subset of + templates can be returned that match a template type. + operationId: listSmsTemplates + parameters: + - in: query + name: templateType + type: string + x-openapi-v3-schema-ref: '#/definitions/SmsTemplateType' + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/SmsTemplate' + type: array + security: + - api_token: [] + summary: List SMS Templates + tags: + - Template + post: + consumes: + - application/json + description: Adds a new custom SMS template to your organization. + operationId: createSmsTemplate + parameters: + - in: body + name: smsTemplate + required: true + schema: + $ref: '#/definitions/SmsTemplate' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/SmsTemplate' + security: + - api_token: [] + summary: Add SMS Template + tags: + - Template + '/api/v1/templates/sms/{templateId}': + delete: + consumes: + - application/json + description: Removes an SMS template. + operationId: deleteSmsTemplate + parameters: + - in: path + name: templateId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Remove SMS Template + tags: + - Template + get: + consumes: + - application/json + description: Fetches a specific template by `id` + operationId: getSmsTemplate + parameters: + - in: path + name: templateId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/SmsTemplate' + security: + - api_token: [] + summary: Get SMS Template + tags: + - Template + post: + consumes: + - application/json + description: 'Updates only some of the SMS template properties:' + operationId: partialUpdateSmsTemplate + parameters: + - in: path + name: templateId + required: true + type: string + - in: body + name: smsTemplate + required: true + schema: + $ref: '#/definitions/SmsTemplate' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/SmsTemplate' + security: + - api_token: [] + summary: Partial SMS Template Update + tags: + - Template + put: + consumes: + - application/json + description: Updates the SMS template. + operationId: updateSmsTemplate + parameters: + - in: path + name: templateId + required: true + type: string + - in: body + name: smsTemplate + required: true + schema: + $ref: '#/definitions/SmsTemplate' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/SmsTemplate' + security: + - api_token: [] + summary: Update SMS Template + tags: + - Template + /api/v1/trustedOrigins: + get: + consumes: + - application/json + description: Success + operationId: listOrigins + parameters: + - in: query + name: q + type: string + - in: query + name: filter + type: string + - in: query + name: after + type: string + - default: -1 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/TrustedOrigin' + type: array + security: + - api_token: [] + tags: + - TrustedOrigin + post: + consumes: + - application/json + description: Success + operationId: createOrigin + parameters: + - in: body + name: trustedOrigin + required: true + schema: + $ref: '#/definitions/TrustedOrigin' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TrustedOrigin' + security: + - api_token: [] + tags: + - TrustedOrigin + '/api/v1/trustedOrigins/{trustedOriginId}': + delete: + consumes: + - application/json + description: Success + operationId: deleteOrigin + parameters: + - in: path + name: trustedOriginId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - TrustedOrigin + get: + consumes: + - application/json + description: Success + operationId: getOrigin + parameters: + - in: path + name: trustedOriginId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TrustedOrigin' + security: + - api_token: [] + tags: + - TrustedOrigin + put: + consumes: + - application/json + description: Success + operationId: updateOrigin + parameters: + - in: path + name: trustedOriginId + required: true + type: string + - in: body + name: trustedOrigin + required: true + schema: + $ref: '#/definitions/TrustedOrigin' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TrustedOrigin' + security: + - api_token: [] + tags: + - TrustedOrigin + '/api/v1/trustedOrigins/{trustedOriginId}/lifecycle/activate': + post: + consumes: + - application/json + description: Success + operationId: activateOrigin + parameters: + - in: path + name: trustedOriginId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TrustedOrigin' + security: + - api_token: [] + tags: + - TrustedOrigin + '/api/v1/trustedOrigins/{trustedOriginId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: Success + operationId: deactivateOrigin + parameters: + - in: path + name: trustedOriginId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TrustedOrigin' + security: + - api_token: [] + tags: + - TrustedOrigin + /api/v1/users: + get: + consumes: + - application/json + description: >- + Lists users in your organization with pagination in most cases. A + subset of users can be returned that match a supported filter expression + or search criteria. + operationId: listUsers + parameters: + - description: 'Finds a user that matches firstName, lastName, and email properties' + in: query + name: q + type: string + - description: Specifies the pagination cursor for the next page of users + in: query + name: after + type: string + - default: 10 + description: Specifies the number of results returned + format: int32 + in: query + name: limit + type: integer + - description: Filters users with a supported expression for a subset of properties + in: query + name: filter + type: string + - description: >- + Searches for users with a supported filtering expression for most + properties + in: query + name: search + type: string + - in: query + name: sortBy + type: string + - in: query + name: sortOrder + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/User' + type: array + security: + - api_token: [] + summary: List Users + tags: + - User + post: + consumes: + - application/json + description: >- + Creates a new user in your Okta organization with or without + credentials. + operationId: createUser + parameters: + - in: body + name: body + required: true + schema: + $ref: '#/definitions/User' + - default: true + description: Executes activation lifecycle operation when creating the user + in: query + name: activate + type: boolean + - default: false + description: >- + Indicates whether to create a user with a specified authentication + provider + in: query + name: provider + type: boolean + - default: '' + description: >- + With activate=true, set nextLogin to "changePassword" to have the + password be EXPIRED, so user must change it the next time they log + in. + in: query + name: nextLogin + type: string + x-okta-added-version: 0.14.0 + x-openapi-v3-schema-ref: '#/definitions/UserNextLogin' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/User' + security: + - api_token: [] + summary: Create User + tags: + - User + '/api/v1/users/{associatedUserId}/linkedObjects/{primaryRelationshipName}/{primaryUserId}': + put: + consumes: + - application/json + operationId: setLinkedObjectForUser + parameters: + - in: path + name: associatedUserId + required: true + type: string + - in: path + name: primaryRelationshipName + required: true + type: string + - in: path + name: primaryUserId + required: true + type: string + produces: + - application/json + responses: + '204': + description: Success + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}': + delete: + consumes: + - application/json + description: >- + Deletes a user permanently. This operation can only be performed on + users that have a `DEPROVISIONED` status. **This action cannot be + recovered!** + operationId: deactivateOrDeleteUser + parameters: + - in: path + name: userId + required: true + type: string + - default: false + in: query + name: sendEmail + type: boolean + x-okta-added-version: 1.5.0 + produces: + - application/json + responses: + '202': + description: ACCEPTED + security: + - api_token: [] + summary: Delete User + tags: + - User + get: + consumes: + - application/json + description: Fetches a user from your Okta organization. + operationId: getUser + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/User' + security: + - api_token: [] + summary: Get User + tags: + - User + post: + consumes: + - application/json + description: >- + Fetch a user by `id`, `login`, or `login shortname` if the short name is + unambiguous. + operationId: partialUpdateUser + parameters: + - in: body + name: user + required: true + schema: + $ref: '#/definitions/User' + - in: path + name: userId + required: true + type: string + - in: query + name: strict + type: boolean + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/User' + security: + - api_token: [] + tags: + - User + put: + consumes: + - application/json + description: >- + Update a user's profile and/or credentials using strict-update + semantics. + operationId: updateUser + parameters: + - in: body + name: user + required: true + schema: + $ref: '#/definitions/User' + - in: path + name: userId + required: true + type: string + - in: query + name: strict + type: boolean + x-okta-added-version: 1.10.0 + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/User' + security: + - api_token: [] + summary: Update User + tags: + - User + '/api/v1/users/{userId}/appLinks': + get: + consumes: + - application/json + description: >- + Fetches appLinks for all direct or indirect (via group membership) + assigned applications. + operationId: listAppLinks + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/AppLink' + type: array + security: + - api_token: [] + summary: Get Assigned App Links + tags: + - User + '/api/v1/users/{userId}/clients': + get: + consumes: + - application/json + description: >- + Lists all client resources for which the specified user has grants or + tokens. + operationId: listUserClients + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/OAuth2Client' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/clients/{clientId}/grants': + delete: + consumes: + - application/json + description: Revokes all grants for the specified user and client + operationId: revokeGrantsForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: Lists all grants for a specified user and client + operationId: listGrantsForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + - in: query + name: expand + type: string + - in: query + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/clients/{clientId}/tokens': + delete: + consumes: + - application/json + description: Revokes all refresh tokens issued for the specified User and Client. + operationId: revokeTokensForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: Lists all refresh tokens issued for the specified User and Client. + operationId: listRefreshTokensForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + - in: query + name: expand + type: string + - in: query + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/OAuth2RefreshToken' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/clients/{clientId}/tokens/{tokenId}': + delete: + consumes: + - application/json + description: Revokes the specified refresh token. + operationId: revokeTokenForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + - in: path + name: tokenId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: Gets a refresh token issued for the specified User and Client. + operationId: getRefreshTokenForUserAndClient + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: clientId + required: true + type: string + - in: path + name: tokenId + required: true + type: string + - in: query + name: expand + type: string + - default: 20 + in: query + name: limit + type: integer + - in: query + name: after + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/OAuth2RefreshToken' + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/credentials/change_password': + post: + consumes: + - application/json + description: >- + Changes a user's password by validating the user's current password. + This operation can only be performed on users in `STAGED`, `ACTIVE`, + `PASSWORD_EXPIRED`, or `RECOVERY` status that have a valid password + credential + operationId: changePassword + parameters: + - in: body + name: changePasswordRequest + required: true + schema: + $ref: '#/definitions/ChangePasswordRequest' + - in: path + name: userId + required: true + type: string + - in: query + name: strict + type: boolean + x-okta-added-version: 1.10.0 + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserCredentials' + security: + - api_token: [] + summary: Change Password + tags: + - User + '/api/v1/users/{userId}/credentials/change_recovery_question': + post: + consumes: + - application/json + description: >- + Changes a user's recovery question & answer credential by validating the + user's current password. This operation can only be performed on users + in **STAGED**, **ACTIVE** or **RECOVERY** `status` that have a valid + password credential + operationId: changeRecoveryQuestion + parameters: + - in: body + name: userCredentials + required: true + schema: + $ref: '#/definitions/UserCredentials' + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserCredentials' + security: + - api_token: [] + summary: Change Recovery Question + tags: + - User + '/api/v1/users/{userId}/credentials/forgot_password': + post: + consumes: + - application/json + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/ForgotPasswordResponse' + security: + - api_token: [] + summary: Forgot Password + tags: + - User + x-okta-multi-operation: + - description: >- + Generates a one-time token (OTT) that can be used to reset a user's + password + operationId: forgotPasswordGenerateOneTimeToken + parameters: + - default: true + in: query + name: sendEmail + type: boolean + - description: >- + Sets a new password for a user by validating the user's answer to + their current recovery question + operationId: forgotPasswordSetNewPassword + parameters: + - in: body + name: user + required: true + schema: + $ref: '#/definitions/UserCredentials' + - default: true + in: query + name: sendEmail + type: boolean + '/api/v1/users/{userId}/factors': + get: + consumes: + - application/json + description: Enumerates all the enrolled factors for the specified user + operationId: listFactors + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/UserFactor' + type: array + security: + - api_token: [] + tags: + - UserFactor + post: + consumes: + - application/json + description: Enrolls a user with a supported factor. + operationId: enrollFactor + parameters: + - in: path + name: userId + required: true + type: string + - description: Factor + in: body + name: body + required: true + schema: + $ref: '#/definitions/UserFactor' + - default: false + in: query + name: updatePhone + type: boolean + - description: id of SMS template (only for SMS factor) + in: query + name: templateId + type: string + - default: 300 + format: int32 + in: query + name: tokenLifetimeSeconds + type: integer + x-okta-added-version: 1.3.0 + - default: false + in: query + name: activate + type: boolean + x-okta-added-version: 1.3.0 + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserFactor' + security: + - api_token: [] + summary: Enroll Factor + tags: + - UserFactor + '/api/v1/users/{userId}/factors/catalog': + get: + consumes: + - application/json + description: >- + Enumerates all the supported factors that can be enrolled for the + specified user + operationId: listSupportedFactors + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/UserFactor' + type: array + security: + - api_token: [] + tags: + - UserFactor + '/api/v1/users/{userId}/factors/questions': + get: + consumes: + - application/json + description: >- + Enumerates all available security questions for a user's `question` + factor + operationId: listSupportedSecurityQuestions + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/SecurityQuestion' + type: array + security: + - api_token: [] + tags: + - UserFactor + '/api/v1/users/{userId}/factors/{factorId}': + delete: + consumes: + - application/json + description: >- + Unenrolls an existing factor for the specified user, allowing the user + to enroll a new factor. + operationId: deleteFactor + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: factorId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - UserFactor + get: + consumes: + - application/json + description: Fetches a factor for the specified user + operationId: getFactor + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: factorId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserFactor' + security: + - api_token: [] + tags: + - UserFactor + '/api/v1/users/{userId}/factors/{factorId}/lifecycle/activate': + post: + consumes: + - application/json + description: >- + The `sms` and `token:software:totp` factor types require activation to + complete the enrollment process. + operationId: activateFactor + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: factorId + required: true + type: string + - in: body + name: body + schema: + $ref: '#/definitions/ActivateFactorRequest' + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserFactor' + security: + - api_token: [] + summary: Activate Factor + tags: + - UserFactor + '/api/v1/users/{userId}/factors/{factorId}/transactions/{transactionId}': + get: + consumes: + - application/json + description: Polls factors verification transaction for status. + operationId: getFactorTransactionStatus + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: factorId + required: true + type: string + - in: path + name: transactionId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/VerifyUserFactorResponse' + security: + - api_token: [] + tags: + - UserFactor + '/api/v1/users/{userId}/factors/{factorId}/verify': + post: + consumes: + - application/json + description: 'Verifies an OTP for a `token` or `token:hardware` factor' + operationId: verifyFactor + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: factorId + required: true + type: string + - in: query + name: templateId + type: string + - default: 300 + format: int32 + in: query + name: tokenLifetimeSeconds + type: integer + x-okta-added-version: 1.3.0 + - in: body + name: body + schema: + $ref: '#/definitions/VerifyFactorRequest' + - in: header + name: X-Forwarded-For + type: string + x-okta-added-version: 1.11.0 + - in: header + name: User-Agent + type: string + x-okta-added-version: 1.11.0 + - in: header + name: Accept-Language + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/VerifyUserFactorResponse' + security: + - api_token: [] + summary: Verify MFA Factor + tags: + - UserFactor + '/api/v1/users/{userId}/grants': + delete: + consumes: + - application/json + description: Revokes all grants for a specified user + operationId: revokeUserGrants + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: Lists all grants for the specified user + operationId: listUserGrants + parameters: + - in: path + name: userId + required: true + type: string + - in: query + name: scopeId + type: string + - in: query + name: expand + type: string + - in: query + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/grants/{grantId}': + delete: + consumes: + - application/json + description: Revokes one grant for a specified user + operationId: revokeUserGrant + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: grantId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: Gets a grant for the specified user + operationId: getUserGrant + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: grantId + required: true + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/OAuth2ScopeConsentGrant' + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/groups': + get: + consumes: + - application/json + description: Fetches the groups of which the user is a member. + operationId: listUserGroups + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Group' + type: array + security: + - api_token: [] + summary: Get Member Groups + tags: + - User + '/api/v1/users/{userId}/idps': + get: + consumes: + - application/json + description: Lists the IdPs associated with the user. + operationId: listUserIdentityProviders + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/IdentityProvider' + type: array + security: + - api_token: [] + summary: Listing IdPs associated with a user + tags: + - User + '/api/v1/users/{userId}/lifecycle/activate': + post: + consumes: + - application/json + description: >- + Activates a user. This operation can only be performed on users with a + `STAGED` status. Activation of a user is an asynchronous operation. + The user will have the `transitioningToStatus` property with a value of + `ACTIVE` during activation to indicate that the user hasn't completed + the asynchronous operation. The user will have a status of `ACTIVE` + when the activation process is complete. + operationId: activateUser + parameters: + - in: path + name: userId + required: true + type: string + - default: true + description: Sends an activation email to the user if true + in: query + name: sendEmail + required: true + type: boolean + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserActivationToken' + security: + - api_token: [] + summary: Activate User + tags: + - User + '/api/v1/users/{userId}/lifecycle/deactivate': + post: + consumes: + - application/json + description: >- + Deactivates a user. This operation can only be performed on users that + do not have a `DEPROVISIONED` status. Deactivation of a user is an + asynchronous operation. The user will have the `transitioningToStatus` + property with a value of `DEPROVISIONED` during deactivation to indicate + that the user hasn't completed the asynchronous operation. The user + will have a status of `DEPROVISIONED` when the deactivation process is + complete. + operationId: deactivateUser + parameters: + - in: path + name: userId + required: true + type: string + - default: false + in: query + name: sendEmail + type: boolean + x-okta-added-version: 1.5.0 + produces: + - application/json + responses: + '200': + description: OK + security: + - api_token: [] + summary: Deactivate User + tags: + - User + '/api/v1/users/{userId}/lifecycle/expire_password?tempPassword=false': + post: + consumes: + - application/json + description: >- + This operation transitions the user to the status of `PASSWORD_EXPIRED` + so that the user is required to change their password at their next + login. + operationId: expirePassword + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/User' + security: + - api_token: [] + summary: Expire Password + tags: + - User + '/api/v1/users/{userId}/lifecycle/expire_password?tempPassword=true': + post: + consumes: + - application/json + description: >- + This operation transitions the user to the status of `PASSWORD_EXPIRED` + and the user's password is reset to a temporary password that is + returned. + operationId: expirePasswordAndGetTemporaryPassword + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/TempPassword' + security: + - api_token: [] + summary: Expire Password + tags: + - User + '/api/v1/users/{userId}/lifecycle/reactivate': + post: + consumes: + - application/json + description: >- + Reactivates a user. This operation can only be performed on users with + a `PROVISIONED` status. This operation restarts the activation workflow + if for some reason the user activation was not completed when using the + activationToken from [Activate User](#activate-user). + operationId: reactivateUser + parameters: + - in: path + name: userId + required: true + type: string + - default: false + description: Sends an activation email to the user if true + in: query + name: sendEmail + type: boolean + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/UserActivationToken' + security: + - api_token: [] + summary: Reactivate User + tags: + - User + '/api/v1/users/{userId}/lifecycle/reset_factors': + post: + consumes: + - application/json + description: >- + This operation resets all factors for the specified user. All MFA factor + enrollments returned to the unenrolled state. The user's status remains + ACTIVE. This link is present only if the user is currently enrolled in + one or more MFA factors. + operationId: resetFactors + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: OK + security: + - api_token: [] + summary: Reset Factors + tags: + - User + '/api/v1/users/{userId}/lifecycle/reset_password': + post: + consumes: + - application/json + description: >- + Generates a one-time token (OTT) that can be used to reset a user's + password. The OTT link can be automatically emailed to the user or + returned to the API caller and distributed using a custom flow. + operationId: resetPassword + parameters: + - in: path + name: userId + required: true + type: string + - in: query + name: sendEmail + required: true + type: boolean + produces: + - application/json + responses: + '200': + description: Success + schema: + $ref: '#/definitions/ResetPasswordToken' + security: + - api_token: [] + summary: Reset Password + tags: + - User + '/api/v1/users/{userId}/lifecycle/suspend': + post: + consumes: + - application/json + description: >- + Suspends a user. This operation can only be performed on users with an + `ACTIVE` status. The user will have a status of `SUSPENDED` when the + process is complete. + operationId: suspendUser + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: OK + security: + - api_token: [] + summary: Suspend User + tags: + - User + '/api/v1/users/{userId}/lifecycle/unlock': + post: + consumes: + - application/json + description: >- + Unlocks a user with a `LOCKED_OUT` status and returns them to `ACTIVE` + status. Users will be able to login with their current password. + operationId: unlockUser + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + summary: Unlock User + tags: + - User + '/api/v1/users/{userId}/lifecycle/unsuspend': + post: + consumes: + - application/json + description: >- + Unsuspends a user and returns them to the `ACTIVE` state. This + operation can only be performed on users that have a `SUSPENDED` status. + operationId: unsuspendUser + parameters: + - in: path + name: userId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + summary: Unsuspend User + tags: + - User + '/api/v1/users/{userId}/linkedObjects/{relationshipName}': + delete: + consumes: + - application/json + description: >- + Delete linked objects for a user, relationshipName can be ONLY a primary + relationship name + operationId: removeLinkedObjectForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: relationshipName + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + get: + consumes: + - application/json + description: >- + Get linked objects for a user, relationshipName can be a primary or + associated relationship name + operationId: getLinkedObjectsForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: relationshipName + required: true + type: string + - in: query + name: after + type: string + - default: -1 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/ResponseLinks' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles': + get: + consumes: + - application/json + description: Lists all roles assigned to a user. + operationId: listAssignedRolesForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: query + name: expand + type: string + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Role' + type: array + security: + - api_token: [] + tags: + - User + post: + consumes: + - application/json + description: Assigns a role to a user. + operationId: assignRoleToUser + parameters: + - in: body + name: assignRoleRequest + required: true + schema: + $ref: '#/definitions/AssignRoleRequest' + - in: path + name: userId + required: true + type: string + - in: query + name: disableNotifications + type: string + produces: + - application/json + responses: + '201': + description: Created + schema: + $ref: '#/definitions/Role' + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}': + delete: + consumes: + - application/json + description: Unassigns a role from a user. + operationId: removeRoleFromUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}/targets/catalog/apps': + get: + consumes: + - application/json + description: >- + Lists all App targets for an `APP_ADMIN` Role assigned to a User. This + methods return list may include full Applications or Instances. The + response for an instance will have an `ID` value, while Application will + not have an ID. + operationId: listApplicationTargetsForApplicationAdministratorRoleForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: query + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/CatalogApplication' + type: array + security: + - api_token: [] + tags: + - User + put: + consumes: + - application/json + description: Success + operationId: addAllAppsAsTargetToRole + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}/targets/catalog/apps/{appName}': + delete: + consumes: + - application/json + description: Success + operationId: removeApplicationTargetFromApplicationAdministratorRoleForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + put: + consumes: + - application/json + description: Success + operationId: addApplicationTargetToAdminRoleForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}/targets/catalog/apps/{appName}/{applicationId}': + delete: + consumes: + - application/json + description: Remove App Instance Target to App Administrator Role given to a User + operationId: removeApplicationTargetFromAdministratorRoleForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + - in: path + name: applicationId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Remove App Instance Target to App Administrator Role given to a User + tags: + - User + put: + consumes: + - application/json + description: Add App Instance Target to App Administrator Role given to a User + operationId: addApplicationTargetToAppAdminRoleForUser + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: appName + required: true + type: string + - in: path + name: applicationId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + summary: Add App Instance Target to App Administrator Role given to a User + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}/targets/groups': + get: + consumes: + - application/json + description: Success + operationId: listGroupTargetsForRole + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: query + name: after + type: string + - default: 20 + format: int32 + in: query + name: limit + type: integer + produces: + - application/json + responses: + '200': + description: Success + schema: + items: + $ref: '#/definitions/Group' + type: array + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/roles/{roleId}/targets/groups/{groupId}': + delete: + consumes: + - application/json + description: Success + operationId: removeGroupTargetFromRole + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: groupId + required: true + type: string + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User + put: + consumes: + - application/json + description: Success + operationId: addGroupTargetToRole + parameters: + - in: path + name: userId + required: true + type: string + - in: path + name: roleId + required: true + type: string + - in: path + name: groupId + required: true + type: string + produces: + - application/json + responses: + '200': + description: Success + security: + - api_token: [] + tags: + - User + '/api/v1/users/{userId}/sessions': + delete: + consumes: + - application/json + description: >- + Removes all active identity provider sessions. This forces the user to + authenticate on the next operation. Optionally revokes OpenID Connect + and OAuth refresh and access tokens issued to the user. + operationId: clearUserSessions + parameters: + - in: path + name: userId + required: true + type: string + - default: false + description: Revoke issued OpenID Connect and OAuth refresh and access tokens + in: query + name: oauthTokens + type: boolean + produces: + - application/json + responses: + '204': + description: No Content + security: + - api_token: [] + tags: + - User +definitions: + ActivateFactorRequest: + properties: + attestation: + type: string + clientData: + type: string + passCode: + type: string + registrationData: + type: string + stateToken: + type: string + x-okta-tags: + - UserFactor + AppAndInstanceConditionEvaluatorAppOrInstance: + properties: + id: + readOnly: true + type: string + name: + type: string + type: + enum: + - APP_TYPE + - APP + type: string + type: object + x-okta-tags: + - Policy + AppAndInstancePolicyRuleCondition: + properties: + exclude: + items: + $ref: '#/definitions/AppAndInstanceConditionEvaluatorAppOrInstance' + type: array + include: + items: + $ref: '#/definitions/AppAndInstanceConditionEvaluatorAppOrInstance' + type: array + type: object + x-okta-tags: + - Policy + AppInstancePolicyRuleCondition: + properties: + exclude: + items: + type: string + type: array + include: + items: + type: string + type: array + type: object + x-okta-tags: + - Policy + AppLink: + properties: + appAssignmentId: + readOnly: true + type: string + appInstanceId: + readOnly: true + type: string + appName: + readOnly: true + type: string + credentialsSetup: + readOnly: true + type: boolean + hidden: + readOnly: true + type: boolean + id: + readOnly: true + type: string + label: + readOnly: true + type: string + linkUrl: + readOnly: true + type: string + logoUrl: + readOnly: true + type: string + sortOrder: + readOnly: true + type: integer + type: object + x-okta-tags: + - User + AppUser: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + format: date-time + readOnly: true + type: string + credentials: + $ref: '#/definitions/AppUserCredentials' + externalId: + readOnly: true + type: string + id: + type: string + lastSync: + format: date-time + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + passwordChanged: + format: date-time + readOnly: true + type: string + profile: + additionalProperties: + type: object + type: object + scope: + type: string + status: + readOnly: true + type: string + statusChanged: + format: date-time + readOnly: true + type: string + syncState: + readOnly: true + type: string + type: object + x-okta-crud: + - alias: update + arguments: + - dest: appId + parentSrc: appId + - dest: userId + src: id + - dest: appUser + self: true + operationId: updateApplicationUser + - alias: delete + arguments: + - dest: appId + parentSrc: appId + - dest: userId + src: id + operationId: deleteApplicationUser + x-okta-tags: + - Application + AppUserCredentials: + properties: + password: + $ref: '#/definitions/AppUserPasswordCredential' + userName: + type: string + type: object + x-okta-tags: + - Application + AppUserPasswordCredential: + properties: + value: + format: password + type: string + x-okta-tags: + - Application + Application: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + accessibility: + $ref: '#/definitions/ApplicationAccessibility' + created: + format: date-time + readOnly: true + type: string + credentials: + $ref: '#/definitions/ApplicationCredentials' + features: + items: + type: string + type: array + id: + readOnly: true + type: string + label: + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + licensing: + $ref: '#/definitions/ApplicationLicensing' + name: + readOnly: true + type: string + profile: + additionalProperties: + type: object + type: object + settings: + $ref: '#/definitions/ApplicationSettings' + signOnMode: + $ref: '#/definitions/ApplicationSignOnMode' + status: + enum: + - ACTIVE + - INACTIVE + - DELETED + readOnly: true + type: string + visibility: + $ref: '#/definitions/ApplicationVisibility' + type: object + x-okta-crud: + - alias: read + arguments: + - dest: appId + src: id + operationId: getApplication + - alias: update + arguments: + - dest: appId + src: id + - dest: application + self: true + operationId: updateApplication + - alias: delete + arguments: + - dest: appId + src: id + operationId: deleteApplication + x-okta-operations: + - alias: activate + arguments: + - dest: appId + src: id + operationId: activateApplication + - alias: deactivate + arguments: + - dest: appId + src: id + operationId: deactivateApplication + - alias: listApplicationUsers + arguments: + - dest: appId + src: id + operationId: listApplicationUsers + - alias: assignUserToApplication + arguments: + - dest: appId + src: id + operationId: assignUserToApplication + - alias: getApplicationUser + arguments: + - dest: appId + src: id + operationId: getApplicationUser + - alias: createApplicationGroupAssignment + arguments: + - dest: appId + src: id + operationId: createApplicationGroupAssignment + - alias: getApplicationGroupAssignment + arguments: + - dest: appId + src: id + operationId: getApplicationGroupAssignment + - alias: cloneApplicationKey + arguments: + - dest: appId + src: id + operationId: cloneApplicationKey + - alias: getApplicationKey + arguments: + - dest: appId + src: id + operationId: getApplicationKey + - alias: listGroupAssignments + arguments: + - dest: appId + src: id + operationId: listApplicationGroupAssignments + - alias: listKeys + arguments: + - dest: appId + src: id + operationId: listApplicationKeys + - alias: generateKey + arguments: + - dest: appId + src: id + operationId: generateApplicationKey + - alias: generateCsr + arguments: + - dest: appId + src: id + operationId: generateCsrForApplication + - alias: getCsr + arguments: + - dest: appId + src: id + operationId: getCsrForApplication + - alias: revokeCsr + arguments: + - dest: appId + src: id + operationId: revokeCsrFromApplication + - alias: listCsrs + arguments: + - dest: appId + src: id + operationId: listCsrsForApplication + - alias: publishCerCert + arguments: + - dest: appId + src: id + operationId: publishCerCert + - alias: publishBinaryCerCert + arguments: + - dest: appId + src: id + operationId: publishBinaryCerCert + - alias: publishDerCert + arguments: + - dest: appId + src: id + operationId: publishDerCert + - alias: publishBinaryDerCert + arguments: + - dest: appId + src: id + operationId: publishBinaryDerCert + - alias: publishBinaryPemCert + arguments: + - dest: appId + src: id + operationId: publishBinaryPemCert + - alias: listOAuth2Tokens + arguments: + - dest: appId + src: id + operationId: listOAuth2TokensForApplication + - alias: revokeOAuth2TokenForApplication + arguments: + - dest: appId + src: id + operationId: revokeOAuth2TokenForApplication + - alias: getOAuth2Token + arguments: + - dest: appId + src: id + operationId: getOAuth2TokenForApplication + - alias: revokeOAuth2Tokens + arguments: + - dest: appId + src: id + operationId: revokeOAuth2TokensForApplication + - alias: listScopeConsentGrants + arguments: + - dest: appId + src: id + operationId: listScopeConsentGrants + - alias: grantConsentToScope + arguments: + - dest: appId + src: id + operationId: grantConsentToScope + - alias: revokeScopeConsentGrant + arguments: + - dest: appId + src: id + operationId: revokeScopeConsentGrant + - alias: getScopeConsentGrant + arguments: + - dest: appId + src: id + operationId: getScopeConsentGrant + x-okta-tags: + - Application + x-openapi-v3-discriminator: + mapping: + AUTO_LOGIN: '#/definitions/AutoLoginApplication' + BASIC_AUTH: '#/definitions/BasicAuthApplication' + BOOKMARK: '#/definitions/BookmarkApplication' + BROWSER_PLUGIN: '#/definitions/BrowserPluginApplication' + OPENID_CONNECT: '#/definitions/OpenIdConnectApplication' + SAML_2_0: '#/definitions/SamlApplication' + SECURE_PASSWORD_STORE: '#/definitions/SecurePasswordStoreApplication' + WS_FEDERATION: '#/definitions/WsFederationApplication' + propertyName: signOnMode + ApplicationAccessibility: + properties: + errorRedirectUrl: + type: string + loginRedirectUrl: + type: string + selfService: + type: boolean + type: object + x-okta-tags: + - Application + ApplicationCredentials: + properties: + signing: + $ref: '#/definitions/ApplicationCredentialsSigning' + userNameTemplate: + $ref: '#/definitions/ApplicationCredentialsUsernameTemplate' + type: object + x-okta-tags: + - Application + ApplicationCredentialsOAuthClient: + properties: + autoKeyRotation: + type: boolean + client_id: + type: string + client_secret: + type: string + token_endpoint_auth_method: + $ref: '#/definitions/OAuthEndpointAuthenticationMethod' + x-okta-tags: + - Application + ApplicationCredentialsScheme: + enum: + - SHARED_USERNAME_AND_PASSWORD + - EXTERNAL_PASSWORD_SYNC + - EDIT_USERNAME_AND_PASSWORD + - EDIT_PASSWORD_ONLY + - ADMIN_SETS_CREDENTIALS + type: string + x-okta-tags: + - Application + ApplicationCredentialsSigning: + properties: + kid: + type: string + lastRotated: + format: date-time + readOnly: true + type: string + nextRotation: + format: date-time + readOnly: true + type: string + rotationMode: + type: string + use: + $ref: '#/definitions/ApplicationCredentialsSigningUse' + type: object + x-okta-tags: + - Application + ApplicationCredentialsSigningUse: + enum: + - sig + type: string + x-okta-tags: + - AuthorizationServer + ApplicationCredentialsUsernameTemplate: + properties: + suffix: + type: string + template: + type: string + type: + type: string + type: object + x-okta-tags: + - Application + ApplicationGroupAssignment: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object readOnly: true + type: object + id: + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + priority: + type: integer + profile: + additionalProperties: + type: object + type: object + type: object + x-okta-crud: + - alias: delete + arguments: + - dest: appId + parentSrc: appId + - dest: groupId + src: id + operationId: deleteApplicationGroupAssignment + x-okta-tags: + - Application + ApplicationLicensing: + properties: + seatCount: + type: integer + type: object + x-okta-tags: + - Application + ApplicationSettings: + properties: + app: + $ref: '#/definitions/ApplicationSettingsApplication' + implicitAssignment: + type: boolean + inlineHookId: + type: string + notifications: + $ref: '#/definitions/ApplicationSettingsNotifications' + type: object + x-okta-tags: + - Application + ApplicationSettingsApplication: + x-okta-tags: + - Application + ApplicationSettingsNotifications: + properties: + vpn: + $ref: '#/definitions/ApplicationSettingsNotificationsVpn' + type: object + x-okta-tags: + - Application + ApplicationSettingsNotificationsVpn: + properties: + helpUrl: + type: string + message: + type: string + network: + $ref: '#/definitions/ApplicationSettingsNotificationsVpnNetwork' + type: object + x-okta-tags: + - Application + ApplicationSettingsNotificationsVpnNetwork: + properties: + connection: + type: string + exclude: + items: + type: string + type: array + include: + items: + type: string + type: array + type: object + x-okta-tags: + - Application + ApplicationSignOnMode: + enum: + - BOOKMARK + - BASIC_AUTH + - BROWSER_PLUGIN + - SECURE_PASSWORD_STORE + - AUTO_LOGIN + - WS_FEDERATION + - SAML_2_0 + - OPENID_CONNECT + - SAML_1_1 + type: string + x-okta-tags: + - Application + ApplicationVisibility: + properties: + appLinks: + additionalProperties: + type: boolean + type: object + autoSubmitToolbar: + type: boolean + hide: + $ref: '#/definitions/ApplicationVisibilityHide' + type: object + x-okta-tags: + - Application + ApplicationVisibilityHide: + properties: + iOS: + type: boolean + web: type: boolean - id: + type: object + x-okta-tags: + - Application + AssignRoleRequest: + properties: + type: + $ref: '#/definitions/RoleType' + readOnly: false + x-okta-tags: + - Role + AuthenticationProvider: + properties: + name: + type: string + type: + $ref: '#/definitions/AuthenticationProviderType' + type: object + x-okta-tags: + - User + AuthenticationProviderType: + enum: + - ACTIVE_DIRECTORY + - FEDERATION + - LDAP + - OKTA + - SOCIAL + - IMPORT + type: string + x-okta-tags: + - User + AuthorizationServer: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + audiences: + items: + type: string + type: array + created: + format: date-time readOnly: true type: string - label: + credentials: + $ref: '#/definitions/AuthorizationServerCredentials' + description: + type: string + id: readOnly: true type: string - linkUrl: + issuer: + type: string + issuerMode: + enum: + - ORG_URL + - CUSTOM_URL + type: string + lastUpdated: + format: date-time readOnly: true type: string - logoUrl: + name: + type: string + status: + enum: + - ACTIVE + - INACTIVE + type: string + type: object + x-okta-crud: + - alias: create + arguments: + - dest: authorizationServer + self: true + operationId: createAuthorizationServer + - alias: read + arguments: [] + operationId: getAuthorizationServer + - alias: update + arguments: + - dest: authServerId + src: id + - dest: authorizationServer + self: true + operationId: updateAuthorizationServer + - alias: delete + arguments: + - dest: authServerId + src: id + - dest: authorizationServer + self: true + operationId: deleteAuthorizationServer + x-okta-operations: + - alias: listOAuth2Claims + arguments: + - dest: authServerId + src: id + operationId: listOAuth2Claims + - alias: createOAuth2Claim + arguments: + - dest: authServerId + src: id + operationId: createOAuth2Claim + - alias: deleteOAuth2Claim + arguments: + - dest: authServerId + src: id + operationId: deleteOAuth2Claim + - alias: getOAuth2Claim + arguments: + - dest: authServerId + src: id + operationId: getOAuth2Claim + - alias: updateOAuth2Claim + arguments: + - dest: authServerId + src: id + operationId: updateOAuth2Claim + - alias: listOAuth2Clients + arguments: + - dest: authServerId + src: id + operationId: listOAuth2ClientsForAuthorizationServer + - alias: revokeRefreshTokensForClient + arguments: + - dest: authServerId + src: id + operationId: revokeRefreshTokensForAuthorizationServerAndClient + - alias: listRefreshTokensForClient + arguments: + - dest: authServerId + src: id + operationId: listRefreshTokensForAuthorizationServerAndClient + - alias: getRefreshTokenForClient + arguments: + - dest: authServerId + src: id + operationId: getRefreshTokenForAuthorizationServerAndClient + - alias: revokeRefreshTokenForClient + arguments: + - dest: authServerId + src: id + operationId: revokeRefreshTokenForAuthorizationServerAndClient + - alias: listKeys + arguments: + - dest: authServerId + src: id + operationId: listAuthorizationServerKeys + - alias: rotateKeys + arguments: + - dest: authServerId + src: id + operationId: rotateAuthorizationServerKeys + - alias: activate + arguments: + - dest: authServerId + src: id + operationId: activateAuthorizationServer + - alias: deactivate + arguments: + - dest: authServerId + src: id + operationId: deactivateAuthorizationServer + - alias: listPolicies + arguments: + - dest: authServerId + src: id + operationId: listAuthorizationServerPolicies + - alias: createPolicy + arguments: + - dest: authServerId + src: id + operationId: createAuthorizationServerPolicy + - alias: deletePolicy + arguments: + - dest: authServerId + src: id + operationId: deleteAuthorizationServerPolicy + - alias: getPolicy + arguments: + - dest: authServerId + src: id + operationId: getAuthorizationServerPolicy + - alias: updatePolicy + arguments: + - dest: authServerId + src: id + operationId: updateAuthorizationServerPolicy + - alias: listOAuth2Scopes + arguments: + - dest: authServerId + src: id + operationId: listOAuth2Scopes + - alias: createOAuth2Scope + arguments: + - dest: authServerId + src: id + operationId: createOAuth2Scope + - alias: deleteOAuth2Scope + arguments: + - dest: authServerId + src: id + operationId: deleteOAuth2Scope + - alias: getOAuth2Scope + arguments: + - dest: authServerId + src: id + operationId: getOAuth2Scope + - alias: updateOAuth2Scope + arguments: + - dest: authServerId + src: id + operationId: updateOAuth2Scope + x-okta-tags: + - AuthorizationServer + AuthorizationServerCredentials: + properties: + signing: + $ref: '#/definitions/AuthorizationServerCredentialsSigningConfig' + x-okta-tags: + - Application + AuthorizationServerCredentialsRotationMode: + enum: + - AUTO + - MANUAL + type: string + x-okta-tags: + - AuthorizationServer + AuthorizationServerCredentialsSigningConfig: + properties: + kid: + type: string + lastRotated: + format: date-time readOnly: true type: string - sortOrder: + nextRotation: + format: date-time readOnly: true - type: integer + type: string + rotationMode: + $ref: '#/definitions/AuthorizationServerCredentialsRotationMode' + use: + $ref: '#/definitions/AuthorizationServerCredentialsUse' + x-okta-tags: + - AuthorizationServer + AuthorizationServerCredentialsUse: + enum: + - sig + type: string + x-okta-tags: + - AuthorizationServer + AutoLoginApplication: + properties: + credentials: + $ref: '#/definitions/SchemeApplicationCredentials' + settings: + $ref: '#/definitions/AutoLoginApplicationSettings' + x-okta-parent: '#/definitions/Application' + x-okta-tags: + - Application + AutoLoginApplicationSettings: + properties: + signOn: + $ref: '#/definitions/AutoLoginApplicationSettingsSignOn' + x-okta-parent: '#/definitions/ApplicationSettings' + x-okta-tags: + - Application + AutoLoginApplicationSettingsSignOn: + properties: + loginUrl: + type: string + redirectUrl: + type: string + x-okta-tags: + - Application + BasicApplicationSettings: + properties: + app: + $ref: '#/definitions/BasicApplicationSettingsApplication' + x-okta-parent: '#/definitions/ApplicationSettings' + x-okta-tags: + - Application + BasicApplicationSettingsApplication: + properties: + authURL: + type: string + url: + type: string + x-okta-parent: '#/definitions/ApplicationSettingsApplication' + x-okta-tags: + - Application + BasicAuthApplication: + properties: + credentials: + $ref: '#/definitions/SchemeApplicationCredentials' + name: + default: template_basic_auth + settings: + $ref: '#/definitions/BasicApplicationSettings' + x-okta-defined-as: + name: template_basic_auth + x-okta-parent: '#/definitions/Application' + x-okta-tags: + - Application + BeforeScheduledActionPolicyRuleCondition: + properties: + duration: + $ref: '#/definitions/Duration' + lifecycleAction: + $ref: '#/definitions/ScheduledUserLifecycleAction' type: object x-okta-tags: - - User - AppUser: + - Policy + BookmarkApplication: properties: - _embedded: - additionalProperties: - type: object + name: + default: bookmark + settings: + $ref: '#/definitions/BookmarkApplicationSettings' + x-okta-defined-as: + name: bookmark + x-okta-parent: '#/definitions/Application' + x-okta-tags: + - Application + BookmarkApplicationSettings: + properties: + app: + $ref: '#/definitions/BookmarkApplicationSettingsApplication' + x-okta-parent: '#/definitions/ApplicationSettings' + x-okta-tags: + - Application + BookmarkApplicationSettingsApplication: + properties: + requestIntegration: + type: boolean + url: + type: string + x-okta-parent: '#/definitions/ApplicationSettingsApplication' + x-okta-tags: + - Application + BrowserPluginApplication: + properties: + credentials: + $ref: '#/definitions/SchemeApplicationCredentials' + x-okta-parent: '#/definitions/Application' + x-okta-tags: + - Application + x-openapi-v3-discriminator: + mapping: + template_swa: '#/definitions/SwaApplication' + template_swa3field: '#/definitions/SwaThreeFieldApplication' + propertyName: name + CatalogApplication: + properties: + id: + type: string + readOnly: true + name: + type: string + displayName: + type: string + description: + type: string + status: + $ref: '#/definitions/CatalogApplicationStatus' + lastUpdated: + format: date-time readOnly: true - type: object + type: string + category: + type: string + verificationStatus: + type: string + website: + type: string + signOnModes: + items: + type: string + type: array + features: + items: + type: string + type: array _links: additionalProperties: type: object readOnly: true type: object + x-okta-tags: + - Role + CatalogApplicationStatus: + enum: + - ACTIVE + - INACTIVE + type: string + x-okta-tags: + - Role + Csr: + properties: created: format: date-time readOnly: true type: string - credentials: - $ref: '#/definitions/AppUserCredentials' - externalId: + csr: readOnly: true type: string id: - type: string - lastSync: - format: date-time readOnly: true type: string - lastUpdated: - format: date-time + kty: readOnly: true type: string - passwordChanged: - format: date-time - readOnly: true + type: object + x-okta-tags: + - Application + CsrMetadata: + properties: + subject: + $ref: '#/definitions/CsrMetadataSubject' + subjectAltNames: + $ref: '#/definitions/CsrMetadataSubjectAltNames' + x-okta-tags: + - Application + CsrMetadataSubject: + properties: + commonName: + type: string + countryName: + type: string + localityName: + type: string + organizationName: + type: string + organizationalUnitName: type: string + stateOrProvinceName: + type: string + x-okta-tags: + - Application + CsrMetadataSubjectAltNames: + properties: + dnsNames: + items: + type: string + type: array + x-okta-tags: + - Application + CallUserFactor: + properties: profile: - additionalProperties: - type: object - type: object - scope: + $ref: '#/definitions/CallUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' + x-okta-tags: + - UserFactor + CallUserFactorProfile: + properties: + phoneExtension: type: string - status: - readOnly: true + phoneNumber: type: string - statusChanged: - format: date-time - readOnly: true + x-okta-tags: + - UserFactor + ChangePasswordRequest: + properties: + newPassword: + $ref: '#/definitions/PasswordCredential' + oldPassword: + $ref: '#/definitions/PasswordCredential' + type: object + x-okta-tags: + - User + ClientPolicyCondition: + properties: + include: + items: + type: string + type: array + type: object + x-okta-tags: + - Policy + ContextPolicyRuleCondition: + properties: + expression: type: string - syncState: - readOnly: true + type: object + x-okta-tags: + - Policy + CreateSessionRequest: + properties: + sessionToken: type: string type: object - x-okta-crud: - - alias: update - arguments: - - dest: appId - parentSrc: appId - - dest: userId - src: id - - dest: appUser - self: true - operationId: updateApplicationUser - - alias: delete - arguments: - - dest: appId - parentSrc: appId - - dest: userId - src: id - operationId: deleteApplicationUser x-okta-tags: - - Application - AppUserCredentials: + - Session + CreateUserRequest: properties: - password: - $ref: '#/definitions/AppUserPasswordCredential' - userName: + credentials: + $ref: '#/definitions/UserCredentials' + groupIds: + items: + type: string + type: array + profile: + $ref: '#/definitions/UserProfile' + type: + $ref: '#/definitions/UserType' + type: object + x-okta-parent: '#/definitions/User' + x-okta-tags: + - User + DevicePolicyRuleCondition: + properties: + migrated: + type: boolean + platform: + $ref: '#/definitions/DevicePolicyRuleConditionPlatform' + rooted: + type: boolean + trustLevel: + enum: + - ANY + - TRUSTED type: string type: object x-okta-tags: - - Application - AppUserPasswordCredential: + - Policy + DevicePolicyRuleConditionPlatform: properties: - value: - format: password + supportedMDMFrameworks: + items: + $ref: '#/definitions/MDMFrameworks' + type: array + types: + items: + $ref: '#/definitions/Platforms' + type: array + type: object + x-okta-tags: + - Policy + Duration: + properties: + number: + type: integer + unit: type: string + type: object x-okta-tags: - - Application - Application: + - Policy + EmailUserFactor: + properties: + profile: + $ref: '#/definitions/EmailUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' + x-okta-tags: + - UserFactor + EmailUserFactorProfile: + properties: + email: + type: string + x-okta-tags: + - UserFactor + EnabledStatus: + enum: + - ENABLED + - DISABLED + type: string + x-okta-tags: + - Common + EventHook: properties: - _embedded: - additionalProperties: - type: object - readOnly: true - type: object _links: additionalProperties: type: object readOnly: true type: object - accessibility: - $ref: '#/definitions/ApplicationAccessibility' + channel: + $ref: '#/definitions/EventHookChannel' created: format: date-time readOnly: true type: string - credentials: - $ref: '#/definitions/ApplicationCredentials' - features: - items: - type: string - type: array + createdBy: + type: string + events: + $ref: '#/definitions/EventSubscriptions' id: readOnly: true type: string - label: - type: string lastUpdated: format: date-time readOnly: true type: string - licensing: - $ref: '#/definitions/ApplicationLicensing' name: - readOnly: true type: string - profile: - additionalProperties: - type: object - type: object - settings: - $ref: '#/definitions/ApplicationSettings' - signOnMode: - $ref: '#/definitions/ApplicationSignOnMode' status: enum: - ACTIVE - INACTIVE - - DELETED - readOnly: true type: string - visibility: - $ref: '#/definitions/ApplicationVisibility' + verificationStatus: + enum: + - UNVERIFIED + - VERIFIED + type: string type: object - x-okta-crud: - - alias: read - arguments: - - dest: appId - src: id - operationId: getApplication - - alias: update - arguments: - - dest: appId - src: id - - dest: application - self: true - operationId: updateApplication - - alias: delete - arguments: - - dest: appId - src: id - operationId: deleteApplication - x-okta-operations: - - alias: activate - arguments: - - dest: appId - src: id - operationId: activateApplication - - alias: deactivate - arguments: - - dest: appId - src: id - operationId: deactivateApplication - - alias: listApplicationUsers - arguments: - - dest: appId - src: id - operationId: listApplicationUsers - - alias: assignUserToApplication - arguments: - - dest: appId - src: id - operationId: assignUserToApplication - - alias: getApplicationUser - arguments: - - dest: appId - src: id - operationId: getApplicationUser - - alias: createApplicationGroupAssignment - arguments: - - dest: appId - src: id - operationId: createApplicationGroupAssignment - - alias: getApplicationGroupAssignment + x-okta-crud: + - alias: create arguments: - - dest: appId + - dest: eventHook + self: true + operationId: createEventHook + - alias: read + arguments: [] + operationId: getEventHook + - alias: update + arguments: + - dest: eventHookId src: id - operationId: getApplicationGroupAssignment - - alias: cloneApplicationKey + - dest: eventHook + self: true + operationId: updateEventHook + - alias: delete arguments: - - dest: appId + - dest: eventHookId src: id - operationId: cloneApplicationKey - - alias: getApplicationKey + operationId: deleteEventHook + x-okta-operations: + - alias: activate arguments: - - dest: appId + - dest: eventHookId src: id - operationId: getApplicationKey - - alias: listGroupAssignments + operationId: activateEventHook + - alias: deactivate arguments: - - dest: appId + - dest: eventHookId src: id - operationId: listApplicationGroupAssignments - - alias: listKeys + operationId: deactivateEventHook + - alias: verify arguments: - - dest: appId + - dest: eventHookId src: id - operationId: listApplicationKeys + operationId: verifyEventHook x-okta-tags: - - Application - x-openapi-v3-discriminator: - mapping: - AUTO_LOGIN: '#/definitions/AutoLoginApplication' - BASIC_AUTH: '#/definitions/BasicAuthApplication' - BOOKMARK: '#/definitions/BookmarkApplication' - BROWSER_PLUGIN: '#/definitions/BrowserPluginApplication' - OPENID_CONNECT: '#/definitions/OpenIdConnectApplication' - SAML_2_0: '#/definitions/SamlApplication' - SECURE_PASSWORD_STORE: '#/definitions/SecurePasswordStoreApplication' - WS_FEDERATION: '#/definitions/WsFederationApplication' - propertyName: signOnMode - ApplicationAccessibility: + - EventHook + EventHookChannel: properties: - errorRedirectUrl: + config: + $ref: '#/definitions/EventHookChannelConfig' + readOnly: false + type: + enum: + - HTTP + readOnly: false type: string - loginRedirectUrl: + version: + readOnly: false type: string - selfService: - type: boolean type: object x-okta-tags: - - Application - ApplicationCredentials: + - EventHook + EventHookChannelConfig: properties: - signing: - $ref: '#/definitions/ApplicationCredentialsSigning' - userNameTemplate: - $ref: '#/definitions/ApplicationCredentialsUsernameTemplate' + authScheme: + $ref: '#/definitions/EventHookChannelConfigAuthScheme' + type: object + headers: + items: + $ref: '#/definitions/EventHookChannelConfigHeader' + type: array + uri: + type: string type: object x-okta-tags: - - Application - ApplicationCredentialsOAuthClient: + - EventHook + EventHookChannelConfigAuthScheme: properties: - autoKeyRotation: - type: boolean - client_id: + key: type: string - client_secret: + type: + $ref: '#/definitions/EventHookChannelConfigAuthSchemeType' + value: type: string - token_endpoint_auth_method: - $ref: '#/definitions/OAuthEndpointAuthenticationMethod' + type: object x-okta-tags: - - Application - ApplicationCredentialsScheme: + - EventHook + EventHookChannelConfigAuthSchemeType: enum: - - SHARED_USERNAME_AND_PASSWORD - - EXTERNAL_PASSWORD_SYNC - - EDIT_USERNAME_AND_PASSWORD - - EDIT_PASSWORD_ONLY - - ADMIN_SETS_CREDENTIALS + - HEADER type: string x-okta-tags: - - Application - ApplicationCredentialsSigning: + - EventHook + EventHookChannelConfigHeader: properties: - kid: - type: string - lastRotated: - format: date-time - readOnly: true - type: string - nextRotation: - format: date-time - readOnly: true + key: type: string - rotationMode: + value: type: string type: object x-okta-tags: - - Application - ApplicationCredentialsUsernameTemplate: + - EventHook + EventSubscriptions: properties: - suffix: - type: string - template: - type: string + items: + items: + type: string + type: array type: + enum: + - EVENT_TYPE + - FLOW_EVENT type: string type: object x-okta-tags: - - Application - ApplicationGroupAssignment: + - EventHook + FactorProvider: + enum: + - OKTA + - RSA + - GOOGLE + - SYMANTEC + - DUO + - YUBICO + type: string + x-okta-tags: + - UserFactor + FactorResultType: + enum: + - SUCCESS + - CHALLENGE + - WAITING + - FAILED + - REJECTED + - TIMEOUT + - TIME_WINDOW_EXCEEDED + - PASSCODE_REPLAYED + - ERROR + - CANCELLED + type: string + x-okta-tags: + - UserFactor + FactorStatus: + enum: + - PENDING_ACTIVATION + - ACTIVE + - INACTIVE + - NOT_SETUP + - ENROLLED + - DISABLED + - EXPIRED + type: string + x-okta-tags: + - UserFactor + FactorType: + enum: + - call + - email + - push + - question + - sms + - 'token:hardware' + - 'token:hotp' + - 'token:software:totp' + - token + - u2f + - web + - webauthn + type: string + x-okta-tags: + - UserFactor + Feature: properties: - _embedded: - additionalProperties: - type: object - readOnly: true - type: object _links: additionalProperties: type: object readOnly: true type: object + description: + type: string id: readOnly: true type: string - lastUpdated: - format: date-time - readOnly: true + name: type: string - priority: - type: integer - profile: - additionalProperties: - type: object - type: object + stage: + $ref: '#/definitions/FeatureStage' + status: + $ref: '#/definitions/EnabledStatus' + type: + $ref: '#/definitions/FeatureType' type: object x-okta-crud: - - alias: delete + - alias: read + arguments: [] + operationId: getFeature + x-okta-operations: + - alias: updateLifecycle arguments: - - dest: appId - parentSrc: appId - - dest: groupId + - dest: featureId src: id - operationId: deleteApplicationGroupAssignment + operationId: updateFeatureLifecycle + - alias: getDependents + arguments: + - dest: featureId + src: id + operationId: listFeatureDependents + - alias: getDependencies + arguments: + - dest: featureId + src: id + operationId: listFeatureDependencies x-okta-tags: - - Application - ApplicationLicensing: + - Feature + FeatureStage: properties: - seatCount: - type: integer + state: + $ref: '#/definitions/FeatureStageState' + value: + $ref: '#/definitions/FeatureStageValue' type: object x-okta-tags: - - Application - ApplicationSettings: + - Feature + FeatureStageState: + enum: + - OPEN + - CLOSED + type: string + x-okta-tags: + - Feature + FeatureStageValue: + enum: + - EA + - BETA + type: string + x-okta-tags: + - Feature + FeatureType: + enum: + - self-service + type: string + x-okta-tags: + - Feature + ForgotPasswordResponse: properties: - app: - $ref: '#/definitions/ApplicationSettingsApplication' - implicitAssignment: - type: boolean - inlineHookId: + resetPasswordUrl: + readOnly: true type: string - notifications: - $ref: '#/definitions/ApplicationSettingsNotifications' - type: object - x-okta-tags: - - Application - ApplicationSettingsApplication: x-okta-tags: - - Application - ApplicationSettingsNotifications: + - User + GrantTypePolicyRuleCondition: properties: - vpn: - $ref: '#/definitions/ApplicationSettingsNotificationsVpn' + include: + items: + type: string + type: array type: object x-okta-tags: - - Application - ApplicationSettingsNotificationsVpn: + - Policy + Group: properties: - helpUrl: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + format: date-time + readOnly: true + type: string + id: + readOnly: true + type: string + lastMembershipUpdated: + format: date-time + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true type: string - message: + objectClass: + items: + type: string + readOnly: true + type: array + profile: + $ref: '#/definitions/GroupProfile' + type: + $ref: '#/definitions/GroupType' + readOnly: true type: string - network: - $ref: '#/definitions/ApplicationSettingsNotificationsVpnNetwork' type: object + x-okta-crud: + - alias: update + arguments: + - dest: groupId + src: id + - dest: group + self: true + operationId: updateGroup + - alias: delete + arguments: + - dest: groupId + src: id + operationId: deleteGroup + x-okta-operations: + - alias: removeUser + arguments: + - dest: groupId + src: id + operationId: removeUserFromGroup + - alias: listUsers + arguments: + - dest: groupId + src: id + operationId: listGroupUsers + - alias: listApplications + arguments: + - dest: groupId + src: id + operationId: listAssignedApplicationsForGroup + - alias: assignRole + arguments: + - dest: groupId + src: id + operationId: assignRoleToGroup x-okta-tags: - - Application - ApplicationSettingsNotificationsVpnNetwork: + - Group + GroupCondition: properties: - connection: - type: string exclude: items: type: string @@ -2996,477 +8138,452 @@ definitions: items: type: string type: array - type: object - x-okta-tags: - - Application - ApplicationSignOnMode: - enum: - - BOOKMARK - - BASIC_AUTH - - BROWSER_PLUGIN - - SECURE_PASSWORD_STORE - - AUTO_LOGIN - - WS_FEDERATION - - SAML_2_0 - - OPENID_CONNECT - - SAML_1_1 - type: string - x-okta-tags: - - Application - ApplicationVisibility: - properties: - appLinks: - additionalProperties: - type: boolean - type: object - autoSubmitToolbar: - type: boolean - hide: - $ref: '#/definitions/ApplicationVisibilityHide' - type: object x-okta-tags: - - Application - ApplicationVisibilityHide: + - Policy + GroupPolicyRuleCondition: properties: - iOS: - type: boolean - web: - type: boolean + exclude: + items: + type: string + type: array + include: + items: + type: string + type: array type: object x-okta-tags: - - Application - AuthenticationProvider: + - Policy + GroupProfile: properties: + description: + type: string name: type: string - type: - $ref: '#/definitions/AuthenticationProviderType' type: object x-okta-tags: - - User - AuthenticationProviderType: - enum: - - ACTIVE_DIRECTORY - - FEDERATION - - LDAP - - OKTA - - SOCIAL - - IMPORT - type: string - x-okta-tags: - - User - AutoLoginApplication: - properties: - credentials: - $ref: '#/definitions/SchemeApplicationCredentials' - settings: - $ref: '#/definitions/AutoLoginApplicationSettings' - x-okta-parent: '#/definitions/Application' - x-okta-tags: - - Application - AutoLoginApplicationSettings: - properties: - signOn: - $ref: '#/definitions/AutoLoginApplicationSettingsSignOn' - x-okta-parent: '#/definitions/ApplicationSettings' - x-okta-tags: - - Application - AutoLoginApplicationSettingsSignOn: + - Group + GroupRule: properties: - loginUrl: - type: string - redirectUrl: + actions: + $ref: '#/definitions/GroupRuleAction' + conditions: + $ref: '#/definitions/GroupRuleConditions' + created: + format: date-time + readOnly: true type: string - x-okta-tags: - - Application - BasicApplicationSettings: - properties: - app: - $ref: '#/definitions/BasicApplicationSettingsApplication' - x-okta-parent: '#/definitions/ApplicationSettings' - x-okta-tags: - - Application - BasicApplicationSettingsApplication: - properties: - authURL: + id: + readOnly: true type: string - url: + lastUpdated: + format: date-time + readOnly: true type: string - x-okta-parent: '#/definitions/ApplicationSettingsApplication' - x-okta-tags: - - Application - BasicAuthApplication: - properties: - credentials: - $ref: '#/definitions/SchemeApplicationCredentials' - name: - default: template_basic_auth - settings: - $ref: '#/definitions/BasicApplicationSettings' - x-okta-defined-as: - name: template_basic_auth - x-okta-parent: '#/definitions/Application' - x-okta-tags: - - Application - BookmarkApplication: - properties: name: - default: bookmark - settings: - $ref: '#/definitions/BookmarkApplicationSettings' - x-okta-defined-as: - name: bookmark - x-okta-parent: '#/definitions/Application' - x-okta-tags: - - Application - BookmarkApplicationSettings: - properties: - app: - $ref: '#/definitions/BookmarkApplicationSettingsApplication' - x-okta-parent: '#/definitions/ApplicationSettings' - x-okta-tags: - - Application - BookmarkApplicationSettingsApplication: - properties: - requestIntegration: - type: boolean - url: - type: string - x-okta-parent: '#/definitions/ApplicationSettingsApplication' - x-okta-tags: - - Application - BrowserPluginApplication: - properties: - credentials: - $ref: '#/definitions/SchemeApplicationCredentials' - x-okta-parent: '#/definitions/Application' - x-okta-tags: - - Application - x-openapi-v3-discriminator: - mapping: - template_swa: '#/definitions/SwaApplication' - template_swa3field: '#/definitions/SwaThreeFieldApplication' - propertyName: name - CallFactor: - properties: - profile: - $ref: '#/definitions/CallFactorProfile' - x-okta-parent: '#/definitions/Factor' - x-okta-tags: - - UserFactor - CallFactorProfile: - properties: - phoneExtension: type: string - phoneNumber: + status: + $ref: '#/definitions/GroupRuleStatus' + readOnly: true + type: type: string - x-okta-parent: '#/definitions/FactorProfile' + type: object + x-okta-crud: + - alias: update + arguments: + - dest: ruleId + src: id + - dest: groupRule + self: true + operationId: updateGroupRule + - alias: delete + arguments: + - dest: ruleId + src: id + operationId: deleteGroupRule + x-okta-operations: + - alias: activate + arguments: + - dest: ruleId + src: id + operationId: activateGroupRule + - alias: deactivate + arguments: + - dest: ruleId + src: id + operationId: deactivateGroupRule x-okta-tags: - - UserFactor - ChangePasswordRequest: + - GroupRule + GroupRuleAction: properties: - newPassword: - $ref: '#/definitions/PasswordCredential' - oldPassword: - $ref: '#/definitions/PasswordCredential' + assignUserToGroups: + $ref: '#/definitions/GroupRuleGroupAssignment' type: object x-okta-tags: - - User - CreateSessionRequest: + - GroupRule + GroupRuleConditions: properties: - sessionToken: - type: string + expression: + $ref: '#/definitions/GroupRuleExpression' + people: + $ref: '#/definitions/GroupRulePeopleCondition' type: object x-okta-tags: - - Session - EmailAddress: + - GroupRule + GroupRuleExpression: properties: - status: - $ref: '#/definitions/EmailStatus' - readOnly: true type: - $ref: '#/definitions/EmailType' - readOnly: true + type: string value: - readOnly: true type: string type: object x-okta-tags: - - User - EmailFactor: + - GroupRule + GroupRuleGroupAssignment: properties: - profile: - $ref: '#/definitions/EmailFactorProfile' - x-okta-parent: '#/definitions/Factor' + groupIds: + items: + type: string + type: array + type: object x-okta-tags: - - UserFactor - EmailFactorProfile: + - GroupRule + GroupRuleGroupCondition: properties: - email: - type: string - x-okta-parent: '#/definitions/FactorProfile' + exclude: + items: + type: string + type: array + include: + items: + type: string + type: array + type: object x-okta-tags: - - UserFactor - EmailStatus: + - GroupRule + GroupRulePeopleCondition: + properties: + groups: + $ref: '#/definitions/GroupRuleGroupCondition' + users: + $ref: '#/definitions/GroupRuleUserCondition' + type: object + x-okta-tags: + - GroupRule + GroupRuleStatus: enum: - - VERIFIED - - UNVERIFIED + - ACTIVE + - INACTIVE + - INVALID type: string x-okta-tags: - - User - EmailType: + - GroupRule + GroupRuleUserCondition: + properties: + exclude: + items: + type: string + type: array + include: + items: + type: string + type: array + type: object + x-okta-tags: + - GroupRule + GroupType: enum: - - PRIMARY - - SECONDARY + - OKTA_GROUP + - APP_GROUP + - BUILT_IN type: string x-okta-tags: - - User - Factor: + - Group + HardwareUserFactor: + properties: + profile: + $ref: '#/definitions/HardwareUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' + x-okta-tags: + - UserFactor + HardwareUserFactorProfile: + properties: + credentialId: + type: string + x-okta-tags: + - UserFactor + IdentityProvider: properties: - _embedded: - additionalProperties: - type: object - readOnly: true - type: object _links: additionalProperties: type: object readOnly: true type: object - device: - type: string - deviceType: + created: + format: date-time readOnly: true type: string - factorType: - $ref: '#/definitions/FactorType' id: readOnly: true type: string - mfaStateTokenId: + issuerMode: + enum: + - ORG_URL + - CUSTOM_URL_DOMAIN type: string - x-okta-deprecated: 1.10.0 - profile: - $ref: '#/definitions/FactorProfile' - provider: - $ref: '#/definitions/FactorProvider' - rechallengeExistingFactor: - type: boolean - sessionId: + lastUpdated: + format: date-time + readOnly: true + type: string + name: type: string + policy: + $ref: '#/definitions/IdentityProviderPolicy' + protocol: + $ref: '#/definitions/Protocol' status: - $ref: '#/definitions/FactorStatus' - readOnly: true - tokenLifetimeSeconds: - type: integer - userId: + enum: + - ACTIVE + - INACTIVE + type: string + type: + enum: + - SAML2 + - GOOGLE + - FACEBOOK + - LINKEDIN + - MICROSOFT + - OIDC + - OKTA + - IWA + - AgentlessDSSO + - X509 type: string - verify: - $ref: '#/definitions/VerifyFactorRequest' type: object x-okta-crud: + - alias: create + arguments: + - dest: idpTrust + self: true + operationId: createIdentityProvider + - alias: read + arguments: [] + operationId: getIdentityProvider + - alias: update + arguments: + - dest: idpId + src: id + - dest: idpTrust + self: true + operationId: updateIdentityProvider - alias: delete arguments: - - dest: factorId + - dest: idpId src: id - - dest: userId - parentSrc: id - operationId: deleteFactor + operationId: deleteIdentityProvider x-okta-operations: + - alias: listSigningCsrs + arguments: + - dest: idpId + src: id + operationId: listCsrsForIdentityProvider + - alias: generateCsr + arguments: + - dest: idpId + src: id + operationId: generateCsrForIdentityProvider + - alias: deleteSigningCsr + arguments: + - dest: idpId + src: id + operationId: revokeCsrForIdentityProvider + - alias: getSigningCsr + arguments: + - dest: idpId + src: id + operationId: getCsrForIdentityProvider + - alias: listSigningKeys + arguments: + - dest: idpId + src: id + operationId: listIdentityProviderSigningKeys + - alias: generateSigningKey + arguments: + - dest: idpId + src: id + operationId: generateIdentityProviderSigningKey + - alias: getSigningKey + arguments: + - dest: idpId + src: id + operationId: getIdentityProviderSigningKey + - alias: deleteSigningKey + arguments: + - dest: idpId + src: id + operationId: deleteIdentityProviderKey + - alias: cloneKey + arguments: + - dest: idpId + src: id + operationId: cloneIdentityProviderKey - alias: activate arguments: - - dest: factorId + - dest: idpId src: id - - dest: userId - parentSrc: id - operationId: activateFactor - - alias: verify + operationId: activateIdentityProvider + - alias: deactivate arguments: - - dest: factorId + - dest: idpId src: id - - dest: userId - parentSrc: id - operationId: verifyFactor - x-okta-tags: - - UserFactor - x-openapi-v3-discriminator: - mapping: - call: '#/definitions/CallFactor' - email: '#/definitions/EmailFactor' - push: '#/definitions/PushFactor' - question: '#/definitions/SecurityQuestionFactor' - sms: '#/definitions/SmsFactor' - token: '#/definitions/TokenFactor' - 'token:hardware': '#/definitions/HardwareFactor' - 'token:software:totp': '#/definitions/TotpFactor' - u2f: '#/definitions/U2fFactor' - web: '#/definitions/WebFactor' - propertyName: factorType - FactorProfile: - properties: {} - x-okta-tags: - - UserFactor - FactorProvider: - enum: - - OKTA - - RSA - - GOOGLE - - SYMANTEC - - DUO - - YUBICO - - FIDO - type: string + operationId: deactivateIdentityProvider + - alias: listUsers + arguments: + - dest: idpId + src: id + operationId: listIdentityProviderApplicationUsers + - alias: unlinkUser + arguments: + - dest: idpId + src: id + operationId: unlinkUserFromIdentityProvider + - alias: getUser + arguments: + - dest: idpId + src: id + operationId: getIdentityProviderApplicationUser + - alias: linkUser + arguments: + - dest: idpId + src: id + operationId: linkUserToIdentityProvider + - alias: listSocialAuthTokens + arguments: + - dest: idpId + src: id + operationId: listSocialAuthTokens x-okta-tags: - - UserFactor - FactorResultType: - enum: - - SUCCESS - - CHALLENGE - - WAITING - - FAILED - - REJECTED - - TIMEOUT - - TIME_WINDOW_EXCEEDED - - PASSCODE_REPLAYED - - ERROR - type: string + - IdentityProvider + IdentityProviderApplicationUser: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + type: string + externalId: + type: string + id: + readOnly: true + type: string + lastUpdated: + type: string + profile: + additionalProperties: + type: object + type: object + type: object x-okta-tags: - - UserFactor - FactorStatus: - enum: - - PENDING_ACTIVATION - - ACTIVE - - INACTIVE - - NOT_SETUP - - ENROLLED - - DISABLED - - EXPIRED - type: string + - IdentityProvider + IdentityProviderCredentials: + properties: + client: + $ref: '#/definitions/IdentityProviderCredentialsClient' + signing: + $ref: '#/definitions/IdentityProviderCredentialsSigning' + trust: + $ref: '#/definitions/IdentityProviderCredentialsTrust' + type: object x-okta-tags: - - UserFactor - FactorType: - enum: - - push - - sms - - call - - token - - 'token:software:totp' - - 'token:hardware' - - question - - web - - email - - u2f - - webauthn - - 'token:software' - - custom - type: string + - IdentityProvider + IdentityProviderCredentialsClient: + properties: + client_id: + type: string + client_secret: + type: string + type: object x-okta-tags: - - UserFactor - ForgotPasswordResponse: + - IdentityProvider + IdentityProviderCredentialsSigning: properties: - resetPasswordUrl: - readOnly: true + kid: type: string + type: object x-okta-tags: - - User - Group: + - IdentityProvider + IdentityProviderCredentialsTrust: properties: - _embedded: - additionalProperties: - type: object - readOnly: true - type: object - _links: - additionalProperties: - type: object - readOnly: true - type: object - created: - format: date-time - readOnly: true - type: string - id: - readOnly: true + audience: type: string - lastMembershipUpdated: - format: date-time - readOnly: true + issuer: type: string - lastUpdated: - format: date-time - readOnly: true + kid: type: string - objectClass: - items: - type: string - readOnly: true - type: array - profile: - $ref: '#/definitions/GroupProfile' - type: - readOnly: true + revocation: + enum: + - CRL + - DELTA_CRL + - OCSP type: string + revocationCacheLifetime: + type: integer type: object - x-okta-crud: - - alias: update - arguments: - - dest: groupId - src: id - - dest: group - self: true - operationId: updateGroup - - alias: delete - arguments: - - dest: groupId - src: id - operationId: deleteGroup - x-okta-operations: - - alias: removeUser - arguments: - - dest: groupId - src: id - operationId: removeGroupUser - - alias: listUsers - arguments: - - dest: groupId - src: id - operationId: listGroupUsers x-okta-tags: - - Group - GroupCondition: + - IdentityProvider + IdentityProviderPolicy: properties: - exclude: - items: - type: string - type: array - include: + accountLink: + $ref: '#/definitions/PolicyAccountLink' + maxClockSkew: + type: integer + provisioning: + $ref: '#/definitions/Provisioning' + subject: + $ref: '#/definitions/PolicySubject' + type: object + x-okta-parent: '#/definitions/Policy' + x-okta-tags: + - Policy + IdentityProviderPolicyRuleCondition: + properties: + idpIds: items: type: string type: array + provider: + enum: + - ANY + - OKTA + - SPECIFIC_IDP + type: string + type: object x-okta-tags: - Policy - GroupProfile: + InactivityPolicyRuleCondition: properties: - description: - type: string - name: + number: + type: integer + unit: type: string type: object x-okta-tags: - - Group - GroupRule: + - Policy + InlineHook: properties: - _embedded: + _links: additionalProperties: type: object readOnly: true type: object - actions: - $ref: '#/definitions/GroupRuleAction' - allGroupsValid: - type: boolean - conditions: - $ref: '#/definitions/GroupRuleConditions' + channel: + $ref: '#/definitions/InlineHookChannel' created: format: date-time readOnly: true @@ -3481,128 +8598,207 @@ definitions: name: type: string status: - $ref: '#/definitions/GroupRuleStatus' - readOnly: true + $ref: '#/definitions/InlineHookStatus' type: + $ref: '#/definitions/InlineHookType' + version: type: string type: object x-okta-crud: + - alias: create + arguments: + - dest: inlineHook + self: true + operationId: createInlineHook + - alias: read + arguments: [] + operationId: getInlineHook - alias: update arguments: - - dest: ruleId + - dest: inlineHookId src: id - - dest: groupRule + - dest: inlineHook self: true - operationId: updateRule + operationId: updateInlineHook - alias: delete arguments: - - dest: ruleId + - dest: inlineHookId src: id - operationId: deleteRule + operationId: deleteInlineHook x-okta-operations: - alias: activate arguments: - - dest: ruleId + - dest: inlineHookId src: id - operationId: activateRule + operationId: activateInlineHook - alias: deactivate arguments: - - dest: ruleId + - dest: inlineHookId + src: id + operationId: deactivateInlineHook + - alias: execute + arguments: + - dest: inlineHookId src: id - operationId: deactivateRule + operationId: executeInlineHook x-okta-tags: - - GroupRule - GroupRuleAction: + - InlineHook + InlineHookChannel: properties: - assignUserToGroups: - $ref: '#/definitions/GroupRuleGroupAssignment' + config: + $ref: '#/definitions/InlineHookChannelConfig' + readOnly: false + type: + enum: + - HTTP + readOnly: false + type: string + version: + readOnly: false + type: string type: object x-okta-tags: - - GroupRule - GroupRuleConditions: + - InlineHook + InlineHookChannelConfig: properties: - expression: - $ref: '#/definitions/GroupRuleExpression' - people: - $ref: '#/definitions/GroupRulePeopleCondition' + authScheme: + $ref: '#/definitions/InlineHookChannelConfigAuthScheme' + type: object + headers: + items: + $ref: '#/definitions/InlineHookChannelConfigHeaders' + type: array + uri: + type: string type: object x-okta-tags: - - GroupRule - GroupRuleExpression: + - InlineHook + InlineHookChannelConfigAuthScheme: properties: + key: + type: string type: type: string value: type: string type: object x-okta-tags: - - GroupRule - GroupRuleGroupAssignment: + - InlineHook + InlineHookChannelConfigHeaders: properties: - groupIds: - items: - type: string - type: array + key: + type: string + value: + type: string type: object x-okta-tags: - - GroupRule - GroupRuleGroupCondition: + - InlineHook + InlineHookPayload: + type: object + x-okta-extensible: true + x-okta-tags: + - InlineHook + InlineHookResponse: properties: - exclude: - items: - type: string - type: array - include: + commands: items: - type: string + $ref: '#/definitions/InlineHookResponseCommands' type: array type: object x-okta-tags: - - GroupRule - GroupRulePeopleCondition: + - InlineHook + InlineHookResponseCommandValue: properties: - groups: - $ref: '#/definitions/GroupRuleGroupCondition' - users: - $ref: '#/definitions/GroupRuleUserCondition' - type: object + op: + type: string + path: + type: string + value: + type: string x-okta-tags: - - GroupRule - GroupRuleStatus: + - InlineHook + InlineHookResponseCommands: + properties: + type: + type: string + value: + items: + $ref: '#/definitions/InlineHookResponseCommandValue' + type: array + x-okta-tags: + - InlineHook + InlineHookStatus: enum: - ACTIVE - INACTIVE - - INVALID type: string x-okta-tags: - - GroupRule - GroupRuleUserCondition: + - InlineHook + InlineHookType: + enum: + - com.okta.oauth2.tokens.transform + - com.okta.import.transform + - com.okta.saml.tokens.transform + - com.okta.user.pre-registration + - com.okta.user.credential.password.import + type: string + x-okta-tags: + - InlineHook + IonField: properties: - exclude: + form: + $ref: '#/definitions/IonForm' + label: + type: string + mutable: + type: boolean + name: + type: string + required: + type: boolean + secret: + type: boolean + type: + type: string + value: + additionalProperties: + type: object + type: object + visible: + type: boolean + type: object + x-okta-tags: + - Ion + IonForm: + properties: + accepts: + type: string + href: + type: string + method: + type: string + name: + type: string + produces: + type: string + refresh: + type: integer + rel: items: type: string type: array - include: + relatesTo: items: type: string type: array + value: + items: + $ref: '#/definitions/IonField' + readOnly: true + type: array type: object x-okta-tags: - - GroupRule - HardwareFactor: - properties: - profile: - $ref: '#/definitions/HardwareFactorProfile' - x-okta-parent: '#/definitions/Factor' - x-okta-tags: - - UserFactor - HardwareFactorProfile: - properties: - credentialId: - type: string - x-okta-parent: '#/definitions/FactorProfile' - x-okta-tags: - - UserFactor + - Ion JsonWebKey: properties: _links: @@ -3651,7 +8847,7 @@ definitions: x5c: items: type: string - readOnly: true + readOnly: false type: array x5t: readOnly: true @@ -3659,12 +8855,80 @@ definitions: 'x5t#S256': readOnly: true type: string - x5u: - readOnly: true + x5u: + readOnly: true + type: string + type: object + x-okta-tags: + - Application + JwkUse: + properties: + use: + enum: + - sig + type: string + x-okta-tags: + - Application + LifecycleExpirationPolicyRuleCondition: + properties: + lifecycleStatus: + type: string + number: + type: integer + unit: + type: string + type: object + x-okta-tags: + - Policy + LinkedObject: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + name: + type: string + associated: + $ref: '#/definitions/LinkedObjectDetails' + primary: + $ref: '#/definitions/LinkedObjectDetails' + type: object + x-okta-crud: + - alias: create + arguments: + - dest: linkedObjectDefinition + self: true + operationId: addLinkedObjectDefinition + - alias: read + arguments: [] + operationId: getLinkedObjectDefinition + - alias: delete + arguments: + - dest: linkedObjectName + src: name + operationId: deleteLinkedObjectDefinition + x-okta-tags: + - LinkedObject + LinkedObjectDetails: + properties: + description: type: string + name: + type: string + title: + type: string + type: + $ref: '#/definitions/LinkedObjectDetailsType' type: object x-okta-tags: - - Application + - LinkedObject + LinkedObjectDetailsType: + enum: + - USER + type: string + x-okta-tags: + - LinkedObject LogActor: properties: alternateId: @@ -3697,15 +8961,9 @@ definitions: readOnly: true type: integer credentialProvider: - items: - $ref: '#/definitions/LogCredentialProvider' - readOnly: true - type: array + $ref: '#/definitions/LogCredentialProvider' credentialType: - items: - $ref: '#/definitions/LogCredentialType' - readOnly: true - type: array + $ref: '#/definitions/LogCredentialType' externalSessionId: readOnly: true type: string @@ -3982,29 +9240,322 @@ definitions: type: object readOnly: true type: object - id: - readOnly: true + id: + readOnly: true + type: string + type: + readOnly: true + type: string + type: object + x-okta-tags: + - Log + LogUserAgent: + properties: + browser: + readOnly: true + type: string + os: + readOnly: true + type: string + rawUserAgent: + readOnly: true + type: string + type: object + x-okta-tags: + - Log + MDMEnrollmentPolicyRuleCondition: + properties: + blockNonSafeAndroid: + type: boolean + enrollment: + enum: + - OMM + - ANY_OR_NONE + type: string + type: object + x-okta-tags: + - Policy + MDMFrameworks: + enum: + - authorization_code + - implicit + - password + - refresh_token + - client_credentials + type: string + x-okta-tags: + - Policy + OAuth2Actor: + properties: + id: + readOnly: true + type: string + type: + type: string + type: object + x-okta-tags: + - Application + OAuth2Claim: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + alwaysIncludeInToken: + type: boolean + claimType: + enum: + - IDENTITY + - RESOURCE + type: string + conditions: + $ref: '#/definitions/OAuth2ClaimConditions' + group_filter_type: + enum: + - STARTS_WITH + - EQUALS + - CONTAINS + - REGEX + type: string + id: + readOnly: true + type: string + name: + type: string + status: + enum: + - ACTIVE + - INACTIVE + type: string + system: + type: boolean + value: + type: string + valueType: + enum: + - EXPRESSION + - GROUPS + - SYSTEM + type: string + type: object + x-okta-tags: + - Application + OAuth2ClaimConditions: + properties: + scopes: + items: + type: string + type: array + type: object + x-okta-tags: + - Application + OAuth2Client: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + client_id: + readOnly: true + type: string + client_name: + readOnly: true + type: string + client_uri: + readOnly: true + type: string + logo_uri: + readOnly: true + type: string + type: object + x-okta-tags: + - Application + OAuth2RefreshToken: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + clientId: + type: string + created: + format: date-time + readOnly: true + type: string + createdBy: + $ref: '#/definitions/OAuth2Actor' + expiresAt: + format: date-time + readOnly: true + type: string + id: + readOnly: true + type: string + issuer: + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + scopes: + items: + type: string + type: array + status: + enum: + - ACTIVE + - REVOKED + type: string + userId: + type: string + type: object + x-okta-tags: + - Application + OAuth2Scope: + properties: + consent: + enum: + - REQUIRED + - IMPLICIT + - ADMIN + type: string + default: + type: boolean + description: + type: string + displayName: + type: string + id: + readOnly: true + type: string + metadataPublish: + enum: + - ALL_CLIENTS + - NO_CLIENTS + type: string + name: + type: string + system: + type: boolean + type: object + x-okta-tags: + - Application + OAuth2ScopeConsentGrant: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + clientId: + type: string + userId: + type: string + created: + format: date-time + readOnly: true + type: string + createdBy: + $ref: '#/definitions/OAuth2Actor' + id: + readOnly: true + type: string + issuer: + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + scopeId: + type: string + source: + $ref: '#/definitions/OAuth2ScopeConsentGrantSource' + status: + $ref: '#/definitions/OAuth2ScopeConsentGrantStatus' + type: object + x-okta-tags: + - Application + OAuth2ScopeConsentGrantSource: + enum: + - END_USER + - ADMIN + type: string + x-okta-tags: + - Application + OAuth2ScopeConsentGrantStatus: + enum: + - ACTIVE + - REVOKED + type: string + x-okta-tags: + - Application + OAuth2ScopesMediationPolicyRuleCondition: + properties: + include: + items: + type: string + type: array + type: object + x-okta-tags: + - Application + OAuth2Token: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + clientId: type: string - type: + created: + format: date-time readOnly: true type: string - type: object - x-okta-tags: - - Log - LogUserAgent: - properties: - browser: + expiresAt: + format: date-time readOnly: true type: string - os: + id: readOnly: true type: string - rawUserAgent: + issuer: + type: string + lastUpdated: + format: date-time readOnly: true type: string + scopes: + items: + type: string + type: array + status: + enum: + - ACTIVE + - REVOKED + type: string + userId: + type: string type: object x-okta-tags: - - Log + - Application OAuthApplicationCredentials: properties: oauthClient: @@ -4012,6 +9563,10 @@ definitions: x-okta-parent: '#/definitions/ApplicationCredentials' x-okta-tags: - Application + OAuthAuthorizationPolicy: + x-okta-parent: '#/definitions/Policy' + x-okta-tags: + - Policy OAuthEndpointAuthenticationMethod: enum: - none @@ -4051,6 +9606,7 @@ definitions: properties: people: $ref: '#/definitions/PolicyPeopleCondition' + x-okta-parent: '#/definition/PolicyRuleConditions' x-okta-tags: - Policy OktaSignOnPolicyRule: @@ -4140,6 +9696,13 @@ definitions: type: string x-okta-tags: - Application + OpenIdConnectApplicationIssuerMode: + enum: + - CUSTOM_URL + - ORG_URL + type: string + x-okta-tags: + - Application OpenIdConnectApplicationSettings: properties: oauthClient: @@ -4159,10 +9722,18 @@ definitions: items: $ref: '#/definitions/OAuthGrantType' type: array + initiate_login_uri: + type: string + issuer_mode: + $ref: '#/definitions/OpenIdConnectApplicationIssuerMode' logo_uri: type: string policy_uri: type: string + post_logout_redirect_uris: + items: + type: string + type: array redirect_uris: items: type: string @@ -4186,12 +9757,48 @@ definitions: - Application PasswordCredential: properties: + hash: + $ref: '#/definitions/PasswordCredentialHash' + hook: + $ref: '#/definitions/PasswordCredentialHook' value: format: password type: string type: object x-okta-tags: - User + PasswordCredentialHash: + properties: + algorithm: + $ref: '#/definitions/PasswordCredentialHashAlgorithm' + salt: + type: string + saltOrder: + type: string + value: + type: string + workerFactor: + type: integer + type: object + x-okta-tags: + - User + PasswordCredentialHashAlgorithm: + enum: + - BCRYPT + - SHA-512 + - SHA-256 + - SHA-1 + - MD5 + type: string + x-okta-tags: + - User + PasswordCredentialHook: + properties: + type: + type: string + type: object + x-okta-tags: + - User PasswordDictionary: properties: common: @@ -4207,6 +9814,15 @@ definitions: type: object x-okta-tags: - Policy + PasswordExpirationPolicyRuleCondition: + properties: + number: + type: integer + unit: + type: string + type: object + x-okta-tags: + - Policy PasswordPolicy: properties: conditions: @@ -4239,6 +9855,7 @@ definitions: $ref: '#/definitions/PasswordPolicyAuthenticationProviderCondition' people: $ref: '#/definitions/PolicyPeopleCondition' + x-okta-parent: '#/definition/PolicyRuleConditions' x-okta-tags: - Policy PasswordPolicyDelegationSettings: @@ -4471,6 +10088,72 @@ definitions: type: object x-okta-tags: - Policy + Platforms: + enum: + - IOS + - ANDROID + - OSX + - WINDOWS + type: string + x-okta-tags: + - Policy + PlatformConditionEvaluatorPlatform: + properties: + os: + $ref: '#/definitions/PlatformConditionEvaluatorPlatformOperatingSystem' + type: + enum: + - DESKTOP + - MOBILE + - OTHER + - ANY + type: string + type: object + x-okta-tags: + - Policy + PlatformConditionEvaluatorPlatformOperatingSystem: + properties: + expression: + type: string + type: + enum: + - ANDROID + - IOS + - WINDOWS + - OSX + - OTHER + - ANY + type: string + version: + $ref: '#/definitions/PlatformConditionEvaluatorPlatformOperatingSystemVersion' + type: object + x-okta-tags: + - Policy + PlatformConditionEvaluatorPlatformOperatingSystemVersion: + properties: + matchType: + enum: + - EXPRESSION + - SEMVER + type: string + value: + type: string + type: object + x-okta-tags: + - Policy + PlatformPolicyRuleCondition: + properties: + exclude: + items: + $ref: '#/definitions/PlatformConditionEvaluatorPlatform' + type: array + include: + items: + $ref: '#/definitions/PlatformConditionEvaluatorPlatform' + type: array + type: object + x-okta-tags: + - Policy Policy: properties: _embedded: @@ -4483,6 +10166,8 @@ definitions: type: object readOnly: true type: object + conditions: + $ref: '#/definitions/PolicyRuleConditions' created: format: date-time readOnly: true @@ -4548,7 +10233,7 @@ definitions: arguments: - dest: policyId src: id - operationId: addPolicyRule + operationId: createPolicyRule - alias: getPolicyRule arguments: - dest: policyId @@ -4558,9 +10243,39 @@ definitions: - Policy x-openapi-v3-discriminator: mapping: + IDP_DISCOVERY: '#/definitions/IdentityProviderPolicy' + OAUTH_AUTHORIZATION_POLICY: '#/definitions/OAuthAuthorizationPolicy' OKTA_SIGN_ON: '#/definitions/OktaSignOnPolicy' PASSWORD: '#/definitions/PasswordPolicy' propertyName: type + PolicyAccountLink: + properties: + action: + enum: + - AUTO + - DISABLED + type: string + filter: + $ref: '#/definitions/PolicyAccountLinkFilter' + type: object + x-okta-tags: + - Policy + PolicyAccountLinkFilter: + properties: + groups: + $ref: '#/definitions/PolicyAccountLinkFilterGroups' + type: object + x-okta-tags: + - Policy + PolicyAccountLinkFilterGroups: + properties: + include: + items: + type: string + type: array + type: object + x-okta-tags: + - Policy PolicyNetworkCondition: properties: connection: @@ -4595,6 +10310,7 @@ definitions: readOnly: true type: string id: + readOnly: true type: string lastUpdated: format: date-time @@ -4650,52 +10366,326 @@ definitions: parentSrc: policyId operationId: deactivatePolicyRule x-okta-tags: - - Policy - x-openapi-v3-discriminator: - mapping: - PASSWORD: '#/definitions/PasswordPolicyRule' - SIGN_ON: '#/definitions/OktaSignOnPolicyRule' - propertyName: type - PolicyRuleAuthContextCondition: + - Policy + x-openapi-v3-discriminator: + mapping: + PASSWORD: '#/definitions/PasswordPolicyRule' + SIGN_ON: '#/definitions/OktaSignOnPolicyRule' + propertyName: type + PolicyRuleAuthContextCondition: + properties: + authType: + enum: + - ANY + - RADIUS + type: string + type: object + x-okta-tags: + - Policy + PolicyRuleConditions: + properties: + app: + $ref: '#/definitions/AppAndInstancePolicyRuleCondition' + apps: + $ref: '#/definitions/AppInstancePolicyRuleCondition' + authContext: + $ref: '#/definitions/PolicyRuleAuthContextCondition' + authProvider: + $ref: '#/definitions/PasswordPolicyAuthenticationProviderCondition' + beforeScheduledAction: + $ref: '#/definitions/BeforeScheduledActionPolicyRuleCondition' + clients: + $ref: '#/definitions/ClientPolicyCondition' + context: + $ref: '#/definitions/ContextPolicyRuleCondition' + device: + $ref: '#/definitions/DevicePolicyRuleCondition' + grantTypes: + $ref: '#/definitions/GrantTypePolicyRuleCondition' + groups: + $ref: '#/definitions/GroupPolicyRuleCondition' + identityProvider: + $ref: '#/definitions/IdentityProviderPolicyRuleCondition' + mdmEnrollment: + $ref: '#/definitions/MDMEnrollmentPolicyRuleCondition' + network: + $ref: '#/definitions/PolicyNetworkCondition' + people: + $ref: '#/definitions/PolicyPeopleCondition' + platform: + $ref: '#/definitions/PlatformPolicyRuleCondition' + risk: + $ref: '#/definitions/RiskPolicyRuleCondition' + riskScore: + $ref: '#/definitions/RiskScorePolicyRuleCondition' + scopes: + $ref: '#/definitions/OAuth2ScopesMediationPolicyRuleCondition' + userIdentifier: + $ref: '#/definitions/UserIdentifierPolicyRuleCondition' + userStatus: + $ref: '#/definitions/UserStatusPolicyRuleCondition' + users: + $ref: '#/definitions/UserPolicyRuleCondition' + type: object + x-okta-tags: + - Policy + PolicySubject: + properties: + filter: + type: string + format: + items: + type: string + type: array + matchAttribute: + type: string + matchType: + $ref: '#/definitions/PolicySubjectMatchType' + userNameTemplate: + $ref: '#/definitions/PolicyUserNameTemplate' + type: object + x-okta-tags: + - Policy + PolicySubjectMatchType: + enum: + - USERNAME + - EMAIL + - USERNAME_OR_EMAIL + - CUSTOM_ATTRIBUTE + type: string + x-okta-tags: + - Policy + PolicyType: + enum: + - OAUTH_AUTHORIZATION_POLICY + - OKTA_SIGN_ON + - PASSWORD + - IDP_DISCOVERY + type: string + x-okta-tags: + - Policy + PolicyUserNameTemplate: + properties: + template: + type: string + type: object + x-okta-tags: + - Policy + Protocol: + properties: + algorithms: + $ref: '#/definitions/ProtocolAlgorithms' + credentials: + $ref: '#/definitions/IdentityProviderCredentials' + endpoints: + $ref: '#/definitions/ProtocolEndpoints' + issuer: + $ref: '#/definitions/ProtocolEndpoint' + relayState: + $ref: '#/definitions/ProtocolRelayState' + scopes: + items: + type: string + type: array + settings: + $ref: '#/definitions/ProtocolSettings' + type: + enum: + - SAML2 + - OIDC + - OAUTH2 + - MTLS + type: string + type: object + x-okta-tags: + - IdentityProvider + ProtocolAlgorithmType: + properties: + signature: + $ref: '#/definitions/ProtocolAlgorithmTypeSignature' + type: object + x-okta-tags: + - IdentityProvider + ProtocolAlgorithmTypeSignature: + properties: + algorithm: + type: string + scope: + enum: + - RESPONSE + - TOKEN + - ANY + - REQUEST + - NONE + type: string + type: object + x-okta-tags: + - IdentityProvider + ProtocolAlgorithms: + properties: + request: + $ref: '#/definitions/ProtocolAlgorithmType' + response: + $ref: '#/definitions/ProtocolAlgorithmType' + type: object + x-okta-tags: + - IdentityProvider + ProtocolEndpoint: + properties: + binding: + enum: + - HTTP-POST + - HTTP-REDIRECT + type: string + destination: + type: string + type: + enum: + - INSTANCE + - ORG + type: string + url: + type: string + type: object + x-okta-tags: + - IdentityProvider + ProtocolEndpoints: + properties: + acs: + $ref: '#/definitions/ProtocolEndpoint' + authorization: + $ref: '#/definitions/ProtocolEndpoint' + jwks: + $ref: '#/definitions/ProtocolEndpoint' + metadata: + $ref: '#/definitions/ProtocolEndpoint' + slo: + $ref: '#/definitions/ProtocolEndpoint' + sso: + $ref: '#/definitions/ProtocolEndpoint' + token: + $ref: '#/definitions/ProtocolEndpoint' + userInfo: + $ref: '#/definitions/ProtocolEndpoint' + type: object + x-okta-tags: + - IdentityProvider + ProtocolRelayState: + properties: + format: + $ref: '#/definitions/ProtocolRelayStateFormat' + type: object + x-okta-tags: + - IdentityProvider + ProtocolRelayStateFormat: + enum: + - OPAQUE + - FROM_URL + type: string + x-okta-tags: + - IdentityProvider + ProtocolSettings: + properties: + nameFormat: + type: string + type: object + x-okta-tags: + - IdentityProvider + Provisioning: + properties: + action: + enum: + - AUTO + - CALLOUT + - DISABLED + type: string + conditions: + $ref: '#/definitions/ProvisioningConditions' + groups: + $ref: '#/definitions/ProvisioningGroups' + profileMaster: + type: boolean + type: object + x-okta-tags: + - IdentityProvider + ProvisioningConditions: + properties: + deprovisioned: + $ref: '#/definitions/ProvisioningDeprovisionedCondition' + suspended: + $ref: '#/definitions/ProvisioningSuspendedCondition' + type: object + x-okta-tags: + - IdentityProvider + ProvisioningDeprovisionedCondition: properties: - authType: + action: enum: - - ANY - - RADIUS + - NONE + - REACTIVATE type: string type: object x-okta-tags: - - Policy - PolicyType: - enum: - - OAUTH_AUTHORIZATION_POLICY - - OKTA_SIGN_ON - - PASSWORD - type: string + - IdentityProvider + ProvisioningGroups: + properties: + action: + enum: + - NONE + - APPEND + - SYNC + - ASSIGN + type: string + assignments: + items: + type: string + type: array + filter: + items: + type: string + type: array + sourceAttributeName: + type: string + type: object x-okta-tags: - - Policy - PushFactor: + - IdentityProvider + ProvisioningSuspendedCondition: + properties: + action: + enum: + - NONE + - UNSUSPEND + type: string + type: object + x-okta-tags: + - IdentityProvider + PushUserFactor: properties: + expiresAt: + format: date-time + type: string + readOnly: true + factorResult: + $ref: '#/definitions/FactorResultType' profile: - $ref: '#/definitions/PushFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/PushUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - PushFactorProfile: + PushUserFactorProfile: properties: credentialId: type: string + deviceToken: + type: string deviceType: - readOnly: true type: string name: type: string platform: - readOnly: true type: string version: type: string - x-okta-parent: '#/definitions/FactorProfile' x-okta-tags: - UserFactor RecoveryQuestionCredential: @@ -4715,6 +10705,28 @@ definitions: type: object x-okta-tags: - User + ResponseLinks: + properties: {} + type: object + x-okta-tags: + - User + RiskPolicyRuleCondition: + properties: + behaviors: + items: + type: string + type: array + uniqueItems: true + type: object + x-okta-tags: + - Policy + RiskScorePolicyRuleCondition: + properties: + level: + type: string + type: object + x-okta-tags: + - Policy Role: properties: _embedded: @@ -4728,9 +10740,7 @@ definitions: readOnly: true type: object assignmentType: - enum: - - GROUP - - USER + $ref: '#/definitions/RoleAssignmentType' type: string created: format: date-time @@ -4752,10 +10762,61 @@ definitions: $ref: '#/definitions/RoleStatus' readOnly: true type: + $ref: '#/definitions/RoleType' type: string type: object x-okta-tags: - User + x-okta-operations: + - alias: addAdminGroupTarget + arguments: + - dest: roleId + src: id + - dest: groupId + parentSrc: id + operationId: addGroupTargetToGroupAdministratorRoleForGroup + - alias: addAppInstanceTargetToAdminRole + arguments: + - dest: roleId + src: id + - dest: groupId + parentSrc: id + operationId: addApplicationInstanceTargetToAppAdminRoleGivenToGroup + - alias: addAppTargetToAdminRole + arguments: + - dest: roleId + src: id + - dest: groupId + parentSrc: id + operationId: addApplicationTargetToAdminRoleGivenToGroup + - alias: addAllAppsAsTargetToRole + arguments: + - dest: roleId + src: id + - dest: userId + parentSrc: id + operationId: addAllAppsAsTargetToRole + - alias: addAppTargetToAppAdminRoleForUser + arguments: + - dest: roleId + src: id + - dest: userId + parentSrc: id + operationId: addApplicationTargetToAppAdminRoleForUser + - alias: addAppTargetToAdminRoleForUser + arguments: + - dest: roleId + src: id + - dest: userId + parentSrc: id + operationId: addApplicationTargetToAdminRoleForUser + RoleAssignmentType: + enum: + - GROUP + - USER + type: string + x-okta-tags: + - Role RoleStatus: enum: - ACTIVE @@ -4763,6 +10824,20 @@ definitions: type: string x-okta-tags: - User + RoleType: + enum: + - SUPER_ADMIN + - ORG_ADMIN + - APP_ADMIN + - USER_ADMIN + - HELP_DESK_ADMIN + - READ_ONLY_ADMIN + - MOBILE_ADMIN + - API_ACCESS_MANAGEMENT_ADMIN + - REPORT_ADMIN + type: string + x-okta-tags: + - Role SamlApplication: properties: settings: @@ -4839,6 +10914,22 @@ definitions: type: array x-okta-tags: - Application + ScheduledUserLifecycleAction: + properties: + status: + enum: + - ACTIVE + - INACTIVE + - PENDING + - DELETED + - EXPIRED_PASSWORD + - ACTIVATING + - SUSPENDED + - DELETING + type: string + type: object + x-okta-tags: + - Policy SchemeApplicationCredentials: properties: password: @@ -4854,6 +10945,22 @@ definitions: x-okta-parent: '#/definitions/ApplicationCredentials' x-okta-tags: - Application + Scope: + properties: + stringValue: + type: string + type: + $ref: '#/definitions/ScopeType' + type: object + x-okta-tags: + - Role + ScopeType: + enum: + - CORS + - REDIRECT + type: string + x-okta-tags: + - Role SecurePasswordStoreApplication: properties: credentials: @@ -4907,14 +11014,14 @@ definitions: type: string x-okta-tags: - UserFactor - SecurityQuestionFactor: + SecurityQuestionUserFactor: properties: profile: - $ref: '#/definitions/SecurityQuestionFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/SecurityQuestionUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - SecurityQuestionFactorProfile: + SecurityQuestionUserFactorProfile: properties: answer: type: string @@ -4922,7 +11029,6 @@ definitions: type: string questionText: type: string - x-okta-parent: '#/definitions/FactorProfile' x-okta-tags: - UserFactor Session: @@ -5032,20 +11138,108 @@ definitions: type: string x-okta-tags: - Session - SmsFactor: + SmsTemplate: + properties: + created: + format: date-time + readOnly: true + type: string + id: + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + name: + type: string + template: + type: string + translations: + $ref: '#/definitions/SmsTemplateTranslations' + type: + $ref: '#/definitions/SmsTemplateType' + type: object + x-okta-crud: + - alias: create + arguments: + - dest: smsTemplate + self: true + operationId: createSmsTemplate + - alias: read + arguments: [] + operationId: getSmsTemplate + - alias: update + arguments: + - dest: templateId + src: id + - dest: smsTemplate + self: true + operationId: updateSmsTemplate + - alias: delete + arguments: + - dest: templateId + src: id + operationId: deleteSmsTemplate + x-okta-operations: + - alias: partialUpdate + arguments: + - dest: templateId + src: id + - dest: smsTemplate + self: true + operationId: partialUpdateSmsTemplate + x-okta-tags: + - Template + SmsTemplateTranslations: + type: object + x-okta-extensible: true + x-okta-tags: + - Template + SmsTemplateType: + enum: + - SMS_VERIFY_CODE + type: string + x-okta-tags: + - Template + SmsUserFactor: properties: profile: - $ref: '#/definitions/SmsFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/SmsUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - SmsFactorProfile: + SmsUserFactorProfile: properties: phoneNumber: type: string - x-okta-parent: '#/definitions/FactorProfile' x-okta-tags: - UserFactor + SocialAuthToken: + properties: + expiresAt: + format: date-time + readOnly: true + type: string + id: + readOnly: true + type: string + scopes: + items: + type: string + type: array + token: + type: string + tokenAuthScheme: + type: string + tokenType: + enum: + - ACCESS + - REFRESH + type: string + type: object + x-okta-tags: + - IdentityProvider SwaApplication: properties: name: @@ -5109,7 +11303,7 @@ definitions: type: string passwordSelector: type: string - targetUrl: + targetURL: type: string userNameSelector: type: string @@ -5123,43 +11317,99 @@ definitions: type: string x-okta-tags: - User - TokenFactor: + TokenUserFactor: properties: profile: - $ref: '#/definitions/TokenFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/TokenUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - TokenFactorProfile: + TokenUserFactorProfile: properties: credentialId: type: string - x-okta-parent: '#/definitions/FactorProfile' x-okta-tags: - UserFactor - TotpFactor: + TotpUserFactor: properties: profile: - $ref: '#/definitions/TotpFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/TotpUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - TotpFactorProfile: + TotpUserFactorProfile: properties: credentialId: type: string - x-okta-parent: '#/definitions/FactorProfile' x-okta-tags: - UserFactor - U2fFactor: + TrustedOrigin: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + format: date-time + readOnly: true + type: string + createdBy: + type: string + id: + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + lastUpdatedBy: + type: string + name: + type: string + origin: + type: string + scopes: + items: + $ref: '#/definitions/Scope' + type: array + status: + type: string + type: object + x-okta-crud: + - alias: create + arguments: + - dest: trustedOrigin + self: true + operationId: createOrigin + - alias: read + arguments: [] + operationId: getOrigin + - alias: update + arguments: + - dest: trustedOriginId + src: id + - dest: trustedOrigin + self: true + operationId: updateOrigin + - alias: delete + arguments: + - dest: trustedOriginId + src: id + operationId: deleteOrigin + x-okta-tags: + - TrustedOrigin + U2fUserFactor: properties: profile: - $ref: '#/definitions/U2fFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/U2fUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - U2fFactorProfile: - x-okta-parent: '#/definitions/FactorProfile' + U2fUserFactorProfile: + properties: + credentialId: + type: string x-okta-tags: - UserFactor User: @@ -5211,6 +11461,8 @@ definitions: transitioningToStatus: $ref: '#/definitions/UserStatus' readOnly: true + type: + $ref: '#/definitions/UserType' type: object x-okta-crud: - alias: create @@ -5236,11 +11488,6 @@ definitions: self: true operationId: deactivateOrDeleteUser x-okta-operations: - - alias: endAllSessions - arguments: - - dest: userId - src: id - operationId: endAllUserSessions - alias: listAppLinks arguments: - dest: userId @@ -5255,52 +11502,112 @@ definitions: arguments: - dest: userId src: id - operationId: changeRecoveryQuestion - - alias: forgotPassword + operationId: changeRecoveryQuestion + - alias: forgotPasswordSetNewPassword + arguments: + - dest: userId + src: id + operationId: forgotPasswordSetNewPassword + - alias: forgotPasswordGenerateOneTimeToken + arguments: + - dest: userId + src: id + operationId: forgotPasswordGenerateOneTimeToken + - alias: assignRole + arguments: + - dest: userId + src: id + operationId: assignRoleToUser + - alias: removeRole + arguments: + - dest: userId + src: id + operationId: removeRoleFromUser + - alias: listGroupTargets + arguments: + - dest: userId + src: id + operationId: listGroupTargetsForRole + - alias: removeGroupTarget + arguments: + - dest: userId + src: id + operationId: removeGroupTargetFromRole + - alias: addGroupTarget + arguments: + - dest: userId + src: id + operationId: addGroupTargetToRole + - alias: listAssignedRoles + arguments: + - dest: userId + src: id + operationId: listAssignedRolesForUser + - alias: addAllAppsAsTarget + arguments: + - dest: userId + src: id + operationId: addAllAppsAsTargetToRole + - alias: listGroups + arguments: + - dest: userId + src: id + operationId: listUserGroups + - alias: listGrants + arguments: + - dest: userId + src: id + operationId: listUserGrants + - alias: revokeGrants arguments: - dest: userId src: id - operationId: forgotPassword - - alias: listRoles + operationId: revokeUserGrants + - alias: revokeGrant arguments: - dest: userId src: id - operationId: listAssignedRoles - - alias: addRole + operationId: revokeUserGrant + - alias: revokeGrantsForUserAndClient arguments: - dest: userId src: id - operationId: addRoleToUser - - alias: removeRole + operationId: revokeGrantsForUserAndClient + - alias: listRefreshTokensForUserAndClient arguments: - dest: userId src: id - operationId: removeRoleFromUser - - alias: listGroupTargetsForRole + operationId: listRefreshTokensForUserAndClient + - alias: revokeTokenForUserAndClient arguments: - dest: userId src: id - operationId: listGroupTargetsForRole - - alias: removeGroupTargetFromRole + operationId: revokeTokenForUserAndClient + - alias: getRefreshTokenForUserAndClient arguments: - dest: userId src: id - operationId: removeGroupTargetFromRole - - alias: addGroupTargetToRole + operationId: getRefreshTokenForUserAndClient + - alias: revokeTokensForUserAndClient arguments: - dest: userId src: id - operationId: addGroupTargetToRole - - alias: listGroups + operationId: revokeTokensForUserAndClient + - alias: listClients arguments: - dest: userId src: id - operationId: listUserGroups + operationId: listUserClients - alias: activate arguments: - dest: userId src: id operationId: activateUser + - alias: reactivate + arguments: + - dest: userId + src: id + operationId: reactivateUser - alias: deactivate arguments: - dest: userId @@ -5326,6 +11633,11 @@ definitions: - dest: userId src: id operationId: expirePassword + - alias: expirePasswordAndGetTemporaryPassword + arguments: + - dest: userId + src: id + operationId: expirePasswordAndGetTemporaryPassword - alias: unlock arguments: - dest: userId @@ -5335,17 +11647,23 @@ definitions: arguments: - dest: userId src: id - operationId: resetAllFactors + operationId: resetFactors + - alias: deleteFactor + arguments: + - dest: userId + src: id + operationId: deleteFactor - alias: addToGroup arguments: - dest: userId src: id + description: Adds a user to a group with 'OKTA_GROUP' type operationId: addUserToGroup - - alias: addFactor + - alias: enrollFactor arguments: - dest: userId src: id - operationId: addFactor + operationId: enrollFactor - alias: listSupportedFactors arguments: - dest: userId @@ -5366,6 +11684,31 @@ definitions: - dest: userId src: id operationId: getFactor + - alias: setLinkedObject + arguments: + - dest: associatedUserId + src: id + operationId: setLinkedObjectForUser + - alias: listIdentityProviders + arguments: + - dest: userId + src: id + operationId: listUserIdentityProviders + - alias: getLinkedObjects + arguments: + - dest: userId + src: id + operationId: getLinkedObjectsForUser + - alias: clearSessions + arguments: + - dest: userId + src: id + operationId: clearUserSessions + - alias: removeLinkedObject + arguments: + - dest: userId + src: id + operationId: removeLinkedObjectForUser x-okta-tags: - User UserActivationToken: @@ -5393,10 +11736,6 @@ definitions: - Policy UserCredentials: properties: - emails: - items: - $ref: '#/definitions/EmailAddress' - type: array password: $ref: '#/definitions/PasswordCredential' provider: @@ -5406,59 +11745,335 @@ definitions: type: object x-okta-tags: - User + UserFactor: + properties: + _embedded: + additionalProperties: + type: object + readOnly: true + type: object + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + format: date-time + readOnly: true + type: string + factorType: + $ref: '#/definitions/FactorType' + id: + readOnly: true + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + provider: + $ref: '#/definitions/FactorProvider' + status: + $ref: '#/definitions/FactorStatus' + readOnly: true + type: string + verify: + $ref: '#/definitions/VerifyFactorRequest' + type: object + x-okta-crud: + - alias: deleteFactor + arguments: + - dest: factorId + src: id + - dest: userId + parentSrc: id + operationId: deleteFactor + x-okta-operations: + - alias: activate + arguments: + - dest: factorId + src: id + - dest: userId + parentSrc: id + operationId: activateFactor + - alias: verify + arguments: + - dest: factorId + src: id + - dest: userId + parentSrc: id + operationId: verifyFactor + x-okta-tags: + - UserFactor + x-openapi-v3-discriminator: + mapping: + call: '#/definitions/CallUserFactor' + email: '#/definitions/EmailUserFactor' + push: '#/definitions/PushUserFactor' + question: '#/definitions/SecurityQuestionUserFactor' + sms: '#/definitions/SmsUserFactor' + token: '#/definitions/TokenUserFactor' + 'token:hardware': '#/definitions/HardwareUserFactor' + 'token:software:totp': '#/definitions/TotpUserFactor' + u2f: '#/definitions/U2fUserFactor' + web: '#/definitions/WebUserFactor' + webauthn: '#/definitions/WebAuthnUserFactor' + propertyName: factorType + UserIdentifierConditionEvaluatorPattern: + properties: + matchType: + enum: + - SUFFIX + - EXPRESSION + - STARTS_WITH + - EQUALS + - CONTAINS + type: string + value: + type: string + type: object + x-okta-tags: + - Policy + UserIdentifierPolicyRuleCondition: + properties: + attribute: + type: string + patterns: + items: + $ref: '#/definitions/UserIdentifierConditionEvaluatorPattern' + type: array + type: + enum: + - IDENTIFIER + - ATTRIBUTE + type: string + type: object + x-okta-tags: + - Policy + UserIdentityProviderLinkRequest: + properties: + externalId: + type: string + type: object + x-okta-tags: + - Policy + UserLifecycleAttributePolicyRuleCondition: + properties: + attributeName: + type: string + matchingValue: + type: string + type: object + x-okta-tags: + - Policy UserNextLogin: enum: - changePassword type: string x-okta-tags: - User + UserPolicyRuleCondition: + properties: + exclude: + items: + type: string + type: array + inactivity: + $ref: '#/definitions/InactivityPolicyRuleCondition' + include: + items: + type: string + type: array + lifecycleExpiration: + $ref: '#/definitions/LifecycleExpirationPolicyRuleCondition' + passwordExpiration: + $ref: '#/definitions/PasswordExpirationPolicyRuleCondition' + userLifecycleAttribute: + $ref: '#/definitions/UserLifecycleAttributePolicyRuleCondition' + type: object + x-okta-tags: + - Policy UserProfile: properties: + city: + type: string + costCenter: + type: string + countryCode: + type: string + department: + type: string + displayName: + type: string + division: + type: string email: type: string + employeeNumber: + type: string firstName: type: string + honorificPrefix: + type: string + honorificSuffix: + type: string lastName: type: string + locale: + type: string login: type: string + manager: + type: string + managerId: + type: string + middleName: + type: string mobilePhone: type: string + nickName: + type: string + organization: + type: string + postalAddress: + type: string + preferredLanguage: + type: string + primaryPhone: + type: string + profileUrl: + type: string secondEmail: type: string + state: + type: string + streetAddress: + type: string + timezone: + type: string + title: + type: string + userType: + type: string + zipCode: + type: string type: object x-okta-extensible: true x-okta-tags: - User UserStatus: enum: - - STAGED - - PROVISIONED - ACTIVE - - RECOVERY - - PASSWORD_EXPIRED - - LOCKED_OUT - DEPROVISIONED + - LOCKED_OUT + - PASSWORD_EXPIRED + - PROVISIONED + - RECOVERY + - STAGED - SUSPENDED type: string x-okta-tags: - User + UserStatusPolicyRuleCondition: + properties: + value: + enum: + - ACTIVE + - INACTIVE + - PENDING + - DELETED + - EXPIRED_PASSWORD + - ACTIVATING + - SUSPENDED + - DELETING + type: string + type: object + x-okta-tags: + - Policy + UserType: + properties: + _links: + additionalProperties: + type: object + readOnly: true + type: object + created: + format: date-time + readOnly: true + type: string + createdBy: + readOnly: true + type: string + default: + readOnly: true + type: boolean + description: + type: string + displayName: + type: string + id: + type: string + lastUpdated: + format: date-time + readOnly: true + type: string + lastUpdatedBy: + readOnly: true + type: string + name: + type: string + type: object + x-okta-crud: + - alias: create + arguments: + - dest: userType + self: true + operationId: createUserType + - alias: update + arguments: + - dest: typeId + src: id + - dest: userType + self: true + operationId: updateUserType + - alias: read + arguments: + - dest: typeId + src: id + operationId: getUserType + - alias: delete + arguments: + - dest: typeId + src: id + operationId: deleteUserType + x-okta-operations: + - alias: replaceUserType + arguments: + - dest: roleId + src: id + operationId: replaceUserType + x-okta-tags: + - User VerifyFactorRequest: properties: activationToken: type: string answer: type: string + attestation: + type: string + clientData: + type: string nextPassCode: type: string passCode: type: string - tokenLifetimeSeconds: - type: integer - type: object + registrationData: + type: string + stateToken: + type: string x-okta-tags: - UserFactor - VerifyFactorResponse: + VerifyUserFactorResponse: properties: _embedded: additionalProperties: @@ -5471,30 +12086,51 @@ definitions: readOnly: true type: object expiresAt: - format: date-time - readOnly: true type: string factorResult: - $ref: '#/definitions/FactorResultType' - readOnly: true + enum: + - SUCCESS + - EXPIRED + - CHALLENGE + - WAITING + - FAILED + - REJECTED + - TIMEOUT + - TIME_WINDOW_EXCEEDED + - PASSCODE_REPLAYED + - ERROR + type: string factorResultMessage: - readOnly: true type: string type: object x-okta-tags: - UserFactor - WebFactor: + WebUserFactor: + properties: + profile: + $ref: '#/definitions/WebUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' + x-okta-tags: + - UserFactor + WebUserFactorProfile: + properties: + credentialId: + type: string + x-okta-tags: + - UserFactor + WebAuthnUserFactor: properties: profile: - $ref: '#/definitions/WebFactorProfile' - x-okta-parent: '#/definitions/Factor' + $ref: '#/definitions/WebAuthnUserFactorProfile' + x-okta-parent: '#/definitions/UserFactor' x-okta-tags: - UserFactor - WebFactorProfile: + WebAuthnUserFactorProfile: properties: credentialId: type: string - x-okta-parent: '#/definitions/FactorProfile' + authenticatorName: + type: string x-okta-tags: - UserFactor WsFederationApplication: diff --git a/swagger-templates/pom.xml b/swagger-templates/pom.xml index 23728a09b3d..d5df8637bc6 100644 --- a/swagger-templates/pom.xml +++ b/swagger-templates/pom.xml @@ -21,7 +21,7 @@ com.okta.sdk okta-sdk-root - 1.6.1-SNAPSHOT + 2.0.0-SNAPSHOT okta-api-swagger-templates diff --git a/swagger-templates/src/main/java/com/okta/swagger/codegen/AbstractOktaJavaClientCodegen.java b/swagger-templates/src/main/java/com/okta/swagger/codegen/AbstractOktaJavaClientCodegen.java index 8880cf03361..96b957ec77c 100644 --- a/swagger-templates/src/main/java/com/okta/swagger/codegen/AbstractOktaJavaClientCodegen.java +++ b/swagger-templates/src/main/java/com/okta/swagger/codegen/AbstractOktaJavaClientCodegen.java @@ -282,10 +282,12 @@ private void addAllIfNotNull(List destList, List srcList } private void handleOktaLinkedOperations(Swagger swagger) { - // we want to move any operations defined by the 'x-okta-operations' or 'x-okta-crud' vendor extension to the model + // we want to move any operations defined by the 'x-okta-operations' or 'x-okta-crud' + // or 'x-okta-multi-operation' vendor extension to the model Map modelMap = swagger.getDefinitions().entrySet().stream() .filter(e -> e.getValue().getVendorExtensions().containsKey("x-okta-operations") - || e.getValue().getVendorExtensions().containsKey("x-okta-crud")) + || e.getValue().getVendorExtensions().containsKey("x-okta-crud") + || e.getValue().getVendorExtensions().containsKey("x-okta-multi-operation")) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); @@ -294,6 +296,7 @@ private void handleOktaLinkedOperations(Swagger swagger) { addAllIfNotNull(linkNodes, (List) model.getVendorExtensions().get("x-okta-operations")); addAllIfNotNull(linkNodes, (List) model.getVendorExtensions().get("x-okta-crud")); + addAllIfNotNull(linkNodes, (List) model.getVendorExtensions().get("x-okta-multi-operation")); Map operationMap = new HashMap<>(); @@ -302,7 +305,10 @@ private void handleOktaLinkedOperations(Swagger swagger) { // find the swagger path operation swagger.getPaths().forEach((pathName, path) -> { - Optional> operationEntry = path.getOperationMap().entrySet().stream().filter(e -> e.getValue().getOperationId().equals(operationId)).findFirst(); + Optional> operationEntry = + path.getOperationMap().entrySet().stream().filter( + e -> e.getValue().getOperationId() != null && + e.getValue().getOperationId().equals(operationId)).findFirst(); if (operationEntry.isPresent()) { @@ -768,7 +774,9 @@ private void addOptionalArgs(CodegenOperation co, List params) } private void addBackwardCompatibleArgs(CodegenOperation co, List params) { - if (params.parallelStream().anyMatch(param -> param.vendorExtensions.containsKey("x-okta-added-version"))) { + // add backward compatible args only for major revisions greater than 1 + if (params.parallelStream().anyMatch(param -> param.vendorExtensions.containsKey("x-okta-added-version") && + Integer.parseInt(param.vendorExtensions.get("x-okta-added-version").toString().substring(0, 1)) > 1)) { // capture the backward compat params Map> versionedParamsMap = new LinkedHashMap<>(); diff --git a/swagger-templates/src/main/java/com/okta/swagger/codegen/OktaJavaClientImplCodegen.java b/swagger-templates/src/main/java/com/okta/swagger/codegen/OktaJavaClientImplCodegen.java index 991e0dc9f11..eff3c05f962 100644 --- a/swagger-templates/src/main/java/com/okta/swagger/codegen/OktaJavaClientImplCodegen.java +++ b/swagger-templates/src/main/java/com/okta/swagger/codegen/OktaJavaClientImplCodegen.java @@ -24,16 +24,11 @@ import io.swagger.models.Operation; import io.swagger.models.Swagger; import org.apache.commons.lang3.BooleanUtils; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -317,20 +312,5 @@ protected void buildDiscriminationMap(Swagger swagger) { } catch (IOException e) { throw new RuntimeException("Failed to write discrimination map to json: "+ destFileJson.getAbsolutePath(), e); } - - // deprecated, use JSON going forward to remove the runtime dependency on a YAML parser - File destFileYaml = new File(destDir, "/discrimination.yaml"); - try (OutputStream outputStream = new FileOutputStream(destFileYaml)) { - - // pretty print - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setPrettyFlow(true); - Yaml yaml = new Yaml(options); - Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8); - yaml.dump(rootConfigMap, writer); - } catch (IOException e) { - throw new RuntimeException("Failed to write discrimination map to yaml: "+ destFileYaml.getAbsolutePath(), e); - } } } \ No newline at end of file diff --git a/swagger-templates/src/main/resources/OktaJava/Factor.mustache b/swagger-templates/src/main/resources/OktaJava/Factor.mustache deleted file mode 100644 index 8391bfb5814..00000000000 --- a/swagger-templates/src/main/resources/OktaJava/Factor.mustache +++ /dev/null @@ -1,44 +0,0 @@ -{{! - Copyright 2018-Present Okta, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - 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. -}} - - /** - * Verify MFA Factor - * Verifies an OTP for a `token` or `token:hardware` factor - * @param templateId (required) - * @param body (required) - * @return VerifyFactorResponse - * @deprecated use {@link Factor#verify(VerifyFactorRequest, String)} - */ - @javax.annotation.Generated( - value = "com.okta.swagger.codegen.OktaJavaClientApiCodegen", - comments = "POST - /api/v1/users/{userId}/factors/{factorId}/verify") - @Deprecated - VerifyFactorResponse verify(String templateId, VerifyFactorRequest body); - - /** - * Verify MFA Factor - * Verifies an OTP for a `token` or `token:hardware` factor - * @param templateId (optional) - * @param tokenLifetimeSeconds (optional, default to 300) - * @param body (required) - * @return VerifyFactorResponse - * @deprecated use {@link Factor#verify(VerifyFactorRequest, String, Integer)} - */ - @javax.annotation.Generated( - value = "com.okta.swagger.codegen.OktaJavaClientApiCodegen", - comments = "POST - /api/v1/users/{userId}/factors/{factorId}/verify") - @Deprecated - VerifyFactorResponse verify(String templateId, Integer tokenLifetimeSeconds, VerifyFactorRequest body); \ No newline at end of file diff --git a/swagger-templates/src/main/resources/OktaJava/User.mustache b/swagger-templates/src/main/resources/OktaJava/User.mustache deleted file mode 100644 index 538835f3ff8..00000000000 --- a/swagger-templates/src/main/resources/OktaJava/User.mustache +++ /dev/null @@ -1,62 +0,0 @@ -{{! - Copyright 2018-Present Okta, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - 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. -}} - - /** - * Enroll Factor - * Enrolls a user with a supported factor. - * @param updatePhone (optional, default to false) - * @param templateId id of SMS template (only for SMS factor) (optional) - * @param tokenLifetimeSeconds (optional, default to 300) - * @param activate (optional, default to false) - * @param body Factor (required) - * @return Factor - * @deprecated use {@link User#addFactor(Factor, Boolean, String, Integer, Boolean)} - */ - @javax.annotation.Generated( - value = "com.okta.swagger.codegen.OktaJavaClientApiCodegen", - comments = "POST - /api/v1/users/{userId}/factors") - @Deprecated - Factor addFactor(Boolean updatePhone, String templateId, Integer tokenLifetimeSeconds, Boolean activate, Factor body); - - /** - * Enroll Factor - * Enrolls a user with a supported factor. - * @param updatePhone (optional, default to false) - * @param templateId id of SMS template (only for SMS factor) (optional) - * @param body Factor (required) - * @return Factor - * @deprecated use {@link User#addFactor(Factor, Boolean, String)} - */ - @javax.annotation.Generated( - value = "com.okta.swagger.codegen.OktaJavaClientApiCodegen", - comments = "POST - /api/v1/users/{userId}/factors") - @Deprecated - Factor addFactor(Boolean updatePhone, String templateId, Factor body); - - /** - * Forgot Password - * Generates a one-time token (OTT) that can be used to reset a user's password. The user will be required to validate their security question's answer when visiting the reset link. - * This operation can only be performed on users with a valid [recovery question credential](#recovery-question-object) and have an `ACTIVE` status. - * @param sendEmail (optional, default to true) - * @param userCredentials (optional) - * @return ForgotPasswordResponse - * @deprecated use {@link User#forgotPassword(UserCredentials, Boolean)} - */ - @javax.annotation.Generated( - value = "com.okta.swagger.codegen.OktaJavaClientApiCodegen", - comments = "POST - /api/v1/users/{userId}/credentials/forgot_password") - @Deprecated - ForgotPasswordResponse forgotPassword(Boolean sendEmail, UserCredentials userCredentials); \ No newline at end of file diff --git a/swagger-templates/src/main/resources/OktaJava/licenseInfo.mustache b/swagger-templates/src/main/resources/OktaJava/licenseInfo.mustache index 2a94c35ce12..ff43812357d 100644 --- a/swagger-templates/src/main/resources/OktaJava/licenseInfo.mustache +++ b/swagger-templates/src/main/resources/OktaJava/licenseInfo.mustache @@ -1,5 +1,5 @@ {{! - Copyright 2017 Okta + Copyright 2017-Present Okta, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/swagger-templates/src/main/resources/OktaJavaImpl/Factor.mustache b/swagger-templates/src/main/resources/OktaJavaImpl/Factor.mustache deleted file mode 100644 index 172d3b2d8b5..00000000000 --- a/swagger-templates/src/main/resources/OktaJavaImpl/Factor.mustache +++ /dev/null @@ -1,24 +0,0 @@ -{{! - Copyright 2018-Present Okta, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - 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. -}} - @Override - public VerifyFactorResponse verify(String templateId, VerifyFactorRequest body) { - return verify(body, templateId); - } - - @Override - public VerifyFactorResponse verify(String templateId, Integer tokenLifetimeSeconds, VerifyFactorRequest body) { - return verify(body, templateId, tokenLifetimeSeconds); - } \ No newline at end of file diff --git a/swagger-templates/src/main/resources/OktaJavaImpl/User.mustache b/swagger-templates/src/main/resources/OktaJavaImpl/User.mustache deleted file mode 100644 index 62d74b7e056..00000000000 --- a/swagger-templates/src/main/resources/OktaJavaImpl/User.mustache +++ /dev/null @@ -1,29 +0,0 @@ -{{! - Copyright 2018-Present Okta, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - 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. -}} - @Override - public Factor addFactor(Boolean updatePhone, String templateId, Integer tokenLifetimeSeconds, Boolean activate, Factor body) { - return addFactor(body, updatePhone, templateId, tokenLifetimeSeconds, activate); - } - - @Override - public Factor addFactor(Boolean updatePhone, String templateId, Factor body) { - return addFactor(body, updatePhone, templateId); - } - - @Override - public ForgotPasswordResponse forgotPassword(Boolean sendEmail, UserCredentials userCredentials) { - return forgotPassword(userCredentials, sendEmail); - } \ No newline at end of file diff --git a/swagger-templates/src/main/resources/OktaJavaImpl/api.mustache b/swagger-templates/src/main/resources/OktaJavaImpl/api.mustache index abaa4c1cf79..70d0d47149a 100644 --- a/swagger-templates/src/main/resources/OktaJavaImpl/api.mustache +++ b/swagger-templates/src/main/resources/OktaJavaImpl/api.mustache @@ -18,7 +18,7 @@ package {{package}}; import com.okta.sdk.cache.CacheManager; import com.okta.sdk.client.AuthenticationScheme; -import com.okta.sdk.client.Proxy; +import com.okta.commons.http.config.Proxy; import com.okta.commons.http.QueryString; import com.okta.commons.http.HttpHeaders; import com.okta.sdk.impl.config.ClientConfiguration; @@ -46,7 +46,7 @@ import static com.okta.commons.lang.Assert.hasText; value = "{{generatorClass}}", date = "{{generatedDate}}") @SuppressWarnings("deprecation") -public class {{classname}} extends com.okta.sdk.impl.client.AbstractClient { +public class {{classname}} extends com.okta.sdk.impl.client.BaseClient implements com.okta.sdk.client.Client { /** * Instantiates a new Client instance that will communicate with the Okta REST API. See the class-level diff --git a/swagger-templates/src/main/resources/OktaJavaImpl/licenseInfo.mustache b/swagger-templates/src/main/resources/OktaJavaImpl/licenseInfo.mustache index 2a94c35ce12..ff43812357d 100644 --- a/swagger-templates/src/main/resources/OktaJavaImpl/licenseInfo.mustache +++ b/swagger-templates/src/main/resources/OktaJavaImpl/licenseInfo.mustache @@ -1,5 +1,5 @@ {{! - Copyright 2017 Okta + Copyright 2017-Present Okta, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.