Skip to content

Commit

Permalink
Support source and references metadata attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
rmouritzen-splunk committed Oct 11, 2024
1 parent 29c4744 commit bdf824a
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG elixir_image=elixir:1.17.2-alpine
ARG elixir_image=elixir:1.17.3-alpine

FROM ${elixir_image} AS builder

Expand Down
3 changes: 3 additions & 0 deletions lib/schema/cache.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,7 @@ defmodule Schema.Cache do
# Top-level path-based observables.
# Only occurs in classes, but is safe to do for objects too.
|> Utils.put_non_nil(:observables, item[:observables])
|> Utils.put_non_nil(:references, item[:references])
|> patch_constraints(item)

Map.put(acc, base_key, patched_base)
Expand Down Expand Up @@ -1366,6 +1367,8 @@ defmodule Schema.Cache do
|> copy_new(from, :object_name)
|> copy_new(from, :object_type)
|> copy_new(from, :observable)
|> copy_new(from, :source)
|> copy_new(from, :references)
end

defp copy_new(to, from, key) do
Expand Down
7 changes: 7 additions & 0 deletions lib/schema_web/templates/page/class.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
<% category_name = @data[:category_name] %>
<% extension = @data[:extension] %>
<% observables = @data[:observables] %>
<% references = @data[:references] %>

<div class="row">
<div class="col-md move-up">
Expand All @@ -45,6 +46,12 @@ limitations under the License.
<%= if observables != nil and !Enum.empty?(observables) do %>Class-specific attribute path observables
are <a href="#observables">at the bottom of this page</a>.<% end %>
</div>
<%= if references != nil and !Enum.empty?(references) do %>
<dd>
<dt>References
<%= raw Enum.map(references, fn ref -> ["<dd class=\"ml-3\">", reference_anchor(ref)] end) %>
</dd>
<% end %>
</div>
<div class="col-md-auto fixed-right mt-2">
<div class="navbar-expand-md">
Expand Down
8 changes: 8 additions & 0 deletions lib/schema_web/templates/page/object.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
show("#json-schema");
</script>

<% references = @data[:references] %>

<div class="row">
<div class="col-md move-up">
<h3 class="extensions">
Expand Down Expand Up @@ -45,6 +47,12 @@
<strong>Note:</strong> a superscript &quot;O&quot; after a caption indicates attribute is an observable,
for example: <strong>Device <sup>O</sup></strong>.
</div>
<%= if references != nil and !Enum.empty?(references) do %>
<dd>
<dt>References
<%= raw Enum.map(references, fn ref -> ["<dd class=\"ml-3\">", reference_anchor(ref)] end) %>
</dd>
<% end %>
</div>
<div class="col-md-auto fixed-right mt-2">
<div class="navbar-expand-md">
Expand Down
44 changes: 43 additions & 1 deletion lib/schema_web/views/page_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -470,11 +470,41 @@ defmodule SchemaWeb.PageView do

@spec format_desc(String.t() | atom(), map()) :: any
def format_desc(key, obj) do
source = obj[:source]
references = obj[:references]

source_html =
if source != nil do
# source can have embedded markup
["<dt>Source<dd class=\"ml-3\">", source]
else
""
end

refs_html =
if references != nil and !Enum.empty?(references) do
[
"<dt>References",
Enum.map(references, fn ref -> ["<dd class=\"ml-3\">", reference_anchor(ref)] end)
]
else
""
end

if source_html != "" or refs_html != "" do
[base_format_desc(key, obj), "<p><hr><dd>", source_html, refs_html, "</dd>"]
else
base_format_desc(key, obj)
end
end

@spec base_format_desc(String.t() | atom(), map()) :: any
defp base_format_desc(key, obj) do
description = description(obj)

case Map.get(obj, :enum) do
nil ->
description
[description]

values ->
sorted =
Expand Down Expand Up @@ -1162,4 +1192,16 @@ defmodule SchemaWeb.PageView do
Map.get(deprecated, :message)
]
end

@spec reference_anchor(map()) :: any()
def reference_anchor(reference) do
# The url and description attributes of reference are not meant to have markup
[
"<a target=\"_blank\" href=\"",
URI.encode(reference[:url]),
"\">",
reference[:description] |> Phoenix.HTML.html_escape() |> Phoenix.HTML.safe_to_string(),
"</a>"
]
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
defmodule Schema.MixProject do
use Mix.Project

@version "2.73.1"
@version "2.74.0"

