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