112 lines
4.5 KiB
Ruby
112 lines
4.5 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
module YiffRocks
|
||
|
class HomeController < YiffRest::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 site_domain
|
||
|
YiffRocksRoutes::DOMAIN
|
||
|
end
|
||
|
|
||
|
def site_title
|
||
|
"Yiff Rocks - URL Shortener"
|
||
|
end
|
||
|
|
||
|
def assets_path
|
||
|
YiffMediaRoutes::DOMAIN
|
||
|
end
|
||
|
|
||
|
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
|