From d6241631c9ffd9f636db3d9e547ba9cdb72e3de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Thu, 25 Aug 2016 15:14:20 +0200 Subject: [PATCH 1/7] Render path links depending on the configuration --- .../stormpath/rails/forgot_password/new.html.erb | 4 +++- app/views/stormpath/rails/register/new.html.erb | 4 +++- spec/features/forgot_password_feature_spec.rb | 12 ++++++++++++ spec/features/login_feature_spec.rb | 11 +++++++++++ spec/features/register_feature_spec.rb | 12 ++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/views/stormpath/rails/forgot_password/new.html.erb b/app/views/stormpath/rails/forgot_password/new.html.erb index c7c4943..2ffbaee 100644 --- a/app/views/stormpath/rails/forgot_password/new.html.erb +++ b/app/views/stormpath/rails/forgot_password/new.html.erb @@ -37,7 +37,9 @@ <% end %> - <%= link_to "Back to Log In", new_login_path, class: "forgot" %> + <% if Stormpath::Rails.config.web.login.enabled %> + <%= link_to "Back to Log In", new_login_path, class: "forgot" %> + <% end %> diff --git a/app/views/stormpath/rails/register/new.html.erb b/app/views/stormpath/rails/register/new.html.erb index 4c44dc8..8ec61f9 100644 --- a/app/views/stormpath/rails/register/new.html.erb +++ b/app/views/stormpath/rails/register/new.html.erb @@ -4,7 +4,9 @@
<%= render partial: 'stormpath/rails/register/form' %>
- <%= link_to "Back to Log In", new_login_path, class: "to-login" %> + <% if Stormpath::Rails.config.web.login.enabled %> + <%= link_to "Back to Log In", new_login_path, class: "to-login" %> + <% end %> diff --git a/spec/features/forgot_password_feature_spec.rb b/spec/features/forgot_password_feature_spec.rb index a4b0d0f..b5e76f5 100644 --- a/spec/features/forgot_password_feature_spec.rb +++ b/spec/features/forgot_password_feature_spec.rb @@ -15,6 +15,7 @@ } end + before { Rails.application.reload_routes! } after { account.delete } describe 'GET /forgot' do @@ -27,6 +28,17 @@ visit 'forgot' expect(find_field('email')['placeholder']).to eq('Email') end + + it 'should render the page when login is disabled' do + allow(configuration.web.login).to receive(:enabled).and_return(false) + + Rails.application.reload_routes! + + visit 'forgot' + expect(page.status_code).to eq(200) + expect(page).to have_content('Submit') + expect(page).not_to have_content('Back to Log In') + end end describe 'POST /forgot' do diff --git a/spec/features/login_feature_spec.rb b/spec/features/login_feature_spec.rb index e1b286e..4b24410 100644 --- a/spec/features/login_feature_spec.rb +++ b/spec/features/login_feature_spec.rb @@ -66,6 +66,17 @@ expect(page).to have_content('Log in') end + it 'does not blow up with wrong path helpers when forgot_password is disabled' do + allow(configuration.web.forgot_password).to receive(:enabled).and_return(false) + + Rails.application.reload_routes! + + visit 'login' + + expect(page.status_code).to eq(200) + expect(page).to have_content('Log in') + end + xit 'shows social logins when needed' do end diff --git a/spec/features/register_feature_spec.rb b/spec/features/register_feature_spec.rb index 45641f9..b83c033 100644 --- a/spec/features/register_feature_spec.rb +++ b/spec/features/register_feature_spec.rb @@ -16,6 +16,7 @@ type: 'text' ) reload_form_class + Rails.application.reload_routes! end after do @@ -47,6 +48,17 @@ expect(find_field('password')['placeholder']).to eq('Password') expect(find_field('confirmPassword')['placeholder']).to eq('Confirm Password') end + + it 'should render the page when login is disabled' do + allow(configuration.web.login).to receive(:enabled).and_return(false) + + Rails.application.reload_routes! + + visit 'register' + expect(page.status_code).to eq(200) + expect(page).to have_content('Create Account') + expect(page).not_to have_content('Back to Log In') + end end describe 'POST /register' do From a085ae15e2d178409234c380713e620ba936c9c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Thu, 25 Aug 2016 17:39:04 +0200 Subject: [PATCH 2/7] Add missing cases for links dependent on configuration --- app/views/stormpath/rails/login/_form.html.erb | 7 ++++++- app/views/stormpath/rails/register/_form.html.erb | 2 +- app/views/stormpath/rails/verify_email/new.html.erb | 4 +++- spec/features/email_verification_spec.rb | 11 +++++++++++ spec/features/login_feature_spec.rb | 12 ++++++++++++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/views/stormpath/rails/login/_form.html.erb b/app/views/stormpath/rails/login/_form.html.erb index 9f57dab..39dd016 100644 --- a/app/views/stormpath/rails/login/_form.html.erb +++ b/app/views/stormpath/rails/login/_form.html.erb @@ -17,7 +17,12 @@ <% case params[:status] %> <% when 'unverified' %>
-

