Skip to content

Commit

Permalink
Merge 8d690a9 into 1cbb3f9
Browse files Browse the repository at this point in the history
  • Loading branch information
jhass committed Jan 21, 2020
2 parents 1cbb3f9 + 8d690a9 commit b665df2
Show file tree
Hide file tree
Showing 130 changed files with 9,701 additions and 232 deletions.
15 changes: 0 additions & 15 deletions app/controllers/api/v0/base_controller.rb

This file was deleted.

79 changes: 79 additions & 0 deletions app/controllers/api/v1/aspects_controller.rb
@@ -0,0 +1,79 @@
# frozen_string_literal: true

module Api
module V1
class AspectsController < Api::V1::BaseController
before_action except: %i[create update destroy] do
require_access_token %w[contacts:read]
end

before_action only: %i[create update destroy] do
require_access_token %w[contacts:modify]
end

def index
aspects_query = current_user.aspects
aspects_page = index_pager(aspects_query).response
aspects_page[:data] = aspects_page[:data].map {|a| aspect_as_json(a, false) }
render_paged_api_response aspects_page
end

def show
aspect = current_user.aspects.where(id: params[:id]).first
if aspect
render json: aspect_as_json(aspect, true)
else
render json: I18n.t("api.endpoint_errors.aspects.not_found"), status: :not_found
end
end

def create
params.require(%i[name])
aspect = current_user.aspects.build(name: params[:name])
if aspect&.save
render json: aspect_as_json(aspect, true)
else
render json: I18n.t("api.endpoint_errors.aspects.cant_create"), status: :unprocessable_entity
end
rescue ActionController::ParameterMissing
render json: I18n.t("api.endpoint_errors.aspects.cant_create"), status: :unprocessable_entity
end

def update
aspect = current_user.aspects.where(id: params[:id]).first

if !aspect
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :not_found
elsif aspect.update!(aspect_params(true))
render json: aspect_as_json(aspect, true)
else
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :unprocessable_entity
end
rescue ActionController::ParameterMissing, ActiveRecord::RecordInvalid
render json: I18n.t("api.endpoint_errors.aspects.cant_update"), status: :unprocessable_entity
end

def destroy
aspect = current_user.aspects.where(id: params[:id]).first
if aspect&.destroy
head :no_content
else
render json: I18n.t("api.endpoint_errors.aspects.cant_delete"), status: :unprocessable_entity
end
end

private

def aspect_params(allow_order=false)
parameters = params.permit(:name)
parameters[:order_id] = params[:order] if params.has_key?(:order) && allow_order

parameters
end

def aspect_as_json(aspect, as_full)
AspectPresenter.new(aspect).as_api_json(as_full)
end
end
end
end
74 changes: 74 additions & 0 deletions app/controllers/api/v1/base_controller.rb
@@ -0,0 +1,74 @@
# frozen_string_literal: true

module Api
module V1
class BaseController < ApplicationController
include Api::OpenidConnect::ProtectedResourceEndpoint

protect_from_forgery unless: -> { request.format.json? }

protected

rescue_from Exception do |e|
logger.error e.message
logger.error e.backtrace.join("\n")
render json: error_body(500, e.message), status: :internal_server_error
end

rescue_from Rack::OAuth2::Server::Resource::Forbidden do |e|
logger.error e.message
render json: error_body(403, e.message), status: :forbidden
end

rescue_from ActiveRecord::RecordNotFound do |e|
logger.error e.message
message = I18n.t("api.error.not_found")
render json: error_body(404, message), status: :not_found
end

rescue_from ActiveRecord::RecordInvalid do |e|
logger.error e.message
render json: error_body(422, e.to_s), status: :unprocessable_entity
end

rescue_from ActionController::ParameterMissing do |e|
logger.error e.message
message = I18n.t("api.error.wrong_parameters") + ": " + e.message
render json: error_body(422, message), status: :unprocessable_entity
end

def error_body(code, message)
{code: code, message: message}
end

def current_user
current_token ? current_token.authorization.user : nil
end

def index_pager(query)
Api::Paging::RestPaginatorBuilder.new(query, request).index_pager(params)
end

