sorcery 0.2.1 → 0.4.2

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.
Files changed (163) hide show
  1. data/Gemfile +3 -2
  2. data/Gemfile.lock +13 -11
  3. data/README.rdoc +157 -61
  4. data/Rakefile +4 -4
  5. data/VERSION +1 -1
  6. data/lib/generators/sorcery_migration/sorcery_migration_generator.rb +24 -0
  7. data/lib/generators/sorcery_migration/templates/activity_logging.rb +17 -0
  8. data/lib/generators/sorcery_migration/templates/brute_force_protection.rb +11 -0
  9. data/lib/generators/sorcery_migration/templates/core.rb +16 -0
  10. data/lib/generators/sorcery_migration/templates/external.rb +14 -0
  11. data/lib/generators/sorcery_migration/templates/remember_me.rb +15 -0
  12. data/lib/generators/sorcery_migration/templates/reset_password.rb +13 -0
  13. data/lib/generators/sorcery_migration/templates/user_activation.rb +17 -0
  14. data/lib/sorcery/controller/adapters/sinatra.rb +97 -0
  15. data/lib/sorcery/controller/submodules/external/protocols/oauth1.rb +35 -0
  16. data/lib/sorcery/controller/submodules/external/protocols/oauth2.rb +26 -0
  17. data/lib/sorcery/controller/submodules/{oauth → external}/providers/facebook.rb +24 -6
  18. data/lib/sorcery/controller/submodules/{oauth → external}/providers/twitter.rb +31 -6
  19. data/lib/sorcery/controller/submodules/{oauth.rb → external.rb} +18 -27
  20. data/lib/sorcery/controller/submodules/http_basic_auth.rb +11 -7
  21. data/lib/sorcery/controller.rb +21 -21
  22. data/lib/sorcery/crypto_providers/bcrypt.rb +3 -5
  23. data/lib/sorcery/crypto_providers/common.rb +35 -0
  24. data/lib/sorcery/crypto_providers/md5.rb +3 -23
  25. data/lib/sorcery/crypto_providers/sha1.rb +4 -16
  26. data/lib/sorcery/crypto_providers/sha256.rb +3 -23
  27. data/lib/sorcery/crypto_providers/sha512.rb +3 -23
  28. data/lib/sorcery/engine.rb +4 -0
  29. data/lib/sorcery/initializers/initializer.rb +86 -0
  30. data/lib/sorcery/model/submodules/activity_logging.rb +2 -2
  31. data/lib/sorcery/model/submodules/brute_force_protection.rb +1 -5
  32. data/lib/sorcery/model/submodules/{oauth.rb → external.rb} +3 -3
  33. data/lib/sorcery/model/submodules/reset_password.rb +1 -1
  34. data/lib/sorcery/model.rb +34 -9
  35. data/lib/sorcery/railties/tasks.rake +10 -0
  36. data/lib/sorcery/sinatra.rb +5 -0
  37. data/lib/sorcery/test_helpers/internal/rails.rb +52 -0
  38. data/lib/sorcery/test_helpers/internal/sinatra.rb +122 -0
  39. data/lib/sorcery/test_helpers/internal.rb +55 -0
  40. data/lib/sorcery/test_helpers/rails.rb +16 -0
  41. data/lib/sorcery/test_helpers/sinatra.rb +85 -0
  42. data/lib/sorcery/test_helpers.rb +0 -79
  43. data/lib/sorcery.rb +25 -7
  44. data/sorcery.gemspec +207 -137
  45. data/spec/Gemfile +2 -2
  46. data/spec/Gemfile.lock +20 -12
  47. data/spec/Rakefile +1 -0
  48. data/spec/rails3/.rspec +1 -1
  49. data/spec/rails3/{app_root/Gemfile → Gemfile} +5 -7
  50. data/spec/rails3/{app_root/Gemfile.lock → Gemfile.lock} +20 -23
  51. data/spec/rails3/{app_root/Rakefile → Rakefile} +1 -0
  52. data/spec/rails3/{app_root/app → app}/controllers/application_controller.rb +11 -11
  53. data/spec/rails3/config/database.yml +27 -0
  54. data/spec/rails3/{app_root/spec → spec}/controller_activity_logging_spec.rb +2 -4
  55. data/spec/rails3/{app_root/spec → spec}/controller_brute_force_protection_spec.rb +3 -2
  56. data/spec/rails3/{app_root/spec → spec}/controller_oauth2_spec.rb +25 -22
  57. data/spec/rails3/{app_root/spec → spec}/controller_oauth_spec.rb +24 -19
  58. data/spec/rails3/spec/controller_session_timeout_spec.rb +55 -0
  59. data/spec/rails3/{app_root/spec → spec}/controller_spec.rb +6 -16
  60. data/spec/rails3/spec/spec.opts +2 -0
  61. data/spec/rails3/spec/spec_helper.rb +70 -0
  62. data/spec/rails3/{app_root/spec → spec}/user_activation_spec.rb +7 -13
  63. data/spec/rails3/{app_root/spec → spec}/user_brute_force_protection_spec.rb +2 -30
  64. data/spec/rails3/{app_root/spec → spec}/user_oauth_spec.rb +7 -7
  65. data/spec/rails3/{app_root/spec → spec}/user_remember_me_spec.rb +3 -11
  66. data/spec/rails3/{app_root/spec → spec}/user_reset_password_spec.rb +20 -17
  67. data/spec/rails3/{app_root/spec → spec}/user_spec.rb +21 -11
  68. data/spec/sinatra/Gemfile +12 -0
  69. data/spec/sinatra/Gemfile.lock +134 -0
  70. data/spec/sinatra/Rakefile +11 -0
  71. data/spec/sinatra/authentication.rb +3 -0
  72. data/spec/sinatra/db/migrate/activation/20101224223622_add_activation_to_users.rb +17 -0
  73. data/spec/sinatra/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +17 -0
  74. data/spec/sinatra/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +11 -0
  75. data/spec/sinatra/db/migrate/core/20101224223620_create_users.rb +16 -0
  76. data/spec/sinatra/db/migrate/external/20101224223628_create_authentications.rb +14 -0
  77. data/spec/sinatra/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +15 -0
  78. data/spec/sinatra/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +13 -0
  79. data/spec/sinatra/filters.rb +21 -0
  80. data/spec/sinatra/myapp.rb +133 -0
  81. data/spec/sinatra/sorcery_mailer.rb +25 -0
  82. data/spec/sinatra/spec/controller_activity_logging_spec.rb +85 -0
  83. data/spec/sinatra/spec/controller_brute_force_protection_spec.rb +70 -0
  84. data/spec/sinatra/spec/controller_http_basic_auth_spec.rb +53 -0
  85. data/spec/sinatra/spec/controller_oauth2_spec.rb +120 -0
  86. data/spec/sinatra/spec/controller_oauth_spec.rb +121 -0
  87. data/spec/sinatra/spec/controller_remember_me_spec.rb +64 -0
  88. data/spec/sinatra/spec/controller_session_timeout_spec.rb +57 -0
  89. data/spec/sinatra/spec/controller_spec.rb +120 -0
  90. data/spec/sinatra/spec/spec.opts +2 -0
  91. data/spec/sinatra/spec/spec_helper.rb +46 -0
  92. data/spec/sinatra/user.rb +6 -0
  93. data/spec/sinatra/views/test_login.erb +4 -0
  94. data/spec/sorcery_crypto_providers_spec.rb +5 -4
  95. data/spec/spec.opts +2 -0
  96. data/spec/spec_helper.rb +3 -4
  97. data/spec/untitled folder +18 -0
  98. metadata +217 -139
  99. data/lib/sorcery/controller/submodules/oauth/oauth1.rb +0 -26
  100. data/lib/sorcery/controller/submodules/oauth/oauth2.rb +0 -24
  101. data/spec/rails3/app_root/.rspec +0 -1
  102. data/spec/rails3/app_root/config/database.yml +0 -27
  103. data/spec/rails3/app_root/spec/controller_session_timeout_spec.rb +0 -50
  104. data/spec/rails3/app_root/spec/spec_helper.rb +0 -61
  105. /data/spec/rails3/{app_root/.gitignore → .gitignore} +0 -0
  106. /data/spec/rails3/{app_root/README → README} +0 -0
  107. /data/spec/rails3/{app_root/Rakefile.unused → Rakefile.unused} +0 -0
  108. /data/spec/rails3/{app_root/app → app}/helpers/application_helper.rb +0 -0
  109. /data/spec/rails3/{app_root/app → app}/mailers/sorcery_mailer.rb +0 -0
  110. /data/spec/rails3/{app_root/app → app}/models/authentication.rb +0 -0
  111. /data/spec/rails3/{app_root/app → app}/models/user.rb +0 -0
  112. /data/spec/rails3/{app_root/app → app}/views/layouts/application.html.erb +0 -0
  113. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.html.erb +0 -0
  114. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_email.text.erb +0 -0
  115. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.html.erb +0 -0
  116. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/activation_success_email.text.erb +0 -0
  117. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.html.erb +0 -0
  118. /data/spec/rails3/{app_root/app → app}/views/sorcery_mailer/reset_password_email.text.erb +0 -0
  119. /data/spec/rails3/{app_root/config → config}/application.rb +0 -0
  120. /data/spec/rails3/{app_root/config → config}/boot.rb +0 -0
  121. /data/spec/rails3/{app_root/config → config}/environment.rb +0 -0
  122. /data/spec/rails3/{app_root/config → config}/environments/development.rb +0 -0
  123. /data/spec/rails3/{app_root/config → config}/environments/in_memory.rb +0 -0
  124. /data/spec/rails3/{app_root/config → config}/environments/production.rb +0 -0
  125. /data/spec/rails3/{app_root/config → config}/environments/test.rb +0 -0
  126. /data/spec/rails3/{app_root/config → config}/initializers/backtrace_silencers.rb +0 -0
  127. /data/spec/rails3/{app_root/config → config}/initializers/inflections.rb +0 -0
  128. /data/spec/rails3/{app_root/config → config}/initializers/mime_types.rb +0 -0
  129. /data/spec/rails3/{app_root/config → config}/initializers/secret_token.rb +0 -0
  130. /data/spec/rails3/{app_root/config → config}/initializers/session_store.rb +0 -0
  131. /data/spec/rails3/{app_root/config → config}/locales/en.yml +0 -0
  132. /data/spec/rails3/{app_root/config → config}/routes.rb +0 -0
  133. /data/spec/rails3/{app_root/config.ru → config.ru} +0 -0
  134. /data/spec/rails3/{app_root/db → db}/migrate/activation/20101224223622_add_activation_to_users.rb +0 -0
  135. /data/spec/rails3/{app_root/db → db}/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +0 -0
  136. /data/spec/rails3/{app_root/db → db}/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +0 -0
  137. /data/spec/rails3/{app_root/db → db}/migrate/core/20101224223620_create_users.rb +0 -0
  138. /data/spec/rails3/{app_root/db/migrate/oauth → db/migrate/external}/20101224223628_create_authentications.rb +0 -0
  139. /data/spec/rails3/{app_root/db → db}/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +0 -0
  140. /data/spec/rails3/{app_root/db → db}/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +0 -0
  141. /data/spec/rails3/{app_root/db → db}/schema.rb +0 -0
  142. /data/spec/rails3/{app_root/db → db}/seeds.rb +0 -0
  143. /data/spec/rails3/{app_root/lib → lib}/tasks/.gitkeep +0 -0
  144. /data/spec/rails3/{app_root/public → public}/404.html +0 -0
  145. /data/spec/rails3/{app_root/public → public}/422.html +0 -0
  146. /data/spec/rails3/{app_root/public → public}/500.html +0 -0
  147. /data/spec/rails3/{app_root/public → public}/favicon.ico +0 -0
  148. /data/spec/rails3/{app_root/public → public}/images/rails.png +0 -0
  149. /data/spec/rails3/{app_root/public → public}/index.html +0 -0
  150. /data/spec/rails3/{app_root/public → public}/javascripts/application.js +0 -0
  151. /data/spec/rails3/{app_root/public → public}/javascripts/controls.js +0 -0
  152. /data/spec/rails3/{app_root/public → public}/javascripts/dragdrop.js +0 -0
  153. /data/spec/rails3/{app_root/public → public}/javascripts/effects.js +0 -0
  154. /data/spec/rails3/{app_root/public → public}/javascripts/prototype.js +0 -0
  155. /data/spec/rails3/{app_root/public → public}/javascripts/rails.js +0 -0
  156. /data/spec/rails3/{app_root/public → public}/robots.txt +0 -0
  157. /data/spec/rails3/{app_root/public → public}/stylesheets/.gitkeep +0 -0
  158. /data/spec/rails3/{app_root/script → script}/rails +0 -0
  159. /data/spec/rails3/{app_root/spec → spec}/controller_http_basic_auth_spec.rb +0 -0
  160. /data/spec/rails3/{app_root/spec → spec}/controller_remember_me_spec.rb +0 -0
  161. /data/spec/rails3/{app_root/spec → spec}/spec_helper.orig.rb +0 -0
  162. /data/spec/rails3/{app_root/spec → spec}/user_activity_logging_spec.rb +0 -0
  163. /data/spec/rails3/{app_root/vendor → vendor}/plugins/.gitkeep +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.3.0"
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.3.0)
85
- rspec-core (~> 2.3.0)
86
- rspec-expectations (~> 2.3.0)
87
- rspec-mocks (~> 2.3.0)
88
- rspec-core (2.3.1)
89
- rspec-expectations (2.3.0)
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.3.0)
92
- rspec-rails (2.3.1)
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.3.0)
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.3.0)
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
@@ -1,34 +1,151 @@
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.
6
+ OAuth code inspired by OmniAuth and Ryan Bates's railscasts about it.
7
7
 
