deviseOne 1.0.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.
Files changed (246) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +38 -0
  4. data/.yardopts +9 -0
  5. data/CHANGELOG.md +1117 -0
  6. data/CONTRIBUTING.md +14 -0
  7. data/Gemfile +29 -0
  8. data/Gemfile.lock +199 -0
  9. data/MIT-LICENSE +20 -0
  10. data/README.md +529 -0
  11. data/Rakefile +35 -0
  12. data/app/controllers/devise/confirmations_controller.rb +47 -0
  13. data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
  14. data/app/controllers/devise/passwords_controller.rb +71 -0
  15. data/app/controllers/devise/registrations_controller.rb +143 -0
  16. data/app/controllers/devise/sessions_controller.rb +166 -0
  17. data/app/controllers/devise/unlocks_controller.rb +46 -0
  18. data/app/controllers/devise_controller.rb +193 -0
  19. data/app/helpers/devise_helper.rb +25 -0
  20. data/app/mailers/devise/mailer.rb +20 -0
  21. data/app/views/devise/confirmations/new.html.erb +16 -0
  22. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  23. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  24. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  25. data/app/views/devise/passwords/edit.html.erb +25 -0
  26. data/app/views/devise/passwords/new.html.erb +16 -0
  27. data/app/views/devise/registrations/edit.html.erb +39 -0
  28. data/app/views/devise/registrations/new.html.erb +29 -0
  29. data/app/views/devise/sessions/new.html.erb +27 -0
  30. data/app/views/devise/shared/_links.html.erb +21 -0
  31. data/app/views/devise/unlocks/new.html.erb +16 -0
  32. data/config/locales/en.yml +70 -0
  33. data/devise.gemspec +33 -0
  34. data/devise.png +0 -0
  35. data/gemfiles/Gemfile.rails-3.2-stable +29 -0
  36. data/gemfiles/Gemfile.rails-3.2-stable.lock +169 -0
  37. data/gemfiles/Gemfile.rails-4.0-stable +29 -0
  38. data/gemfiles/Gemfile.rails-4.0-stable.lock +165 -0
  39. data/gemfiles/Gemfile.rails-4.1-stable +29 -0
  40. data/gemfiles/Gemfile.rails-4.1-stable.lock +170 -0
  41. data/lib/devise.rb +499 -0
  42. data/lib/devise/controllers/helpers.rb +284 -0
  43. data/lib/devise/controllers/rememberable.rb +47 -0
  44. data/lib/devise/controllers/scoped_views.rb +17 -0
  45. data/lib/devise/controllers/sign_in_out.rb +102 -0
  46. data/lib/devise/controllers/store_location.rb +58 -0
  47. data/lib/devise/controllers/url_helpers.rb +69 -0
  48. data/lib/devise/delegator.rb +16 -0
  49. data/lib/devise/failure_app.rb +212 -0
  50. data/lib/devise/hooks/activatable.rb +10 -0
  51. data/lib/devise/hooks/csrf_cleaner.rb +7 -0
  52. data/lib/devise/hooks/forgetable.rb +9 -0
  53. data/lib/devise/hooks/lockable.rb +7 -0
  54. data/lib/devise/hooks/proxy.rb +21 -0
  55. data/lib/devise/hooks/rememberable.rb +7 -0
  56. data/lib/devise/hooks/timeoutable.rb +35 -0
  57. data/lib/devise/hooks/trackable.rb +9 -0
  58. data/lib/devise/mailers/helpers.rb +90 -0
  59. data/lib/devise/mapping.rb +175 -0
  60. data/lib/devise/models.rb +119 -0
  61. data/lib/devise/models/authenticatable.rb +290 -0
  62. data/lib/devise/models/confirmable.rb +305 -0
  63. data/lib/devise/models/database_authenticatable.rb +164 -0
  64. data/lib/devise/models/lockable.rb +196 -0
  65. data/lib/devise/models/omniauthable.rb +27 -0
  66. data/lib/devise/models/recoverable.rb +157 -0
  67. data/lib/devise/models/registerable.rb +25 -0
  68. data/lib/devise/models/rememberable.rb +142 -0
  69. data/lib/devise/models/timeoutable.rb +49 -0
  70. data/lib/devise/models/trackable.rb +38 -0
  71. data/lib/devise/models/validatable.rb +66 -0
  72. data/lib/devise/modules.rb +28 -0
  73. data/lib/devise/omniauth.rb +28 -0
  74. data/lib/devise/omniauth/config.rb +45 -0
  75. data/lib/devise/omniauth/url_helpers.rb +18 -0
  76. data/lib/devise/orm/active_record.rb +3 -0
  77. data/lib/devise/orm/mongoid.rb +3 -0
  78. data/lib/devise/parameter_filter.rb +40 -0
  79. data/lib/devise/parameter_sanitizer.rb +99 -0
  80. data/lib/devise/rails.rb +56 -0
  81. data/lib/devise/rails/routes.rb +495 -0
  82. data/lib/devise/rails/warden_compat.rb +22 -0
  83. data/lib/devise/strategies/authenticatable.rb +173 -0
  84. data/lib/devise/strategies/base.rb +20 -0
  85. data/lib/devise/strategies/database_authenticatable.rb +24 -0
  86. data/lib/devise/strategies/rememberable.rb +59 -0
  87. data/lib/devise/test_helpers.rb +132 -0
  88. data/lib/devise/time_inflector.rb +14 -0
  89. data/lib/devise/token_generator.rb +70 -0
  90. data/lib/devise/version.rb +3 -0
  91. data/lib/generators/active_record/devise_generator.rb +91 -0
  92. data/lib/generators/active_record/templates/migration.rb +18 -0
  93. data/lib/generators/active_record/templates/migration_existing.rb +25 -0
  94. data/lib/generators/devise/controllers_generator.rb +44 -0
  95. data/lib/generators/devise/devise_generator.rb +26 -0
  96. data/lib/generators/devise/install_generator.rb +29 -0
  97. data/lib/generators/devise/orm_helpers.rb +51 -0
  98. data/lib/generators/devise/views_generator.rb +135 -0
  99. data/lib/generators/mongoid/devise_generator.rb +55 -0
  100. data/lib/generators/templates/README +35 -0
  101. data/lib/generators/templates/controllers/README +14 -0
  102. data/lib/generators/templates/controllers/confirmations_controller.rb +28 -0
  103. data/lib/generators/templates/controllers/omniauth_callbacks_controller.rb +28 -0
  104. data/lib/generators/templates/controllers/passwords_controller.rb +32 -0
  105. data/lib/generators/templates/controllers/registrations_controller.rb +60 -0
  106. data/lib/generators/templates/controllers/sessions_controller.rb +25 -0
  107. data/lib/generators/templates/controllers/unlocks_controller.rb +28 -0
  108. data/lib/generators/templates/devise.rb +263 -0
  109. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  110. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  111. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  112. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +16 -0
  113. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  114. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  115. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +27 -0
  116. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  117. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  118. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +16 -0
  119. data/script/cached-bundle +49 -0
  120. data/script/s3-put +71 -0
  121. data/test/controllers/custom_registrations_controller_test.rb +35 -0
  122. data/test/controllers/custom_strategy_test.rb +62 -0
  123. data/test/controllers/helpers_test.rb +316 -0
  124. data/test/controllers/internal_helpers_test.rb +129 -0
  125. data/test/controllers/load_hooks_controller_test.rb +19 -0
  126. data/test/controllers/passwords_controller_test.rb +31 -0
  127. data/test/controllers/sessions_controller_test.rb +102 -0
  128. data/test/controllers/url_helpers_test.rb +65 -0
  129. data/test/delegator_test.rb +19 -0
  130. data/test/devise_test.rb +107 -0
  131. data/test/failure_app_test.rb +275 -0
  132. data/test/generators/active_record_generator_test.rb +109 -0
  133. data/test/generators/controllers_generator_test.rb +48 -0
  134. data/test/generators/devise_generator_test.rb +39 -0
  135. data/test/generators/install_generator_test.rb +13 -0
  136. data/test/generators/mongoid_generator_test.rb +23 -0
  137. data/test/generators/views_generator_test.rb +96 -0
  138. data/test/helpers/devise_helper_test.rb +49 -0
  139. data/test/integration/authenticatable_test.rb +731 -0
  140. data/test/integration/confirmable_test.rb +324 -0
  141. data/test/integration/database_authenticatable_test.rb +94 -0
  142. data/test/integration/http_authenticatable_test.rb +105 -0
  143. data/test/integration/lockable_test.rb +239 -0
  144. data/test/integration/omniauthable_test.rb +133 -0
  145. data/test/integration/recoverable_test.rb +334 -0
  146. data/test/integration/registerable_test.rb +361 -0
  147. data/test/integration/rememberable_test.rb +176 -0
  148. data/test/integration/timeoutable_test.rb +189 -0
  149. data/test/integration/trackable_test.rb +92 -0
  150. data/test/mailers/confirmation_instructions_test.rb +115 -0
  151. data/test/mailers/reset_password_instructions_test.rb +96 -0
  152. data/test/mailers/unlock_instructions_test.rb +91 -0
  153. data/test/mapping_test.rb +128 -0
  154. data/test/models/authenticatable_test.rb +23 -0
  155. data/test/models/confirmable_test.rb +461 -0
  156. data/test/models/database_authenticatable_test.rb +249 -0
  157. data/test/models/lockable_test.rb +328 -0
  158. data/test/models/omniauthable_test.rb +7 -0
  159. data/test/models/recoverable_test.rb +205 -0
  160. data/test/models/registerable_test.rb +7 -0
  161. data/test/models/rememberable_test.rb +198 -0
  162. data/test/models/serializable_test.rb +49 -0
  163. data/test/models/timeoutable_test.rb +51 -0
  164. data/test/models/trackable_test.rb +41 -0
  165. data/test/models/validatable_test.rb +127 -0
  166. data/test/models_test.rb +144 -0
  167. data/test/omniauth/config_test.rb +57 -0
  168. data/test/omniauth/url_helpers_test.rb +54 -0
  169. data/test/orm/active_record.rb +10 -0
  170. data/test/orm/mongoid.rb +13 -0
  171. data/test/parameter_sanitizer_test.rb +81 -0
  172. data/test/rails_app/Rakefile +6 -0
  173. data/test/rails_app/app/active_record/admin.rb +6 -0
  174. data/test/rails_app/app/active_record/shim.rb +2 -0
  175. data/test/rails_app/app/active_record/user.rb +6 -0
  176. data/test/rails_app/app/active_record/user_on_engine.rb +7 -0
  177. data/test/rails_app/app/active_record/user_on_main_app.rb +7 -0
  178. data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
  179. data/test/rails_app/app/controllers/admins_controller.rb +11 -0
  180. data/test/rails_app/app/controllers/application_controller.rb +12 -0
  181. data/test/rails_app/app/controllers/application_with_fake_engine.rb +30 -0
  182. data/test/rails_app/app/controllers/custom/registrations_controller.rb +21 -0
  183. data/test/rails_app/app/controllers/home_controller.rb +25 -0
  184. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
  185. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
  186. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
  187. data/test/rails_app/app/controllers/users_controller.rb +31 -0
  188. data/test/rails_app/app/helpers/application_helper.rb +3 -0
  189. data/test/rails_app/app/mailers/users/from_proc_mailer.rb +3 -0
  190. data/test/rails_app/app/mailers/users/mailer.rb +3 -0
  191. data/test/rails_app/app/mailers/users/reply_to_mailer.rb +4 -0
  192. data/test/rails_app/app/mongoid/admin.rb +29 -0
  193. data/test/rails_app/app/mongoid/shim.rb +23 -0
  194. data/test/rails_app/app/mongoid/user.rb +39 -0
  195. data/test/rails_app/app/mongoid/user_on_engine.rb +39 -0
  196. data/test/rails_app/app/mongoid/user_on_main_app.rb +39 -0
  197. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  198. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  199. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  200. data/test/rails_app/app/views/home/index.html.erb +1 -0
  201. data/test/rails_app/app/views/home/join.html.erb +1 -0
  202. data/test/rails_app/app/views/home/private.html.erb +1 -0
  203. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  204. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  205. data/test/rails_app/app/views/users/edit_form.html.erb +1 -0
  206. data/test/rails_app/app/views/users/index.html.erb +1 -0
  207. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  208. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  209. data/test/rails_app/bin/bundle +3 -0
  210. data/test/rails_app/bin/rails +4 -0
  211. data/test/rails_app/bin/rake +4 -0
  212. data/test/rails_app/config.ru +4 -0
  213. data/test/rails_app/config/application.rb +40 -0
  214. data/test/rails_app/config/boot.rb +14 -0
  215. data/test/rails_app/config/database.yml +18 -0
  216. data/test/rails_app/config/environment.rb +5 -0
  217. data/test/rails_app/config/environments/development.rb +30 -0
  218. data/test/rails_app/config/environments/production.rb +80 -0
  219. data/test/rails_app/config/environments/test.rb +36 -0
  220. data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  221. data/test/rails_app/config/initializers/devise.rb +180 -0
  222. data/test/rails_app/config/initializers/inflections.rb +2 -0
  223. data/test/rails_app/config/initializers/secret_token.rb +8 -0
  224. data/test/rails_app/config/initializers/session_store.rb +1 -0
  225. data/test/rails_app/config/routes.rb +122 -0
  226. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +71 -0
  227. data/test/rails_app/db/schema.rb +55 -0
  228. data/test/rails_app/lib/shared_admin.rb +17 -0
  229. data/test/rails_app/lib/shared_user.rb +29 -0
  230. data/test/rails_app/lib/shared_user_without_omniauth.rb +13 -0
  231. data/test/rails_app/public/404.html +26 -0
  232. data/test/rails_app/public/422.html +26 -0
  233. data/test/rails_app/public/500.html +26 -0
  234. data/test/rails_app/public/favicon.ico +0 -0
  235. data/test/routes_test.rb +264 -0
  236. data/test/support/action_controller/record_identifier.rb +10 -0
  237. data/test/support/assertions.rb +39 -0
  238. data/test/support/helpers.rb +73 -0
  239. data/test/support/integration.rb +92 -0
  240. data/test/support/locale/en.yml +8 -0
  241. data/test/support/mongoid.yml +6 -0
  242. data/test/support/webrat/integrations/rails.rb +24 -0
  243. data/test/test_helper.rb +34 -0
  244. data/test/test_helpers_test.rb +163 -0
  245. data/test/test_models.rb +33 -0
  246. metadata +531 -0
