+ # handle OpenID authentication
+ def openid_authentication(openid_url)
+ # If we don't appear to have a user for this URL then ask the
+ # provider for some extra information to help with signup
+ if openid_url and User.find_by_openid_url(openid_url)
+ optional = nil
+ else
+ optional = [:nickname, :email]
+ end
+
+ # Start the authentication
+ authenticate_with_open_id(openid_url, :optional => optional) do |result, identity_url, registration|
+ if result.successful?
+ # We need to use the openid url passed back from the OpenID provider
+ # rather than the one supplied by the user, as these can be different.
+ #
+ # For example, you can simply enter yahoo.com in the login box rather
+ # than a user specific url. Only once it comes back from the provider
+ # provider do we know the unique address for the user.
+ if user = User.find_by_openid_url(identity_url)
+ case user.status
+ when "pending" then failed_login t('user.login.account not active')
+ when "active", "confirmed" then successful_login(user)
+ when "suspended" then failed_login t('user.login.account suspended')
+ else failed_login t('user.login.auth failure')
+ end
+ else
+ # We don't have a user registered to this OpenID, so redirect
+ # to the create account page with username and email filled
+ # in if they have been given by the OpenID provider through
+ # the simple registration protocol.
+ redirect_to :controller => 'user', :action => 'new', :nickname => registration['nickname'], :email => registration['email'], :openid => identity_url
+ end
+ elsif result.missing?
+ # Try and apply some heuristics to make common cases more user friendly
+ if openid_url = openid_alternate_url(openid_url)
+ openid_authentication(openid_url)
+ else
+ failed_login t('user.login.openid missing provider')
+ end
+ elsif result.invalid?
+ failed_login t('user.login.openid invalid')
+ else
+ failed_login t('user.login.auth failure')
+ end
+ end