]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
9539b143a4ba2f4b6b570edc1fa63cd62fff78af
[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.Date;
28 import java.util.List;
29 import java.util.UUID;
30
31 import org.collectionspace.services.account.AccountTenant;
32 import org.collectionspace.services.account.AccountsCommon;
33 import org.collectionspace.services.account.AccountsCommonList;
34 import org.apache.commons.text.RandomStringGenerator;
35 import org.collectionspace.services.account.AccountListItem;
36 import org.collectionspace.services.account.AccountRoleSubResource;
37 import org.collectionspace.services.account.Status;
38 import org.collectionspace.services.authorization.AccountRole;
39 import org.collectionspace.services.authorization.SubjectType;
40 import org.collectionspace.services.account.RoleValue;
41 import org.collectionspace.services.client.AccountClient;
42 import org.collectionspace.services.client.AccountRoleFactory;
43 import org.collectionspace.services.common.storage.TransactionContext;
44 import org.collectionspace.services.common.storage.jpa.JpaDocumentHandler;
45 import org.collectionspace.services.common.api.Tools;
46 import org.collectionspace.services.common.context.ServiceContext;
47 import org.collectionspace.services.common.document.DocumentFilter;
48 import org.collectionspace.services.common.document.DocumentWrapper;
49 import org.collectionspace.services.common.document.JaxbUtils;
50 import org.collectionspace.services.common.security.SecurityUtils;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54
55 /**
56  *
57  * @author
58  */
59 public class AccountDocumentHandler
60         extends JpaDocumentHandler<AccountsCommon, AccountsCommonList, AccountsCommon, List<AccountsCommon>> {
61
62     private final Logger logger = LoggerFactory.getLogger(AccountDocumentHandler.class);
63     private AccountsCommon account;
64     private AccountsCommonList accountList;
65
66     @Override
67     public void handleCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
68         String id = UUID.randomUUID().toString();
69         AccountsCommon account = wrapDoc.getWrappedObject();
70
71         account.setCsid(id);
72
73         setTenant(account);
74
75         if (account.getStatus() == null) {
76             account.setStatus(Status.ACTIVE);
77         }
78
79         // We do not allow creation of locked accounts through the services.
80         account.setMetadataProtection(null);
81         account.setRolesProtection(null);
82     }
83
84     @Override
85     public void handleUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
86         AccountsCommon accountFound = wrapDoc.getWrappedObject();
87         AccountsCommon accountReceived = getCommonPart();
88         // If marked as metadata immutable, do not do update
89         if (!AccountClient.IMMUTABLE.equals(accountFound.getMetadataProtection())) {
90             merge(accountReceived, accountFound);
91         }
92         //
93         // Update the accountroles if supplied
94         //
95         if (accountReceived.getRoleList() != null) { // if null, no <roleList> element was supplied so we don't do anything to the account-role relationships
96             //
97             // First, delete the existing accountroles
98             //
99             AccountRoleSubResource subResource =
100                     new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
101             subResource.deleteAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
102             //
103             // Check to see if the payload has new roles to relate to the account
104             //
105             List<RoleValue> roleValueList = accountReceived.getRoleList().getRole();
106             if (roleValueList != null && roleValueList.size() > 0) {
107                 //
108                 // Next, create the new accountroles
109                 //
110                 AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountFound,
111                         roleValueList, true, true);
112                 String accountRoleCsid = subResource.createAccountRole(getServiceContext(), accountRole, SubjectType.ROLE);
113                 //
114                 // Finally, set the updated role list in the result
115                 //
116                 AccountRole newAccountRole = subResource.getAccountRole(getServiceContext(), accountFound.getCsid(), SubjectType.ROLE);
117                 accountFound.setRoleList(AccountRoleFactory.convert(newAccountRole.getRole()));
118             }
119         }
120     }
121
122     /**
123      * merge manually merges the from account to the to account
124      * -this method is created due to inefficiency of JPA EM merge
125      * @param from
126      * @param to
127      * @return merged account
128      */
129     private AccountsCommon merge(AccountsCommon from, AccountsCommon to) {
130         Date now = new Date();
131         to.setUpdatedAtItem(now);
132         if (from.getEmail() != null) {
133             to.setEmail(from.getEmail());
134         }
135         if (from.getPhone() != null) {
136             to.setPhone(from.getPhone());
137         }
138         if (from.getMobile() != null) {
139             to.setMobile(from.getMobile());
140         }
141         if (from.getScreenName() != null) {
142             to.setScreenName(from.getScreenName());
143         }
144         if (from.getStatus() != null) {
145             to.setStatus(from.getStatus());
146         }
147         if (from.getPersonRefName() != null) {
148             to.setPersonRefName(from.getPersonRefName());
149         }
150
151         // Note that we do not allow update of locks
152         //fixme update for tenant association
153
154         if (logger.isDebugEnabled()) {
155             logger.debug("merged account="
156                     + JaxbUtils.toString(to, AccountsCommon.class));
157         }
158         return to;
159     }
160
161     @Override
162     /**
163      * If the create payload included a list of role, relate them to the account.
164      */
165     public void completeCreate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
166         AccountsCommon accountsCommon = wrapDoc.getWrappedObject();
167         List<RoleValue> roleValueList = account.getRoleList() != null ? account.getRoleList().getRole() : null;
168         if (roleValueList != null && roleValueList.size() > 0) {
169             //
170             // To prevent new Accounts being created (especially low-level Spring Security accounts/SIDs), we'll first flush the current
171             // JPA context to ensure our Account can be successfully persisted.
172             //
173             TransactionContext jpaTransactionContext = this.getServiceContext().getCurrentTransactionContext();
174             jpaTransactionContext.flush();
175
176             AccountRoleSubResource subResource = new AccountRoleSubResource(AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
177             AccountRole accountRole = AccountRoleFactory.createAccountRoleInstance(accountsCommon, roleValueList, true, true);
178             subResource.createAccountRole(this.getServiceContext(), accountRole, SubjectType.ROLE);
179         }
180     }
181
182     @Override
183     public void completeUpdate(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
184         AccountsCommon upAcc = wrapDoc.getWrappedObject();
185         getServiceContext().setOutput(upAcc);
186     }
187
188     @Override
189     public void handleGet(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
190         setCommonPart(extractCommonPart(wrapDoc));
191         sanitize(getCommonPart());
192         getServiceContext().setOutput(account);
193     }
194
195     @Override
196     public void handleGetAll(DocumentWrapper<List<AccountsCommon>> wrapDoc) throws Exception {
197         AccountsCommonList accList = extractCommonPartList(wrapDoc);
198         setCommonPartList(accList);
199         getServiceContext().setOutput(getCommonPartList());
200     }
201
202     @SuppressWarnings("unchecked")
203     @Override
204     public AccountsCommon extractCommonPart(DocumentWrapper<AccountsCommon> wrapDoc) throws Exception {
205         AccountsCommon account = wrapDoc.getWrappedObject();
206
207         String includeRolesQueryParamValue = (String) getServiceContext().getQueryParams().getFirst(AccountClient.INCLUDE_ROLES_QP);
208         boolean includeRoles = Tools.isTrue(includeRolesQueryParamValue);
209         if (includeRoles) {
210             AccountRoleSubResource accountRoleResource = new AccountRoleSubResource(
211                     AccountRoleSubResource.ACCOUNT_ACCOUNTROLE_SERVICE);
212             AccountRole accountRole = accountRoleResource.getAccountRole(getServiceContext(), account.getCsid(),
213                     SubjectType.ROLE);
214             account.setRoleList(AccountRoleFactory.convert(accountRole.getRole()));
215         }
216
217         return wrapDoc.getWrappedObject();
218     }
219
220     @Override
221     public void fillCommonPart(AccountsCommon obj, DocumentWrapper<AccountsCommon> wrapDoc)
222             throws Exception {
223         throw new UnsupportedOperationException("operation not relevant for AccountDocumentHandler");
224     }
225
226     @Override
227     public AccountsCommonList extractCommonPartList(
228             DocumentWrapper<List<AccountsCommon>> wrapDoc)
229             throws Exception {
230
231         AccountsCommonList accList = this.extractPagingInfo(new AccountsCommonList(), wrapDoc);
232 //        AccountsCommonList accList = new AccountsCommonList();
233         List<AccountListItem> list = accList.getAccountListItem();
234
235         for (Object obj : wrapDoc.getWrappedObject()) {
236             AccountsCommon account = (AccountsCommon) obj;
237             AccountListItem accListItem = new AccountListItem();
238             accListItem.setScreenName(account.getScreenName());
239             accListItem.setUserid(account.getUserId());
240             //
241             // Since accounts can be associated with more than 1 tenant, we only want to include
242             // the tenant information for the current service context.
243             //
244                 String tenantInCtx = this.getServiceContext().getTenantId();
245             List<AccountTenant> associatedTenantList = account.getTenants();
246             for (AccountTenant associatedTenant : associatedTenantList) {
247                 if (associatedTenant != null && associatedTenant.getTenantId() != null) {
248                         if (associatedTenant.getTenantId().equalsIgnoreCase(tenantInCtx)) {
249                                 accListItem.setTenantid(associatedTenant.getTenantId());
250                                 break;
251                         }
252                 }
253             }
254
255             accListItem.setTenants(account.getTenants());
256             accListItem.setEmail(account.getEmail());
257             accListItem.setStatus(account.getStatus());
258             String id = account.getCsid();
259             accListItem.setUri(getServiceContextPath() + id);
260             accListItem.setCsid(id);
261             list.add(accListItem);
262         }
263         return accList;
264     }
265
266     @Override
267     public AccountsCommon getCommonPart() {
268         return account;
269     }
270
271     @Override
272     public void setCommonPart(AccountsCommon account) {
273         this.account = account;
274     }
275
276     @Override
277     public AccountsCommonList getCommonPartList() {
278         return accountList;
279     }
280
281     @Override
282     public void setCommonPartList(AccountsCommonList accountList) {
283         this.accountList = accountList;
284     }
285
286     @Override
287     public String getQProperty(
288             String prop) {
289         return null;
290     }
291
292     @Override
293     public DocumentFilter createDocumentFilter() {
294         DocumentFilter filter = new AccountJpaFilter(this.getServiceContext());
295         return filter;
296     }
297
298     private void setTenant(AccountsCommon account) {
299         //set tenant only if not available from input
300         ServiceContext ctx = getServiceContext();
301         if (account.getTenants() == null || account.getTenants().size() == 0) {
302             if (ctx.getTenantId() != null) {
303                 AccountTenant at = new AccountTenant();
304                 at.setTenantId(ctx.getTenantId());
305                 List<AccountTenant> atList = new ArrayList<AccountTenant>();
306                 atList.add(at);
307                 account.setTenants(atList);
308             }
309         }
310     }
311
312     /**
313      * sanitize removes data not needed to be sent to the consumer
314      * @param account
315      */
316     @Override
317     public void sanitize(DocumentWrapper<AccountsCommon> wrapDoc) {
318         AccountsCommon account = wrapDoc.getWrappedObject();
319         sanitize(account);
320     }
321
322     private void sanitize(AccountsCommon account) {
323         account.setPassword(null);
324         if (!SecurityUtils.isCSpaceAdmin()) {
325             account.setTenants(new ArrayList<AccountTenant>(0));
326         }
327     }
328
329     /* (non-Javadoc)
330      * @see org.collectionspace.services.common.document.DocumentHandler#initializeDocumentFilter(org.collectionspace.services.common.context.ServiceContext)
331      */
332     public void initializeDocumentFilter(ServiceContext<AccountsCommon, AccountsCommon> ctx) {
333         // set a default document filter in this method
334     }
335 }