8
- == Summary
9
8
 
10
- Sorcery aims to make your life easier by giving you an easy API to write your own user authentication flow with.
11
- It does this with a few goals in mind:
9
+ == Philosophy
12
10
 
13
- * Less is more - less than 20 simple methods to remember for the entire feature-set make the lib easy to 'get'.
14
- * No built-in or generated code - use the API inside *your own* MVC structures, and don't fight to fix someone else's.
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.
15
17
  * Magic yes, Voodoo no - the lib should be easy to hack for most developers.
16
18
  * Configuration over Confusion - Simple & short configuration as possible, not drowning in syntactic sugar.
17
19
  * Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions.
18
20
 
19
21
  Hopefully, I've achieved this. If not, let me know.
20
22
 
23
+
21
24
  == Useful Links:
22
25
 
23
- Example app using sorcery: https://github.com/NoamB/sorcery-example-app
24
26
 
25
- Documentation: http://rubydoc.info/gems/sorcery/0.2.0/frames
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.4.2/frames
26
32
 
27
33
  Check out the tutorials in the github wiki!
28
34
 
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
+
78
+ == Installation:
79
+
80
+
81
+ If using bundler, first add 'sorcery' to your Gemfile:
82
+
83
+ gem "sorcery"
84
+
85
+ And run
86
+
87
+ bundle install
88
+
89
+ Otherwise simply
90
+
91
+ gem install sorcery
92
+
93
+
94
+ == Rails 3 Configuration:
95
+
96
+
97
+ For Rails 3 create an initializer file using:
98
+
99
+ rake sorcery:bootstrap
100
+
101
+ This will create the file as config/initializers/sorcery.rb .
102
+ Inside it the comments will tell you everything you need to know.
103
+
104
+ For your convenience, Sorcery includes a migrations generator for Rails, which can be used like so:
105
+
106
+ rails g sorcery_migration [list of submodules]
107
+
108
+ For example, for only the core functionality use:
109
+
110
+ rails g sorcery_migration core
111
+
112
+ To generate migrations for both the core AND 'remember_me' submodule:
113
+
114
+ rails g sorcery_migration core remember_me
115
+
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.
117
+
118
+
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:
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
138
+
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
143
+
144
+
29
145
  == Full Features List by module:
