door_mat 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +88 -0
  6. data/Rakefile +32 -0
  7. data/app/assets/javascripts/door_mat/application.js +13 -0
  8. data/app/assets/stylesheets/door_mat/application.css +15 -0
  9. data/app/assets/stylesheets/scaffold.css +56 -0
  10. data/app/controllers/door_mat/activities_controller.rb +106 -0
  11. data/app/controllers/door_mat/application_controller.rb +14 -0
  12. data/app/controllers/door_mat/change_password_controller.rb +32 -0
  13. data/app/controllers/door_mat/forgot_passwords_controller.rb +57 -0
  14. data/app/controllers/door_mat/manage_email_controller.rb +61 -0
  15. data/app/controllers/door_mat/password_less_session_controller.rb +121 -0
  16. data/app/controllers/door_mat/reconfirm_password_controller.rb +27 -0
  17. data/app/controllers/door_mat/sessions_controller.rb +17 -0
  18. data/app/controllers/door_mat/sign_in_controller.rb +60 -0
  19. data/app/controllers/door_mat/sign_up_controller.rb +59 -0
  20. data/app/controllers/door_mat/static_controller.rb +5 -0
  21. data/app/mailers/door_mat/activity_mailer.rb +18 -0
  22. data/app/mailers/door_mat/password_less_session_mailer.rb +12 -0
  23. data/app/models/door_mat/access_token.rb +315 -0
  24. data/app/models/door_mat/activity.rb +14 -0
  25. data/app/models/door_mat/activity_confirm_email.rb +45 -0
  26. data/app/models/door_mat/activity_download_recovery_key.rb +30 -0
  27. data/app/models/door_mat/activity_reset_password.rb +47 -0
  28. data/app/models/door_mat/actor.rb +149 -0
  29. data/app/models/door_mat/change_password.rb +12 -0
  30. data/app/models/door_mat/email.rb +58 -0
  31. data/app/models/door_mat/forgot_password.rb +12 -0
  32. data/app/models/door_mat/membership.rb +42 -0
  33. data/app/models/door_mat/session.rb +315 -0
  34. data/app/models/door_mat/sign_in.rb +31 -0
  35. data/app/models/door_mat/sign_up.rb +17 -0
  36. data/app/views/door_mat/activity_mailer/confirm_email.html.erb +11 -0
  37. data/app/views/door_mat/activity_mailer/confirm_email.text.erb +7 -0
  38. data/app/views/door_mat/activity_mailer/reset_password.html.erb +11 -0
  39. data/app/views/door_mat/activity_mailer/reset_password.text.erb +7 -0
  40. data/app/views/door_mat/change_password/new.html.erb +22 -0
  41. data/app/views/door_mat/forgot_passwords/choose_new_password.html.erb +34 -0
  42. data/app/views/door_mat/forgot_passwords/new.html.erb +14 -0
  43. data/app/views/door_mat/helpers/_errors_if_any.html.erb +10 -0
  44. data/app/views/door_mat/manage_email/new.html.erb +14 -0
  45. data/app/views/door_mat/password_less_session/access_token.html.erb +16 -0
  46. data/app/views/door_mat/password_less_session/new.html.erb +34 -0
  47. data/app/views/door_mat/password_less_session_mailer/send_token.html.erb +11 -0
  48. data/app/views/door_mat/password_less_session_mailer/send_token.text.erb +7 -0
  49. data/app/views/door_mat/reconfirm_password/new.html.erb +12 -0
  50. data/app/views/door_mat/sign_in/new.html.erb +30 -0
  51. data/app/views/door_mat/sign_up/new.html.erb +24 -0
  52. data/app/views/door_mat/static/add_email_success.html.erb +5 -0
  53. data/app/views/door_mat/static/change_password_success.html.erb +2 -0
  54. data/app/views/door_mat/static/confirm_email_success.html.erb +2 -0
  55. data/app/views/door_mat/static/email_confirmation_required.html.erb +17 -0
  56. data/app/views/door_mat/static/forgot_password_verification_mail_sent.html.erb +2 -0
  57. data/app/views/door_mat/static/reconfirm_password_success.html.erb +4 -0
  58. data/app/views/door_mat/static/sign_in_success.html.erb +5 -0
  59. data/app/views/door_mat/static/sign_out_success.html.erb +5 -0
  60. data/app/views/door_mat/static/sign_up_success.html.erb +4 -0
  61. data/bin/rails +12 -0
  62. data/config/locales/en.yml +73 -0
  63. data/config/routes.rb +48 -0
  64. data/db/migrate/20140616234935_create_door_mat_actors.rb +23 -0
  65. data/db/migrate/20140617233357_create_door_mat_sessions.rb +17 -0
  66. data/db/migrate/20140630043202_create_door_mat_emails.rb +12 -0
  67. data/db/migrate/20140702045729_create_door_mat_activities.rb +14 -0
  68. data/db/migrate/20141115183045_create_door_mat_access_tokens.rb +17 -0
  69. data/db/migrate/20141121191824_create_door_mat_memberships.rb +14 -0
  70. data/db/migrate/20150910182126_rename_session_guid_column.rb +5 -0
  71. data/db/migrate/20150918210831_add_access_token_rating_column.rb +5 -0
  72. data/door_mat.gemspec +37 -0
  73. data/lib/door_mat.rb +20 -0
  74. data/lib/door_mat/attr_asymmetric_store.rb +82 -0
  75. data/lib/door_mat/attr_symmetric_store.rb +82 -0
  76. data/lib/door_mat/configuration.rb +193 -0
  77. data/lib/door_mat/controller.rb +117 -0
  78. data/lib/door_mat/crypto.rb +49 -0
  79. data/lib/door_mat/crypto/asymmetric_store.rb +77 -0
  80. data/lib/door_mat/crypto/fast_hash.rb +17 -0
  81. data/lib/door_mat/crypto/password_hash.rb +39 -0
  82. data/lib/door_mat/crypto/secure_compare.rb +23 -0
  83. data/lib/door_mat/crypto/symmetric_store.rb +68 -0
  84. data/lib/door_mat/engine.rb +23 -0
  85. data/lib/door_mat/process/actor_password_change.rb +65 -0
  86. data/lib/door_mat/process/actor_sign_in.rb +38 -0
  87. data/lib/door_mat/process/actor_sign_up.rb +39 -0
  88. data/lib/door_mat/process/create_new_anonymous_actor.rb +36 -0
  89. data/lib/door_mat/process/manage_email.rb +42 -0
  90. data/lib/door_mat/process/reset_password.rb +50 -0
  91. data/lib/door_mat/regex.rb +17 -0
  92. data/lib/door_mat/test_helper.rb +58 -0
  93. data/lib/door_mat/url_protocol.rb +9 -0
  94. data/lib/door_mat/version.rb +3 -0
  95. data/lib/tasks/door_mat_tasks.rake +31 -0
  96. data/spec/controllers/door_mat/activities_controller_spec.rb +70 -0
  97. data/spec/controllers/door_mat/forgot_passwords_controller_spec.rb +57 -0
  98. data/spec/controllers/door_mat/manage_email_spec.rb +181 -0
  99. data/spec/controllers/door_mat/password_less_session_controller_spec.rb +344 -0
  100. data/spec/controllers/door_mat/sign_in_controller_spec.rb +211 -0
  101. data/spec/controllers/door_mat/sign_up_controller_spec.rb +90 -0
  102. data/spec/factories/door_mat_access_tokens.rb +6 -0
  103. data/spec/factories/door_mat_activitiess.rb +6 -0
  104. data/spec/factories/door_mat_actors.rb +23 -0
  105. data/spec/factories/door_mat_emails.rb +14 -0
  106. data/spec/factories/door_mat_memberships.rb +6 -0
  107. data/spec/factories/door_mat_sessions.rb +24 -0
  108. data/spec/features/password_less_session_spec.rb +165 -0
  109. data/spec/features/remember_me_spec.rb +672 -0
  110. data/spec/features/session_spec.rb +336 -0
  111. data/spec/lib/attr_store_spec.rb +237 -0
  112. data/spec/lib/crypto_spec.rb +130 -0
  113. data/spec/lib/process_spec.rb +159 -0
  114. data/spec/models/door_mat/access_token_spec.rb +134 -0
  115. data/spec/models/door_mat/activity_spec.rb +38 -0
  116. data/spec/models/door_mat/actor_spec.rb +56 -0
  117. data/spec/models/door_mat/email_spec.rb +25 -0
  118. data/spec/models/door_mat/session_spec.rb +69 -0
  119. data/spec/spec_helper.rb +223 -0
  120. data/spec/support/timecop/timecop_helper.rb +52 -0
  121. data/spec/test_app/README.rdoc +28 -0
  122. data/spec/test_app/Rakefile +6 -0
  123. data/spec/test_app/app/assets/javascripts/application.js +13 -0
  124. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  125. data/spec/test_app/app/controllers/account_controller.rb +28 -0
  126. data/spec/test_app/app/controllers/application_controller.rb +10 -0
  127. data/spec/test_app/app/controllers/password_less_sample_controller.rb +56 -0
  128. data/spec/test_app/app/controllers/static_controller.rb +7 -0
  129. data/spec/test_app/app/helpers/account_helper.rb +2 -0
  130. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  131. data/spec/test_app/app/models/game.rb +62 -0
  132. data/spec/test_app/app/models/shared_data.rb +4 -0
  133. data/spec/test_app/app/models/shared_key.rb +8 -0
  134. data/spec/test_app/app/models/user_detail.rb +7 -0
  135. data/spec/test_app/app/views/account/show.html.erb +133 -0
  136. data/spec/test_app/app/views/door_mat/static/sign_out_success.html.erb +7 -0
  137. data/spec/test_app/app/views/layouts/application.html.erb +20 -0
  138. data/spec/test_app/app/views/password_less_sample/draw_results.html.erb +6 -0
  139. data/spec/test_app/app/views/password_less_sample/final_result.html.erb +7 -0
  140. data/spec/test_app/app/views/password_less_sample/play_game.html.erb +5 -0
  141. data/spec/test_app/app/views/password_less_sample/show_loosing_door.html.erb +10 -0
  142. data/spec/test_app/app/views/static/index.html.erb +12 -0
  143. data/spec/test_app/app/views/static/only_confirmed_email_allowed.html.erb +10 -0
  144. data/spec/test_app/app/views/static/page_that_require_password_reconfirmation.html.erb +16 -0
  145. data/spec/test_app/app/views/static/session_protected_page.html.erb +32 -0
  146. data/spec/test_app/bin/bundle +3 -0
  147. data/spec/test_app/bin/rails +4 -0
  148. data/spec/test_app/bin/rake +4 -0
  149. data/spec/test_app/config.ru +4 -0
  150. data/spec/test_app/config/application.rb +29 -0
  151. data/spec/test_app/config/boot.rb +5 -0
  152. data/spec/test_app/config/database.yml +25 -0
  153. data/spec/test_app/config/environment.rb +19 -0
  154. data/spec/test_app/config/environments/development.rb +50 -0
  155. data/spec/test_app/config/environments/production.rb +83 -0
  156. data/spec/test_app/config/environments/test.rb +48 -0
  157. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  158. data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
  159. data/spec/test_app/config/initializers/door_mat.rb +72 -0
  160. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  161. data/spec/test_app/config/initializers/inflections.rb +16 -0
  162. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  163. data/spec/test_app/config/initializers/session_store.rb +3 -0
  164. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  165. data/spec/test_app/config/locales/en.yml +23 -0
  166. data/spec/test_app/config/routes.rb +42 -0
  167. data/spec/test_app/config/secrets.yml +31 -0
  168. data/spec/test_app/db/migrate/20140717182813_create_user_details.rb +10 -0
  169. data/spec/test_app/db/migrate/20140908225256_create_shared_data.rb +10 -0
  170. data/spec/test_app/db/migrate/20140908225604_create_shared_keys.rb +11 -0
  171. data/spec/test_app/db/migrate/20141121190714_create_games.rb +10 -0
  172. data/spec/test_app/public/404.html +67 -0
  173. data/spec/test_app/public/422.html +67 -0
  174. data/spec/test_app/public/500.html +66 -0
  175. data/spec/test_app/public/favicon.ico +0 -0
  176. metadata +552 -0
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ module DoorMat
4
+ describe Actor do
5
+ let(:user1) { {email: 'user1@example.com', password: 'password_user1'} }
6
+ let(:user2) { {email: 'user2@example.com', password: 'password_user2'} }
7
+
8
+ describe '#can_add_email?' do
9
+
10
+ it 'can not add more emails than max_email_count_per_actor' do
11
+ actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
12
+ DoorMat::configuration.max_email_count_per_actor = 1
13
+ email = DoorMat::Email.for('user@example.com')
14
+ expect(actor1.can_add_email?(email)).to be false
15
+ expect(email.errors.count).to eq(1)
16
+ expect(email.errors.full_messages.join('')).to match(/maximum number of email per account was reached/)
17
+ DoorMat::configuration.max_email_count_per_actor = 2
18
+ end
19
+
20
+ it 'can not add the same email twice' do
21
+ actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
22
+ DoorMat::configuration.max_email_count_per_actor = 2
23
+ email = DoorMat::Email.for(user1[:email])
24
+
25
+ expect(actor1.can_add_email?(email)).to be false
26
+ expect(email.errors.count).to eq(1)
27
+ expect(email.errors.full_messages.join('')).to match(/already associated/)
28
+ end
29
+
30
+ it 'can add a new email' do
31
+ actor1, _ = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
32
+ DoorMat::configuration.max_email_count_per_actor = 2
33
+ email = DoorMat::Email.for('user@example.com')
34
+
35
+ expect(actor1.can_add_email?(email)).to be true
36
+ end
37
+ end
38
+
39
+ it "can share a secret with an other actor" do
40
+ message = "some message"
41
+ actor1, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
42
+ actor2, session2 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user2[:email], user2[:password])
43
+
44
+ share = actor1.share_with(actor2, message)
45
+
46
+ RequestStore.store[:current_session] = session1
47
+ messages = DoorMat::Crypto.decrypt_shared(share[:secrets], actor1.decrypt_shared_key(share[:key], session1))
48
+ expect(message).to eq(messages.first)
49
+
50
+ messages = DoorMat::Crypto.decrypt_shared(share[:secrets], actor2.decrypt_shared_key(share[:other_key], session2))
51
+ expect(message).to eq(messages.first)
52
+ end
53
+
54
+ end
55
+ end
56
+
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module DoorMat
4
+ describe Email do
5
+
6
+ it 'creates a valid email from an email address' do
7
+ address = 'user@example.com'
8
+
9
+ email = DoorMat::Email.for(address)
10
+ expect(email).to be_valid
11
+
12
+ urlsafe_encoded_address = email.to_urlsafe_encoded
13
+ expect(DoorMat::Email.decode_urlsafe(urlsafe_encoded_address)).to eq(address)
14
+ expect(DoorMat::Email.address_hash(address)).to eq(DoorMat::Email.address_hash_from_encoded_address(urlsafe_encoded_address))
15
+ end
16
+
17
+ it 'returns an invalid url encoded address unchanged' do
18
+ address = 'user@example.com'
19
+
20
+ expect(DoorMat::Email.decode_urlsafe(address)).to eq(address)
21
+ end
22
+
23
+ end
24
+ end
25
+
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ module DoorMat
4
+ describe Session do
5
+ let(:user1) { {email: 'user1@example.com', password: 'password_user1'} }
6
+ let(:user2) { {email: 'user2@example.com', password: 'password_user2'} }
7
+
8
+ it "initialize a session with an actor and password" do
9
+ actor = DoorMat::TestHelper.create_signed_up_actor_with_confirmed_email_address(user1[:email], user1[:password])
10
+
11
+ session = DoorMat::Session.new
12
+ session.ip = "request.remote_ip"
13
+ session.agent = "request.user_agent"
14
+ session.initialize_with(actor, user1[:password])
15
+ expect(session.valid?).to be true
16
+ end
17
+
18
+ it "fail to initialize a session if an error is raised" do
19
+ actor = DoorMat::TestHelper.create_signed_up_actor_with_confirmed_email_address(user1[:email], user1[:password])
20
+
21
+ allow(DoorMat::Crypto::PasswordHash).to receive(:pbkdf2_hash).and_raise(StandardError)
22
+
23
+ session = DoorMat::Session.new
24
+ session.ip = "request.remote_ip"
25
+ session.agent = "request.user_agent"
26
+ session.initialize_with(actor, 'wrong_password')
27
+ expect(session.valid?).to be false
28
+ end
29
+
30
+ it 'can add an authenticated sub session' do
31
+ _, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
32
+ _, session2 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user2[:email], user2[:password])
33
+ invalid_session = DoorMat::Session.new
34
+
35
+ RequestStore.store[:current_session] = session2
36
+ expect(session1.append_sub_session(session2)).to be false
37
+
38
+ RequestStore.store[:current_session] = session1
39
+ expect(session1.append_sub_session(invalid_session)).to be false
40
+
41
+ expect(session1.append_sub_session(session2)).to be true
42
+
43
+ expect(session1.append_sub_session(session2)).to be true
44
+ end
45
+
46
+ it 'can encrypt and decrypt messages' do
47
+ message = "some message"
48
+ _, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
49
+
50
+ ciphertext = session1.encrypt(message)
51
+ expect(session1.decrypt(ciphertext)).to eq message
52
+
53
+ allow(DoorMat::Crypto::SymmetricStore).to receive(:decrypt).and_raise(OpenSSL::Cipher::CipherError)
54
+ expect(session1.decrypt(ciphertext)).to be_nil
55
+ end
56
+
57
+ it 'can encrypt and decrypt the recovery key' do
58
+ actor1, session1 = DoorMat::TestHelper.create_signed_in_actor_with_confirmed_email_address(user1[:email], user1[:password])
59
+
60
+ recovery_key = session1.package_recovery_key
61
+ expect(session1.recovery_key_restore(actor1, recovery_key)).to be true
62
+
63
+ allow(DoorMat::Crypto::SymmetricStore).to receive(:decrypt).and_raise(OpenSSL::Cipher::CipherError)
64
+ expect(session1.recovery_key_restore(actor1, recovery_key)).to be false
65
+ end
66
+
67
+ end
68
+ end
69
+
@@ -0,0 +1,223 @@
1
+ # This file is copied to spec/ when you run 'rails generate rspec:install'
2
+ ENV["RAILS_ENV"] ||= 'test'
3
+ require File.expand_path("../test_app/config/environment", __FILE__)
4
+
5
+ require 'email_spec'
6
+ require 'rspec/rails'
7
+ require 'database_cleaner'
8
+ require 'capybara/rspec'
9
+ require 'capybara/poltergeist'
10
+ require 'factory_girl_rails'
11
+ require 'door_mat'
12
+ require 'door_mat/test_helper'
13
+ require 'byebug'
14
+ require 'show_me_the_cookies'
15
+ require 'timecop'
16
+
17
+ Rails.backtrace_cleaner.remove_silencers!
18
+
19
+ # Requires supporting ruby files with custom matchers and macros, etc, in
20
+ # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
21
+ # run as spec files by default. This means that files in spec/support that end
22
+ # in _spec.rb will both be required and run as specs, causing the specs to be
23
+ # run twice. It is recommended that you do not name files matching this glob to
24
+ # end with _spec.rb. You can configure this pattern with with the --pattern
25
+ # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
26
+ # Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
27
+ ENGINE_RAILS_ROOT=File.join(File.dirname(__FILE__), '../')
28
+ Dir[File.join(ENGINE_RAILS_ROOT, "spec/support/**/*.rb")].each {|f| require f }
29
+
30
+ # Checks for pending migrations before tests are run.
31
+ # If you are not using ActiveRecord, you can remove this line.
32
+ ActiveRecord::Migration.maintain_test_schema!
33
+
34
+ RSpec.configure do |config|
35
+
36
+ # ## Mock Framework
37
+ #
38
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
39
+ #
40
+ # config.mock_with :mocha
41
+ # config.mock_with :flexmock
42
+ # config.mock_with :rr
43
+ config.include FactoryGirl::Syntax::Methods # If you do not include FactoryGirl::Syntax::Methods in your test suite, then all factory_girl methods will need to be prefaced with FactoryGirl.
44
+ config.include ShowMeTheCookies
45
+
46
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
47
+ # config.fixture_path = "#{::Rails.root}/spec/fixtures"
48
+
49
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
50
+ # examples within a transaction, remove the following line or assign false
51
+ # instead of true.
52
+ config.use_transactional_fixtures = false
53
+
54
+ # If true, the base class of anonymous controllers will be inferred
55
+ # automatically. This will be the default behavior in future versions of
56
+ # rspec-rails.
57
+ config.infer_base_class_for_anonymous_controllers = false
58
+
59
+ # Run specs in random order to surface order dependencies. If you find an
60
+ # order dependency and want to debug it, you can fix the order by providing
61
+ # the seed, which is printed after each run.
62
+ # --seed 1234
63
+ config.order = "random"
64
+
65
+ # RSpec Rails can automatically mix in different behaviours to your tests
66
+ # based on their file location, for example enabling you to call `get` and
67
+ # `post` in specs under `spec/controllers`.
68
+ #
69
+ # You can disable this behaviour by removing the line below, and instead
70
+ # explictly tag your specs with their type, e.g.:
71
+ #
72
+ # describe UsersController, :type => :controller do
73
+ # # ...
74
+ # end
75
+ #
76
+ # The different available types are documented in the features, such as in
77
+ # https://relishapp.com/rspec/rspec-rails/v/3-0/docs
78
+ config.infer_spec_type_from_file_location!
79
+
80
+
81
+ config.expect_with :rspec do |expectations|
82
+ # This option will default to `true` in RSpec 4. It makes the `description`
83
+ # and `failure_message` of custom matchers include text for helper methods
84
+ # defined using `chain`, e.g.:
85
+ # be_bigger_than(2).and_smaller_than(4).description
86
+ # # => "be bigger than 2 and smaller than 4"
87
+ # ...rather than:
88
+ # # => "be bigger than 2"
89
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
90
+ end
91
+
92
+
93
+
94
+ config.before(:suite) do
95
+ DatabaseCleaner.clean_with(:truncation)
96
+ end
97
+
98
+ config.before(:each) do
99
+ DatabaseCleaner.strategy = :truncation
100
+ end
101
+
102
+ config.before(:each, :js => true) do
103
+ DatabaseCleaner.strategy = :truncation
104
+ end
105
+
106
+ config.before(:each) do
107
+ DatabaseCleaner.start
108
+ ActionMailer::Base.deliveries.clear
109
+ Timecop.return
110
+ end
111
+
112
+ config.after(:each) do
113
+ DatabaseCleaner.clean
114
+ end
115
+ end
116
+
117
+ if ENV['IN_BROWSER']
118
+ # On demand: non-headless tests via Selenium/WebDriver
119
+ # To run the scenarios in browser (default: Firefox), use the following command line:
120
+ # IN_BROWSER=true bundle exec rspec
121
+ # or (to have a pause of 1 second between each step):
122
+ # IN_BROWSER=true PAUSE=1 bundle exec rspec
123
+ Capybara.default_driver = :selenium
124
+ # AfterStep do
125
+ # sleep (ENV['PAUSE'] || 0).to_i
126
+ # end
127
+ else
128
+ # DEFAULT: headless tests with poltergeist/PhantomJS
129
+ Capybara.register_driver :poltergeist do |app|
130
+ Capybara::Poltergeist::Driver.new(
131
+ app,
132
+ window_size: [1280, 1024],
133
+ timeout: 300,
134
+ phantomjs_options: ['--ignore-ssl-errors=yes', '--ssl-protocol=any'], # http://phantomjs.org/api/command-line.html ie ['--debug=no', '--load-images=no', '--ignore-ssl-errors=yes', '--ssl-protocol=TLSv1']
135
+ debug: false
136
+ )
137
+ end
138
+ Capybara.default_driver = :poltergeist
139
+ Capybara.javascript_driver = :poltergeist
140
+ end
141
+
142
+ Capybara.default_wait_time = 5
143
+
144
+ Capybara.register_driver :rack_test do |app|
145
+ Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' })
146
+ end
147
+
148
+ def set_hidden_input_value(css_matcher, value)
149
+ find(:css, css_matcher, :visible => false).set(value)
150
+ end
151
+
152
+ def fill_access_token_form(name, identifier, confirm_identifier=nil, is_public_computer=true, remember_me=false, return_path_with_access_token=true)
153
+ confirm_identifier ||= identifier
154
+
155
+ fill_in 'access_token_name', with: name
156
+ fill_in 'access_token_identifier', with: identifier
157
+ fill_in 'access_token_confirm_identifier', with: confirm_identifier
158
+
159
+ if is_public_computer
160
+ check('access_token_is_public')
161
+ else
162
+ uncheck('access_token_is_public')
163
+ end
164
+
165
+ if remember_me
166
+ check('access_token_remember_me')
167
+ else
168
+ uncheck('access_token_remember_me')
169
+ end
170
+ click_button 'Request access token'
171
+
172
+ if return_path_with_access_token
173
+ expect(unread_emails_for(identifier).size).to eq(parse_email_count(1))
174
+ e = open_last_email_for(identifier)
175
+ return links_in_email(e).select {|url| /access_token/.match(url)}.first
176
+ else
177
+ return nil
178
+ end
179
+ end
180
+
181
+ def fill_sign_in_form(email, password, is_public_computer=true, remember_me=false)
182
+ fill_in 'sign_in_email', with: email
183
+ fill_in 'sign_in_password', with: password
184
+
185
+ if is_public_computer
186
+ check('sign_in_is_public')
187
+ else
188
+ uncheck('sign_in_is_public')
189
+ end
190
+
191
+ if remember_me
192
+ check('sign_in_remember_me')
193
+ else
194
+ uncheck('sign_in_remember_me')
195
+ end
196
+ click_button 'Sign In'
197
+ end
198
+
199
+ def fill_sign_up_form(email, password, password_confirmation=nil)
200
+ password_confirmation ||= password
201
+ fill_in 'sign_up_email', with: email
202
+ fill_in 'sign_up_password', with: password
203
+ fill_in 'sign_up_password_confirmation', with: password_confirmation
204
+ click_button 'Sign Up'
205
+ end
206
+
207
+ def reload_page
208
+ visit(current_path)
209
+ end
210
+
211
+ def reset_default_config
212
+ DoorMat.configuration.password_reconfirm_delay = 5
213
+ DoorMat.configuration.public_computer_access_session_timeout = 30
214
+ DoorMat.configuration.private_computer_access_session_timeout = 60
215
+ DoorMat.configuration.allow_remember_me_feature = false
216
+ DoorMat.configuration.remember_me_require_private_computer_confirmation = true
217
+ DoorMat.configuration.remember_me_max_day_count = 30
218
+ end
219
+
220
+
221
+ def test_only_session_guid_anywhere_regex
222
+ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/
223
+ end
@@ -0,0 +1,52 @@
1
+
2
+
3
+ # Generic steps
4
+
5
+ def wait_two_minutes
6
+ t = 2.minutes.from_now
7
+ Timecop.travel(t)
8
+ end
9
+
10
+ def wait_two_days
11
+ t = 2.days.from_now
12
+ Timecop.travel(t)
13
+ end
14
+
15
+
16
+ # public computer timeout
17
+
18
+ def wait_longer_than_public_computer_session_timeout
19
+ t = (DoorMat.configuration.public_computer_access_session_timeout + 1).minutes.from_now
20
+ Timecop.travel(t)
21
+ end
22
+
23
+ def wait_less_than_public_computer_session_timeout
24
+ t = (DoorMat.configuration.public_computer_access_session_timeout - 1).minutes.from_now
25
+ Timecop.travel(t)
26
+ end
27
+
28
+
29
+ # private computer timeout
30
+
31
+ def wait_longer_than_private_computer_session_timeout
32
+ t = (DoorMat.configuration.private_computer_access_session_timeout + 1).minutes.from_now
33
+ Timecop.travel(t)
34
+ end
35
+
36
+ def wait_less_than_private_computer_session_timeout
37
+ t = (DoorMat.configuration.private_computer_access_session_timeout - 1).minutes.from_now
38
+ Timecop.travel(t)
39
+ end
40
+
41
+
42
+ # remember me timeout
43
+
44
+ def wait_longer_than_remember_me_timeout
45
+ t = (DoorMat.configuration.remember_me_max_day_count + 1).day.from_now
46
+ Timecop.travel(t)
47
+ end
48
+
49
+ def wait_less_than_remember_me_timeout
50
+ t = (DoorMat.configuration.remember_me_max_day_count - 1).day.from_now
51
+ Timecop.travel(t)
52
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.