|
| 1 | +/******************************************************************************* |
| 2 | + * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved. DO NOT |
| 3 | + * ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| 4 | + * |
| 5 | + * The Universal Permissive License (UPL), Version 1.0 |
| 6 | + * |
| 7 | + * Subject to the condition set forth below, permission is hereby granted to any |
| 8 | + * person obtaining a copy of this software, associated documentation and/or |
| 9 | + * data (collectively the "Software"), free of charge and under any and all |
| 10 | + * copyright rights in the Software, and any and all patent rights owned or |
| 11 | + * freely licensable by each licensor hereunder covering either (i) the |
| 12 | + * unmodified Software as contributed to or provided by such licensor, or (ii) |
| 13 | + * the Larger Works (as defined below), to deal in both |
| 14 | + * |
| 15 | + * (a) the Software, and |
| 16 | + * |
| 17 | + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if |
| 18 | + * one is included with the Software each a "Larger Work" to which the Software |
| 19 | + * is contributed by such licensors), |
| 20 | + * |
| 21 | + * without restriction, including without limitation the rights to copy, create |
| 22 | + * derivative works of, display, perform, and distribute the Software and make, |
| 23 | + * use, sell, offer for sale, import, export, have made, and have sold the |
| 24 | + * Software and the Larger Work(s), and to sublicense the foregoing rights on |
| 25 | + * either these or other terms. |
| 26 | + * |
| 27 | + * This license is subject to the following condition: |
| 28 | + * |
| 29 | + * The above copyright notice and either this complete permission notice or at a |
| 30 | + * minimum a reference to the UPL must be included in all copies or substantial |
| 31 | + * portions of the Software. |
| 32 | + * |
| 33 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 34 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 35 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 36 | + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 37 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 38 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 39 | + * SOFTWARE. |
| 40 | + *******************************************************************************/ |
| 41 | + |
| 42 | +package com.oracle.sample; |
| 43 | + |
| 44 | +import java.util.Calendar; |
| 45 | + |
| 46 | +import java.util.Date; |
| 47 | +import java.util.HashMap; |
| 48 | +import java.util.HashSet; |
| 49 | +import java.util.List; |
| 50 | +import java.util.Set; |
| 51 | +import java.util.concurrent.TimeUnit; |
| 52 | +import java.util.logging.Level; |
| 53 | +import java.util.logging.Logger; |
| 54 | + |
| 55 | +import oracle.iam.identity.usermgmt.api.UserManager; |
| 56 | +import oracle.iam.identity.usermgmt.api.UserManagerConstants; |
| 57 | +import oracle.iam.identity.usermgmt.vo.User; |
| 58 | +import oracle.iam.platform.Platform; |
| 59 | +import oracle.iam.platform.entitymgr.vo.SearchCriteria; |
| 60 | +import oracle.iam.provisioning.api.ProvisioningConstants; |
| 61 | +import oracle.iam.provisioning.api.ProvisioningService; |
| 62 | +import oracle.iam.provisioning.vo.Account; |
| 63 | +import oracle.iam.scheduler.exception.SchedulerException; |
| 64 | +import oracle.iam.scheduler.vo.TaskSupport; |
| 65 | + |
| 66 | +/** |
| 67 | + * Sample scheduled task implementation that disables all the access of a user |
| 68 | + * which goes on a leave of absence. The LOA status is determined based on a |
| 69 | + * custom attribute (UDF), specified as a parameter in the scheduled task |
| 70 | + * definition. |
| 71 | + * |
| 72 | + * The scheduled task will also handle the re-enabling of user accounts once the |
| 73 | + * LOA end date is hit, and also the clearing of the UDF value which signifies |
| 74 | + * the LOA state. |
| 75 | + * |
| 76 | + * @author mgere-oracle |
| 77 | + */ |
| 78 | +public class LOAAccountDisable extends TaskSupport { |
| 79 | + |
| 80 | + private static final Logger logger = Logger.getLogger(LOAAccountDisable.class.getName()); |
| 81 | + |
| 82 | + @Override |
| 83 | + public void execute(HashMap arg0) throws Exception { |
| 84 | + logger.log(Level.INFO, "The scheduled task run has started."); |
| 85 | + |
| 86 | + if (arg0 == null) { |
| 87 | + // arg0 will never be null if a valid scheduled task definition file is used |
| 88 | + throw new SchedulerException("Scheduled task definition is incorrect. Aborting run."); |
| 89 | + } |
| 90 | + |
| 91 | + UserManager userManager = Platform.getService(UserManager.class); |
| 92 | + ProvisioningService provService = Platform.getService(ProvisioningService.class); |
| 93 | + |
| 94 | + final String LOA_DATE_FIELD_NAME = (String) arg0.get("LOA end date user attribute"); |
| 95 | + logger.log(Level.FINE, "LOA_DATE_FIELD_NAME: {0}", LOA_DATE_FIELD_NAME); |
| 96 | + |
| 97 | + // construct a criteria for all active users in the system; |
| 98 | + // note that user access is disabled in this case, not the users themselves |
| 99 | + SearchCriteria userSearchCriteriaActive = new SearchCriteria(UserManagerConstants.AttributeName.STATUS.getId(), |
| 100 | + UserManagerConstants.AttributeValues.USER_STATUS_ACTIVE.getId(), SearchCriteria.Operator.EQUAL); |
| 101 | + Set<String> retAttrs = new HashSet<>(); |
| 102 | + |
| 103 | + List<User> activeUserList = userManager.search(userSearchCriteriaActive, retAttrs, null); |
| 104 | + Date currentDate = Calendar.getInstance().getTime(); |
| 105 | + logger.log(Level.FINE, "Current date: {0}", currentDate); |
| 106 | + |
| 107 | + for (User currentUser : activeUserList) { |
| 108 | + try { |
| 109 | + Date loaAccountDisableDate = (Date) currentUser.getAttribute(LOA_DATE_FIELD_NAME); |
| 110 | + |
| 111 | + if (loaAccountDisableDate != null) { |
| 112 | + logger.log(Level.INFO, "Processing user: {0}", currentUser.getLogin()); |
| 113 | + logger.log(Level.FINE, "LOA account disable date: {0}", loaAccountDisableDate); |
| 114 | + |
| 115 | + String userStatus = currentUser.getStatus(); |
| 116 | + logger.log(Level.FINE, "User status: {0}", userStatus); |
| 117 | + |
| 118 | + // calculate the difference in days between the LOA account disable date, |
| 119 | + // typically set in the future, and the current date |
| 120 | + Long dayDiff = TimeUnit.DAYS.convert(loaAccountDisableDate.getTime() - currentDate.getTime(), |
| 121 | + TimeUnit.MILLISECONDS); |
| 122 | + logger.log(Level.FINE, "Time diff: {0}", dayDiff); |
| 123 | + |
| 124 | + if (dayDiff <= 0 |
| 125 | + && userStatus.equals(UserManagerConstants.AttributeValues.USER_STATUS_ACTIVE.getId())) { |
| 126 | + logger.log(Level.INFO, "Parental leave date has been hit. Enabling user accounts..."); |
| 127 | + |
| 128 | + SearchCriteria disableAccountSearch = new SearchCriteria( |
| 129 | + ProvisioningConstants.AccountSearchAttribute.ACCOUNT_STATUS.getId(), |
| 130 | + ProvisioningConstants.ObjectStatus.DISABLED.getId(), SearchCriteria.Operator.EQUAL); |
| 131 | + List<Account> disabledAccounts = provService.getAccountsProvisionedToUser(currentUser.getId(), |
| 132 | + disableAccountSearch, null); |
| 133 | + |
| 134 | + for (Account currentDisabledAccount : disabledAccounts) { |
| 135 | + try { |
| 136 | + logger.log(Level.INFO, "Enabling user account: {0}", |
| 137 | + currentDisabledAccount.getAccountDescriptiveField()); |
| 138 | + provService.enable(Long.parseLong(currentDisabledAccount.getAccountID())); |
| 139 | + logger.log(Level.INFO, "Account enabled."); |
| 140 | + } catch (Exception e) { |
| 141 | + logger.log(Level.WARNING, "Enabling of account has failed: ", e); |
| 142 | + } |
| 143 | + } |
| 144 | + |
| 145 | + logger.log(Level.INFO, "Clearing LOA end date value..."); |
| 146 | + User updatedUser = new User(currentUser.getId()); |
| 147 | + updatedUser.setAttribute(LOA_DATE_FIELD_NAME, ""); |
| 148 | + userManager.modify(updatedUser); |
| 149 | + logger.log(Level.INFO, "LOA end date cleared."); |
| 150 | + |
| 151 | + } else if (dayDiff > 0 |
| 152 | + && userStatus.equals(UserManagerConstants.AttributeValues.USER_STATUS_ACTIVE.getId())) { |
| 153 | + logger.log(Level.INFO, "A future LOA end date is set. Disabling user accounts..."); |
| 154 | + |
| 155 | + // only list provisioned or enabled accounts, as those will be eligible for disabling |
| 156 | + SearchCriteria provisionedAccountSearch = new SearchCriteria( |
| 157 | + ProvisioningConstants.AccountSearchAttribute.ACCOUNT_STATUS.getId(), |
| 158 | + ProvisioningConstants.ObjectStatus.PROVISIONED.getId(), SearchCriteria.Operator.EQUAL); |
| 159 | + SearchCriteria enabledAccountSearch = new SearchCriteria( |
| 160 | + ProvisioningConstants.AccountSearchAttribute.ACCOUNT_STATUS.getId(), |
| 161 | + ProvisioningConstants.ObjectStatus.ENABLED.getId(), SearchCriteria.Operator.EQUAL); |
| 162 | + SearchCriteria activeAccountsSearch = new SearchCriteria(provisionedAccountSearch, |
| 163 | + enabledAccountSearch, SearchCriteria.Operator.OR); |
| 164 | + |
| 165 | + List<Account> activeAccounts = provService.getAccountsProvisionedToUser(currentUser.getId(), |
| 166 | + activeAccountsSearch, null); |
| 167 | + |
| 168 | + for (Account currentAccount : activeAccounts) { |
| 169 | + try { |
| 170 | + logger.log(Level.INFO, "Disabling user account: {0}", |
| 171 | + currentAccount.getAccountDescriptiveField()); |
| 172 | + provService.disable(Long.parseLong(currentAccount.getAccountID())); |
| 173 | + logger.log(Level.INFO, "Account disabled."); |
| 174 | + } catch (Exception e) { |
| 175 | + logger.log(Level.WARNING, "Disabling of account has failed: ", e); |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | + } else { |
| 180 | + logger.log(Level.FINE, "LOA end date not set. Skipping."); |
| 181 | + } |
| 182 | + } catch (Exception e) { |
| 183 | + logger.log(Level.WARNING, "User processing failed: ", e); |
| 184 | + } |
| 185 | + } |
| 186 | + |
| 187 | + logger.log(Level.INFO, "The scheduled task run has finished."); |
| 188 | + } |
| 189 | + |
| 190 | + @SuppressWarnings("rawtypes") |
| 191 | + @Override |
| 192 | + public HashMap getAttributes() { |
| 193 | + return new HashMap<>(); |
| 194 | + } |
| 195 | + |
| 196 | + @Override |
| 197 | + public void setAttributes() { |
| 198 | + } |
| 199 | +} |
0 commit comments