30
146
 
31
- Core (see lib/sorcery/model/model.rb and lib/sorcery/controller/controller.rb):
147
+
148
+ Core (see lib/sorcery/model.rb and lib/sorcery/controller.rb):
32
149
  * login/logout, optional return user to requested url on login, configurable redirect for non-logged-in users.
33
150
  * password encryption, algorithms: bcrypt(default), md5, sha1, sha256, sha512, aes256, custom(yours!), none. Configurable stretches and salt.
34
151
  * configurable attribute names for username, password and email.
@@ -68,88 +185,67 @@ Activity Logging (see lib/sorcery/model/submodules/activity_logging.rb):
68
185
  * an easy method of collecting the list of currently logged in users.
69
186
  * configurable timeout by which to decide whether to include a user in the list of logged in users.
70
187
 
71
- Oauth (see lib/sorcery/controller/submodules/oauth.rb):
188
+ External (see lib/sorcery/controller/submodules/external.rb):
72
189
  * OAuth1 and OAuth2 support (currently twitter & facebook)
73
190
  * configurable db field names and authentications table.
74
191
 
192
+
75
193
  == Next Planned Features:
76
194
 
195
+
77
196
  I've got many plans which include (by priority):
78
- * Sinatra support
197
+ * Forgot username, maybe as part of the reset_password module
198
+ * Scoping logins (to a subdomain or another arbitrary field)
79
199
  * Mongoid support
