157 lines
5.9 KiB
Ruby
157 lines
5.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module YiffRest
|
|
class ApikeysController < ApplicationController
|
|
include ::ApplicationController::ReadonlyMethods
|
|
before_action :validate_discord, except: %i[logout]
|
|
before_action :handle_ratelimit, except: %i[index logout]
|
|
before_action :prepare_user, except: %i[logout]
|
|
before_action :load_apikey, except: %i[index new create logout]
|
|
before_action :manager_only, only: %i[disable]
|
|
before_action :admin_only, only: %i[edit]
|
|
before_action :check_can_create_apikeys, only: %i[new create]
|
|
before_action -> { check_apikey_access(:can_edit?) }, only: %i[update]
|
|
before_action -> { check_apikey_access(:can_delete?) }, only: %i[destroy]
|
|
before_action -> { check_apikey_access(:can_disable?) }, only: %i[disable enable]
|
|
before_action -> { check_apikey_access(:can_deactivate?) }, only: %i[deactivate reactivate]
|
|
before_action -> { check_apikey_access(:can_regenerate?) }, only: %i[regenerate]
|
|
|
|
protect_from_forgery with: :exception
|
|
def index
|
|
@apikeys = APIKey.all
|
|
@apikeys = @apikeys.where(owner_id: CurrentUser.id) unless CurrentUser.is_manager?
|
|
@apikeys = @apikeys.search(search_params)
|
|
end
|
|
|
|
def new
|
|
@apikey = APIKey.new(owner_id: CurrentUser.id)
|
|
end
|
|
|
|
def edit
|
|
end
|
|
|
|
def create
|
|
allowed_params = apikey_params
|
|
allowed_params[:owner_id] ||= CurrentUser.id
|
|
apiuser = APIUser.find_by(id: allowed_params[:owner_id])
|
|
APIUser.create!(id: allowed_params[:owner_id], name: "User#{allowed_params[:owner_id]}") if apiuser.nil?
|
|
@apikey = APIKey.create(allowed_params)
|
|
if @apikey.errors.any?
|
|
redirect_back(fallback_location: new_yiff_rest_apikey_path, notice: @apikey.errors.full_messages.join("; "))
|
|
else
|
|
redirect_to(yiff_rest_apikeys_path, notice: "API Key created. You can view the documentation via the link in the top bar. Click \"View\" to see your apikey.")
|
|
end
|
|
end
|
|
|
|
def update
|
|
@apikey.update(apikey_params)
|
|
return redirect_back(fallback_location: edit_yiff_rest_apikey_path(@apikey), notice: @apikey.errors.full_messages.join("; ")) if @apikey.errors.any?
|
|
redirect_to(yiff_rest_apikeys_path, notice: "API Key Updated.")
|
|
end
|
|
|
|
def destroy
|
|
@apikey.destroy
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path)
|
|
end
|
|
|
|
def disable
|
|
@apikey.update(disabled: true, disabled_reason: disable_params[:disabled_reason])
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path, notice: @apikey.errors.any? ? @apikey.errors.full_messages : "API Key disabled.")
|
|
end
|
|
|
|
def enable
|
|
@apikey.update(disabled: false, disabled_reason: nil)
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path, notice: @apikey.errors.any? ? @apikey.errors.full_messages : "API Key enabled.")
|
|
end
|
|
|
|
def deactivate
|
|
@apikey.update(active: false)
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path, notice: @apikey.errors.any? ? @apikey.errors.full_messages : "API Key deactivated.")
|
|
end
|
|
|
|
def reactivate
|
|
@apikey.update(active: true)
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path, notice: @apikey.errors.any? ? @apikey.errors.full_messages : "API Key reactivated.")
|
|
end
|
|
|
|
def regenerate
|
|
@apikey.regenerate!
|
|
redirect_back(fallback_location: yiff_rest_apikeys_path, notice: @apikey.errors.any? ? @apikey.errors.full_messages : "API Key regenerated.")
|
|
end
|
|
|
|
def logout
|
|
session.delete("discord_user")
|
|
CurrentUser.user = nil
|
|
redirect_to(yiff_rest_root_path, notice: "You have been logged out.")
|
|
end
|
|
|
|
private
|
|
|
|
def site_domain
|
|
YiffRestRoutes::DOMAIN
|
|
end
|
|
|
|
def site_title
|
|
"YiffyAPI - API Keys"
|
|
end
|
|
|
|
def assets_path
|
|
YiffMediaRoutes::DOMAIN
|
|
end
|
|
|
|
def validate_discord
|
|
redirect_to(Websites.config.yiffyapi_discord_redirect("apikey"), allow_other_host: true) if session[:discord_user].blank?
|
|
end
|
|
|
|
def apikey_params
|
|
permitted_params = %i[application_name usage]
|
|
permitted_params += %i[super unlimited bulk_limit limit_long limit_short window_long window_short flags_images flags_thumbs flags_shortener flags_images_bulk owner_id] if CurrentUser.is_admin?
|
|
params.require(:api_key).permit(permitted_params)
|
|
end
|
|
|
|
def disable_params
|
|
params.require(:api_key).permit(:disabled_reason)
|
|
end
|
|
|
|
def search_params
|
|
permitted_params = %i[]
|
|
permitted_params += %i[owner_id application_name usage active disabled disabled_reason] if CurrentUser.is_manager?
|
|
permit_search_params(permitted_params)
|
|
end
|
|
|
|
def handle_ratelimit
|
|
info, body, rlheaders = RateLimiter.process(request, ignore_auth: true)
|
|
headers.merge!(rlheaders)
|
|
return if info.nil?
|
|
# noinspection RubyCaseWithoutElseBlockInspection
|
|
case info
|
|
when :RATELIMIT_SHORT
|
|
render_error(YiffyAPIErrorCodes::RATELIMIT_ROUTE, error: "Request Limit Exceeded", info: body)
|
|
when :RATELIMIT_LONG
|
|
render_error(YiffyAPIErrorCodes::RATELIMIT_GLOBAL, error: "Request Limit Exceeded", info: body)
|
|
end
|
|
end
|
|
|
|
def prepare_user
|
|
name = session.dig("discord_user", "global_name") || "#{session.dig('discord_user', 'username')}#{@session.dig('discord_user', 'discriminator')}"
|
|
CurrentUser.user = APIUser.find_or_create_by(id: session.dig("discord_user", "id"))
|
|
CurrentUser.update!(name: name, discord_data: session["discord_user"])
|
|
CurrentUser.update_avatar(session.dig("discord_user", "avatar"))
|
|
end
|
|
|
|
def load_apikey
|
|
@apikey = APIKey.find(params[:id])
|
|
end
|
|
|
|
def check_apikey_access(method)
|
|
return if @apikey.nil?
|
|
access_denied(message: "You don't have access to that.") unless @apikey.send(method, CurrentUser)
|
|
end
|
|
|
|
def check_can_create_apikeys
|
|
return if CurrentUser.is_admin?
|
|
access_denied(message: "You already have the maximum amount of apikeys.") unless CurrentUser.can_create_apikey?
|
|
end
|
|
end
|
|
end
|