lib/plezi/oauth/auth_controller.rb in plezi-0.8.4 vs lib/plezi/oauth/auth_controller.rb in plezi-0.8.5

- old
+ new

@@ -1,63 +1,82 @@ -require 'open-uri' + module Plezi ######################################### - # This is a social Authentication Controller + # This is a social Authentication Controller for OAuth2 services. + # This controller allows you to easily deploy Facebook Login, Google Login and any other OAuth2 complient login service. # - # This controller currently supports: + # To include this controller in your application, you need to require it using: # + # require 'plezi/oauth' + # + # It is possible to manualy register any OAuth 2.0 authentication service using the `register_service` method: + # + # register_service(:foo, + # app_id: 'registered app id / client id', + # app_secret: 'registered app secret / client secret', + # auth_url: "https://foo.bar.com/o/oauth2/auth", + # token_url: "https://foo.bar.com/oauth2/v3/token", + # profile_url: "https://foo.bar/oauth2/v1/userinfo", + # scope: "profile email") + # + # The `.register_service` method will be automatically called for the following login services: + # # - Facebook authentication using the Graph API, v. 2.3 - [see Facebook documentation](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3). # - Google authentication using the OAuth 2.0 API - [see Google documentation](https://developers.google.com/identity/protocols/OAuth2WebServer). # - # It's also possible to manualy register any OAuth 2.0 authentication service using the `register_service` method. - # - # To use this Controller in your application, make sure the following variables are set: + # To enjoy autorgistration for Facebook or Google, make sure the following environment variables are set: # ENV['FB_APP_ID'] = {facebook_app_id} # ENV['FB_APP_SECRET'] = {facebook_app_secret} # ENV['GOOGLE_APP_ID'] = {google_app_id} # ENV['GOOGLE_APP_SECRET'] = {google_app_secret} # - # Add the following route to routes.rb file (as always, route placement order effects behavior): + # To add the OAuth routes to the routes, use the following short-cut method (add it to the `routes.rb`) file: # # create_auth_shared_route do |service, remote_user_id, email, full_remote_response| # # perform any specific app authentication logic such as saving the info. # # return the current user or false if the callback is called with an authentication failure. # end # - # The `create_auth_shared_route` method is a shortcut for calling the `#shared_route` method with the relevant arguments and setting the OAuth2Ctrl callback. + # \* Notice that, as always, route placement order effects behavior, so that routes are checked according to order of creation. # + # The `create_auth_shared_route` method is a shortcut taht calls the `#shared_route` method with the relevant arguments and sets the OAuth2Ctrl callback. + # # Use the following links for social authentication: # - # - Facebook: "/auth/facebook?redirect_after=/foo/bar" - # - Google: "/auth/google?redirect_after=/foo/bar" - # - foo_service: "/auth/foo_service?redirect_after=/foo/bar" + # - Facebook: "/auth/facebook" + # - Google: "/auth/google" + # - foo_service: "/auth/foo_service" # + # You can control the page to which the user will return once authentication is complete + # (even when authentication fails) by setting the "redirect_after" parameter into the GET request in the url. for example: + # + # - Google: "/auth/google?redirect_after=/foo/bar" class OAuth2Ctrl - # Sets (or gets) the callback to be called after authentication is attempeted. + # Sets (or gets) the global callback to be called after authentication is attempeted. # # Accepts a block that will be called with the following parameters: # service_name:: the name of the service. i.e. :facebook, :google, etc'. # service_token:: the authentication token returned by the service. This token should be stored for future access # remote_user_id:: service's user id. - # remote_user_email:: users primamry email, if registed with the service. + # remote_user_email:: user's primamry email, as (and if) registed with the service. # remote_response:: a Hash with the complete user data response (including email and id). # - # If the authentication fails for Facebook, the block will be called with the following values `auth_callback.call(nil, ni, {server: :responce, might_be: :empty})` + # If the authentication fails for the service, the block will be called with the following values `auth_callback.call(nil, ni, {server: :responce, might_be: :empty})` # # The block will be run in the context of the controller and all the controller's methods will be available to it. # # i.e.: - # OAuth2Ctrl.auth_callback |service, service_token, id, email, res| cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email } + # OAuth2Ctrl.auth_callback |service, service_token, id, email, full_res| PL.info "OAuth got: #{full_res.to_s}"; cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email } # # defaults to the example above, which isn't a very sercure behavior, but allows for easy testing. def self.auth_callback &block - block_given? ? (@auth_callback = block) : ( @auth_callback ||= (Proc.new {|service, service_token, id, email, res| Plezi.info "deafult callback called for #{service}, with response: #{res.to_s}"; cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email}) ) + block_given? ? (@@auth_callback = block) : ( @@auth_callback ||= (Proc.new {|service, service_token, id, email, res| Plezi.info "deafult callback called for #{service}, with response: #{res.to_s}"; cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email}) ) end # Stores the registered services library SERVICES = {} @@ -67,32 +86,34 @@ # Accepts the following required parameters: # service_name:: a Symbol naming the service. i.e. :facebook or :google . # options:: a Hash of options, some of which are required. # # The options are: - # app_id:: the aplication's unique ID registered with the service. i.e. ENV[FB_APP_ID] (storing these in environment variables is safer then hardcoding them) - # app_secret:: the aplication's unique secret registered with the service. - # auth_url:: the authentication URL. This is the url to which the user is redirected. i.e.: "https://www.facebook.com/dialog/oauth" - # token_url:: the token request URL. This is the url used to switch the single-use code into a persistant authentication token. i.e.: "https://www.googleapis.com/oauth2/v3/token" - # profile_url:: the URL used to ask the service for the user's profile (the service's API url). i.e.: "https://graph.facebook.com/v2.3/me" + # app_id:: Required. The aplication's unique ID registered with the service. i.e. ENV [FB_APP_ID] (storing these in environment variables is safer then hardcoding them) + # app_secret:: Required. The aplication's unique secret registered with the service. + # auth_url:: Required. The authentication URL. This is the url to which the user is redirected. i.e.: "https://www.facebook.com/dialog/oauth" + # token_url:: Required. The token request URL. This is the url used to switch the single-use code into a persistant authentication token. i.e.: "https://www.googleapis.com/oauth2/v3/token" + # profile_url:: Required. The URL used to ask the service for the user's profile (the service's API url). i.e.: "https://graph.facebook.com/v2.3/me" # scope:: a String representing the scope requested. i.e. 'email profile'. # - # There will be an attempt to aitomatically register Facebook and Google login services under these conditions: + # There will be an attempt to automatically register Facebook and Google login services under these conditions: # - # * For Facebook: Both ENV['FB_APP_ID'] && ENV['FB_APP_SECRET'] have been defined. - # * For Google: Both ENV['GOOGLE_APP_ID'] && ENV['GOOGLE_APP_SECRET'] have been defined. + # * For Facebook: Both ENV ['FB_APP_ID'] && ENV ['FB_APP_SECRET'] have been defined. + # * For Google: Both ENV ['GOOGLE_APP_ID'] && ENV ['GOOGLE_APP_SECRET'] have been defined. # # - # Just for reference, at the time of this writing: + # The auto registration uses the following urls (updated to June 5, 2015): # # * facebook auth_url: "https://www.facebook.com/dialog/oauth" # * facebook token_url: "https://graph.facebook.com/v2.3/oauth/access_token" # * facebook profile_url: "https://graph.facebook.com/v2.3/me" # * google auth_url: "https://accounts.google.com/o/oauth2/auth" # * google token_url: "https://www.googleapis.com/oauth2/v3/token" # * google profile_url: "https://www.googleapis.com/plus/v1/people/me" # + # to change the default url's for Facebook or Google, simpley re-register the service using this method. + # def self.register_service service_name, options raise "Cannot register service, missing required information." unless service_name && options[:auth_url] && options[:token_url] && options[:profile_url] && options[:app_id] && options[:app_secret] # for google, scope is space delimited. for facebook it's comma delimited options[:scope] ||= 'profile, email' SERVICES[service_name] = options @@ -199,10 +220,10 @@ # # The method accepts a block that will be used to set the authentication callback. See the Plezi::OAuth2Ctrl documentation for details. # # The method can be called only once and will self-destruct. def create_auth_shared_route options = {}, &block - shared_route "auth/(:id)/(:code)" , Plezi::OAuth2Ctrl + shared_route "auth/(:id)" , Plezi::OAuth2Ctrl undef create_auth_shared_route - Plezi::OAuth2Ctrl.auth_callback = block if block + Plezi::OAuth2Ctrl.auth_callback &block if block Plezi::OAuth2Ctrl end