atlas_rb 1.8.6 → 1.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.version +1 -1
- data/CHANGELOG.md +36 -0
- data/Gemfile.lock +1 -1
- data/lib/atlas_rb/resource.rb +32 -0
- data/lib/atlas_rb/system/token.rb +59 -0
- data/lib/atlas_rb.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 790f093dac74f6f06ec40f1be385888d0acb3123901f2056b39996ab8050e1ef
|
|
4
|
+
data.tar.gz: 5137778cc466b711c9862ab661d849b795142429b3507cc3e4a2549c8ccf7813
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f3244e997c783521e0a86b49cdfe2cd471ad744cca7399d4497d2a250102bb3c51f3f92c6d54b17d6137171baa355fe9f4ff42464565641efbb7fc7e83e489c3
|
|
7
|
+
data.tar.gz: 676ec01145ceb6773fa6ed13eda23a40949ef1ccaf7e984576fd00988169bdd19ae1710dc7f06f72b48f48165224aa57b585e1d9bdcd74c64038f58cb96f4b05
|
data/.version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.8.
|
|
1
|
+
1.8.8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.8.8
|
|
4
|
+
|
|
5
|
+
### Added — type-agnostic current MODS (`Resource.mods`)
|
|
6
|
+
|
|
7
|
+
New polymorphic wrapper `AtlasRb::Resource.mods(id, kind = nil, …)` for Atlas's
|
|
8
|
+
`GET /resources/:id/mods` — fetch the current descriptive MODS of any Modsable
|
|
9
|
+
resource (Work / Collection / Community) by NOID, without knowing its type.
|
|
10
|
+
Returns the raw response body, mirroring the typed `Work.mods` / `Collection.mods`
|
|
11
|
+
/ `Community.mods`; output is byte-identical to the typed routes. `kind` omitted
|
|
12
|
+
yields the JSON projection (server default); pass `"xml"` for MODS XML.
|
|
13
|
+
|
|
14
|
+
Collapses the `children → find_many (for klass) → dispatch-by-klass` two-step a
|
|
15
|
+
bulk MODS exporter needed just to pick the typed MODS URL down to one call per
|
|
16
|
+
member. `404` (unknown id / non-Modsable / no MODS) comes back as an empty body.
|
|
17
|
+
|
|
18
|
+
## 1.8.7
|
|
19
|
+
|
|
20
|
+
### Added — personal-access token lifecycle (`System::Token.mint` / `.revoke`)
|
|
21
|
+
|
|
22
|
+
New system-context binding for the `POST /nuid` / `DELETE /nuid` endpoints so a
|
|
23
|
+
host app can mint and revoke a user's personal-access JWT (`ATLAS_JWT`, BYO-JWT
|
|
24
|
+
mode). Both are :system-gated on Atlas ("minting for an arbitrary NUID is
|
|
25
|
+
'become anyone'"), so they authenticate via `FaradayHelper#system_connection`
|
|
26
|
+
(hard-pinned system token + `User: NUID` header) — never the ambient-user
|
|
27
|
+
relay-signing path — mirroring `System::User`.
|
|
28
|
+
|
|
29
|
+
- `AtlasRb::System::Token.mint(nuid:)` → the JWT (`String`), or `nil` when the
|
|
30
|
+
NUID has no Atlas User row (404). The token is full-privilege for that user,
|
|
31
|
+
1-week TTL, single-jti.
|
|
32
|
+
- `AtlasRb::System::Token.revoke(nuid:)` → `true` on success (204), `false` on
|
|
33
|
+
404. Rotates the user's jti (single-jti model → all outstanding tokens die at
|
|
34
|
+
once). "Regenerate" is `revoke` followed by a fresh `mint`.
|
|
35
|
+
|
|
36
|
+
Unblocks Cerberus's "My DRS → Programmatic access" section (generate / regenerate
|
|
37
|
+
/ revoke), gated to the `northeastern:drs:repository:api` Grouper group.
|
|
38
|
+
|
|
3
39
|
## 1.8.5
|
|
4
40
|
|
|
5
41
|
### Fixed — `find` returns a tombstone (`410`) instead of raising
|
data/Gemfile.lock
CHANGED
data/lib/atlas_rb/resource.rb
CHANGED
|
@@ -170,6 +170,38 @@ module AtlasRb
|
|
|
170
170
|
))
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
+
# Fetch the CURRENT MODS of any Modsable resource by NOID — the polymorphic
|
|
174
|
+
# sibling of {Work.mods} / {Collection.mods} / {Community.mods}. Wraps
|
|
175
|
+
# `GET /resources/<id>/mods[.kind]` and returns the **raw response body**
|
|
176
|
+
# (not parsed), mirroring the typed wrappers. Lets a caller holding only a
|
|
177
|
+
# NOID (no type) fetch descriptive MODS in one call, instead of resolving
|
|
178
|
+
# the klass first to pick the typed route — e.g. a bulk Collection/Set MODS
|
|
179
|
+
# export that has bare member NOIDs from {Collection.children}.
|
|
180
|
+
#
|
|
181
|
+
# @param id [String] an Atlas resource ID (NOID).
|
|
182
|
+
# @param kind [String, nil] response-format extension: omit for the JSON
|
|
183
|
+
# projection (the server default), or pass `"xml"` for MODS XML (`"json"`
|
|
184
|
+
# / `"html"` also accepted). Output is byte-identical to the typed route
|
|
185
|
+
# for the resolved type.
|
|
186
|
+
# @param nuid [String, nil] optional acting user's NUID. On the relay-signing
|
|
187
|
+
# path it is signed into the assertion `sub`; on the BYO-JWT (`ATLAS_JWT`)
|
|
188
|
+
# path it is ignored (identity lives in the token).
|
|
189
|
+
# @param on_behalf_of [String, nil] optional NUID for the `On-Behalf-Of`
|
|
190
|
+
# header. Falls through to {AtlasRb.config}.default_on_behalf_of when omitted.
|
|
191
|
+
# @return [String, nil] the raw MODS body (XML or JSON per `kind`). The
|
|
192
|
+
# server returns `404` (empty body) for an unknown id, a non-Modsable
|
|
193
|
+
# resource, or one with no MODS.
|
|
194
|
+
#
|
|
195
|
+
# @example Bulk-export a Set's members' MODS without klass dispatch
|
|
196
|
+
# AtlasRb::Collection.children(set_id).each do |noid|
|
|
197
|
+
# xml = AtlasRb::Resource.mods(noid, "xml")
|
|
198
|
+
# end
|
|
199
|
+
def self.mods(id, kind = nil, nuid: nil, on_behalf_of: nil)
|
|
200
|
+
connection({}, nuid, on_behalf_of: on_behalf_of).get(
|
|
201
|
+
'/resources/' + id + '/mods' + (kind.present? ? ".#{kind}" : '')
|
|
202
|
+
)&.body
|
|
203
|
+
end
|
|
204
|
+
|
|
173
205
|
# List the retained MODS versions for a resource.
|
|
174
206
|
#
|
|
175
207
|
# Wraps Atlas's `GET /resources/<id>/mods/versions`, which returns the
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AtlasRb
|
|
4
|
+
module System
|
|
5
|
+
# Personal-access token lifecycle — mint and revoke the 1-week JWT a real
|
|
6
|
+
# person exports as `ATLAS_JWT` to drive atlas_rb / curl against Atlas
|
|
7
|
+
# headless (BYO-JWT mode, see {AtlasRb::FaradayHelper}). Cerberus's "My DRS
|
|
8
|
+
# → Programmatic access" section calls these post-SSO and hands the token
|
|
9
|
+
# to the librarian; the token is never persisted by Cerberus.
|
|
10
|
+
#
|
|
11
|
+
# ## Why a separate class from {System::User}
|
|
12
|
+
#
|
|
13
|
+
# Token lifecycle is a distinct concern from SSO user provisioning: minting
|
|
14
|
+
# a bearer credential for someone is "become anyone," which is exactly why
|
|
15
|
+
# both Atlas endpoints are :system-gated (`authorize! :mint_token, User`).
|
|
16
|
+
# Keeping it in its own class keeps that carve-out legible rather than
|
|
17
|
+
# burying it among provisioning methods.
|
|
18
|
+
#
|
|
19
|
+
# Both methods authenticate via {FaradayHelper#system_connection} — the
|
|
20
|
+
# hard-pinned system token + `User: NUID` header — so there is no way to
|
|
21
|
+
# issue them as a regular user. This is never the ambient-user
|
|
22
|
+
# relay-signing path.
|
|
23
|
+
class Token
|
|
24
|
+
extend AtlasRb::FaradayHelper
|
|
25
|
+
|
|
26
|
+
# Mint a personal-access JWT for a real person (`POST /nuid`).
|
|
27
|
+
# System-gated. The returned token authenticates as `nuid` in BYO-JWT
|
|
28
|
+
# mode (Atlas resolves identity from the token's `sub`, ignores any
|
|
29
|
+
# `User:` / `On-Behalf-Of` header, and refuses `:system`/`:anonymous`).
|
|
30
|
+
# Full-privilege for that user, 1-week TTL, single-jti.
|
|
31
|
+
#
|
|
32
|
+
# @param nuid [String] the NUID the token will act as.
|
|
33
|
+
# @return [String, nil] the JWT, or nil when the NUID has no Atlas User
|
|
34
|
+
# row (404) — a clean "no such user" signal for the caller to surface.
|
|
35
|
+
def self.mint(nuid:)
|
|
36
|
+
response = system_connection.post("/nuid", { nuid: nuid }.to_json)
|
|
37
|
+
return nil if response.status == 404
|
|
38
|
+
|
|
39
|
+
AtlasRb::Mash.new(JSON.parse(response.body))["token"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Revoke every outstanding token for a user (`DELETE /nuid`) by rotating
|
|
43
|
+
# its jti. System-gated. Single-jti model → all-or-nothing: every token
|
|
44
|
+
# the user holds dies at once. "Regenerate" on the Cerberus side is
|
|
45
|
+
# {.revoke} followed by a fresh {.mint}.
|
|
46
|
+
#
|
|
47
|
+
# The NUID rides as a query param (`system_connection`'s params hash) so
|
|
48
|
+
# this sidesteps DELETE-with-body handling; Atlas reads it from
|
|
49
|
+
# `params[:nuid]` either way.
|
|
50
|
+
#
|
|
51
|
+
# @param nuid [String] the NUID whose tokens to invalidate.
|
|
52
|
+
# @return [Boolean] true on success (204), false when the NUID has no
|
|
53
|
+
# Atlas User row (404).
|
|
54
|
+
def self.revoke(nuid:)
|
|
55
|
+
system_connection({ nuid: nuid }).delete("/nuid").status == 204
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/atlas_rb.rb
CHANGED
|
@@ -30,6 +30,7 @@ require_relative "atlas_rb/admin/collection"
|
|
|
30
30
|
require_relative "atlas_rb/admin/community"
|
|
31
31
|
require_relative "atlas_rb/system"
|
|
32
32
|
require_relative "atlas_rb/system/user"
|
|
33
|
+
require_relative "atlas_rb/system/token"
|
|
33
34
|
require_relative "atlas_rb/audit_event"
|
|
34
35
|
|
|
35
36
|
# Ruby client for the Atlas API — Northeastern University's institutional
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: atlas_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.8.
|
|
4
|
+
version: 1.8.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Cliff
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -150,6 +150,7 @@ files:
|
|
|
150
150
|
- lib/atlas_rb/person.rb
|
|
151
151
|
- lib/atlas_rb/resource.rb
|
|
152
152
|
- lib/atlas_rb/system.rb
|
|
153
|
+
- lib/atlas_rb/system/token.rb
|
|
153
154
|
- lib/atlas_rb/system/user.rb
|
|
154
155
|
- lib/atlas_rb/user.rb
|
|
155
156
|
- lib/atlas_rb/version.rb
|