| 
									
										
										
										
											2016-11-15 16:56:29 +01:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-20 00:39:03 +02:00
										 |  |  | class SubscribeService < BaseService | 
					
						
							|  |  |  |   def call(account) | 
					
						
							| 
									
										
										
										
											2017-08-21 17:32:41 +02:00
										 |  |  |     return if account.hub_url.blank? | 
					
						
							| 
									
										
										
										
											2017-07-19 17:06:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 20:41:49 +02:00
										 |  |  |     @account        = account | 
					
						
							|  |  |  |     @account.secret = SecureRandom.hex | 
					
						
							| 
									
										
										
										
											2018-03-24 20:49:54 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     build_request.perform do |response| | 
					
						
							|  |  |  |       if response_failed_permanently? response | 
					
						
							|  |  |  |         # We're not allowed to subscribe. Fail and move on. | 
					
						
							|  |  |  |         @account.secret = '' | 
					
						
							|  |  |  |         @account.save! | 
					
						
							|  |  |  |       elsif response_successful? response | 
					
						
							|  |  |  |         # The subscription will be confirmed asynchronously. | 
					
						
							|  |  |  |         @account.save! | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         # The response was either a 429 rate limit, or a 5xx error. | 
					
						
							|  |  |  |         # We need to retry at a later time. Fail loudly! | 
					
						
							|  |  |  |         raise Mastodon::UnexpectedResponseError, response | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-09-20 00:39:03 +02:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2017-05-05 02:23:01 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-14 20:41:49 +02:00
										 |  |  |   def build_request | 
					
						
							|  |  |  |     request = Request.new(:post, @account.hub_url, form: subscription_params) | 
					
						
							|  |  |  |     request.on_behalf_of(some_local_account) if some_local_account | 
					
						
							|  |  |  |     request | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def subscription_params | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       'hub.topic': @account.remote_url, | 
					
						
							|  |  |  |       'hub.mode': 'subscribe', | 
					
						
							|  |  |  |       'hub.callback': api_subscription_url(@account.id), | 
					
						
							|  |  |  |       'hub.verify': 'async', | 
					
						
							|  |  |  |       'hub.secret': @account.secret, | 
					
						
							|  |  |  |       'hub.lease_seconds': 7.days.seconds, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def some_local_account | 
					
						
							| 
									
										
										
										
											2017-08-31 06:44:00 -07:00
										 |  |  |     @some_local_account ||= Account.local.where(suspended: false).first | 
					
						
							| 
									
										
										
										
											2017-07-14 20:41:49 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 18:45:02 -04:00
										 |  |  |   # Any response in the 3xx or 4xx range, except for 429 (rate limit) | 
					
						
							| 
									
										
										
										
											2018-03-24 20:49:54 +09:00
										 |  |  |   def response_failed_permanently?(response) | 
					
						
							|  |  |  |     (response.status.redirect? || response.status.client_error?) && !response.status.too_many_requests? | 
					
						
							| 
									
										
										
										
											2017-05-05 02:23:01 +02:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-09-20 00:39:03 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-08 18:45:02 -04:00
										 |  |  |   # Any response in the 2xx range | 
					
						
							| 
									
										
										
										
											2018-03-24 20:49:54 +09:00
										 |  |  |   def response_successful?(response) | 
					
						
							|  |  |  |     response.status.success? | 
					
						
							| 
									
										
										
										
											2016-09-20 00:39:03 +02:00
										 |  |  |   end | 
					
						
							|  |  |  | end |