Your account verification email has been sent! Before you can log into your account, you need to activate your account by clicking the link we sent to your inbox. Didn't get the email? <%= link_to "Click Here", Stormpath::Rails.config.web.verify_email.uri %>

+ <% if Stormpath::Rails.config.web.verify_email.enabled %> +

+ Your account verification email has been sent! Before you can log into your account, you need to activate your account by clicking the link we sent to your inbox. Didn't get the email? + <%= link_to "Click Here", Stormpath::Rails.config.web.verify_email.uri %> +

+ <% end %>
<% when 'verified' %>
diff --git a/app/views/stormpath/rails/register/_form.html.erb b/app/views/stormpath/rails/register/_form.html.erb index 1f2d5b5..57647ac 100644 --- a/app/views/stormpath/rails/register/_form.html.erb +++ b/app/views/stormpath/rails/register/_form.html.erb @@ -14,6 +14,6 @@ <%= render 'stormpath/rails/shared/input', form: form, input_config: Stormpath::Rails.config.web.register.form.fields.send(field), input_name: field.to_s.camelize(:lower), value: params[field.to_s.camelize(:lower)] %> <% end %> - <%= button_tag "Create Account", :class => "btn btn-register btn-sp-green", :type => "submit" %> + <%= button_tag "Create Account", class: "btn btn-register btn-sp-green", type: "submit" %> <% end %>
diff --git a/app/views/stormpath/rails/verify_email/new.html.erb b/app/views/stormpath/rails/verify_email/new.html.erb index 872fa64..f087576 100644 --- a/app/views/stormpath/rails/verify_email/new.html.erb +++ b/app/views/stormpath/rails/verify_email/new.html.erb @@ -43,7 +43,9 @@ <% end %> - <%= link_to "Back to Log In", new_login_path, class: "forgot" %> + <% if Stormpath::Rails.config.web.login.enabled %> + <%= link_to "Back to Log In", new_login_path, class: "forgot" %> + <% end %> diff --git a/spec/features/email_verification_spec.rb b/spec/features/email_verification_spec.rb index 8756830..8b7cf5d 100644 --- a/spec/features/email_verification_spec.rb +++ b/spec/features/email_verification_spec.rb @@ -44,6 +44,17 @@ folder." ) end + + it 'does not blow up with wrong path helpers when login is disabled' do + allow(configuration.web.login).to receive(:enabled).and_return(false) + + Rails.application.reload_routes! + + visit 'verify' + + expect(page.status_code).to eq(200) + expect(page).not_to have_content('Back to Log In') + end end describe 'with invalid sptoken' do diff --git a/spec/features/login_feature_spec.rb b/spec/features/login_feature_spec.rb index 26399ba..4ee7f78 100644 --- a/spec/features/login_feature_spec.rb +++ b/spec/features/login_feature_spec.rb @@ -77,6 +77,18 @@ expect(page).to have_content('Log in') end + it 'does not blow up with wrong path helpers when verify_email is disabled' do + allow(configuration.web.verify_email).to receive(:enabled).and_return(false) + + Rails.application.reload_routes! + + visit 'login' + + expect(page.status_code).to eq(200) + expect(page).not_to have_content('Click Here') + expect(page).to have_content('Log in') + end + xit 'shows social logins when needed' do end From 3045ee39dcd54ff9328ae8bada195d28e3aad622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Fri, 26 Aug 2016 10:43:56 +0200 Subject: [PATCH 3/7] Fix failing build by setting the configuration for verifying email to enabled --- spec/features/register_feature_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/features/register_feature_spec.rb b/spec/features/register_feature_spec.rb index 9c8428e..ef0471b 100644 --- a/spec/features/register_feature_spec.rb +++ b/spec/features/register_feature_spec.rb @@ -138,6 +138,9 @@ def delete_test_account end it 'creates an account and redirects to login with status UNVERIFIED' do + allow(configuration.web.verify_email).to receive(:enabled).and_return(true) + Rails.application.reload_routes! + visit 'register' fill_in 'givenName', with: 'Damir' From 3422f3f98a083532400a856aa9cb4eaeac63f866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Fri, 26 Aug 2016 14:31:51 +0200 Subject: [PATCH 4/7] Use _path helper for verify emails path links --- spec/dummy/config/stormpath.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/dummy/config/stormpath.yml b/spec/dummy/config/stormpath.yml index ae865da..66e8093 100644 --- a/spec/dummy/config/stormpath.yml +++ b/spec/dummy/config/stormpath.yml @@ -120,7 +120,7 @@ stormpath: # store for the defined Stormpath application has the email verification # workflow enabled. verifyEmail: - enabled: null + enabled: true uri: "/verify" nextUri: "/login?status=verified" view: "stormpath/rails/verify_email/new" From e9b6acd971f72757820811c81d9f5191eb8ab404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Fri, 26 Aug 2016 15:55:00 +0200 Subject: [PATCH 5/7] Use path helper for verify email link in login form --- app/views/stormpath/rails/login/_form.html.erb | 2 +- lib/stormpath/rails/router.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/stormpath/rails/login/_form.html.erb b/app/views/stormpath/rails/login/_form.html.erb index 39dd016..31306c4 100644 --- a/app/views/stormpath/rails/login/_form.html.erb +++ b/app/views/stormpath/rails/login/_form.html.erb @@ -20,7 +20,7 @@ <% if Stormpath::Rails.config.web.verify_email.enabled %>

