sorcery 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sorcery might be problematic. Click here for more details.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +129 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +139 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/features/support/env.rb +13 -0
- data/lib/sorcery.rb +28 -0
- data/lib/sorcery/controller.rb +156 -0
- data/lib/sorcery/controller/submodules/brute_force_protection.rb +89 -0
- data/lib/sorcery/controller/submodules/remember_me.rb +43 -0
- data/lib/sorcery/controller/submodules/session_timeout.rb +42 -0
- data/lib/sorcery/crypto_providers/aes256.rb +44 -0
- data/lib/sorcery/crypto_providers/bcrypt.rb +96 -0
- data/lib/sorcery/crypto_providers/md5.rb +39 -0
- data/lib/sorcery/crypto_providers/sha1.rb +40 -0
- data/lib/sorcery/crypto_providers/sha256.rb +55 -0
- data/lib/sorcery/crypto_providers/sha512.rb +55 -0
- data/lib/sorcery/engine.rb +20 -0
- data/lib/sorcery/model.rb +175 -0
- data/lib/sorcery/model/submodules/password_reset.rb +64 -0
- data/lib/sorcery/model/submodules/remember_me.rb +42 -0
- data/lib/sorcery/model/submodules/user_activation.rb +84 -0
- data/spec/Gemfile +11 -0
- data/spec/Gemfile.lock +108 -0
- data/spec/Rakefile +11 -0
- data/spec/rails3/.rspec +1 -0
- data/spec/rails3/Gemfile +12 -0
- data/spec/rails3/Gemfile.lock +114 -0
- data/spec/rails3/Rakefile +10 -0
- data/spec/rails3/app_root/.gitignore +4 -0
- data/spec/rails3/app_root/README +256 -0
- data/spec/rails3/app_root/Rakefile.unused +7 -0
- data/spec/rails3/app_root/app/controllers/application_controller.rb +61 -0
- data/spec/rails3/app_root/app/helpers/application_helper.rb +2 -0
- data/spec/rails3/app_root/app/mailers/sorcery_mailer.rb +25 -0
- data/spec/rails3/app_root/app/models/user.rb +3 -0
- data/spec/rails3/app_root/app/views/layouts/application.html.erb +14 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.html.erb +17 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.text.erb +9 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
- data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
- data/spec/rails3/app_root/config.ru +4 -0
- data/spec/rails3/app_root/config/application.rb +48 -0
- data/spec/rails3/app_root/config/boot.rb +13 -0
- data/spec/rails3/app_root/config/database.yml +27 -0
- data/spec/rails3/app_root/config/environment.rb +5 -0
- data/spec/rails3/app_root/config/environments/development.rb +26 -0
- data/spec/rails3/app_root/config/environments/in_memory.rb +0 -0
- data/spec/rails3/app_root/config/environments/production.rb +49 -0
- data/spec/rails3/app_root/config/environments/test.rb +35 -0
- data/spec/rails3/app_root/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails3/app_root/config/initializers/inflections.rb +10 -0
- data/spec/rails3/app_root/config/initializers/mime_types.rb +5 -0
- data/spec/rails3/app_root/config/initializers/secret_token.rb +7 -0
- data/spec/rails3/app_root/config/initializers/session_store.rb +8 -0
- data/spec/rails3/app_root/config/locales/en.yml +5 -0
- data/spec/rails3/app_root/config/routes.rb +67 -0
- data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +15 -0
- data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +16 -0
- data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +9 -0
- data/spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
- data/spec/rails3/app_root/db/schema.rb +23 -0
- data/spec/rails3/app_root/db/seeds.rb +7 -0
- data/spec/rails3/app_root/lib/tasks/.gitkeep +0 -0
- data/spec/rails3/app_root/public/404.html +26 -0
- data/spec/rails3/app_root/public/422.html +26 -0
- data/spec/rails3/app_root/public/500.html +26 -0
- data/spec/rails3/app_root/public/favicon.ico +0 -0
- data/spec/rails3/app_root/public/images/rails.png +0 -0
- data/spec/rails3/app_root/public/index.html +239 -0
- data/spec/rails3/app_root/public/javascripts/application.js +2 -0
- data/spec/rails3/app_root/public/javascripts/controls.js +965 -0
- data/spec/rails3/app_root/public/javascripts/dragdrop.js +974 -0
- data/spec/rails3/app_root/public/javascripts/effects.js +1123 -0
- data/spec/rails3/app_root/public/javascripts/prototype.js +6001 -0
- data/spec/rails3/app_root/public/javascripts/rails.js +175 -0
- data/spec/rails3/app_root/public/robots.txt +5 -0
- data/spec/rails3/app_root/public/stylesheets/.gitkeep +0 -0
- data/spec/rails3/app_root/script/rails +6 -0
- data/spec/rails3/app_root/test/fixtures/users.yml +9 -0
- data/spec/rails3/app_root/test/performance/browsing_test.rb +9 -0
- data/spec/rails3/app_root/test/test_helper.rb +13 -0
- data/spec/rails3/app_root/test/unit/user_test.rb +8 -0
- data/spec/rails3/app_root/vendor/plugins/.gitkeep +0 -0
- data/spec/rails3/controller_brute_force_protection_spec.rb +72 -0
- data/spec/rails3/controller_remember_me_spec.rb +65 -0
- data/spec/rails3/controller_session_timeout_spec.rb +49 -0
- data/spec/rails3/controller_spec.rb +115 -0
- data/spec/rails3/spec_helper.rb +115 -0
- data/spec/rails3/user_activation_spec.rb +148 -0
- data/spec/rails3/user_password_reset_spec.rb +76 -0
- data/spec/rails3/user_remember_me_spec.rb +66 -0
- data/spec/rails3/user_spec.rb +283 -0
- data/spec/sorcery_crypto_providers_spec.rb +182 -0
- data/spec/spec_helper.rb +18 -0
- metadata +341 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rails", "3.0.3"
|
10
|
+
gem "rspec", "~> 2.3.0"
|
11
|
+
gem 'rspec-rails'
|
12
|
+
gem 'ruby-debug19'
|
13
|
+
gem 'sqlite3-ruby', :require => 'sqlite3'
|
14
|
+
gem "yard", "~> 0.6.0"
|
15
|
+
gem "cucumber", ">= 0"
|
16
|
+
gem "bundler", "~> 1.0.0"
|
17
|
+
gem "jeweler", "~> 1.5.2"
|
18
|
+
gem 'simplecov', '>= 0.3.8', :require => false # Will install simplecov-html as a dependency
|
19
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionmailer (3.0.3)
|
6
|
+
actionpack (= 3.0.3)
|
7
|
+
mail (~> 2.2.9)
|
8
|
+
actionpack (3.0.3)
|
9
|
+
activemodel (= 3.0.3)
|
10
|
+
activesupport (= 3.0.3)
|
11
|
+
builder (~> 2.1.2)
|
12
|
+
erubis (~> 2.6.6)
|
13
|
+
i18n (~> 0.4)
|
14
|
+
rack (~> 1.2.1)
|
15
|
+
rack-mount (~> 0.6.13)
|
16
|
+
rack-test (~> 0.5.6)
|
17
|
+
tzinfo (~> 0.3.23)
|
18
|
+
activemodel (3.0.3)
|
19
|
+
activesupport (= 3.0.3)
|
20
|
+
builder (~> 2.1.2)
|
21
|
+
i18n (~> 0.4)
|
22
|
+
activerecord (3.0.3)
|
23
|
+
activemodel (= 3.0.3)
|
24
|
+
activesupport (= 3.0.3)
|
25
|
+
arel (~> 2.0.2)
|
26
|
+
tzinfo (~> 0.3.23)
|
27
|
+
activeresource (3.0.3)
|
28
|
+
activemodel (= 3.0.3)
|
29
|
+
activesupport (= 3.0.3)
|
30
|
+
activesupport (3.0.3)
|
31
|
+
archive-tar-minitar (0.5.2)
|
32
|
+
arel (2.0.6)
|
33
|
+
builder (2.1.2)
|
34
|
+
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
|
+
diff-lcs (1.1.2)
|
42
|
+
erubis (2.6.6)
|
43
|
+
abstract (>= 1.0.0)
|
44
|
+
gherkin (2.3.2)
|
45
|
+
json (~> 1.4.6)
|
46
|
+
term-ansicolor (~> 1.0.5)
|
47
|
+
git (1.2.5)
|
48
|
+
i18n (0.5.0)
|
49
|
+
jeweler (1.5.2)
|
50
|
+
bundler (~> 1.0.0)
|
51
|
+
git (>= 1.2.5)
|
52
|
+
rake
|
53
|
+
json (1.4.6)
|
54
|
+
linecache19 (0.5.11)
|
55
|
+
ruby_core_source (>= 0.1.4)
|
56
|
+
mail (2.2.13)
|
57
|
+
activesupport (>= 2.3.6)
|
58
|
+
i18n (>= 0.4.0)
|
59
|
+
mime-types (~> 1.16)
|
60
|
+
treetop (~> 1.4.8)
|
61
|
+
mime-types (1.16)
|
62
|
+
polyglot (0.3.1)
|
63
|
+
rack (1.2.1)
|
64
|
+
rack-mount (0.6.13)
|
65
|
+
rack (>= 1.0.0)
|
66
|
+
rack-test (0.5.6)
|
67
|
+
rack (>= 1.0)
|
68
|
+
rails (3.0.3)
|
69
|
+
actionmailer (= 3.0.3)
|
70
|
+
actionpack (= 3.0.3)
|
71
|
+
activerecord (= 3.0.3)
|
72
|
+
activeresource (= 3.0.3)
|
73
|
+
activesupport (= 3.0.3)
|
74
|
+
bundler (~> 1.0)
|
75
|
+
railties (= 3.0.3)
|
76
|
+
railties (3.0.3)
|
77
|
+
actionpack (= 3.0.3)
|
78
|
+
activesupport (= 3.0.3)
|
79
|
+
rake (>= 0.8.7)
|
80
|
+
thor (~> 0.14.4)
|
81
|
+
rake (0.8.7)
|
82
|
+
rspec (2.3.0)
|
83
|
+
rspec-core (~> 2.3.0)
|
84
|
+
rspec-expectations (~> 2.3.0)
|
85
|
+
rspec-mocks (~> 2.3.0)
|
86
|
+
rspec-core (2.3.1)
|
87
|
+
rspec-expectations (2.3.0)
|
88
|
+
diff-lcs (~> 1.1.2)
|
89
|
+
rspec-mocks (2.3.0)
|
90
|
+
rspec-rails (2.3.1)
|
91
|
+
actionpack (~> 3.0)
|
92
|
+
activesupport (~> 3.0)
|
93
|
+
railties (~> 3.0)
|
94
|
+
rspec (~> 2.3.0)
|
95
|
+
ruby-debug-base19 (0.11.24)
|
96
|
+
columnize (>= 0.3.1)
|
97
|
+
linecache19 (>= 0.5.11)
|
98
|
+
ruby_core_source (>= 0.1.4)
|
99
|
+
ruby-debug19 (0.11.6)
|
100
|
+
columnize (>= 0.3.1)
|
101
|
+
linecache19 (>= 0.5.11)
|
102
|
+
ruby-debug-base19 (>= 0.11.19)
|
103
|
+
ruby_core_source (0.1.4)
|
104
|
+
archive-tar-minitar (>= 0.5.2)
|
105
|
+
simplecov (0.3.9)
|
106
|
+
simplecov-html (>= 0.3.7)
|
107
|
+
simplecov-html (0.3.9)
|
108
|
+
sqlite3-ruby (1.3.2)
|
109
|
+
term-ansicolor (1.0.5)
|
110
|
+
thor (0.14.6)
|
111
|
+
treetop (1.4.9)
|
112
|
+
polyglot (>= 0.3.1)
|
113
|
+
tzinfo (0.3.23)
|
114
|
+
yard (0.6.4)
|
115
|
+
|
116
|
+
PLATFORMS
|
117
|
+
ruby
|
118
|
+
|
119
|
+
DEPENDENCIES
|
120
|
+
bundler (~> 1.0.0)
|
121
|
+
cucumber
|
122
|
+
jeweler (~> 1.5.2)
|
123
|
+
rails (= 3.0.3)
|
124
|
+
rspec (~> 2.3.0)
|
125
|
+
rspec-rails
|
126
|
+
ruby-debug19
|
127
|
+
simplecov (>= 0.3.8)
|
128
|
+
sqlite3-ruby
|
129
|
+
yard (~> 0.6.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Noam Ben-Ari
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
= sorcery
|
2
|
+
Magical Authentication for Rails 3.
|
3
|
+
|
4
|
+
Inspired by restful_authentication, Authlogic and Devise.
|
5
|
+
Crypto code taken almost unchanged from Authlogic.
|
6
|
+
|
7
|
+
== Example app using sorcery:
|
8
|
+
|
9
|
+
https://github.com/NoamB/sorcery-example-app
|
10
|
+
|
11
|
+
== Current Features:
|
12
|
+
|
13
|
+
* Basic Login/Logout.
|
14
|
+
* Password encryption with configurable algorithm.
|
15
|
+
* User activation by email with optional success email.
|
16
|
+
* Reset password with email verification.
|
17
|
+
* Remember me with configurable expiration.
|
18
|
+
* Configurable session timeout.
|
19
|
+
* Brute force login hammering protection.
|
20
|
+
* Modular design, load only the modules you need.
|
21
|
+
* 100% TDD'd code, 100% test coverage.
|
22
|
+
|
23
|
+
== Planned Features:
|
24
|
+
|
25
|
+
I've got many plans which include:
|
26
|
+
* Basic HTTP Authentication
|
27
|
+
* Auto login
|
28
|
+
* Hammering reset password protection
|
29
|
+
* Other reset password strategies (security questions?)
|
30
|
+
* Sinatra support
|
31
|
+
* Mongoid support
|
32
|
+
* OmniAuth integration
|
33
|
+
* Activity logging
|
34
|
+
* Have an idea? Let me know, and it might get into the gem!
|
35
|
+
|
36
|
+
== Project Goals:
|
37
|
+
|
38
|
+
This gem plugin was started out of a few personal goals which are not related to the problem solved by it at all:
|
39
|
+
* I wanted to write something 100% TDD from start to finish.
|
40
|
+
* I wanted to learn how to write an engine for Rails 3.
|
41
|
+
|
42
|
+
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:
|
43
|
+
* Simple & short configuration as possible, not drowning in syntactic sugar.
|
44
|
+
* Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
|
45
|
+
* Magic yes, Voodoo no.
|
46
|
+
* No generated code polluting the application's code.
|
47
|
+
* No built-in controllers, models, mailers, migrations or templates; Real apps will need all of these custom made.
|
48
|
+
|
49
|
+
Hopefully, I've achieved this. If not, let me know.
|
50
|
+
|
51
|
+
== Installation:
|
52
|
+
|
53
|
+
You can either git clone and then 'rake install',
|
54
|
+
|
55
|
+
In the future will be available:
|
56
|
+
|
57
|
+
gem install sorcery
|
58
|
+
|
59
|
+
== Configuration:
|
60
|
+
|
61
|
+
First add 'sorcery' to your Gemfile:
|
62
|
+
|
63
|
+
gem "sorcery"
|
64
|
+
|
65
|
+
And run
|
66
|
+
|
67
|
+
bundle install
|
68
|
+
|
69
|
+
There are 2 required places to configure the plugin, and an optional one:
|
70
|
+
1. config/application.rb
|
71
|
+
|
72
|
+
config.sorcery.submodules = [:user_activation, :remember_me] # add the modules you want to use
|
73
|
+
|
74
|
+
You can also configure here any controller and any controller-submodule option here.
|
75
|
+
For example:
|
76
|
+
|
77
|
+
config.sorcery.session_timeout = 10.minutes
|
78
|
+
|
79
|
+
|
80
|
+
2. app/models/user.rb (or another model of your choice)
|
81
|
+
|
82
|
+
activate_sorcery! do |config|
|
83
|
+
config.sorcery_mailer = MyMailer
|
84
|
+
config.username_attribute_name = :email
|
85
|
+
end
|
86
|
+
|
87
|
+
3. app/controllers/application_controller.rb (OPTIONAL: this is actually needed only in some cases)
|
88
|
+
|
89
|
+
activate_sorcery! do |config|
|
90
|
+
config.session_timeout = 10.minutes
|
91
|
+
end
|
92
|
+
|
93
|
+
Also check the migrations in the example app to see what database fields are expected.
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
The configuration options vary with the modules you've chosen to use.
|
98
|
+
|
99
|
+
== Basic Configuration (in Model):
|
100
|
+
|
101
|
+
see lib/sorcery/model.rb
|
102
|
+
|
103
|
+
== User Activation Configuration (in Model):
|
104
|
+
|
105
|
+
see lib/sorcery/model/submodules/user_activation.rb
|
106
|
+
|
107
|
+
== Remember Me Configuration (in Model):
|
108
|
+
|
109
|
+
see lib/sorcery/model/submodules/remember_me.rb
|
110
|
+
|
111
|
+
== Password Reset Configuration (in Model):
|
112
|
+
|
113
|
+
see lib/sorcery/model/submodules/password_reset.rb
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
== Session Timeout Configuration (in Controller or config/application.rb):
|
118
|
+
|
119
|
+
see lib/sorcery/controller/submodules/session_timeout.rb
|
120
|
+
|
121
|
+
== Brute Force Protection Configuration (in Controller or config/application.rb):
|
122
|
+
|
123
|
+
see lib/sorcery/controller/submodules/brute_force_protection.rb
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
== Contributing to sorcery
|
128
|
+
|
129
|
+
I can use help of any kind, be it comments on code (code review), suggestions, features, bug reports, bug fixes and even a donation.
|
130
|
+
|
131
|
+
== Contact
|
132
|
+
|
133
|
+
email: nbenari@gmail.com
|
134
|
+
|
135
|
+
== Copyright
|
136
|
+
|
137
|
+
Copyright (c) 2010 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for further details.
|
138
|
+
Released with permission from Kontera (http://www.kontera.com), where I work.
|
139
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# require 'bundler'
|
2
|
+
# begin
|
3
|
+
# Bundler.setup(:default, :development)
|
4
|
+
# rescue Bundler::BundlerError => e
|
5
|
+
# $stderr.puts e.message
|
6
|
+
# $stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
# exit e.status_code
|
8
|
+
# end
|
9
|
+
require 'rake'
|
10
|
+
|
11
|
+
require 'jeweler'
|
12
|
+
Jeweler::Tasks.new do |gem|
|
13
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
14
|
+
gem.name = "sorcery"
|
15
|
+
gem.homepage = "http://github.com/NoamB/sorcery"
|
16
|
+
gem.license = "MIT"
|
17
|
+
gem.summary = "Magical authentication for Rails 3 applications"
|
18
|
+
gem.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password."
|
19
|
+
gem.email = "nbenari@gmail.com"
|
20
|
+
gem.authors = ["Noam Ben Ari"]
|
21
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
22
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
23
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
24
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
35
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
36
|
+
spec.rcov = true
|
37
|
+
end
|
38
|
+
|
39
|
+
require 'cucumber/rake/task'
|
40
|
+
Cucumber::Rake::Task.new(:features)
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
require 'yard'
|
45
|
+
YARD::Rake::YardocTask.new
|
46
|
+
|
47
|
+
|
48
|
+
#task :default => :spec
|
49
|
+
desc 'Default: Run all specs.'
|
50
|
+
task :default => :all_specs
|
51
|
+
|
52
|
+
desc "Run all specs"
|
53
|
+
task :all_specs do
|
54
|
+
Dir['spec/**/Rakefile'].each do |rakefile|
|
55
|
+
directory_name = File.dirname(rakefile)
|
56
|
+
sh <<-CMD
|
57
|
+
cd #{directory_name}
|
58
|
+
bundle exec rake
|
59
|
+
CMD
|
60
|
+
end
|
61
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
begin
|
3
|
+
Bundler.setup(:default, :development)
|
4
|
+
rescue Bundler::BundlerError => e
|
5
|
+
$stderr.puts e.message
|
6
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
exit e.status_code
|
8
|
+
end
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
|
11
|
+
require 'sorcery'
|
12
|
+
|
13
|
+
require 'rspec/expectations'
|
data/lib/sorcery.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sorcery
|
2
|
+
autoload :Model, 'sorcery/model'
|
3
|
+
module Model
|
4
|
+
module Submodules
|
5
|
+
autoload :UserActivation, 'sorcery/model/submodules/user_activation'
|
6
|
+
autoload :PasswordReset, 'sorcery/model/submodules/password_reset'
|
7
|
+
autoload :RememberMe, 'sorcery/model/submodules/remember_me'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
autoload :Controller, 'sorcery/controller'
|
11
|
+
module Controller
|
12
|
+
module Submodules
|
13
|
+
autoload :RememberMe, 'sorcery/controller/submodules/remember_me'
|
14
|
+
autoload :SessionTimeout, 'sorcery/controller/submodules/session_timeout'
|
15
|
+
autoload :BruteForceProtection, 'sorcery/controller/submodules/brute_force_protection'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
module CryptoProviders
|
19
|
+
autoload :AES256, 'sorcery/crypto_providers/aes256'
|
20
|
+
autoload :BCrypt, 'sorcery/crypto_providers/bcrypt'
|
21
|
+
autoload :MD5, 'sorcery/crypto_providers/md5'
|
22
|
+
autoload :SHA1, 'sorcery/crypto_providers/sha1'
|
23
|
+
autoload :SHA256, 'sorcery/crypto_providers/sha256'
|
24
|
+
autoload :SHA512, 'sorcery/crypto_providers/sha512'
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'sorcery/engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
|
28
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module Sorcery
|
2
|
+
module Controller
|
3
|
+
def self.included(klass)
|
4
|
+
klass.class_eval do
|
5
|
+
extend ClassMethods
|
6
|
+
include InstanceMethods
|
7
|
+
Config.submodules.each do |mod|
|
8
|
+
begin
|
9
|
+
include Submodules.const_get(mod.to_s.split("_").map {|p| p.capitalize}.join(""))
|
10
|
+
rescue NameError
|
11
|
+
# don't stop on a missing submodule.
|
12
|
+
end
|
13
|
+
end
|
14
|
+
Config.update!
|
15
|
+
Config.user_class = User
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def activate_sorcery!(&block)
|
21
|
+
yield Config if block_given?
|
22
|
+
after_config!
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_config!
|
26
|
+
Config.after_config.each {|c| send(c)}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module InstanceMethods
|
31
|
+
# To be used as before_filter.
|
32
|
+
# Will trigger auto-login attempts via the call to logged_in?
|
33
|
+
# If all attempts to auto-login fail, the failure callback will be called.
|
34
|
+
def require_user_login
|
35
|
+
if !logged_in?
|
36
|
+
session[:user_wanted_url] = request.url if Config.save_user_wanted_url
|
37
|
+
self.send(Config.not_authenticated_action)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def login(*credentials)
|
42
|
+
user = Config.user_class.authenticate(*credentials)
|
43
|
+
if user
|
44
|
+
reset_session # protect from session fixation attacks
|
45
|
+
login_user(user)
|
46
|
+
after_login!(user, credentials)
|
47
|
+
logged_in_user
|
48
|
+
else
|
49
|
+
after_failed_login!(user, credentials)
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def logout
|
55
|
+
if logged_in?
|
56
|
+
reset_session
|
57
|
+
after_logout!
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def logged_in?
|
62
|
+
!!logged_in_user
|
63
|
+
end
|
64
|
+
|
65
|
+
# attempts to auto-login from the sources defined (session, basic_auth, cookie, etc.)
|
66
|
+
# returns the logged in user if found, false if not (using old restful-authentication trick).
|
67
|
+
def logged_in_user
|
68
|
+
@logged_in_user ||= login_from_session || login_from_other_sources unless @logged_in_user == false # || login_from_basic_auth || )
|
69
|
+
end
|
70
|
+
|
71
|
+
def login_from_other_sources
|
72
|
+
result = nil
|
73
|
+
Config.login_sources.find do |source|
|
74
|
+
result = send(source)
|
75
|
+
end
|
76
|
+
result || false
|
77
|
+
end
|
78
|
+
|
79
|
+
def not_authenticated
|
80
|
+
redirect_to root_path
|
81
|
+
end
|
82
|
+
|
83
|
+
protected
|
84
|
+
|
85
|
+
def login_user(user)
|
86
|
+
session[:user_id] = user.id
|
87
|
+
end
|
88
|
+
|
89
|
+
def login_from_session
|
90
|
+
@logged_in_user = (Config.user_class.find_by_id(session[:user_id]) if session[:user_id]) || false
|
91
|
+
end
|
92
|
+
|
93
|
+
def after_login!(user, credentials)
|
94
|
+
Config.after_login.each {|c| self.send(c, user, credentials)}
|
95
|
+
end
|
96
|
+
|
97
|
+
def after_failed_login!(user, credentials)
|
98
|
+
Config.after_failed_login.each {|c| self.send(c, user, credentials)}
|
99
|
+
end
|
100
|
+
|
101
|
+
def after_logout!
|
102
|
+
Config.after_logout.each {|c| self.send(c)}
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
module Config
|
108
|
+
class << self
|
109
|
+
attr_accessor :submodules,
|
110
|
+
|
111
|
+
:user_class, # what class to use as the user class.
|
112
|
+
|
113
|
+
:not_authenticated_action, # what controller action to call for non-authenticated users.
|
114
|
+
|
115
|
+
:save_user_wanted_url, # when a non logged in user tries to enter a page that requires login, save the URL he wanted to reach,
|
116
|
+
# and send him there after login.
|
117
|
+
|
118
|
+
:login_sources,
|
119
|
+
:after_login,
|
120
|
+
:after_failed_login,
|
121
|
+
:after_logout,
|
122
|
+
:after_config
|
123
|
+
|
124
|
+
|
125
|
+
def init!
|
126
|
+
@defaults = {
|
127
|
+
:@user_class => nil,
|
128
|
+
:@submodules => [],
|
129
|
+
:@not_authenticated_action => :not_authenticated,
|
130
|
+
:@login_sources => [],
|
131
|
+
:@after_login => [],
|
132
|
+
:@after_failed_login => [],
|
133
|
+
:@after_logout => [],
|
134
|
+
:@after_config => [],
|
135
|
+
:@save_user_wanted_url => true
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
# Resets all configuration options to their default values.
|
140
|
+
def reset!
|
141
|
+
@defaults.each do |k,v|
|
142
|
+
instance_variable_set(k,v)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def update!
|
147
|
+
@defaults.each do |k,v|
|
148
|
+
instance_variable_set(k,v) if !instance_variable_defined?(k)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
init!
|
153
|
+
reset!
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|