001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kim.impl.identity.external;
017
018import javax.persistence.CascadeType;
019import javax.persistence.Column;
020import javax.persistence.Entity;
021import javax.persistence.GeneratedValue;
022import javax.persistence.Id;
023import javax.persistence.JoinColumn;
024import javax.persistence.ManyToOne;
025import javax.persistence.PrePersist;
026import javax.persistence.PreUpdate;
027import javax.persistence.Table;
028import javax.persistence.Transient;
029
030import org.apache.commons.lang.StringUtils;
031import org.apache.log4j.Logger;
032import org.eclipse.persistence.annotations.JoinFetch;
033import org.eclipse.persistence.annotations.JoinFetchType;
034import org.kuali.rice.core.api.CoreApiServiceLocator;
035import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifier;
036import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierContract;
037import org.kuali.rice.kim.api.identity.external.EntityExternalIdentifierType;
038import org.kuali.rice.kim.api.services.KimApiServiceLocator;
039import org.kuali.rice.krad.bo.DataObjectBase;
040import org.kuali.rice.krad.data.jpa.PortableSequenceGenerator;
041
042@Entity
043@Table(name = "KRIM_ENTITY_EXT_ID_T")
044public class EntityExternalIdentifierBo extends DataObjectBase implements EntityExternalIdentifierContract {
045    private static final Logger LOG = org.apache.log4j.Logger.getLogger(EntityExternalIdentifierBo.class);
046    private static final long serialVersionUID = 1L;
047
048    @Id
049    @Column(name = "ENTITY_EXT_ID_ID")
050    @PortableSequenceGenerator(name = "KRIM_ENTITY_EXT_ID_ID_S")
051    @GeneratedValue(generator = "KRIM_ENTITY_EXT_ID_ID_S")
052    private String id;
053
054    @Column(name = "ENTITY_ID")
055    private String entityId;
056
057    @Column(name = "EXT_ID_TYP_CD")
058    private String externalIdentifierTypeCode;
059
060    @Column(name = "EXT_ID")
061    private String externalId;
062
063    @JoinFetch(value= JoinFetchType.OUTER)
064    @ManyToOne(targetEntity = EntityExternalIdentifierTypeBo.class, cascade = { CascadeType.REFRESH })
065    @JoinColumn(name = "EXT_ID_TYP_CD", referencedColumnName = "EXT_ID_TYP_CD", insertable = false, updatable = false)
066    private EntityExternalIdentifierTypeBo externalIdentifierType;
067
068    @Transient
069    private EntityExternalIdentifierType cachedExtIdType = null;
070
071    @Transient
072    private boolean encryptionRequired = false;
073
074    @Transient
075    private boolean decryptionNeeded = false;
076
077    public static EntityExternalIdentifier to(EntityExternalIdentifierBo bo) {
078        if (bo == null) {
079            return null;
080        }
081        return EntityExternalIdentifier.Builder.create(bo).build();
082    }
083
084    /**
085     * Creates a EntityExternalIdentifierBo business object from an immutable representation of a
086     * EntityExternalIdentifier.
087     *
088     * @param immutable immutable EntityExternalIdentifier
089     * @return a EntityExternalIdentifierBo
090     */
091    public static EntityExternalIdentifierBo from(EntityExternalIdentifier immutable) {
092        if (immutable == null) {
093            return null;
094        }
095        EntityExternalIdentifierBo bo = new EntityExternalIdentifierBo();
096        bo.id = immutable.getId();
097        bo.externalId = immutable.getExternalId();
098        bo.entityId = immutable.getEntityId();
099        bo.externalIdentifierTypeCode = immutable.getExternalIdentifierTypeCode();
100        bo.externalIdentifierType = immutable.getExternalIdentifierType() != null ? EntityExternalIdentifierTypeBo.from(immutable.getExternalIdentifierType()) : null;
101        bo.setVersionNumber(immutable.getVersionNumber());
102        bo.setObjectId(immutable.getObjectId());
103        return bo;
104    }
105
106    @Override
107    @PrePersist
108    protected void prePersist() {
109        super.prePersist();
110        encryptExternalId();
111    }
112
113    @Override
114    @PreUpdate
115    protected void preUpdate() {
116        super.preUpdate();
117        if (!this.decryptionNeeded) {
118            encryptExternalId();
119        }
120    }
121
122    protected void encryptExternalId() {
123        evaluateExternalIdentifierType();
124        if (encryptionRequired && StringUtils.isNotEmpty(this.externalId)) {
125            try {
126                if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
127                    this.externalId = CoreApiServiceLocator.getEncryptionService().encrypt(this.externalId);
128                    this.decryptionNeeded = true;
129                }
130            } catch (Exception e) {
131                LOG.info("Unable to encrypt value : " + e.getMessage() + " or it is already encrypted");
132            }
133        }
134    }
135
136    protected void decryptExternalId() {
137        evaluateExternalIdentifierType();
138        if (encryptionRequired && StringUtils.isNotEmpty(externalId)) {
139            try {
140                if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
141                    this.externalId = CoreApiServiceLocator.getEncryptionService().decrypt(this.externalId);
142                }
143            } catch (Exception e) {
144                LOG.info("Unable to decrypt value : " + e.getMessage() + " or it is already decrypted");
145            }
146        }
147    }
148
149    protected void evaluateExternalIdentifierType() {
150        if (cachedExtIdType == null) {
151            cachedExtIdType = KimApiServiceLocator.getIdentityService().getExternalIdentifierType(externalIdentifierTypeCode);
152            encryptionRequired = cachedExtIdType != null && cachedExtIdType.isEncryptionRequired();
153        }
154    }
155
156    protected String decryptedExternalId() {
157        evaluateExternalIdentifierType();
158        if (encryptionRequired && StringUtils.isNotEmpty(externalId)) {
159            try {
160                if (CoreApiServiceLocator.getEncryptionService().isEnabled()) {
161                    return CoreApiServiceLocator.getEncryptionService().decrypt(this.externalId);
162                }
163            } catch (Exception e) {
164                LOG.info("Unable to decrypt value : " + e.getMessage() + " or it is already decrypted");
165            }
166        }
167        return "";
168    }
169
170    public void setExternalId(String externalId) {
171        this.externalId = externalId;
172        this.decryptionNeeded = false;
173    }
174
175    public void setExternalIdentifierTypeCode(String externalIdentifierTypeCode) {
176        this.externalIdentifierTypeCode = externalIdentifierTypeCode;
177        cachedExtIdType = null;
178    }
179
180    public void setExternalIdentifierType(EntityExternalIdentifierTypeBo externalIdentifierType) {
181        this.externalIdentifierType = externalIdentifierType;
182        cachedExtIdType = null;
183    }
184
185    @Override
186    public EntityExternalIdentifierTypeBo getExternalIdentifierType() {
187        return this.externalIdentifierType;
188    }
189
190    @Override
191    public String getExternalId() {
192        if (this.decryptionNeeded) {
193            return decryptedExternalId();
194        }
195        return externalId;
196    }
197
198    @Override
199    public String getId() {
200        return id;
201    }
202
203    public void setId(String id) {
204        this.id = id;
205    }
206
207    @Override
208    public String getEntityId() {
209        return entityId;
210    }
211
212    public void setEntityId(String entityId) {
213        this.entityId = entityId;
214    }
215
216    @Override
217    public String getExternalIdentifierTypeCode() {
218        return externalIdentifierTypeCode;
219    }
220}