80
- * Configurable Auto login on registration/activation
81
200
  * Other reset password strategies (security questions?)
82
201
  * Other brute force protection strategies (captcha)
83
202
  * Have an idea? Let me know, and it might get into the gem!
84
203
 
85
- == Installation:
86
-
87
- You can either git clone and then 'rake install' to live on the edge (unstable),
88
-
89
- Or simply (stable):
90
-
91
- gem install sorcery
92
-
93
- == Configuration:
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
94
209
 
95
- First add 'sorcery' to your Gemfile:
96
-
97
- gem "sorcery"
98
-
99
- And run
100
-
101
- bundle install
102
-
103
- There are 2 required places to configure the plugin, and an optional one:
104
- 1. config/application.rb
105
-
106
- config.sorcery.submodules = [:user_activation, :remember_me] # add the modules you want to use
107
-
108
- You can also configure here any controller and any controller-submodule option here.
109
- For example:
110
-
111
- config.sorcery.session_timeout = 10.minutes
112
210
 
211
+ == Backward compatibility
113
212
 
114
- 2. app/models/user.rb (or another model of your choice)
115
213
 
116
- activate_sorcery! do |config|
117
- config.user_activation_mailer = MyMailer
118
- config.username_attribute_name = :email
119
- end
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.
120
218
 
