socialite 0.1.0.pre → 0.1.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. data/app/assets/images/socialite/facebook_64.png +0 -0
  2. data/app/assets/images/socialite/twitter_64.png +0 -0
  3. data/app/controllers/socialite/sessions_controller.rb +69 -0
  4. data/app/controllers/socialite/users_controller.rb +2 -31
  5. data/app/views/layouts/socialite/application.html.haml +1 -1
  6. data/app/views/socialite/identities/new.html.haml +6 -19
  7. data/app/views/socialite/sessions/new.html.haml +30 -0
  8. data/app/views/socialite/users/new.html.haml +10 -0
  9. data/config/routes.rb +6 -7
  10. data/lib/generators/socialite/install_generator.rb +24 -5
  11. data/lib/generators/socialite/migrations_generator.rb +1 -1
  12. data/lib/generators/socialite/templates/socialite.rb +9 -0
  13. data/lib/generators/socialite/templates/users.rb.erb +5 -1
  14. data/lib/generators/socialite/views_generator.rb +22 -0
  15. data/lib/socialite.rb +4 -8
  16. data/lib/socialite/controllers/helpers.rb +5 -115
  17. data/lib/socialite/engine.rb +8 -11
  18. data/lib/socialite/ext/omniauth/identity/model.rb +29 -0
  19. data/lib/socialite/models/identity_concern.rb +24 -5
  20. data/lib/socialite/models/user_concern.rb +39 -0
  21. data/lib/socialite/version.rb +1 -1
  22. data/spec/dummy/app/controllers/pages_controller.rb +7 -0
  23. data/spec/dummy/app/models/user.rb +2 -0
  24. data/spec/dummy/app/views/pages/index.html.haml +5 -0
  25. data/spec/dummy/config/initializers/omniauth-identity.rb +11 -0
  26. data/spec/dummy/config/initializers/socialite.rb +9 -0
  27. data/spec/dummy/config/routes.rb +17 -1
  28. data/spec/dummy/db/migrate/20130207223009_create_socialite_users.rb +16 -0
  29. data/spec/dummy/db/migrate/{20130206224517_create_socialite_identities.rb → 20130207223010_create_socialite_identities.rb} +0 -0
  30. data/spec/dummy/db/schema.rb +7 -3
  31. data/spec/factories/user.rb +11 -1
  32. data/{features/registration/twitter_signup.feature → spec/features/.gitkeep} +0 -0
  33. data/spec/features/facebook_registration_spec.rb +16 -0
  34. data/spec/features/identity_login_spec.rb +26 -0
  35. data/spec/features/identity_registration_spec.rb +31 -0
  36. data/spec/generators/socialite/install_generator_spec.rb +8 -1
  37. data/spec/generators/socialite/views_generator_spec.rb +27 -0
  38. data/spec/models/identity_spec.rb +4 -6
  39. data/spec/models/user_spec.rb +18 -18
  40. data/spec/socialite_spec.rb +31 -7
  41. data/spec/spec_helper.rb +4 -1
  42. data/spec/support/capybara.rb +3 -0
  43. data/spec/support/database_cleaner.rb +18 -0
  44. data/spec/support/identity_shared_example.rb +4 -23
  45. data/spec/support/omniauth.rb +35 -0
  46. metadata +95 -78
  47. data/app/controllers/socialite/identities_controller.rb +0 -41
  48. data/app/controllers/socialite/session_controller.rb +0 -32
  49. data/app/views/socialite/session/new.html.haml +0 -31
  50. data/app/views/socialite/user/_form.html.haml +0 -13
  51. data/app/views/socialite/user/edit.html.haml +0 -1
  52. data/app/views/socialite/user/show.html.haml +0 -16
  53. data/features/authentication/facebook_signin.feature +0 -5
  54. data/features/authentication/twitter_signin.feature +0 -5
  55. data/features/identities/facebook_management.feature +0 -14
  56. data/features/identities/twitter_management.feature +0 -7
  57. data/features/registration/facebook_signup.feature +0 -10
  58. data/features/step_definitions/authentication_steps.rb +0 -31
  59. data/features/step_definitions/common_steps.rb +0 -13
  60. data/features/step_definitions/identity_steps.rb +0 -5
  61. data/features/step_definitions/web_steps.rb +0 -254
  62. data/features/support/env.rb +0 -58
  63. data/features/support/hooks.rb +0 -3
  64. data/features/support/omniauth.rb +0 -31
  65. data/features/support/paths.rb +0 -34
  66. data/features/support/selectors.rb +0 -39
  67. data/lib/socialite/helpers/authentication.rb +0 -17
  68. data/lib/socialite/models/facebook_identity.rb +0 -14
  69. data/spec/dummy/db/migrate/20130206224516_create_socialite_users.rb +0 -12
  70. data/spec/factories/facebook.rb +0 -5
  71. data/spec/factories/twitter.rb +0 -6
  72. data/spec/models/facebook_spec.rb +0 -31
