social_stream-ostatus 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/app/assets/images/logos/contact/remote_subject.png +0 -0
- data/app/assets/images/logos/original/remote_subject.png +0 -0
- data/app/assets/images/logos/profile/remote_subject.png +0 -0
- data/app/controllers/pshb_controller.rb +14 -22
- data/app/controllers/remote_subjects_controller.rb +19 -0
- data/app/controllers/salmon_controller.rb +15 -0
- data/app/controllers/webfinger_controller.rb +12 -3
- data/app/decorators/social_stream/base/activity_decorator.rb +3 -0
- data/app/decorators/social_stream/base/actor_decorator.rb +3 -0
- data/app/decorators/social_stream/base/audience_decorator.rb +3 -0
- data/app/decorators/social_stream/base/relation/custom_decorator.rb +3 -0
- data/app/decorators/social_stream/base/tie_decorator.rb +3 -0
- data/app/models/actor_key.rb +30 -0
- data/app/models/remote_subject.rb +111 -15
- data/app/views/remote_subjects/_show.html.erb +6 -0
- data/app/views/remote_subjects/show.html.erb +5 -0
- data/config/routes.rb +7 -4
- data/db/migrate/20120905145030_create_social_stream_ostatus.rb +2 -1
- data/db/migrate/20120918194708_create_actor_keys.rb +18 -0
- data/lib/generators/social_stream/ostatus/install_generator.rb +0 -6
- data/lib/generators/social_stream/ostatus/templates/initializer.rb +16 -2
- data/lib/social_stream/ostatus/activity_streams.rb +79 -0
- data/lib/social_stream/ostatus/controllers/debug_requests.rb +24 -0
- data/lib/social_stream/ostatus/engine.rb +6 -6
- data/lib/social_stream/ostatus/models/activity.rb +41 -0
- data/lib/social_stream/ostatus/models/actor.rb +60 -14
- data/lib/social_stream/ostatus/models/audience.rb +2 -2
- data/lib/social_stream/ostatus/models/object.rb +28 -0
- data/lib/social_stream/ostatus/models/relation/custom.rb +22 -0
- data/lib/social_stream/ostatus/models/tie.rb +24 -0
- data/lib/social_stream/ostatus/version.rb +1 -1
- data/lib/social_stream-ostatus.rb +31 -4
- data/social_stream-ostatus.gemspec +2 -2
- data/spec/controllers/host_meta_controller_spec.rb +10 -0
- data/spec/controllers/remote_subjects_controller_spec.rb +37 -0
- data/spec/controllers/webfinger_controller_spec.rb +13 -0
- data/spec/factories/remote_subject.rb +39 -0
- data/spec/models/actor_key_spec.rb +9 -0
- data/spec/models/post_spec.rb +25 -0
- data/spec/models/remote_subject_spec.rb +24 -0
- data/spec/social_stream_ostatus_activity_streams.spec.rb +31 -0
- metadata +34 -8
- data/app/controllers/remoteusers_controller.rb +0 -30
- data/app/views/remoteusers/index.html.erb +0 -8
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,34 +1,26 @@
|
|
|
1
1
|
class PshbController < ApplicationController
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
include SocialStream::Ostatus::Controllers::DebugRequests
|
|
3
|
+
|
|
4
|
+
skip_before_filter :verify_authenticity_token
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
case params['hub.mode']
|
|
8
|
+
#TODO check PuSH specification about subscribe or async
|
|
9
|
+
when 'subscribe', 'async'
|
|
6
10
|
render :text => params['hub.challenge'], :status => 200
|
|
7
|
-
#
|
|
11
|
+
# TODO: confirm that params['hub.topic'] is a real
|
|
8
12
|
# requested subscription by someone in this node
|
|
9
13
|
return
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
#sync unsubscription verification
|
|
13
|
-
if params['hub.mode']=='unsubscribe'
|
|
14
|
+
when 'unsubscribe'
|
|
14
15
|
render :text => params['hub.challenge'], :status => 200
|
|
15
|
-
#
|
|
16
|
+
# TODO: confirm that params['hub.topic'] is a real
|
|
16
17
|
# requested unsubscription by someone in this node
|
|
17
18
|
# and delete permissions/remote actor if necessary
|
|
18
19
|
return
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
webfinger_id = origin[5]+"@"+origin[2]
|
|
25
|
-
|
|
26
|
-
activity_texts = doc.xpath("//xmlns:content")
|
|
27
|
-
activity_texts.each do |activity_text|
|
|
28
|
-
r_user = RemoteSubject.find_by_webfinger_id(webfinger_id)
|
|
29
|
-
if r_user != nil
|
|
30
|
-
Post.create!(:text => activity_text.content, :_activity_tie_id => r_user.public_tie)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
22
|
+
SocialStream::ActivityStreams.from_pshb_callback(request.body.read)
|
|
23
|
+
|
|
24
|
+
render text: "Success!"
|
|
33
25
|
end
|
|
34
26
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class RemoteSubjectsController < ApplicationController
|
|
2
|
+
def index
|
|
3
|
+
raise ActiveRecord::NotFound if params[:q].blank?
|
|
4
|
+
|
|
5
|
+
@remote_subject =
|
|
6
|
+
RemoteSubject.find_or_create_by_webfinger_uri!(params[:q])
|
|
7
|
+
|
|
8
|
+
redirect_to @remote_subject
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def show
|
|
12
|
+
@remote_subject =
|
|
13
|
+
RemoteSubject.find_by_slug!(params[:id])
|
|
14
|
+
|
|
15
|
+
if params[:refresh]
|
|
16
|
+
@remote_subject.refresh_webfinger!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class SalmonController < ApplicationController
|
|
2
|
+
include SocialStream::Ostatus::Controllers::DebugRequests
|
|
3
|
+
|
|
4
|
+
skip_before_filter :verify_authenticity_token
|
|
5
|
+
|
|
6
|
+
def index
|
|
7
|
+
actor = Actor.find_by_slug! params[:slug]
|
|
8
|
+
|
|
9
|
+
SocialStream::ActivityStreams.from_salmon_callback request.body.read, actor
|
|
10
|
+
|
|
11
|
+
# TODO handle errors
|
|
12
|
+
|
|
13
|
+
render text: "Success!"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -5,9 +5,18 @@ class WebfingerController < ActionController::Metal
|
|
|
5
5
|
def index
|
|
6
6
|
actor = Actor.find_by_webfinger!(params[:q])
|
|
7
7
|
|
|
8
|
-
finger = Proudhon::Finger.new
|
|
9
|
-
:
|
|
10
|
-
|
|
8
|
+
finger = Proudhon::Finger.new(
|
|
9
|
+
:subject => actor.webfinger_uri,
|
|
10
|
+
:alias => [polymorphic_url(actor.subject)],
|
|
11
|
+
:links => {
|
|
12
|
+
avatar: root_url + actor.logo.url(:original),
|
|
13
|
+
profile: polymorphic_url([actor.subject, :profile]),
|
|
14
|
+
updates_from: polymorphic_url([actor.subject, :activities], :format => :atom),
|
|
15
|
+
salmon: salmon_url(actor.slug),
|
|
16
|
+
replies: salmon_url(actor.slug),
|
|
17
|
+
mention: salmon_url(actor.slug),
|
|
18
|
+
magic_key: actor.magic_public_key
|
|
19
|
+
})
|
|
11
20
|
|
|
12
21
|
self.response_body = finger.to_xml
|
|
13
22
|
self.content_type = Mime::XML
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
3
|
+
# Store OStatus private and public key
|
|
4
|
+
class ActorKey < ActiveRecord::Base
|
|
5
|
+
KEY_SIZE = 1024
|
|
6
|
+
|
|
7
|
+
belongs_to :actor
|
|
8
|
+
|
|
9
|
+
validates_presence_of :key_der
|
|
10
|
+
|
|
11
|
+
before_validation :generate_key, on: :create
|
|
12
|
+
|
|
13
|
+
def key
|
|
14
|
+
@key ||=
|
|
15
|
+
OpenSSL::PKey::RSA.new(key_der)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def key= new_key
|
|
19
|
+
@key = new_key
|
|
20
|
+
self.key_der = new_key.to_der
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def generate_key
|
|
26
|
+
return if key_der.present?
|
|
27
|
+
|
|
28
|
+
self.key = OpenSSL::PKey::RSA.generate(KEY_SIZE)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -1,27 +1,53 @@
|
|
|
1
1
|
class RemoteSubject < ActiveRecord::Base
|
|
2
|
-
|
|
2
|
+
include SocialStream::Models::Subject
|
|
3
|
+
# Create absolute routes
|
|
4
|
+
include Rails.application.routes.url_helpers
|
|
5
|
+
|
|
6
|
+
attr_reader :url_helper
|
|
7
|
+
attr_accessible :webfinger_id
|
|
8
|
+
|
|
9
|
+
# Save webfinger_info hash into the database
|
|
10
|
+
serialize :webfinger_info
|
|
11
|
+
|
|
12
|
+
validates_uniqueness_of :webfinger_id
|
|
13
|
+
|
|
14
|
+
before_validation :fill_information,
|
|
15
|
+
:on => :create
|
|
16
|
+
|
|
17
|
+
after_create :subscribe_to_public_feed
|
|
18
|
+
after_destroy :unsubscribe_to_public_feed
|
|
19
|
+
|
|
20
|
+
scope :webfinger_alias, lambda { |uri|
|
|
21
|
+
where('webfinger_info LIKE ?', "%aliases%#{ uri }%")
|
|
22
|
+
}
|
|
3
23
|
|
|
4
24
|
#validates_format_of :webfinger_slug, :with => Devise.email_regexp, :allow_blank => true
|
|
5
25
|
|
|
6
26
|
class << self
|
|
7
|
-
def
|
|
8
|
-
|
|
27
|
+
def find_or_create_by_webfinger_uri!(uri)
|
|
28
|
+
if uri =~ /^https?:\/\//
|
|
29
|
+
records = webfinger_alias(uri)
|
|
9
30
|
|
|
10
|
-
|
|
31
|
+
# SQL scope is not reliable
|
|
32
|
+
if records.present?
|
|
33
|
+
return records.find{ |r| r.webfinger_aliases.include?(uri) }
|
|
34
|
+
end
|
|
11
35
|
|
|
12
|
-
|
|
13
|
-
|
|
36
|
+
# TODO: create by http uri?
|
|
37
|
+
|
|
38
|
+
raise ::ActiveRecord::RecordNotFound
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
id = uri.dup
|
|
42
|
+
|
|
43
|
+
if id =~ /^acct:/
|
|
44
|
+
id.gsub!('acct:', '')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
find_or_create_by_webfinger_id!(id)
|
|
14
48
|
end
|
|
15
49
|
end
|
|
16
50
|
|
|
17
|
-
# Public feed url for this RemoteSubject
|
|
18
|
-
#
|
|
19
|
-
# TODO: get from webfinger?
|
|
20
|
-
# It does not work for every remote user!
|
|
21
|
-
def public_feed_url
|
|
22
|
-
"http://#{ webfinger_url }/api/user/#{ name }/public.atom"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
51
|
# Return the slug in the webfinger_id
|
|
26
52
|
def webfinger_slug
|
|
27
53
|
splitted_webfinger_id.first
|
|
@@ -32,12 +58,82 @@ class RemoteSubject < ActiveRecord::Base
|
|
|
32
58
|
splitted_webfinger_id.last
|
|
33
59
|
end
|
|
34
60
|
|
|
35
|
-
|
|
61
|
+
# URL of the activity feed from this {RemoteSubject}
|
|
62
|
+
def public_feed_url
|
|
63
|
+
webfinger_info[:updates_from]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# URL of the Salmon endpoint for this {RemoteSubject}
|
|
67
|
+
def salmon_url
|
|
68
|
+
webfinger_info[:salmon]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Webfinger Alias
|
|
72
|
+
def webfinger_aliases
|
|
73
|
+
webfinger_info[:aliases]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Fetch the webfinger again
|
|
77
|
+
def refresh_webfinger!
|
|
78
|
+
fill_webfinger_info
|
|
79
|
+
|
|
80
|
+
save!
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
36
84
|
|
|
37
85
|
def splitted_webfinger_id
|
|
38
86
|
@splitted_webfinger_id ||=
|
|
39
87
|
webfinger_id.split('@')
|
|
40
88
|
end
|
|
41
89
|
|
|
90
|
+
def fill_information
|
|
91
|
+
fill_webfinger_info
|
|
92
|
+
|
|
93
|
+
self.name = webfinger_id
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def fill_webfinger_info
|
|
97
|
+
self.webfinger_info = build_webfinger_info
|
|
98
|
+
self.rsa_key = finger.magic_key
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def build_webfinger_info
|
|
102
|
+
{
|
|
103
|
+
updates_from: finger.links[:updates_from],
|
|
104
|
+
salmon: finger.links[:salmon],
|
|
105
|
+
aliases: finger.alias
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def finger
|
|
110
|
+
@finger ||=
|
|
111
|
+
fetch_finger
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def fetch_finger
|
|
115
|
+
finger =
|
|
116
|
+
Proudhon::Finger.fetch webfinger_id
|
|
42
117
|
|
|
118
|
+
# FIXME custom error
|
|
119
|
+
raise ::ActiveRecord::RecordNotFound if finger.blank?
|
|
120
|
+
|
|
121
|
+
finger
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def subscribe_to_public_feed
|
|
125
|
+
return if public_feed_url.blank?
|
|
126
|
+
|
|
127
|
+
atom = Proudhon::Atom.from_uri(public_feed_url)
|
|
128
|
+
|
|
129
|
+
atom.subscribe(pshb_url(:host => SocialStream::Ostatus.pshb_host))
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def unsubscribe_to_public_feed
|
|
133
|
+
return if public_feed_url.blank?
|
|
134
|
+
|
|
135
|
+
atom = Proudhon::Atom.from_uri(public_feed_url)
|
|
136
|
+
|
|
137
|
+
atom.unsubscribe(pshb_url(:host => SocialStream::Ostatus.pshb_host))
|
|
138
|
+
end
|
|
43
139
|
end
|
data/config/routes.rb
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
Rails.application.routes.draw do
|
|
2
|
-
#
|
|
2
|
+
# Host Meta
|
|
3
3
|
match '/.well-known/host-meta', :to => HostMetaController.action(:index)
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Webfinger
|
|
6
6
|
match '/webfinger' => 'webfinger#index', :as => 'webfinger'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
match '
|
|
8
|
+
# PushSubHubBub callback
|
|
9
|
+
match 'pshb' => 'pshb#index', as: :pshb
|
|
10
|
+
|
|
11
|
+
# Salmon callback
|
|
12
|
+
match 'salmon/:slug' => 'salmon#index', as: :salmon
|
|
10
13
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class CreateActorKeys < ActiveRecord::Migration
|
|
2
|
+
def up
|
|
3
|
+
create_table :actor_keys do |t|
|
|
4
|
+
t.integer :actor_id
|
|
5
|
+
t.binary :key_der
|
|
6
|
+
|
|
7
|
+
t.timestamps
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
add_index "actor_keys", "actor_id"
|
|
11
|
+
add_foreign_key "actor_keys", "actors", :name => "actor_keys_on_actor_id"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def down
|
|
15
|
+
remove_foreign_key "actor_keys", :name => "actor_keys_on_actor_id"
|
|
16
|
+
drop_table :actor_keys
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -13,10 +13,4 @@ class SocialStream::Ostatus::InstallGenerator < Rails::Generators::Base
|
|
|
13
13
|
def config_initializer
|
|
14
14
|
copy_file 'initializer.rb', 'config/initializers/social_stream-ostatus.rb'
|
|
15
15
|
end
|
|
16
|
-
|
|
17
|
-
def inject_remote_user_relation
|
|
18
|
-
append_file 'config/relations.yml',
|
|
19
|
-
"\nremote_subject:\n friend:\n name: friend\n permissions:\n - [ follow ]\n sphere: personal\n"+
|
|
20
|
-
" public:\n name: public\n permissions:\n - [ read, tie, star_tie ]\n sphere: personal"
|
|
21
|
-
end
|
|
22
16
|
end
|
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
SocialStream::Ostatus.setup do |config|
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
# Default to the PuSH reference Hub server
|
|
3
|
+
#
|
|
4
|
+
# config.hub = 'http://pubsubhubbub.appspot.com'
|
|
5
|
+
|
|
6
|
+
# The host where the hub should take the activity feed from
|
|
7
|
+
#
|
|
8
|
+
# Local subjects will publish their public activities there
|
|
9
|
+
config.activity_feed_host = 'localhost:3000'
|
|
10
|
+
|
|
11
|
+
# The host where the PuSH should send the callbacks to
|
|
12
|
+
#
|
|
13
|
+
# Remote subjects get their local activities updates with the PuSH callback
|
|
14
|
+
config.pshb_host = 'localhost:3000'
|
|
15
|
+
|
|
16
|
+
# Debug OStatus requests
|
|
17
|
+
# config.debug_requests = true
|
|
4
18
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module ActivityStreams
|
|
4
|
+
# Parses the body from a {PshbController#index} and dispatches
|
|
5
|
+
# entries for parsing to {#record_from_entry!}
|
|
6
|
+
def from_pshb_callback(body)
|
|
7
|
+
atom = Proudhon::Atom.parse body
|
|
8
|
+
|
|
9
|
+
atom.entries.each do |entry|
|
|
10
|
+
# FIXME: get author from feed
|
|
11
|
+
# https://github.com/shf/proudhon/issues/8
|
|
12
|
+
entry.author.uri ||= feed.author.uri
|
|
13
|
+
|
|
14
|
+
activity_from_entry! entry
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Parses an activity form a PuSH or Salmon notification
|
|
19
|
+
# Decides what action should be taken from an ActivityStreams entry
|
|
20
|
+
def activity_from_entry! entry, receiver = nil
|
|
21
|
+
# FIXME: should not use to_sym
|
|
22
|
+
# https://github.com/shf/proudhon/issues/7
|
|
23
|
+
case entry.verb.to_sym
|
|
24
|
+
when :follow
|
|
25
|
+
Tie.from_entry! entry, receiver
|
|
26
|
+
else
|
|
27
|
+
# :post is the default verb
|
|
28
|
+
r = record_from_entry! entry, receiver
|
|
29
|
+
r.post_activity
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Redirects parsing to the suitable SocialStream's model
|
|
34
|
+
def record_from_entry! entry, receiver
|
|
35
|
+
model!(entry.objtype).from_entry! entry, receiver
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Finds or creates a {RemoteSubject} from an ActivityStreams entry
|
|
39
|
+
#
|
|
40
|
+
def actor_from_entry! entry
|
|
41
|
+
webfinger_id = entry.author.uri
|
|
42
|
+
|
|
43
|
+
if webfinger_id.blank?
|
|
44
|
+
raise "Entry author without uri: #{ entry.to_xml }"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
RemoteSubject.find_or_create_by_webfinger_uri! webfinger_id
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Parses the body from a {Salmon#index} and receiving actor
|
|
51
|
+
def from_salmon_callback(body, receiver)
|
|
52
|
+
salmon = Proudhon::Salmon.new body
|
|
53
|
+
|
|
54
|
+
validate_salmon salmon
|
|
55
|
+
|
|
56
|
+
activity_from_entry! salmon.to_entry, receiver
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def validate_salmon salmon
|
|
60
|
+
remote_subject = RemoteSubject.find_or_create_by_webfinger_uri!(salmon.to_entry.author.uri)
|
|
61
|
+
key = remote_subject.rsa_key
|
|
62
|
+
|
|
63
|
+
unless salmon.verify(key)
|
|
64
|
+
raise "Invalid salmon: #{ salmon }"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Translate SocialStream activity verb to Proudhon verb
|
|
69
|
+
def verb orig
|
|
70
|
+
case orig
|
|
71
|
+
when 'make-friend'
|
|
72
|
+
:follow
|
|
73
|
+
else
|
|
74
|
+
orig.to_sym
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module Controllers
|
|
4
|
+
module DebugRequests
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
before_filter :debug_request
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def debug_request
|
|
14
|
+
return unless SocialStream::Ostatus.debug_requests
|
|
15
|
+
|
|
16
|
+
logger.info request.body.read
|
|
17
|
+
|
|
18
|
+
# Set StringIO to initial state for the action to get the content
|
|
19
|
+
request.body.rewind
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
module SocialStream
|
|
2
2
|
module Ostatus
|
|
3
3
|
class Engine < Rails::Engine
|
|
4
|
-
initializer 'social_stream-ostatus.
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
initializer 'social_stream-ostatus.activity_streams' do
|
|
5
|
+
SocialStream::ActivityStreams.class_eval do
|
|
6
|
+
extend SocialStream::Ostatus::ActivityStreams
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
initializer 'social_stream-ostatus.
|
|
11
|
-
|
|
12
|
-
include SocialStream::Ostatus::Models::
|
|
10
|
+
initializer 'social_stream-ostatus.models.object' do
|
|
11
|
+
SocialStream::Models::Object::ClassMethods.module_eval do
|
|
12
|
+
include SocialStream::Ostatus::Models::Object::ClassMethods
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module Models
|
|
4
|
+
module Activity
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
after_commit :send_salmon
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# Send Salmon notification to remote subject
|
|
14
|
+
def send_salmon
|
|
15
|
+
return if sender.subject_type == "RemoteSubject" ||
|
|
16
|
+
receiver.subject_type != "RemoteSubject"
|
|
17
|
+
|
|
18
|
+
entry =
|
|
19
|
+
Proudhon::Entry.new id: "tag:#{ SocialStream::Ostatus.activity_feed_host },2005:activity-#{ id }",
|
|
20
|
+
title: stream_title,
|
|
21
|
+
content: stream_content,
|
|
22
|
+
verb: SocialStream::ActivityStreams.verb(verb),
|
|
23
|
+
author: Proudhon::Author.new(name: sender.name,
|
|
24
|
+
uri: sender.webfinger_uri)
|
|
25
|
+
salmon = entry.to_salmon
|
|
26
|
+
|
|
27
|
+
if SocialStream::Ostatus.debug_requests
|
|
28
|
+
logger.info entry.to_xml
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# FIXME: Rails 4 queues
|
|
32
|
+
Thread.new do
|
|
33
|
+
salmon.deliver receiver_subject.salmon_url, sender.rsa_key
|
|
34
|
+
|
|
35
|
+
ActiveRecord::Base.connection.close
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -6,9 +6,15 @@ module SocialStream
|
|
|
6
6
|
module Models
|
|
7
7
|
module Actor
|
|
8
8
|
extend ActiveSupport::Concern
|
|
9
|
+
|
|
10
|
+
include Rails.application.routes.url_helpers
|
|
9
11
|
|
|
10
12
|
included do
|
|
11
|
-
|
|
13
|
+
has_one :actor_key, dependent: :destroy,
|
|
14
|
+
validate: true,
|
|
15
|
+
autosave: true
|
|
16
|
+
|
|
17
|
+
after_commit :publish_feed
|
|
12
18
|
end
|
|
13
19
|
|
|
14
20
|
module ClassMethods
|
|
@@ -20,21 +26,61 @@ module SocialStream
|
|
|
20
26
|
find_by_slug! $2
|
|
21
27
|
end
|
|
22
28
|
end
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
29
|
+
|
|
30
|
+
# The Webfinger ID for this {Actor}
|
|
31
|
+
def webfinger_id
|
|
32
|
+
"#{ slug }@#{ SocialStream::Ostatus.activity_feed_host }"
|
|
27
33
|
end
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
|
|
35
|
+
# The Webfinger URI for this {Actor}
|
|
36
|
+
def webfinger_uri
|
|
37
|
+
"acct:#{ webfinger_id }"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Fetch or create the associated {ActorKey}
|
|
41
|
+
def actor_key!
|
|
42
|
+
actor_key ||
|
|
43
|
+
create_actor_key!
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# OpenSSL::PKey::RSA key
|
|
47
|
+
#
|
|
48
|
+
# The key is generated if it does not exist
|
|
49
|
+
def rsa_key
|
|
50
|
+
actor_key!.key
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Set OpenSSL::PKey::RSA key
|
|
54
|
+
def rsa_key= key
|
|
55
|
+
k = actor_key || build_actor_key
|
|
56
|
+
k.key = key
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Public RSA instance of {#rsa_key}
|
|
60
|
+
def rsa_public_key
|
|
61
|
+
rsa_key.public_key
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# MagicKey string from public key
|
|
65
|
+
def magic_public_key
|
|
66
|
+
Proudhon::MagicKey.to_s rsa_public_key
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def publish_feed
|
|
70
|
+
return if subject_type == "RemoteSubject"
|
|
71
|
+
|
|
72
|
+
# FIXME: Rails 4 queues
|
|
73
|
+
Thread.new do
|
|
74
|
+
uri = URI.parse(SocialStream::Ostatus.hub)
|
|
75
|
+
topic = polymorphic_url [subject, :activities],
|
|
76
|
+
:format => :atom,
|
|
77
|
+
:host => SocialStream::Ostatus.activity_feed_host
|
|
33
78
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
79
|
+
response = Net::HTTP::post_form uri, { 'hub.mode' => 'publish',
|
|
80
|
+
'hub.url' => topic }
|
|
81
|
+
#TODO: process 4XX look at: response.status
|
|
82
|
+
|
|
83
|
+
ActiveRecord::Base.connection.close
|
|
38
84
|
end
|
|
39
85
|
end
|
|
40
86
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module Models
|
|
4
|
+
module Object
|
|
5
|
+
module ClassMethods
|
|
6
|
+
# Creates an new instance from ActivityStreams entry
|
|
7
|
+
#
|
|
8
|
+
def from_entry! entry, receiver
|
|
9
|
+
create! do |obj|
|
|
10
|
+
obj.author =
|
|
11
|
+
obj.user_author =
|
|
12
|
+
SocialStream::ActivityStreams.actor_from_entry!(entry)
|
|
13
|
+
|
|
14
|
+
obj.owner = receiver || obj.author
|
|
15
|
+
|
|
16
|
+
obj.title = entry.title
|
|
17
|
+
obj.description = entry.summary || entry.content
|
|
18
|
+
|
|
19
|
+
obj.relation_ids = [ ::Relation::Public.instance.id ]
|
|
20
|
+
|
|
21
|
+
yield obj if block_given?
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module Models
|
|
4
|
+
module Relation
|
|
5
|
+
module Custom
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
const_get("DEFAULT")['remote_subject'] = {
|
|
10
|
+
'default' => {
|
|
11
|
+
'name' => 'default',
|
|
12
|
+
'permissions' => [
|
|
13
|
+
[ 'read', 'activity' ]
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module SocialStream
|
|
2
|
+
module Ostatus
|
|
3
|
+
module Models
|
|
4
|
+
module Tie
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
module ClassMethods
|
|
8
|
+
# Create a new {Tie} from OStatus entry
|
|
9
|
+
def from_entry! entry, receiver
|
|
10
|
+
# Sender must be remote
|
|
11
|
+
sender = RemoteSubject.find_or_create_by_webfinger_uri! entry.author.uri
|
|
12
|
+
|
|
13
|
+
contact = sender.contact_to!(receiver)
|
|
14
|
+
|
|
15
|
+
# FIXME: hack
|
|
16
|
+
contact.user_author = sender
|
|
17
|
+
|
|
18
|
+
contact.relation_ids = [::Relation::Public.instance.id]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -5,21 +5,48 @@ require 'proudhon'
|
|
|
5
5
|
|
|
6
6
|
module SocialStream
|
|
7
7
|
module Ostatus
|
|
8
|
+
# PuSH hub
|
|
8
9
|
mattr_accessor :hub
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
mattr_accessor :node_base_url
|
|
12
|
-
@@node_base_url = :node_base_url
|
|
10
|
+
# Default to the PubSubHubbub reference Hub server
|
|
11
|
+
@@hub = 'http://pubsubhubbub.appspot.com'
|
|
13
12
|
|
|
13
|
+
# The host where the hub should take the activity feed from
|
|
14
|
+
mattr_accessor :activity_feed_host
|
|
15
|
+
@@activity_feed_host = 'localhost:3000'
|
|
16
|
+
|
|
17
|
+
# The host where the PuSH should send the callbacks to
|
|
18
|
+
mattr_accessor :pshb_host
|
|
19
|
+
@@pshb_host = 'localhost:3000'
|
|
20
|
+
|
|
21
|
+
# Debug OStatus request with logger.info
|
|
22
|
+
mattr_accessor :debug_requests
|
|
23
|
+
@@debug_requests = false
|
|
24
|
+
|
|
14
25
|
class << self
|
|
15
26
|
def setup
|
|
16
27
|
yield self
|
|
17
28
|
end
|
|
18
29
|
end
|
|
19
30
|
|
|
31
|
+
autoload :ActivityStreams, 'social_stream/ostatus/activity_streams'
|
|
32
|
+
|
|
20
33
|
module Models
|
|
34
|
+
autoload :Activity, 'social_stream/ostatus/models/activity'
|
|
21
35
|
autoload :Actor, 'social_stream/ostatus/models/actor'
|
|
22
36
|
autoload :Audience, 'social_stream/ostatus/models/audience'
|
|
37
|
+
autoload :Tie, 'social_stream/ostatus/models/tie'
|
|
38
|
+
|
|
39
|
+
module Object
|
|
40
|
+
autoload :ClassMethods, 'social_stream/ostatus/models/object'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
module Relation
|
|
44
|
+
autoload :Custom, 'social_stream/ostatus/models/relation/custom'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
module Controllers
|
|
49
|
+
autoload :DebugRequests, 'social_stream/ostatus/controllers/debug_requests'
|
|
23
50
|
end
|
|
24
51
|
end
|
|
25
52
|
end
|
|
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
|
|
|
12
12
|
s.files = `git ls-files`.split("\n")
|
|
13
13
|
|
|
14
14
|
# Gem dependencies
|
|
15
|
-
s.add_runtime_dependency('social_stream-base','~> 0.
|
|
16
|
-
s.add_runtime_dependency('proudhon','>= 0.3')
|
|
15
|
+
s.add_runtime_dependency('social_stream-base', '~> 0.23.0')
|
|
16
|
+
s.add_runtime_dependency('proudhon','>= 0.3.5')
|
|
17
17
|
s.add_runtime_dependency('nokogiri','> 1.4.4')
|
|
18
18
|
|
|
19
19
|
# Development Gem dependencies
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RemoteSubjectsController do
|
|
4
|
+
render_views
|
|
5
|
+
|
|
6
|
+
context "with remote subject" do
|
|
7
|
+
before do
|
|
8
|
+
@remote_subject = Factory(:remote_subject)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should redirect index to show" do
|
|
12
|
+
get :index, q: @remote_subject.webfinger_id
|
|
13
|
+
|
|
14
|
+
response.should redirect_to(@remote_subject)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should render show" do
|
|
18
|
+
get :show, id: @remote_subject.slug
|
|
19
|
+
|
|
20
|
+
response.should be_success
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
describe "refreshing show" do
|
|
25
|
+
before do
|
|
26
|
+
RemoteSubject.should_receive(:find_by_slug!).with(@remote_subject.slug) { @remote_subject }
|
|
27
|
+
@remote_subject.should_receive(:refresh_webfinger!)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should refresh remote_subject" do
|
|
31
|
+
get :show, id: @remote_subject.slug, refresh: true
|
|
32
|
+
|
|
33
|
+
response.should be_success
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class << Proudhon::Finger
|
|
2
|
+
def fetch id
|
|
3
|
+
obj = Object.new
|
|
4
|
+
def obj.links
|
|
5
|
+
{ updates_from: 'feed' }
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def obj.magic_key
|
|
9
|
+
OpenSSL::PKey::RSA.generate 256
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
obj
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class << Proudhon::Atom
|
|
17
|
+
def from_uri uri
|
|
18
|
+
obj = Object.new
|
|
19
|
+
|
|
20
|
+
def obj.subscribe(callback)
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
obj
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
RemoteSubject.class_eval do
|
|
29
|
+
def build_webfinger_info
|
|
30
|
+
{
|
|
31
|
+
aliases: [ "http://example.com/#{ webfinger_id.split('@').first }" ]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Factory.define :remote_subject do |s|
|
|
38
|
+
s.sequence(:webfinger_id) { |n| "remote_subject-#{ n }@example.com" }
|
|
39
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Post do
|
|
4
|
+
describe "from_entry!" do
|
|
5
|
+
before do
|
|
6
|
+
@remote_subject = Factory(:remote_subject)
|
|
7
|
+
@entry = double("Proudhon::Entry")
|
|
8
|
+
|
|
9
|
+
SocialStream::ActivityStreams.should_receive(:actor_from_entry!) { @remote_subject }
|
|
10
|
+
|
|
11
|
+
@entry.should_receive(:title) { "testing" }
|
|
12
|
+
@entry.should_receive(:summary) { "testing" }
|
|
13
|
+
|
|
14
|
+
end
|
|
15
|
+
it "should create post" do
|
|
16
|
+
post_count = Post.count
|
|
17
|
+
|
|
18
|
+
post = Post.from_entry! @entry, nil
|
|
19
|
+
|
|
20
|
+
post.author.should == @remote_subject.actor
|
|
21
|
+
|
|
22
|
+
Post.count.should == post_count + 1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RemoteSubject do
|
|
4
|
+
describe "find_or_create_by_webfinger_uri" do
|
|
5
|
+
before do
|
|
6
|
+
@remote_subject = Factory(:remote_subject)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "should find without acct:" do
|
|
10
|
+
RemoteSubject.find_or_create_by_webfinger_uri!(@remote_subject.webfinger_id).should == @remote_subject
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should find with acct:" do
|
|
14
|
+
RemoteSubject.find_or_create_by_webfinger_uri!("acct:#{ @remote_subject.webfinger_id}").should == @remote_subject
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should find with alias" do
|
|
18
|
+
splt = @remote_subject.webfinger_id.split('@')
|
|
19
|
+
uri = "http://#{ splt.last }/#{ splt.first }"
|
|
20
|
+
|
|
21
|
+
RemoteSubject.find_or_create_by_webfinger_uri!(uri)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe SocialStream::Ostatus::ActivityStreams do
|
|
4
|
+
describe "from_pshb_callback" do
|
|
5
|
+
before do
|
|
6
|
+
@entry = double("Proudhon::Entry")
|
|
7
|
+
|
|
8
|
+
@remote_subject = double("RemoteSubject")
|
|
9
|
+
|
|
10
|
+
Proudhon::Atom.should_receive(:parse) { [ @entry ] }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "with post note" do
|
|
14
|
+
before do
|
|
15
|
+
@entry.should_receive(:verb) { :post }
|
|
16
|
+
@entry.should_receive(:objtype) { :note }
|
|
17
|
+
|
|
18
|
+
@post = double "post"
|
|
19
|
+
|
|
20
|
+
@post.should_receive :post_activity
|
|
21
|
+
|
|
22
|
+
Post.should_receive(:from_entry!).with(@entry) { @post }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should call stubs" do
|
|
26
|
+
SocialStream::ActivityStreams.from_pshb_callback "test"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: social_stream-ostatus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2012-
|
|
13
|
+
date: 2012-10-03 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: social_stream-base
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
requirements:
|
|
20
20
|
- - ~>
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: 0.
|
|
22
|
+
version: 0.23.0
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -27,7 +27,7 @@ dependencies:
|
|
|
27
27
|
requirements:
|
|
28
28
|
- - ~>
|
|
29
29
|
- !ruby/object:Gem::Version
|
|
30
|
-
version: 0.
|
|
30
|
+
version: 0.23.0
|
|
31
31
|
- !ruby/object:Gem::Dependency
|
|
32
32
|
name: proudhon
|
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -35,7 +35,7 @@ dependencies:
|
|
|
35
35
|
requirements:
|
|
36
36
|
- - ! '>='
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
|
-
version:
|
|
38
|
+
version: 0.3.5
|
|
39
39
|
type: :runtime
|
|
40
40
|
prerelease: false
|
|
41
41
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -43,7 +43,7 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - ! '>='
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version:
|
|
46
|
+
version: 0.3.5
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
48
|
name: nokogiri
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -152,25 +152,46 @@ files:
|
|
|
152
152
|
- README.rdoc
|
|
153
153
|
- Rakefile
|
|
154
154
|
- app/assets/images/logos/actor/remote_subject.png
|
|
155
|
+
- app/assets/images/logos/contact/remote_subject.png
|
|
156
|
+
- app/assets/images/logos/original/remote_subject.png
|
|
157
|
+
- app/assets/images/logos/profile/remote_subject.png
|
|
155
158
|
- app/controllers/host_meta_controller.rb
|
|
156
159
|
- app/controllers/pshb_controller.rb
|
|
157
|
-
- app/controllers/
|
|
160
|
+
- app/controllers/remote_subjects_controller.rb
|
|
161
|
+
- app/controllers/salmon_controller.rb
|
|
158
162
|
- app/controllers/subjects_controller.rb
|
|
159
163
|
- app/controllers/webfinger_controller.rb
|
|
164
|
+
- app/decorators/social_stream/base/activity_decorator.rb
|
|
165
|
+
- app/decorators/social_stream/base/actor_decorator.rb
|
|
166
|
+
- app/decorators/social_stream/base/audience_decorator.rb
|
|
167
|
+
- app/decorators/social_stream/base/relation/custom_decorator.rb
|
|
168
|
+
- app/decorators/social_stream/base/tie_decorator.rb
|
|
169
|
+
- app/models/actor_key.rb
|
|
160
170
|
- app/models/remote_subject.rb
|
|
161
|
-
- app/views/
|
|
171
|
+
- app/views/remote_subjects/_show.html.erb
|
|
172
|
+
- app/views/remote_subjects/show.html.erb
|
|
162
173
|
- config/locales/en.yml
|
|
163
174
|
- config/routes.rb
|
|
164
175
|
- db/migrate/20120905145030_create_social_stream_ostatus.rb
|
|
176
|
+
- db/migrate/20120918194708_create_actor_keys.rb
|
|
165
177
|
- lib/generators/social_stream/ostatus/install_generator.rb
|
|
166
178
|
- lib/generators/social_stream/ostatus/templates/initializer.rb
|
|
167
179
|
- lib/social_stream-ostatus.rb
|
|
168
180
|
- lib/social_stream/migrations/ostatus.rb
|
|
181
|
+
- lib/social_stream/ostatus/activity_streams.rb
|
|
182
|
+
- lib/social_stream/ostatus/controllers/debug_requests.rb
|
|
169
183
|
- lib/social_stream/ostatus/engine.rb
|
|
184
|
+
- lib/social_stream/ostatus/models/activity.rb
|
|
170
185
|
- lib/social_stream/ostatus/models/actor.rb
|
|
171
186
|
- lib/social_stream/ostatus/models/audience.rb
|
|
187
|
+
- lib/social_stream/ostatus/models/object.rb
|
|
188
|
+
- lib/social_stream/ostatus/models/relation/custom.rb
|
|
189
|
+
- lib/social_stream/ostatus/models/tie.rb
|
|
172
190
|
- lib/social_stream/ostatus/version.rb
|
|
173
191
|
- social_stream-ostatus.gemspec
|
|
192
|
+
- spec/controllers/host_meta_controller_spec.rb
|
|
193
|
+
- spec/controllers/remote_subjects_controller_spec.rb
|
|
194
|
+
- spec/controllers/webfinger_controller_spec.rb
|
|
174
195
|
- spec/dummy/Rakefile
|
|
175
196
|
- spec/dummy/app/controllers/application_controller.rb
|
|
176
197
|
- spec/dummy/app/helpers/application_helper.rb
|
|
@@ -202,8 +223,13 @@ files:
|
|
|
202
223
|
- spec/dummy/public/javascripts/rails.js
|
|
203
224
|
- spec/dummy/public/stylesheets/.gitkeep
|
|
204
225
|
- spec/dummy/script/rails
|
|
226
|
+
- spec/factories/remote_subject.rb
|
|
205
227
|
- spec/integration/navigation_spec.rb
|
|
228
|
+
- spec/models/actor_key_spec.rb
|
|
229
|
+
- spec/models/post_spec.rb
|
|
230
|
+
- spec/models/remote_subject_spec.rb
|
|
206
231
|
- spec/social_stream_ostatus.spec.rb
|
|
232
|
+
- spec/social_stream_ostatus_activity_streams.spec.rb
|
|
207
233
|
- spec/spec_helper.rb
|
|
208
234
|
homepage: http://social-stream.dit.upm.es
|
|
209
235
|
licenses: []
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
class RemoteusersController < ApplicationController
|
|
2
|
-
before_filter :authenticate_user!
|
|
3
|
-
|
|
4
|
-
def index
|
|
5
|
-
if params[:slug].present?
|
|
6
|
-
#Selecting the remote subject
|
|
7
|
-
u = RemoteSubject.find_or_create_using_wslug(params[:slug])
|
|
8
|
-
|
|
9
|
-
#Creating the tie between me and the remote subject
|
|
10
|
-
t = Tie.create!(:sender => current_user.actor,
|
|
11
|
-
:receiver => u.actor,
|
|
12
|
-
:relation_name => "friend")
|
|
13
|
-
|
|
14
|
-
#Requesting a subscription to the hub
|
|
15
|
-
t = Thread.new do
|
|
16
|
-
uri = URI.parse(SocialStream::Ostatus.hub)
|
|
17
|
-
response = Net::HTTP::post_form(uri,{ 'hub.callback' => pshb_callback_url,
|
|
18
|
-
'hub.mode' => "subscribe",
|
|
19
|
-
'hub.topic' => u.public_feed_url,
|
|
20
|
-
'hub.verify' => 'sync'})
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
respond_to do |format|
|
|
26
|
-
format.html
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
end
|