door_mat 0.0.5
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.
- checksums.yaml +7 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/MIT-LICENSE +20 -0
- data/README.md +88 -0
- data/Rakefile +32 -0
- data/app/assets/javascripts/door_mat/application.js +13 -0
- data/app/assets/stylesheets/door_mat/application.css +15 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/door_mat/activities_controller.rb +106 -0
- data/app/controllers/door_mat/application_controller.rb +14 -0
- data/app/controllers/door_mat/change_password_controller.rb +32 -0
- data/app/controllers/door_mat/forgot_passwords_controller.rb +57 -0
- data/app/controllers/door_mat/manage_email_controller.rb +61 -0
- data/app/controllers/door_mat/password_less_session_controller.rb +121 -0
- data/app/controllers/door_mat/reconfirm_password_controller.rb +27 -0
- data/app/controllers/door_mat/sessions_controller.rb +17 -0
- data/app/controllers/door_mat/sign_in_controller.rb +60 -0
- data/app/controllers/door_mat/sign_up_controller.rb +59 -0
- data/app/controllers/door_mat/static_controller.rb +5 -0
- data/app/mailers/door_mat/activity_mailer.rb +18 -0
- data/app/mailers/door_mat/password_less_session_mailer.rb +12 -0
- data/app/models/door_mat/access_token.rb +315 -0
- data/app/models/door_mat/activity.rb +14 -0
- data/app/models/door_mat/activity_confirm_email.rb +45 -0
- data/app/models/door_mat/activity_download_recovery_key.rb +30 -0
- data/app/models/door_mat/activity_reset_password.rb +47 -0
- data/app/models/door_mat/actor.rb +149 -0
- data/app/models/door_mat/change_password.rb +12 -0
- data/app/models/door_mat/email.rb +58 -0
- data/app/models/door_mat/forgot_password.rb +12 -0
- data/app/models/door_mat/membership.rb +42 -0
- data/app/models/door_mat/session.rb +315 -0
- data/app/models/door_mat/sign_in.rb +31 -0
- data/app/models/door_mat/sign_up.rb +17 -0
- data/app/views/door_mat/activity_mailer/confirm_email.html.erb +11 -0
- data/app/views/door_mat/activity_mailer/confirm_email.text.erb +7 -0
- data/app/views/door_mat/activity_mailer/reset_password.html.erb +11 -0
- data/app/views/door_mat/activity_mailer/reset_password.text.erb +7 -0
- data/app/views/door_mat/change_password/new.html.erb +22 -0
- data/app/views/door_mat/forgot_passwords/choose_new_password.html.erb +34 -0
- data/app/views/door_mat/forgot_passwords/new.html.erb +14 -0
- data/app/views/door_mat/helpers/_errors_if_any.html.erb +10 -0
- data/app/views/door_mat/manage_email/new.html.erb +14 -0
- data/app/views/door_mat/password_less_session/access_token.html.erb +16 -0
- data/app/views/door_mat/password_less_session/new.html.erb +34 -0
- data/app/views/door_mat/password_less_session_mailer/send_token.html.erb +11 -0
- data/app/views/door_mat/password_less_session_mailer/send_token.text.erb +7 -0
- data/app/views/door_mat/reconfirm_password/new.html.erb +12 -0
- data/app/views/door_mat/sign_in/new.html.erb +30 -0
- data/app/views/door_mat/sign_up/new.html.erb +24 -0
- data/app/views/door_mat/static/add_email_success.html.erb +5 -0
- data/app/views/door_mat/static/change_password_success.html.erb +2 -0
- data/app/views/door_mat/static/confirm_email_success.html.erb +2 -0
- data/app/views/door_mat/static/email_confirmation_required.html.erb +17 -0
- data/app/views/door_mat/static/forgot_password_verification_mail_sent.html.erb +2 -0
- data/app/views/door_mat/static/reconfirm_password_success.html.erb +4 -0
- data/app/views/door_mat/static/sign_in_success.html.erb +5 -0
- data/app/views/door_mat/static/sign_out_success.html.erb +5 -0
- data/app/views/door_mat/static/sign_up_success.html.erb +4 -0
- data/bin/rails +12 -0
- data/config/locales/en.yml +73 -0
- data/config/routes.rb +48 -0
- data/db/migrate/20140616234935_create_door_mat_actors.rb +23 -0
- data/db/migrate/20140617233357_create_door_mat_sessions.rb +17 -0
- data/db/migrate/20140630043202_create_door_mat_emails.rb +12 -0
- data/db/migrate/20140702045729_create_door_mat_activities.rb +14 -0
- data/db/migrate/20141115183045_create_door_mat_access_tokens.rb +17 -0
- data/db/migrate/20141121191824_create_door_mat_memberships.rb +14 -0
- data/db/migrate/20150910182126_rename_session_guid_column.rb +5 -0
- data/db/migrate/20150918210831_add_access_token_rating_column.rb +5 -0
- data/door_mat.gemspec +37 -0
- data/lib/door_mat.rb +20 -0
- data/lib/door_mat/attr_asymmetric_store.rb +82 -0
- data/lib/door_mat/attr_symmetric_store.rb +82 -0
- data/lib/door_mat/configuration.rb +193 -0
- data/lib/door_mat/controller.rb +117 -0
- data/lib/door_mat/crypto.rb +49 -0
- data/lib/door_mat/crypto/asymmetric_store.rb +77 -0
- data/lib/door_mat/crypto/fast_hash.rb +17 -0
- data/lib/door_mat/crypto/password_hash.rb +39 -0
- data/lib/door_mat/crypto/secure_compare.rb +23 -0
- data/lib/door_mat/crypto/symmetric_store.rb +68 -0
- data/lib/door_mat/engine.rb +23 -0
- data/lib/door_mat/process/actor_password_change.rb +65 -0
- data/lib/door_mat/process/actor_sign_in.rb +38 -0
- data/lib/door_mat/process/actor_sign_up.rb +39 -0
- data/lib/door_mat/process/create_new_anonymous_actor.rb +36 -0
- data/lib/door_mat/process/manage_email.rb +42 -0
- data/lib/door_mat/process/reset_password.rb +50 -0
- data/lib/door_mat/regex.rb +17 -0
- data/lib/door_mat/test_helper.rb +58 -0
- data/lib/door_mat/url_protocol.rb +9 -0
- data/lib/door_mat/version.rb +3 -0
- data/lib/tasks/door_mat_tasks.rake +31 -0
- data/spec/controllers/door_mat/activities_controller_spec.rb +70 -0
- data/spec/controllers/door_mat/forgot_passwords_controller_spec.rb +57 -0
- data/spec/controllers/door_mat/manage_email_spec.rb +181 -0
- data/spec/controllers/door_mat/password_less_session_controller_spec.rb +344 -0
- data/spec/controllers/door_mat/sign_in_controller_spec.rb +211 -0
- data/spec/controllers/door_mat/sign_up_controller_spec.rb +90 -0
- data/spec/factories/door_mat_access_tokens.rb +6 -0
- data/spec/factories/door_mat_activitiess.rb +6 -0
- data/spec/factories/door_mat_actors.rb +23 -0
- data/spec/factories/door_mat_emails.rb +14 -0
- data/spec/factories/door_mat_memberships.rb +6 -0
- data/spec/factories/door_mat_sessions.rb +24 -0
- data/spec/features/password_less_session_spec.rb +165 -0
- data/spec/features/remember_me_spec.rb +672 -0
- data/spec/features/session_spec.rb +336 -0
- data/spec/lib/attr_store_spec.rb +237 -0
- data/spec/lib/crypto_spec.rb +130 -0
- data/spec/lib/process_spec.rb +159 -0
- data/spec/models/door_mat/access_token_spec.rb +134 -0
- data/spec/models/door_mat/activity_spec.rb +38 -0
- data/spec/models/door_mat/actor_spec.rb +56 -0
- data/spec/models/door_mat/email_spec.rb +25 -0
- data/spec/models/door_mat/session_spec.rb +69 -0
- data/spec/spec_helper.rb +223 -0
- data/spec/support/timecop/timecop_helper.rb +52 -0
- data/spec/test_app/README.rdoc +28 -0
- data/spec/test_app/Rakefile +6 -0
- data/spec/test_app/app/assets/javascripts/application.js +13 -0
- data/spec/test_app/app/assets/stylesheets/application.css +15 -0
- data/spec/test_app/app/controllers/account_controller.rb +28 -0
- data/spec/test_app/app/controllers/application_controller.rb +10 -0
- data/spec/test_app/app/controllers/password_less_sample_controller.rb +56 -0
- data/spec/test_app/app/controllers/static_controller.rb +7 -0
- data/spec/test_app/app/helpers/account_helper.rb +2 -0
- data/spec/test_app/app/helpers/application_helper.rb +2 -0
- data/spec/test_app/app/models/game.rb +62 -0
- data/spec/test_app/app/models/shared_data.rb +4 -0
- data/spec/test_app/app/models/shared_key.rb +8 -0
- data/spec/test_app/app/models/user_detail.rb +7 -0
- data/spec/test_app/app/views/account/show.html.erb +133 -0
- data/spec/test_app/app/views/door_mat/static/sign_out_success.html.erb +7 -0
- data/spec/test_app/app/views/layouts/application.html.erb +20 -0
- data/spec/test_app/app/views/password_less_sample/draw_results.html.erb +6 -0
- data/spec/test_app/app/views/password_less_sample/final_result.html.erb +7 -0
- data/spec/test_app/app/views/password_less_sample/play_game.html.erb +5 -0
- data/spec/test_app/app/views/password_less_sample/show_loosing_door.html.erb +10 -0
- data/spec/test_app/app/views/static/index.html.erb +12 -0
- data/spec/test_app/app/views/static/only_confirmed_email_allowed.html.erb +10 -0
- data/spec/test_app/app/views/static/page_that_require_password_reconfirmation.html.erb +16 -0
- data/spec/test_app/app/views/static/session_protected_page.html.erb +32 -0
- data/spec/test_app/bin/bundle +3 -0
- data/spec/test_app/bin/rails +4 -0
- data/spec/test_app/bin/rake +4 -0
- data/spec/test_app/config.ru +4 -0
- data/spec/test_app/config/application.rb +29 -0
- data/spec/test_app/config/boot.rb +5 -0
- data/spec/test_app/config/database.yml +25 -0
- data/spec/test_app/config/environment.rb +19 -0
- data/spec/test_app/config/environments/development.rb +50 -0
- data/spec/test_app/config/environments/production.rb +83 -0
- data/spec/test_app/config/environments/test.rb +48 -0
- data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
- data/spec/test_app/config/initializers/door_mat.rb +72 -0
- data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/test_app/config/initializers/inflections.rb +16 -0
- data/spec/test_app/config/initializers/mime_types.rb +4 -0
- data/spec/test_app/config/initializers/session_store.rb +3 -0
- data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/test_app/config/locales/en.yml +23 -0
- data/spec/test_app/config/routes.rb +42 -0
- data/spec/test_app/config/secrets.yml +31 -0
- data/spec/test_app/db/migrate/20140717182813_create_user_details.rb +10 -0
- data/spec/test_app/db/migrate/20140908225256_create_shared_data.rb +10 -0
- data/spec/test_app/db/migrate/20140908225604_create_shared_keys.rb +11 -0
- data/spec/test_app/db/migrate/20141121190714_create_games.rb +10 -0
- data/spec/test_app/public/404.html +67 -0
- data/spec/test_app/public/422.html +67 -0
- data/spec/test_app/public/500.html +66 -0
- data/spec/test_app/public/favicon.ico +0 -0
- metadata +552 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Process
|
|
3
|
+
class ActorSignIn
|
|
4
|
+
|
|
5
|
+
def self.with(email, password, is_public, remember_me, request, cookies)
|
|
6
|
+
# Destroy any session linked to existing cookies before
|
|
7
|
+
# replacing it by a new session
|
|
8
|
+
DoorMat::Session.destroy_if_linked_to(cookies)
|
|
9
|
+
|
|
10
|
+
actor = DoorMat::Actor.authenticate_with(email, password)
|
|
11
|
+
return false if actor.blank?
|
|
12
|
+
|
|
13
|
+
DoorMat::Session.for(actor, password, request)
|
|
14
|
+
return false unless DoorMat::Session.current_session.valid?
|
|
15
|
+
|
|
16
|
+
if is_public
|
|
17
|
+
DoorMat::Session.current_session.public_computer!
|
|
18
|
+
else
|
|
19
|
+
DoorMat::Session.current_session.private_computer!
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# User requested to be remembered
|
|
23
|
+
if DoorMat.configuration.allow_remember_me_feature && remember_me
|
|
24
|
+
DoorMat::Session.current_session.remember_me! unless (
|
|
25
|
+
DoorMat.configuration.remember_me_require_private_computer_confirmation &&
|
|
26
|
+
DoorMat::Session.current_session.public_computer?
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
actor.sessions << DoorMat::Session.current_session
|
|
31
|
+
DoorMat::Session.current_session.set_up(cookies)
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Process
|
|
3
|
+
class ActorSignUp
|
|
4
|
+
|
|
5
|
+
def self.with(address, password, request, cookies, controller)
|
|
6
|
+
# Destroy any session linked to existing cookies before
|
|
7
|
+
# replacing it by a new session
|
|
8
|
+
DoorMat::Session.destroy_if_linked_to(cookies)
|
|
9
|
+
|
|
10
|
+
# Sign up with the credentials of
|
|
11
|
+
# an existing account fails
|
|
12
|
+
return false if DoorMat::Actor.authenticate_with(address, password)
|
|
13
|
+
|
|
14
|
+
actor = DoorMat::Actor.create_with(password)
|
|
15
|
+
return false if actor.blank?
|
|
16
|
+
|
|
17
|
+
email = DoorMat::Email.for(address)
|
|
18
|
+
email.status = :not_available if DoorMat::Email.count_matching(address) >= DoorMat::configuration.plausible_deniability_count
|
|
19
|
+
actor.current_email = email
|
|
20
|
+
DoorMat::Session.for(actor, password, request)
|
|
21
|
+
return false unless DoorMat::Session.current_session.valid?
|
|
22
|
+
|
|
23
|
+
actor.sessions << DoorMat::Session.current_session
|
|
24
|
+
actor.emails << email
|
|
25
|
+
|
|
26
|
+
# setup public key pairs
|
|
27
|
+
actor.setup_public_key_pairs(DoorMat::Session.current_session)
|
|
28
|
+
|
|
29
|
+
return false unless actor.save
|
|
30
|
+
|
|
31
|
+
DoorMat::Session.current_session.set_up(cookies)
|
|
32
|
+
DoorMat::ActivityConfirmEmail.for(email, controller)
|
|
33
|
+
DoorMat::ActivityDownloadRecoveryKey.for(actor)
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Process
|
|
3
|
+
class CreateNewAnonymousActor
|
|
4
|
+
|
|
5
|
+
def self.owned_by(owner)
|
|
6
|
+
password = DoorMat::Crypto::SymmetricStore.random_key
|
|
7
|
+
anonymous_actor = Actor.create_with(password)
|
|
8
|
+
return nil if anonymous_actor.blank?
|
|
9
|
+
|
|
10
|
+
sub_session = DoorMat::Session.new_sub_session_for_actor(anonymous_actor, password)
|
|
11
|
+
anonymous_actor.setup_public_key_pairs(sub_session)
|
|
12
|
+
|
|
13
|
+
owner.with_lock do
|
|
14
|
+
anonymous_actor.save!
|
|
15
|
+
|
|
16
|
+
if DoorMat::Session.current_session.append_sub_session(sub_session)
|
|
17
|
+
membership = DoorMat::Membership.new
|
|
18
|
+
membership.member = owner
|
|
19
|
+
membership.member_of = anonymous_actor
|
|
20
|
+
membership.sponsor = DoorMat::Membership.sponsors[:sponsor_true]
|
|
21
|
+
membership.owner = DoorMat::Membership.owners[:owner_true]
|
|
22
|
+
membership.permission = DoorMat::Membership.permissions[:no_permission]
|
|
23
|
+
membership.key = password
|
|
24
|
+
membership.save!
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
anonymous_actor
|
|
29
|
+
rescue Exception => e
|
|
30
|
+
DoorMat.configuration.logger.error "ERROR: CreateNewAnonymousActor failed to with error - #{e}"
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Process
|
|
3
|
+
class ManageEmail
|
|
4
|
+
|
|
5
|
+
def self.add(email, actor, controller)
|
|
6
|
+
return false unless email.valid?
|
|
7
|
+
|
|
8
|
+
actor.with_lock do
|
|
9
|
+
return false unless actor.can_add_email? email
|
|
10
|
+
|
|
11
|
+
email.status = :not_available if DoorMat::Email.count_matching(email.address) > DoorMat::configuration.plausible_deniability_count
|
|
12
|
+
|
|
13
|
+
actor.emails << email
|
|
14
|
+
|
|
15
|
+
DoorMat::ActivityConfirmEmail.for(email, controller)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
true
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.set_primary(encoded_address, actor)
|
|
22
|
+
actor.with_lock do
|
|
23
|
+
email = actor.email_from_urlsafe_encoded(encoded_address)
|
|
24
|
+
return false if email.blank?
|
|
25
|
+
|
|
26
|
+
return true if email.primary?
|
|
27
|
+
|
|
28
|
+
return false unless email.confirmed?
|
|
29
|
+
|
|
30
|
+
actor.emails.primary.each do |e|
|
|
31
|
+
e.confirmed!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
email.primary!
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Process
|
|
3
|
+
class ResetPassword
|
|
4
|
+
|
|
5
|
+
def self.for(address, controller)
|
|
6
|
+
emails = DoorMat::Email.confirmed_matching(address)
|
|
7
|
+
return false if emails.blank?
|
|
8
|
+
|
|
9
|
+
# Several DoorMat::Email could match the address
|
|
10
|
+
# pick the first one for now.
|
|
11
|
+
# They will all be tested at reset time to apply the reset to the proper one
|
|
12
|
+
email = emails.first
|
|
13
|
+
|
|
14
|
+
# Because email was loaded without a valid session
|
|
15
|
+
# the address attribute is still encrypted.
|
|
16
|
+
# Temporarily update it here with the plain text.
|
|
17
|
+
# The reason it is trusted is because the hash
|
|
18
|
+
# of the user input matched a previously confirmed email address
|
|
19
|
+
# hash already in the system.
|
|
20
|
+
email.address = address
|
|
21
|
+
|
|
22
|
+
DoorMat::ActivityResetPassword.for(email, controller)
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.with(forgot_password)
|
|
27
|
+
emails = DoorMat::Email.confirmed_matching(forgot_password.email)
|
|
28
|
+
return false if emails.blank?
|
|
29
|
+
|
|
30
|
+
activity = DoorMat::ActivityResetPassword.with(forgot_password.token, emails)
|
|
31
|
+
return false if activity.blank?
|
|
32
|
+
|
|
33
|
+
return false if forgot_password.recovery_key.blank?
|
|
34
|
+
recovery_key = forgot_password.recovery_key.read
|
|
35
|
+
|
|
36
|
+
emails.each do |email|
|
|
37
|
+
if DoorMat::Process::ActorPasswordChange.after_password_reset(email.actor, forgot_password.password, recovery_key)
|
|
38
|
+
DoorMat::ActivityDownloadRecoveryKey.for(email.actor)
|
|
39
|
+
activity.done!
|
|
40
|
+
return true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
activity.failed!
|
|
45
|
+
return false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module Regex
|
|
3
|
+
|
|
4
|
+
def self.simple_email
|
|
5
|
+
# http://tools.ietf.org/html/rfc3696#section-3
|
|
6
|
+
# min 1 char local part and min 2 char domain part
|
|
7
|
+
# max 64 char local part and max 255 char domain part
|
|
8
|
+
# first and last char can not be blank
|
|
9
|
+
/\A\S.{0,63}@.{1,254}\S\z/
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.session_guid
|
|
13
|
+
/\A[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}\z/
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module DoorMat
|
|
2
|
+
module TestHelper
|
|
3
|
+
|
|
4
|
+
def self.create_signed_up_actor_with_confirmed_email_address(address="me@example.com", password="n7f3d;3#)")
|
|
5
|
+
actor, _ = create_signed_in_actor_with_confirmed_email_address(address, password)
|
|
6
|
+
DoorMat::Session.clear_current_session
|
|
7
|
+
actor
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.create_signed_in_actor_with_confirmed_email_address(address="me@example.com", password="n7f3d;3#)")
|
|
11
|
+
DoorMat::Session.clear_current_session
|
|
12
|
+
actor = DoorMat::Actor.create_with(password)
|
|
13
|
+
|
|
14
|
+
email = DoorMat::Email.for(address)
|
|
15
|
+
email.status = :primary
|
|
16
|
+
|
|
17
|
+
session = DoorMat::Session.new
|
|
18
|
+
session.ip = "request.remote_ip"
|
|
19
|
+
session.agent = "request.user_agent"
|
|
20
|
+
actor.current_email = email
|
|
21
|
+
|
|
22
|
+
RequestStore.store[:current_session] = session.initialize_with(actor, password)
|
|
23
|
+
|
|
24
|
+
actor.sessions << DoorMat::Session.current_session
|
|
25
|
+
actor.emails << email
|
|
26
|
+
|
|
27
|
+
# setup public key pairs
|
|
28
|
+
actor.setup_public_key_pairs(DoorMat::Session.current_session)
|
|
29
|
+
|
|
30
|
+
actor.save!
|
|
31
|
+
|
|
32
|
+
DoorMat::ActivityDownloadRecoveryKey.for(actor)
|
|
33
|
+
[actor, RequestStore.store[:current_session]]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.sign_in_existing_actor(address="me@example.com", password="n7f3d;3#)")
|
|
37
|
+
DoorMat::Session.clear_current_session
|
|
38
|
+
actor = DoorMat::Actor.authenticate_with(address, password)
|
|
39
|
+
|
|
40
|
+
session = DoorMat::Session.new
|
|
41
|
+
session.ip = "request.remote_ip"
|
|
42
|
+
session.agent = "request.user_agent"
|
|
43
|
+
|
|
44
|
+
RequestStore.store[:current_session] = session.initialize_with(actor, password)
|
|
45
|
+
|
|
46
|
+
actor.sessions << DoorMat::Session.current_session
|
|
47
|
+
actor.save!
|
|
48
|
+
|
|
49
|
+
[actor, RequestStore.store[:current_session]]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def self.sign_out(session)
|
|
53
|
+
session.destroy! if session.persisted?
|
|
54
|
+
RequestStore.store[:current_session] = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'door_mat'
|
|
2
|
+
require 'door_mat/test_helper'
|
|
3
|
+
|
|
4
|
+
namespace :door_mat do
|
|
5
|
+
|
|
6
|
+
desc "Create an admin actor in the system, useful if you need to share data between a user and the system - specify admin_account_email and admin_account_pwd in your rails secret file using environment variables."
|
|
7
|
+
task :create_admin_actor => :environment do
|
|
8
|
+
|
|
9
|
+
if DoorMat::Email.matching(Rails.application.secrets.admin_account_email).count == 0
|
|
10
|
+
DoorMat::TestHelper.create_signed_up_actor_with_confirmed_email_address(
|
|
11
|
+
Rails.application.secrets.admin_account_email,
|
|
12
|
+
Rails.application.secrets.admin_account_pwd
|
|
13
|
+
)
|
|
14
|
+
puts "SUCCESS: #{Rails.application.secrets.admin_account_email} is now defined in the database"
|
|
15
|
+
else
|
|
16
|
+
puts "ERROR: #{Rails.application.secrets.admin_account_email} is already defined in the database"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc "Environment cleanup before building gem"
|
|
22
|
+
task :cleanup => :environment do
|
|
23
|
+
list = Dir['spec/test_app/db/*sqlite3', 'spec/test_app/db/schema.rb', 'spec/test_app/tmp', 'spec/test_app/log/*log']
|
|
24
|
+
list.each do |file|
|
|
25
|
+
FileUtils.remove_entry_secure(file)
|
|
26
|
+
puts file
|
|
27
|
+
end
|
|
28
|
+
puts "Ready to run: rake build"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module DoorMat
|
|
4
|
+
describe ActivitiesController do
|
|
5
|
+
routes { DoorMat::Engine.routes }
|
|
6
|
+
let(:user) { {email: 'user@example.com', password: 'k#dkvKfdj38g!'} }
|
|
7
|
+
|
|
8
|
+
describe '#resend_email_confirmation' do
|
|
9
|
+
it 'redirects to :back if the email is invalid' do
|
|
10
|
+
_, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
11
|
+
@request.headers["HTTP_REFERER"] = '/some_path'
|
|
12
|
+
post :resend_email_confirmation, {email: 'invalid_email'}
|
|
13
|
+
expect(response).to have_http_status(302)
|
|
14
|
+
expect(response).to redirect_to('/some_path')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'redirects to :confirm_email_success if the email is already confirmed' do
|
|
18
|
+
actor, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
19
|
+
@request.headers["HTTP_REFERER"] = '/some_path'
|
|
20
|
+
post :resend_email_confirmation, {email: actor.current_email.to_urlsafe_encoded}
|
|
21
|
+
expect(response).to have_http_status(302)
|
|
22
|
+
expect(response).to redirect_to('/confirm_email_success')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'redirects to :back if the address is not confirmed' do
|
|
26
|
+
actor, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
27
|
+
email = DoorMat::Email.for('new_address@example.com')
|
|
28
|
+
actor.emails << email
|
|
29
|
+
|
|
30
|
+
@request.headers["HTTP_REFERER"] = '/some_path'
|
|
31
|
+
post :resend_email_confirmation, {email: email.to_urlsafe_encoded}
|
|
32
|
+
expect(response).to have_http_status(302)
|
|
33
|
+
expect(response).to redirect_to('/some_path')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
it 'redirects to main app root url if the address is not confirmed and HTTP_REFERER is not set' do
|
|
38
|
+
actor, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
39
|
+
email = DoorMat::Email.for('new_address@example.com')
|
|
40
|
+
actor.emails << email
|
|
41
|
+
|
|
42
|
+
post :resend_email_confirmation, {email: email.to_urlsafe_encoded}
|
|
43
|
+
expect(response).to have_http_status(302)
|
|
44
|
+
expect(response).to redirect_to('/')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe '#confirm_email' do
|
|
50
|
+
it 'redirects to :back after an invalid email confirmation request' do
|
|
51
|
+
_, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
52
|
+
@request.headers["HTTP_REFERER"] = '/some_path'
|
|
53
|
+
get :confirm_email, {token: 'invalid_token', email: 'invalid_email'}
|
|
54
|
+
expect(response).to have_http_status(302)
|
|
55
|
+
expect(response).to redirect_to('/some_path')
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe '#download_recovery_key' do
|
|
60
|
+
it 'redirects to :back after an invalid download request' do
|
|
61
|
+
_, _ = TestHelper::create_signed_in_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
62
|
+
@request.headers["HTTP_REFERER"] = '/some_path'
|
|
63
|
+
post :download_recovery_key
|
|
64
|
+
expect(response).to have_http_status(302)
|
|
65
|
+
expect(response).to redirect_to('/some_path')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module DoorMat
|
|
4
|
+
describe ForgotPasswordsController do
|
|
5
|
+
routes { DoorMat::Engine.routes }
|
|
6
|
+
let(:user) { {email: 'user@example.com', password: 'k#dkvKfdj38g!'} }
|
|
7
|
+
|
|
8
|
+
describe '#create' do
|
|
9
|
+
render_views
|
|
10
|
+
|
|
11
|
+
it 'render new if the user input validation fails' do
|
|
12
|
+
post :create, forgot_password: {email: 'email'}
|
|
13
|
+
expect(response).to have_http_status(200)
|
|
14
|
+
expect(response.body).to match(/Email is invalid/)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'redirects the user to the same page no matter if the email exists or not in the system' do
|
|
18
|
+
_ = TestHelper::create_signed_up_actor_with_confirmed_email_address(user[:email], user[:password])
|
|
19
|
+
|
|
20
|
+
post :create, {"utf8"=>"✓", "forgot_password"=>{"email"=>user[:email]} }
|
|
21
|
+
expect(response).to have_http_status(302)
|
|
22
|
+
expect(response).to redirect_to('/forgot_password_verification_mail_sent')
|
|
23
|
+
|
|
24
|
+
post :create, {"utf8"=>"✓", "forgot_password"=>{"email"=>"not_an_actual_user@example.com"} }
|
|
25
|
+
expect(response).to have_http_status(302)
|
|
26
|
+
expect(response).to redirect_to('/forgot_password_verification_mail_sent')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
describe '#reset_password' do
|
|
32
|
+
render_views
|
|
33
|
+
|
|
34
|
+
it 'render choose_new_password if something is wrong with the user inputs' do
|
|
35
|
+
post :reset_password, forgot_password: {email: 'email'}
|
|
36
|
+
expect(response).to have_http_status(200)
|
|
37
|
+
expect(response.body).to match(/Password is too short/)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'redirects the user to the sign in url if the password reset is successful' do
|
|
41
|
+
allow(DoorMat::Process::ResetPassword).to receive(:with).and_return(true)
|
|
42
|
+
post :reset_password, forgot_password: {email: user[:email], password: user[:password], password_confirmation: user[:password]}
|
|
43
|
+
expect(response).to have_http_status(302)
|
|
44
|
+
expect(response).to redirect_to('/sign_in')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'redirect the user to the start of the forgot password recovery process if an error occurs' do
|
|
48
|
+
allow(DoorMat::Process::ResetPassword).to receive(:with).and_return(false)
|
|
49
|
+
post :reset_password, forgot_password: {email: user[:email], password: user[:password], password_confirmation: user[:password]}
|
|
50
|
+
expect(response).to have_http_status(302)
|
|
51
|
+
expect(response).to redirect_to('/forgot_password')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|