]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
d67d684607d3919a3c1d070a8dbf8eb36acb9592
[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.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.security.Principal;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import javax.security.auth.Subject;
34 import javax.security.jacc.PolicyContext;
35 import javax.security.jacc.PolicyContextException;
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 = null; //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 while processing request for " +
77                     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         List<ServiceObjectType> objectTypes = serviceBinding.getObject();
119         for (ServiceObjectType objectType : objectTypes) {
120             List<ObjectPartType> objectPartTypes = objectType.getPart();
121             for (ObjectPartType objectPartType : objectPartTypes) {
122                 objectPartMap.put(objectPartType.getLabel(), objectPartType);
123             }
124         }
125         return objectPartMap;
126     }
127
128     @Override
129     public String getQualifiedServiceName() {
130         return TenantBindingConfigReader.getTenantQualifiedServiceName(getTenantId(), getServiceName());
131     }
132
133     @Override
134     public String getRepositoryClientName() {
135         return serviceBinding.getRepositoryClient();
136     }
137
138     @Override
139     public ClientType getRepositoryClientType() {
140         //assumption: there is only one repository client configured
141         return ServiceMain.getInstance().getClientType();
142     }
143
144     @Override
145     public String getRepositoryDomainName() {
146         return tenantBinding.getRepositoryDomain();
147     }
148
149     @Override
150     public String getRepositoryWorkspaceId() {
151         TenantBindingConfigReader tbConfigReader = ServiceMain.getInstance().getTenantBindingConfigReader();
152         return tbConfigReader.getWorkspaceId(getTenantId(), getServiceName());
153     }
154
155     @Override
156     public String getRepositoryWorkspaceName() {
157         //service name is workspace name by convention
158         return serviceBinding.getName();
159     }
160
161     @Override
162     public ServiceBindingType getServiceBinding() {
163         return serviceBinding;
164     }
165
166     @Override
167     public String getServiceName() {
168         return serviceBinding.getName();
169     }
170
171     @Override
172     public String getDocumentType() {
173         // If they have not overridden the setting, use the type of the service
174         // object.
175         return (overrideDocumentType != null) ? overrideDocumentType : serviceBinding.getObject().get(0).getName();
176     }
177
178     @Override
179     public void setDocumentType(String docType) {
180         overrideDocumentType = docType;
181     }
182
183     @Override
184     public String getTenantId() {
185         return tenantBinding.getId();
186     }
187
188     @Override
189     public String getTenantName() {
190         return tenantBinding.getName();
191     }
192
193     @Override
194     public abstract IT getInput();
195
196     @Override
197     public abstract void setInput(IT input);
198
199     @Override
200     public abstract OT getOutput();
201
202     @Override
203     public abstract void setOutput(OT output);
204
205     @Override
206     public Map<String, Object> getProperties() {
207         return properties;
208     }
209
210     @Override
211     public void setProperties(Map<String, Object> props) {
212         properties.putAll(props);
213     }
214
215     public Object getProperty(String name) {
216         return properties.get(name);
217     }
218
219     public void setProperty(String name, Object o) {
220         properties.put(name, o);
221     }
222     private static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
223
224     private String retrieveTenantId() throws UnauthorizedException {
225
226         String tenantId = null;
227         Subject caller = null;
228         Set<Principal> principals = null;
229         try {
230             caller = (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
231             if (caller == null) {
232                 //logger.warn("security not enabled...");
233                 return tenantId;
234             }
235             principals = caller.getPrincipals(Principal.class);
236             if (principals != null && principals.size() == 0) {
237                 //TODO: find out why subject is not null
238                 if (logger.isDebugEnabled()) {
239                     logger.debug("weird case where subject is not null and there are no principals");
240                 }
241                 return tenantId;
242             }
243         } catch (PolicyContextException pce) {
244             String msg = "Could not retrieve principal information";
245             logger.error(msg, pce);
246             throw new UnauthorizedException(msg);
247         }
248         for (Principal p : principals) {
249             try {
250                 Method m = p.getClass().getMethod("getTenantId");
251                 Object r = m.invoke(p);
252                 if (logger.isDebugEnabled()) {
253                     logger.debug("retrieved tenantid=" + r +
254                             " for principal=" + p.getName());
255                 }
256                 tenantId = (String) r;
257                 break;
258             } catch (Exception e) {
259                 //continue with next principal
260             }
261         }
262         if (tenantId == null) {
263             String msg = "Could not find tenant context";
264             logger.error(msg);
265             throw new UnauthorizedException(msg);
266         }
267         return tenantId;
268     }
269
270     @Override
271     public String toString() {
272         StringBuilder msg = new StringBuilder();
273         msg.append("AbstractServiceContext [");
274         msg.append("service name=" + serviceBinding.getName() + " ");
275         msg.append("service version=" + serviceBinding.getVersion() + " ");
276         msg.append("tenant id=" + tenantBinding.getId() + " ");
277         msg.append("tenant name=" + tenantBinding.getName() + " ");
278         msg.append(tenantBinding.getDisplayName() + " ");
279         msg.append("tenant repository domain=" + tenantBinding.getRepositoryDomain());
280         for (Map.Entry<String, Object> entry : properties.entrySet()) {
281             msg.append("property name=" + entry.getKey() + " value=" + entry.getValue().toString());
282         }
283         msg.append("]");
284         return msg.toString();
285     }
286 }