From 13049ebeba11bf4940cf97e3ab21fee90271dc78 Mon Sep 17 00:00:00 2001 From: Gonzalo Riestra Date: Tue, 30 Oct 2018 12:34:48 +0100 Subject: [PATCH] Revert "Revert "Add forgot password fields to user"" --- NEWS.md | 2 +- .../carto/user_metadata_export_service.rb | 5 +- ...81023112320_add_password_reset_to_users.rb | 14 +++ .../user_metadata_export_service_spec.rb | 85 ++++++++++++------- 4 files changed, 73 insertions(+), 33 deletions(-) create mode 100644 db/migrate/20181023112320_add_password_reset_to_users.rb diff --git a/NEWS.md b/NEWS.md index e64f24ec79..ecb5a3fdc8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,7 +5,7 @@ Development - None yet ### Features -- None yet +- WIP: Forgot password (#14333) ### Bug fixes / enhancements - Scrollbar resized after notifications (#12953) diff --git a/app/services/carto/user_metadata_export_service.rb b/app/services/carto/user_metadata_export_service.rb index e6634a7b76..e4ed771997 100644 --- a/app/services/carto/user_metadata_export_service.rb +++ b/app/services/carto/user_metadata_export_service.rb @@ -17,10 +17,11 @@ require_dependency 'carto/export/connector_configuration_exporter' # 1.0.4: company and phone in users table # 1.0.5: synchronization_oauths and connector configurations # 1.0.6: client_applications & friends and sql_copy rate_limits +# 1.0.7: export password_reset_token and password_reset_sent_at user fields module Carto module UserMetadataExportServiceConfiguration - CURRENT_VERSION = '1.0.6'.freeze + CURRENT_VERSION = '1.0.7'.freeze EXPORTED_USER_ATTRIBUTES = [ :email, :crypted_password, :salt, :database_name, :username, :admin, :enabled, :invite_token, :invite_token_date, :map_enabled, :quota_in_bytes, :table_quota, :account_type, :private_tables_enabled, :period_end_date, @@ -39,7 +40,7 @@ module Carto :salesforce_datasource_enabled, :builder_enabled, :geocoder_provider, :isolines_provider, :routing_provider, :github_user_id, :engine_enabled, :mapzen_routing_quota, :mapzen_routing_block_price, :soft_mapzen_routing_limit, :no_map_logo, :org_admin, :last_name, :user_render_timeout, :database_render_timeout, :frontend_version, - :asset_host, :state, :company, :phone, :industry, :job_role + :asset_host, :state, :company, :phone, :industry, :job_role, :password_reset_token, :password_reset_sent_at ].freeze BLANK_UUID = '00000000-0000-0000-0000-000000000000'.freeze diff --git a/db/migrate/20181023112320_add_password_reset_to_users.rb b/db/migrate/20181023112320_add_password_reset_to_users.rb new file mode 100644 index 0000000000..d464b4aff9 --- /dev/null +++ b/db/migrate/20181023112320_add_password_reset_to_users.rb @@ -0,0 +1,14 @@ +require 'carto/db/migration_helper' + +include Carto::Db::MigrationHelper + +migration( + Proc.new do + add_column :users, :password_reset_token, String, null: true + add_column :users, :password_reset_sent_at, DateTime, null: true + end, + Proc.new do + drop_column :users, :password_reset_token + drop_column :users, :password_reset_sent_at + end +) diff --git a/spec/services/carto/user_metadata_export_service_spec.rb b/spec/services/carto/user_metadata_export_service_spec.rb index 8cda1048bd..c0e0b930a9 100644 --- a/spec/services/carto/user_metadata_export_service_spec.rb +++ b/spec/services/carto/user_metadata_export_service_spec.rb @@ -51,11 +51,15 @@ describe Carto::UserMetadataExportService do @remote_visualization.update_attributes!(user: @user) # Create SearchTweets: one associated to an existing table, and one with invalid table - @map2, @table2, @table_visualization2, @visualization2 = create_full_visualization(@user, visualization_attributes: { name: 'waduswadus22' }) + @map2, @table2, @table_visualization2, @visualization2 = create_full_visualization( + @user, visualization_attributes: { name: 'waduswadus22' } + ) @table2.data_import = FactoryGirl.create(:data_import, user: @user, table_id: @table2.id) @table2.save! @st1 = FactoryGirl.create(:carto_search_tweet, user_id: @user.id, data_import_id: @table2.data_import.id) - @st2 = FactoryGirl.create(:carto_search_tweet, user_id: @user.id, data_import_id: FactoryGirl.create(:data_import).id) + @st2 = FactoryGirl.create( + :carto_search_tweet, user_id: @user.id, data_import_id: FactoryGirl.create(:data_import).id + ) # Rate limits sequel_user = ::User[@user.id] @@ -88,7 +92,7 @@ describe Carto::UserMetadataExportService do user.update_attributes!(viewer: false) unless user.destroyed? gum = CartoDB::GeocoderUsageMetrics.new(user.username) - $users_metadata.DEL(gum.send(:user_key_prefix, :geocoder_here, :success_responses, DateTime.now)) + $users_metadata.DEL(gum.send(:user_key_prefix, :geocoder_here, :success_responses, Time.zone.now)) destroy_full_visualization(@map, @table, @table_visualization, @visualization) destroy_full_visualization(@map2, @table2, @table_visualization2, @visualization2) @@ -156,6 +160,13 @@ describe Carto::UserMetadataExportService do test_import_user_from_export(full_export) end + it 'imports 1.0.6 (without password_reset_token and password_reset_sent_at)' do + user = test_import_user_from_export(full_export_one_zero_six) + + expect(user.password_reset_token).to be_nil + expect(user.password_reset_sent_at).to be_nil + end + it 'imports 1.0.5 (without client_application)' do user = test_import_user_from_export(full_export_one_zero_five) @@ -183,13 +194,13 @@ describe Carto::UserMetadataExportService do end it 'imports 1.0.1 (without static notifications)' do - user = test_import_user_from_export(full_export_one_zero_one) + user = test_import_user_from_export(full_export_one_zero_one) expect(user.static_notifications.notifications).to be_empty end it 'imports 1.0.0 (without search tweets)' do - user = test_import_user_from_export(full_export_one_zero_zero) + user = test_import_user_from_export(full_export_one_zero_zero) expect(user.search_tweets).to be_empty end @@ -305,7 +316,8 @@ describe Carto::UserMetadataExportService do def expect_export_matches_user(export, user) Carto::UserMetadataExportService::EXPORTED_USER_ATTRIBUTES.each do |att| - expect(export[att]).to eq(user.attributes[att.to_s]), "attribute #{att.inspect} expected: #{user.attributes[att.to_s].inspect} got: #{export[att].inspect}" + error = "attribute #{att.inspect} expected: #{user.attributes[att.to_s].inspect} got: #{export[att].inspect}" + expect(export[att]).to eq(user.attributes[att.to_s]), error end expect(export[:layers].count).to eq user.layers.size @@ -371,22 +383,22 @@ describe Carto::UserMetadataExportService do expect(exported_search_tweet[:service_item_id]).to eq search_tweet.service_item_id expect(exported_search_tweet[:retrieved_items]).to eq search_tweet.retrieved_items expect(exported_search_tweet[:state]).to eq search_tweet.state - expect(exported_search_tweet[:created_at]).to eq search_tweet.created_at - expect(exported_search_tweet[:updated_at]).to eq search_tweet.updated_at + expect(exported_search_tweet[:created_at].to_s).to eq search_tweet.created_at.to_s + expect(exported_search_tweet[:updated_at].to_s).to eq search_tweet.updated_at.to_s end def expect_export_matches_synchronization_oauth(exported_so, so) expect(exported_so[:service]).to eq so.service expect(exported_so[:token]).to eq so.token - expect(exported_so[:created_at]).to eq so.created_at - expect(exported_so[:updated_at]).to eq so.updated_at + expect(exported_so[:created_at].to_s).to eq so.created_at.to_s + expect(exported_so[:updated_at].to_s).to eq so.updated_at.to_s end def expect_export_matches_connector_configuration(exported_cc, cc) expect(exported_cc[:enabled]).to eq cc.enabled expect(exported_cc[:max_rows]).to eq cc.max_rows - expect(exported_cc[:created_at]).to eq cc.created_at - expect(exported_cc[:updated_at]).to eq cc.updated_at + expect(exported_cc[:created_at].to_s).to eq cc.created_at.to_s + expect(exported_cc[:updated_at].to_s).to eq cc.updated_at.to_s expect(exported_cc[:provider_name]).to eq cc.connector_provider.name end @@ -546,6 +558,12 @@ describe Carto::UserMetadataExportService do end end + let(:service_item_id) do + '{\"dates\":{\"fromDate\":\"2014-07-29\",\"fromHour\":0,\"fromMin\":0,\"toDate\":'\ + '\"2014-08-27\",\"toHour\":23,\"toMin\":59,\"user_timezone\":0,\"max_days\":30},\"categories\":'\ + '[{\"terms\":[\"cartodb\"],\"category\":\"1\",\"counter\":1007}]}' + end + let(:full_export) do { version: "1.0.6", @@ -582,8 +600,8 @@ describe Carto::UserMetadataExportService do api_key: "21ee521b8a107ea55d61fd7b485dd93d54c0b9d2", notification: nil, organization_id: nil, - created_at: DateTime.now, - updated_at: DateTime.now, + created_at: Time.zone.now, + updated_at: Time.zone.now, disqus_shortname: nil, id: "5be8c3d4-49f0-11e7-8698-bc5ff4c95cd0", twitter_username: nil, @@ -742,8 +760,8 @@ describe Carto::UserMetadataExportService do type: 'import', entries: '' }, - updated_at: DateTime.now, - created_at: DateTime.now, + updated_at: Time.zone.now, + created_at: Time.zone.now, error_code: nil, queue_id: nil, tables_created_count: nil, @@ -754,7 +772,7 @@ describe Carto::UserMetadataExportService do from_query: nil, id: '118813f4-c943-4583-822e-111ed0b51ca4', service_name: 'twitter_search', - service_item_id: '{\"dates\":{\"fromDate\":\"2014-07-29\",\"fromHour\":0,\"fromMin\":0,\"toDate\":\"2014-08-27\",\"toHour\":23,\"toMin\":59,\"user_timezone\":0,\"max_days\":30},\"categories\":[{\"terms\":[\"cartodb\"],\"category\":\"1\",\"counter\":1007}]}', + service_item_id: service_item_id, stats: '{}', type_guessing: true, quoted_fields_guessing: true, @@ -776,40 +794,40 @@ describe Carto::UserMetadataExportService do collision_strategy: nil, external_data_imports: [] }, - service_item_id: '{\"dates\":{\"fromDate\":\"2014-07-29\",\"fromHour\":0,\"fromMin\":0,\"toDate\":\"2014-08-27\",\"toHour\":23,\"toMin\":59,\"user_timezone\":0,\"max_days\":30},\"categories\":[{\"terms\":[\"cartodb\"],\"category\":\"1\",\"counter\":1007}]}', + service_item_id: service_item_id, retrieved_items: 123, state: 'complete', - created_at: DateTime.now, - updated_at: DateTime.now + created_at: Time.zone.now, + updated_at: Time.zone.now }, { data_import: nil, - service_item_id: '{\"dates\":{\"fromDate\":\"2014-07-29\",\"fromHour\":0,\"fromMin\":0,\"toDate\":\"2014-08-27\",\"toHour\":23,\"toMin\":59,\"user_timezone\":0,\"max_days\":30},\"categories\":[{\"terms\":[\"cartodb\"],\"category\":\"1\",\"counter\":1007}]}', + service_item_id: service_item_id, retrieved_items: 123, state: 'complete', - created_at: DateTime.now, - updated_at: DateTime.now + created_at: Time.zone.now, + updated_at: Time.zone.now } ], notifications: { builder: { onboarding: true, - :"layer-style-onboarding" => true, - :"layer-analyses-onboarding" => true + "layer-style-onboarding": true, + "layer-analyses-onboarding": true } }, synchronization_oauths: [ { service: 'gdrive', token: '1234567890', - created_at: DateTime.now, - updated_at: DateTime.now + created_at: Time.zone.now, + updated_at: Time.zone.now } ], connector_configurations: [ { - created_at: DateTime.now, - updated_at: DateTime.now, + created_at: Time.zone.now, + updated_at: Time.zone.now, enabled: true, max_rows: 100000, provider_name: @connector_provider.name @@ -853,8 +871,15 @@ describe Carto::UserMetadataExportService do } end + let(:full_export_one_zero_six) do + user_hash = full_export[:user].except!(:password_reset_token, :password_reset_sent_at) + + full_export[:user] = user_hash + full_export + end + let(:full_export_one_zero_five) do - user_hash = full_export[:user].except!(:client_application) + user_hash = full_export_one_zero_six[:user].except!(:client_application) limits_hash = full_export[:user][:rate_limit][:limits] full_export[:user] = user_hash full_export[:user][:rate_limit][:limits] = limits_hash.except!(:sql_copy_from).except!(:sql_copy_to)