64 lines
2.7 KiB
Ruby
64 lines
2.7 KiB
Ruby
|
|
# frozen_string_literal: true
|
||
|
|
|
||
|
|
module Api
|
||
|
|
# Version the API explicitly in the URL to allow different versions with breaking changes to co-exist if necessary.
|
||
|
|
# The roll over to the next number should happen when code written against the old version will not work
|
||
|
|
# with the new version.
|
||
|
|
module V2
|
||
|
|
class BaseController < ApplicationController
|
||
|
|
skip_before_action :verify_authenticity_token
|
||
|
|
before_action :restrict_access
|
||
|
|
|
||
|
|
# Prevent unhandled errors from returning the normal HTML page
|
||
|
|
rescue_from StandardError, with: :render_standard_error_response
|
||
|
|
|
||
|
|
private
|
||
|
|
|
||
|
|
# Look for a token in the Authorization header only and check that the token isn't currently banned
|
||
|
|
def restrict_access
|
||
|
|
authenticate_or_request_with_http_token do |token, _|
|
||
|
|
ApiKey.exists?(access_token: token) && !ApiKey.find_by(access_token: token).banned?
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
# Top-level error handling: returns a 403 forbidden if a valid archivist isn't supplied and a 400
|
||
|
|
# if no works are supplied. If there is neither a valid archivist nor valid works, a 400 is returned
|
||
|
|
# with both errors as a message
|
||
|
|
def batch_errors(archivist, import_items)
|
||
|
|
errors = []
|
||
|
|
status = ""
|
||
|
|
|
||
|
|
if archivist&.is_archivist?
|
||
|
|
if import_items.nil? || import_items.empty?
|
||
|
|
status = :empty_request
|
||
|
|
errors << "No items to import were provided."
|
||
|
|
elsif import_items.size >= ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST
|
||
|
|
status = :too_many_request
|
||
|
|
errors << "This request contains too many items to import. A maximum of #{ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST} " \
|
||
|
|
"items can be imported at one time by an archivist."
|
||
|
|
end
|
||
|
|
else
|
||
|
|
status = :forbidden
|
||
|
|
errors << "The \"archivist\" field must specify the name of an Archive user with archivist privileges."
|
||
|
|
end
|
||
|
|
|
||
|
|
status = :ok if errors.empty?
|
||
|
|
[status, errors]
|
||
|
|
end
|
||
|
|
|
||
|
|
# Return a standard HTTP + Json envelope for all API responses
|
||
|
|
def render_api_response(status, messages, response = {})
|
||
|
|
# It's a bad request unless it's ok or an authorisation error
|
||
|
|
http_status = %i[forbidden ok].include?(status) ? status : :bad_request
|
||
|
|
render status: http_status, json: { status: status, messages: messages }.merge(response)
|
||
|
|
end
|
||
|
|
|
||
|
|
# Return a standard HTTP + Json envelope for errors that drop through other handling
|
||
|
|
def render_standard_error_response(exception)
|
||
|
|
message = "An error occurred in the Archive code: #{exception.message}"
|
||
|
|
render status: :internal_server_error, json: { status: :internal_server_error, messages: [message] }
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|