This repository has been archived by the owner on Jul 3, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement naive and mostly hardcoded flow for following a remote user
- Loading branch information
Showing
17 changed files
with
352 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
module Aggregates | ||
## | ||
# A +Peer+ is a remote actor. | ||
class Peer | ||
include EventSourcery::AggregateRoot | ||
|
||
AWAIT_SYNCING_VALUE = 'Synching...' | ||
|
||
attr_reader :name, :bio | ||
|
||
def initialize(id, events) | ||
@name = AWAIT_SYNCING_VALUE | ||
@bio = AWAIT_SYNCING_VALUE | ||
super(id, events) | ||
end | ||
|
||
apply PeerSynched do | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# frozen_string_literal: true | ||
|
||
module Reactors | ||
## | ||
# Adds an actor to a members' followers on various Events | ||
class ContactFetcher | ||
include EventSourcery::Postgres::Reactor | ||
|
||
processor_name :contact_fetcher | ||
|
||
emits_events PeerSynched | ||
|
||
process PeerFetchRequested do |event| | ||
emit_event( | ||
PeerSynched.new( | ||
aggregate_id: event.aggregate_id, | ||
body: event.body, | ||
causation_id: event.uuid | ||
) | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
app/web/controllers/web/remote_confirmations_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# frozen_string_literal: true | ||
|
||
module Web | ||
## | ||
# Handles incoming redirects from remotes to confirm an action | ||
class RemoteConfirmationsController < WebController | ||
# TODO: authenticate and authorize | ||
get '/remote_confirmation' do | ||
erb( | ||
:remote_confirmation, | ||
layout: :layout_member, | ||
locals: { | ||
message: message, | ||
form_action: form_action, | ||
target: target, | ||
taget_type: target_type | ||
} | ||
) | ||
end | ||
|
||
private | ||
|
||
# TODO: Once we have more actions, fetch this from signed attributes and | ||
# pull through an allowlist | ||
def form_action | ||
'contacts' | ||
end | ||
|
||
# TODO: Unhardcode this message | ||
def message | ||
"As @harry@example.com you want to follow #{target}" | ||
end | ||
|
||
# TODO: Fetch the target from attributes | ||
def target | ||
'@luna@ravenclaw.example.org' | ||
end | ||
|
||
# TODO: Once we have more target types, fetch this from signed attributes | ||
# and pull through an allowlist | ||
def target_type | ||
'account' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: true | ||
|
||
module Web | ||
## | ||
# Handles Remote redirects | ||
# TODO: sanitize and whitelist actions | ||
# TODO: handle misparsed handles | ||
# TODO: exchange server-server signed secrets with remote instance so that | ||
# remote instance knows this request is coming and can validate it. | ||
class RemoteController < WebController | ||
get '/remote' do | ||
erb( | ||
:remote, | ||
layout: :layout_anonymous, | ||
locals: { | ||
message: message, | ||
action: action, | ||
target: target, | ||
taget_type: target_type | ||
} | ||
) | ||
end | ||
|
||
post '/remote' do | ||
redirect remote_confirm_uri | ||
end | ||
|
||
private | ||
|
||
def remote_confirm_uri | ||
URI::HTTPS.build( | ||
host: Handle.parse(params[:handle]).domain, | ||
path: '/remote_confirmation', | ||
query: URI.encode_www_form( | ||
action: action, | ||
target: target, | ||
target_type: target_type | ||
) | ||
) | ||
end | ||
|
||
def action | ||
'follow' | ||
end | ||
|
||
def message | ||
'Provide your handle to follow @luna@ravenclaw.example.org' | ||
end | ||
|
||
def target | ||
'@luna.ravenclaw.example.org' | ||
end | ||
|
||
def target_type | ||
'account' | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<form action="/remote" method="post"> | ||
<input name="action" type="hidden" value="<%= action %>"> | ||
|
||
<input name="target" type="hidden" value="<%= target %>"> | ||
<input name="target_type" type="hidden" value="<%= target_type %>"> | ||
|
||
<div class="field"> | ||
<label class="label" for="handle"><%= message %></label> | ||
<div class="control"> | ||
<input name="handle" | ||
id="handle" | ||
class="input" | ||
type="text" | ||
placeholder="@username@example.com"> | ||
</div> | ||
</div> | ||
<div class="control"> | ||
<button class="button is-primary"><%= action.capitalize %></button> | ||
</div> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<p><%= message %></p> | ||
<form action="/<%= form_action %>" method="post"> | ||
<input name="handle" type="hidden" value="<%= target %>"> | ||
<div class="control"> | ||
<button class="button is-primary">Confirm</button> | ||
</div> | ||
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'test_helper' | ||
|
||
module Aggregates | ||
## | ||
# Unit test for the more complex logic in Peer Aggregate | ||
class PeerTest < Minitest::Spec | ||
let(:applied_events) { [] } | ||
let(:aggregate_id) { fake_uuid(Aggregates::Peer, 1) } | ||
|
||
let(:subject) { Aggregates::Peer.new(aggregate_id, applied_events) } | ||
|
||
it '.name defaults to "Synching..."' do | ||
assert_equal('Synching...', subject.name) | ||
end | ||
|
||
it '.bio defaults to "Synching..."' do | ||
assert_equal('Synching...', subject.bio) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'test_helper' | ||
|
||
## | ||
# As a member using the web-app | ||
# When I visit another members' profile | ||
# And I click the "add to contacts" button | ||
# Then the member is added to my contacts | ||
class FederatedContactsTest < Minitest::WebSpec | ||
before do | ||
skip 'implement remote flow first' | ||
harry | ||
as(harry) | ||
|
||
# INK: remote_action. | ||
adds_contact.upto(:contact_added) | ||
end | ||
|
||
it 'adds another member to contacts' do | ||
# NOTE that the handle uses .com and rons email .org | ||
assert_content( | ||
flash(:success), | ||
'ron@example.com was added to your contacts' | ||
) | ||
|
||
visit '/contacts' | ||
assert_content('ron@example.com') | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'test_helper' | ||
|
||
## | ||
# As a member of this.example.com instance | ||
# When I visit other.example.com instance | ||
# And I request an action there | ||
# Then I am am presented with a form for my handle | ||
# And when I fill that form and click "{action}" button | ||
# Then I am redirected to my own instance with the proper payload | ||
# So that I can finalize the action on my own instance | ||
# | ||
# NOTE: {action} is any of (but not limited to), add contact, tag, annotate, | ||
# etc. | ||
class RemoteActionTest < Minitest::WebSpec | ||
let(:handle) { luna[:handle] } | ||
|
||
it 'adds remote member as contact' do | ||
landing_path = at(ravenclaw) do | ||
visit "/m/#{handle}" | ||
click_icon('account-plus') | ||
|
||
fill_in( | ||
"Provide your handle to follow #{handle}", | ||
with: '@harry@example.com' | ||
) | ||
click_button('Follow') | ||
page.current_path | ||
end | ||
|
||
# Revisit the page to open it with harry as session | ||
as(harry) | ||
visit landing_path | ||
|
||
assert_content(page, "As @harry@example.com you want to follow #{handle}") | ||
click_button('Confirm') | ||
assert_content(flash(:success), "#{handle} was added to your contacts") | ||
|
||
process_events(%w[contact_fetch_requested contact_added]) | ||
|
||
visit '/contacts' | ||
assert_content(luna[:handle]) | ||
end | ||
|
||
# TODO: handle non-logged in on local. | ||
# TODO: handle authentication properly with oauth secrets exchange. | ||
|
||
private | ||
|
||
def ravenclaw | ||
@ravenclaw ||= RemoteInstance.new('ravenclaw.example.org', self) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.