121
- 3. app/controllers/application_controller.rb (OPTIONAL: this is actually needed only in some cases)
122
-
123
- activate_sorcery! do |config|
124
- config.session_timeout = 10.minutes
125
- end
126
-
127
- Also check the migrations in the example app to see what database fields are expected.
128
-
129
- The configuration options vary with the modules you've chosen to use.
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.
130
221
 
131
222
 
132
223
  == Contributing to sorcery
133
224
 
225
+
134
226
  Your feedback is very welcome and will make this gem much much better for you, me and everyone else.
135
227
  Besides feedback on code, features, suggestions and bug reports, you may want to actually make an impact on the code.
136
228
  For this:
137
229
 
138
- * Fork the project.
139
- * Make your feature addition or bug fix.
140
- * Add tests for it. This is important so I don’t break it in a future version unintentionally.
141
- * 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)
142
- * Send me a pull request. Bonus points for topic branches.
230
+ * Fork it.
231
+ * Fix it.
232
+ * Test it.
233
+ * Commit it.
234
+ * Send me a pull request so I'll... Pull it.
235
+
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.
143
237
 
144
- 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.
145
238
 
146
239
  == Contact
147
240
 
241
+
242
+ Feel free to ask questions using these contact details:
243
+
148
244
  email: nbenari@gmail.com ( also for paypal )
149
245
  twitter: @nbenari
150
246
 
247
+
151
248
  == Copyright
152
249
 
153
- Copyright (c) 2010 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for further details.
154
- Released with permission from Kontera (http://www.kontera.com), where I work.
155
250
 
251
+ Copyright (c) 2010 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for further details.
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 => :all_specs
44
+ desc 'Default: Run all sorcery specs.'
45
+ task :default => :all_sorcery_specs
46
46
 
47
- desc "Run all specs"
48
- task :all_specs do
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.2.1
1
+ 0.4.2
@@ -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 # 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
+ 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 SorceryExternal < 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
@@ -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