First commit!
This commit is contained in:
75
app/controllers/api/events_controller.rb
Normal file
75
app/controllers/api/events_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::EventsController < ApplicationController
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
||||
# POST /api/:project_id/events
|
||||
def create
|
||||
project = authenticate_project!
|
||||
return head :not_found unless project
|
||||
|
||||
# Parse the incoming WAF event data
|
||||
event_data = parse_event_data(request)
|
||||
|
||||
# Create event asynchronously
|
||||
ProcessWafEventJob.perform_later(
|
||||
project_id: project.id,
|
||||
event_data: event_data,
|
||||
headers: extract_serializable_headers(request)
|
||||
)
|
||||
|
||||
# Always return 200 OK to avoid agent retries
|
||||
head :ok
|
||||
rescue DsnAuthenticationService::AuthenticationError => e
|
||||
Rails.logger.warn "DSN authentication failed: #{e.message}"
|
||||
head :unauthorized
|
||||
rescue JSON::ParserError => e
|
||||
Rails.logger.error "Invalid JSON in event data: #{e.message}"
|
||||
head :bad_request
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_project!
|
||||
DsnAuthenticationService.authenticate(request, params[:project_id])
|
||||
end
|
||||
|
||||
def parse_event_data(request)
|
||||
# Handle different content types
|
||||
content_type = request.content_type || "application/json"
|
||||
|
||||
case content_type
|
||||
when /application\/json/
|
||||
JSON.parse(request.body.read)
|
||||
when /application\/x-www-form-urlencoded/
|
||||
# Convert form data to JSON-like hash
|
||||
request.request_parameters
|
||||
else
|
||||
# Try to parse as JSON anyway
|
||||
JSON.parse(request.body.read)
|
||||
end
|
||||
rescue => e
|
||||
Rails.logger.error "Failed to parse event data: #{e.message}"
|
||||
{}
|
||||
ensure
|
||||
request.body.rewind if request.body.respond_to?(:rewind)
|
||||
end
|
||||
|
||||
def extract_serializable_headers(request)
|
||||
# Only extract the headers we need for analytics, avoiding IO objects
|
||||
important_headers = %w[
|
||||
User-Agent Content-Type Content-Length Accept
|
||||
X-Forwarded-For X-Real-IP X-Forwarded-Proto
|
||||
Authorization X-Baffle-Auth X-Sentry-Auth
|
||||
Referer Accept-Language Accept-Encoding
|
||||
]
|
||||
|
||||
headers = {}
|
||||
important_headers.each do |header|
|
||||
value = request.headers[header]
|
||||
headers[header] = value if value.present?
|
||||
end
|
||||
|
||||
headers
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user