@@ -0,0 +1,69 @@
1
+ module Socialite
2
+ class SessionsController < ApplicationController
3
+ unloadable
4
+
5
+ def new
6
+ # Login Page
7
+ end
8
+
9
+ def create
10
+ auth = request.env['omniauth.auth']
11
+ # Find an identity here
12
+ @identity = Socialite.identity_class.find_or_create_from_omniauth(auth)
13
+
14
+ if user_signed_in? # Check if user is already signed in.
15
+ if @identity.user == current_user
16
+ # User is signed in so they are trying to link an identity with their
17
+ # account. But we found the identity and the user associated with it
18
+ # is the current user. So the identity is already associated with
19
+ # this user. So let's display an error message.
20
+ redirect_to main_app.root_url, :notice => "You have already linked this account"
21
+ else
22
+ # The identity is not associated with the current_user so lets
23
+ # associate the identity.
24
+ @identity.user = current_user
25
+ @identity.save
26
+ redirect_to main_app.root_url, :notice => "Account successfully authenticated"
27
+ end
28
+ else # User is not logged in, this is a new signin
29
+ if @identity.user.present?
30
+ # The identity we found had a user associated with it so let's
31
+ # just log them in here
32
+ self.current_user = @identity.user
33
+ redirect_to main_app.root_url, :notice => "Signed in!"
34
+ else
35
+ # The authentication has no user assigned and there is no user signed in
36
+ # Our decision here is to create a new account for the user
37
+ # But your app may do something different (eg. ask the user
38
+ # if he already signed up with some other service)
39
+ user = if @identity.provider == 'identity'
40
+ Socialite.user_class.find(@identity.uid)
41
+ # If the provider is identity, then it means we already created a user
42
+ # So we just load it up
43
+ else
44
+ # otherwise we have to create a user with the auth hash
45
+ Socialite.user_class.create_from_omniauth(auth)
46
+ # NOTE: we will handle the different types of data we get back
47
+ # from providers at the model level in create_from_omniauth
48
+ end
49
+ # We can now link the authentication with the user and log him in
50
+ user.identities << @identity
51
+ self.current_user = user
52
+ redirect_to main_app.root_path, notice: "Welcome to The app!"
53
+
54
+ # No user associated with the identity so we need to create a new one
55
+ # redirect_to new_user_url, :notice => "Please finish registering"
56
+ end
57
+ end
58
+ end
59
+
60
+ def destroy
61
+ self.current_user = nil
62
+ redirect_to main_app.root_url, :notice => 'Signed out!'
63
+ end
64
+
65
+ def failure
66
+ redirect_to main_app.root_url, :alert => "Authentication failed, please try again."
67
+ end
68
+ end
69
+ end
@@ -2,37 +2,8 @@ module Socialite
2
2
  class UsersController < ApplicationController
3
3
  unloadable
4
4
 
5
- before_filter :ensure_user
6
- respond_to :html, :json
7
-
8
- def show
9
- respond_with(user)
10
- end
11
-
12
- def edit
13
- respond_with(user)
14
- end
15
-
16
- def update
17
- flash_message :notice, 'Your account has been removed along with any associated identities.'
18
- respond_with(user) do |format|
19
- format.html { redirect_back_or_default(user_path) }
20
- end
21
- end
22
-
23
- def destroy
24
- user.destroy
25
- logout!
26
- flash_message :notice, 'Your account has been removed along with any associated identities.'
27
- respond_with(user) do |format|
28
- format.html { redirect_back_or_default(user_path) }
29
- end
30
- end
31
-
32
- private
33
-
34
- def user
35
- @user = current_user
5
+ def new
6
+ @user = env['omniauth.identity'] ||= Socialite.user_class.new
36
7
  end
37
8
  end
38
9
  end
@@ -2,7 +2,7 @@
2
2
  %html
3
3
  %head
4
4
  %title Socialite
5
- = stylesheet_link_tag "socialite/application", :media => "all"
5
+ = stylesheet_link_tag "socialite/application", :media => "all"
6
6
  = javascript_include_tag "socialite/application"
7
7
  = csrf_meta_tags
8
8
  %body
@@ -1,27 +1,14 @@
1
1
  %h1 New Account
