Clean up well-known routes/controllers (#1649)
* Add request spec for host meta route returning xml * Add routing spec for xrd routes * Update well-known routes * Move webfinger and host-meta actions to their own controllers
This commit is contained in:
		
							parent
							
								
									3a9eb81a80
								
							
						
					
					
						commit
						137100dcf3
					
				
					 12 changed files with 119 additions and 83 deletions
				
			
		
							
								
								
									
										13
									
								
								app/controllers/well_known/host_meta_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/controllers/well_known/host_meta_controller.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  |   # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | module WellKnown | ||||||
|  |   class HostMetaController < ApplicationController | ||||||
|  |     def show | ||||||
|  |       @webfinger_template = "#{webfinger_url}?resource={uri}" | ||||||
|  | 
 | ||||||
|  |       respond_to do |format| | ||||||
|  |         format.xml { render content_type: 'application/xrd+xml' } | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										43
									
								
								app/controllers/well_known/webfinger_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/controllers/well_known/webfinger_controller.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | module WellKnown | ||||||
|  |   class WebfingerController < ApplicationController | ||||||
|  |     def show | ||||||
|  |       @account = Account.find_local!(username_from_resource) | ||||||
|  |       @canonical_account_uri = @account.to_webfinger_s | ||||||
|  |       @magic_key = pem_to_magic_key(@account.keypair.public_key) | ||||||
|  | 
 | ||||||
|  |       respond_to do |format| | ||||||
|  |         format.xml  { render content_type: 'application/xrd+xml' } | ||||||
|  |         format.json { render content_type: 'application/jrd+json' } | ||||||
|  |       end | ||||||
|  |     rescue ActiveRecord::RecordNotFound | ||||||
|  |       head 404 | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     private | ||||||
|  | 
 | ||||||
|  |     def username_from_resource | ||||||
|  |       WebfingerResource.new(resource_param).username | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def pem_to_magic_key(public_key) | ||||||
|  |       modulus, exponent = [public_key.n, public_key.e].map do |component| | ||||||
|  |         result = [] | ||||||
|  | 
 | ||||||
|  |         until component.zero? | ||||||
|  |           result << [component % 256].pack('C') | ||||||
|  |           component >>= 8 | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         result.reverse.join | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       (['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.') | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def resource_param | ||||||
|  |       params.require(:resource) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -1,55 +0,0 @@ | ||||||
| # frozen_string_literal: true |  | ||||||
| 
 |  | ||||||
| class XrdController < ApplicationController |  | ||||||
|   before_action :set_default_format_xml, only: :host_meta |  | ||||||
| 
 |  | ||||||
|   def host_meta |  | ||||||
|     @webfinger_template = "#{webfinger_url}?resource={uri}" |  | ||||||
| 
 |  | ||||||
|     respond_to do |format| |  | ||||||
|       format.xml { render content_type: 'application/xrd+xml' } |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def webfinger |  | ||||||
|     @account = Account.find_local!(username_from_resource) |  | ||||||
|     @canonical_account_uri = @account.to_webfinger_s |  | ||||||
|     @magic_key = pem_to_magic_key(@account.keypair.public_key) |  | ||||||
| 
 |  | ||||||
|     respond_to do |format| |  | ||||||
|       format.xml  { render content_type: 'application/xrd+xml' } |  | ||||||
|       format.json { render content_type: 'application/jrd+json' } |  | ||||||
|     end |  | ||||||
|   rescue ActiveRecord::RecordNotFound |  | ||||||
|     head 404 |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   private |  | ||||||
| 
 |  | ||||||
|   def set_default_format_xml |  | ||||||
|     request.format = 'xml' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil? |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def username_from_resource |  | ||||||
|     WebfingerResource.new(resource_param).username |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def pem_to_magic_key(public_key) |  | ||||||
|     modulus, exponent = [public_key.n, public_key.e].map do |component| |  | ||||||
|       result = [] |  | ||||||
| 
 |  | ||||||
|       until component.zero? |  | ||||||
|         result << [component % 256].pack('C') |  | ||||||
|         component >>= 8 |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       result.reverse.join |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     (['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.') |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   def resource_param |  | ||||||
|     params.require(:resource) |  | ||||||
|   end |  | ||||||
| end |  | ||||||
|  | @ -15,8 +15,8 @@ Rails.application.routes.draw do | ||||||
|     controllers authorizations: 'oauth/authorizations', authorized_applications: 'oauth/authorized_applications' |     controllers authorizations: 'oauth/authorizations', authorized_applications: 'oauth/authorized_applications' | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta |   get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' } | ||||||
|   get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger, defaults: { format: 'json' } |   get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger, defaults: { format: 'json' } | ||||||
| 
 | 
 | ||||||
|   devise_for :users, path: 'auth', controllers: { |   devise_for :users, path: 'auth', controllers: { | ||||||
|     sessions:           'auth/sessions', |     sessions:           'auth/sessions', | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								spec/controllers/well_known/host_meta_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								spec/controllers/well_known/host_meta_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | describe WellKnown::HostMetaController, type: :controller do | ||||||
|  |   render_views | ||||||
|  | 
 | ||||||
|  |   describe 'GET #show' do | ||||||
|  |     it 'returns http success' do | ||||||
|  |       get :show, format: :xml | ||||||
|  | 
 | ||||||
|  |       expect(response).to have_http_status(:success) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										21
									
								
								spec/controllers/well_known/webfinger_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								spec/controllers/well_known/webfinger_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | describe WellKnown::WebfingerController, type: :controller do | ||||||
|  |   render_views | ||||||
|  | 
 | ||||||
|  |   describe 'GET #show' do | ||||||
|  |     let(:alice) { Fabricate(:account, username: 'alice') } | ||||||
|  | 
 | ||||||
|  |     it 'returns http success when account can be found' do | ||||||
|  |       get :show, params: { resource: alice.to_webfinger_s }, format: :json | ||||||
|  | 
 | ||||||
|  |       expect(response).to have_http_status(:success) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns http not found when account cannot be found' do | ||||||
|  |       get :show, params: { resource: 'acct:not@existing.com' }, format: :json | ||||||
|  | 
 | ||||||
|  |       expect(response).to have_http_status(:not_found) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -1,26 +0,0 @@ | ||||||
| require 'rails_helper' |  | ||||||
| 
 |  | ||||||
| RSpec.describe XrdController, type: :controller do |  | ||||||
|   render_views |  | ||||||
| 
 |  | ||||||
|   describe 'GET #host_meta' do |  | ||||||
|     it 'returns http success' do |  | ||||||
|       get :host_meta |  | ||||||
|       expect(response).to have_http_status(:success) |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   describe 'GET #webfinger' do |  | ||||||
|     let(:alice) { Fabricate(:account, username: 'alice') } |  | ||||||
| 
 |  | ||||||
|     it 'returns http success when account can be found' do |  | ||||||
|       get :webfinger, params: { resource: alice.to_webfinger_s }, format: :json |  | ||||||
|       expect(response).to have_http_status(:success) |  | ||||||
|     end |  | ||||||
| 
 |  | ||||||
|     it 'returns http not found when account cannot be found' do |  | ||||||
|       get :webfinger, params: { resource: 'acct:not@existing.com' }, format: :json |  | ||||||
|       expect(response).to have_http_status(:not_found) |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| end |  | ||||||
							
								
								
									
										12
									
								
								spec/requests/host_meta_request_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								spec/requests/host_meta_request_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | require "rails_helper" | ||||||
|  | 
 | ||||||
|  | describe "The host_meta route" do | ||||||
|  |   describe "requested without accepts headers" do | ||||||
|  |     it "returns an xml response" do | ||||||
|  |       get host_meta_url | ||||||
|  | 
 | ||||||
|  |       expect(response).to have_http_status(:success) | ||||||
|  |       expect(response.content_type).to eq "application/xrd+xml" | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										15
									
								
								spec/routing/well_known_routes_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spec/routing/well_known_routes_spec.rb
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | describe 'the host-meta route' do | ||||||
|  |   it 'routes to correct place with xml format' do | ||||||
|  |     expect(get('/.well-known/host-meta')). | ||||||
|  |       to route_to('well_known/host_meta#show', format: 'xml') | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | describe 'the webfinger route' do | ||||||
|  |   it 'routes to correct place with json format' do | ||||||
|  |     expect(get('/.well-known/webfinger')). | ||||||
|  |       to route_to('well_known/webfinger#show', format: 'json') | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
		Reference in a new issue