def render_paged_api_response(page)
link_header = []
link_header << %(<#{page[:links][:next]}>; rel="next") if page[:links][:next]
link_header << %(<#{page[:links][:previous]}>; rel="previous") if page[:links][:previous]
response.set_header("Link", link_header.join(", ")) if link_header.present?

render json: page[:data]
end

def time_pager(query)
Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params)
end

def private_read?
access_token? %w[private:read]
end

def private_modify?
access_token? %w[private:modify]
end
end
end
end
118 changes: 118 additions & 0 deletions app/controllers/api/v1/comments_controller.rb
@@ -0,0 +1,118 @@
# frozen_string_literal: true

module Api
module V1
class CommentsController < Api::V1::BaseController
before_action except: %i[create destroy] do
require_access_token %w[public:read]
end

before_action only: %i[create destroy] do
require_access_token %w[interactions public:modify]
end

rescue_from ActiveRecord::RecordNotFound do
render json: I18n.t("api.endpoint_errors.posts.post_not_found"), status: :not_found
end

rescue_from ActiveRecord::RecordInvalid do
render json: I18n.t("api.endpoint_errors.comments.not_allowed"), status: :unprocessable_entity
end

def create
find_post
comment = comment_service.create(params.require(:post_id), params.require(:body))
rescue ActiveRecord::RecordNotFound
render json: I18n.t("api.endpoint_errors.posts.post_not_found"), status: :not_found
else
render json: comment_as_json(comment), status: :created
end

def index
find_post
comments_query = comment_service.find_for_post(params.require(:post_id))
params[:after] = Time.utc(1900).iso8601 if params.permit(:before, :after).empty?

comments_page = time_pager(comments_query).response
comments_page[:data] = comments_page[:data].map {|x| comment_as_json(x) }
render_paged_api_response comments_page
end

def destroy
find_post
if comment_and_post_validate(params.require(:post_id), params[:id])
comment_service.destroy!(params[:id])
head :no_content
end
rescue ActiveRecord::RecordInvalid
render json: I18n.t("api.endpoint_errors.comments.no_delete"), status: :forbidden
end

def report
find_post
post_guid = params.require(:post_id)
comment_guid = params.require(:comment_id)
return unless comment_and_post_validate(post_guid, comment_guid)

reason = params.require(:reason)
comment = comment_service.find!(comment_guid)
report = current_user.reports.new(
item_id: comment.id,
item_type: "Comment",
text: reason
)
if report.save
head :no_content
else
render json: I18n.t("api.endpoint_errors.comments.duplicate_report"), status: :conflict
end
end

private

def comment_and_post_validate(post_guid, comment_guid)
if !comment_exists(comment_guid)
render json: I18n.t("api.endpoint_errors.comments.not_found"), status: :not_found
false
elsif !comment_is_for_post(post_guid, comment_guid)
render json: I18n.t("api.endpoint_errors.comments.not_found"), status: :not_found
false
else
true
end
end

def comment_is_for_post(post_guid, comment_guid)
comments = comment_service.find_for_post(post_guid)
comment = comments.find {|comment| comment[:guid] == comment_guid }
comment ? true : false
end

def comment_exists(comment_guid)
comment = comment_service.find!(comment_guid)
comment ? true : false
rescue ActiveRecord::RecordNotFound
false
end

def comment_service
@comment_service ||= CommentService.new(current_user)
end

def post_service
@post_service ||= PostService.new(current_user)
end

def comment_as_json(comment)
CommentPresenter.new(comment).as_api_response
end

def find_post
post = post_service.find!(params[:post_id])
return post if post.public? || private_read?

raise ActiveRecord::RecordNotFound
end
end
end
end
62 changes: 62 additions & 0 deletions app/controllers/api/v1/contacts_controller.rb
@@ -0,0 +1,62 @@
# frozen_string_literal: true

require "api/paging/index_paginator"

module Api
module V1
class ContactsController < Api::V1::BaseController
before_action except: %i[create destroy] do
require_access_token %w[contacts:read]
end

before_action only: %i[create destroy] do
require_access_token %w[contacts:modify]
end

rescue_from ActiveRecord::RecordNotFound do
render json: I18n.t("api.endpoint_errors.aspects.not_found"), status: :not_found
end

def index
contacts_query = aspects_membership_service.contacts_in_aspect(params.require(:aspect_id))
contacts_page = index_pager(contacts_query).response
contacts_page[:data] = contacts_page[:data].map do |c|
ContactPresenter.new(c, current_user).as_api_json_without_contact
end
render_paged_api_response contacts_page
end

def create
aspect_id = params.require(:aspect_id)
person = Person.find_by(guid: params.require(:person_guid))
aspect_membership = aspects_membership_service.create(aspect_id, person.id) if person.present?

if aspect_membership
head :no_content
else
render json: I18n.t("api.endpoint_errors.contacts.cant_create"), status: :unprocessable_entity
end
rescue ActiveRecord::RecordNotUnique
render json: I18n.t("api.endpoint_errors.contacts.cant_create"), status: :unprocessable_entity
end

def destroy
aspect_id = params.require(:aspect_id)
person = Person.find_by(guid: params[:id])
result = aspects_membership_service.destroy_by_ids(aspect_id, person.id) if person.present?

if result && result[:success]
head :no_content
else
render json: I18n.t("api.endpoint_errors.contacts.cant_delete"), status: :unprocessable_entity
end
rescue ActiveRecord::RecordNotFound
render json: I18n.t("api.endpoint_errors.contacts.not_found"), status: :not_found
end

def aspects_membership_service
AspectsMembershipService.new(current_user)
end
end
end
end

0 comments on commit b665df2

Please sign in to comment.