2
2
 
3
- = form_tag "/auth/identity/register" do
3
+ = simple_form_for @identity, :url => '/auth/identity/register' do |f|
4
4
  - if @identity && @identity.errors.any?
5
5
  .error_messages
6
6
  %h2 #{pluralize(@identity.errors.count, "error")} prohibited this account from being saved:
7
7
  %ul
8
8
  - @identity.errors.full_messages.each do |msg|
9
9
  %li= msg
10
- .field
11
- = label_tag :name
12
- %br
13
- = text_field_tag :name, @identity.try(:name)
14
- .field
15
- = label_tag :email
16
- %br
17
- = text_field_tag :email, @identity.try(:email)
18
- .field
19
- = label_tag :password
20
- %br
21
- = password_field_tag :password
22
- .field
23
- = label_tag :password_confirmation
24
- %br
25
- = password_field_tag :password_confirmation
26
- .actions
27
- = submit_tag "Register"
10
+
11
+ = f.input :email, :input_html => {:name => 'email'}
12
+ = f.input :password, :as => 'password', :input_html => {:name => 'password'}
13
+ = f.input :password_confirmation, :label => "Confirm Password", :as => 'password', :input_html => {:name => 'password_confirmation'}
14
+ = f.button :submit, 'Register'
@@ -0,0 +1,30 @@
1
+ %h1 Sign In
2
+
3
+ %p
4
+ %strong Sign in through one of these services:
5
+
6
+ .auth_providers
7
+ - if defined?(OmniAuth::Strategies::Twitter)
8
+ %a.auth_provider{:href => "/auth/twitter"}
9
+ = image_tag "twitter_64.png", :size => "64x64", :alt => "Twitter"
10
+ Twitter
11
+ - if defined?(OmniAuth::Strategies::Facebook)
12
+ %a.auth_provider{:href => "/auth/facebook"}
13
+ = image_tag "facebook_64.png", :size => "64x64", :alt => "Facebook"
14
+ Facebook
15
+
16
+ %p
17
+ %strong Don't use these services?
18
+ #{link_to "Create an account", signup_path} or login below.
19
+
20
+ = form_tag "/auth/identity/callback" do
21
+ .field
22
+ = label_tag :auth_key, "Email"
23
+ %br
24
+ = text_field_tag :auth_key
25
+ .field
26
+ = label_tag :password
27
+ %br
28
+ = password_field_tag :password
29
+ .actions
30
+ = submit_tag "Sign in"
@@ -0,0 +1,10 @@
1
+ -# UsersController#new registration form is ONLY used with omniauth-identity
2
+
3
+ = simple_form_for @user, :url => '/auth/identity/register' do |f|
4
+ %h1 Create an Account
5
+ -# specify :input_html to avoid params nesting
6
+ -# = f.input :name, :input_html => {:name => 'name'}
7
+ = f.input :email, :input_html => {:name => 'email'}
8
+ = f.input :password, :as => 'password', :input_html => {:name => 'password'}
9
+ = f.input :password_confirmation, :label => "Confirm Password", :as => 'password', :input_html => {:name => 'password_confirmation'}
10
+ = f.button :submit, 'Sign Up'
@@ -1,10 +1,9 @@
1
1
  Socialite::Engine.routes.draw do
2
- # match '/login' => 'session#new', :as => :login
3
- # match '/auth/:service/callback' => 'identities#create', :as => :callback
4
- # match '/auth/failure' => 'identities#failure'
5
- # match '/logout' => 'session#destroy', :as => :logout
2
+ match '/signup', :to => 'users#new'
3
+ match '/auth/:provider/callback', :to => 'sessions#create'
6
4
 
7
- # resource :user, :except => [:new, :create] do
8
- # resources :identities
9
- # end
5
+ match '/logout', :to => 'sessions#destroy', :as => 'logout'
6
+ match '/login', :to => 'sessions#new', :as => 'login'
7
+
8
+ resources :users # needed by omniauth-identity
10
9
  end
@@ -2,7 +2,7 @@ require 'rails/generators'
2
2
 
3
3
  module Socialite
4
4
  module Generators
5
- class InstallGenerator < ::Rails::Generators::Base
5
+ class InstallGenerator < ::Rails::Generators::Base #:nodoc:
6
6
  source_root File.expand_path("../templates", __FILE__)
7
7
 
8
8
  desc 'Creates a socialite initializer'
@@ -10,10 +10,29 @@ module Socialite
10
10
  template 'socialite.rb', 'config/initializers/socialite.rb'
11
11
  end
12
12
 
