/* * ==================== * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common Development * and Distribution License("CDDL") (the "License"). You may not use this file * except in compliance with the License. * * You can obtain a copy of the License at * http://opensource.org/licenses/cddl1.php * See the License for the specific language governing permissions and limitations * under the License. * * When distributing the Covered Code, include this CDDL Header Notice in each file * and include the License file at http://opensource.org/licenses/cddl1.php. * If applicable, add the following below this CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * ==================== */ package org.identityconnectors.oracleerp; import static org.identityconnectors.oracleerp.OracleERPUtil.DIRECT_RESPS; import static org.identityconnectors.oracleerp.OracleERPUtil.MSG_ACCOUNT_NOT_UPDATE; import static org.identityconnectors.oracleerp.OracleERPUtil.MSG_COULD_NOT_DISABLE_USER; import static org.identityconnectors.oracleerp.OracleERPUtil.MSG_COULD_NOT_ENABLE_USER; import static org.identityconnectors.oracleerp.OracleERPUtil.MSG_COULD_NOT_RENAME_USER; import static org.identityconnectors.oracleerp.OracleERPUtil.OWNER; import static org.identityconnectors.oracleerp.OracleERPUtil.RESPS; import static org.identityconnectors.oracleerp.OracleERPUtil.SEC_ATTRS; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.text.MessageFormat; import java.util.Set; import org.identityconnectors.common.logging.Log; import org.identityconnectors.dbcommon.SQLUtil; import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.Name; import org.identityconnectors.framework.common.objects.ObjectClass; import org.identityconnectors.framework.common.objects.OperationOptions; import org.identityconnectors.framework.common.objects.OperationalAttributes; import org.identityconnectors.framework.common.objects.Uid; import org.identityconnectors.framework.spi.operations.UpdateOp; import org.identityconnectors.oracleerp.AccountSQLCall.AccountSQLCallBuilder; /** * The Account CreateOp implementation of the SPI * * { call {0}fnd_user_pkg.{1} ( {2} ) } // {0} .. "APPS.", {1} .. "UpdateUser" * {2} ... is an array of x_user_name => ?, x_owner => ?, x_unencrypted_password * => ?, x_session_number => ?, x_start_date => ?, x_end_date => ?, * x_last_logon_date => ?, x_description => ?, x_password_date => ?, * x_password_accesses_left => ?, x_password_lifespan_accesses => ?, * x_password_lifespan_days => ?, x_employee_id => ?, x_email_address => ?, * x_fax => ?, x_customer_id => ?, x_supplier_id => ? ) }; * * * @author Petr Jung * @version $Revision 1.0$ * @since 1.0 */ final class AccountOperationUpdate extends Operation implements UpdateOp { private static final Log LOG = Log.getLog(AccountOperationUpdate.class); /** * Resp Operations. */ private ResponsibilitiesOperations respOps; /** * @param conn * @param cfg */ protected AccountOperationUpdate(OracleERPConnection conn, OracleERPConfiguration cfg) { super(conn, cfg); respOps = new ResponsibilitiesOperations(conn, cfg); } /* * (non-Javadoc) * * @see org.identityconnectors.framework.spi.operations.UpdateOp#update(org. * identityconnectors.framework.common.objects.ObjectClass, * org.identityconnectors.framework.common.objects.Uid, java.util.Set, * org.identityconnectors.framework.common.objects.OperationOptions) */ public Uid update(ObjectClass objclass, Uid uid, Set<Attribute> attrs, OperationOptions options) { final String id = uid.getUidValue().toUpperCase(); LOG.ok("update user ''{0}''", id); // Enable/dissable user final Attribute enableAttr = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, attrs); if (enableAttr != null) { boolean enable = AttributeUtil.getBooleanValue(enableAttr); if (enable) { // delete user is the same as dissable enable(objclass, id, options); } else { disable(objclass, id, options); } } final Name nameAttr = AttributeUtil.getNameFromAttributes(attrs); if (nameAttr != null) { // Cannot rename user if (nameAttr.getNameValue() != null) { final String newName = nameAttr.getNameValue(); if (!id.equalsIgnoreCase(newName)) { final String emsg = getCfg().getMessage(MSG_COULD_NOT_RENAME_USER, id, newName); throw new IllegalStateException(emsg); } } } // Get the User values final AccountSQLCallBuilder asb = new AccountSQLCallBuilder(getCfg(), false); // add the id asb.setAttribute(objclass, AttributeBuilder.build(Uid.NAME, id), options); // Add default owner asb.setAttribute(objclass, AttributeBuilder.build(OWNER, getCfg().getDefaultOwner()), options); for (Attribute attr : attrs) { asb.setAttribute(objclass, attr, options); } if (!asb.isEmpty()) { // Run the create call, new style is using the defaults CallableStatement cs = null; final AccountSQLCall aSql = asb.build(); final String msg = "Update user account {0}"; LOG.ok(msg, id); try { // Create the user cs = getConn().prepareCall(aSql.getCallSql(), aSql.getSqlParams()); cs.execute(); } catch (Exception e) { String message = getCfg().getMessage(MSG_ACCOUNT_NOT_UPDATE, id); LOG.error(e, message); SQLUtil.rollbackQuietly(getConn()); throw new ConnectorException(message, e); } finally { SQLUtil.closeQuietly(cs); } } // Update responsibilities final Attribute resp = AttributeUtil.find(RESPS, attrs); final Attribute directResp = AttributeUtil.find(DIRECT_RESPS, attrs); if (directResp != null) { respOps.updateUserResponsibilities(directResp, id); } else if (resp != null) { respOps.updateUserResponsibilities(resp, id); } final Attribute secAttr = AttributeUtil.find(SEC_ATTRS, attrs); if (secAttr != null) { new SecuringAttributesOperations(getConn(), getCfg()).updateUserSecuringAttrs(secAttr, id); } getConn().commit(); // Return new UID LOG.ok("update user ''{0}'' done", id); return new Uid(id); } /** * @param objclass * @param userName * @param options */ private void enable(ObjectClass objclass, String userName, OperationOptions options) { final String method = "enable"; LOG.ok(method); // Map attrs = _actionUtil.getAccountAttributes(user, // JActionUtil.OP_ENABLE_USER); // no enable user stored procedure that I could find, null out // end_date will do nicely // Need user's OWNER, so need to do a getUser(); PreparedStatement st = null; try { StringBuilder b = new StringBuilder(); b.append("{ call " + getCfg().app() + "fnd_user_pkg.updateuser(x_user_name => ?"); b.append(",x_owner => upper(?),x_end_date => FND_USER_PKG.null_date"); b.append(") }"); final String sql = b.toString(); st = getConn().prepareStatement(sql); st.setString(1, userName.toUpperCase()); st.setString(2, getCfg().getDefaultOwner()); st.execute(); } catch (Exception e) { final String msg = getCfg().getMessage(MSG_COULD_NOT_ENABLE_USER, userName); LOG.error(e, msg); SQLUtil.rollbackQuietly(getConn()); throw new ConnectorException(msg, e); } finally { SQLUtil.closeQuietly(st); st = null; } LOG.ok(method); } /** * @param objclass * @param uid * @param options */ private void disable(ObjectClass objclass, String userName, OperationOptions options) { final String sql = "{ call " + getCfg().app() + "fnd_user_pkg.disableuser(?) }"; final String method = "disable"; LOG.ok(method); CallableStatement cs = null; try { cs = getConn().prepareCall(sql); cs.setString(1, userName); cs.execute(); // No Result ?? } catch (Exception e) { final String msg = getCfg().getMessage(MSG_COULD_NOT_DISABLE_USER, userName); SQLUtil.rollbackQuietly(getConn()); throw new ConnectorException(MessageFormat.format(msg, userName), e); } finally { SQLUtil.closeQuietly(cs); cs = null; } LOG.ok(method); } }