docbrown/app/controllers/api/v0/analytics_controller.rb
Andy Zhao 3e89796d9d Add API Analytics Endpoints (#2293)
* Add API endpoints for analytics

* Remove comment and spacing

* Use proper time formatting

* Refactor and clean up some logic

* Add pro and org member traits

* Use shared examples for analytics API spec

* Add analytics authorization specs

* Remove accidental include Pundit

* Raise not_authorized for invalid requests

* Make attributes and time methods private

* Add custom UnauthorizedError

* Raise and use rescue_from to handle 4xx requests

* Enforce date parameters to follow a specific format

* Use current user to allow same origin requests

* Use custom headers and not params for token auth

* Default to current user for same origin requests

* Use correct boolean for choosing user

* Update tests to use request headers and add stricter tests
2019-04-04 10:52:45 -04:00

83 lines
2.8 KiB
Ruby

module Api
module V0
class AnalyticsController < ApiController
rescue_from ArgumentError, with: :unprocessable_entity
rescue_from UnauthorizedError, with: :not_authorized
def totals
user = get_authenticated_user!
data = if params[:organization_id]
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(organization: org).totals
else
AnalyticsService.new(user: user).totals
end
render json: data.to_json
end
def historical
raise ArgumentError, "Required 'start' parameter is missing" if params[:start].blank?
raise ArgumentError, "Date parameters 'start' or 'end' must be in the format of 'yyyy-mm-dd'" unless valid_date_params?
user = get_authenticated_user!
data = if params[:organization_id]
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(organization: org, start: params[:start], end: params[:end]).stats_grouped_by_day
else
AnalyticsService.new(user: user, start: params[:start], end: params[:end]).stats_grouped_by_day
end
render json: data.to_json
end
def past_day
user = get_authenticated_user!
data = if params[:organization_id]
org = Organization.find_by(id: params[:organization_id])
raise UnauthorizedError unless org && belongs_to_org?(user, org)
AnalyticsService.new(organization: org, start: DateTime.current - 1.day).stats_grouped_by_day
else
AnalyticsService.new(user: user, start: DateTime.current - 1.day).stats_grouped_by_day
end
render json: data.to_json
end
private
def get_authenticated_user!
user = if request.headers["HTTP_API_KEY"].blank?
current_user
else
api_secret = ApiSecret.find_by(secret: request.headers["HTTP_API_KEY"])
raise UnauthorizedError if api_secret.blank?
api_secret.user
end
raise UnauthorizedError unless user.present? && user.has_role?(:pro)
user
end
def belongs_to_org?(user, org)
user.organization_id == org.id
end
def valid_date_params?
date_regex = /\A\d{4}-\d{1,2}-\d{1,2}\Z/ # for example, 2019-03-22 or 2019-2-1
if params[:end]
(params[:start] =~ date_regex)&.zero? && (params[:end] =~ date_regex)&.zero?
else
(params[:start] =~ date_regex)&.zero?
end
end
end
end
end