@@ -0,0 +1,5 @@
1
+ Welcome <%= @email %>!
2
+
3
+ You can confirm your account through the link below:
4
+
5
+ <%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
@@ -0,0 +1,8 @@
1
+ Hello <%= @resource.email %>!
2
+
3
+ Someone has requested a link to change your password, and you can do this through the link below.
4
+
5
+ <%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
6
+
7
+ If you didn't request this, please ignore this email.
8
+ Your password won't change until you access the link above and create a new one.
@@ -0,0 +1,7 @@
1
+ Hello <%= @resource.email %>!
2
+
3
+ Your account has been locked due to an excessive number of unsuccessful sign in attempts.
4
+
5
+ Click the link below to unlock your account:
6
+
7
+ <%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
@@ -0,0 +1,16 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+ <%= f.full_error :confirmation_token %>
6
+
7
+ <div class="form-inputs">
8
+ <%= f.input :email, required: true, autofocus: true %>
9
+ </div>
10
+
11
+ <div class="form-actions">
12
+ <%= f.button :submit, "Resend confirmation instructions" %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,19 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <%= f.input :reset_password_token, as: :hidden %>
7
+ <%= f.full_error :reset_password_token %>
8
+
9
+ <div class="form-inputs">
10
+ <%= f.input :password, label: "New password", required: true, autofocus: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable) %>
11
+ <%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
12
+ </div>
13
+
14
+ <div class="form-actions">
15
+ <%= f.button :submit, "Change my password" %>
16
+ </div>
17
+ <% end %>
18
+
19
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="form-inputs">
7
+ <%= f.input :email, required: true, autofocus: true %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, "Send me reset password instructions" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,27 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="form-inputs">
7
+ <%= f.input :email, required: true, autofocus: true %>
8
+
9
+ <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
10
+ <p>Currently waiting confirmation for: <%= resource.unconfirmed_email %></p>
11
+ <% end %>
12
+
13
+ <%= f.input :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", required: false %>
14
+ <%= f.input :password_confirmation, required: false %>
15
+ <%= f.input :current_password, hint: "we need your current password to confirm your changes", required: true %>
16
+ </div>
17
+
18
+ <div class="form-actions">
19
+ <%= f.button :submit, "Update" %>
20
+ </div>
21
+ <% end %>
22
+
23
+ <h3>Cancel my account</h3>
24
+
25
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
26
+
27
+ <%= link_to "Back", :back %>
@@ -0,0 +1,17 @@
1
+ <h2>Sign up</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
4
+ <%= f.error_notification %>
5
+
6
+ <div class="form-inputs">
7
+ <%= f.input :email, required: true, autofocus: true %>
8
+ <%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable) %>
9
+ <%= f.input :password_confirmation, required: true %>
10
+ </div>
11
+
12
+ <div class="form-actions">
13
+ <%= f.button :submit, "Sign up" %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,15 @@
1
+ <h2>Log in</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
4
+ <div class="form-inputs">
5
+ <%= f.input :email, required: false, autofocus: true %>
6
+ <%= f.input :password, required: false %>
7
+ <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, "Log in" %>
12
+ </div>
13
+ <% end %>
14
+
15
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,16 @@
1
+ <h2>Resend unlock instructions</h2>
2
+
3
+ <%= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
4
+ <%= f.error_notification %>
5
+ <%= f.full_error :unlock_token %>
6
+
7
+ <div class="form-inputs">
8
+ <%= f.input :email, required: true, autofocus: true %>
9
+ </div>
10
+
11
+ <div class="form-actions">
12
+ <%= f.button :submit, "Resend unlock instructions" %>
13
+ </div>
14
+ <% end %>
15
+
16
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: cached-bundle install --deployment
3
+ #
4
+ # After running `bundle`, caches the `vendor/bundle` directory to S3.
5
+ # On the next run, restores the cached directory before running `bundle`.
6
+ # When `Gemfile.lock` changes, the cache gets rebuilt.
7
+ #
8
+ # Requirements:
9
+ # - Gemfile.lock
10
+ # - TRAVIS_REPO_SLUG
11
+ # - TRAVIS_RUBY_VERSION
12
+ # - AMAZON_S3_BUCKET
13
+ # - script/s3-put
14
+ # - bundle
15
+ # - curl
16
+ #
17
+ # Author: Mislav Marohnić
18
+
19
+ set -e
20
+
21
+ compute_md5() {
22
+ local output="$(openssl md5)"
23
+ echo "${output##* }"
24
+ }
25
+
26
+ download() {
27
+ curl --tcp-nodelay -qsfL "$1" -o "$2"
28
+ }
29
+
30
+
31
+ gemfile="${BUNDLE_GEMFILE:-Gemfile}"
32
+ bundle_fullpath="$(dirname $gemfile)/vendor/bundle"
33
+ bundle_path=${bundle_fullpath#$PWD/}
34
+ gemfile_hash="$(compute_md5 <"${gemfile}.lock")"
35
+ cache_name="${TRAVIS_RUBY_VERSION}-${gemfile_hash}.tgz"
36
+ fetch_url="http://${AMAZON_S3_BUCKET}.s3.amazonaws.com/${TRAVIS_REPO_SLUG}/${cache_name}"
37
+
38
+ if download "$fetch_url" "$cache_name"; then
39
+ echo "Reusing cached bundle ${cache_name}"
40
+ tar xzf "$cache_name"
41
+ fi
42
+
43
+ bundle "$@"
44
+
45
+ if [ ! -f "$cache_name" ] && [ -n "$AMAZON_SECRET_ACCESS_KEY" ]; then
46
+ echo "Caching \`${bundle_path}' to S3"
47
+ tar czf "$cache_name" "$bundle_path"
48
+ script/s3-put "$cache_name" "${AMAZON_S3_BUCKET}:${TRAVIS_REPO_SLUG}/${cache_name}"
49
+ fi
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ # Usage: s3-put <FILE> <S3_BUCKET>[:<PATH>] [<CONTENT_TYPE>]
3
+ #
4
+ # Uploads a file to the Amazon S3 service.
5
+ # Outputs the URL for the newly uploaded file.
6
+ #
7
+ # Requirements:
8
+ # - AMAZON_ACCESS_KEY_ID
9
+ # - AMAZON_SECRET_ACCESS_KEY
10
+ # - openssl
11
+ # - curl
12
+ #
13
+ # Author: Mislav Marohnić
14
+
15
+ set -e
16
+
17
+ authorization() {
18
+ local signature="$(string_to_sign | hmac_sha1 | base64)"
19
+ echo "AWS ${AMAZON_ACCESS_KEY_ID?}:${signature}"
20
+ }
21
+
22
+ hmac_sha1() {
23
+ openssl dgst -binary -sha1 -hmac "${AMAZON_SECRET_ACCESS_KEY?}"
24
+ }
25
+
26
+ base64() {
27
+ openssl enc -base64
28
+ }
29
+
30
+ bin_md5() {
31
+ openssl dgst -binary -md5
32
+ }
33
+
34
+ string_to_sign() {
35
+ echo "$http_method"
36
+ echo "$content_md5"
37
+ echo "$content_type"
38
+ echo "$date"
39
+ echo "x-amz-acl:$acl"
40
+ printf "/$bucket/$remote_path"
41
+ }
42
+
43
+ date_string() {
44
+ LC_TIME=C date "+%a, %d %h %Y %T %z"
45
+ }
46
+
47
+ file="$1"
48
+ bucket="${2%%:*}"
49
+ remote_path="${2#*:}"
50
+ content_type="$3"
51
+
52
+ if [ -z "$remote_path" ] || [ "$remote_path" = "$bucket" ]; then
53
+ remote_path="${file##*/}"
54
+ fi
55
+
56
+ http_method=PUT
57
+ acl="public-read"
58
+ content_md5="$(bin_md5 < "$file" | base64)"
59
+ date="$(date_string)"
60
+
61
+ url="https://$bucket.s3.amazonaws.com/$remote_path"
62
+
63
+ curl -qsSf -T "$file" \
64
+ -H "Authorization: $(authorization)" \
65
+ -H "x-amz-acl: $acl" \
66
+ -H "Date: $date" \
67
+ -H "Content-MD5: $content_md5" \
68
+ -H "Content-Type: $content_type" \
69
+ "$url"
70
+
71
+ echo "$url"
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class CustomRegistrationsControllerTest < ActionController::TestCase
4
+ tests Custom::RegistrationsController
5
+
6
+ include Devise::TestHelpers
7
+
8
+ setup do
9
+ request.env["devise.mapping"] = Devise.mappings[:user]
10
+ @password = 'password'
11
+ @user = create_user(password: @password, password_confirmation: @password).tap(&:confirm!)
12
+ end
13
+
14
+ test "yield resource to block on create success" do
15
+ post :create, { user: { email: "user@example.org", password: "password", password_confirmation: "password" } }
16
+ assert @controller.create_block_called?, "create failed to yield resource to provided block"
17
+ end
18
+
19
+ test "yield resource to block on create failure" do
20
+ post :create, { user: { } }
21
+ assert @controller.create_block_called?, "create failed to yield resource to provided block"
22
+ end
23
+
24
+ test "yield resource to block on update success" do
25
+ sign_in @user
26
+ put :update, { user: { current_password: @password } }
27
+ assert @controller.update_block_called?, "update failed to yield resource to provided block"
28
+ end
29
+
30
+ test "yield resource to block on update failure" do
31
+ sign_in @user
32
+ put :update, { user: { } }
33
+ assert @controller.update_block_called?, "update failed to yield resource to provided block"
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+ require 'ostruct'
3
+ require 'warden/strategies/base'
4
+ require 'devise/test_helpers'
5
+
6
+ class CustomStrategyController < ActionController::Base
7
+ def new
8
+ warden.authenticate!(:custom_strategy)
9
+ end
10
+ end
11
+
12
+ # These tests are to prove that a warden strategy can successfully
13
+ # return a custom response, including a specific status code and
14
+ # custom http response headers. This does work in production,
15
+ # however, at the time of writing this, the Devise test helpers do
16
+ # not recognise the custom response and proceed to calling the
17
+ # Failure App. This makes it impossible to write tests for a
18
+ # strategy that return a custom response with Devise.
19
+ class CustomStrategy < Warden::Strategies::Base
20
+ def authenticate!
21
+ custom_headers = { "X-FOO" => "BAR" }
22
+ response = Rack::Response.new("BAD REQUEST", 400, custom_headers)
23
+ custom! response.finish
24
+ end
25
+ end
26
+
27
+ class CustomStrategyTest < ActionController::TestCase
28
+ tests CustomStrategyController
29
+
30
+ include Devise::TestHelpers
31
+
32
+ setup do
33
+ Warden::Strategies.add(:custom_strategy, CustomStrategy)
34
+ end
35
+
36
+ teardown do
37
+ Warden::Strategies._strategies.delete(:custom_strategy)
38
+ end
39
+
40
+ test "custom strategy can return its own status code" do
41
+ ret = get :new
42
+
43
+ # check the returned rack array
44
+ assert ret.is_a?(Array)
45
+ assert_equal 400, ret.first
46
+
47
+ # check the saved response as well. This is purely so that the response is available to the testing framework
48
+ # for verification. In production, the above array would be delivered directly to Rack.
49
+ assert_response 400
50
+ end
51
+
52
+ test "custom strategy can return custom headers" do
53
+ ret = get :new
54
+
55
+ # check the returned rack array
56
+ assert ret.is_a?(Array)
57
+ assert_equal ret.third['X-FOO'], 'BAR'
58
+
59
+ # check the saved response headers as well.
60
+ assert_equal response.headers['X-FOO'], 'BAR'
61
+ end
62
+ end
@@ -0,0 +1,316 @@
1
+ require 'test_helper'
2
+ require 'ostruct'
3
+
4
+ class ControllerAuthenticatableTest < ActionController::TestCase
5
+ tests ApplicationController
6
+
7
+ def setup
8
+ @mock_warden = OpenStruct.new
9
+ @controller.request.env['warden'] = @mock_warden
10
+ end
11
+
12
+ test 'provide access to warden instance' do
13
+ assert_equal @mock_warden, @controller.warden
14
+ end
15
+
16
+ test 'proxy signed_in?(scope) to authenticate?' do
17
+ @mock_warden.expects(:authenticate?).with(scope: :my_scope)
18
+ @controller.signed_in?(:my_scope)
19
+ end
20
+
21
+ test 'proxy signed_in?(nil) to authenticate?' do
22
+ Devise.mappings.keys.each do |scope| # :user, :admin, :manager
23
+ @mock_warden.expects(:authenticate?).with(scope: scope)
24
+ end
25
+ @controller.signed_in?
26
+ end
27
+
28
+ test 'proxy [group]_signed_in? to authenticate? with each scope' do
29
+ [:user, :admin].each do |scope|
30
+ @mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
31
+ end
32
+ @controller.commenter_signed_in?
33
+ end
34
+
35
+ test 'proxy current_user to authenticate with user scope' do
36
+ @mock_warden.expects(:authenticate).with(scope: :user)
37
+ @controller.current_user
38
+ end
39
+
40
+ test 'proxy current_admin to authenticate with admin scope' do
41
+ @mock_warden.expects(:authenticate).with(scope: :admin)
42
+ @controller.current_admin
43
+ end
44
+
45
+ test 'proxy current_[group] to authenticate with each scope' do
46
+ [:user, :admin].each do |scope|
47
+ @mock_warden.expects(:authenticate).with(scope: scope).returns(nil)
48
+ end
49
+ @controller.current_commenter
50
+ end
51
+
52
+ test 'proxy current_[plural_group] to authenticate with each scope' do
53
+ [:user, :admin].each do |scope|
54
+ @mock_warden.expects(:authenticate).with(scope: scope)
55
+ end
56
+ @controller.current_commenters
57
+ end
58
+
59
+ test 'proxy current_publisher_account to authenticate with namespaced publisher account scope' do
60
+ @mock_warden.expects(:authenticate).with(scope: :publisher_account)
61
+ @controller.current_publisher_account
62
+ end
63
+
64
+ test 'proxy authenticate_user! to authenticate with user scope' do
65
+ @mock_warden.expects(:authenticate!).with(scope: :user)
66
+ @controller.authenticate_user!
67
+ end
68
+
69
+ test 'proxy authenticate_user! options to authenticate with user scope' do
70
+ @mock_warden.expects(:authenticate!).with(scope: :user, recall: "foo")
71
+ @controller.authenticate_user!(recall: "foo")
72
+ end
73
+
74
+ test 'proxy authenticate_admin! to authenticate with admin scope' do
75
+ @mock_warden.expects(:authenticate!).with(scope: :admin)
76
+ @controller.authenticate_admin!
77
+ end
78
+
79
+ test 'proxy authenticate_[group]! to authenticate!? with each scope' do
80
+ [:user, :admin].each do |scope|
81
+ @mock_warden.expects(:authenticate!).with(scope: scope)
82
+ @mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
83
+ end
84
+ @controller.authenticate_commenter!
85
+ end
86
+
87
+ test 'proxy authenticate_publisher_account! to authenticate with namespaced publisher account scope' do
88
+ @mock_warden.expects(:authenticate!).with(scope: :publisher_account)
89
+ @controller.authenticate_publisher_account!
90
+ end
91
+
92
+ test 'proxy user_signed_in? to authenticate with user scope' do
93
+ @mock_warden.expects(:authenticate).with(scope: :user).returns("user")
94
+ assert @controller.user_signed_in?
95
+ end
96
+
97
+ test 'proxy admin_signed_in? to authenticatewith admin scope' do
98
+ @mock_warden.expects(:authenticate).with(scope: :admin)
99
+ assert_not @controller.admin_signed_in?
100
+ end
101
+
102
+ test 'proxy publisher_account_signed_in? to authenticate with namespaced publisher account scope' do
103
+ @mock_warden.expects(:authenticate).with(scope: :publisher_account)
104
+ @controller.publisher_account_signed_in?
105
+ end
106
+
107
+ test 'proxy user_session to session scope in warden' do
108
+ @mock_warden.expects(:authenticate).with(scope: :user).returns(true)
109
+ @mock_warden.expects(:session).with(:user).returns({})
110
+ @controller.user_session
111
+ end
112
+
113
+ test 'proxy admin_session to session scope in warden' do
114
+ @mock_warden.expects(:authenticate).with(scope: :admin).returns(true)
115
+ @mock_warden.expects(:session).with(:admin).returns({})
116
+ @controller.admin_session
117
+ end
118
+
119
+ test 'proxy publisher_account_session from namespaced scope to session scope in warden' do
120
+ @mock_warden.expects(:authenticate).with(scope: :publisher_account).returns(true)
121
+ @mock_warden.expects(:session).with(:publisher_account).returns({})
122
+ @controller.publisher_account_session
123
+ end
124
+
125
+ test 'sign in proxy to set_user on warden' do
126
+ user = User.new
127
+ @mock_warden.expects(:user).returns(nil)
128
+ @mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
129
+ @controller.sign_in(:user, user)
130
+ end
131
+
132
+ test 'sign in accepts a resource as argument' do
133
+ user = User.new
134
+ @mock_warden.expects(:user).returns(nil)
135
+ @mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
136
+ @controller.sign_in(user)
137
+ end
138
+
139
+ test 'does not sign in again if the user is already in' do
140
+ user = User.new
141
+ @mock_warden.expects(:user).returns(user)
142
+ @mock_warden.expects(:set_user).never
143
+ assert @controller.sign_in(user)
144
+ end
145
+
146
+ test 'sign in again when the user is already in only if force is given' do
147
+ user = User.new
148
+ @mock_warden.expects(:user).returns(user)
149
+ @mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
150
+ @controller.sign_in(user, force: true)
151
+ end
152
+
153
+ test 'sign in accepts bypass as option' do
154
+ user = User.new
155
+ @mock_warden.expects(:session_serializer).returns(serializer = mock())
156
+ serializer.expects(:store).with(user, :user)
157
+ @controller.sign_in(user, bypass: true)
158
+ end
159
+
160
+ test 'sign out clears up any signed in user from all scopes' do
161
+ user = User.new
162
+ @mock_warden.expects(:user).times(Devise.mappings.size)
163
+ @mock_warden.expects(:logout).with().returns(true)
164
+ @controller.instance_variable_set(:@current_user, user)
165
+ @controller.instance_variable_set(:@current_admin, user)
166
+ @controller.sign_out
167
+ assert_equal nil, @controller.instance_variable_get(:@current_user)
168
+ assert_equal nil, @controller.instance_variable_get(:@current_admin)
169
+ end
170
+
171
+ test 'sign out logs out and clears up any signed in user by scope' do
172
+ user = User.new
173
+ @mock_warden.expects(:user).with(scope: :user, run_callbacks: false).returns(user)
174
+ @mock_warden.expects(:logout).with(:user).returns(true)
175
+ @mock_warden.expects(:clear_strategies_cache!).with(scope: :user).returns(true)
176
+ @controller.instance_variable_set(:@current_user, user)
177
+ @controller.sign_out(:user)
178
+ assert_equal nil, @controller.instance_variable_get(:@current_user)
179
+ end
180
+
181
+ test 'sign out accepts a resource as argument' do
182
+ @mock_warden.expects(:user).with(scope: :user, run_callbacks: false).returns(true)
183
+ @mock_warden.expects(:logout).with(:user).returns(true)
184
+ @mock_warden.expects(:clear_strategies_cache!).with(scope: :user).returns(true)
185
+ @controller.sign_out(User.new)
186
+ end
187
+
188
+ test 'sign out without args proxy to sign out all scopes' do
189
+ @mock_warden.expects(:user).times(Devise.mappings.size)
190
+ @mock_warden.expects(:logout).with().returns(true)
191
+ @mock_warden.expects(:clear_strategies_cache!).with().returns(true)
192
+ @controller.sign_out
193
+ end
194
+
195
+ test 'sign out everybody proxy to logout on warden' do
196
+ @mock_warden.expects(:user).times(Devise.mappings.size)
197
+ @mock_warden.expects(:logout).with().returns(true)
198
+ @controller.sign_out_all_scopes
199
+ end
200
+
201
+ test 'stored location for returns the location for a given scope' do
202
+ assert_nil @controller.stored_location_for(:user)
203
+ @controller.session[:"user_return_to"] = "/foo.bar"
204
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
205
+ end
206
+
207
+ test 'stored location for accepts a resource as argument' do
208
+ assert_nil @controller.stored_location_for(:user)
209
+ @controller.session[:"user_return_to"] = "/foo.bar"
210
+ assert_equal "/foo.bar", @controller.stored_location_for(User.new)
211
+ end
212
+
213
+ test 'stored location cleans information after reading' do
214
+ @controller.session[:"user_return_to"] = "/foo.bar"
215
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
216
+ assert_nil @controller.session[:"user_return_to"]
217
+ end
218
+
219
+ test 'store location for stores a location to redirect back to' do
220
+ assert_nil @controller.stored_location_for(:user)
221
+ @controller.store_location_for(:user, "/foo.bar")
222
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
223
+ end
224
+
225
+ test 'store bad location for stores a location to redirect back to' do
226
+ assert_nil @controller.stored_location_for(:user)
227
+ @controller.store_location_for(:user, "/foo.bar\">Carry")
228
+ assert_nil @controller.stored_location_for(:user)
229
+ end
230
+
231
+ test 'store location for accepts a resource as argument' do
232
+ @controller.store_location_for(User.new, "/foo.bar")
233
+ assert_equal "/foo.bar", @controller.stored_location_for(User.new)
234
+ end
235
+
236
+ test 'store location for stores paths' do
237
+ @controller.store_location_for(:user, "//host/foo.bar")
238
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
239
+ @controller.store_location_for(:user, "///foo.bar")
240
+ assert_equal "/foo.bar", @controller.stored_location_for(:user)
241
+ end
242
+
243
+ test 'store location for stores query string' do
244
+ @controller.store_location_for(:user, "/foo?bar=baz")
245
+ assert_equal "/foo?bar=baz", @controller.stored_location_for(:user)
246
+ end
247
+
248
+ test 'store location for stores fragments' do
249
+ @controller.store_location_for(:user, "/foo#bar")
250
+ assert_equal "/foo#bar", @controller.stored_location_for(:user)
251
+ end
252
+
253
+ test 'after sign in path defaults to root path if none by was specified for the given scope' do
254
+ assert_equal root_path, @controller.after_sign_in_path_for(:user)
255
+ end
256
+
257
+ test 'after sign in path defaults to the scoped root path' do
258
+ assert_equal admin_root_path, @controller.after_sign_in_path_for(:admin)
259
+ end
260
+
261
+ test 'after sign out path defaults to the root path' do
262
+ assert_equal root_path, @controller.after_sign_out_path_for(:admin)
263
+ assert_equal root_path, @controller.after_sign_out_path_for(:user)
264
+ end
265
+
266
+ test 'sign in and redirect uses the stored location' do
267
+ user = User.new
268
+ @controller.session[:user_return_to] = "/foo.bar"
269
+ @mock_warden.expects(:user).with(:user).returns(nil)
270
+ @mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
271
+ @controller.expects(:redirect_to).with("/foo.bar")
272
+ @controller.sign_in_and_redirect(user)
273
+ end
274
+
275
+ test 'sign in and redirect uses the configured after sign in path' do
276
+ admin = Admin.new
277
+ @mock_warden.expects(:user).with(:admin).returns(nil)
278
+ @mock_warden.expects(:set_user).with(admin, scope: :admin).returns(true)
279
+ @controller.expects(:redirect_to).with(admin_root_path)
280
+ @controller.sign_in_and_redirect(admin)
281
+ end
282
+
283
+ test 'sign in and redirect does not sign in again if user is already signed' do
284
+ admin = Admin.new
285
+ @mock_warden.expects(:user).with(:admin).returns(admin)
286
+ @mock_warden.expects(:set_user).never
287
+ @controller.expects(:redirect_to).with(admin_root_path)
288
+ @controller.sign_in_and_redirect(admin)
289
+ end
290
+
291
+ test 'sign out and redirect uses the configured after sign out path when signing out only the current scope' do
292
+ swap Devise, sign_out_all_scopes: false do
293
+ @mock_warden.expects(:user).with(scope: :admin, run_callbacks: false).returns(true)
294
+ @mock_warden.expects(:logout).with(:admin).returns(true)
295
+ @mock_warden.expects(:clear_strategies_cache!).with(scope: :admin).returns(true)
296
+ @controller.expects(:redirect_to).with(admin_root_path)
297
+ @controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end"
298
+ @controller.sign_out_and_redirect(:admin)
299
+ end
300
+ end
301
+
302
+ test 'sign out and redirect uses the configured after sign out path when signing out all scopes' do
303
+ swap Devise, sign_out_all_scopes: true do
304
+ @mock_warden.expects(:user).times(Devise.mappings.size)
305
+ @mock_warden.expects(:logout).with().returns(true)
306
+ @mock_warden.expects(:clear_strategies_cache!).with().returns(true)
307
+ @controller.expects(:redirect_to).with(admin_root_path)
308
+ @controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end"
309
+ @controller.sign_out_and_redirect(:admin)
310
+ end
311
+ end
312
+
313
+ test 'is not a devise controller' do
314
+ assert_not @controller.devise_controller?
315
+ end
316
+ end