socialite 0.0.1.beta4 → 0.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +33 -34
- data/Rakefile +8 -21
- data/app/controllers/socialite/application_controller.rb +4 -0
- data/app/controllers/socialite/identities_controller.rb +2 -14
- data/app/controllers/socialite/session_controller.rb +20 -0
- data/app/controllers/socialite/users_controller.rb +0 -1
- data/app/views/layouts/socialite/application.html.haml +11 -0
- data/app/views/socialite/identities/new.html.haml +27 -0
- data/app/views/socialite/session/new.html.haml +31 -14
- data/app/views/socialite/user/edit.html.haml +1 -1
- data/config/routes.rb +7 -7
- data/lib/generators/socialite/install_generator.rb +7 -9
- data/lib/generators/socialite/migrations_generator.rb +34 -0
- data/lib/generators/socialite/templates/identity.rb.erb +25 -0
- data/lib/generators/socialite/templates/socialite.rb +20 -7
- data/lib/generators/socialite/templates/users.rb.erb +12 -0
- data/lib/socialite.rb +25 -27
- data/lib/socialite/controllers/helpers.rb +107 -111
- data/lib/socialite/engine.rb +19 -32
- data/lib/socialite/helpers/authentication.rb +1 -1
- data/lib/socialite/models/identity_concern.rb +91 -0
- data/lib/socialite/models/user_concern.rb +54 -0
- data/lib/socialite/version.rb +1 -1
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -3
- data/spec/dummy/app/assets/stylesheets/application.css +11 -5
- data/{app/assets/images/socialite → spec/dummy/app/mailers}/.gitkeep +0 -0
- data/{app/assets/javascripts/socialite → spec/dummy/app/models}/.gitkeep +0 -0
- data/spec/dummy/app/models/identity.rb +4 -0
- data/spec/dummy/app/models/user.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +1 -5
- data/spec/dummy/config/application.rb +19 -2
- data/spec/dummy/config/boot.rb +1 -11
- data/spec/dummy/config/database.yml +18 -2
- data/spec/dummy/config/environments/development.rb +8 -1
- data/spec/dummy/config/environments/production.rb +9 -2
- data/spec/dummy/config/environments/test.rb +4 -9
- data/spec/dummy/config/initializers/inflections.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +1 -1
- data/spec/dummy/config/initializers/session_store.rb +1 -1
- data/spec/dummy/config/initializers/socialite.rb +26 -4
- data/spec/dummy/config/initializers/wrap_parameters.rb +1 -1
- data/spec/dummy/config/routes.rb +2 -10
- data/{db/migrate/20110914215410_create_users.rb → spec/dummy/db/migrate/20130206224516_create_socialite_users.rb} +2 -4
- data/spec/dummy/db/migrate/20130206224517_create_socialite_identities.rb +25 -0
- data/spec/dummy/db/schema.rb +12 -20
- data/{lib/tasks → spec/dummy/lib/assets}/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/500.html +0 -1
- data/spec/factories/facebook.rb +5 -5
- data/spec/factories/identity.rb +3 -3
- data/spec/factories/user.rb +10 -12
- data/spec/generators/socialite/install_generator_spec.rb +43 -0
- data/spec/generators/socialite/migrations_generator_spec.rb +27 -0
- data/spec/models/facebook_spec.rb +24 -21
- data/spec/models/identity_spec.rb +2 -2
- data/spec/models/user_spec.rb +7 -7
- data/spec/socialite_spec.rb +53 -0
- data/spec/spec_helper.rb +23 -10
- data/spec/support/identity_shared_example.rb +24 -20
- metadata +202 -144
- data/.autotest +0 -7
- data/.gitignore +0 -9
- data/.rspec +0 -2
- data/.travis.yml +0 -10
- data/.yardopts +0 -8
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -208
- data/app/models/socialite/facebook_identity.rb +0 -5
- data/app/models/socialite/identity.rb +0 -5
- data/app/models/socialite/user.rb +0 -10
- data/config/initializers/simple_form.rb +0 -90
- data/config/locales/simple_form.en.yml +0 -23
- data/db/migrate/20110925224222_create_identities.rb +0 -26
- data/db/migrate/20110926005551_create_facebook_identities.rb +0 -12
- data/lib/socialite/api_wrappers/facebook.rb +0 -67
- data/lib/socialite/api_wrappers/twitter.rb +0 -19
- data/lib/socialite/models/identity.rb +0 -99
- data/lib/socialite/models/user.rb +0 -50
- data/lib/socialite/service_config.rb +0 -14
- data/lib/tasks/cucumber.rake +0 -65
- data/script/cucumber +0 -10
- data/script/rails +0 -6
- data/socialite.gemspec +0 -39
- data/spec/dummy/app/controllers/home_controller.rb +0 -11
- data/spec/dummy/app/views/home/index.html.haml +0 -12
- data/spec/dummy/app/views/home/show.html.haml +0 -6
@@ -7,131 +7,127 @@ module Socialite
|
|
7
7
|
helper_method :current_user, :user_signed_in?, :current_user?, :default_route
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@default_route = route
|
19
|
-
end
|
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
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
39
37
|
|
40
|
-
|
38
|
+
protected
|
41
39
|
|
42
|
-
|
40
|
+
# Filters
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
51
49
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
59
57
|
|
60
|
-
|
58
|
+
## Utilities
|
61
59
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
91
89
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
90
|
+
# Fetch the User model associated with the current session.
|
91
|
+
#
|
92
|
+
# @return [User]
|
93
|
+
# (see #current_user=)
|
94
|
+
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
|
100
|
+
end
|
103
101
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
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
|
114
111
|
end
|
112
|
+
end
|
115
113
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
cookies.delete(:remember_token)
|
134
|
-
end
|
114
|
+
# Accessor method for checking if a user is currently signed in
|
115
|
+
#
|
116
|
+
# @return [Boolean]
|
117
|
+
# (see #current_user)
|
118
|
+
def user_signed_in?
|
119
|
+
!!current_user
|
120
|
+
end
|
121
|
+
alias_method :current_user?, :user_signed_in?
|
122
|
+
|
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)
|
135
131
|
end
|
136
132
|
end
|
137
133
|
end
|
data/lib/socialite/engine.rb
CHANGED
@@ -1,45 +1,32 @@
|
|
1
1
|
require 'haml'
|
2
|
-
require 'omniauth
|
3
|
-
require 'omniauth/oauth'
|
2
|
+
require 'omniauth'
|
4
3
|
|
5
4
|
module Socialite
|
6
|
-
class Engine < Rails::Engine
|
5
|
+
class Engine < ::Rails::Engine
|
7
6
|
isolate_namespace Socialite
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
config.app_middleware.use OmniAuth::Strategies::Twitter,
|
17
|
-
Socialite.service_configs[:twitter].app_key,
|
18
|
-
Socialite.service_configs[:twitter].app_secret
|
19
|
-
end
|
20
|
-
end
|
8
|
+
config.generators do |g|
|
9
|
+
g.test_framework :rspec, :fixture => false
|
10
|
+
g.integration_tool :rspec
|
11
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
12
|
+
g.assets false
|
13
|
+
g.helper false
|
14
|
+
end
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Socialite.service_configs[:facebook].app_secret,
|
27
|
-
Socialite.service_configs[:facebook].options
|
28
|
-
else
|
29
|
-
config.app_middleware.use OmniAuth::Strategies::Facebook,
|
30
|
-
Socialite.service_configs[:facebook].app_key,
|
31
|
-
Socialite.service_configs[:facebook].app_secret,
|
32
|
-
Socialite.service_configs[:facebook].options
|
16
|
+
initializer 'socialite.load_middleware', :after => :load_config_initializers do
|
17
|
+
Socialite.providers.each do |provider_info|
|
18
|
+
OmniAuth.configure do |config|
|
19
|
+
config.provider(*provider_info)
|
33
20
|
end
|
34
21
|
end
|
35
22
|
end
|
36
23
|
|
37
|
-
ActiveSupport.on_load(:action_controller) do
|
38
|
-
include Socialite::Controllers::Helpers
|
39
|
-
end
|
24
|
+
# ActiveSupport.on_load(:action_controller) do
|
25
|
+
# include Socialite::Controllers::Helpers
|
26
|
+
# end
|
40
27
|
|
41
|
-
ActiveSupport.on_load(:action_view) do
|
42
|
-
include Socialite::Helpers::Authentication
|
43
|
-
end
|
28
|
+
# ActiveSupport.on_load(:action_view) do
|
29
|
+
# include Socialite::Helpers::Authentication
|
30
|
+
# end
|
44
31
|
end
|
45
32
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module Socialite
|
2
|
+
module Models
|
3
|
+
module IdentityConcern
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
belongs_to :user,
|
8
|
+
:class_name => Socialite.user_class_name,
|
9
|
+
:foreign_key => "#{Socialite.user_class.table_name.singularize}_id"
|
10
|
+
serialize :auth_hash
|
11
|
+
|
12
|
+
# Ensure that before validation happens that the provider
|
13
|
+
# database column matches what is inside of the auth_hash
|
14
|
+
# dataset.
|
15
|
+
before_validation do |identity|
|
16
|
+
if identity.auth_hash.present?
|
17
|
+
identity.provider = identity.auth_hash.delete('provider') if identity.provider.blank?
|
18
|
+
identity.uid = identity.auth_hash.delete('uid') if identity.uid.blank?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Ensure each user has only a single identity per provider type
|
23
|
+
validates :provider,
|
24
|
+
:uniqueness => {:scope => "#{Socialite.user_class.table_name.singularize}_id", :case_sensitive => false},
|
25
|
+
:presence => true
|
26
|
+
|
27
|
+
# Ensure an identity is never reused by another account
|
28
|
+
validates :uid,
|
29
|
+
:uniqueness => {:scope => :provider},
|
30
|
+
:presence => true
|
31
|
+
|
32
|
+
# Ensure an associated user exists before creating the identity
|
33
|
+
# validates_associated :user
|
34
|
+
end
|
35
|
+
|
36
|
+
module ClassMethods
|
37
|
+
# Finder method that finds the matching Provider and Unique ID or
|
38
|
+
# initializes a new, unsaved, object.
|
39
|
+
#
|
40
|
+
# @params [Hash] the OAuth authentication hash
|
41
|
+
# @returns [Identity]
|
42
|
+
def find_or_initialize_by_omniauth(auth)
|
43
|
+
identity = where(:provider => auth['provider'], :uid => auth['uid']).first || new
|
44
|
+
identity.auth_hash = auth
|
45
|
+
identity
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Convenience method for accessing the OAuth access token
|
50
|
+
#
|
51
|
+
# @returns [String] OAuth access token
|
52
|
+
# (see #credentials)
|
53
|
+
def access_token
|
54
|
+
credentials['token']
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convenience method for accessing the OAuth access token secret
|
58
|
+
#
|
59
|
+
# @returns [String] OAuth access token secret
|
60
|
+
# (see #credentials)
|
61
|
+
def access_token_secret
|
62
|
+
credentials['secret']
|
63
|
+
end
|
64
|
+
|
65
|
+
# Convenience method for accessing the OAuth credentials sub-hash
|
66
|
+
#
|
67
|
+
# @returns [Hash] OAuth credentials sub-hash
|
68
|
+
# (see #access_token)
|
69
|
+
# (see #access_token_secret)
|
70
|
+
def credentials
|
71
|
+
auth_hash['credentials']
|
72
|
+
end
|
73
|
+
|
74
|
+
# Convenience method for accessing the nickname, which is typically
|
75
|
+
# set to the login name used for that provider.
|
76
|
+
#
|
77
|
+
# @returns [String] user nickname for the provider identity
|
78
|
+
def nickname
|
79
|
+
info['nickname']
|
80
|
+
end
|
81
|
+
|
82
|
+
# Convenience method for accessing the user information from the
|
83
|
+
# OAuth provider.
|
84
|
+
#
|
85
|
+
# @returns [Hash] the user information sub-hash
|
86
|
+
def info
|
87
|
+
auth_hash['info']
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Socialite
|
2
|
+
module Models
|
3
|
+
module UserConcern
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :identities,
|
8
|
+
:dependent => :destroy,
|
9
|
+
:class_name => Socialite.identity_class_name,
|
10
|
+
:foreign_key => "#{Socialite.user_class.table_name.singularize}_id"
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(id, *args, &block)
|
14
|
+
if id =~ /(\w+)_identity$/ && @identity = self.identities.where(:provider => $1).first
|
15
|
+
@identity
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the first linked facebook identity
|
22
|
+
#
|
23
|
+
# @return [Identity] the first facebook identity
|
24
|
+
def facebook
|
25
|
+
self.facebook_identity
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the first linked twitter account
|
29
|
+
#
|
30
|
+
# @return [Identity] the first twitter identity
|
31
|
+
def twitter
|
32
|
+
self.twitter_identity
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set the user's remember token
|
36
|
+
#
|
37
|
+
# @return [User] the current user
|
38
|
+
# def remember_me!
|
39
|
+
# self.remember_token = Socialite.generate_token
|
40
|
+
# save(:validate => false)
|
41
|
+
# end
|
42
|
+
|
43
|
+
# Clear the user's remember token
|
44
|
+
#
|
45
|
+
# @return [User] the current user
|
46
|
+
# def forget_me!
|
47
|
+
# if persisted?
|
48
|
+
# self.remember_token = nil
|
49
|
+
# save(:validate => false)
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|