sorcery 0.1.4 → 0.3.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 +4 -2
- data/Gemfile.lock +16 -13
- data/README.rdoc +111 -78
- data/Rakefile +5 -0
- data/VERSION +1 -1
- data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +24 -0
- data/lib/generators/sorcery_migration/templates/activity_logging.rb +17 -0
- data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +11 -0
- data/lib/generators/sorcery_migration/templates/core.rb +16 -0
- data/lib/generators/sorcery_migration/templates/oauth.rb +14 -0
- data/lib/generators/sorcery_migration/templates/remember_me.rb +15 -0
- data/lib/generators/sorcery_migration/templates/reset_password.rb +13 -0
- data/lib/generators/sorcery_migration/templates/user_activation.rb +17 -0
- data/lib/sorcery/controller/adapters/sinatra.rb +97 -0
- data/lib/sorcery/controller/submodules/activity_logging.rb +20 -7
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +9 -2
- data/lib/sorcery/controller/submodules/http_basic_auth.rb +18 -9
- data/lib/sorcery/controller/submodules/oauth/oauth1.rb +33 -0
- data/lib/sorcery/controller/submodules/oauth/oauth2.rb +24 -0
- data/lib/sorcery/controller/submodules/oauth/providers/facebook.rb +64 -0
- data/lib/sorcery/controller/submodules/oauth/providers/twitter.rb +61 -0
- data/lib/sorcery/controller/submodules/oauth.rb +95 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +14 -5
- data/lib/sorcery/controller/submodules/session_timeout.rb +6 -1
- data/lib/sorcery/controller.rb +29 -17
- data/lib/sorcery/engine.rb +9 -2
- data/lib/sorcery/model/submodules/activity_logging.rb +13 -8
- data/lib/sorcery/model/submodules/brute_force_protection.rb +11 -8
- data/lib/sorcery/model/submodules/oauth.rb +53 -0
- data/lib/sorcery/model/submodules/remember_me.rb +5 -3
- data/lib/sorcery/model/submodules/reset_password.rb +16 -13
- data/lib/sorcery/model/submodules/user_activation.rb +38 -19
- data/lib/sorcery/model/temporary_token.rb +22 -0
- data/lib/sorcery/model.rb +10 -3
- data/lib/sorcery/sinatra.rb +14 -0
- data/lib/sorcery/test_helpers/rails.rb +57 -0
- data/lib/sorcery/test_helpers/sinatra.rb +131 -0
- data/lib/sorcery/test_helpers.rb +40 -0
- data/lib/sorcery.rb +20 -0
- data/sorcery.gemspec +144 -41
- data/spec/Gemfile +3 -2
- data/spec/Gemfile.lock +15 -2
- data/spec/rails3/app_root/.rspec +1 -0
- data/spec/rails3/{Gemfile → app_root/Gemfile} +4 -4
- data/spec/rails3/{Gemfile.lock → app_root/Gemfile.lock} +23 -3
- data/spec/rails3/app_root/app/controllers/application_controller.rb +42 -1
- data/spec/rails3/app_root/app/models/authentication.rb +3 -0
- data/spec/rails3/app_root/app/models/user.rb +4 -1
- data/spec/rails3/app_root/config/application.rb +1 -3
- data/spec/rails3/app_root/config/routes.rb +1 -10
- data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +6 -4
- data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +4 -4
- data/spec/rails3/app_root/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
- data/spec/rails3/{controller_activity_logging_spec.rb → app_root/spec/controller_activity_logging_spec.rb} +13 -13
- data/spec/rails3/{controller_brute_force_protection_spec.rb → app_root/spec/controller_brute_force_protection_spec.rb} +16 -6
- data/spec/rails3/{controller_http_basic_auth_spec.rb → app_root/spec/controller_http_basic_auth_spec.rb} +3 -3
- data/spec/rails3/app_root/spec/controller_oauth2_spec.rb +119 -0
- data/spec/rails3/app_root/spec/controller_oauth_spec.rb +122 -0
- data/spec/rails3/{controller_remember_me_spec.rb → app_root/spec/controller_remember_me_spec.rb} +4 -4
- data/spec/rails3/{controller_session_timeout_spec.rb → app_root/spec/controller_session_timeout_spec.rb} +6 -6
- data/spec/rails3/{controller_spec.rb → app_root/spec/controller_spec.rb} +20 -13
- data/spec/rails3/app_root/spec/spec_helper.orig.rb +27 -0
- data/spec/rails3/app_root/spec/spec_helper.rb +62 -0
- data/spec/rails3/{user_activation_spec.rb → app_root/spec/user_activation_spec.rb} +60 -20
- data/spec/rails3/{user_activity_logging_spec.rb → app_root/spec/user_activity_logging_spec.rb} +4 -4
- data/spec/rails3/{user_brute_force_protection_spec.rb → app_root/spec/user_brute_force_protection_spec.rb} +7 -7
- data/spec/rails3/app_root/spec/user_oauth_spec.rb +39 -0
- data/spec/rails3/{user_remember_me_spec.rb → app_root/spec/user_remember_me_spec.rb} +4 -4
- data/spec/rails3/{user_reset_password_spec.rb → app_root/spec/user_reset_password_spec.rb} +21 -41
- data/spec/rails3/app_root/spec/user_spec.rb +317 -0
- data/spec/sinatra/Gemfile +12 -0
- data/spec/sinatra/Gemfile.lock +134 -0
- data/spec/sinatra/Rakefile +10 -0
- data/spec/sinatra/authentication.rb +3 -0
- data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
- data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
- data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
- data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/sinatra/db/migrate/oauth/20101224223628_create_authentications.rb +14 -0
- data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
- data/spec/sinatra/filters.rb +21 -0
- data/spec/sinatra/myapp.rb +133 -0
- data/spec/sinatra/sorcery_mailer.rb +25 -0
- data/spec/sinatra/spec/controller_activity_logging_spec.rb +85 -0
- data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +69 -0
- data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +53 -0
- data/spec/sinatra/spec/controller_oauth2_spec.rb +119 -0
- data/spec/sinatra/spec/controller_oauth_spec.rb +121 -0
- data/spec/sinatra/spec/controller_remember_me_spec.rb +64 -0
- data/spec/sinatra/spec/controller_session_timeout_spec.rb +52 -0
- data/spec/sinatra/spec/controller_spec.rb +120 -0
- data/spec/sinatra/spec/spec.opts +4 -0
- data/spec/sinatra/spec/spec_helper.rb +44 -0
- data/spec/sinatra/spec/user_activation_spec.rb +188 -0
- data/spec/sinatra/spec/user_activity_logging_spec.rb +36 -0
- data/spec/sinatra/spec/user_brute_force_protection_spec.rb +76 -0
- data/spec/sinatra/spec/user_oauth_spec.rb +39 -0
- data/spec/sinatra/spec/user_remember_me_spec.rb +66 -0
- data/spec/sinatra/spec/user_reset_password_spec.rb +178 -0
- data/spec/{rails3 → sinatra/spec}/user_spec.rb +68 -38
- data/spec/sinatra/user.rb +6 -0
- data/spec/sinatra/views/test_login.erb +4 -0
- data/spec/untitled folder +18 -0
- metadata +201 -58
- data/spec/rails3/app_root/test/fixtures/users.yml +0 -9
- data/spec/rails3/app_root/test/performance/browsing_test.rb +0 -9
- data/spec/rails3/app_root/test/test_helper.rb +0 -13
- data/spec/rails3/app_root/test/unit/user_test.rb +0 -8
- data/spec/rails3/spec_helper.rb +0 -135
- /data/spec/rails3/{Rakefile → app_root/Rakefile} +0 -0
data/Gemfile
CHANGED
|
@@ -2,11 +2,13 @@ source "http://rubygems.org"
|
|
|
2
2
|
# Add dependencies required to use your gem here.
|
|
3
3
|
# Example:
|
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
|
5
|
-
|
|
5
|
+
gem "rails", ">= 3.0.0"
|
|
6
|
+
gem 'json', ">= 1.5.1"
|
|
7
|
+
gem 'oauth', ">= 0.4.4"
|
|
8
|
+
gem 'oauth2', ">= 0.1.1"
|
|
6
9
|
# Add dependencies to develop your gem here.
|
|
7
10
|
# Include everything needed to run rake, tests, features, etc.
|
|
8
11
|
group :development do
|
|
9
|
-
gem "rails", ">= 3.0.0"
|
|
10
12
|
gem "rspec", "~> 2.3.0"
|
|
11
13
|
gem 'rspec-rails'
|
|
12
14
|
gem 'ruby-debug19'
|
data/Gemfile.lock
CHANGED
|
@@ -28,29 +28,25 @@ GEM
|
|
|
28
28
|
activemodel (= 3.0.3)
|
|
29
29
|
activesupport (= 3.0.3)
|
|
30
30
|
activesupport (3.0.3)
|
|
31
|
+
addressable (2.2.4)
|
|
31
32
|
archive-tar-minitar (0.5.2)
|
|
32
33
|
arel (2.0.6)
|
|
33
34
|
builder (2.1.2)
|
|
34
35
|
columnize (0.3.2)
|
|
35
|
-
cucumber (0.10.0)
|
|
36
|
-
builder (>= 2.1.2)
|
|
37
|
-
diff-lcs (~> 1.1.2)
|
|
38
|
-
gherkin (~> 2.3.2)
|
|
39
|
-
json (~> 1.4.6)
|
|
40
|
-
term-ansicolor (~> 1.0.5)
|
|
41
36
|
diff-lcs (1.1.2)
|
|
42
37
|
erubis (2.6.6)
|
|
43
38
|
abstract (>= 1.0.0)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
39
|
+
faraday (0.5.5)
|
|
40
|
+
addressable (~> 2.2.4)
|
|
41
|
+
multipart-post (~> 1.1.0)
|
|
42
|
+
rack (< 2, >= 1.1.0)
|
|
47
43
|
git (1.2.5)
|
|
48
44
|
i18n (0.5.0)
|
|
49
45
|
jeweler (1.5.2)
|
|
50
46
|
bundler (~> 1.0.0)
|
|
51
47
|
git (>= 1.2.5)
|
|
52
48
|
rake
|
|
53
|
-
json (1.
|
|
49
|
+
json (1.5.1)
|
|
54
50
|
linecache19 (0.5.11)
|
|
55
51
|
ruby_core_source (>= 0.1.4)
|
|
56
52
|
mail (2.2.13)
|
|
@@ -59,6 +55,12 @@ GEM
|
|
|
59
55
|
mime-types (~> 1.16)
|
|
60
56
|
treetop (~> 1.4.8)
|
|
61
57
|
mime-types (1.16)
|
|
58
|
+
multi_json (0.0.5)
|
|
59
|
+
multipart-post (1.1.0)
|
|
60
|
+
oauth (0.4.4)
|
|
61
|
+
oauth2 (0.1.1)
|
|
62
|
+
faraday (~> 0.5.0)
|
|
63
|
+
multi_json (~> 0.0.4)
|
|
62
64
|
polyglot (0.3.1)
|
|
63
65
|
rack (1.2.1)
|
|
64
66
|
rack-mount (0.6.13)
|
|
@@ -106,7 +108,6 @@ GEM
|
|
|
106
108
|
simplecov-html (>= 0.3.7)
|
|
107
109
|
simplecov-html (0.3.9)
|
|
108
110
|
sqlite3-ruby (1.3.2)
|
|
109
|
-
term-ansicolor (1.0.5)
|
|
110
111
|
thor (0.14.6)
|
|
111
112
|
treetop (1.4.9)
|
|
112
113
|
polyglot (>= 0.3.1)
|
|
@@ -118,9 +119,11 @@ PLATFORMS
|
|
|
118
119
|
|
|
119
120
|
DEPENDENCIES
|
|
120
121
|
bundler (~> 1.0.0)
|
|
121
|
-
cucumber
|
|
122
122
|
jeweler (~> 1.5.2)
|
|
123
|
-
|
|
123
|
+
json (>= 1.5.1)
|
|
124
|
+
oauth (>= 0.4.4)
|
|
125
|
+
oauth2 (>= 0.1.1)
|
|
126
|
+
rails (>= 3.0.0)
|
|
124
127
|
rspec (~> 2.3.0)
|
|
125
128
|
rspec-rails
|
|
126
129
|
ruby-debug19
|
data/README.rdoc
CHANGED
|
@@ -1,30 +1,118 @@
|
|
|
1
1
|
= sorcery
|
|
2
|
-
Magical Authentication for Rails 3.
|
|
2
|
+
Magical Authentication for Rails 3 and Sinatra.
|
|
3
3
|
|
|
4
4
|
Inspired by restful_authentication, Authlogic and Devise.
|
|
5
5
|
Crypto code taken almost unchanged from Authlogic.
|
|
6
|
+
OAuth code inspired by OmniAuth and Ryan Bates's railscasts about it.
|
|
6
7
|
|
|
7
|
-
== Example app using sorcery:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
== Summary
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Sorcery is a stripped-down, bare-bones authentication library, with which you can write your own authentication flow.
|
|
13
|
+
It was built with a few goals in mind:
|
|
14
|
+
|
|
15
|
+
* Less is more - less than 20 public methods to remember for the entire feature-set make the lib easy to 'get'.
|
|
16
|
+
* No built-in or generated code - use the library's methods inside *your own* MVC structures, and don't fight to fix someone else's.
|
|
17
|
+
* Magic yes, Voodoo no - the lib should be easy to hack for most developers.
|
|
18
|
+
* Configuration over Confusion - Simple & short configuration as possible, not drowning in syntactic sugar.
|
|
19
|
+
* Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
|
|
20
|
+
|
|
21
|
+
Hopefully, I've achieved this. If not, let me know.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
== Useful Links:
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Example Rails 3 app using sorcery: https://github.com/NoamB/sorcery-example-app
|
|
28
|
+
|
|
29
|
+
Example Sinatra app using sorcery: https://github.com/NoamB/sorcery-example-app-sinatra
|
|
30
|
+
|
|
31
|
+
Documentation: http://rubydoc.info/gems/sorcery/0.3.0/frames
|
|
32
|
+
|
|
33
|
+
Check out the tutorials in the github wiki!
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
== Installation:
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
If using bundler, first add 'sorcery' to your Gemfile:
|
|
40
|
+
|
|
41
|
+
gem "sorcery"
|
|
42
|
+
|
|
43
|
+
And run
|
|
44
|
+
|
|
45
|
+
bundle install
|
|
46
|
+
|
|
47
|
+
Otherwise simply
|
|
48
|
+
|
|
49
|
+
gem install sorcery
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
== Configuration:
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
1. config/application.rb
|
|
56
|
+
|
|
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
|
+
|
|
61
|
+
2. app/models/user.rb (or another model of your choice, but a User class is assumed by default)
|
|
62
|
+
|
|
63
|
+
activate_sorcery! do |config|
|
|
64
|
+
config.user_activation_mailer = MyMailer
|
|
65
|
+
config.username_attribute_name = :email
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
3. app/controllers/application_controller.rb (OPTIONAL: this is actually needed only in some cases)
|
|
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.
|
|
75
|
+
|
|
76
|
+
For your convenience, Sorcery includes a migrations generator for Rails, which can be used like so:
|
|
77
|
+
|
|
78
|
+
rails g sorcery_migration [list of submodules]
|
|
79
|
+
|
|
80
|
+
For example, for only the core functionality use:
|
|
81
|
+
|
|
82
|
+
rails g sorcery_migration core
|
|
83
|
+
|
|
84
|
+
To generate migrations for both the core AND 'remember_me' submodule:
|
|
85
|
+
|
|
86
|
+
rails g sorcery_migration core remember_me
|
|
87
|
+
|
|
88
|
+
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
|
+
|
|
90
|
+
|
|
91
|
+
== Usage
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Please see the tutorials in the github wiki.
|
|
95
|
+
|
|
10
96
|
|
|
11
97
|
== Full Features List by module:
|
|
12
98
|
|
|
13
|
-
|
|
14
|
-
|
|
99
|
+
|
|
100
|
+
Core (see lib/sorcery/model.rb and lib/sorcery/controller.rb):
|
|
101
|
+
* login/logout, optional return user to requested url on login, configurable redirect for non-logged-in users.
|
|
15
102
|
* password encryption, algorithms: bcrypt(default), md5, sha1, sha256, sha512, aes256, custom(yours!), none. Configurable stretches and salt.
|
|
16
103
|
* configurable attribute names for username, password and email.
|
|
17
104
|
|
|
18
105
|
User Activation (see lib/sorcery/model/submodules/user_activation.rb):
|
|
19
106
|
* User activation by email with optional success email.
|
|
20
107
|
* configurable attribute names.
|
|
21
|
-
* configurable mailer.
|
|
108
|
+
* configurable mailer, method name, and attribute name.
|
|
109
|
+
* configurable temporary token expiration.
|
|
22
110
|
* Optionally prevent non-active users to login.
|
|
23
111
|
|
|
24
112
|
Reset Password (see lib/sorcery/model/submodules/reset_password.rb):
|
|
25
113
|
* Reset password with email verification.
|
|
26
114
|
* configurable mailer, method name, and attribute name.
|
|
27
|
-
* configurable expiration.
|
|
115
|
+
* configurable temporary token expiration.
|
|
28
116
|
* configurable time between emails (hammering protection).
|
|
29
117
|
|
|
30
118
|
Remember Me (see lib/sorcery/model/submodules/remember_me.rb):
|
|
@@ -49,82 +137,24 @@ Activity Logging (see lib/sorcery/model/submodules/activity_logging.rb):
|
|
|
49
137
|
* an easy method of collecting the list of currently logged in users.
|
|
50
138
|
* configurable timeout by which to decide whether to include a user in the list of logged in users.
|
|
51
139
|
|
|
52
|
-
|
|
53
|
-
*
|
|
54
|
-
*
|
|
140
|
+
Oauth (see lib/sorcery/controller/submodules/oauth.rb):
|
|
141
|
+
* OAuth1 and OAuth2 support (currently twitter & facebook)
|
|
142
|
+
* configurable db field names and authentications table.
|
|
143
|
+
|
|
55
144
|
|
|
56
145
|
== Next Planned Features:
|
|
57
146
|
|
|
58
|
-
|
|
147
|
+
|
|
148
|
+
I've got many plans which include (by priority):
|
|
149
|
+
* Scoping logins (to a subdomain or another arbitrary field)
|
|
150
|
+
* Simple auth (no user)
|
|
151
|
+
* Switching authentication mode at runtime (Maintenance mode)
|
|
152
|
+
* Mongoid support
|
|
59
153
|
* Configurable Auto login on registration/activation
|
|
60
154
|
* Other reset password strategies (security questions?)
|
|
61
155
|
* Other brute force protection strategies (captcha)
|
|
62
|
-
* Sinatra support
|
|
63
|
-
* Mongoid support
|
|
64
|
-
* OAuth1 and OAuth2 support
|
|
65
156
|
* Have an idea? Let me know, and it might get into the gem!
|
|
66
157
|
|
|
67
|
-
== Project Goals:
|
|
68
|
-
|
|
69
|
-
This gem plugin was started out of a few personal goals which are not related to the problem solved by it at all:
|
|
70
|
-
* I wanted to write something 100% TDD from start to finish.
|
|
71
|
-
* I wanted to learn how to write an engine for Rails 3.
|
|
72
|
-
|
|
73
|
-
In addition to the above goals, when I decided this will be an authentication plugin, and while looking at existing solutions, these goals came up:
|
|
74
|
-
* Simple & short configuration as possible, not drowning in syntactic sugar.
|
|
75
|
-
* Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
|
|
76
|
-
* Magic yes, Voodoo no.
|
|
77
|
-
* No generated code polluting the application's code.
|
|
78
|
-
* No built-in controllers, models, mailers, migrations or templates; Real apps will need all of these custom made.
|
|
79
|
-
|
|
80
|
-
Hopefully, I've achieved this. If not, let me know.
|
|
81
|
-
|
|
82
|
-
== Installation:
|
|
83
|
-
|
|
84
|
-
You can either git clone and then 'rake install' to live on the edge (unstable),
|
|
85
|
-
|
|
86
|
-
Or simply (stable):
|
|
87
|
-
|
|
88
|
-
gem install sorcery
|
|
89
|
-
|
|
90
|
-
== Configuration:
|
|
91
|
-
|
|
92
|
-
First add 'sorcery' to your Gemfile:
|
|
93
|
-
|
|
94
|
-
gem "sorcery"
|
|
95
|
-
|
|
96
|
-
And run
|
|
97
|
-
|
|
98
|
-
bundle install
|
|
99
|
-
|
|
100
|
-
There are 2 required places to configure the plugin, and an optional one:
|
|
101
|
-
1. config/application.rb
|
|
102
|
-
|
|
103
|
-
config.sorcery.submodules = [:user_activation, :remember_me] # add the modules you want to use
|
|
104
|
-
|
|
105
|
-
You can also configure here any controller and any controller-submodule option here.
|
|
106
|
-
For example:
|
|
107
|
-
|
|
108
|
-
config.sorcery.session_timeout = 10.minutes
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
2. app/models/user.rb (or another model of your choice)
|
|
112
|
-
|
|
113
|
-
activate_sorcery! do |config|
|
|
114
|
-
config.user_activation_mailer = MyMailer
|
|
115
|
-
config.username_attribute_name = :email
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
3. app/controllers/application_controller.rb (OPTIONAL: this is actually needed only in some cases)
|
|
119
|
-
|
|
120
|
-
activate_sorcery! do |config|
|
|
121
|
-
config.session_timeout = 10.minutes
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
Also check the migrations in the example app to see what database fields are expected.
|
|
125
|
-
|
|
126
|
-
The configuration options vary with the modules you've chosen to use.
|
|
127
|
-
|
|
128
158
|
|
|
129
159
|
== Contributing to sorcery
|
|
130
160
|
|
|
@@ -134,19 +164,22 @@ For this:
|
|
|
134
164
|
|
|
135
165
|
* Fork the project.
|
|
136
166
|
* Make your feature addition or bug fix.
|
|
137
|
-
* Add tests for it.
|
|
167
|
+
* Add tests for it. I've used RSpec so far, please remain consistent with it.
|
|
138
168
|
* Commit, do not mess with Rakefiles, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
139
169
|
* Send me a pull request. Bonus points for topic branches.
|
|
140
170
|
|
|
141
171
|
If you feel my work has made your life easier, and you would like to thank me through a donation, my paypal email is in the contact details.
|
|
142
172
|
|
|
173
|
+
|
|
143
174
|
== Contact
|
|
144
175
|
|
|
176
|
+
Feel free to ask questions using these contact details:
|
|
177
|
+
|
|
145
178
|
email: nbenari@gmail.com ( also for paypal )
|
|
146
179
|
twitter: @nbenari
|
|
147
180
|
|
|
181
|
+
|
|
148
182
|
== Copyright
|
|
149
183
|
|
|
150
|
-
Copyright (c) 2010 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for further details.
|
|
151
|
-
Released with permission from Kontera (http://www.kontera.com), where I work.
|
|
152
184
|
|
|
185
|
+
Copyright (c) 2010 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for further details.
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# require 'bundler'
|
|
2
|
+
# -- Commented because it's slow
|
|
2
3
|
# begin
|
|
3
4
|
# Bundler.setup(:default, :development)
|
|
4
5
|
# rescue Bundler::BundlerError => e
|
|
@@ -6,6 +7,8 @@
|
|
|
6
7
|
# $stderr.puts "Run `bundle install` to install missing gems"
|
|
7
8
|
# exit e.status_code
|
|
8
9
|
# end
|
|
10
|
+
# --
|
|
11
|
+
|
|
9
12
|
require 'rake'
|
|
10
13
|
|
|
11
14
|
require 'jeweler'
|
|
@@ -23,6 +26,8 @@ Jeweler::Tasks.new do |gem|
|
|
|
23
26
|
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
|
24
27
|
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
|
25
28
|
gem.add_runtime_dependency 'bcrypt-ruby', '~> 2.1.4'
|
|
29
|
+
gem.add_runtime_dependency 'oauth', '>= 0.4.4'
|
|
30
|
+
gem.add_runtime_dependency 'oauth2', '>= 0.1.1'
|
|
26
31
|
end
|
|
27
32
|
Jeweler::RubygemsDotOrgTasks.new
|
|
28
33
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.3.0
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
require 'rails/generators/migration'
|
|
3
|
+
|
|
4
|
+
class SorceryMigrationGenerator < Rails::Generators::Base
|
|
5
|
+
include Rails::Generators::Migration
|
|
6
|
+
|
|
7
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
|
8
|
+
argument :submodules, :type => :array, :required => true
|
|
9
|
+
|
|
10
|
+
def self.next_migration_number(dirname)
|
|
11
|
+
if ActiveRecord::Base.timestamped_migrations
|
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
|
13
|
+
else
|
|
14
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_migration_file
|
|
19
|
+
self.submodules.each do |submodule|
|
|
20
|
+
migration_template "#{submodule}.rb", "db/migrate/sorcery_#{submodule}.rb"
|
|
21
|
+
sleep 1 # for the timestamp to change
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class SorceryActivityLogging < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :users, :last_login_at, :datetime, :default => nil
|
|
4
|
+
add_column :users, :last_logout_at, :datetime, :default => nil
|
|
5
|
+
add_column :users, :last_activity_at, :datetime, :default => nil
|
|
6
|
+
|
|
7
|
+
add_index :users, [:last_logout_at, :last_activity_at]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.down
|
|
11
|
+
remove_index :users, [:last_logout_at, :last_activity_at]
|
|
12
|
+
|
|
13
|
+
remove_column :users, :last_activity_at
|
|
14
|
+
remove_column :users, :last_logout_at
|
|
15
|
+
remove_column :users, :last_login_at
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class SorceryBruteForceProtection < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :users, :failed_logins_count, :integer, :default => 0
|
|
4
|
+
add_column :users, :lock_expires_at, :datetime, :default => nil
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.down
|
|
8
|
+
remove_column :users, :lock_expires_at
|
|
9
|
+
remove_column :users, :failed_logins_count
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class SorceryCore < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :users do |t|
|
|
4
|
+
t.string :username, :null => false
|
|
5
|
+
t.string :email, :default => nil
|
|
6
|
+
t.string :crypted_password, :default => nil
|
|
7
|
+
t.string :salt, :default => nil
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.down
|
|
14
|
+
drop_table :users
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class SorceryOauth < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table :authentications do |t|
|
|
4
|
+
t.integer :user_id, :null => false
|
|
5
|
+
t.string :provider, :uid, :null => false
|
|
6
|
+
|
|
7
|
+
t.timestamps
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.down
|
|
12
|
+
drop_table :authentications
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class SorceryRememberMe < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :users, :remember_me_token, :string, :default => nil
|
|
4
|
+
add_column :users, :remember_me_token_expires_at, :datetime, :default => nil
|
|
5
|
+
|
|
6
|
+
add_index :users, :remember_me_token
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.down
|
|
10
|
+
remove_index :users, :remember_me_token
|
|
11
|
+
|
|
12
|
+
remove_column :users, :remember_me_token_expires_at
|
|
13
|
+
remove_column :users, :remember_me_token
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class SorceryResetPassword < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :users, :reset_password_token, :string, :default => nil
|
|
4
|
+
add_column :users, :reset_password_token_expires_at, :datetime, :default => nil
|
|
5
|
+
add_column :users, :reset_password_email_sent_at, :datetime, :default => nil
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.down
|
|
9
|
+
remove_column :users, :reset_password_email_sent_at
|
|
10
|
+
remove_column :users, :reset_password_token_expires_at
|
|
11
|
+
remove_column :users, :reset_password_token
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class SorceryUserActivation < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
add_column :users, :activation_state, :string, :default => nil
|
|
4
|
+
add_column :users, :activation_token, :string, :default => nil
|
|
5
|
+
add_column :users, :activation_token_expires_at, :datetime, :default => nil
|
|
6
|
+
|
|
7
|
+
add_index :users, :activation_token
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.down
|
|
11
|
+
remove_index :users, :activation_token
|
|
12
|
+
|
|
13
|
+
remove_column :users, :activation_token_expires_at
|
|
14
|
+
remove_column :users, :activation_token
|
|
15
|
+
remove_column :users, :activation_state
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module Sorcery
|
|
2
|
+
module Controller
|
|
3
|
+
module Adapters
|
|
4
|
+
# This module does the magic of translating Rails commands to Sinatra.
|
|
5
|
+
# This way the Rails code doesn't change, but it actually now calls Sinatra calls.
|
|
6
|
+
module Sinatra
|
|
7
|
+
def self.included(base)
|
|
8
|
+
base.class_eval do
|
|
9
|
+
class << self
|
|
10
|
+
# prepend a filter
|
|
11
|
+
def prepend_filter(type, path = nil, options = {}, &block)
|
|
12
|
+
return filters[type].unshift block unless path
|
|
13
|
+
path, options = //, path if path.respond_to?(:each_pair)
|
|
14
|
+
block, *arguments = compile!(type, path, block, options)
|
|
15
|
+
prepend_filter(type) do
|
|
16
|
+
process_route(*arguments) { instance_eval(&block) }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def after_filter(filter)
|
|
21
|
+
after do
|
|
22
|
+
send(filter)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
::Sinatra::Request.class_eval do
|
|
29
|
+
def authorization
|
|
30
|
+
env['HTTP_AUTHORIZATION'] ||
|
|
31
|
+
env['X-HTTP_AUTHORIZATION'] ||
|
|
32
|
+
env['X_HTTP_AUTHORIZATION'] ||
|
|
33
|
+
env['REDIRECT_X_HTTP_AUTHORIZATION'] || nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
base.send(:include, InstanceMethods)
|
|
38
|
+
base.extend(ClassMethods)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
module InstanceMethods
|
|
42
|
+
def reset_session
|
|
43
|
+
session.clear
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def redirect_to(*args)
|
|
47
|
+
args.pop if args.last.is_a?(Hash)
|
|
48
|
+
redirect(*args)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def root_path
|
|
52
|
+
'/'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
helpers do
|
|
56
|
+
def request_http_basic_authentication(realm)
|
|
57
|
+
response.header['WWW-Authenticate'] = %(Basic realm="#{realm}")
|
|
58
|
+
response.status = 401
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def authenticate_with_http_basic(&blk)
|
|
62
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
|
63
|
+
yield @auth.credentials if ( @auth.provided? && @auth.basic? && @auth.credentials )
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def cookies
|
|
68
|
+
@cookie_proxy ||= CookieProxy.new(request,response)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class CookieProxy
|
|
73
|
+
def initialize(request,response)
|
|
74
|
+
@request = request
|
|
75
|
+
@response = response
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def [](key)
|
|
79
|
+
@request.cookies[key.to_s]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def []=(key, value)
|
|
83
|
+
@response.set_cookie(key, value)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
module ClassMethods
|
|
88
|
+
def prepend_before_filter(filter)
|
|
89
|
+
prepend_filter(:before) do
|
|
90
|
+
send(filter)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
module Sorcery
|
|
2
2
|
module Controller
|
|
3
3
|
module Submodules
|
|
4
|
+
# This submodule keeps track of events such as login, logout, and last activity time, per user.
|
|
5
|
+
# It helps in estimating which users are active now in the site.
|
|
6
|
+
# This cannot be determined absolutely because a user might be reading a page without clicking anything for a while.
|
|
7
|
+
|
|
8
|
+
# This is the controller part of the submodule, which adds hooks to register user events,
|
|
9
|
+
# and methods to collect active users data for use in the app.
|
|
10
|
+
# see Socery::Model::Submodules::ActivityLogging for configuration options.
|
|
4
11
|
module ActivityLogging
|
|
5
12
|
def self.included(base)
|
|
6
13
|
base.send(:include, InstanceMethods)
|
|
@@ -10,33 +17,39 @@ module Sorcery
|
|
|
10
17
|
end
|
|
11
18
|
|
|
12
19
|
module InstanceMethods
|
|
13
|
-
|
|
14
|
-
|
|
20
|
+
# Returns an array of the active users.
|
|
21
|
+
def current_users
|
|
22
|
+
Config.user_class.current_users
|
|
15
23
|
# A possible patch here:
|
|
16
|
-
# we'll add the
|
|
24
|
+
# we'll add the current_user to the users list if he's not in it (can happen when he was inactive for more than activity timeout):
|
|
17
25
|
#
|
|
18
|
-
# users.unshift!(
|
|
26
|
+
# users.unshift!(current_user) if logged_in? && users.find {|u| u.id == current_user.id}.nil?
|
|
19
27
|
#
|
|
20
28
|
# disadvantages: can hurt performance.
|
|
21
29
|
end
|
|
22
30
|
|
|
23
31
|
protected
|
|
24
32
|
|
|
33
|
+
# registers last login time on every login.
|
|
34
|
+
# This runs as a hook just after a successful login.
|
|
25
35
|
def register_login_time_to_db(user, credentials)
|
|
26
36
|
user.send(:"#{user.sorcery_config.last_login_at_attribute_name}=", Time.now.utc.to_s(:db))
|
|
27
37
|
user.save!(:validate => false)
|
|
28
38
|
end
|
|
29
39
|
|
|
40
|
+
# registers last logout time on every logout.
|
|
41
|
+
# This runs as a hook just before a logout.
|
|
30
42
|
def register_logout_time_to_db(user)
|
|
31
43
|
user.send(:"#{user.sorcery_config.last_logout_at_attribute_name}=", Time.now.utc.to_s(:db))
|
|
32
44
|
user.save!(:validate => false)
|
|
33
45
|
end
|
|
34
46
|
|
|
35
|
-
#
|
|
47
|
+
# Updates last activity time on every request.
|
|
48
|
+
# The only exception is logout - we do not update activity on logout
|
|
36
49
|
def register_last_activity_time_to_db
|
|
37
50
|
return if !logged_in?
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
current_user.send(:"#{current_user.sorcery_config.last_activity_at_attribute_name}=", Time.now.utc.to_s(:db))
|
|
52
|
+
current_user.save!(:validate => false)
|
|
40
53
|
end
|
|
41
54
|
end
|
|
42
55
|
end
|