diff --git a/README.md b/README.md index e89adbe..cb13701 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,30 @@ The configuration parameters are specified in the following table. One thing to When this value is true the user will be immediately logged out when a deactivate event occurs. + + Ignore Update Error On Disabled User + + no + + When this value is true the connector won't return errors when trying to update a disabled user. This means that disabled users will remain out of sync, but actions won't cause errors to be returned. When this value is false (default), any updates performed on disabled users will result in errors. + + + + Remove Phone Feature On Disabled User + + no + + When this value is true the connector will remove the phone feature from disabled users when ZOOM_PHONE_FEATURE is set to false. This is done by temporarily enabling the user, performing that and any other updates, then disabling the user again. When this value is false (default), any attempted changes at changing ZOOM_PHONE_FEATURE on a disabled user will result in an error. + + + + Update Disabled Users + + no + + When this value is true the connector will update user information on disabled users, including the ZOOM_PHONE_FEATURE. This is done by temporarily enabling the user, performing the update, then disabling the user again. When this value is false (default), any attempted changes at chaging attributes on a disabled user will result in an error. + + @@ -622,4 +646,4 @@ If more than 3 attempts are made to change a user's address within a 24 hour per 3. [Zoom User API](https://developers.zoom.us/docs/api/rest/reference/user/methods/#tag/Users) 4. [Zoom Phone User API](https://developers.zoom.us/docs/api/rest/reference/phone/methods/#tag/Users) 5. [Zoom Site API ](https://developers.zoom.us/docs/zoom-phone/apis/#tag/Sites) -6. [List of Zoom Phone Calling Plans](https://developers.zoom.us/docs/api/rest/other-references/calling-plans/) \ No newline at end of file +6. [List of Zoom Phone Calling Plans](https://developers.zoom.us/docs/api/rest/other-references/calling-plans/) diff --git a/configuration.structure.yml b/configuration.structure.yml index 52c1c6b..a51510b 100644 --- a/configuration.structure.yml +++ b/configuration.structure.yml @@ -42,4 +42,22 @@ custom: default: 'false' display: 'Entitlement Deletion Enabled' help: 'Enables the connector''s group deletion capability allowing the automated removal of Zoom groups via the Zoom API. The group removal capability is disabled by default.' + ignoreUpdateErrorOnDisabledUser: + type: boolean + order: 3060 + default: 'false' + display: 'Ignore Error on Disabled User' + help: 'Ignores update errors on disabled users, as they can''t be updated. Phone feature will still cause errors to be thrown.' + removePhoneFeatureOnDisabledUser: + type: boolean + order: 3070 + default: 'false' + display: 'Remove Phone Feature on Disabled User' + help: 'Removes the Phone feature on disabled users by temporarily reenabling them. Other updates may fire at the time.' + updateDisabledUsers: + type: boolean + order: 3080 + default: 'false' + display: 'Update Disabled Users' + help: 'Updates information on disabled users by temporarily reenabling them.' diff --git a/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/UserDisabledException.java b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/UserDisabledException.java new file mode 100644 index 0000000..8b5c35e --- /dev/null +++ b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/UserDisabledException.java @@ -0,0 +1,22 @@ +/* + Copyright 2020 Exclamation Labs + 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.exclamationlabs.connid.base.zoom.driver.rest; + +import org.identityconnectors.framework.common.exceptions.ConnectorException; + +public class UserDisabledException extends ConnectorException { + public UserDisabledException(String message) { + super(message); + } +} diff --git a/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomFaultProcessor.java b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomFaultProcessor.java index 10bafa1..fd75f13 100644 --- a/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomFaultProcessor.java +++ b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomFaultProcessor.java @@ -92,7 +92,8 @@ private Boolean checkRecognizedFaultCodes(ErrorResponse faultData) { switch (faultData.getCode()) { case PAID_SUBSCRIPTION_REQUIRED: throw new PaidAccountRequiredException(faultData.getMessage()); - + case USER_DISABLE: + throw new UserDisabledException(faultData.getMessage()); case USER_NOT_FOUND: case GROUP_NOT_FOUND: return false; @@ -116,20 +117,4 @@ private Boolean checkRecognizedFaultCodes(ErrorResponse faultData) { return true; } - private Boolean checkRecognizedFaultMessages(ErrorResponse faultData) { - if (faultData != null - && faultData.getMessage() != null - && (!faultData.getMessage().isEmpty())) { - String message = faultData.getMessage(); - if (message.contains("User does not exist")) { - Logger.info(this, message); - return true; - } else { - Logger.error(this, message); - throw new ConnectorException( - "Unhandled Exception Received from Zoom. Message: " + faultData.getMessage()); - } - } - return false; - } } diff --git a/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomUsersInvocator.java b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomUsersInvocator.java index c455b3d..ced342a 100644 --- a/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomUsersInvocator.java +++ b/src/main/java/com/exclamationlabs/connid/base/zoom/driver/rest/ZoomUsersInvocator.java @@ -112,7 +112,20 @@ public void update(ZoomDriver driver, String userId, ZoomUser user) throws Conne .withRequestBody(user) .withRequestUri("/users/" + userId) .build(); - RestResponseData response = driver.executeRequest(req); + RestResponseData response; + try { + response = driver.executeRequest(req); + } catch(UserDisabledException e) { + if (driver.getConfiguration().getIgnoreUpdateErrorOnDisabledUser() + || driver.getConfiguration().getUpdateDisabledUsers() + || driver.getConfiguration().getRemovePhoneFeatureOnDisabledUser()) { + handleDisabledUser(driver, userId, user); + return; + } else { + // proceed as normal and throw exception + throw new ConnectorException(e); + } + } if (response.getResponseStatusCode() == 204) { ZoomUser current = getOne(driver, userId, null); @@ -744,4 +757,51 @@ private Integer unAssignPhoneNumbers(ZoomDriver driver, String userId, Set(Void.class) + .withPatch() + .withRequestBody(user) + .withRequestUri("/users/" + userId) + .build(); + RestResponseData response = driver.executeRequest(req); + updateUserStatus(driver, "inactive", userId); + return; + } + + // check to see if the phone feature should be removed. + // removal of the phone feature removes numbers and sites, so don't need + // do to removal of those too. Will coincidentally update other attributes too + if (driver.getConfiguration().getRemovePhoneFeatureOnDisabledUser() + && user.getFeature() != null + && !user.getFeature().getZoomPhone()) { + Logger.info(this, String.format("Removing phone feature from a disabled user %s", userId)); + updateUserStatus(driver, "active", userId); + RestRequest req = + new RestRequest.Builder<>(Void.class) + .withPatch() + .withRequestBody(user) + .withRequestUri("/users/" + userId) + .build(); + RestResponseData response = driver.executeRequest(req); + updateUserStatus(driver, "inactive", userId); + return; + } + + // check config for ignore action + // last possible option here, so no op + Logger.info(this, String.format("Ignoring a disabled user %s", userId)); + } } diff --git a/src/main/java/com/exclamationlabs/connid/base/zoom/model/response/fault/ErrorResponseCode.java b/src/main/java/com/exclamationlabs/connid/base/zoom/model/response/fault/ErrorResponseCode.java index 445638f..04bbd83 100644 --- a/src/main/java/com/exclamationlabs/connid/base/zoom/model/response/fault/ErrorResponseCode.java +++ b/src/main/java/com/exclamationlabs/connid/base/zoom/model/response/fault/ErrorResponseCode.java @@ -22,6 +22,7 @@ public interface ErrorResponseCode { int USER_NOT_FOUND = 1001; int USER_ALREADY_EXISTS = 1005; + int USER_DISABLE = 1053; int REQUIRES_MANAGED_DOMAIN = 1116; int GROUP_NOT_FOUND = 4130;