001/*
002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $
020 */
021
022package org.nuxeo.ecm.http.client;
023
024import java.io.IOException;
025import java.io.InputStream;
026import java.io.OutputStream;
027import java.util.List;
028import java.util.Map;
029
030import org.nuxeo.ecm.http.client.authentication.PortalSSOAuthenticationProvider;
031import org.restlet.Client;
032import org.restlet.Request;
033import org.restlet.Response;
034import org.restlet.data.ChallengeResponse;
035import org.restlet.data.ChallengeScheme;
036import org.restlet.data.Cookie;
037import org.restlet.data.Form;
038import org.restlet.data.MediaType;
039import org.restlet.data.Method;
040import org.restlet.data.Parameter;
041import org.restlet.data.Protocol;
042import org.restlet.representation.OutputRepresentation;
043import org.restlet.representation.Representation;
044import org.restlet.util.Series;
045
046public class NuxeoServer {
047
048    public static final int AUTH_TYPE_NONE = 0;
049
050    public static final int AUTH_TYPE_BASIC = 1;
051
052    public static final int AUTH_TYPE_SECRET = 2;
053
054    protected String baseURL = "http://127.0.0.1:8080/nuxeo";
055
056    protected String restPrefix = "restAPI";
057
058    protected String davPrefix = "dav";
059
060    protected List<Cookie> cookies;
061
062    protected int authType = AUTH_TYPE_NONE;
063
064    protected String userName;
065
066    protected String password;
067
068    protected String secretToken;
069
070    protected Client restClient;
071
072    public NuxeoServer(String baseURL) {
073        this.baseURL = baseURL;
074    }
075
076    public NuxeoServer(String protocol, String serverIP, String serverPort) {
077        this(protocol, serverIP, serverPort, "nuxeo");
078    }
079
080    public NuxeoServer(String protocol, String serverIP, String serverPort, String servletPath) {
081        StringBuffer sb = new StringBuffer();
082        sb.append(protocol);
083        sb.append("://");
084        sb.append(serverIP);
085        if (serverPort != null && !serverIP.equals("80")) {
086            sb.append(':');
087            sb.append(serverPort);
088        }
089        sb.append(servletPath);
090        sb.append('/');
091        baseURL = sb.toString();
092    }
093
094    public void setBasicAuthentication(String userName, String password) {
095        authType = AUTH_TYPE_BASIC;
096        this.userName = userName;
097        this.password = password;
098    }
099
100    public void setSharedSecretAuthentication(String userName, String secretToken) {
101        authType = AUTH_TYPE_SECRET;
102        this.userName = userName;
103        this.secretToken = secretToken;
104    }
105
106    public void setCookies(List<Cookie> cookies) {
107        this.cookies = cookies;
108    }
109
110    /**
111     * @deprecated Use {@link NuxeoServer#doRestletPostCall(List, Map, InputStream, Long)} and provide a length.
112     * @param pathParams
113     * @param queryParams
114     * @param istream
115     * @return
116     */
117    public Representation doRestletPostCall(List<String> pathParams, Map<String, String> queryParams,
118            InputStream istream) {
119        return doRestletPostCall(pathParams, queryParams, istream, null);
120    }
121
122    public Representation doRestletPostCall(List<String> pathParams, Map<String, String> queryParams,
123            InputStream istream, Long size) {
124        String path = "";
125        StringBuffer pathBuffer = new StringBuffer();
126
127        if (pathParams != null) {
128            for (String p : pathParams) {
129                pathBuffer.append(p);
130                pathBuffer.append('/');
131            }
132            path = pathBuffer.toString();
133        }
134
135        return doRestletPostCall(path, queryParams, istream, size);
136    }
137
138    public Representation doRestletPostCall(String subPath, Map<String, String> queryParams, InputStream istream,
139            Long size) {
140        StringBuffer urlBuffer = new StringBuffer();
141
142        if (subPath.startsWith("/")) {
143            subPath = subPath.substring(1);
144        }
145        if (subPath.endsWith("/")) {
146            subPath = subPath.substring(0, subPath.length() - 1);
147        }
148
149        urlBuffer.append(baseURL);
150        urlBuffer.append('/');
151        urlBuffer.append(restPrefix);
152        urlBuffer.append('/');
153        urlBuffer.append(subPath);
154
155        if (queryParams != null) {
156            urlBuffer.append('?');
157            for (String qpName : queryParams.keySet()) {
158                urlBuffer.append(qpName);
159                urlBuffer.append('=');
160                urlBuffer.append(queryParams.get(qpName).replaceAll(" ", "%20"));
161                urlBuffer.append('&');
162            }
163        }
164
165        String completeURL = urlBuffer.toString();
166
167        Request request = new Request(Method.POST, completeURL);
168
169        setupAuth(request);
170        setupCookies(request);
171        final InputStream in = istream;
172        OutputRepresentation representation = new OutputRepresentation(MediaType.MULTIPART_FORM_DATA) {
173            @Override
174            public void write(OutputStream outputStream) throws IOException {
175                byte[] buffer = new byte[1024 * 64];
176                int read;
177                while ((read = in.read(buffer)) != -1) {
178                    outputStream.write(buffer, 0, read);
179                }
180
181            }
182        };
183        request.setEntity(representation);
184        if (size != null) {
185            representation.setSize(size);
186        }
187
188        return getRestClient().handle(request).getEntity();
189    }
190
191    public Representation doRestletGetCall(List<String> pathParams, Map<String, String> queryParams) {
192        String path = "";
193        StringBuffer pathBuffer = new StringBuffer();
194
195        if (pathParams != null) {
196            for (String p : pathParams) {
197                pathBuffer.append(p);
198                pathBuffer.append('/');
199            }
200            path = pathBuffer.toString();
201        }
202
203        return doRestletGetCall(path, queryParams);
204    }
205
206    public Representation doRestletGetCall(String subPath, Map<String, String> queryParams) {
207        StringBuffer urlBuffer = new StringBuffer();
208
209        if (subPath.startsWith("/")) {
210            subPath = subPath.substring(1);
211        }
212        if (subPath.endsWith("/")) {
213            subPath = subPath.substring(0, subPath.length() - 1);
214        }
215
216        urlBuffer.append(baseURL);
217        urlBuffer.append('/');
218        urlBuffer.append(restPrefix);
219        urlBuffer.append('/');
220        urlBuffer.append(subPath);
221
222        if (queryParams != null) {
223            urlBuffer.append('?');
224            for (String qpName : queryParams.keySet()) {
225                urlBuffer.append(qpName);
226                urlBuffer.append('=');
227                urlBuffer.append(queryParams.get(qpName).replaceAll(" ", "%20"));
228                urlBuffer.append('&');
229            }
230        }
231
232        String completeURL = urlBuffer.toString();
233
234        Request request = new Request(Method.GET, completeURL);
235        setupAuth(request);
236        setupCookies(request);
237
238        Response response = getRestClient().handle(request);
239        if (response.getLocationRef() != null) {
240            request = new Request(Method.GET, response.getLocationRef());
241            setupAuth(request);
242            setupCookies(request);
243            response = getRestClient().handle(request);
244        }
245        return response.getEntity();
246    }
247
248    protected void setupAuth(Request request) {
249
250        if (authType == AUTH_TYPE_BASIC) {
251            ChallengeScheme scheme = ChallengeScheme.HTTP_BASIC;
252            ChallengeResponse authentication = new ChallengeResponse(scheme, userName, password);
253            request.setChallengeResponse(authentication);
254
255        } else if (authType == AUTH_TYPE_SECRET) {
256            Series<Parameter> additionnalHeaders = new Form();
257
258            Map<String, String> securityHeaders = PortalSSOAuthenticationProvider.getHeaders(secretToken, userName);
259
260            for (String hn : securityHeaders.keySet()) {
261                additionnalHeaders.add(hn, securityHeaders.get(hn));
262            }
263
264            request.getAttributes().put("org.restlet.http.headers", additionnalHeaders);
265        }
266    }
267
268    protected void setupCookies(Request request) {
269        if (cookies != null) {
270            request.getCookies().clear();
271            for (Cookie cookie : cookies) {
272                request.getCookies().add(cookie);
273            }
274        }
275
276    }
277
278    protected Client getRestClient() {
279        if (restClient == null) {
280            if (baseURL.startsWith("https")) {
281                restClient = new Client(Protocol.HTTPS);
282            } else {
283                restClient = new Client(Protocol.HTTP);
284            }
285        }
286
287        return restClient;
288    }
289
290    public int getAuthType() {
291        return authType;
292    }
293
294    public void setAuthType(int authType) {
295        this.authType = authType;
296    }
297
298    public String getDavPrefix() {
299        return davPrefix;
300    }
301
302    public void setDavPrefix(String davPrefix) {
303        this.davPrefix = davPrefix;
304    }
305
306    public String getPassword() {
307        return password;
308    }
309
310    public void setPassword(String password) {
311        this.password = password;
312    }
313
314    public String getRestPrefix() {
315        return restPrefix;
316    }
317
318    public void setRestPrefix(String restPrefix) {
319        this.restPrefix = restPrefix;
320    }
321
322    public String getSecretToken() {
323        return secretToken;
324    }
325
326    public void setSecretToken(String secretToken) {
327        this.secretToken = secretToken;
328    }
329
330    public String getUserName() {
331        return userName;
332    }
333
334    public void setUserName(String userName) {
335        this.userName = userName;
336    }
337
338}