Websites/app/controllers/yiff_rocks/home_controller.rb
2024-07-14 13:49:24 -05:00

100 lines
4.3 KiB
Ruby

# frozen_string_literal: true
module YiffRocks
class HomeController < ApplicationController
include ::ApplicationController::ReadonlyMethods
before_action :handle_ratelimit, only: %i[create update destroy]
before_action :validate_api_key_required, only: %i[create update destroy]
before_action :validate_shortener_access, only: %i[create update destroy]
before_action :load_shorturl, only: %i[update destroy]
before_action :ensure_edit_access, only: %i[update destroy]
before_action -> { track_usage("shortener") }, except: %i[index]
wrap_parameters format: :json, name: "short_url"
def index
end
def show
code = params[:code]
preview = code.ends_with?("+")
code = code[..-2] if preview
if params[:format] == "json"
return if handle_ratelimit && performed?
return if validate_api_key_required && performed?
return if validate_shortener_access && performed?
@short = ShortUrl.find_by(code: code)
return render_error(YiffyAPIErrorCodes::SHORTENER_NOT_FOUND, error: "A short url with that code was not found.") if @short.nil?
return render(json: {
success: true,
data: @short,
})
end
@short = ShortUrl.find_by(code: code)
return render(plain: "Unknown short url code.", status: 404) if @short.nil?
return render("preview") if preview
redirect_to(@short.url, allow_other_host: true)
end
def create
@short_url = ShortUrl.create(creator_ua: request.headers["User-Agent"], **short_url_params(:create))
handle_errors
return if performed?
render(json: @short_url)
end
def update
@short_url.update(short_url_params(:update))
handle_errors
return if performed?
return render_error(YiffyAPIErrorCodes::SHORTENER_NO_CHANGES, message: "No changes were detected.") unless @short_url.saved_change_to_url? || @short_url.saved_change_to_creator_name?
render(json: @short_url)
end
def destroy
@short_url.destroy
end
private
def short_url_params(context = nil)
permitted_params = %i[url credit creator_name]
permitted_params += %i[code] if context == :create
params.require(:short_url).permit(permitted_params)
end
def handle_errors
if @short_url.errors.any?
@short_url.errors.full_messages.each do |error|
return render_error(YiffyAPIErrorCodes::SHORTENER_CODE_TOO_LONG, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Code is too long/
return render_error(YiffyAPIErrorCodes::SHORTENER_INVALID_CODE, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Code is invalid/
return render_error(YiffyAPIErrorCodes::SHORTENER_INVALID_URL, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Url is invalid/
return render_error(YiffyAPIErrorCodes::SHORTENER_URL_TOO_LONG, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Url is too long/
return render_error(YiffyAPIErrorCodes::SHORTENER_CREDIT_TOO_LONG, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Creator name is too long/
return render_error(YiffyAPIErrorCodes::SHORTENER_CODE_IN_USE, message: error, errors: @short_url.errors.full_messages) if error.to_s =~ /Code has already been taken/
@short_url.save! # Make further failed validations raise
end
end
end
def load_shorturl
@short_url = ShortUrl.find_by(code: params[:code])
render_error(YiffyAPIErrorCodes::SHORTENER_NOT_FOUND, message: "A short url with that code was not found.") if @short_url.nil?
end
def ensure_edit_access
management_code = params.fetch(:short_url, {}).permit(:managementCode)[:managementCode]
params[:short_url].delete(:managementCode) if management_code.present?
if CurrentUser.user.id != @short_url.creator_id
return render_error(YiffyAPIErrorCodes::SHORTENER_NO_MANAGEMENT_CODE, message: "That short url cannot be edited by you.") if @short_url.management_code.blank? || management_code.blank?
render_error(YiffyAPIErrorCodes::SHORTENER_MANAGEMENT_CODE_MISMATCH, message: "That management code does not match this short url.") if management_code != @short_url.management_code
end
end
end
end