Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions app/controllers/api/v1/statuses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module Api::V1
class StatusesController < ApiController
before_action :whitelist_domains

def boost_post
@api_base_url = ENV.fetch('MASTODON_INSTANCE_URL')

unless params[:post_url].present? && params[:boost_post_username].present? && params[:boost_post_user_domain].present?
return render_error("Missing post_url or boost_post_username or boost_post_user_domain", :unprocessable_entity)
end

@token = fetch_oauth_token(params[:boost_post_username], params[:boost_post_user_domain])
return render_error("Could not generate OAuth token for #{params[:boost_post_username]}@#{params[:boost_post_user_domain]}", :unauthorized) unless @token.present?

post_id = SearchPostService.new(@api_base_url, @token, params[:post_url]).call
return render_error("Post not found or invalid post URL", :not_found) unless post_id.present?

result = ReblogPostService.new(@token, post_id).call
render json: result
end

private

def whitelist_domains
allowed_domains = ["mo-me.social"]

unless allowed_domains.include?(request.host)
render_error("Request domain not allowed", :forbidden)
end
end

def fetch_oauth_token(username, user_domain)
user_domain = nil if user_domain == 'channel.org'
admin = Account.find_by(username: username, domain: user_domain)
return nil unless admin&.user

GenerateAdminAccessTokenService.new(admin.user.id).call
rescue => e
nil
end

def render_error(message, status)
render json: {
status: status,
body: message
}
end
end
end
38 changes: 38 additions & 0 deletions app/services/reblog_post_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'httparty'

class ReblogPostService
include HTTParty

base_uri ENV['MASTODON_INSTANCE_URL']

def initialize(token, status_id)
@token = token
@status_id = status_id
end

def call
reblog_post
end

private

# Reblog a status
def reblog_post
response = self.class.post(
"/api/v1/statuses/#{@status_id}/reblog",
headers: {
"Authorization" => "Bearer #{@token}",
"Content-Type" => "application/json"
},
body: { visibility: 'public' }.to_json
)

{
status: response.success? ? :ok : :error,
body: response.parsed_response
}
rescue StandardError => e
Rails.logger.error("ReblogPostService Error: #{e.message}")
{ status: :error, body: { error: e.message } }
end
end
21 changes: 21 additions & 0 deletions app/services/search_post_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require 'httparty'

class SearchPostService
def initialize(api_base_url, token, query)
@api_base_url = api_base_url
@token = token
@query = query
end

def call
response = HTTParty.get("#{@api_base_url}/api/v2/search",
query: { q: @query, type: 'statuses', resolve: true, limit: 1 },
headers: { 'Authorization' => "Bearer #{@token}" }
)
if response.success?
return response['statuses']&.first&.dig('id')
end

nil
end
end
9 changes: 7 additions & 2 deletions config/routes/api_v1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@
get 'general_icons', to: 'community_links#general'
get 'social_icons', to: 'community_links#social'

resources :app_versions,only: [] do
resources :app_versions,only: [] do
collection do
get 'check_version' => 'app_versions#check_version', as: 'check_version'
end
Expand All @@ -112,6 +112,11 @@
post :upsert
end
end

resources :statuses, only: [] do
collection do
post :boost_post
end
end
end
end