- def openid_specialcase_mapping(openid_url)
- #Special case gmail.com, as it is pontentially a popular OpenID provider and unlike
- #yahoo.com, where it works automatically, Google have hidden their OpenID endpoint
- #somewhere obscure making it less userfriendly.
- if (openid_url.match(/(.*)gmail.com(\/?)$/) or openid_url.match(/(.*)googlemail.com(\/?)$/) )
- return 'https://www.google.com/accounts/o8/id'
- end
-
- return nil
- end
-
- def openid_verify(openid_url,account_create)
- authenticate_with_open_id(openid_url) do |result, identity_url|
- 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.
- #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url
- #only once it comes back from the OpenID provider do we know the unique address for
- #the user.
- @user = session[:new_usr] unless @user #this is used for account creation when the user is not yet in the database
- @user.openid_url = identity_url
- elsif result.missing?
- mapped_id = openid_specialcase_mapping(openid_url)
- if mapped_id
- openid_verify(mapped_id, account_create)
- else
- flash.now[:error] = t 'user.login.openid missing provider'
- end
- elsif result.invalid?
- flash.now[:error] = t 'user.login.openid invalid'
- else
- flash.now[:error] = t 'user.login.auth failure'
- end
- end
- end
-
- def open_id_authentication(openid_url)
- #TODO: only ask for nickname and email, if we don't already have a user for that openID, in which case
- #email and nickname are already filled out. I don't know how to do that with ruby syntax though, as we
- #don't want to duplicate the do block
- #On the other hand it also doesn't matter too much if we ask every time, as the OpenID provider should
- #remember these results, and shouldn't repromt the user for these data each time.
- user = nil
- authenticate_with_open_id(openid_url, :return_to => request.protocol + request.host_with_port + '/login?referer=' + params[:referer], :optional => [:nickname, :email]) 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.
- #e.g. one can simply enter yahoo.com in the login box, i.e. no user specific url
- #only once it comes back from the OpenID provider do we know the unique address for
- #the user.
- user = User.find_by_openid_url(identity_url)
- if user
- if user.visible? and user.active?
- session[:user] = user.id
- session_expires_after 1.month if session[:remember]
- return user
- else
- user = nil
- flash.now[:error] = t 'user.login.account not active'
- end
- else
- #We don't have a user registered to this OpenID. 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
- else if result.missing?
- #Try and apply some heuristics to make common cases more userfriendly
- mapped_id = openid_specialcase_mapping(openid_url)
- if mapped_id
- open_id_authentication(mapped_id)
- else
- flash.now[:error] = t 'user.login.openid missing provider'
- end
- else if result.invalid?
- flash.now[:error] = t 'user.login.openid invalid'
- else
- flash.now[:error] = t 'user.login.auth failure'
- end
- end
- end
- end
- return user
- end
-