diff --git a/.gitignore b/.gitignore index 901f4bf..f051548 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .bundle/ -log/*.log pkg/ # IDE files @@ -8,6 +7,9 @@ pkg/ # coverage reports coverage +# documentation +rdoc + # Temporary files .DS_Store *.swp diff --git a/.rubocop.yml b/.rubocop.yml index 1273fea..3ecc6cb 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,6 +3,7 @@ AllCops: Exclude: - "bin/**/*" - "test/dummy/bin/**/*" + - "test/dummy/db/**/*" # Commonly used screens these days easily fit more than 80 characters. Metrics/LineLength: diff --git a/app/controllers/diaspora_federation/webfinger_controller.rb b/app/controllers/diaspora_federation/webfinger_controller.rb new file mode 100644 index 0000000..a8f217c --- /dev/null +++ b/app/controllers/diaspora_federation/webfinger_controller.rb @@ -0,0 +1,20 @@ +require_dependency "diaspora_federation/application_controller" + +module DiasporaFederation + class WebfingerController < ApplicationController + def host_meta + render "host_meta", content_type: "application/xrd+xml" + end + + ## + # this is the pre RFC 7033 webfinger + def legacy_webfinger + @person = Person.find_local_by_diaspora_handle(params[:q].strip.downcase.gsub("acct:", "")) if params[:q] + + return render nothing: true, status: 404 if @person.nil? + + logger.info "webfinger profile request for: #{@person.diaspora_handle}" + render "webfinger", content_type: "application/xrd+xml" + end + end +end diff --git a/app/views/diaspora_federation/webfinger/host_meta.erb b/app/views/diaspora_federation/webfinger/host_meta.erb new file mode 100644 index 0000000..dd796f3 --- /dev/null +++ b/app/views/diaspora_federation/webfinger/host_meta.erb @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/app/views/diaspora_federation/webfinger/webfinger.erb b/app/views/diaspora_federation/webfinger/webfinger.erb new file mode 100644 index 0000000..eaf5a4d --- /dev/null +++ b/app/views/diaspora_federation/webfinger/webfinger.erb @@ -0,0 +1,14 @@ + + + acct:<%=@person.diaspora_handle%> + "<%= @person.url %>" + + + + + + + + + + diff --git a/config/routes.rb b/config/routes.rb index de3c0f8..64369d3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,4 +3,9 @@ DiasporaFederation::Engine.routes.draw do post "receive/public" => :public, :as => "receive_public" post "receive/users/:guid" => :private, :as => "receive_private" end + + controller :webfinger do + get ".well-known/host-meta" => :host_meta, :as => "host_meta" + get "webfinger" => :legacy_webfinger, :as => "legacy_webfinger" + end end diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index c5faea4..0bb8953 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -1,4 +1,36 @@ require "diaspora_federation/engine" +## +# diaspora* federation rails engine module DiasporaFederation + class << self + ## + # the pod url + # + # Example: + # config.server_uri = URI("http://localhost:3000/") + # or + # config.server_uri = AppConfig.pod_uri + attr_accessor :server_uri + + ## + # the class to use as person. + # + # Example: + # config.person_class = Person.class.to_s + attr_accessor :person_class + def person_class + const_get(@person_class) + end + + ## + # configure the federation engine + # + # DiasporaFederation.configure do |config| + # config.server_uri = "http://localhost:3000/" + # end + def configure + yield self + end + end end diff --git a/lib/diaspora_federation/engine.rb b/lib/diaspora_federation/engine.rb index db6a12c..183116a 100644 --- a/lib/diaspora_federation/engine.rb +++ b/lib/diaspora_federation/engine.rb @@ -1,4 +1,6 @@ module DiasporaFederation + ## + # diaspora* federation rails engine class Engine < ::Rails::Engine isolate_namespace DiasporaFederation diff --git a/lib/diaspora_federation/version.rb b/lib/diaspora_federation/version.rb index 6120d2a..ef1fcb1 100644 --- a/lib/diaspora_federation/version.rb +++ b/lib/diaspora_federation/version.rb @@ -1,3 +1,5 @@ module DiasporaFederation + ## + # the gem version VERSION = "0.0.1" end diff --git a/spec/controllers/diaspora_federation/webfinger_controller_spec.rb b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb new file mode 100644 index 0000000..375d8b2 --- /dev/null +++ b/spec/controllers/diaspora_federation/webfinger_controller_spec.rb @@ -0,0 +1,43 @@ +module DiasporaFederation + describe WebfingerController, type: :controller do + routes { DiasporaFederation::Engine.routes } + + describe "#host_meta" do + it "succeeds" do + get :host_meta + expect(response).to be_success + end + + it "contains the webfinger-template" do + DiasporaFederation.server_uri = "http://localhost:3000/" + get :host_meta + expect(response.body).to include "template=\"http://localhost:3000/webfinger?q={uri}\"" + end + + it "renders the host_meta template" do + get :host_meta + expect(response).to render_template("host_meta") + expect(response.header["Content-Type"]).to include "application/xrd+xml" + end + end + + describe "#legacy_webfinger" do + it "succeeds when the person exists" do + skip + post :legacy_webfinger, "q" => "bob@diaspora.pod" + expect(response).to be_success + end + + it "succeeds with 'acct:' in the query when the person exists" do + skip + post :legacy_webfinger, "q" => "acct:bob@diaspora.pod" + expect(response).to be_success + end + + it "404s when the person does not exist" do + post :legacy_webfinger, "q" => "me@mydiaspora.pod.com" + expect(response).to be_not_found + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 544f03e..0aaabcf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,6 +14,8 @@ CodeClimate::TestReporter.start RSpec.configure do |config| config.infer_spec_type_from_file_location! + config.render_views + config.expect_with :rspec do |expect_config| expect_config.syntax = :expect end diff --git a/test/dummy/app/models/.keep b/test/dummy/app/models/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/test/dummy/app/models/person.rb b/test/dummy/app/models/person.rb new file mode 100644 index 0000000..a92a5b6 --- /dev/null +++ b/test/dummy/app/models/person.rb @@ -0,0 +1,26 @@ +class Person < ActiveRecord::Base + def salmon_url + "#{url}receive/users/#{guid}" + end + + def atom_url + "#{url}public/#{diaspora_handle.split('@')[0]}.atom" + end + + def profile_url + "#{url}u/#{diaspora_handle.split('@')[0]}" + end + + def hcard_url + "#{url}hcard/users/#{guid}" + end + + def self.find_by_diaspora_handle(identifier) + find_by(diaspora_handle: identifier) + end + + def self.find_local_by_diaspora_handle(identifier) + # no remote? check ... this class is only for testing + find_by_diaspora_handle(identifier) + end +end diff --git a/test/dummy/config/initializers/diaspora_federation.rb b/test/dummy/config/initializers/diaspora_federation.rb new file mode 100644 index 0000000..5d67288 --- /dev/null +++ b/test/dummy/config/initializers/diaspora_federation.rb @@ -0,0 +1,8 @@ +# configure the federation engine +DiasporaFederation.configure do |config| + # the pod url + config.server_uri = URI("http://localhost:3000/") + + # the class to be used for a person + config.person_class = Person.class.to_s +end diff --git a/test/dummy/db/migrate/20150614014411_create_people.rb b/test/dummy/db/migrate/20150614014411_create_people.rb new file mode 100644 index 0000000..1bd5087 --- /dev/null +++ b/test/dummy/db/migrate/20150614014411_create_people.rb @@ -0,0 +1,12 @@ +class CreatePeople < ActiveRecord::Migration + def change + create_table :people do |t| + t.string "guid", null: false + t.text "url", null: false + t.string "diaspora_handle", null: false + t.text "serialized_public_key", null: false + + t.timestamps null: false + end + end +end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb new file mode 100644 index 0000000..7167574 --- /dev/null +++ b/test/dummy/db/schema.rb @@ -0,0 +1,25 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20150614014411) do + + create_table "people", force: :cascade do |t| + t.string "guid", null: false + t.text "url", null: false + t.string "diaspora_handle", null: false + t.text "serialized_public_key", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + +end