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