]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
0e1dcd8f0839406d9a3019aa6536db424031b312
[tmp/jakarta-migration.git] /
1 /**
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:
5
6  *  http://www.collectionspace.org
7  *  http://wiki.collectionspace.org
8
9  *  Copyright 2009 University of California at Berkeley
10
11  *  Licensed under the Educational Community License (ECL), Version 2.0.
12  *  You may not use this file except in compliance with this License.
13
14  *  You may obtain a copy of the ECL 2.0 License at
15
16  *  https://source.collectionspace.org/collection-space/LICENSE.txt
17
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.
23  */
24 package org.collectionspace.services.account.storage;
25
26 import java.util.ArrayList;
27 import java.util.List;
28 import javax.persistence.EntityManager;
29 import javax.persistence.EntityManagerFactory;
30 import javax.persistence.Query;
31 import org.apache.commons.codec.binary.Base64;
32 import org.collectionspace.services.account.AccountsCommon;
33 import org.collectionspace.services.authentication.User;
34 import org.collectionspace.services.common.context.ServiceContext;
35 import org.collectionspace.services.common.document.BadRequestException;
36 import org.collectionspace.services.common.document.DocumentException;
37 import org.collectionspace.services.common.document.DocumentHandler;
38 import org.collectionspace.services.common.document.DocumentHandler.Action;
39 import org.collectionspace.services.common.document.DocumentNotFoundException;
40 import org.collectionspace.services.common.document.DocumentWrapper;
41 import org.collectionspace.services.common.document.DocumentWrapperImpl;
42 import org.collectionspace.services.common.security.SecurityUtils;
43 import org.collectionspace.services.common.storage.jpa.JpaStorageClient;
44
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 /**
49  * AccountStorageClient deals with both Account and Default Identity Provider's
50  * state in persistent storage
51  * @author 
52  */
53 public class AccountStorageClient extends JpaStorageClient {
54
55     private final Logger logger = LoggerFactory.getLogger(AccountStorageClient.class);
56
57     public AccountStorageClient() {
58     }
59
60     @Override
61     public String create(ServiceContext ctx,
62             DocumentHandler handler) throws BadRequestException,
63             DocumentException {
64
65         String docType = ctx.getDocumentType();
66         if (docType == null) {
67             throw new DocumentNotFoundException(
68                     "Unable to find DocumentType for service " + ctx.getServiceName());
69         }
70         if (handler == null) {
71             throw new IllegalArgumentException(
72                     "AccountStorageClient.create: handler is missing");
73         }
74         EntityManagerFactory emf = null;
75         EntityManager em = null;
76         try {
77             handler.prepare(Action.CREATE);
78             AccountsCommon account = (AccountsCommon) handler.getCommonPart();
79             DocumentWrapper<AccountsCommon> wrapDoc =
80                     new DocumentWrapperImpl<AccountsCommon>(account);
81             handler.handle(Action.CREATE, wrapDoc);
82             emf = getEntityManagerFactory();
83             em = emf.createEntityManager();
84             em.getTransaction().begin();
85             //if userid and password are given, add to default id provider
86             if (account.getUserId() != null && account.getPassword() != null) {
87                 User user = createUser(account);
88                 em.persist(user);
89             }
90 //            if (account.getTenant() != null) {
91 //                UserTenant ut = createTenantAssoc(account);
92 //                em.persist(ut);
93 //            }
94             em.persist(account);
95             em.getTransaction().commit();
96             handler.complete(Action.CREATE, wrapDoc);
97             return (String) getValue(account, "getCsid");
98         } catch (BadRequestException bre) {
99             if (em != null && em.getTransaction().isActive()) {
100                 em.getTransaction().rollback();
101             }
102             throw bre;
103         } catch (Exception e) {
104             if (em != null && em.getTransaction().isActive()) {
105                 em.getTransaction().rollback();
106             }
107             if (logger.isDebugEnabled()) {
108                 logger.debug("Caught exception ", e);
109             }
110             throw new DocumentException(e);
111         } finally {
112             if (em != null) {
113                 releaseEntityManagerFactory(emf);
114             }
115         }
116     }
117
118     @Override
119     public void update(ServiceContext ctx, String id, DocumentHandler handler)
120             throws BadRequestException, DocumentNotFoundException,
121             DocumentException {
122         String docType = ctx.getDocumentType();
123         if (docType == null) {
124             throw new DocumentNotFoundException(
125                     "Unable to find DocumentType for service " + ctx.getServiceName());
126         }
127         if (handler == null) {
128             throw new IllegalArgumentException(
129                     "AccountStorageClient.update: handler is missing");
130         }
131         EntityManagerFactory emf = null;
132         EntityManager em = null;
133         try {
134             handler.prepare(Action.UPDATE);
135             AccountsCommon account = (AccountsCommon) handler.getCommonPart();
136             DocumentWrapper<AccountsCommon> wrapDoc =
137                     new DocumentWrapperImpl<AccountsCommon>(account);
138             setCsid(account, id); //set id just in case it was not populated by consumer
139             handler.handle(Action.UPDATE, wrapDoc);
140             emf = getEntityManagerFactory();
141             em = emf.createEntityManager();
142             em.getTransaction().begin();
143             AccountsCommon accountFound = getAccount(em, id);
144
145             checkAllowedUpdates(account, accountFound);
146             //if userid and password are given, add to default id provider
147             if (account.getUserId() != null && account.getPassword() != null) {
148
149                 User userFound = getUser(em, account);
150                 User user = createUser(account);
151                 em.merge(user);
152             }
153             em.merge(account);
154             em.getTransaction().commit();
155             handler.complete(Action.UPDATE, wrapDoc);
156         } catch (BadRequestException bre) {
157             if (em != null && em.getTransaction().isActive()) {
158                 em.getTransaction().rollback();
159             }
160             throw bre;
161         } catch (DocumentException de) {
162             if (em != null && em.getTransaction().isActive()) {
163                 em.getTransaction().rollback();
164             }
165             throw de;
166         } catch (Exception e) {
167             if (logger.isDebugEnabled()) {
168                 logger.debug("Caught exception ", e);
169             }
170             throw new DocumentException(e);
171         } finally {
172             if (emf != null) {
173                 releaseEntityManagerFactory(emf);
174             }
175         }
176     }
177
178     @Override
179     public void delete(ServiceContext ctx, String id)
180             throws DocumentNotFoundException,
181             DocumentException {
182
183         if (logger.isDebugEnabled()) {
184             logger.debug("deleting entity with id=" + id);
185         }
186         String docType = ctx.getDocumentType();
187         if (docType == null) {
188             throw new DocumentNotFoundException(
189                     "Unable to find DocumentType for service " + ctx.getServiceName());
190         }
191         EntityManagerFactory emf = null;
192         EntityManager em = null;
193         try {
194             emf = getEntityManagerFactory();
195             em = emf.createEntityManager();
196             //TODO investigate if deep delete is possible
197             //query an delete is inefficient
198             AccountsCommon accountFound = getAccount(em, id);
199
200             StringBuilder accDelStr = new StringBuilder("DELETE FROM ");
201             accDelStr.append(getEntityName(ctx));
202             accDelStr.append(" WHERE csid = :csid");
203             //TODO: add tenant id
204             Query accDel = em.createQuery(accDelStr.toString());
205             accDel.setParameter("csid", id);
206             //TODO: add tenant id
207
208             //if userid gives any indication about the id provider, it should
209             //be used to avoid the following approach
210             Query usrDel = null;
211             User userLocal = getUser(em, accountFound);
212             if (userLocal != null) {
213                 StringBuilder usrDelStr = new StringBuilder("DELETE FROM ");
214                 usrDelStr.append(User.class.getCanonicalName());
215                 usrDelStr.append(" WHERE username = :username");
216                 //TODO: add tenant id
217                 usrDel = em.createQuery(usrDelStr.toString());
218                 usrDel.setParameter("username", accountFound.getUserId());
219             }
220             em.getTransaction().begin();
221 //            int accDelCount = accDel.executeUpdate();
222 //            if (accDelCount != 1) {
223 //                if (em != null && em.getTransaction().isActive()) {
224 //                    em.getTransaction().rollback();
225 //                }
226 //            }
227             if (userLocal != null) {
228                 int usrDelCount = usrDel.executeUpdate();
229                 if (usrDelCount != 1) {
230                     if (em != null && em.getTransaction().isActive()) {
231                         em.getTransaction().rollback();
232                     }
233                 }
234                 if (usrDelCount != 1) {
235                     String msg = "could not find user with username=" + accountFound.getUserId();
236                     logger.error(msg);
237                     throw new DocumentNotFoundException(msg);
238                 }
239             }
240             em.remove(accountFound);
241             em.getTransaction().commit();
242
243         } catch (DocumentException de) {
244             if (em != null && em.getTransaction().isActive()) {
245                 em.getTransaction().rollback();
246             }
247             throw de;
248         } catch (Exception e) {
249             if (logger.isDebugEnabled()) {
250                 logger.debug("Caught exception ", e);
251             }
252             if (em != null && em.getTransaction().isActive()) {
253                 em.getTransaction().rollback();
254             }
255             throw new DocumentException(e);
256         } finally {
257             if (emf != null) {
258                 releaseEntityManagerFactory(emf);
259             }
260         }
261     }
262
263     private AccountsCommon getAccount(EntityManager em, String id) throws DocumentNotFoundException {
264         AccountsCommon accountFound = em.find(AccountsCommon.class, id);
265         if (accountFound == null) {
266             if (em != null && em.getTransaction().isActive()) {
267                 em.getTransaction().rollback();
268             }
269             String msg = "could not find account with id=" + id;
270             logger.error(msg);
271             throw new DocumentNotFoundException(msg);
272         }
273         return accountFound;
274     }
275
276     private boolean checkAllowedUpdates(AccountsCommon toAccount, AccountsCommon fromAccount) throws BadRequestException {
277         if (!fromAccount.getUserId().equals(toAccount.getUserId())) {
278             String msg = "User id " + toAccount.getUserId() + " not found!";
279             logger.error(msg);
280             logger.debug(msg + " found userid=" + fromAccount.getUserId());
281             throw new BadRequestException(msg);
282         }
283         return true;
284     }
285
286     private User createUser(AccountsCommon account) {
287         User user = new User();
288         user.setUsername(account.getUserId());
289         byte[] bpass = Base64.decodeBase64(account.getPassword());
290         SecurityUtils.validatePassword(new String(bpass));
291         String secEncPasswd = SecurityUtils.createPasswordHash(
292                 account.getUserId(), new String(bpass));
293         user.setPasswd(secEncPasswd);
294         return user;
295     }
296
297     private User getUser(EntityManager em, AccountsCommon account) throws DocumentNotFoundException {
298         User userFound = em.find(User.class, account.getUserId());
299         if (userFound == null) {
300             if (em != null && em.getTransaction().isActive()) {
301                 em.getTransaction().rollback();
302             }
303             String msg = "could not find user with id=" + account.getUserId();
304             logger.error(msg);
305             throw new DocumentNotFoundException(msg);
306         }
307         return userFound;
308     }
309
310 //    private UserTenant createTenantAssoc(AccountsCommon account) {
311 //        UserTenant userTenant = new UserTenant();
312 //        userTenant.setUserId(account.getUserId());
313 //        List<AccountsCommon.Tenant> atl = account.getTenant();
314 //        List<UserTenant.Tenant> utl =
315 //                new ArrayList<UserTenant.Tenant>();
316 //        for (AccountsCommon.Tenant at : atl) {
317 //            UserTenant.Tenant ut = new UserTenant.Tenant();
318 //            ut.setId(at.getId());
319 //            ut.setName(at.getName());
320 //            utl.add(ut);
321 //        }
322 //        userTenant.setTenant(utl);
323 //        return userTenant;
324 //    }
325 }