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.

Files changed (101) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +19 -0
  4. data/Gemfile.lock +129 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +139 -0
  7. data/Rakefile +61 -0
  8. data/VERSION +1 -0
  9. data/features/support/env.rb +13 -0
  10. data/lib/sorcery.rb +28 -0
  11. data/lib/sorcery/controller.rb +156 -0
  12. data/lib/sorcery/controller/submodules/brute_force_protection.rb +89 -0
  13. data/lib/sorcery/controller/submodules/remember_me.rb +43 -0
  14. data/lib/sorcery/controller/submodules/session_timeout.rb +42 -0
  15. data/lib/sorcery/crypto_providers/aes256.rb +44 -0
  16. data/lib/sorcery/crypto_providers/bcrypt.rb +96 -0
  17. data/lib/sorcery/crypto_providers/md5.rb +39 -0
  18. data/lib/sorcery/crypto_providers/sha1.rb +40 -0
  19. data/lib/sorcery/crypto_providers/sha256.rb +55 -0
  20. data/lib/sorcery/crypto_providers/sha512.rb +55 -0
  21. data/lib/sorcery/engine.rb +20 -0
  22. data/lib/sorcery/model.rb +175 -0
  23. data/lib/sorcery/model/submodules/password_reset.rb +64 -0
  24. data/lib/sorcery/model/submodules/remember_me.rb +42 -0
  25. data/lib/sorcery/model/submodules/user_activation.rb +84 -0
  26. data/spec/Gemfile +11 -0
  27. data/spec/Gemfile.lock +108 -0
  28. data/spec/Rakefile +11 -0
  29. data/spec/rails3/.rspec +1 -0
  30. data/spec/rails3/Gemfile +12 -0
  31. data/spec/rails3/Gemfile.lock +114 -0
  32. data/spec/rails3/Rakefile +10 -0
  33. data/spec/rails3/app_root/.gitignore +4 -0
  34. data/spec/rails3/app_root/README +256 -0
  35. data/spec/rails3/app_root/Rakefile.unused +7 -0
  36. data/spec/rails3/app_root/app/controllers/application_controller.rb +61 -0
  37. data/spec/rails3/app_root/app/helpers/application_helper.rb +2 -0
  38. data/spec/rails3/app_root/app/mailers/sorcery_mailer.rb +25 -0
  39. data/spec/rails3/app_root/app/models/user.rb +3 -0
  40. data/spec/rails3/app_root/app/views/layouts/application.html.erb +14 -0
  41. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.html.erb +17 -0
  42. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_email.text.erb +9 -0
  43. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.html.erb +17 -0
  44. data/spec/rails3/app_root/app/views/sorcery_mailer/activation_success_email.text.erb +9 -0
  45. data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.html.erb +16 -0
  46. data/spec/rails3/app_root/app/views/sorcery_mailer/reset_password_email.text.erb +8 -0
  47. data/spec/rails3/app_root/config.ru +4 -0
  48. data/spec/rails3/app_root/config/application.rb +48 -0
  49. data/spec/rails3/app_root/config/boot.rb +13 -0
  50. data/spec/rails3/app_root/config/database.yml +27 -0
  51. data/spec/rails3/app_root/config/environment.rb +5 -0
  52. data/spec/rails3/app_root/config/environments/development.rb +26 -0
  53. data/spec/rails3/app_root/config/environments/in_memory.rb +0 -0
  54. data/spec/rails3/app_root/config/environments/production.rb +49 -0
  55. data/spec/rails3/app_root/config/environments/test.rb +35 -0
  56. data/spec/rails3/app_root/config/initializers/backtrace_silencers.rb +7 -0
  57. data/spec/rails3/app_root/config/initializers/inflections.rb +10 -0
  58. data/spec/rails3/app_root/config/initializers/mime_types.rb +5 -0
  59. data/spec/rails3/app_root/config/initializers/secret_token.rb +7 -0
  60. data/spec/rails3/app_root/config/initializers/session_store.rb +8 -0
  61. data/spec/rails3/app_root/config/locales/en.yml +5 -0
  62. data/spec/rails3/app_root/config/routes.rb +67 -0
  63. data/spec/rails3/app_root/db/migrate/activation/20101224223622_add_activation_to_users.rb +15 -0
  64. data/spec/rails3/app_root/db/migrate/core/20101224223620_create_users.rb +16 -0
  65. data/spec/rails3/app_root/db/migrate/password_reset/20101224223622_add_password_reset_to_users.rb +9 -0
  66. data/spec/rails3/app_root/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  67. data/spec/rails3/app_root/db/schema.rb +23 -0
  68. data/spec/rails3/app_root/db/seeds.rb +7 -0
  69. data/spec/rails3/app_root/lib/tasks/.gitkeep +0 -0
  70. data/spec/rails3/app_root/public/404.html +26 -0
  71. data/spec/rails3/app_root/public/422.html +26 -0
  72. data/spec/rails3/app_root/public/500.html +26 -0
  73. data/spec/rails3/app_root/public/favicon.ico +0 -0
  74. data/spec/rails3/app_root/public/images/rails.png +0 -0
  75. data/spec/rails3/app_root/public/index.html +239 -0
  76. data/spec/rails3/app_root/public/javascripts/application.js +2 -0
  77. data/spec/rails3/app_root/public/javascripts/controls.js +965 -0
  78. data/spec/rails3/app_root/public/javascripts/dragdrop.js +974 -0
  79. data/spec/rails3/app_root/public/javascripts/effects.js +1123 -0
  80. data/spec/rails3/app_root/public/javascripts/prototype.js +6001 -0
  81. data/spec/rails3/app_root/public/javascripts/rails.js +175 -0
  82. data/spec/rails3/app_root/public/robots.txt +5 -0
  83. data/spec/rails3/app_root/public/stylesheets/.gitkeep +0 -0
  84. data/spec/rails3/app_root/script/rails +6 -0
  85. data/spec/rails3/app_root/test/fixtures/users.yml +9 -0
  86. data/spec/rails3/app_root/test/performance/browsing_test.rb +9 -0
  87. data/spec/rails3/app_root/test/test_helper.rb +13 -0
  88. data/spec/rails3/app_root/test/unit/user_test.rb +8 -0
  89. data/spec/rails3/app_root/vendor/plugins/.gitkeep +0 -0
  90. data/spec/rails3/controller_brute_force_protection_spec.rb +72 -0
  91. data/spec/rails3/controller_remember_me_spec.rb +65 -0
  92. data/spec/rails3/controller_session_timeout_spec.rb +49 -0
  93. data/spec/rails3/controller_spec.rb +115 -0
  94. data/spec/rails3/spec_helper.rb +115 -0
  95. data/spec/rails3/user_activation_spec.rb +148 -0
  96. data/spec/rails3/user_password_reset_spec.rb +76 -0
  97. data/spec/rails3/user_remember_me_spec.rb +66 -0
  98. data/spec/rails3/user_spec.rb +283 -0
  99. data/spec/sorcery_crypto_providers_spec.rb +182 -0
  100. data/spec/spec_helper.rb +18 -0
  101. metadata +341 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
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