Index: xwiki-core/pom.xml
===================================================================
--- xwiki-core/pom.xml (revision 11817)
+++ xwiki-core/pom.xml (working copy)
@@ -332,6 +332,13 @@
2.0
+
+
+ org.openid4java
+ openid4java
+ 0.9.3
+
+
dom4j
Index: xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java
===================================================================
--- xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java (revision 11817)
+++ xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java (working copy)
@@ -23,6 +23,7 @@
import java.io.IOException;
import java.security.Principal;
+import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -30,6 +31,14 @@
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.velocity.VelocityContext;
+import org.openid4java.OpenIDException;
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.consumer.VerificationResult;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.discovery.Identifier;
+import org.openid4java.message.AuthRequest;
+import org.openid4java.message.ParameterList;
import org.securityfilter.authenticator.Authenticator;
import org.securityfilter.authenticator.FormAuthenticator;
import org.securityfilter.filter.SecurityRequestWrapper;
@@ -37,7 +46,9 @@
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.plugin.openid.OpenIdHelper;
import com.xpn.xwiki.web.SavedRequestRestorerFilter;
+import com.xpn.xwiki.web.XWikiServletURLFactory;
public class MyFormAuthenticator extends FormAuthenticator implements Authenticator, XWikiAuthenticator
{
@@ -116,7 +127,7 @@
}
} catch (Exception e) {
// in case of exception we continue on Form Auth.
- // we don't want this to interfere with the most common behavior
+ // we don't want this to interfere with the most common behaviour
}
// process any persistent login information, if user is not already logged in,
@@ -139,13 +150,27 @@
}
}
- // process login form submittal
+ // process login form data
if ((this.loginSubmitPattern != null) && request.getMatchableURL().endsWith(this.loginSubmitPattern)) {
- String username = convertUsername(request.getParameter(FORM_USERNAME), context);
- String password = request.getParameter(FORM_PASSWORD);
- String rememberme = request.getParameter(FORM_REMEMBERME);
- rememberme = (rememberme == null) ? "false" : rememberme;
- return processLogin(username, password, rememberme, request, response, context);
+ if (request.getParameter("authentication_method") != null
+ && request.getParameter("authentication_method").equalsIgnoreCase("openid")) {
+ // OpenID login
+ String openid_identifier = request.getParameter("openid_identifier");
+ String rememberme = request.getParameter(FORM_REMEMBERME);
+ rememberme = (rememberme == null) ? "false" : rememberme;
+ return processOpenIdLogin(openid_identifier, rememberme, request, response, context);
+ } else if (request.getParameter("authentication_method") != null
+ && request.getParameter("authentication_method").equalsIgnoreCase("useraccount")) {
+ // Normal user account login
+ String username = convertUsername(request.getParameter(FORM_USERNAME), context);
+ String password = request.getParameter(FORM_PASSWORD);
+ String rememberme = request.getParameter(FORM_REMEMBERME);
+ rememberme = (rememberme == null) ? "false" : rememberme;
+ return processLogin(username, password, rememberme, request, response, context);
+ } else if (request.getParameter("openid.mode") != null) {
+ // OpenID: OP response
+ return processOpenIdLoginResponse(request, response, context);
+ }
}
return false;
}
@@ -155,6 +180,9 @@
* abort further processing after the method completes (for example, if a redirect was sent as part of the login
* processing).
*
+ * @param username
+ * @param password
+ * @param rememberme
* @param request
* @param response
* @return true if the filter should return after this method ends, false otherwise
@@ -169,7 +197,8 @@
log.info("User " + principal.getName() + " has been logged-in");
}
- // invalidate old session if the user was already authenticated, and they logged in as a different user
+ // invalidate old session if the user was already authenticated, and they logged in as a
+ // different user
if (request.getUserPrincipal() != null && !username.equals(request.getRemoteUser())) {
request.getSession().invalidate();
}
@@ -190,7 +219,8 @@
Boolean bAjax = (Boolean) context.get("ajax");
if ((bAjax == null) || (!bAjax.booleanValue())) {
String continueToURL = getContinueToURL(request);
- // This is the url that the user was initially accessing before being prompted for login.
+ // This is the url that the user was initially accessing before being prompted for
+ // login.
response.sendRedirect(response.encodeRedirectURL(continueToURL));
}
} else {
@@ -215,6 +245,173 @@
}
/**
+ * Processes an OpenID login. It redirects the user as part of a normal OpenID login process to the OpenID provider.
+ * The response is handled by {@link MyFormAuthenticator#processOpenIdLoginResponse processOpenIdLoginResponse}.
+ * Returns true if SecurityFilter should abort further processing after the method completes (for example, if a
+ * redirect was sent as part of the login processing which is the normal behaviour).
+ *
+ * @param openid_identifier the OpenID identifier
+ * @param rememberme "true"
if the login should be persistent, null
or
+ * "false"
otherwise.
+ * @param request the request object
+ * @param response the response object
+ * @return true if the filter should return after this method ends, false otherwise
+ */
+ public boolean processOpenIdLogin(String openid_identifier, String rememberme, SecurityRequestWrapper request,
+ HttpServletResponse response, XWikiContext context) throws Exception
+ {
+ if (openid_identifier == null || openid_identifier.trim().equals("")) {
+ context.put("message", "noopenid");
+ return false;
+ }
+
+ try {
+ ConsumerManager manager = OpenIdHelper.getConsumerManager();
+
+ String return_to_url =
+ context.getWiki().getExternalURL("XWikiLogin", "loginsubmit", "rememberme=" + rememberme, context);
+
+ List discoveries = manager.discover(openid_identifier);
+ DiscoveryInformation discovered = manager.associate(discoveries);
+
+ // store the discovery information in the user's session
+ request.getSession().setAttribute("openid-discovery", discovered);
+
+ AuthRequest auth_request = manager.authenticate(discovered, return_to_url);
+
+ // set the realm
+ auth_request.setRealm(((XWikiServletURLFactory) context.getURLFactory()).getServerURL(context).toString()
+ + ((XWikiServletURLFactory) context.getURLFactory()).getContextPath());
+
+ if (log.isInfoEnabled()) {
+ log.info("Redirecting user to OP (OpenID identifier: " + openid_identifier + ")");
+ }
+
+ if (discovered.isVersion2()) {
+ // OpenID 2.0 supports HTML FORM Redirection which allows payloads >2048 bytes
+ VelocityContext vcontext = (VelocityContext) context.get("vcontext");
+ vcontext.put("op_endpoint", auth_request.getDestinationUrl(false));
+ vcontext.put("openid_parameters", auth_request.getParameterMap());
+
+ String redirect_form = context.getWiki().parseTemplate("openid_form_redirect.vm", context);
+
+ response.getOutputStream().print(redirect_form);
+
+ // Close the output stream - otherwise the login form documented is also written to it
+ response.getOutputStream().close();
+ } else {
+ // The only method supported in OpenID 1.x is a HTTP-redirect (GET) to the OpenID Provider endpoint (the
+ // redirect-URL usually limited ~2048 bytes)
+ response.sendRedirect(auth_request.getDestinationUrl(true));
+ }
+ } catch (OpenIDException e) {
+ if (log.isInfoEnabled()) {
+ log.info("OpenID discovery failed: " + e.getMessage());
+ }
+
+ // present error to the user
+ context.put("message", "loginfailed");
+ }
+
+ return true;
+ }
+
+ /**
+ * Processes the response of an OpenID provider to complete the login process. Checks the response of the OP and in
+ * case of success it logs in the user. Otherwise an error message is put into the context and shown to the user
+ * afterwards.
+ *
+ * @param request the request object
+ * @param response the response object
+ * @param context the context
+ * @return true if the filter should return after this method ends, false otherwise
+ */
+ public boolean processOpenIdLoginResponse(SecurityRequestWrapper request, HttpServletResponse response,
+ XWikiContext context) throws Exception
+ {
+ try {
+ ConsumerManager manager = OpenIdHelper.getConsumerManager();
+
+ // extract the parameters from the authentication response which come in as a HTTP request from the OpenID
+ // provider
+ ParameterList openid_response = new ParameterList(request.getParameterMap());
+
+ // retrieve the previously stored discovery information
+ DiscoveryInformation discovered =
+ (DiscoveryInformation) request.getSession().getAttribute("openid-discovery");
+
+ // verify the response
+ StringBuffer receivingURL = request.getRequestURL();
+ String queryString = request.getQueryString();
+ if (queryString != null && queryString.length() > 0)
+ receivingURL.append("?").append(request.getQueryString());
+
+ VerificationResult verification = manager.verify(receivingURL.toString(), openid_response, discovered);
+ Identifier verified = verification.getVerifiedId();
+
+ if (verified != null) {
+ String username = OpenIdHelper.findUser(verified.getIdentifier(), context);
+
+ if (username == null) {
+ // no user was found for this OpenID identifier
+ if (log.isInfoEnabled()) {
+ log.info("No user for OpenID " + verified.getIdentifier() + " found.");
+ }
+
+ context.put("message", "openid_not_associated");
+ response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+ return true;
+ }
+
+ // The current authentication mechanisms is implemented in a very restrictive manner, we have to
+ // retrieve the user password (which is generated randomly during registration for OpenID users) and use
+ // it in order to authenticate the user.
+ String password = OpenIdHelper.getOpenIdUserPassword(verified.getIdentifier(), context);
+ Principal principal = authenticate(username, password, context);
+ if (principal != null) {
+ // invalidate old session if the user was already authenticated and logged in as a different user
+ if (request.getUserPrincipal() != null) {
+ request.getSession().invalidate();
+ }
+
+ // manage persistent login info if persistent login management is enabled
+ String rememberme = request.getParameter(FORM_REMEMBERME);
+ rememberme = (rememberme == null) ? "false" : rememberme;
+
+ if (this.persistentLoginManager != null) {
+ if (rememberme != null) {
+ this.persistentLoginManager.rememberLogin(request, response, username, password);
+ } else {
+ this.persistentLoginManager.forgetLogin(request, response);
+ }
+ }
+
+ request.setUserPrincipal(principal);
+
+ String continueToURL = getContinueToURL(request);
+ response.sendRedirect(response.encodeRedirectURL(continueToURL));
+ }
+ } else {
+ // authentication failed, show and log error message
+ if (openid_response.getParameter("openid.mode") != null
+ && openid_response.getParameter("openid.mode").getValue().equals("cancel")) {
+ context.put("message", "openidlogin_cancelled");
+ } else {
+ if (log.isInfoEnabled() && openid_response.getParameter("error") != null) {
+ log.info("OpenID login failed (error: "
+ + openid_response.getParameter("openid.error").getValue() + ")");
+ }
+ context.put("message", "loginfailed");
+ }
+ }
+ } catch (OpenIDException e) {
+ context.put("message", "loginfailed");
+ }
+
+ return true;
+ }
+
+ /**
* FormAuthenticator has a special case where the user should be sent to a default page if the user spontaneously
* submits a login request.
*
Index: xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java
===================================================================
--- xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java (revision 11817)
+++ xwiki-core/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java (working copy)
@@ -242,7 +242,7 @@
String sql =
"delete from XWikiLock as lock where lock.userName=:userName";
Query query = session.createQuery(sql);
- String localName = user.getName().substring(user.getName().indexOf(":") + 1);
+ String localName = user.getName().substring(user.getName().indexOf(":") + 1);
query.setString("userName", localName);
query.executeUpdate();
} catch (Exception e) {
@@ -475,18 +475,23 @@
return user;
}
- protected boolean checkPassword(String username, String password, XWikiContext context)
- throws XWikiException
+ protected boolean checkPassword(String username, String password, XWikiContext context) throws XWikiException
{
try {
boolean result = false;
XWikiDocument doc = context.getWiki().getDocument(username, context);
- // We only allow empty password from users having a XWikiUsers object.
- if (doc.getObject("XWiki.XWikiUsers") != null) {
+ if (doc.getObject("XWiki.OpenIdIdentifier") != null) {
+ // For users having an OpenID the password doesn't need to be adjusted because it is set to the current
+ // value during the login process
String passwd = doc.getStringValue("XWiki.XWikiUsers", "password");
+ result = (password.equals(passwd));
+ }
+ if (result == false && doc.getObject("XWiki.XWikiUsers") != null) {
+ // We only allow empty password from users having a XWikiUsers object.
+ String passwd = doc.getStringValue("XWiki.XWikiUsers", "password");
password =
- ((PasswordClass) context.getWiki().getClass("XWiki.XWikiUsers", context)
- .getField("password")).getEquivalentPassword(passwd, password);
+ ((PasswordClass) context.getWiki().getClass("XWiki.XWikiUsers", context).getField("password"))
+ .getEquivalentPassword(passwd, password);
result = (password.equals(passwd));
}
Index: xwiki-core/src/main/java/com/xpn/xwiki/web/RegisterAction.java
===================================================================
--- xwiki-core/src/main/java/com/xpn/xwiki/web/RegisterAction.java (revision 11817)
+++ xwiki-core/src/main/java/com/xpn/xwiki/web/RegisterAction.java (working copy)
@@ -20,41 +20,284 @@
*/
package com.xpn.xwiki.web;
+import java.util.List;
+
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.plugin.openid.OpenIdHelper;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
-public class RegisterAction extends XWikiAction {
- public boolean action(XWikiContext context) throws XWikiException {
+import org.openid4java.consumer.ConsumerManager;
+import org.openid4java.consumer.VerificationResult;
+import org.openid4java.discovery.Identifier;
+import org.openid4java.discovery.DiscoveryInformation;
+import org.openid4java.message.ax.AxMessage;
+import org.openid4java.message.ax.FetchRequest;
+import org.openid4java.message.ax.FetchResponse;
+import org.openid4java.message.sreg.SRegMessage;
+import org.openid4java.message.sreg.SRegRequest;
+import org.openid4java.message.sreg.SRegResponse;
+import org.openid4java.message.*;
+import org.openid4java.OpenIDException;
+
+/**
+ * Action used to register new users. This action implements both, registration for classical user accounts with user
+ * name and password and users using OpenID.
+ */
+public class RegisterAction extends XWikiAction
+{
+ private static final Log log = LogFactory.getLog(RegisterAction.class);
+
+ private String template = "register";
+
+ public boolean action(XWikiContext context) throws XWikiException
+ {
XWiki xwiki = context.getWiki();
XWikiRequest request = context.getRequest();
XWikiResponse response = context.getResponse();
- XWikiDocument doc = context.getDoc();
+ template = "register";
+
String register = request.getParameter("register");
- if ((register!=null)&&(register.equals("1"))) {
+ if ((register != null) && (register.equals("1"))) {
int useemail = xwiki.getXWikiPreferenceAsInt("use_email_verification", 0, context);
int result;
- if (useemail==1)
- result = xwiki.createUser(true, "edit", context);
+ if (useemail == 1)
+ result = xwiki.createUser(true, "edit", context);
else
- result = xwiki.createUser(context);
+ result = xwiki.createUser(context);
VelocityContext vcontext = (VelocityContext) context.get("vcontext");
vcontext.put("reg", new Integer(result));
+ } else if ((register != null) && (register.equals("openid-discover"))) {
+ if (discoverOpenID(context))
+ return false;
+ } else if ((register != null) && (register.equals("openid-confirm"))) {
+ String confirm = request.getParameter("register-confirm");
+ if ("1".equals(confirm) == false) {
+ confirmOpenIDRegistration(context);
+ return true;
+ } else {
+ VelocityContext vcontext = (VelocityContext) context.get("vcontext");
+ vcontext.put("reg", new Integer(registerOpenID(context)));
+ }
}
String redirect = Utils.getRedirect(request, null);
- if (redirect==null)
+ if (redirect == null)
return true;
else {
sendRedirect(response, redirect);
return false;
}
- }
-
- public String render(XWikiContext context) throws XWikiException {
- return "register";
- }
+ }
+
+ public String render(XWikiContext context) throws XWikiException
+ {
+ return template;
+ }
+
+ /**
+ * Starts registration of an OpenID user. The OpenID provider belonging to the entered OpenID identifier is searched
+ * and the user is redirected to it to authenticate there. This processed is used to assure that the entered OpenID
+ * is valid and in possession of that user. If discovery fails, an error message is shown.
+ *
+ * @param context
+ * @return returns true if a redirect was sent, otherwise false.
+ * @author Markus Lanthaler
+ */
+ protected boolean discoverOpenID(XWikiContext context)
+ {
+ XWikiRequest request = context.getRequest();
+ XWikiResponse response = context.getResponse();
+ VelocityContext vcontext = (VelocityContext) context.get("vcontext");
+
+ // Check for empty OpenID identifier
+ String openid_identifier = request.getParameter("openid_identifier");
+ if (openid_identifier == null || openid_identifier.equals("")) {
+ vcontext.put("reg", new Integer(-14));
+ return false;
+ }
+
+ try {
+ ConsumerManager manager = OpenIdHelper.getConsumerManager();
+
+ String return_to_url =
+ context.getWiki().getExternalURL("Register", "register", "register=openid-confirm", context);
+
+ // perform discovery on the user-supplied identifier
+ List discoveries = manager.discover(openid_identifier);
+
+ // attempt to associate with the OpenID provider and retrieve one service endpoint for authentication
+ DiscoveryInformation discovered = manager.associate(discoveries);
+ request.getSession().setAttribute("openid-disc", discovered);
+
+ // obtain a AuthRequest message to be sent to the OpenID provider
+ AuthRequest auth_request = manager.authenticate(discovered, return_to_url);
+
+ // set the realm
+ auth_request.setRealm(((XWikiServletURLFactory) context.getURLFactory()).getServerURL(context).toString()
+ + ((XWikiServletURLFactory) context.getURLFactory()).getContextPath());
+
+ // attribute exchange (request user data from the OP to speed-up the registration process)
+ FetchRequest att_exchange = FetchRequest.createFetchRequest();
+ att_exchange.addAttribute("email", "http://schema.openid.net/contact/email", true);
+ att_exchange.addAttribute("firstname", "http://axschema.org/namePerson/first", true);
+ att_exchange.addAttribute("lastname", "http://axschema.org/namePerson/last", true);
+
+ SRegRequest simple_reg_req = SRegRequest.createFetchRequest();
+ simple_reg_req.addAttribute("fullname", true);
+ simple_reg_req.addAttribute("firstname", true);
+ simple_reg_req.addAttribute("lastname", true);
+ simple_reg_req.addAttribute("nickname", true);
+ simple_reg_req.addAttribute("email", true);
+
+ auth_request.addExtension(att_exchange);
+ auth_request.addExtension(simple_reg_req);
+
+ if (discovered.isVersion2()) {
+ // OpenID 2.0 supports HTML form redirection which allows payloads >2048 bytes
+ vcontext.put("op_endpoint", auth_request.getDestinationUrl(false));
+ vcontext.put("openid_parameters", auth_request.getParameterMap());
+ template = "openid_form_redirect";
+ return false;
+ } else {
+ // the only method supported in OpenID 1.x is a HTTP-redirect (GET) to the OpenID Provider endpoint (the
+ // redirect-URL usually limited ~2048 bytes)
+ sendRedirect(response, auth_request.getDestinationUrl(true));
+ return true;
+ }
+ } catch (OpenIDException e) {
+ context.put("message", "register_openid_discovery_failed");
+ } catch (Exception e) {
+ context.put("message", "register_openid_discovery_failed");
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks the response of the OpenID provider (OP) and outputs a confirmation form. If the OP returns an error or
+ * the user cancelled at its site, an error message is shown to the user.
+ *
+ * @param context
+ * @throws XWikiException
+ * @author Markus Lanthaler
+ */
+ protected void confirmOpenIDRegistration(XWikiContext context) throws XWikiException
+ {
+ XWikiRequest request = context.getRequest();
+ VelocityContext vcontext = (VelocityContext) context.get("vcontext");
+
+ try {
+ ConsumerManager manager = OpenIdHelper.getConsumerManager();
+
+ // extract the parameters from the authentication response
+ // (which comes in as a HTTP request from the OpenID provider)
+ ParameterList openid_response = new ParameterList(request.getParameterMap());
+
+ // retrieve the previously stored discovery information
+ DiscoveryInformation discovered = (DiscoveryInformation) request.getSession().getAttribute("openid-disc");
+
+ // extract the receiving URL from the HTTP request
+ StringBuffer receiving_url = request.getRequestURL();
+ String query_string = request.getQueryString();
+ if (query_string != null && query_string.length() > 0)
+ receiving_url.append("?").append(request.getQueryString());
+
+ // verify the response; ConsumerManager needs to be the same
+ // (static) instance used to place the authentication request
+ VerificationResult verification = manager.verify(receiving_url.toString(), openid_response, discovered);
+
+ // examine the verification result and extract the verified identifier
+ Identifier verified = verification.getVerifiedId();
+
+ if (verified != null) {
+ // check if this OpenID is already registered
+ if (OpenIdHelper.findUser(verified.getIdentifier(), context) != null) {
+ vcontext.put("reg", new Integer(-13));
+ vcontext.put("openid_identifier", verified.getIdentifier());
+ return;
+ }
+
+ // OpenID not used yet, continue with registration (ask the user for confirmation)
+ vcontext.put("reg", new Integer(2));
+ vcontext.put("openid_identifier", verified.getIdentifier());
+
+ AuthSuccess auth_success = (AuthSuccess) verification.getAuthResponse();
+
+ String email = null;
+ String firstname = null;
+ String lastname = null;
+
+ if (auth_success.hasExtension(AxMessage.OPENID_NS_AX)) {
+ FetchResponse fetch_resp = (FetchResponse) auth_success.getExtension(AxMessage.OPENID_NS_AX);
+ email = (String) fetch_resp.getAttributeValues("email").get(0);
+ firstname = (String) fetch_resp.getAttributeValues("firstname").get(0);
+ lastname = (String) fetch_resp.getAttributeValues("lastname").get(0);
+ }
+
+ if (auth_success.getExtension(SRegMessage.OPENID_NS_SREG) instanceof SRegResponse) {
+ SRegResponse simple_reg_resp = (SRegResponse) auth_success.getExtension(SRegMessage.OPENID_NS_SREG);
+
+ if (email == null)
+ email = simple_reg_resp.getAttributeValue("email");
+
+ if (firstname == null && lastname == null)
+ firstname = simple_reg_resp.getAttributeValue("fullname");
+ }
+
+ vcontext.put("email", email);
+ vcontext.put("first_name", firstname);
+ vcontext.put("last_name", lastname);
+ } else {
+ // authentication failed, show and log error message
+ if (openid_response.getParameter("openid.mode") != null
+ && openid_response.getParameter("openid.mode").getValue().equals("cancel")) {
+ context.put("message", "register_openid_discovery_cancelled");
+ } else {
+ if (log.isInfoEnabled() && openid_response.getParameter("error") != null) {
+ log.info("OpenID login failed (error: "
+ + openid_response.getParameter("openid.error").getValue() + ")");
+ }
+ context.put("message", "register_openid_discovery_failed");
+ }
+ }
+ } catch (OpenIDException e) {
+ context.put("message", "register_openid_discovery_failed");
+ }
+ }
+
+ /**
+ * Completes the registration of an OpenID user. The user name is created automatically based on the OpenID
+ * identifier by {@link OpenIdHelper#openIdIdentifierToUsername}.
+ *
+ * @param context
+ * @return an status code describing the success or failure of the registration
+ * @throws XWikiException
+ * @author Markus Lanthaler
+ * @see OpenIdHelper#openIdIdentifierToUsername
+ */
+ protected int registerOpenID(XWikiContext context) throws XWikiException
+ {
+ XWikiRequest request = context.getRequest();
+ String openid_identifier = request.getParameter("openid_identifier");
+ String firstname = request.getParameter("register_first_name");
+ String lastname = request.getParameter("register_last_name");
+ String email = request.getParameter("register_email");
+
+ int result = OpenIdHelper.createUser(openid_identifier, firstname, lastname, email, context);
+ if (result == 3) {
+ // user registration successful
+ VelocityContext vcontext = (VelocityContext) context.get("vcontext");
+ vcontext.put("username", context.getWiki().getUserName(OpenIdHelper.findUser(openid_identifier, context),
+ context));
+ vcontext.put("openid_identifier", openid_identifier);
+ }
+
+ return result;
+ }
}
Index: xwiki-core/src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java
===================================================================
--- xwiki-core/src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java (revision 11817)
+++ xwiki-core/src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java (working copy)
@@ -134,12 +134,12 @@
return servletPath;
}
- private URL getServerURL(XWikiContext context) throws MalformedURLException
+ public URL getServerURL(XWikiContext context) throws MalformedURLException
{
return getServerURL(context.getDatabase(), context);
}
- private URL getServerURL(String xwikidb, XWikiContext context) throws MalformedURLException
+ public URL getServerURL(String xwikidb, XWikiContext context) throws MalformedURLException
{
URL serverURL = this.serverURL;
if (context.getRequest() != null) { // necessary to the tests
Index: xwiki-core/src/main/resources/ApplicationResources.properties
===================================================================
--- xwiki-core/src/main/resources/ApplicationResources.properties (revision 11817)
+++ xwiki-core/src/main/resources/ApplicationResources.properties (working copy)
@@ -110,6 +110,7 @@
attachthisfile=Attach this file
username=Username
password=Password
+openid=OpenID
xwikidoc=Documentation
documentation=Documentation
xwikisyntax=XWiki Syntax
@@ -527,12 +528,32 @@
admin.adminappnotinstalled=The administration application is not installed. Since XWiki Enterprise 1.5 the Administration is distributed as an application. You can download it from {0}.
#login
+login_username_password_desc=with your username and password
+login_openid_desc=... or with your OpenID
nousername=No user name given
+noopenid=Please enter your OpenID identifier to log in
nopassword=No password given
wronguser=Wrong user name
wrongpassword=Wrong password
loginfailed=Internal error
+openidlogin_cancelled=The login process was cancelled at the OpenID provider site
+openid_not_associated=No user was found for this OpenID
+#openid form redirect
+openid.form_redirect.title=OpenID login in progress
+openid.form_redirect.description=You are redirected to your OpenID provider in a few seconds. Please wait...
+openid.form_redirect.button=Continue...
+
+#openid registration form
+openid.registration.welcome=If you have an OpenID or i-name you can speed-up your registration by entering it here
+openid.registration.openid=OpenID
+openid.registration.discovery_submit=Register with OpenID
+openid.registration.confirmation=Verify the form below and complete your OpenID registration
+openid.registration.confirmation_submit=Create OpenID account
+openid.registration.invalidOpenID=Enter a valid OpenID to continue with registration
+openid.registration.openIdAlreadyRegistered=The OpenID "{0}" is already registered. You can directly log in if it is in your possession.
+openid.registration.successful=Successfully registered user {0} ({1}).
+
switchto=Switch to
sectionEdit=Sectional Editing
@@ -619,6 +640,8 @@
registerfailed=Registration has failed
registerfailedcode=code
registersuccessful=Registration successful
+register_openid_discovery_cancelled=The registration with OpenID was cancelled at the OpenID provider site
+register_openid_discovery_failed=The registration with OpenID failed due to an internal error
leftPanels=Left Panels
rightPanels=Right Panels
@@ -764,6 +787,7 @@
core.comment.updateClassPropertyName=Updated class property name
core.comment.createdUser=Created user
core.comment.addedUserToGroup=Added user to group
+core.comment.addedOpenIdIdentifier=Added OpenID identifier
core.comment.rollback=Rollback to version {0}
core.comment.updateContent=Update Content
core.comment.uploadAttachmentComment=Upload new attachment {0}
Index: xwiki-core/src/main/resources/JcrQueries.properties
===================================================================
--- xwiki-core/src/main/resources/JcrQueries.properties (revision 11817)
+++ xwiki-core/src/main/resources/JcrQueries.properties (working copy)
@@ -3,3 +3,4 @@
getAllDocuments=//element(*, xwiki:document)/@fullName
listGroupsForUser=//element(*, xwiki:document)[obj/XWiki/XWikiGroups[@xp:member=:{username} or @xp:member=:{shortname} or @xp:member=:{veryshortname}]/@fullName
getAllUsers=//element(*, xwiki:document)[obj/XWiki/XWikiUsers]/@fullName
+getUserDocByOpenIdIdentifier=//element(*, xwiki:document)[obj/XWiki/OpenIdIdentifier/@xp:identifier=:{identifier}]/@fullName
Index: xwiki-core/src/main/resources/queries.hbm.xml
===================================================================
--- xwiki-core/src/main/resources/queries.hbm.xml (revision 11817)
+++ xwiki-core/src/main/resources/queries.hbm.xml (working copy)
@@ -23,4 +23,7 @@
select doc.fullName from XWikiDocument as doc, BaseObject as obj
where obj.name=doc.fullName and obj.className='XWiki.XWikiUsers'
+
+ select doc.fullName from XWikiDocument as doc, BaseObject as obj, StringProperty as prop where doc.fullName=obj.name and obj.className='XWiki.OpenIdIdentifier' and obj.id=prop.id.id and prop.id.name='identifier' and prop.value=:identifier
+