2 * This document is a part of the source code and related artifacts
3 * for CollectionSpace, an open source collections management system
4 * for museums and related institutions:
6 * http://www.collectionspace.org
7 * http://wiki.collectionspace.org
9 * Copyright 2009 University of California at Berkeley
11 * Licensed under the Educational Community License (ECL), Version 2.0.
12 * You may not use this file except in compliance with this License.
14 * You may obtain a copy of the ECL 2.0 License at
16 * https://source.collectionspace.org/collection-space/LICENSE.txt
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
24 package org.collectionspace.services.account.storage;
26 import javax.persistence.EntityManager;
27 import javax.persistence.EntityManagerFactory;
28 import javax.persistence.Query;
29 import org.apache.commons.codec.binary.Base64;
30 import org.collectionspace.services.account.AccountsCommon;
31 import org.collectionspace.services.account.AccountsCommon;
32 import org.collectionspace.services.authentication.User;
33 import org.collectionspace.services.common.context.ServiceContext;
34 import org.collectionspace.services.common.document.BadRequestException;
35 import org.collectionspace.services.common.document.DocumentException;
36 import org.collectionspace.services.common.document.DocumentHandler;
37 import org.collectionspace.services.common.document.DocumentHandler.Action;
38 import org.collectionspace.services.common.document.DocumentNotFoundException;
39 import org.collectionspace.services.common.document.DocumentWrapper;
40 import org.collectionspace.services.common.document.DocumentWrapperImpl;
41 import org.collectionspace.services.common.security.SecurityUtils;
42 import org.collectionspace.services.common.storage.jpa.JpaStorageClient;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * AccountStorageClient deals with both Account and Default Identity Provider's
48 * state in persistent storage
51 public class AccountStorageClient extends JpaStorageClient {
53 private final Logger logger = LoggerFactory.getLogger(AccountStorageClient.class);
55 public AccountStorageClient() {
59 public String create(ServiceContext ctx,
60 DocumentHandler handler) throws BadRequestException,
63 String docType = ctx.getDocumentType();
64 if (docType == null) {
65 throw new DocumentNotFoundException(
66 "Unable to find DocumentType for service " + ctx.getServiceName());
68 if (handler == null) {
69 throw new IllegalArgumentException(
70 "AccountStorageClient.create: handler is missing");
72 EntityManagerFactory emf = null;
73 EntityManager em = null;
75 handler.prepare(Action.CREATE);
76 AccountsCommon account = (AccountsCommon) handler.getCommonPart();
77 DocumentWrapper<AccountsCommon> wrapDoc =
78 new DocumentWrapperImpl<AccountsCommon>(account);
79 handler.handle(Action.CREATE, wrapDoc);
80 emf = getEntityManagerFactory();
81 em = emf.createEntityManager();
82 em.getTransaction().begin();
83 //if userid and password are given, add to default id provider
84 if (account.getUserId() != null && account.getPassword() != null) {
85 User user = createUser(account);
88 account.setTenantid(ctx.getTenantId());
90 em.getTransaction().commit();
91 handler.complete(Action.CREATE, wrapDoc);
92 return (String) getValue(account, "getCsid");
93 } catch (Exception e) {
94 if (em != null && em.getTransaction().isActive()) {
95 em.getTransaction().rollback();
97 if (logger.isDebugEnabled()) {
98 logger.debug("Caught exception ", e);
100 throw new DocumentException(e);
103 releaseEntityManagerFactory(emf);
109 public void delete(ServiceContext ctx, String id)
110 throws DocumentNotFoundException,
113 if (logger.isDebugEnabled()) {
114 logger.debug("deleting entity with id=" + id);
116 String docType = ctx.getDocumentType();
117 if (docType == null) {
118 throw new DocumentNotFoundException(
119 "Unable to find DocumentType for service " + ctx.getServiceName());
121 EntityManagerFactory emf = null;
122 EntityManager em = null;
124 emf = getEntityManagerFactory();
125 em = emf.createEntityManager();
126 //TODO investigate if deep delete is possible
127 //query an delete is inefficient
128 AccountsCommon accountFound = em.find(AccountsCommon.class, id);
129 if (accountFound == null) {
130 if (em != null && em.getTransaction().isActive()) {
131 em.getTransaction().rollback();
133 String msg = "could not find entity with id=" + id;
135 throw new DocumentNotFoundException(msg);
138 StringBuilder accDelStr = new StringBuilder("DELETE FROM ");
139 accDelStr.append(getEntityName(ctx));
140 accDelStr.append(" WHERE csid = :csid");
141 //TODO: add tenant id
142 Query accDel = em.createQuery(accDelStr.toString());
143 accDel.setParameter("csid", id);
144 //TODO: add tenant id
146 //if userid gives any indication about the id provider, it should
147 //be used to avoid the following approach
148 User userLocal = em.find(User.class, accountFound.getUserId());
150 if (userLocal != null) {
151 StringBuilder usrDelStr = new StringBuilder("DELETE FROM ");
152 usrDelStr.append(User.class.getCanonicalName());
153 usrDelStr.append(" WHERE username = :username");
154 //TODO: add tenant id
155 usrDel = em.createQuery(usrDelStr.toString());
156 usrDel.setParameter("username", accountFound.getUserId());
158 em.getTransaction().begin();
159 int accDelCount = accDel.executeUpdate();
160 if (accDelCount != 1) {
161 if (em != null && em.getTransaction().isActive()) {
162 em.getTransaction().rollback();
165 if (userLocal != null) {
166 int usrDelCount = usrDel.executeUpdate();
167 if (usrDelCount != 1) {
168 if (em != null && em.getTransaction().isActive()) {
169 em.getTransaction().rollback();
172 if (usrDelCount != 1) {
173 String msg = "could not find user with username=" + accountFound.getUserId();
175 throw new DocumentNotFoundException(msg);
178 em.getTransaction().commit();
180 } catch (DocumentException de) {
182 } catch (Exception e) {
183 if (logger.isDebugEnabled()) {
184 logger.debug("Caught exception ", e);
186 if (em != null && em.getTransaction().isActive()) {
187 em.getTransaction().rollback();
189 throw new DocumentException(e);
192 releaseEntityManagerFactory(emf);
197 private User createUser(AccountsCommon account) {
198 User user = new User();
199 user.setUsername(account.getUserId());
200 byte[] bpass = Base64.decodeBase64(account.getPassword());
201 SecurityUtils.validatePassword(new String(bpass));
202 String secEncPasswd = SecurityUtils.createPasswordHash(
203 account.getUserId(), new String(bpass));
204 user.setPasswd(secEncPasswd);