Your account verification email has been sent! Before you can log into your account, you need to activate your account by clicking the link we sent to your inbox. Didn't get the email? - <%= link_to "Click Here", Stormpath::Rails.config.web.verify_email.uri %> + <%= link_to "Click Here", new_verify_email_path %>

<% end %> diff --git a/lib/stormpath/rails/router.rb b/lib/stormpath/rails/router.rb index c57fd32..9513c43 100644 --- a/lib/stormpath/rails/router.rb +++ b/lib/stormpath/rails/router.rb @@ -63,7 +63,7 @@ def stormpath_rails_routes(actions: {}) # VERIFY EMAIL if Stormpath::Rails.config.web.verify_email.enabled - get Stormpath::Rails.config.web.verify_email.uri => actions['verify_email#show'] + get Stormpath::Rails.config.web.verify_email.uri => actions['verify_email#show'], as: :new_verify_email post Stormpath::Rails.config.web.verify_email.uri => actions['verify_email#create'], as: :verify_email end end From f686f1bc7f08f1d3f30c7f60488a9de92b86ad57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Fri, 26 Aug 2016 16:39:12 +0200 Subject: [PATCH 6/7] Use factory girl attributes for to generate always random data and make travis pass --- spec/factories.rb | 7 ++ spec/requests/registration/post_spec.rb | 135 +++++------------------- 2 files changed, 36 insertions(+), 106 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index c11efe2..ba421d8 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -7,6 +7,13 @@ username { Faker::Internet.user_name } end + factory :account_without_username, class: Stormpath::Resource::Account do + sequence(:email) { |n| "dev#{n}@example.com" } + password 'Password1337' + given_name { Faker::Name.first_name } + surname { Faker::Name.last_name } + end + factory :unverified_account, parent: :account do status 'UNVERIFIED' end diff --git a/spec/requests/registration/post_spec.rb b/spec/requests/registration/post_spec.rb index 6482aac..aeef8e6 100644 --- a/spec/requests/registration/post_spec.rb +++ b/spec/requests/registration/post_spec.rb @@ -19,14 +19,15 @@ def delete_account Stormpath::Rails::Client.application.accounts.get(response_body['account']['href']).delete end - let(:user_attrs) do - { - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - username: 'SirExample' - } + let(:account_attrs) { FactoryGirl.attributes_for(:account_without_username) } + let(:account_attrs_with_blank_given_name) do + FactoryGirl.attributes_for(:account_without_username, given_name: nil) + end + let(:account_attrs_with_blank_email) do + FactoryGirl.attributes_for(:account_without_username, email: nil) + end + let(:account_attrs_with_blank_password) do + FactoryGirl.attributes_for(:account_without_username, password: nil) end describe 'json is enabled' do @@ -34,12 +35,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD' - ) + json_register_post(account_attrs) expect(response.status).to eq(200) end @@ -49,12 +45,7 @@ def delete_account end it 'respond with status 200 and sets cookies' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD' - ) + json_register_post(account_attrs) expect(response.status).to eq(200) expect(response.cookies['access_token']).to be expect(response.cookies['refresh_token']).to be @@ -64,11 +55,7 @@ def delete_account describe 'submit blank givenName' do it 'respond with status 400' do - json_register_post( - email: 'example@test.com', - surname: 'Test', - password: 'Pa$$W0RD' - ) + json_register_post(account_attrs_with_blank_given_name) expect(response.status).to eq(400) expect(error_message).to eq('First Name is required.') end @@ -89,12 +76,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD' - ) + json_register_post(account_attrs) expect(response.status).to eq(200) end end @@ -136,7 +118,7 @@ def delete_account end it 'respond with status 400' do - json_register_post(givenName: 'Example', surname: 'Test', password: 'Pa$$W0RD') + json_register_post(account_attrs_with_blank_email) expect(response.status).to eq(400) expect(error_message).to eq('Account email address is required; it cannot be null, empty, or blank.') end @@ -153,7 +135,7 @@ def delete_account end it 'respond with status 400' do - json_register_post(email: 'example@test.com', givenName: 'Example', surname: 'Test') + json_register_post(account_attrs_with_blank_password) expect(response.status).to eq(400) expect(error_message).to eq('Account password is required; it cannot be null, empty, or blank.') end @@ -180,13 +162,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - age: 25 - ) + json_register_post(account_attrs.merge(age: 25)) expect(response.status).to eq(200) account = Stormpath::Rails::Client.application.accounts.get( response_body['account']['href'] @@ -199,13 +175,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - customData: { age: 25 } - ) + json_register_post(account_attrs.merge(customData: { age: 25 })) expect(response.status).to eq(200) account = Stormpath::Rails::Client.application.accounts.get( response_body['account']['href'] @@ -217,12 +187,7 @@ def delete_account describe 'and not submitted' do it 'respond with status 400' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD' - ) + json_register_post(account_attrs) expect(error_message).to eq('Age is required.') expect(response.status).to eq(400) end @@ -248,13 +213,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - age: 25 - ) + json_register_post(account_attrs.merge(age: 25)) expect(response.status).to eq(200) end end @@ -263,13 +222,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - customData: { age: 25 } - ) + json_register_post(account_attrs.merge(customData: { age: 25 })) expect(response.status).to eq(200) end end @@ -290,25 +243,13 @@ def delete_account after { delete_account } it 'responds with status 200 if matches' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - confirmPassword: 'Pa$$W0RD' - ) + json_register_post(account_attrs.merge(confirmPassword: 'Password1337')) expect(response.status).to eq(200) end end it 'responds with status 400 if does not match' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - confirmPassword: 'Pa$$' - ) + json_register_post(account_attrs.merge(confirmPassword: 'Pa$$')) expect(response.status).to eq(400) expect(error_message).to eq('Passwords do not match') end @@ -327,7 +268,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post(email: 'example@test.com', surname: 'Test', password: 'Pa$$W0RD') + json_register_post(account_attrs.except(:given_name)) expect(response.status).to eq(200) expect(response_body['account']['givenName']).to eq('UNKNOWN') end @@ -346,7 +287,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post(email: 'example@test.com', givenName: 'Example', password: 'Pa$$W0RD') + json_register_post(account_attrs.except(:surname)) expect(response.status).to eq(200) expect(response_body['account']['surname']).to eq('UNKNOWN') end @@ -365,7 +306,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post(email: 'example@test.com', surname: 'Test', password: 'Pa$$W0RD') + json_register_post(account_attrs.except(:given_name)) expect(response.status).to eq(200) expect(response_body['account']['givenName']).to eq('UNKNOWN') end @@ -384,7 +325,7 @@ def delete_account after { delete_account } it 'respond with status 200' do - json_register_post(email: 'example@test.com', givenName: 'Example', password: 'Pa$$W0RD') + json_register_post(account_attrs.except(:surname)) expect(response.status).to eq(200) expect(response_body['account']['surname']).to eq('UNKNOWN') end @@ -393,13 +334,7 @@ def delete_account describe 'unknown field submission' do describe 'nested inside the root' do it 'respond with status 400' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - age: 25 - ) + json_register_post(account_attrs.merge(age: 25)) expect(response.status).to eq(400) expect(error_message).to eq("Can't submit arbitrary data: age") end @@ -407,13 +342,7 @@ def delete_account describe 'nested inside the customData hash' do it 'respond with status 400' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - customData: { age: 25 } - ) + json_register_post(account_attrs.merge(customData: { age: 25 })) expect(response.status).to eq(400) expect(error_message).to eq("Can't submit arbitrary data: age") end @@ -431,13 +360,7 @@ def delete_account end it 'respond with status 400' do - json_register_post( - email: 'example@test.com', - givenName: 'Example', - surname: 'Test', - password: 'Pa$$W0RD', - middleName: 'Hako' - ) + json_register_post(account_attrs.merge(middleName: 'Hako')) expect(response.status).to eq(400) expect(error_message).to eq("Can't submit arbitrary data: middle_name") end From aab26a0af3314e11b27ad651dbc483bce4cb8633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20=C4=86ilimkovi=C4=87?= Date: Mon, 29 Aug 2016 10:09:31 +0200 Subject: [PATCH 7/7] Dynamically configure verify email functionality --- lib/stormpath/rails/config/dynamic_configuration.rb | 10 ++++++++++ lib/stormpath/rails/configuration.rb | 1 + spec/dummy/config/stormpath.yml | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/stormpath/rails/config/dynamic_configuration.rb b/lib/stormpath/rails/config/dynamic_configuration.rb index e04ba8b..05c2504 100644 --- a/lib/stormpath/rails/config/dynamic_configuration.rb +++ b/lib/stormpath/rails/config/dynamic_configuration.rb @@ -26,6 +26,11 @@ def change_password_enabled? password_reset_enabled? end + def verify_email_enabled? + return false if static_config.stormpath.web.verify_email.enabled == false + email_verification_enabled? + end + private def password_reset_enabled? @@ -33,6 +38,11 @@ def password_reset_enabled? default_account_store.password_policy.reset_email_status == 'ENABLED' end + def email_verification_enabled? + return false if default_account_store.nil? + default_account_store.account_creation_policy.verification_email_status == 'ENABLED' + end + def default_account_store @default_account_store ||= app.default_account_store_mapping && app.default_account_store_mapping.account_store diff --git a/lib/stormpath/rails/configuration.rb b/lib/stormpath/rails/configuration.rb index 5cc7926..817bd06 100644 --- a/lib/stormpath/rails/configuration.rb +++ b/lib/stormpath/rails/configuration.rb @@ -26,6 +26,7 @@ def config_object config.stormpath.application.href = dynamic_config.app.href config.stormpath.web.forgot_password.enabled = dynamic_config.forgot_password_enabled? config.stormpath.web.change_password.enabled = dynamic_config.change_password_enabled? + config.stormpath.web.verify_email.enabled = dynamic_config.verify_email_enabled? end end diff --git a/spec/dummy/config/stormpath.yml b/spec/dummy/config/stormpath.yml index 66e8093..ae865da 100644 --- a/spec/dummy/config/stormpath.yml +++ b/spec/dummy/config/stormpath.yml @@ -120,7 +120,7 @@ stormpath: # store for the defined Stormpath application has the email verification # workflow enabled. verifyEmail: - enabled: true + enabled: null uri: "/verify" nextUri: "/login?status=verified" view: "stormpath/rails/verify_email/new"