Module: AtlasRb::FaradayHelper

Included in:
Admin::Collection, Admin::Community, Admin::Work, Authentication, Reset, Resource, System::User
Defined in:
lib/atlas_rb/faraday_helper.rb

Overview

HTTP transport helpers shared by every resource class.

Every Atlas request reads two environment variables:

  • ATLAS_URL — base URL of the Atlas API (e.g. https://atlas.example.edu).
  • ATLAS_TOKEN — bearer token used in the Authorization header.

Most calls also identify the acting user via a User: NUID <nuid> header, and optionally an On-Behalf-Of: NUID <nuid> header for acting-as / view-as flows. When nuid / on_behalf_of are omitted (positional arg nil, kwarg nil), the helper falls through to config's default_nuid / default_on_behalf_of callables — host applications wire those up to their request-scoped Current.* source. Caller-passed values always win over the configured defaults.

The module is mixed in via extend, so its methods become class methods on the host (e.g. AtlasRb::Work.connection({})).

Instance Method Summary collapse

Instance Method Details

#connection(params, nuid = nil, on_behalf_of: nil, idempotency_key: nil) ⇒ Faraday::Connection

Build a JSON-content Faraday connection to the Atlas API.

Examples:

Fetching a community

AtlasRb::Community.connection({}).get('/communities/abc123')

Parameters:

  • params (Hash)

    query-string / body params to attach to the request. Resource classes use this to pass things like parent_id:, work_id:, or metadata: without manually serializing.

  • nuid (String, nil) (defaults to: nil)

    optional Northeastern University ID to send in the User header. When nil, falls through to AtlasRb.config.default_nuid&.call; if that is also nil, no User: header is sent (legacy bearer-only path).

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header. When nil, falls through to AtlasRb.config.default_on_behalf_of&.call; if that is also nil, no On-Behalf-Of: header is sent. Used by acting-as / view-as flows.

  • idempotency_key (String, nil) (defaults to: nil)

    optional UUID to send in the Idempotency-Key header. Used by retry-safe create flows (currently POST /works, POST /file_sets, POST /files) to deduplicate replays against the originally-created resource. Generated by the caller — this gem does not mint keys.

Returns:

  • (Faraday::Connection)

    a connection that follows redirects and uses Faraday's default adapter.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/atlas_rb/faraday_helper.rb', line 45

def connection(params, nuid=nil, on_behalf_of: nil, idempotency_key: nil)
  nuid         ||= AtlasRb.config.default_nuid&.call
  on_behalf_of ||= AtlasRb.config.default_on_behalf_of&.call

  headers = {
    "Content-Type" => "application/json",
    "Authorization" => "Bearer #{ENV.fetch("ATLAS_TOKEN", nil)}"
  }
  headers["User"]            = "NUID #{nuid}" if nuid
  headers["On-Behalf-Of"]    = "NUID #{on_behalf_of}" if on_behalf_of
  headers["Idempotency-Key"] = idempotency_key if idempotency_key

  Faraday.new(
    url: ENV.fetch("ATLAS_URL", nil),
    params: params,
    headers: headers
  ) do |f|
    f.use AtlasRb::Middleware::RaiseOnStaleResource
    f.response :follow_redirects
    f.adapter Faraday.default_adapter
  end
end

#multipart(nuid = nil, on_behalf_of: nil, idempotency_key: nil) ⇒ Faraday::Connection

Build a multipart Faraday connection used for binary and XML uploads.

The same ATLAS_URL / ATLAS_TOKEN env vars apply. Unlike #connection, the Content-Type is set automatically by the multipart middleware, and callers pass a payload hash whose values may include Faraday::Multipart::FilePart instances. Fall-through semantics for nuid / on_behalf_of match #connection.

Examples:

Posting a binary blob

payload = {
  work_id: "w-123",
  binary: Faraday::Multipart::FilePart.new(File.open("scan.pdf"),
                                            "application/octet-stream",
                                            "scan.pdf")
}
AtlasRb::Blob.multipart.post('/files/', payload)

Parameters:

  • nuid (String, nil) (defaults to: nil)

    optional NUID for the User header.

  • on_behalf_of (String, nil) (defaults to: nil)

    optional NUID for the On-Behalf-Of header.

  • idempotency_key (String, nil) (defaults to: nil)

    optional UUID to send in the Idempotency-Key header. See #connection for semantics; the POST /files (Blob) create flow uses this transport.

Returns:

  • (Faraday::Connection)

    a multipart-aware connection.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/atlas_rb/faraday_helper.rb', line 92

def multipart(nuid=nil, on_behalf_of: nil, idempotency_key: nil)
  nuid         ||= AtlasRb.config.default_nuid&.call
  on_behalf_of ||= AtlasRb.config.default_on_behalf_of&.call

  headers = {
    "Authorization" => "Bearer #{ENV.fetch("ATLAS_TOKEN", nil)}"
  }
  headers["User"]            = "NUID #{nuid}" if nuid
  headers["On-Behalf-Of"]    = "NUID #{on_behalf_of}" if on_behalf_of
  headers["Idempotency-Key"] = idempotency_key if idempotency_key

  Faraday.new(
    url: ENV.fetch("ATLAS_URL", nil),
    headers: headers
  ) do |f|
    f.use AtlasRb::Middleware::RaiseOnStaleResource
    f.request :multipart
    f.request :url_encoded
  end
end

#system_connection(params = {}) ⇒ Faraday::Connection

Build a Faraday connection authenticated as the Atlas :system fixture for system-context calls (SSO user provisioning, etc.).

Distinct from #connection. The bearer token comes from Rails.application.credentials.atlas_system_token (NOT ENV — the source report's leak-halving argument: a .env leak shouldn't expose the system token alongside the user token). The User: header is hard-pinned to System::NUID so this path always identifies as the Atlas system principal. The configurable default_nuid / default_on_behalf_of are never consulted — there is no ambient user context on this path.

Used exclusively by classes under System.

Parameters:

  • params (Hash) (defaults to: {})

    query-string / body params.

Returns:

  • (Faraday::Connection)

    a system-authenticated connection.

Raises:

  • (RuntimeError)

    if the credential is not configured.

  • (NameError)

    if Rails is not loaded (the gem assumes a Rails host for system-path calls).



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/atlas_rb/faraday_helper.rb', line 132

def system_connection(params = {})
  token = Rails.application.credentials.atlas_system_token ||
          raise("atlas_rb: Rails.application.credentials.atlas_system_token not configured")

  headers = {
    "Content-Type"  => "application/json",
    "Authorization" => "Bearer #{token}",
    "User"          => "NUID #{AtlasRb::System::NUID}"
  }

  Faraday.new(
    url: ENV.fetch("ATLAS_URL", nil),
    params: params,
    headers: headers
  ) do |f|
    f.response :follow_redirects
    f.adapter Faraday.default_adapter
  end
end