diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/activitypub/replies_controller_spec.rb | 17 | ||||
-rw-r--r-- | spec/controllers/auth/sessions_controller_spec.rb | 66 | ||||
-rw-r--r-- | spec/fabricators/device_fabricator.rb | 8 | ||||
-rw-r--r-- | spec/fabricators/encrypted_message_fabricator.rb | 8 | ||||
-rw-r--r-- | spec/fabricators/one_time_key_fabricator.rb | 11 | ||||
-rw-r--r-- | spec/fabricators/system_key_fabricator.rb | 3 | ||||
-rw-r--r-- | spec/lib/activitypub/activity/create_spec.rb | 56 | ||||
-rw-r--r-- | spec/mailers/previews/user_mailer_preview.rb | 5 | ||||
-rw-r--r-- | spec/models/device_spec.rb | 5 | ||||
-rw-r--r-- | spec/models/encrypted_message_spec.rb | 5 | ||||
-rw-r--r-- | spec/models/one_time_key_spec.rb | 5 | ||||
-rw-r--r-- | spec/models/system_key_spec.rb | 5 | ||||
-rw-r--r-- | spec/services/clear_domain_media_service_spec.rb | 23 | ||||
-rw-r--r-- | spec/workers/domain_block_worker_spec.rb | 4 | ||||
-rw-r--r-- | spec/workers/domain_clear_media_worker_spec.rb | 26 |
15 files changed, 241 insertions, 6 deletions
diff --git a/spec/controllers/activitypub/replies_controller_spec.rb b/spec/controllers/activitypub/replies_controller_spec.rb index a5ed14180..d956e1b35 100644 --- a/spec/controllers/activitypub/replies_controller_spec.rb +++ b/spec/controllers/activitypub/replies_controller_spec.rb @@ -4,6 +4,7 @@ require 'rails_helper' RSpec.describe ActivityPub::RepliesController, type: :controller do let(:status) { Fabricate(:status, visibility: parent_visibility) } + let(:remote_reply_id) { nil } let(:remote_account) { nil } before do @@ -14,6 +15,8 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do Fabricate(:status, thread: status, visibility: :private) Fabricate(:status, account: status.account, thread: status, visibility: :public) Fabricate(:status, account: status.account, thread: status, visibility: :private) + + Fabricate(:status, account: remote_account, thread: status, visibility: :public, uri: remote_reply_id) if remote_reply_id end describe 'GET #index' do @@ -110,6 +113,20 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do expect(json[:first][:items].size).to eq 2 expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true end + + context 'with remote responses' do + let(:remote_reply_id) { 'foo' } + + it 'returned items are all inlined local toots or are ids' do + json = body_as_json + + expect(json[:first]).to be_a Hash + expect(json[:first][:items]).to be_an Array + expect(json[:first][:items].size).to eq 3 + expect(json[:first][:items].all? { |item| item.is_a?(Hash) ? ActivityPub::TagManager.instance.local_uri?(item[:id]) : item.is_a?(String) }).to be true + expect(json[:first][:items]).to include remote_reply_id + end + end end end diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index 1950c173a..c387842cd 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -215,7 +215,7 @@ RSpec.describe Auth::SessionsController, type: :controller do context 'using a valid OTP' do before do - post :create, params: { user: { otp_attempt: user.current_otp } }, session: { otp_user_id: user.id } + post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id } end it 'redirects to home' do @@ -230,7 +230,7 @@ RSpec.describe Auth::SessionsController, type: :controller do context 'when the server has an decryption error' do before do allow_any_instance_of(User).to receive(:validate_and_consume_otp!).and_raise(OpenSSL::Cipher::CipherError) - post :create, params: { user: { otp_attempt: user.current_otp } }, session: { otp_user_id: user.id } + post :create, params: { user: { otp_attempt: user.current_otp } }, session: { attempt_user_id: user.id } end it 'shows a login error' do @@ -244,7 +244,7 @@ RSpec.describe Auth::SessionsController, type: :controller do context 'using a valid recovery code' do before do - post :create, params: { user: { otp_attempt: recovery_codes.first } }, session: { otp_user_id: user.id } + post :create, params: { user: { otp_attempt: recovery_codes.first } }, session: { attempt_user_id: user.id } end it 'redirects to home' do @@ -258,7 +258,7 @@ RSpec.describe Auth::SessionsController, type: :controller do context 'using an invalid OTP' do before do - post :create, params: { user: { otp_attempt: 'wrongotp' } }, session: { otp_user_id: user.id } + post :create, params: { user: { otp_attempt: 'wrongotp' } }, session: { attempt_user_id: user.id } end it 'shows a login error' do @@ -270,5 +270,63 @@ RSpec.describe Auth::SessionsController, type: :controller do end end end + + context 'when 2FA is disabled and IP is unfamiliar' do + let!(:user) { Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', current_sign_in_at: 3.weeks.ago, current_sign_in_ip: '0.0.0.0') } + + before do + request.remote_ip = '10.10.10.10' + request.user_agent = 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0' + + allow(UserMailer).to receive(:sign_in_token).and_return(double('email', deliver_later!: nil)) + end + + context 'using email and password' do + before do + post :create, params: { user: { email: user.email, password: user.password } } + end + + it 'renders sign in token authentication page' do + expect(controller).to render_template("sign_in_token") + end + + it 'generates sign in token' do + expect(user.reload.sign_in_token).to_not be_nil + end + + it 'sends sign in token e-mail' do + expect(UserMailer).to have_received(:sign_in_token) + end + end + + context 'using a valid sign in token' do + before do + user.generate_sign_in_token && user.save + post :create, params: { user: { sign_in_token_attempt: user.sign_in_token } }, session: { attempt_user_id: user.id } + end + + it 'redirects to home' do + expect(response).to redirect_to(root_path) + end + + it 'logs the user in' do + expect(controller.current_user).to eq user + end + end + + context 'using an invalid sign in token' do + before do + post :create, params: { user: { sign_in_token_attempt: 'wrongotp' } }, session: { attempt_user_id: user.id } + end + + it 'shows a login error' do + expect(flash[:alert]).to match I18n.t('users.invalid_sign_in_token') + end + + it "doesn't log the user in" do + expect(controller.current_user).to be_nil + end + end + end end end diff --git a/spec/fabricators/device_fabricator.rb b/spec/fabricators/device_fabricator.rb new file mode 100644 index 000000000..b15d8248f --- /dev/null +++ b/spec/fabricators/device_fabricator.rb @@ -0,0 +1,8 @@ +Fabricator(:device) do + access_token + account + device_id { Faker::Number.number(digits: 5) } + name { Faker::App.name } + fingerprint_key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } + identity_key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } +end diff --git a/spec/fabricators/encrypted_message_fabricator.rb b/spec/fabricators/encrypted_message_fabricator.rb new file mode 100644 index 000000000..e65f66302 --- /dev/null +++ b/spec/fabricators/encrypted_message_fabricator.rb @@ -0,0 +1,8 @@ +Fabricator(:encrypted_message) do + device + from_account + from_device_id { Faker::Number.number(digits: 5) } + type 0 + body "" + message_franking "" +end diff --git a/spec/fabricators/one_time_key_fabricator.rb b/spec/fabricators/one_time_key_fabricator.rb new file mode 100644 index 000000000..8794baeb5 --- /dev/null +++ b/spec/fabricators/one_time_key_fabricator.rb @@ -0,0 +1,11 @@ +Fabricator(:one_time_key) do + device + key_id { Faker::Alphanumeric.alphanumeric(number: 10) } + key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) } + + signature do |attrs| + signing_key = Ed25519::SigningKey.generate + attrs[:device].update(fingerprint_key: Base64.strict_encode64(signing_key.verify_key.to_bytes)) + Base64.strict_encode64(signing_key.sign(attrs[:key])) + end +end diff --git a/spec/fabricators/system_key_fabricator.rb b/spec/fabricators/system_key_fabricator.rb new file mode 100644 index 000000000..f808495e0 --- /dev/null +++ b/spec/fabricators/system_key_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:system_key) do + +end diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 5220deabb..2ac4acc12 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -579,6 +579,62 @@ RSpec.describe ActivityPub::Activity::Create do end end + context 'with an encrypted message' do + let(:recipient) { Fabricate(:account) } + let(:target_device) { Fabricate(:device, account: recipient) } + + subject { described_class.new(json, sender, delivery: true, delivered_to_account_id: recipient.id) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'EncryptedMessage', + attributedTo: { + type: 'Device', + deviceId: '1234', + }, + to: { + type: 'Device', + deviceId: target_device.device_id, + }, + messageType: 1, + cipherText: 'Foo', + messageFranking: 'Baz678', + digest: { + digestAlgorithm: 'Bar456', + digestValue: 'Foo123', + }, + } + end + + before do + subject.perform + end + + it 'creates an encrypted message' do + encrypted_message = target_device.encrypted_messages.reload.first + + expect(encrypted_message).to_not be_nil + expect(encrypted_message.from_device_id).to eq '1234' + expect(encrypted_message.from_account).to eq sender + expect(encrypted_message.type).to eq 1 + expect(encrypted_message.body).to eq 'Foo' + expect(encrypted_message.digest).to eq 'Foo123' + end + + it 'creates a message franking' do + encrypted_message = target_device.encrypted_messages.reload.first + message_franking = encrypted_message.message_franking + + crypt = ActiveSupport::MessageEncryptor.new(SystemKey.current_key, serializer: Oj) + json = crypt.decrypt_and_verify(message_franking) + + expect(json['source_account_id']).to eq sender.id + expect(json['target_account_id']).to eq recipient.id + expect(json['original_franking']).to eq 'Baz678' + end + end + context 'when sender is followed by local users' do subject { described_class.new(json, sender, delivery: true) } diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index 464f177d0..313666412 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -59,4 +59,9 @@ class UserMailerPreview < ActionMailer::Preview def warning UserMailer.warning(User.first, AccountWarning.new(text: '', action: :silence), [Status.first.id]) end + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/sign_in_token + def sign_in_token + UserMailer.sign_in_token(User.first.tap { |user| user.generate_sign_in_token }, '127.0.0.1', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0', Time.now.utc) + end end diff --git a/spec/models/device_spec.rb b/spec/models/device_spec.rb new file mode 100644 index 000000000..f56fbf978 --- /dev/null +++ b/spec/models/device_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Device, type: :model do + +end diff --git a/spec/models/encrypted_message_spec.rb b/spec/models/encrypted_message_spec.rb new file mode 100644 index 000000000..1238d57b6 --- /dev/null +++ b/spec/models/encrypted_message_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe EncryptedMessage, type: :model do + +end diff --git a/spec/models/one_time_key_spec.rb b/spec/models/one_time_key_spec.rb new file mode 100644 index 000000000..34598334c --- /dev/null +++ b/spec/models/one_time_key_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe OneTimeKey, type: :model do + +end diff --git a/spec/models/system_key_spec.rb b/spec/models/system_key_spec.rb new file mode 100644 index 000000000..a138bc131 --- /dev/null +++ b/spec/models/system_key_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe SystemKey, type: :model do + +end diff --git a/spec/services/clear_domain_media_service_spec.rb b/spec/services/clear_domain_media_service_spec.rb new file mode 100644 index 000000000..8e58c6039 --- /dev/null +++ b/spec/services/clear_domain_media_service_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe ClearDomainMediaService, type: :service do + let!(:bad_account) { Fabricate(:account, username: 'badguy666', domain: 'evil.org') } + let!(:bad_status1) { Fabricate(:status, account: bad_account, text: 'You suck') } + let!(:bad_status2) { Fabricate(:status, account: bad_account, text: 'Hahaha') } + let!(:bad_attachment) { Fabricate(:media_attachment, account: bad_account, status: bad_status2, file: attachment_fixture('attachment.jpg')) } + + subject { ClearDomainMediaService.new } + + describe 'for a silence with reject media' do + before do + subject.call(DomainBlock.create!(domain: 'evil.org', severity: :silence, reject_media: true)) + end + + it 'leaves the domains status and attachements, but clears media' do + expect { bad_status1.reload }.not_to raise_error + expect { bad_status2.reload }.not_to raise_error + expect { bad_attachment.reload }.not_to raise_error + expect(bad_attachment.file.exists?).to be false + end + end +end diff --git a/spec/workers/domain_block_worker_spec.rb b/spec/workers/domain_block_worker_spec.rb index 48b3e38c4..bd8fc4a62 100644 --- a/spec/workers/domain_block_worker_spec.rb +++ b/spec/workers/domain_block_worker_spec.rb @@ -8,7 +8,7 @@ describe DomainBlockWorker do describe 'perform' do let(:domain_block) { Fabricate(:domain_block) } - it 'returns true for non-existent domain block' do + it 'calls domain block service for relevant domain block' do service = double(call: nil) allow(BlockDomainService).to receive(:new).and_return(service) result = subject.perform(domain_block.id) @@ -17,7 +17,7 @@ describe DomainBlockWorker do expect(service).to have_received(:call).with(domain_block, false) end - it 'calls domain block service for relevant domain block' do + it 'returns true for non-existent domain block' do result = subject.perform('aaa') expect(result).to eq(true) diff --git a/spec/workers/domain_clear_media_worker_spec.rb b/spec/workers/domain_clear_media_worker_spec.rb new file mode 100644 index 000000000..36251b1ec --- /dev/null +++ b/spec/workers/domain_clear_media_worker_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe DomainClearMediaWorker do + subject { described_class.new } + + describe 'perform' do + let(:domain_block) { Fabricate(:domain_block, severity: :silence, reject_media: true) } + + it 'calls domain clear media service for relevant domain block' do + service = double(call: nil) + allow(ClearDomainMediaService).to receive(:new).and_return(service) + result = subject.perform(domain_block.id) + + expect(result).to be_nil + expect(service).to have_received(:call).with(domain_block) + end + + it 'returns true for non-existent domain block' do + result = subject.perform('aaa') + + expect(result).to eq(true) + end + end +end |