13
- # def add_opro_routes
14
- # socialite_routes = "mount_socialite_oauth"
15
- # route socialite_routes
16
- # end
13
+ def mount_engine
14
+ puts "Mounting Socialite::Engine at \"/socialite\" in config/routes.rb..."
15
+ insert_into_file("config/routes.rb", :after => /routes.draw.do\n/) do
16
+ %Q{
17
+ # This line mounts Socialite's routes at /socialite by default.
18
+ # This means, any requests to the /socialite URL of your application will go
19
+ # to Socialite::SessionsController#new. If you would like to change where
20
+ # this extension is mounted, simply change the :at option to something
21
+ # different.
22
+ #
23
+ # We ask that you don't use the :as option here, as Socialite relies on it
24
+ # being the default of "socialite"
25
+ mount Socialite::Engine, :at => '/socialite'
26
+ match '/login' => 'socialite::sessions#new'
27
+ match '/logout', :to => 'socialite::sessions#destroy'
28
+ match '/signup', :to => 'socialite::users#new'
29
+ match '/auth/:provider/callback', :to => 'socialite::sessions#create'
30
+ match '/auth/failure', :to => 'socialite::sessions#failure'
31
+
32
+ }
33
+ end
34
+
35
+ end
17
36
  end
18
37
  end
19
38
  end
@@ -2,7 +2,7 @@ require 'rails/generators/migration'
2
2
 
3
3
  module Socialite
4
4
  module Generators
5
- class MigrationsGenerator < ::Rails::Generators::Base
5
+ class MigrationsGenerator < ::Rails::Generators::Base #:nodoc:
6
6
  include Rails::Generators::Migration
7
7
  source_root File.expand_path('../templates', __FILE__)
8
8
 
@@ -20,6 +20,15 @@ Socialite.setup do |config|
20
20
  # }
21
21
  # config.provider :twitter, ENV['TWITTER_APP_KEY'], ENV['TWITTER_SECRET']
22
22
 
23
+ # We highly recommended adding the omniauth-identity gem to your Gemfile.
24
+ # This does not enforce a password on signup, but establishes a common
25
+ # 'password recovery' entry point for all users.
26
+ #
27
+ # config.provider :identity,
28
+ # :model => Socialite.user_class,
29
+ # :fields => [:email],
30
+ # :on_failed_registration => Socialite::UsersController.action(:new)
31
+
23
32
  if Rails.env.production?
24
33
  # Any production specific information
25
34
  elsif Rails.env.development?
@@ -1,9 +1,13 @@
1
1
  class CreateSocialiteUsers < ActiveRecord::Migration
2
2
  def up
3
3
  create_table :<%= options[:users_table] %> do |t|
4
- t.string :name
4
+ t.string :name, :email
5
+ t.string :password_digest # set :null => false to enforce identity, requires 'bcrypt-ruby' in your Gemfile.
5
6
  t.timestamps
6
7
  end
8
+
9
+ # Enforce only every email must be unique
10
+ add_index :<%= options[:users_table] %>, :email, :unique => true
7
11
  end
8
12
 
9
13
  def down
@@ -0,0 +1,22 @@
1
+ require 'rails/generators'
2
+
3
+ module Socialite
4
+ module Generators
5
+ class ViewsGenerator < ::Rails::Generators::Base #:nodoc:
6
+ source_root File.expand_path("../../../../app/views/socialite", __FILE__)
7
+ desc "Used to copy socialite's views to your application's views."
8
+
9
+ def copy_views
10
+ view_directory :identities
11
+ view_directory :sessions
12
+ view_directory :users
13
+ end
14
+
15
+ protected
16
+
17
+ def view_directory(name)
18
+ directory name.to_s, "app/views/socialite/#{name}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -10,10 +10,6 @@ module Socialite
10
10
  autoload :Helpers, 'socialite/controllers/helpers'
11
11
  end
12
12
 
13
- module Helpers
14
- autoload :Authentication, 'socialite/helpers/authentication.rb'
15
- end
16
-
17
13
  module Models
18
14
  autoload :IdentityConcern, 'socialite/models/identity_concern'
19
15
  autoload :UserConcern, 'socialite/models/user_concern'
@@ -35,18 +31,18 @@ module Socialite
35
31
  end
36
32
 
37
33
  def self.identity_class
38
- identity_class_name.constantize
34
+ identity_class_name.try(:constantize)
39
35
  end
40
36
 
41
37
  def self.identity_class_name
42
- @@identity_class.camelize
38
+ @@identity_class.try(:camelize) || 'Identity'
43
39
  end
