Hue.Client (Hue v0.2.0)

Copy Markdown View Source

A configured connection to one bridge.

Holds a Req.Request, which is deliberate: consumers inject plug: for test stubs and set their own timeout and retry policy, so this library invents no configuration system of its own.

Never set :connect_options on the request

The pinned TLS options live at req.options[:connect_options][:transport_opts], and Req.merge/2 replaces :connect_options wholesale rather than merging into it. So

Req.request(client.req, connect_options: [timeout: 1_000])

discards :transport_opts along with it and connects unverified, silently. Hue.new/2 guards its own construction and cannot guard this. Pass :connect_options to Hue.new/2 instead, where they are merged and a :transport_opts among them is refused. Nothing in this library may forward a caller's :connect_options onto a request either.

For the same reason a caller cannot bring their own Finch pool: finch: [name: MyFinch] raises cannot set both :finch and :connect_options, because the pinned options are what the pool is keyed on and built from.

What the redaction covers

Inspect prints the application key as [REDACTED], which keeps it out of ordinary inspect output — Logger, IEx, and the formatting of exceptions that carry a client. That is the whole of the guarantee. inspect(client, structs: false) prints the raw struct, and an erl_crash.dump writes heap terms with no involvement from Inspect at all.

The escape most likely to be reached in practice is neither of those. The key travels as a hue-application-key request header, and Finch puts the whole request — headers included — in the metadata of [:finch, :send, :start], [:finch, :send, :stop], [:finch, :recv, :start], and [:finch, :recv, :stop]. Attaching a handler that logs Finch telemetry is a routine thing to do, and such a handler logs the key. This library's own [:hue, :request] events carry only :method, :path, and :result, but the Finch events underneath them are not ours to redact. Filter the header in the handler.

Summary

Types

t()

@type t() :: %Hue.Client{
  application_key: String.t() | nil,
  base_url: String.t(),
  bridge_id: String.t() | nil,
  fingerprint: String.t() | nil,
  req: Req.Request.t()
}