diff options
author | hellekin <hellekin@cepheide.org> | 2021-03-22 15:30:45 +0100 |
---|---|---|
committer | hellekin <hellekin@cepheide.org> | 2021-03-22 15:30:45 +0100 |
commit | 15096ed20f918d585f7b49610f89deefda0a20b3 (patch) | |
tree | f6014e03bdd466977446eae004205d992a946de4 /app/lib | |
parent | e5619547d5544a043dfec173f17020b09f882a98 (diff) | |
download | incommon-map-15096ed20f918d585f7b49610f89deefda0a20b3.tar.gz |
Add UUIDResolver
The UUIDResolver adds a route at `/by-uuid/:uuid` that enables
applications to request information about a given UUID.
The UUID must be a Random UUID (version 4, see RFC 4122).
If an invalid UUID is given, the controller will return 422 Unprocessable Entity.
If a valid UUID is given:
- 404 indicates that the UUID is not assigned to anything known to the system.
- 302 indicates that the UUID was assigned to a record, and the User-Agent
will be redirected to that record's Location as indicated in the response header.
- 200 indicates that the UUID was assigned to more than one record (which is unlikely)
and will list those records.
Diffstat (limited to 'app/lib')
-rw-r--r-- | app/lib/uuid_resolver.rb | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/app/lib/uuid_resolver.rb b/app/lib/uuid_resolver.rb new file mode 100644 index 0000000..acca494 --- /dev/null +++ b/app/lib/uuid_resolver.rb @@ -0,0 +1,55 @@ +class UUIDResolver + # Note the static '4' in the third group: that's the UUID version. + UUID_V4_REGEX = %r[\A[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}\z] + + attr_reader :records, :count, :record, :uuid + + def initialize(uuid) + @uuid = validate!(uuid) + @records, @count = resolve! + + end + + def record + case @count + when 0 + nil + else + records.first + end + end + + private + + # List models that have UUIDs + def public_record_types + [ + ::Agent, + ::Map, + ::Resource, + ::Taxonomy + ].freeze + end + + # Find records with this UUID + def resolve! + records = [] + + public_record_types.each do |model| + records << model.find_by(uuid: @uuid) + end + + [records.compact, records.compact.size] + end + + # Ensure the passed UUID is correct + def validate!(uuid) + validate_uuid_v4(uuid) || raise(ArgumentError.new("You must pass a valid random UUID (https://tools.ietf.org/html/rfc4122)")) + end + + # Validate a UUID version 4 (random) + def validate_uuid_v4(uuid) + uuid = uuid.to_s.downcase + uuid.match?(UUID_V4_REGEX) ? uuid : false + end +end |