def project do
build = System.get_env("GITHUB_RUN_NUMBER") || "SNAPSHOT"
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
%{
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
"castore": {:hex, :castore, "1.0.8", "dedcf20ea746694647f883590b82d9e96014057aff1d44d03ec90f36a5c0dc6e", [:mix], [], "hexpm", "0b2b66d2ee742cb1d9cb8c8be3b43c3a70ee8651f37b75a8b982e036752983f1"},
"castore": {:hex, :castore, "1.0.9", "5cc77474afadf02c7c017823f460a17daa7908e991b0cc917febc90e466a375c", [:mix], [], "hexpm", "5ea956504f1ba6f2b4eb707061d8e17870de2bee95fb59d512872c2ef06925e7"},
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"},
"credo": {:hex, :credo, "1.7.7", "771445037228f763f9b2afd612b6aa2fd8e28432a95dbbc60d8e03ce71ba4446", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8bc87496c9aaacdc3f90f01b7b0582467b69b4bd2441fe8aae3109d843cc2f2e"},
"credo": {:hex, :credo, "1.7.8", "9722ba1681e973025908d542ec3d95db5f9c549251ba5b028e251ad8c24ab8c5", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cb9e87cc64f152f3ed1c6e325e7b894dea8f5ef2e41123bd864e3cd5ceb44968"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"earmark": {:hex, :earmark, "1.4.47", "7e7596b84fe4ebeb8751e14cbaeaf4d7a0237708f2ce43630cfd9065551f94ca", [:mix], [], "hexpm", "3e96bebea2c2d95f3b346a7ff22285bc68a99fbabdad9b655aa9c6be06c698f8"},
"elixir_uuid": {:hex, :uuid_utils, "1.6.5", "bafd6ffcbec895513a7c10855df3954f29909fb5d05ee52681e30e84297b1a80", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "36aaeee10740eae4d357231f48571a2687cb541730f94f47cbd3f186dc07899c"},
Expand Down
34 changes: 29 additions & 5 deletions test/test_ocsf_schema/dictionary.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "The Attribute Dictionary defines attributes and includes references to the events and objects in which they are used.",
"name": "dictionary",
"attributes": {
"activity_id": {
"activity_id": {
"caption": "Activity ID",
"description": "The normalized identifier of the activity that triggered the event.",
"enum": {
Expand All @@ -17,12 +17,28 @@
}
},
"sibling": "activity_name",
"type": "integer_t"
"type": "integer_t",
"references": [
{
"url": "https://example.com/activity_id",
"description": "Activity ID at example.com <dictionary attribute>"
}
]
},
"activity_name": {
"caption": "Activity",
"description": "The event activity name, as defined by the activity_id.",
"type": "string_t"
"type": "string_t",
"references": [
{
"url": "https://example.com/activity_name?s=1",
"description": "Activity Name (1) at example.com <dictionary attribute>"
},
{
"url": "https://example.com/activity_name?s=2",
"description": "Activity Name (2) at example.com <dictionary attribute>"
}
]
},
"alpha": {
"caption": "Alpha",
Expand All @@ -32,7 +48,8 @@
"beta": {
"caption": "Beta",
"description": "The beta. Whatever that is. This is for testing. Sheesh.",
"type": "string_t"
"type": "string_t",
"source": "Beta is from atomic decay (dictionary attribute)"
},
"category_name": {
"caption": "Category",
Expand Down Expand Up @@ -85,7 +102,14 @@
"device": {
"caption": "Device",
"description": "An addressable device, computer system or host.",
"type": "device"
"type": "device",
"source": "Devices are sourced from suppliers.",
"references": [
{
"url": "https://example.com/device",
"description": "Device at example.com <dictionary attribute>"
}
]
},
"entity_thing": {
"caption": "Entity Thing",
Expand Down
15 changes: 14 additions & 1 deletion test/test_ocsf_schema/events/alpha.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,27 @@
"extends": "ghost",
"uid": 1,
"profiles": [],
"references": [
{
"url": "https://example.com/alpha",
"description": "Alpha at example.com <class>"
}
],
"attributes": {
"alpha": {
"requirement": "required",
"observable": 100
},
"delta": {
"requirement": "optional",
"observable": 101
"observable": 101,
"source": "This is from <i>physics!</i> (class attribute)",
"references": [
{
"url": "https://example.com/delta",
"description": "Delta at example.com <class attribute>"
}
]
},
"ob_by_dict_type_1": {
"requirement": "optional",
Expand Down
4 changes: 4 additions & 0 deletions test/test_ocsf_schema/events/beta.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
"extends": "ghost",
"uid": 2,
"profiles": [],
"references": [
{"url": "https://example.com/beta?n=1", "description": "Beta (1) on example.com <class>"},
{"url": "https://example.com/beta?n=2", "description": "Beta (2) on example.com <class>"}
],
"attributes": {
"beta": {
"requirement": "required",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"description": "Patch extends of the Alpha example event class.",
"extends": "alpha",
"profiles": [],
"references": [
{
"url": "https://example.com/alpha?patched=1",
"description": "Alpha (patch) at example.com <patched class>"
}
],
"attributes": {
"alpha_extra": {
"requirement": "required"
Expand Down
14 changes: 13 additions & 1 deletion test/test_ocsf_schema/objects/device.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"extends": "endpoint",
"name": "device",
"observable": 200,
"references": [
{
"url": "https://example.com/device",
"description": "Device at example.com <object>"
}
],
"attributes": {
"desc": {
"caption": "Description",
Expand All @@ -12,7 +18,13 @@
},
"hostname": {
"description": "The device hostname.",
"requirement": "recommended"
"requirement": "recommended",
"references": [
{
"url": "https://example.com/device_hostname",
"description": "Device hostname at example.com <object attribute>"
}
]
},
"ip": {
"description": "The device IP address, in either IPv4 or IPv6 format.",
Expand Down
8 changes: 7 additions & 1 deletion test/test_ocsf_schema/profiles/host.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
},
"attributes": {
"device": {
"requirement": "recommended"
"requirement": "recommended",
"references": [
{
"url": "https://example.com/device?profile=host",
"description": "Device from host profile on example.com <profile>"
}
]
}
}
}

0 comments on commit bdf824a

Please sign in to comment.