.circleci
.github
app
bin
chart
config
db
dist
lib
log
nanobox
public
spec
controllers
fabricators
features
fixtures
helpers
lib
activitypub
activity
adapter_spec.rb
dereferencer_spec.rb
linked_data_signature_spec.rb
tag_manager_spec.rb
connection_pool
ostatus
proof_provider
rss
settings
delivery_failure_tracker_spec.rb
extractor_spec.rb
fast_ip_map_spec.rb
feed_manager_spec.rb
formatter_spec.rb
hash_object_spec.rb
language_detector_spec.rb
request_pool_spec.rb
request_spec.rb
sanitize_config_spec.rb
spam_check_spec.rb
status_filter_spec.rb
status_finder_spec.rb
tag_manager_spec.rb
user_settings_decorator_spec.rb
webfinger_resource_spec.rb
mailers
models
policies
presenters
requests
routing
serializers
services
support
validators
views
workers
rails_helper.rb
spec_helper.rb
streaming
vendor
.buildpacks
.codeclimate.yml
.dockerignore
.editorconfig
.env.nanobox
.env.production.sample
.env.test
.env.vagrant
.eslintignore
.eslintrc.js
.foreman
.gitattributes
.gitignore
.haml-lint.yml
.nanoignore
.nvmrc
.profile
.rspec
.rubocop.yml
.ruby-version
.sass-lint.yml
.slugignore
.yarnclean
AUTHORS.md
Aptfile
CHANGELOG.md
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Capfile
Dockerfile
Gemfile
Gemfile.lock
LICENSE
Procfile
Procfile.dev
README.md
Rakefile
SECURITY.md
Vagrantfile
app.json
babel.config.js
boxfile.yml
config.ru
crowdin.yml
docker-compose.yml
ide-helper.js
package.json
postcss.config.js
priv-config
scalingo.json
yarn.lock
* No need to re-require sidekiq plugins, they are required via Gemfile * Add derailed_benchmarks tool, no need to require TTY gems in Gemfile * Replace ruby-oembed with FetchOEmbedService Reduce startup by 45382 allocated objects * Remove preloaded JSON-LD in favour of caching HTTP responses Reduce boot RAM by about 6 MiB * Fix tests * Fix test suite by stubbing out JSON-LD contexts
87 lines
2.3 KiB
Ruby
87 lines
2.3 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe ActivityPub::LinkedDataSignature do
|
|
include JsonLdHelper
|
|
|
|
let!(:sender) { Fabricate(:account, uri: 'http://example.com/alice') }
|
|
|
|
let(:raw_json) do
|
|
{
|
|
'@context' => 'https://www.w3.org/ns/activitystreams',
|
|
'id' => 'http://example.com/hello-world',
|
|
}
|
|
end
|
|
|
|
let(:json) { raw_json.merge('signature' => signature) }
|
|
|
|
subject { described_class.new(json) }
|
|
|
|
before do
|
|
stub_jsonld_contexts!
|
|
end
|
|
|
|
describe '#verify_account!' do
|
|
context 'when signature matches' do
|
|
let(:raw_signature) do
|
|
{
|
|
'creator' => 'http://example.com/alice',
|
|
'created' => '2017-09-23T20:21:34Z',
|
|
}
|
|
end
|
|
|
|
let(:signature) { raw_signature.merge('type' => 'RsaSignature2017', 'signatureValue' => sign(sender, raw_signature, raw_json)) }
|
|
|
|
it 'returns creator' do
|
|
expect(subject.verify_account!).to eq sender
|
|
end
|
|
end
|
|
|
|
context 'when signature is missing' do
|
|
let(:signature) { nil }
|
|
|
|
it 'returns nil' do
|
|
expect(subject.verify_account!).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when signature is tampered' do
|
|
let(:raw_signature) do
|
|
{
|
|
'creator' => 'http://example.com/alice',
|
|
'created' => '2017-09-23T20:21:34Z',
|
|
}
|
|
end
|
|
|
|
let(:signature) { raw_signature.merge('type' => 'RsaSignature2017', 'signatureValue' => 's69F3mfddd99dGjmvjdjjs81e12jn121Gkm1') }
|
|
|
|
it 'returns nil' do
|
|
expect(subject.verify_account!).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '#sign!' do
|
|
subject { described_class.new(raw_json).sign!(sender) }
|
|
|
|
it 'returns a hash' do
|
|
expect(subject).to be_a Hash
|
|
end
|
|
|
|
it 'contains signature' do
|
|
expect(subject['signature']).to be_a Hash
|
|
expect(subject['signature']['signatureValue']).to be_present
|
|
end
|
|
|
|
it 'can be verified again' do
|
|
expect(described_class.new(subject).verify_account!).to eq sender
|
|
end
|
|
end
|
|
|
|
def sign(from_account, options, document)
|
|
options_hash = Digest::SHA256.hexdigest(canonicalize(options.merge('@context' => ActivityPub::LinkedDataSignature::CONTEXT)))
|
|
document_hash = Digest::SHA256.hexdigest(canonicalize(document))
|
|
to_be_verified = options_hash + document_hash
|
|
Base64.strict_encode64(from_account.keypair.sign(OpenSSL::Digest::SHA256.new, to_be_verified))
|
|
end
|
|
end
|