docbrown/app/controllers/api/v1/organizations_controller.rb
Duke Greene 9a6f04bd37
api v1 endpoint for creating an organization (#19778)
* api v1 endpoint for creating an organization

* address failing specs, regenerate swagger docs

* remove old comment in destroy now that woreker call takes third argument

* refactor our services for profile images into images folder
2023-07-21 07:43:56 -04:00

123 lines
4.5 KiB
Ruby

module Api
module V1
class OrganizationsController < ApiController
include Api::OrganizationsController
before_action :find_organization, only: %i[users listings articles]
before_action :authenticate!, only: %i[create update destroy]
before_action :authorize_admin, only: %i[update]
before_action :authorize_super_admin, only: %i[create destroy]
after_action :verify_authorized, only: %i[create update destroy]
INDEX_ATTRIBUTES_FOR_SERIALIZATION = %i[
id name profile_image slug summary tag_line url
].freeze
SHOW_ATTRIBUTES_FOR_SERIALIZATION = %i[
id username name summary twitter_username github_username url
location created_at profile_image slug tech_stack tag_line story
].freeze
def index
per_page = (params[:per_page] || 30).to_i
num = [per_page, per_page_max].min
page = params[:page] || 1
organizations = Organization.select(INDEX_ATTRIBUTES_FOR_SERIALIZATION).page(page).per(num)
render json: organizations
end
def show
# This is less RESTful than having a show action that would always assume an id
# unless given e.g. a query parameter specifying a different lookup key.
# The by-username lookup is the current default behavior, this approach
# keeps it intact. Conventionally, the lookup would default to id-based if we keep both.
finder = Organization.select(SHOW_ATTRIBUTES_FOR_SERIALIZATION)
@organization = finder.find_by(id: params[:id_or_slug]) || finder.find_by(slug: params[:id_or_slug])
raise ActiveRecord::RecordNotFound unless @organization
render :show
rescue ArgumentError => e
render json: { error: e }, status: :unprocessable_entity
end
def create
organization = Organization.new params_for_create
authorize organization
if organization.save!
render json: {
id: organization.id,
name: organization.name,
profile_image: organization.profile_image_url,
slug: organization.slug,
summary: organization.summary,
tag_line: organization.tag_line,
url: organization.url
}, status: :created
else
render json: { error: organization.errors_as_sentence, status: 422 }, status: :unprocessable_entity
end
rescue ArgumentError => e
render json: { error: e }, status: :unprocessable_entity
end
def update
set_organization
@organization.assign_attributes(organization_params)
if @organization.save
render json: {
id: @organization.id,
name: @organization.name,
profile_image: @organization.profile_image_url,
slug: @organization.slug,
summary: @organization.summary,
tag_line: @organization.tag_line,
url: @organization.url
}
else
render json: { error: @organization.errors_as_sentence, status: 422 }, status: :unprocessable_entity
end
rescue ArgumentError => e
render json: { error: e }, status: :unprocessable_entity
end
def destroy
set_organization
Organizations::DeleteWorker.perform_async(@organization.id, @user.id, false)
render json: { message: "deletion scheduled for organization with ID #{@organization.id}", status: 200 }
rescue ArgumentError => e
render json: { error: e }, status: :unprocessable_entity
end
private
def authorize_admin
authorize Organization, :access?, policy_class: InternalPolicy
end
def organization_params
params.require(:organization).permit(:id, :name, :profile_image, :slug, :summary, :tag_line, :url)
end
# Accepts either an image file or a remote url for an image in the :profile_image attribute
def params_for_create
image = params.dig(:organization, :profile_image)
# If the user has given a url for the profile image, place it where it should be handled
if image.is_a? String
permitted_params = organization_params.to_h
permitted_params.delete(:profile_image)
permitted_params[:remote_profile_image_url] = Images::SafeRemoteProfileImageUrl.call(image)
end
permitted_params
end
def set_organization
@organization = Organization.find_by(id: params[:id])
not_found unless @organization
authorize @organization
end
end
end
end