From a996f3bd05fc480247fd112f23fa3e67f7d5d7b5 Mon Sep 17 00:00:00 2001
From: Star Rauchenberger <fefferburbia@gmail.com>
Date: Sat, 7 Dec 2024 15:54:39 -0500
Subject: Added support for liking blog posts via webmention

---
 app/controllers/blogs_controller.rb | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

(limited to 'app/controllers')

diff --git a/app/controllers/blogs_controller.rb b/app/controllers/blogs_controller.rb
index 033d6bb..4bbbc28 100644
--- a/app/controllers/blogs_controller.rb
+++ b/app/controllers/blogs_controller.rb
@@ -1,6 +1,9 @@
+require 'microformats'
 require 'redcarpet/render_strip'
+require 'webmention'
 
 class BlogsController < ApplicationController
+  skip_before_action :verify_authenticity_token, only: [:webmention]
 
   def summary
     @blogs = Blog.where(published: true).order(published_at: :desc).paginate(page: params[:page], per_page: 10)
@@ -89,4 +92,35 @@ class BlogsController < ApplicationController
     end
   end
 
+  def webmention
+    @blog = Blog.find_by_slug(params[:slug])
+
+    raise ActiveRecord::RecordNotFound unless @blog
+    raise ActiveRecord::RecordNotFound unless @blog.published
+
+    permalink = url_for(@blog)
+
+    target = params[:target]
+    unless target == permalink
+      render json: { error: "Incorrect target for webmention endpoint (#{target} != #{permalink})." }
+      return
+    end
+
+    source = params[:source]
+    verification = Webmention.verify_webmention(source, target)
+    unless verification.verified?
+      render json: { error: "Webmention could not be verified." }
+      return
+    end
+
+    response = Webmention::Request.get(source)
+    parsed = Microformats.parse(response.body.to_s)
+
+    if parsed.entry.properties.to_hash.include?("like-of") and parsed.entry.like_of(:all).map(&:to_s).include? permalink
+      @blog.like!(parsed.entry.author.url, parsed.entry.author.name)
+    end
+
+    head :ok
+  end
+
 end
-- 
cgit 1.4.1