| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  | class XrdController < ApplicationController | 
					
						
							| 
									
										
										
										
											2016-10-18 16:37:15 +02:00
										 |  |  |   before_action :set_default_format_json, only: :webfinger | 
					
						
							|  |  |  |   before_action :set_default_format_xml, only: :host_meta | 
					
						
							| 
									
										
										
										
											2016-10-18 03:34:26 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   def host_meta | 
					
						
							|  |  |  |     @webfinger_template = "#{webfinger_url}?resource={uri}" | 
					
						
							| 
									
										
										
										
											2016-10-18 02:54:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     respond_to do |format| | 
					
						
							|  |  |  |       format.xml { render content_type: 'application/xrd+xml' } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def webfinger | 
					
						
							| 
									
										
										
										
											2016-12-22 23:17:57 +01:00
										 |  |  |     @account = Account.find_local!(username_from_resource) | 
					
						
							| 
									
										
										
										
											2016-02-29 20:06:39 +01:00
										 |  |  |     @canonical_account_uri = "acct:#{@account.username}@#{Rails.configuration.x.local_domain}" | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |     @magic_key = pem_to_magic_key(@account.keypair.public_key) | 
					
						
							| 
									
										
										
										
											2016-10-18 02:54:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     respond_to do |format| | 
					
						
							|  |  |  |       format.xml  { render content_type: 'application/xrd+xml' } | 
					
						
							|  |  |  |       format.json { render content_type: 'application/jrd+json' } | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-02-29 19:42:08 +01:00
										 |  |  |   rescue ActiveRecord::RecordNotFound | 
					
						
							| 
									
										
										
										
											2016-08-17 17:56:23 +02:00
										 |  |  |     head 404
 | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-18 16:37:15 +02:00
										 |  |  |   def set_default_format_xml | 
					
						
							| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  |     request.format = 'xml' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil? | 
					
						
							| 
									
										
										
										
											2016-10-18 16:37:15 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def set_default_format_json | 
					
						
							| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  |     request.format = 'json' if request.headers['HTTP_ACCEPT'].nil? && params[:format].nil? | 
					
						
							| 
									
										
										
										
											2016-10-18 03:34:26 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   def username_from_resource | 
					
						
							| 
									
										
										
										
											2016-10-18 02:54:49 +02:00
										 |  |  |     if resource_param.start_with?('acct:') || resource_param.include?('@') | 
					
						
							| 
									
										
										
										
											2016-03-16 18:29:52 +01:00
										 |  |  |       resource_param.split('@').first.gsub('acct:', '') | 
					
						
							| 
									
										
										
										
											2016-02-28 15:46:29 +01:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2016-03-16 18:29:52 +01:00
										 |  |  |       url = Addressable::URI.parse(resource_param) | 
					
						
							| 
									
										
										
										
											2016-02-28 15:46:29 +01:00
										 |  |  |       url.path.gsub('/users/', '') | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def pem_to_magic_key(public_key) | 
					
						
							|  |  |  |     modulus, exponent = [public_key.n, public_key.e].map do |component| | 
					
						
							| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  |       result = [] | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 21:28:21 +02:00
										 |  |  |       until component.zero? | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |         result << [component % 256].pack('C') | 
					
						
							|  |  |  |         component >>= 8
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  |       result.reverse.join | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-29 21:28:21 +02:00
										 |  |  |     (['RSA'] + [modulus, exponent].map { |n| Base64.urlsafe_encode64(n) }).join('.') | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-03-16 18:29:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   def resource_param | 
					
						
							|  |  |  |     params.require(:resource) | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-02-22 16:00:20 +01:00
										 |  |  | end |