aboutsummaryrefslogtreecommitdiff
path: root/app/lib
diff options
context:
space:
mode:
authorhellekin <hellekin@cepheide.org>2021-03-22 15:30:45 +0100
committerhellekin <hellekin@cepheide.org>2021-03-22 15:30:45 +0100
commit15096ed20f918d585f7b49610f89deefda0a20b3 (patch)
treef6014e03bdd466977446eae004205d992a946de4 /app/lib
parente5619547d5544a043dfec173f17020b09f882a98 (diff)
downloadincommon-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.rb55
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