Skip to content

Commit e207805

Browse files
committed
Split RailsRoutesSerializer into RailsCollector and serializers
1 parent 0aa3e1e commit e207805

20 files changed

+352
-297
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module Datadog
4+
module AppSec
5+
module APISecurity
6+
module EndpointCollection
7+
# This module serializes Grape routes.
8+
module GrapeRouteSerializer
9+
module_function
10+
11+
def serialize(route, path_prefix: '')
12+
path = path_prefix + route.pattern.origin
13+
14+
{
15+
type: "REST",
16+
resource_name: "#{route.request_method} #{path}",
17+
operation_name: "http.request",
18+
method: route.request_method,
19+
path: path
20+
}
21+
end
22+
end
23+
end
24+
end
25+
end
26+
end

lib/datadog/appsec/api_security/endpoint_collection/grape_routes_serializer.rb

Lines changed: 0 additions & 39 deletions
This file was deleted.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'rails_route_serializer'
4+
require_relative 'grape_route_serializer'
5+
require_relative 'sinatra_route_serializer'
6+
7+
module Datadog
8+
module AppSec
9+
module APISecurity
10+
module EndpointCollection
11+
# This class works with a collection of rails routes
12+
# and produces an Enumerator that yields serialized endpoints.
13+
class RailsCollector
14+
def initialize(routes)
15+
@routes = routes
16+
end
17+
18+
def build_enum
19+
Enumerator.new do |yielder|
20+
@routes.each do |route|
21+
if route.dispatcher?
22+
yielder.yield RailsRouteSerializer.serialize(route)
23+
elsif mounted_grape_app?(route.app.rack_app)
24+
route.app.rack_app.routes.each do |grape_route|
25+
yielder.yield GrapeRouteSerializer.serialize(grape_route, path_prefix: route.path.spec.to_s)
26+
end
27+
elsif mounted_sinatra_app?(route.app.rack_app)
28+
route.app.rack_app.routes.each do |method, sinatra_routes|
29+
next if method == 'HEAD'
30+
31+
sinatra_routes.each do |sinatra_route, _, _|
32+
yielder.yield SinatraRouteSerializer.serialize(
33+
sinatra_route, method: method, path_prefix: route.path.spec.to_s
34+
)
35+
end
36+
end
37+
end
38+
end
39+
end
40+
end
41+
42+
private
43+
44+
def mounted_grape_app?(rack_app)
45+
return false unless defined?(::Grape::API)
46+
47+
rack_app.is_a?(Class) && rack_app < ::Grape::API
48+
end
49+
50+
def mounted_sinatra_app?(rack_app)
51+
return false unless defined?(::Sinatra::Base)
52+
53+
rack_app.is_a?(Class) && rack_app < ::Sinatra::Base
54+
end
55+
end
56+
end
57+
end
58+
end
59+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
module Datadog
4+
module AppSec
5+
module APISecurity
6+
module EndpointCollection
7+
# This module serializes Rails Journey Router routes.
8+
module RailsRouteSerializer
9+
FORMAT_SUFFIX = "(.:format)"
10+
11+
module_function
12+
13+
def serialize(route)
14+
method = route.verb.empty? ? "*" : route.verb
15+
path = route.path.spec.to_s.delete_suffix(FORMAT_SUFFIX)
16+
17+
{
18+
type: "REST",
19+
resource_name: "#{method} #{path}",
20+
operation_name: "http.request",
21+
method: method,
22+
path: path
23+
}
24+
end
25+
end
26+
end
27+
end
28+
end
29+
end

lib/datadog/appsec/api_security/endpoint_collection/rails_routes_serializer.rb

Lines changed: 0 additions & 70 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module Datadog
4+
module AppSec
5+
module APISecurity
6+
module EndpointCollection
7+
# This module serializes Sinatra routes.
8+
module SinatraRouteSerializer
9+
module_function
10+
11+
def serialize(route, method:, path_prefix: '')
12+
path = path_prefix + route.safe_string
13+
14+
{
15+
type: "REST",
16+
resource_name: "#{method} #{path}",
17+
operation_name: "http.request",
18+
method: method,
19+
path: path
20+
}
21+
end
22+
end
23+
end
24+
end
25+
end
26+
end

lib/datadog/appsec/api_security/endpoint_collection/sinatra_routes_serializer.rb

Lines changed: 0 additions & 43 deletions
This file was deleted.

lib/datadog/appsec/contrib/rails/patcher.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
require_relative 'gateway/request'
1111
require_relative 'patches/render_to_body_patch'
1212
require_relative 'patches/process_action_patch'
13-
require_relative '../../api_security/endpoint_collection/rails_routes_serializer'
13+
require_relative '../../api_security/endpoint_collection/rails_collector'
1414

1515
require_relative '../../../tracing/contrib/rack/middlewares'
1616

@@ -154,7 +154,7 @@ def report_routes_via_telemetry(routes)
154154

155155
GUARD_ROUTES_REPORTING_ONCE_PER_APP[::Rails.application].run do
156156
AppSec.telemetry.app_endpoints_loaded(
157-
APISecurity::EndpointCollection::RailsRoutesSerializer.new(routes).to_enum
157+
APISecurity::EndpointCollection::RailsCollector.new(routes).build_enum
158158
)
159159
end
160160
rescue => e
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Datadog
44
module EndpointCollection
55
interface _RailsRoute
66
def dispatcher?: () -> bool
7-
def verb: () -> String
7+
def verb: () -> ::String
88
def path: () -> _RailsRoutePath
99
def app: () -> _RailsRouteApp
1010
end
@@ -14,7 +14,7 @@ module Datadog
1414
end
1515

1616
interface _RailsRouteSpec
17-
def to_s: () -> String
17+
def to_s: () -> ::String
1818
end
1919

2020
interface _RailsRouteApp
@@ -27,22 +27,17 @@ module Datadog
2727
def routes: () -> untyped
2828
end
2929

30-
class RailsRoutesSerializer
31-
FORMAT_SUFFIX: String
32-
33-
@routes: Array[_RailsRoute]
34-
35-
def initialize: (Array[_RailsRoute] routes) -> void
36-
37-
def to_enum: () -> Enumerator[Core::Telemetry::Event::AppEndpointsLoaded::endpoint]
38-
39-
def serialize_route: (_RailsRoute route) -> Core::Telemetry::Event::AppEndpointsLoaded::endpoint
40-
41-
private
30+
interface _GrapeRoute
31+
def request_method: () -> String
32+
def pattern: () -> _GrapeRoutePattern
33+
end
4234

43-
def grape_app?: (_RackApp rack_app) -> bool
35+
interface _GrapeRoutePattern
36+
def origin: () -> String
37+
end
4438

45-
def sinatra_app?: (_RackApp rack_app) -> bool
39+
interface _SinatraRoute
40+
def safe_string: () -> String
4641
end
4742
end
4843
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module Datadog
2+
module AppSec
3+
module APISecurity
4+
module EndpointCollection
5+
module GrapeRouteSerializer
6+
def self?.serialize: (_GrapeRoute route, ?path_prefix: ::String) -> Core::Telemetry::Event::AppEndpointsLoaded::endpoint
7+
end
8+
end
9+
end
10+
end
11+
end

0 commit comments

Comments
 (0)