]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
7c43515813a3d4e3745059e3b1c8eb11f5b1fa88
[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.common.context;
25
26 import java.security.acl.Group;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import javax.security.auth.Subject;
33 import javax.security.jacc.PolicyContext;
34 import javax.security.jacc.PolicyContextException;
35 import org.collectionspace.authentication.CSpaceTenant;
36
37 import org.collectionspace.services.common.ClientType;
38 import org.collectionspace.services.common.ServiceMain;
39 import org.collectionspace.services.common.config.TenantBindingConfigReader;
40 import org.collectionspace.services.common.security.UnauthorizedException;
41 import org.collectionspace.services.common.service.ObjectPartType;
42 import org.collectionspace.services.common.service.ServiceBindingType;
43 import org.collectionspace.services.common.service.ServiceObjectType;
44 import org.collectionspace.services.common.tenant.TenantBindingType;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 /**
49  * AbstractServiceContext
50  *
51  * $LastChangedRevision: $
52  * $LastChangedDate: $
53  */
54 public abstract class AbstractServiceContext<IT, OT>
55         implements ServiceContext<IT, OT> {
56
57     final Logger logger = LoggerFactory.getLogger(AbstractServiceContext.class);
58     Map<String, Object> properties = new HashMap<String, Object>();
59     Map<String, ObjectPartType> objectPartMap = new HashMap<String, ObjectPartType>();
60     private ServiceBindingType serviceBinding;
61     private TenantBindingType tenantBinding;
62     private String overrideDocumentType = null;
63
64     public AbstractServiceContext(String serviceName) throws UnauthorizedException {
65         TenantBindingConfigReader tReader =
66                 ServiceMain.getInstance().getTenantBindingConfigReader();
67         //FIXME retrieveTenantId is not working consistently in non-auth mode
68         //TODO: get tenant binding from security context
69         String tenantId = retrieveTenantId();
70         if (tenantId == null) {
71             //for testing purposes
72             tenantId = "1"; //hardcoded for movingimages.us
73         }
74         tenantBinding = tReader.getTenantBinding(tenantId);
75         if (tenantBinding == null) {
76             String msg = "No tenant binding found for tenantId=" + tenantId
77                     + " while processing request for service= " + serviceName;
78             logger.error(msg);
79             throw new IllegalStateException(msg);
80         }
81         serviceBinding = tReader.getServiceBinding(tenantId, serviceName);
82         if (serviceBinding == null) {
83             String msg = "No service binding found while processing request for "
84                     + serviceName + " for tenant id=" + getTenantId()
85                     + " name=" + getTenantName();
86             logger.error(msg);
87             throw new IllegalStateException(msg);
88         }
89         if (logger.isDebugEnabled()) {
90             logger.debug("tenantId=" + tenantId
91                     + " service binding=" + serviceBinding.getName());
92         }
93     }
94
95     /**
96      * getCommonPartLabel get common part label
97      * @return
98      */
99     @Override
100     public String getCommonPartLabel() {
101         return getCommonPartLabel(getServiceName());
102     }
103
104     /**
105      * getCommonPartLabel get common part label
106      * @return
107      */
108     public String getCommonPartLabel(String schemaName) {
109         return schemaName.toLowerCase() + PART_LABEL_SEPERATOR + PART_COMMON_LABEL;
110     }
111
112     @Override
113     public Map<String, ObjectPartType> getPartsMetadata() {
114         if (objectPartMap.size() != 0) {
115             return objectPartMap;
116         }
117         ServiceBindingType serviceBinding = getServiceBinding();
118         ServiceObjectType objectType = serviceBinding.getObject();
119         List<ObjectPartType> objectPartTypes = objectType.getPart();
120         for (ObjectPartType objectPartType : objectPartTypes) {
121             objectPartMap.put(objectPartType.getLabel(), objectPartType);
122         }
123         return objectPartMap;
124     }
125
126     @Override
127     public String getQualifiedServiceName() {
128         return TenantBindingConfigReader.getTenantQualifiedServiceName(getTenantId(), getServiceName());
129     }
130
131     @Override
132     public String getRepositoryClientName() {
133         if(serviceBinding.getRepositoryClient() == null) {
134             return null;
135         }
136         return serviceBinding.getRepositoryClient().trim();
137     }
138
139     @Override
140     public ClientType getRepositoryClientType() {
141         //assumption: there is only one repository client configured
142         return ServiceMain.getInstance().getClientType();
143     }
144
145     @Override
146     public String getRepositoryDomainName() {
147         return tenantBinding.getRepositoryDomain();
148     }
149
150     @Override
151     public String getRepositoryWorkspaceId() {
152         TenantBindingConfigReader tbConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
153         return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
154     }
155
156     @Override
157     public String getRepositoryWorkspaceName() {
158         //service name is workspace name by convention
159         return serviceBinding.getName();
160     }
161
162     @Override
163     public ServiceBindingType getServiceBinding() {
164         return serviceBinding;
165     }
166
167     @Override
168     public String getDocumentHandlerClass() {
169         if (serviceBinding.getDocumentHandler() == null
170                 || serviceBinding.getDocumentHandler().isEmpty()) {
171             String msg = "Missing documentHandler in service binding for "
172                     + getServiceName() + " for tenant id=" + getTenantId()
173                     + " name=" + getTenantName();
174             logger.error(msg);
175             throw new IllegalStateException(msg);
176         }
177         return serviceBinding.getDocumentHandler().trim();
178     }
179
180     @Override
181     public String getServiceName() {
182         return serviceBinding.getName();
183     }
184
185     @Override
186     public String getDocumentType() {
187         // If they have not overridden the setting, use the type of the service
188         // object.
189         return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().getName();
190     }
191
192     @Override
193     public void setDocumentType(String docType) {
194         overrideDocumentType = docType;
195     }
196
197     @Override
198     public String getTenantId() {
199         return tenantBinding.getId();
200     }
201
202     @Override
203     public String getTenantName() {
204         return tenantBinding.getName();
205     }
206
207     @Override
208     public abstract IT getInput();
209
210     @Override
211     public abstract void setInput(IT input);
212
213     @Override
214     public abstract OT getOutput();
215
216     @Override
217     public abstract void setOutput(OT output);
218
219     @Override
220     public Map<String, Object> getProperties() {
221         return properties;
222     }
223
224     @Override
225     public void setProperties(Map<String, Object> props) {
226         properties.putAll(props);
227     }
228
229     public Object getProperty(String name) {
230         return properties.get(name);
231     }
232
233     public void setProperty(String name, Object o) {
234         properties.put(name, o);
235     }
236     private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
237
238     private String retrieveTenantId() throws UnauthorizedException {
239
240         String tenantId = null;
241         Subject caller = null;
242         Set<Group> groups = null;
243         try {
244             caller = (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
245             if (caller == null) {
246                 //logger.warn("security not enabled...");
247                 return tenantId;
248             }
249             groups = caller.getPrincipals(Group.class);
250             if (groups != null && groups.size() == 0) {
251                 //TODO: find out why subject is not null
252                 if (logger.isDebugEnabled()) {
253                     logger.debug("no tenant(s) found!");
254                 }
255                 return tenantId;
256             }
257         } catch (PolicyContextException pce) {
258             String msg = "Could not retrieve principal information";
259             logger.error(msg, pce);
260             throw new UnauthorizedException(msg);
261         }
262         for (Group g : groups) {
263             if ("Tenants".equals(g.getName())) {
264                 Enumeration members = g.members();
265                 while (members.hasMoreElements()) {
266                     CSpaceTenant tenant = (CSpaceTenant) members.nextElement();
267                     tenantId = tenant.getId();
268                     if (logger.isDebugEnabled()) {
269                         logger.debug("found tenant id=" + tenant.getId()
270                                 + " name=" + tenant.getName());
271                     }
272                 }
273             }
274         }
275         //TODO: if a user is associated with more than one tenants, the tenant
276         //id should be matched with sent over the wire
277         if (tenantId == null) {
278             String msg = "Could not find tenant context";
279             logger.error(msg);
280             throw new UnauthorizedException(msg);
281         }
282         return tenantId;
283     }
284
285     @Override
286     public String toString() {
287         StringBuilder msg = new StringBuilder();
288         msg.append("AbstractServiceContext [");
289         msg.append("service name=" + serviceBinding.getName() + " ");
290         msg.append("service version=" + serviceBinding.getVersion() + " ");
291         msg.append("tenant id=" + tenantBinding.getId() + " ");
292         msg.append("tenant name=" + tenantBinding.getName() + " ");
293         msg.append(tenantBinding.getDisplayName() + " ");
294         msg.append("tenant repository domain=" + tenantBinding.getRepositoryDomain());
295         for (Map.Entry<String, Object> entry : properties.entrySet()) {
296             msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
297         }
298         msg.append("]");
299         return msg.toString();
300     }
301 }