/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/
package org.restlet.example.ext.openid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Logger;
import org.openid4java.message.DirectError;
import org.openid4java.message.Message;
import org.openid4java.message.ParameterList;
import org.openid4java.server.ServerManager;
import org.restlet.data.Form;
import org.restlet.data.Method;
import org.restlet.representation.EmptyRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
/**
* OpenID provider representation implementing an open identity IdP. At the
* moment it is only used for testing.
*
* User backend is not specified and if is only returning one user 'foo'
*
* @author Kristoffer Gronowski
*/
// TODO yadisResolver.discoverRP(realm);
public class OpenIdProvider extends ServerResource {
public OpenIdProvider() {
getLogger().info("OpenID CREATED NEW PROVIDER");
}
@Post("form")
public Representation represent(Representation input) {
Form f = new Form(input);
return handle(new ParameterList(f.getValuesMap()));
}
@Get("form")
public Representation represent() {
return handle(new ParameterList(getQuery().getValuesMap()));
}
private Representation handle(ParameterList request) {
Logger log = getLogger();
log.info("Handle on OP");
ConcurrentMap<String, Object> attribs = getContext().getAttributes();
ServerManager manager = (ServerManager) attribs.get("openid_manager");
log.info("OP endpoint = " + manager.getOPEndpointUrl());
String mode = request.hasParameter("openid.mode") ? request
.getParameterValue("openid.mode") : null;
Message response;
String responseText;
if ("associate".equals(mode)) {
// --- process an association request ---
response = manager.associationResponse(request);
responseText = response.keyValueFormEncoding();
} else if ("checkid_setup".equals(mode)
|| "checkid_immediate".equals(mode)) {
// interact with the user and obtain data needed to continue
List<?> userData = userInteraction(request,
manager.getOPEndpointUrl());
String userSelectedId = (String) userData.get(0);
String userSelectedClaimedId = (String) userData.get(1);
Boolean authenticatedAndApproved = (Boolean) userData.get(2);
// --- process an authentication request ---
response = manager.authResponse(request, userSelectedId,
userSelectedClaimedId,
authenticatedAndApproved.booleanValue());
if (response instanceof DirectError) {
Form f = new Form();
@SuppressWarnings("unchecked")
Map<String, String> m = (Map<String, String>) response
.getParameterMap();
for (String key : m.keySet()) {
f.add(key, m.get(key));
}
return f.getWebRepresentation();
} else {
// caller will need to decide which of the following to use:
// option1: GET HTTP-redirect to the return_to URL
// return new
// StringRepresentation(response.getDestinationUrl(true));
redirectSeeOther(response.getDestinationUrl(true));
return new EmptyRepresentation();
// option2: HTML FORM Redirection
// RequestDispatcher dispatcher =
// getServletContext().getRequestDispatcher("formredirection.jsp");
// httpReq.setAttribute("prameterMap",
// response.getParameterMap());
// httpReq.setAttribute("destinationUrl",
// response.getDestinationUrl(false));
// dispatcher.forward(request, response);
// return null;
}
} else if ("check_authentication".equals(mode)) {
// --- processing a verification request ---
response = manager.verify(request);
log.info("OpenID : " + response.keyValueFormEncoding());
responseText = response.keyValueFormEncoding();
} else if (Method.GET.equals(getMethod())) {
// Could be a discovery request
sendXRDSLocation();
return new StringRepresentation("XRDS Discovery Information");
} else {
// --- error response ---
response = DirectError.createDirectError("Unknown request");
responseText = response.keyValueFormEncoding();
}
// return the result to the user
return new StringRepresentation(responseText);
}
private void sendXRDSLocation() {
ConcurrentMap<String, Object> attribs = getContext().getAttributes();
String id = getQuery().getFirstValue("id");
String xrds = attribs.get("xrds").toString();
String location = (id != null) ? xrds + "?id=" + id : xrds;
getLogger().info("XRDS endpoint = " + xrds);
Form headers = (Form) getResponse().getAttributes().get(
"org.restlet.http.headers");
if (headers == null) {
headers = new Form();
headers.add("X-XRDS-Location", location);
getResponse().getAttributes().put("org.restlet.http.headers",
headers);
} else {
headers.add("X-XRDS-Location", location);
}
getLogger().info("Sending empty representation.");
}
private List<Object> userInteraction(ParameterList request, String endpoint) {
StringBuilder id = new StringBuilder();
id.append(endpoint);
id.append("?id=");
id.append("foo");
List<Object> result = new ArrayList<Object>();
result.add(0, id.toString());
result.add(1, id.toString());
result.add(2, Boolean.TRUE);
return result;
}
}