44
40
 
45
41
  def self.user_class
46
- user_class_name.constantize
42
+ user_class_name.try(:constantize)
47
43
  end
48
44
 
49
45
  def self.user_class_name
50
- @@user_class.camelize
46
+ @@user_class.try(:camelize) || 'User'
51
47
  end
52
48
  end
@@ -4,130 +4,20 @@ module Socialite
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  included do
7
- helper_method :current_user, :user_signed_in?, :current_user?, :default_route
7
+ helper_method :current_user, :user_signed_in?
8
8
  end
9
9
 
10
- # Set default route for redirect
11
- #
12
- # @param [String] the path for default redirects
13
- # @return [String] the default path for redirect
14
- # (see #default_route)
15
- def default_route=(route)
16
- @default_route = route
17
- end
18
-
19
- # Get default route for redirect
20
- #
21
- # @return [String] the default path for redirect
22
- # (see #default_route=)
23
- def default_route
24
- @default_route ||= main_app.root_url
25
- end
26
-
27
- # Helper for supporting multiple flash messages per type
28
- #
29
- # @param [Symbol] the type of flash message. Common types are
30
- # :success, :notice, :error
31
- # @param [String] the message to attach to the flash type
32
- # @return [Hash] all associated flash messages for this request
33
- def flash_message(type, text)
34
- flash[type.to_sym] ||= []
35
- flash[type.to_sym] << text
36
- end
37
-
38
- protected
39
-
40
- # Filters
41
-
42
- # Conditional check to see ensure a current user exists
43
- #
44
- # @return [Boolean]
45
- # (see #current_user?)
46
- def ensure_user
47
- current_user? || deny_access('You must be logged in to perform this action.')
48
- end
49
-
50
- # Conditional check to see ensure there is no current user
51
- #
52
- # @return [Boolean]
53
- # (see #current_user?)
54
- def ensure_no_user
55
- !current_user? || redirect_back_or_default
56
- end
57
-
58
- ## Utilities
59
-
60
- # Store the location URL in the session for later use.
61
- #
62
- # @return [Hash] the modified session object
63
- def store_location
64
- session[:return_to] = request.fullpath
65
- end
66
-
67
- # Stores the URL for the current requested action, then redirects to
68
- # the login page.
69
- #
70
- # @param [String] optional flash message to pass to the user
71
- # @note This method sets the redirect path, but does not return false.
72
- # Meaning you can perform actions after this method is invoked.
73
- def deny_access(message=nil)
74
- store_location
75
- flash_message :notice, message if message.present?
76
- redirect_to login_path
77
- end
78
-
79
- # Conditional redirect to handle an empty return_to path. If return_to
80
- # is empty, the request is redirected to the default path
81
- #
82
- # @param [String] path to use as the default redirect location
83
- # @return [Hash] the modified session hash
84
- def redirect_back_or_default(default=nil)
85
- default = self.default_route
86
- redirect_to(session[:return_to] || default)
87
- session[:return_to] = nil
88
- end
89
-
90
- # Fetch the User model associated with the current session.
91
- #
92
- # @return [User]
93
- # (see #current_user=)
94
10
  def current_user
95
- @current_user ||= if session[:socialite_user_id]
96
- Socialite.user_class.find(session[:socialite_user_id])
97
- elsif cookies[:remember_token]
98
- Socialite.user_class.find_by_remember_token(cookies[:remember_token])
99
- end
11
+ @current_user ||= User.find_by_id(session[:user_id])
100
12
  end
101
13
 
102
- # Assign the User model associated with the current session.
103
- #
104
- # @return [User]
105
- # (see #current_user)
106
- def current_user=(user)
107
- user.tap do |user|
108
- user.remember_me!
109
- session[:user_id] = user.id
110
- cookies[:remember_token] = user.remember_token
111
- end
112
- end
113
-
114
- # Accessor method for checking if a user is currently signed in
115
- #
116
- # @return [Boolean]
117
- # (see #current_user)
118
14
  def user_signed_in?
119
15
  !!current_user
120
16
  end
121
- alias_method :current_user?, :user_signed_in?
122
17
 
123
- # Destroy the current user session, effectively logging them out upon
124
- # the next request.
125
- #
126
- # @return [Hash] the modified session object
127
- def logout!
128
- session[:user_id] = session[:return_to] = nil
129
- @current_user = nil
130
- cookies.delete(:remember_token)
18
+ def current_user=(user)
19
+ @current_user = user
20
+ session[:user_id] = user.nil? ? user : user.id
131
21
  end
132
22
  end
133
23
  end