sorcery 0.3.0 → 0.4.0
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/Gemfile +3 -2
- data/Gemfile.lock +13 -11
- data/README.rdoc +99 -33
- data/Rakefile +4 -4
- data/VERSION +1 -1
- data/lib/generators/sorcery_migration/templates/core.rb +2 -2
- data/lib/generators/sorcery_migration/templates/{oauth.rb → external.rb} +1 -1
- data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +35 -0
- data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +26 -0
- data/lib/sorcery/controller/submodules/{oauth → external}/providers/facebook.rb +24 -6
- data/lib/sorcery/controller/submodules/{oauth → external}/providers/twitter.rb +31 -6
- data/lib/sorcery/controller/submodules/{oauth.rb → external.rb} +18 -30
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +1 -1
- data/lib/sorcery/controller.rb +21 -21
- data/lib/sorcery/crypto_providers/bcrypt.rb +1 -1
- data/lib/sorcery/crypto_providers/common.rb +35 -0
- data/lib/sorcery/crypto_providers/md5.rb +3 -23
- data/lib/sorcery/crypto_providers/sha1.rb +4 -16
- data/lib/sorcery/crypto_providers/sha256.rb +3 -23
- data/lib/sorcery/crypto_providers/sha512.rb +3 -23
- data/lib/sorcery/engine.rb +4 -0
- data/lib/sorcery/initializers/initializer.rb +86 -0
- data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
- data/lib/sorcery/model.rb +13 -8
- data/lib/sorcery/railties/tasks.rake +10 -0
- data/lib/sorcery/sinatra.rb +0 -9
- data/lib/sorcery/test_helpers/rails.rb +6 -9
- data/lib/sorcery/test_helpers/sinatra.rb +6 -9
- data/lib/sorcery/test_helpers.rb +12 -0
- data/lib/sorcery.rb +10 -7
- data/sorcery.gemspec +146 -153
- data/spec/Gemfile +2 -2
- data/spec/Gemfile.lock +10 -10
- data/spec/Rakefile +1 -0
- data/spec/rails3/.rspec +1 -1
- data/spec/rails3/{app_root/Gemfile → Gemfile} +4 -4
- data/spec/rails3/{app_root/Gemfile.lock → Gemfile.lock} +20 -20
- data/spec/rails3/{app_root/Rakefile → Rakefile} +1 -0
- data/spec/rails3/{app_root/app → app}/controllers/application_controller.rb +11 -11
- data/spec/rails3/config/database.yml +27 -0
- data/spec/rails3/{app_root/spec → spec}/controller_brute_force_protection_spec.rb +3 -2
- data/spec/rails3/{app_root/spec → spec}/controller_oauth2_spec.rb +23 -22
- data/spec/rails3/{app_root/spec → spec}/controller_oauth_spec.rb +17 -17
- data/spec/rails3/{app_root/spec → spec}/controller_session_timeout_spec.rb +8 -4
- data/spec/rails3/spec/spec.opts +2 -0
- data/spec/rails3/spec/spec_helper.rb +70 -0
- data/spec/rails3/{app_root/spec → spec}/user_activation_spec.rb +5 -1
- data/spec/{sinatra → rails3}/spec/user_oauth_spec.rb +7 -7
- data/spec/rails3/{app_root/spec → spec}/user_reset_password_spec.rb +7 -3
- data/spec/rails3/{app_root/spec → spec}/user_spec.rb +5 -11
- data/spec/sinatra/Gemfile +3 -3
- data/spec/sinatra/Gemfile.lock +17 -17
- data/spec/sinatra/Rakefile +1 -0
- data/spec/sinatra/myapp.rb +11 -11
- data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +3 -2
- data/spec/sinatra/spec/controller_oauth2_spec.rb +23 -22
- data/spec/sinatra/spec/controller_oauth_spec.rb +17 -17
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +8 -4
- data/spec/sinatra/spec/spec.opts +2 -4
- data/spec/sinatra/spec/spec_helper.rb +2 -1
- data/spec/sorcery_crypto_providers_spec.rb +5 -4
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +3 -4
- metadata +157 -156
- data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -33
- data/lib/sorcery/controller/submodules/oauth/oauth2.rb +0 -24
- data/spec/rails3/app_root/.rspec +0 -1
- data/spec/rails3/app_root/config/database.yml +0 -27
- data/spec/rails3/app_root/spec/spec_helper.rb +0 -62
- data/spec/rails3/app_root/spec/user_oauth_spec.rb +0 -39
- data/spec/sinatra/spec/user_activation_spec.rb +0 -188
- data/spec/sinatra/spec/user_activity_logging_spec.rb +0 -36
- data/spec/sinatra/spec/user_brute_force_protection_spec.rb +0 -76
- data/spec/sinatra/spec/user_remember_me_spec.rb +0 -66
- data/spec/sinatra/spec/user_reset_password_spec.rb +0 -178
- data/spec/sinatra/spec/user_spec.rb +0 -317
- /data/spec/rails3/{app_root/.gitignore → .gitignore} +0 -0
- /data/spec/rails3/{app_root/README → README} +0 -0
- /data/spec/rails3/{app_root/Rakefile.unused → Rakefile.unused} +0 -0
- /data/spec/rails3/{app_root/app → app}/helpers/application_helper.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/mailers/sorcery_mailer.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/models/authentication.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/models/user.rb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/layouts/application.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.text.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.text.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.html.erb +0 -0
- /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.text.erb +0 -0
- /data/spec/rails3/{app_root/config → config}/application.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/boot.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environment.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/development.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/in_memory.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/production.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/environments/test.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/backtrace_silencers.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/inflections.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/mime_types.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/secret_token.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/initializers/session_store.rb +0 -0
- /data/spec/rails3/{app_root/config → config}/locales/en.yml +0 -0
- /data/spec/rails3/{app_root/config → config}/routes.rb +0 -0
- /data/spec/rails3/{app_root/config.ru → config.ru} +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/activation/20101224223622_add_activation_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/core/20101224223620_create_users.rb +0 -0
- /data/spec/rails3/{app_root/db/migrate/oauth → db/migrate/external}/20101224223628_create_authentications.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/schema.rb +0 -0
- /data/spec/rails3/{app_root/db → db}/seeds.rb +0 -0
- /data/spec/rails3/{app_root/lib → lib}/tasks/.gitkeep +0 -0
- /data/spec/rails3/{app_root/public → public}/404.html +0 -0
- /data/spec/rails3/{app_root/public → public}/422.html +0 -0
- /data/spec/rails3/{app_root/public → public}/500.html +0 -0
- /data/spec/rails3/{app_root/public → public}/favicon.ico +0 -0
- /data/spec/rails3/{app_root/public → public}/images/rails.png +0 -0
- /data/spec/rails3/{app_root/public → public}/index.html +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/application.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/controls.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/dragdrop.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/effects.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/prototype.js +0 -0
- /data/spec/rails3/{app_root/public → public}/javascripts/rails.js +0 -0
- /data/spec/rails3/{app_root/public → public}/robots.txt +0 -0
- /data/spec/rails3/{app_root/public → public}/stylesheets/.gitkeep +0 -0
- /data/spec/rails3/{app_root/script → script}/rails +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_activity_logging_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_http_basic_auth_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_remember_me_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/controller_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/spec_helper.orig.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_activity_logging_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_brute_force_protection_spec.rb +0 -0
- /data/spec/rails3/{app_root/spec → spec}/user_remember_me_spec.rb +0 -0
- /data/spec/rails3/{app_root/vendor → vendor}/plugins/.gitkeep +0 -0
- /data/spec/sinatra/db/migrate/{oauth → external}/20101224223628_create_authentications.rb +0 -0
data/Gemfile
CHANGED
|
@@ -9,12 +9,13 @@ gem 'oauth2', ">= 0.1.1"
|
|
|
9
9
|
# Add dependencies to develop your gem here.
|
|
10
10
|
# Include everything needed to run rake, tests, features, etc.
|
|
11
11
|
group :development do
|
|
12
|
-
gem "rspec", "~> 2.
|
|
13
|
-
gem 'rspec-rails'
|
|
12
|
+
gem "rspec", "~> 2.5.0"
|
|
13
|
+
gem 'rspec-rails', "~> 2.5.0"
|
|
14
14
|
gem 'ruby-debug19'
|
|
15
15
|
gem 'sqlite3-ruby', :require => 'sqlite3'
|
|
16
16
|
gem "yard", "~> 0.6.0"
|
|
17
17
|
gem "bundler", "~> 1.0.0"
|
|
18
18
|
gem "jeweler", "~> 1.5.2"
|
|
19
19
|
gem 'simplecov', '>= 0.3.8', :require => false # Will install simplecov-html as a dependency
|
|
20
|
+
gem 'timecop'
|
|
20
21
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -81,19 +81,19 @@ GEM
|
|
|
81
81
|
rake (>= 0.8.7)
|
|
82
82
|
thor (~> 0.14.4)
|
|
83
83
|
rake (0.8.7)
|
|
84
|
-
rspec (2.
|
|
85
|
-
rspec-core (~> 2.
|
|
86
|
-
rspec-expectations (~> 2.
|
|
87
|
-
rspec-mocks (~> 2.
|
|
88
|
-
rspec-core (2.
|
|
89
|
-
rspec-expectations (2.
|
|
84
|
+
rspec (2.5.0)
|
|
85
|
+
rspec-core (~> 2.5.0)
|
|
86
|
+
rspec-expectations (~> 2.5.0)
|
|
87
|
+
rspec-mocks (~> 2.5.0)
|
|
88
|
+
rspec-core (2.5.1)
|
|
89
|
+
rspec-expectations (2.5.0)
|
|
90
90
|
diff-lcs (~> 1.1.2)
|
|
91
|
-
rspec-mocks (2.
|
|
92
|
-
rspec-rails (2.
|
|
91
|
+
rspec-mocks (2.5.0)
|
|
92
|
+
rspec-rails (2.5.0)
|
|
93
93
|
actionpack (~> 3.0)
|
|
94
94
|
activesupport (~> 3.0)
|
|
95
95
|
railties (~> 3.0)
|
|
96
|
-
rspec (~> 2.
|
|
96
|
+
rspec (~> 2.5.0)
|
|
97
97
|
ruby-debug-base19 (0.11.24)
|
|
98
98
|
columnize (>= 0.3.1)
|
|
99
99
|
linecache19 (>= 0.5.11)
|
|
@@ -109,6 +109,7 @@ GEM
|
|
|
109
109
|
simplecov-html (0.3.9)
|
|
110
110
|
sqlite3-ruby (1.3.2)
|
|
111
111
|
thor (0.14.6)
|
|
112
|
+
timecop (0.3.5)
|
|
112
113
|
treetop (1.4.9)
|
|
113
114
|
polyglot (>= 0.3.1)
|
|
114
115
|
tzinfo (0.3.23)
|
|
@@ -124,9 +125,10 @@ DEPENDENCIES
|
|
|
124
125
|
oauth (>= 0.4.4)
|
|
125
126
|
oauth2 (>= 0.1.1)
|
|
126
127
|
rails (>= 3.0.0)
|
|
127
|
-
rspec (~> 2.
|
|
128
|
-
rspec-rails
|
|
128
|
+
rspec (~> 2.5.0)
|
|
129
|
+
rspec-rails (~> 2.5.0)
|
|
129
130
|
ruby-debug19
|
|
130
131
|
simplecov (>= 0.3.8)
|
|
131
132
|
sqlite3-ruby
|
|
133
|
+
timecop
|
|
132
134
|
yard (~> 0.6.0)
|
data/README.rdoc
CHANGED
|
@@ -6,7 +6,7 @@ Crypto code taken almost unchanged from Authlogic.
|
|
|
6
6
|
OAuth code inspired by OmniAuth and Ryan Bates's railscasts about it.
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
==
|
|
9
|
+
== Philosophy
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
Sorcery is a stripped-down, bare-bones authentication library, with which you can write your own authentication flow.
|
|
@@ -28,11 +28,53 @@ Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
|
|
|
28
28
|
|
|
29
29
|
Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
|
|
30
30
|
|
|
31
|
-
Documentation: http://rubydoc.info/gems/sorcery/0.
|
|
31
|
+
Documentation: http://rubydoc.info/gems/sorcery/0.4.0/frames
|
|
32
32
|
|
|
33
33
|
Check out the tutorials in the github wiki!
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
== API Summary
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
Below is a summary of the library methods. Most method names are self explaining and the rest are commented:
|
|
40
|
+
|
|
41
|
+
# core
|
|
42
|
+
require_login # this is a before filter
|
|
43
|
+
login(username,password,remember_me = false)
|
|
44
|
+
logout
|
|
45
|
+
logged_in?
|
|
46
|
+
current_user
|
|
47
|
+
redirect_back_or_to # used when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted.
|
|
48
|
+
@user.external? # external users, such as facebook/twitter etc.
|
|
49
|
+
User.authenticates_with_sorcery!
|
|
50
|
+
|
|
51
|
+
# activity logging
|
|
52
|
+
current_users
|
|
53
|
+
|
|
54
|
+
# http basic auth
|
|
55
|
+
require_login_from_http_basic # this is a before filter
|
|
56
|
+
|
|
57
|
+
# external
|
|
58
|
+
login_at(provider) # sends the user to an external service (twitter etc.) to authenticate.
|
|
59
|
+
login_from(provider) # tries to login from the external provider's callback.
|
|
60
|
+
create_from(provider) # create the user in the local app db.
|
|
61
|
+
|
|
62
|
+
# remember me
|
|
63
|
+
remember_me!
|
|
64
|
+
forget_me!
|
|
65
|
+
|
|
66
|
+
# reset password
|
|
67
|
+
User.load_from_reset_password_token(token)
|
|
68
|
+
@user.deliver_reset_password_instructions!
|
|
69
|
+
@user.reset_password!(params)
|
|
70
|
+
|
|
71
|
+
# user activation
|
|
72
|
+
User.load_from_activation_token(token)
|
|
73
|
+
@user.activate!
|
|
74
|
+
|
|
75
|
+
Please see the tutorials in the github wiki for detailed usage information.
|
|
76
|
+
|
|
77
|
+
|
|
36
78
|
== Installation:
|
|
37
79
|
|
|
38
80
|
|
|
@@ -49,29 +91,15 @@ Otherwise simply
|
|
|
49
91
|
gem install sorcery
|
|
50
92
|
|
|
51
93
|
|
|
52
|
-
== Configuration:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
1. config/application.rb
|
|
94
|
+
== Rails 3 Configuration:
|
|
56
95
|
|
|
57
|
-
config.sorcery.submodules = [:user_activation, :remember_me] # add the submodules you want to use
|
|
58
|
-
# You can also configure here any controller and any controller-submodule option here. For example:
|
|
59
|
-
config.sorcery.session_timeout = 10.minutes
|
|
60
96
|
|
|
61
|
-
|
|
97
|
+
For Rails 3 create an initializer file using:
|
|
62
98
|
|
|
63
|
-
|
|
64
|
-
config.user_activation_mailer = MyMailer
|
|
65
|
-
config.username_attribute_name = :email
|
|
66
|
-
end
|
|
99
|
+
rake sorcery:bootstrap
|
|
67
100
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
activate_sorcery! do |config|
|
|
71
|
-
config.session_timeout = 10.minutes
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
The configuration options vary with the submodules you've chosen to use, so check the documentation or the wiki tutorials regarding the specific submodule.
|
|
101
|
+
This will create the file as config/initializers/sorcery.rb .
|
|
102
|
+
Inside it the comments will tell you everything you need to know.
|
|
75
103
|
|
|
76
104
|
For your convenience, Sorcery includes a migrations generator for Rails, which can be used like so:
|
|
77
105
|
|
|
@@ -88,10 +116,30 @@ To generate migrations for both the core AND 'remember_me' submodule:
|
|
|
88
116
|
These migrations use the default fields. You can choose to use these migrations or make your own tables and fields. Sorcery tries not to impose a database structure and naming scheme on your application.
|
|
89
117
|
|
|
90
118
|
|
|
91
|
-
==
|
|
119
|
+
== Sinatra Configuration:
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
For Sinatra you'll need to create the initializer manually. You can do it in the main app file or in a separate file you require (see example in example app). The code looks as follows:
|
|
92
123
|
|
|
124
|
+
Sorcery::Controller::Config.submodules = [] # specify here the submodules you want to include
|
|
125
|
+
|
|
126
|
+
Sorcery::Controller::Config.configure do |config|
|
|
127
|
+
config.session_timeout = 10.minutes
|
|
128
|
+
...
|
|
129
|
+
...
|
|
130
|
+
|
|
131
|
+
config.user_config do |user|
|
|
132
|
+
user.username_attribute_name = :email
|
|
133
|
+
...
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
end
|
|
93
138
|
|
|
94
|
-
|
|
139
|
+
Finally, to make all the code above take effect, we'll need to re-include the sorcery controller module:
|
|
140
|
+
|
|
141
|
+
include Sorcery::Controller::Adapters::Sinatra
|
|
142
|
+
include Sorcery::Controller
|
|
95
143
|
|
|
96
144
|
|
|
97
145
|
== Full Features List by module:
|
|
@@ -137,7 +185,7 @@ Activity Logging (see lib/sorcery/model/submodules/activity_logging.rb):
|
|
|
137
185
|
* an easy method of collecting the list of currently logged in users.
|
|
138
186
|
* configurable timeout by which to decide whether to include a user in the list of logged in users.
|
|
139
187
|
|
|
140
|
-
|
|
188
|
+
External (see lib/sorcery/controller/submodules/external.rb):
|
|
141
189
|
* OAuth1 and OAuth2 support (currently twitter & facebook)
|
|
142
190
|
* configurable db field names and authentications table.
|
|
143
191
|
|
|
@@ -146,33 +194,51 @@ Oauth (see lib/sorcery/controller/submodules/oauth.rb):
|
|
|
146
194
|
|
|
147
195
|
|
|
148
196
|
I've got many plans which include (by priority):
|
|
197
|
+
* Forgot username, maybe as part of the reset_password module
|
|
149
198
|
* Scoping logins (to a subdomain or another arbitrary field)
|
|
150
|
-
* Simple auth (no user)
|
|
151
|
-
* Switching authentication mode at runtime (Maintenance mode)
|
|
152
199
|
* Mongoid support
|
|
153
|
-
* Configurable Auto login on registration/activation
|
|
154
200
|
* Other reset password strategies (security questions?)
|
|
155
201
|
* Other brute force protection strategies (captcha)
|
|
156
202
|
* Have an idea? Let me know, and it might get into the gem!
|
|
157
203
|
|
|
204
|
+
Other stuff:
|
|
205
|
+
* Improve specs speed
|
|
206
|
+
* Provide an easy way to run specs after install
|
|
207
|
+
* Improve documentation
|
|
208
|
+
* Tty to reduce the number of library methods, and find better names to some
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
== Backward compatibility
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
While the lib is young and evolving fast I'm breaking backward compatibility quite often.
|
|
215
|
+
I'm constantly finding better ways to do things and throwing away old ways.
|
|
216
|
+
To let you know when things are changing in a non-compatible way, I'm bumping the minor version of the gem.
|
|
217
|
+
The patch version changes are backward compatible.
|
|
218
|
+
|
|
219
|
+
In short, an app that works with x.3.1 should be able to upgrade to x.3.2 with no code changes.
|
|
220
|
+
The same cannot be said about upgrading to x.4.0 and above, however.
|
|
221
|
+
|
|
158
222
|
|
|
159
223
|
== Contributing to sorcery
|
|
160
224
|
|
|
225
|
+
|
|
161
226
|
Your feedback is very welcome and will make this gem much much better for you, me and everyone else.
|
|
162
227
|
Besides feedback on code, features, suggestions and bug reports, you may want to actually make an impact on the code.
|
|
163
228
|
For this:
|
|
164
229
|
|
|
165
|
-
* Fork
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* Commit
|
|
169
|
-
* Send me a pull request
|
|
230
|
+
* Fork it.
|
|
231
|
+
* Fix it.
|
|
232
|
+
* Test it.
|
|
233
|
+
* Commit it.
|
|
234
|
+
* Send me a pull request so I'll... Pull it.
|
|
170
235
|
|
|
171
|
-
If you feel
|
|
236
|
+
If you feel sorcery has made your life easier, and you would like to express your thanks via a donation, my paypal email is in the contact details.
|
|
172
237
|
|
|
173
238
|
|
|
174
239
|
== Contact
|
|
175
240
|
|
|
241
|
+
|
|
176
242
|
Feel free to ask questions using these contact details:
|
|
177
243
|
|
|
178
244
|
email: nbenari@gmail.com ( also for paypal )
|
data/Rakefile
CHANGED
|
@@ -41,11 +41,11 @@ end
|
|
|
41
41
|
require 'yard'
|
|
42
42
|
YARD::Rake::YardocTask.new
|
|
43
43
|
|
|
44
|
-
desc 'Default: Run all specs.'
|
|
45
|
-
task :default => :
|
|
44
|
+
desc 'Default: Run all sorcery specs.'
|
|
45
|
+
task :default => :all_sorcery_specs
|
|
46
46
|
|
|
47
|
-
desc "Run all specs"
|
|
48
|
-
task :
|
|
47
|
+
desc "Run all sorcery specs"
|
|
48
|
+
task :all_sorcery_specs do
|
|
49
49
|
Dir['spec/**/Rakefile'].each do |rakefile|
|
|
50
50
|
directory_name = File.dirname(rakefile)
|
|
51
51
|
sh <<-CMD
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
class SorceryCore < ActiveRecord::Migration
|
|
2
2
|
def self.up
|
|
3
3
|
create_table :users do |t|
|
|
4
|
-
t.string :username, :null => false
|
|
5
|
-
t.string :email, :default => nil
|
|
4
|
+
t.string :username, :null => false # if you use another filed as a username, for example email, you can safely remove this field.
|
|
5
|
+
t.string :email, :default => nil # if you use this field as a username, you might want to make it :null => false.
|
|
6
6
|
t.string :crypted_password, :default => nil
|
|
7
7
|
t.string :salt, :default => nil
|
|
8
8
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'oauth'
|
|
2
|
+
module Sorcery
|
|
3
|
+
module Controller
|
|
4
|
+
module Submodules
|
|
5
|
+
module External
|
|
6
|
+
module Protocols
|
|
7
|
+
module Oauth1
|
|
8
|
+
def oauth_version
|
|
9
|
+
"1.0"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def get_request_token(token=nil,secret=nil)
|
|
13
|
+
return ::OAuth::RequestToken.new(get_consumer,token,secret) if token && secret
|
|
14
|
+
get_consumer.get_request_token(:oauth_callback => @callback_url)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def authorize_url(args)
|
|
18
|
+
get_request_token(args[:request_token],args[:request_token_secret]).authorize_url(:oauth_callback => @callback_url)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def get_access_token(args)
|
|
22
|
+
get_request_token(args[:request_token],args[:request_token_secret]).get_access_token(:oauth_verifier => args[:oauth_verifier])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
protected
|
|
26
|
+
|
|
27
|
+
def get_consumer
|
|
28
|
+
::OAuth::Consumer.new(@key, @secret, :site => @site)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'oauth2'
|
|
2
|
+
module Sorcery
|
|
3
|
+
module Controller
|
|
4
|
+
module Submodules
|
|
5
|
+
module External
|
|
6
|
+
module Protocols
|
|
7
|
+
module Oauth2
|
|
8
|
+
def oauth_version
|
|
9
|
+
"2.0"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def authorize_url(*args)
|
|
13
|
+
client = ::OAuth2::Client.new(@key, @secret, :site => @site)
|
|
14
|
+
client.web_server.authorize_url(:redirect_uri => @callback_url, :scope => @scope)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_access_token(args)
|
|
18
|
+
client = ::OAuth2::Client.new(@key, @secret, :site => @site)
|
|
19
|
+
client.web_server.get_access_token(args[:code], :redirect_uri => @callback_url)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
module
|
|
4
|
+
module External
|
|
5
5
|
module Providers
|
|
6
6
|
# This module adds support for OAuth with facebook.com.
|
|
7
7
|
# When included in the 'config.providers' option, it adds a new option, 'config.facebook'.
|
|
@@ -16,7 +16,7 @@ module Sorcery
|
|
|
16
16
|
base.module_eval do
|
|
17
17
|
class << self
|
|
18
18
|
attr_reader :facebook # access to facebook_client.
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
def merge_facebook_defaults!
|
|
21
21
|
@defaults.merge!(:@facebook => FacebookClient)
|
|
22
22
|
end
|
|
@@ -36,7 +36,7 @@ module Sorcery
|
|
|
36
36
|
:scope,
|
|
37
37
|
:user_info_mapping
|
|
38
38
|
|
|
39
|
-
include Oauth2
|
|
39
|
+
include Protocols::Oauth2
|
|
40
40
|
|
|
41
41
|
def init
|
|
42
42
|
@site = "https://graph.facebook.com"
|
|
@@ -45,13 +45,31 @@ module Sorcery
|
|
|
45
45
|
@user_info_mapping = {}
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
def get_user_hash
|
|
48
|
+
def get_user_hash
|
|
49
49
|
user_hash = {}
|
|
50
|
-
response = access_token.get(@user_info_path)
|
|
50
|
+
response = @access_token.get(@user_info_path)
|
|
51
51
|
user_hash[:user_info] = JSON.parse(response)
|
|
52
|
-
user_hash[:uid] = user_hash[:user_info]['id']
|
|
52
|
+
user_hash[:uid] = user_hash[:user_info]['id']
|
|
53
53
|
user_hash
|
|
54
54
|
end
|
|
55
|
+
|
|
56
|
+
def has_callback?
|
|
57
|
+
true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# calculates and returns the url to which the user should be redirected,
|
|
61
|
+
# to get authenticated at the external provider's site.
|
|
62
|
+
def login_url(params,session)
|
|
63
|
+
self.authorize_url
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# tries to login the user from access token
|
|
67
|
+
def process_callback(params,session)
|
|
68
|
+
args = {}
|
|
69
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
70
|
+
@access_token = self.get_access_token(args)
|
|
71
|
+
end
|
|
72
|
+
|
|
55
73
|
end
|
|
56
74
|
init
|
|
57
75
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
module
|
|
4
|
+
module External
|
|
5
5
|
module Providers
|
|
6
6
|
# This module adds support for OAuth with Twitter.com.
|
|
7
7
|
# When included in the 'config.providers' option, it adds a new option, 'config.twitter'.
|
|
@@ -15,7 +15,10 @@ module Sorcery
|
|
|
15
15
|
def self.included(base)
|
|
16
16
|
base.module_eval do
|
|
17
17
|
class << self
|
|
18
|
-
attr_reader :twitter
|
|
18
|
+
attr_reader :twitter
|
|
19
|
+
# def twitter(&blk) # allows block syntax.
|
|
20
|
+
# yield @twitter
|
|
21
|
+
# end
|
|
19
22
|
|
|
20
23
|
def merge_twitter_defaults!
|
|
21
24
|
@defaults.merge!(:@twitter => TwitterClient)
|
|
@@ -25,7 +28,7 @@ module Sorcery
|
|
|
25
28
|
update!
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
|
-
|
|
31
|
+
|
|
29
32
|
module TwitterClient
|
|
30
33
|
class << self
|
|
31
34
|
attr_accessor :key,
|
|
@@ -35,7 +38,7 @@ module Sorcery
|
|
|
35
38
|
:user_info_path,
|
|
36
39
|
:user_info_mapping
|
|
37
40
|
|
|
38
|
-
include Oauth1
|
|
41
|
+
include Protocols::Oauth1
|
|
39
42
|
|
|
40
43
|
def init
|
|
41
44
|
@site = "https://api.twitter.com"
|
|
@@ -43,13 +46,35 @@ module Sorcery
|
|
|
43
46
|
@user_info_mapping = {}
|
|
44
47
|
end
|
|
45
48
|
|
|
46
|
-
def get_user_hash
|
|
49
|
+
def get_user_hash
|
|
47
50
|
user_hash = {}
|
|
48
|
-
response = access_token.get(@user_info_path)
|
|
51
|
+
response = @access_token.get(@user_info_path)
|
|
49
52
|
user_hash[:user_info] = JSON.parse(response.body)
|
|
50
53
|
user_hash[:uid] = user_hash[:user_info]['id']
|
|
51
54
|
user_hash
|
|
52
55
|
end
|
|
56
|
+
|
|
57
|
+
def has_callback?
|
|
58
|
+
true
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# calculates and returns the url to which the user should be redirected,
|
|
62
|
+
# to get authenticated at the external provider's site.
|
|
63
|
+
def login_url(params,session)
|
|
64
|
+
req_token = self.get_request_token
|
|
65
|
+
session[:request_token] = req_token.token
|
|
66
|
+
session[:request_token_secret] = req_token.secret
|
|
67
|
+
self.authorize_url({:request_token => req_token.token, :request_token_secret => req_token.secret})
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# tries to login the user from access token
|
|
71
|
+
def process_callback(params,session)
|
|
72
|
+
args = {}
|
|
73
|
+
args.merge!({:oauth_verifier => params[:oauth_verifier], :request_token => session[:request_token], :request_token_secret => session[:request_token_secret]})
|
|
74
|
+
args.merge!({:code => params[:code]}) if params[:code]
|
|
75
|
+
@access_token = self.get_access_token(args)
|
|
76
|
+
end
|
|
77
|
+
|
|
53
78
|
end
|
|
54
79
|
init
|
|
55
80
|
end
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
-
# This submodule helps you login users from
|
|
4
|
+
# This submodule helps you login users from external auth providers such as Twitter.
|
|
5
5
|
# This is the controller part which handles the http requests and tokens passed between the app and the provider.
|
|
6
|
-
|
|
7
|
-
module Oauth
|
|
6
|
+
module External
|
|
8
7
|
def self.included(base)
|
|
9
8
|
base.send(:include, InstanceMethods)
|
|
10
9
|
Config.module_eval do
|
|
11
10
|
class << self
|
|
12
|
-
attr_reader :
|
|
11
|
+
attr_reader :external_providers # external providers like twitter.
|
|
13
12
|
|
|
14
|
-
def
|
|
15
|
-
@defaults.merge!(:@
|
|
13
|
+
def merge_external_defaults!
|
|
14
|
+
@defaults.merge!(:@external_providers => [])
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
def
|
|
17
|
+
def external_providers=(providers)
|
|
19
18
|
providers.each do |provider|
|
|
20
19
|
include Providers.const_get(provider.to_s.split("_").map {|p| p.capitalize}.join(""))
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
|
-
|
|
23
|
+
merge_external_defaults!
|
|
25
24
|
end
|
|
26
25
|
end
|
|
27
26
|
|
|
@@ -30,26 +29,20 @@ module Sorcery
|
|
|
30
29
|
|
|
31
30
|
# sends user to authenticate at the provider's website.
|
|
32
31
|
# after authentication the user is redirected to the callback defined in the provider config
|
|
33
|
-
def
|
|
32
|
+
def login_at(provider, args = {})
|
|
34
33
|
@provider = Config.send(provider)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
session[:request_token_secret] = req_token.secret
|
|
40
|
-
args.merge!({:request_token => req_token.token, :request_token_secret => req_token.secret})
|
|
34
|
+
if @provider.has_callback?
|
|
35
|
+
redirect_to @provider.login_url(params,session)
|
|
36
|
+
else
|
|
37
|
+
#@provider.login(args)
|
|
41
38
|
end
|
|
42
|
-
redirect_to @provider.authorize_url(args)
|
|
43
39
|
end
|
|
44
40
|
|
|
45
|
-
# tries to login the user from
|
|
46
|
-
def
|
|
41
|
+
# tries to login the user from provider's callback
|
|
42
|
+
def login_from(provider)
|
|
47
43
|
@provider = Config.send(provider)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
args.merge!({:code => params[:code]}) if params[:code]
|
|
51
|
-
@access_token = @provider.get_access_token(args)
|
|
52
|
-
@user_hash = @provider.get_user_hash(@access_token)
|
|
44
|
+
@provider.process_callback(params,session)
|
|
45
|
+
@user_hash = @provider.get_user_hash
|
|
53
46
|
if user = Config.user_class.load_from_provider(provider,@user_hash[:uid])
|
|
54
47
|
reset_session
|
|
55
48
|
login_user(user)
|
|
@@ -57,11 +50,6 @@ module Sorcery
|
|
|
57
50
|
end
|
|
58
51
|
end
|
|
59
52
|
|
|
60
|
-
def get_user_hash(provider)
|
|
61
|
-
@provider = Config.send(provider)
|
|
62
|
-
@provider.get_user_hash(@access_token)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
53
|
# this method automatically creates a new user from the data in the external user hash.
|
|
66
54
|
# The mappings from user hash fields to user db fields are set at controller config.
|
|
67
55
|
# If the hash field you would like to map is nested, use slashes. For example, Given a hash like:
|
|
@@ -73,10 +61,10 @@ module Sorcery
|
|
|
73
61
|
# {:username => "user/name"}
|
|
74
62
|
#
|
|
75
63
|
# And this will cause 'moishe' to be set as the value of :username field.
|
|
76
|
-
def
|
|
64
|
+
def create_from(provider)
|
|
77
65
|
provider = provider.to_sym
|
|
78
66
|
@provider = Config.send(provider)
|
|
79
|
-
@user_hash = get_user_hash
|
|
67
|
+
@user_hash = @provider.get_user_hash
|
|
80
68
|
config = Config.user_class.sorcery_config
|
|
81
69
|
attrs = {}
|
|
82
70
|
@provider.user_info_mapping.each do |k,v|
|
|
@@ -9,7 +9,7 @@ module Sorcery
|
|
|
9
9
|
base.send(:include, InstanceMethods)
|
|
10
10
|
Config.module_eval do
|
|
11
11
|
class << self
|
|
12
|
-
attr_accessor :controller_to_realm_map #
|
|
12
|
+
attr_accessor :controller_to_realm_map # What realm to display for which controller name.
|
|
13
13
|
|
|
14
14
|
def merge_http_basic_auth_defaults!
|
|
15
15
|
@defaults.merge!(:@controller_to_realm_map => {"application" => "Application"})
|