summaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
authorAzul <azul@leap.se>2013-01-25 19:26:51 +0100
committerAzul <azul@leap.se>2013-01-25 19:26:51 +0100
commit9563ed191556e739c8f99be4d0fc75ac31c8f6cd (patch)
tree5a87fc1947921766a5430896f4bcf531dc396bff /users
parent77a51e1de520299afd2b33e7a3992aaafab1d6ae (diff)
parentdac578781baf73a006cc78e29588dd1f6fdc0fd3 (diff)
Merge branch 'master' into merge_leap_ca
Diffstat (limited to 'users')
-rw-r--r--users/app/controllers/webfinger_controller.rb19
-rw-r--r--users/app/models/user.rb2
-rw-r--r--users/app/views/users/_public_key_field.html.haml1
-rw-r--r--users/app/views/users/edit.html.haml1
-rw-r--r--users/app/views/webfinger/host_meta.xml.erb11
-rw-r--r--users/app/views/webfinger/search.xml.erb7
-rw-r--r--users/config/locales/en.yml2
-rw-r--r--users/config/routes.rb2
-rw-r--r--users/lib/leap_web_users/engine.rb2
-rw-r--r--users/lib/webfinger.rb6
-rw-r--r--users/lib/webfinger/host_meta_presenter.rb30
-rw-r--r--users/lib/webfinger/user_presenter.rb35
-rw-r--r--users/test/functional/webfinger_controller_test.rb33
-rw-r--r--users/test/unit/webfinger/host_meta_presenter_test.rb24
-rw-r--r--users/test/unit/webfinger/user_presenter_test.rb49
15 files changed, 224 insertions, 0 deletions
diff --git a/users/app/controllers/webfinger_controller.rb b/users/app/controllers/webfinger_controller.rb
new file mode 100644
index 0000000..8872802
--- /dev/null
+++ b/users/app/controllers/webfinger_controller.rb
@@ -0,0 +1,19 @@
+class WebfingerController < ApplicationController
+
+ respond_to :xml, :json
+ layout false
+
+ def host_meta
+ @host_meta = Webfinger::HostMetaPresenter.new(request)
+ respond_with @host_meta
+ end
+
+ def search
+ username = params[:q].split('@')[0].to_s.downcase
+ user = User.find_by_login(username)
+ raise RECORD_NOT_FOUND, 'User not found' unless user.present?
+ @presenter = Webfinger::UserPresenter.new(user, request)
+ respond_with @presenter
+ end
+
+end
diff --git a/users/app/models/user.rb b/users/app/models/user.rb
index 292fb13..80d49a3 100644
--- a/users/app/models/user.rb
+++ b/users/app/models/user.rb
@@ -9,6 +9,8 @@ class User < CouchRest::Model::Base
property :email_forward, String, :accessible => true
property :email_aliases, [LocalEmail]
+ property :public_key, :accessible => true
+
validates :login, :password_salt, :password_verifier,
:presence => true
diff --git a/users/app/views/users/_public_key_field.html.haml b/users/app/views/users/_public_key_field.html.haml
new file mode 100644
index 0000000..af88cbd
--- /dev/null
+++ b/users/app/views/users/_public_key_field.html.haml
@@ -0,0 +1 @@
+= f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "span5", :rows => 20} # will want to tweak this to be wide enough (maybe smaller text?)
diff --git a/users/app/views/users/edit.html.haml b/users/app/views/users/edit.html.haml
index 238c0eb..950a3b1 100644
--- a/users/app/views/users/edit.html.haml
+++ b/users/app/views/users/edit.html.haml
@@ -8,6 +8,7 @@
%legend=t :email_address
The associated email address is
= render @user.email_address, :as => :span
+ = user_form_with 'public_key_field', :legend => :public_key
= user_form_with 'email_forward_field', :legend => :forward_email
= user_form_with 'email_aliases', :legend => :add_email_alias
= render 'tabs/tabs', :tabs => [:account, :email]
diff --git a/users/app/views/webfinger/host_meta.xml.erb b/users/app/views/webfinger/host_meta.xml.erb
new file mode 100644
index 0000000..cfcbcc0
--- /dev/null
+++ b/users/app/views/webfinger/host_meta.xml.erb
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+ <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
+
+ <Subject><%= @host_meta.subject %></Subject>
+
+ <%- @host_meta.links.each do |rel, link| %>
+ <Link rel='<%= rel %>'
+ type='<%= link[:type] %>'
+ template='<%= link[:template] %>' />
+ <%- end %>
+ </XRD>
diff --git a/users/app/views/webfinger/search.xml.erb b/users/app/views/webfinger/search.xml.erb
new file mode 100644
index 0000000..7328552
--- /dev/null
+++ b/users/app/views/webfinger/search.xml.erb
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
+ <Subject><%= @presenter.subject %></Subject>
+ <%- @presenter.links.each do |rel, link| %>
+ <Link rel=<%=rel%> type=<%=link[:type]%> href="<%= link[:key] %>"/>
+ <% end %>
+</XRD>
diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml
index 7a6ab90..493b5db 100644
--- a/users/config/locales/en.yml
+++ b/users/config/locales/en.yml
@@ -13,10 +13,12 @@ en:
set_email_address: "Set email address"
forward_email: "Forward email"
email_aliases: "Email aliases"
+ public_key: "Public Key"
add_email_alias: "Add email alias"
user_updated_successfully: "Settings have been updated successfully."
user_created_successfully: "Successfully created your account."
email_alias_destroyed_successfully: "Successfully removed the alias '%{alias}'."
+ use_ascii_key: "Use ASCII-armored PGP key"
activemodel:
models:
diff --git a/users/config/routes.rb b/users/config/routes.rb
index 0c2d8d9..4127862 100644
--- a/users/config/routes.rb
+++ b/users/config/routes.rb
@@ -18,4 +18,6 @@ Rails.application.routes.draw do
resources :email_aliases, :only => [:destroy], :id => /.*/
end
+ get "/.well-known/host-meta" => 'webfinger#host_meta'
+ get "/webfinger" => 'webfinger#search'
end
diff --git a/users/lib/leap_web_users/engine.rb b/users/lib/leap_web_users/engine.rb
index 7033576..f8ed71c 100644
--- a/users/lib/leap_web_users/engine.rb
+++ b/users/lib/leap_web_users/engine.rb
@@ -7,6 +7,8 @@ require "ruby-srp"
require "warden/session_serializer"
require "warden/strategies/secure_remote_password"
+require "webfinger"
+
module LeapWebUsers
class Engine < ::Rails::Engine
diff --git a/users/lib/webfinger.rb b/users/lib/webfinger.rb
new file mode 100644
index 0000000..dd49b41
--- /dev/null
+++ b/users/lib/webfinger.rb
@@ -0,0 +1,6 @@
+module Webfinger
+
+ autoload :HostMetaPresenter, 'webfinger/host_meta_presenter'
+ autoload :UserPresenter, 'webfinger/user_presenter'
+
+end
diff --git a/users/lib/webfinger/host_meta_presenter.rb b/users/lib/webfinger/host_meta_presenter.rb
new file mode 100644
index 0000000..84ab7a9
--- /dev/null
+++ b/users/lib/webfinger/host_meta_presenter.rb
@@ -0,0 +1,30 @@
+require 'uri'
+
+class Webfinger::HostMetaPresenter
+ def initialize(request)
+ @request = request
+ end
+
+ def to_json(options = {})
+ {
+ subject: subject,
+ links: links
+ }.to_json(options)
+ end
+
+ def subject
+ url = URI.parse(@request.url)
+ url.path = ''
+ url.to_s
+ end
+
+ def links
+ { lrdd: { type: 'application/xrd+xml', template: webfinger_template } }
+ end
+
+ protected
+
+ def webfinger_template(path = 'webfinger', query_param='q')
+ "#{subject}/#{path}?#{query_param}={uri}"
+ end
+end
diff --git a/users/lib/webfinger/user_presenter.rb b/users/lib/webfinger/user_presenter.rb
new file mode 100644
index 0000000..329f477
--- /dev/null
+++ b/users/lib/webfinger/user_presenter.rb
@@ -0,0 +1,35 @@
+class Webfinger::UserPresenter
+ include Rails.application.routes.url_helpers
+ attr_accessor :user
+
+ def initialize(user, request)
+ @user = user
+ @request = request
+ end
+
+ def to_json(options = {})
+ {
+ subject: subject,
+ links: links
+ }.to_json(options)
+ end
+
+ def subject
+ "acct:#{@user.email_address}"
+ end
+
+ def links
+ links = {}
+ links[:public_key] = { type: 'PGP', href: key } if key
+ return links
+ end
+
+ protected
+
+ def key
+ if @user.public_key.present?
+ Base64.encode64(@user.public_key.to_s)
+ end
+ end
+
+end
diff --git a/users/test/functional/webfinger_controller_test.rb b/users/test/functional/webfinger_controller_test.rb
new file mode 100644
index 0000000..6597b69
--- /dev/null
+++ b/users/test/functional/webfinger_controller_test.rb
@@ -0,0 +1,33 @@
+require 'test_helper'
+
+class WebfingerControllerTest < ActionController::TestCase
+
+ test "get host meta xml" do
+ get :host_meta, :format => :xml
+ assert_response :success
+ assert_equal "application/xml", response.content_type
+ end
+
+ test "get host meta json" do
+ get :host_meta, :format => :json
+ assert_response :success
+ assert_equal "application/json", response.content_type
+ end
+
+ test "get user webfinger xml" do
+ @user = stub_record :user, :public_key => 'my public key'
+ User.stubs(:find_by_login).with(@user.login).returns(@user)
+ get :search, :q => @user.email_address.to_s, :format => :xml
+ assert_response :success
+ assert_equal "application/xml", response.content_type
+ end
+
+ test "get user webfinger json" do
+ @user = stub_record :user, :public_key => 'my public key'
+ User.stubs(:find_by_login).with(@user.login).returns(@user)
+ get :search, :q => @user.email_address.to_s, :format => :json
+ assert_response :success
+ assert_equal "application/json", response.content_type
+ end
+
+end
diff --git a/users/test/unit/webfinger/host_meta_presenter_test.rb b/users/test/unit/webfinger/host_meta_presenter_test.rb
new file mode 100644
index 0000000..af86404
--- /dev/null
+++ b/users/test/unit/webfinger/host_meta_presenter_test.rb
@@ -0,0 +1,24 @@
+require 'test_helper'
+require 'webfinger'
+require 'json'
+
+class Webfinger::HostMetaPresenterTest < ActiveSupport::TestCase
+
+ setup do
+ @request = stub(
+ url: "https://#{APP_CONFIG[:domain]}/.well-known/host-meta"
+ )
+ @meta = Webfinger::HostMetaPresenter.new(@request)
+ end
+
+ test "creates proper json" do
+ hash = JSON.parse @meta.to_json
+ assert_equal ["subject", "links"].sort, hash.keys.sort
+ hash.each do |key, value|
+ assert_equal @meta.send(key.to_sym).to_json, value.to_json
+ end
+ end
+
+end
+
+
diff --git a/users/test/unit/webfinger/user_presenter_test.rb b/users/test/unit/webfinger/user_presenter_test.rb
new file mode 100644
index 0000000..04aeb22
--- /dev/null
+++ b/users/test/unit/webfinger/user_presenter_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+require 'webfinger'
+require 'json'
+
+class Webfinger::UserPresenterTest < ActiveSupport::TestCase
+
+
+ setup do
+ @user = stub(
+ username: 'testuser',
+ email_address: "testuser@#{APP_CONFIG[:domain]}"
+ )
+ @request = stub(
+ host: APP_CONFIG[:domain]
+ )
+ end
+
+ test "user without key has no links" do
+ @user.stubs :public_key => nil
+ presenter = Webfinger::UserPresenter.new(@user, @request)
+ assert_equal Hash.new, presenter.links
+ end
+
+ test "user with key has corresponding link" do
+ @user.stubs :public_key => "here's a key"
+ presenter = Webfinger::UserPresenter.new(@user, @request)
+ assert_equal [:public_key], presenter.links.keys
+ assert_equal "PGP", presenter.links[:public_key][:type]
+ assert_equal presenter.send(:key), presenter.links[:public_key][:href]
+ end
+
+ test "key is base64 encoded" do
+ @user.stubs :public_key => "here's a key"
+ presenter = Webfinger::UserPresenter.new(@user, @request)
+ assert_equal Base64.encode64(@user.public_key), presenter.send(:key)
+ end
+
+ test "creates proper json representation" do
+ @user.stubs :public_key => "here's a key"
+ presenter = Webfinger::UserPresenter.new(@user, @request)
+ hash = JSON.parse presenter.to_json
+ assert_equal ["subject", "links"].sort, hash.keys.sort
+ hash.each do |key, value|
+ assert_equal presenter.send(key.to_sym).to_json, value.to_json
+ end
+ end
+
+
+end