Files
adamantium/slices/micropub/actions/posts/handle.rb
2024-09-29 17:09:23 +10:00

77 lines
2.4 KiB
Ruby

module Micropub
module Actions
module Posts
class Handle < Action
before :authenticate!
include Deps[
"settings",
"commands.posts.create_entry",
post_param_parser: "param_parser.micropub_post",
delete_post: "commands.posts.delete",
undelete_post: "commands.posts.undelete",
update_post: "commands.posts.update",
add_post_syndication_source: "commands.posts.add_syndication_source"
]
def handle(req, res)
req_entity = post_param_parser.call(params: req.params.to_h)
action_type = req.params[:action]
# delete, undelete, update
if action_type
case resolve_command(req: req, action_type: action_type)
in Success[command]
if command.call(params: req.params.to_h).success?
res.status = 200
else
halt 400
end
in Failure[:not_permitted]
halt 401
end
end
# create
if req_entity && verify_scope(req: req, scope: :create)
Dry::Matcher::ResultMatcher.call(create_entry.call(req_entity: req_entity)) do |m|
m.success do |post|
post_type = (post.value!.post_type == :bookmark) ? :bookmark : :post
res.headers["Location"] = "#{settings.micropub_site_url}/#{post_type}/#{post.value!.slug}"
res.headers["HX-Redirect"] = "#{settings.micropub_site_url}/#{post_type}/#{post.value!.slug}"
res.status = 201
end
m.failure do |validation|
res.body = {error: validation.errors.to_h}.to_json
res.status = 422
end
end
end
end
private
def resolve_command(req:, action_type:)
command, permission_check = commands(action_type)
return Failure(:not_permitted) unless permission_check.call(req)
Success(command)
end
def commands(action)
case action
when "delete"
[delete_post, ->(req) { verify_scope(req: req, scope: :delete) }]
when "undelete"
[undelete_post, ->(req) { verify_scope(req: req, scope: :undelete) }]
when "update"
[update_post, ->(req) { verify_scope(req: req, scope: :update) }]
end
end
end
end
end
end