socialite 0.0.1.beta4 → 0.1.0.pre
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.
- 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
|