Is it possible to get name or namespace from UUID V5? - hash

Is it possible to decode the namespace or the name from a given UUID?
Imagine that you have a house with a specific UUID and code, and now you need to know if the door or the windows belongs to the house only by looking at UUIDs.
My idea is to somehow put the house code inside the window and door UUID. and then somehow checking if the generated ids belong to the house extracting the house code inside from them.

Is it possible to get name or namespace from UUID V5?
No. It is not possible to extract either the name or namespace from a type 3 or type 5 UUID.
These two UUID types are produced by using MD5 or SHA1 to generate a 128 or 160 bit hash from a string that combines the name and namespace. Then some bits of the hash are thrown away.
It is mathematically impossible to reverse a hashing function (because of the Pigeonhole Principle) so extracting the original name or namespace would be impossible, even if the UUID contained the complete hash.
See also:
Universally unique identifier: versions 3 & 5
which says:
"Version-3 and version-5 UUIDs have the property that the same namespace and name will map to the same UUID. However, neither the namespace nor name can be determined from the UUID, even if one of them is specified, except by brute-force search. RFC 4122 recommends version 5 (SHA-1) over version 3 (MD5), and warns against use of UUIDs of either version as security credentials."
If you wanted to encode the the UUID and code of a house (or whatever) in an identifier, then you would need to use a reversible transformation on some representation of the information; e.g. Base64 encoding (insecure) or public key or private key encryption (potentially secure).

Related

Design REST endpoint with sublist as query param

I have a get request that will give me a winner based on a list of inputs.
eg). [{rabbit:3, tiger:2}, {rabbit:1, donkey:3}, {bird:2}]. // the winner is {rabbit:1, donkey:3}
I would like to design a get end point that will take a list.
One way I could think of is like this:
/GET
winner?rabbit,3?tiger,2&rabbit,1?donkey,3
A request param map would like like key:{rabbit,3?tiger,2}: value=[]
alternatively, I could do:
/GET
winner?id1=rabbit,3?tiger,2&id2=rabbit,1?donkey,3
but I don't need the id information at all.
While this serves the purpose for what I need, I am wondering what would be the best way to represent query param with sub-object?
There really isn't a great answer here.
As far as HTTP is concerned, any spelling that is consistent with the production rules described by RFC 3986 is fine.
If you have a representation that is easily described by a URI Template, then you (and your clients) can take advantage of the general purpose template libraries.
BUT... templates are not so flexible that they can be used to describe arbitrary message schemas. We've got support for strings, and lists (of strings) and associative arrays (of strings), and... that's pretty much it.
On the web, we might handle an arbitrary case using a form with a textarea control that accepts a string representation of the message; the browser would then create a key value pair, where the value is an encoded representation of the information in the text area.
So, for example, you could copy a string representation of a JSON document into the form, submit the form, and the browser would compose the matching query-part. On the server, you would reverse the process to get at the JSON document.
There's nothing particularly magic about using a key value pair, of course. Another possibility would be to ignore the key of the key value, and just use the properly encoded value as the query. Again, the server just reverses the process.
Another somewhat common attempt is to use key value pairs, treating the keys as "paths" - which is to say each key identifies a location in the original document, and the value indicates the information available at that location.
?/0/rabbit=1&/0/tiger=2&/1/rabbit=1&/1/donkey=3&/2/bird=2
In this example, the schema of the keys is based on JSON Pointer (RFC 6901), which is possible way to flatten hierarchical data into key value pairs. Which may not be "best", but is at least leaning in the direction of readily standardizable. (A standardized form would be an improvement, but I wasn't able to identify one).
The most obvious seems:
GET /winner?rabbit=3&tiger=2&rabbit=1&donkey=3

Can attribute values be used as identifiers in REST urls

I have a resource with identifier id and attribute name - name is unique for each of the resource instances.
In order to get, patch and delete the resource, is it REST and JSON:API compliant to use the name field
as the identifier in the URL?
e.g. to get resource by name, is the following URL compliant:
GET /resource/{name}
or is the following to be used / preferable:
GET /resource?name={name}
to patch or delete by name, can one use:
PATCH /resource/{name}
DELETE /resource/{name}
In order to get, patch and delete the resource, is it REST and JSON:API compliant to use the name field as the identifier in the URL?
Yes. REST doesn't care what spellings you use for your resource identifiers, as long as those identifiers are consistent with the production rules defined in RFC 3986.
That might mean that you need to encode the attribute name - for instance, replacing some reserved characters with the equivalent hex representation.
GET /resource/{name}
PATCH /resource/{name}
DELETE /resource/{name}
That's fine
GET /resource?name={name}
PATCH /resource?name={name}
DELETE /resource?name={name}
Also fine. It's a trade off; encoding information into path segments mean that you can take advantage of relative references and dot segments. Using key value pairs in the query part means that you can use HTML forms to allow the client to specify a name.
GET /resource?name={name}
DELETE /resource/{name}
Technically, you can play mix-and-match, but general purpose caches aren't going to know that you are being clever, and will not invalidate cached entries when the URI are different.
This answer fully ignores that it should be also compliant with JSON API specification.
That's fair comment.
The JSON:API specification does not introduce any significant constraints on the spelling conventions used in URI.
It does, however, expect that identifiers can be extended with application/x-www-form-urlencoded key value pairs to support sorting, pagination, filtering and so on.
(Warning: please be careful when reading the JSON:API specification, as the use of "resource" there does not align particularly well with the meaning of resource in the context of REST.)
The JSON:API recommendations for URI design encourage the use of path segments for referencing "resources" as though they were individually addressable hierarchically organized elements of a single "reference document".
Furthermore, the recommendations call for using a specific hierarchical spelling, using the type and identifier of a resource to compute its URI
/{type}/{id}
In other words, GET /resource/{name} should return a application/vnd.api+json representation with a type member resource and an id member name. The specification applies the additional constraint that this (type, id) combination must be unique.
If name is just a property, and not actually the identifier, then JSON:API recommends that you treat it as a filter
/resource?filter%5Bname%5D=abcde
And the representation returned would include a self link relation that tracks with the identifier in the usual way.
(Note: [] are RFC 3986 gen-delims, and therefore require hex encoding in the query part. At least one of the JSON:API examples includes a note explain this, but filtering example in recommendations does not emphasize this. In practice? you might get away with using them unencoded -- the use of square brackets in the query part was a common non-compliant convention).

Is it legitimate to insert UUIDs into Postgres that have been generated by a client application?

The normal MO for creating items in a database is to let the database control the generation of the primary key (id). That's usually true whether you're using auto-incremented integer ids or UUIDs.
I'm building a clientside app (Angular but the tech is irrelevant) that I want to be able to build offline behaviour into. In order to allow allow offline object creation (and association) I need the the client appplication to generate primary keys for new objects. This is both to allow for associations with other objects created offline and also to allow for indempotence (making sure I don't accidentally save the same object to the server twice due to a network issue).
The challenge though is what happens when that object gets sent to the server. Do you use a temporary clientside ID which you then replace with the ID that the server subsequently generates or you use some sort of ID translation layer between the client and the server - this is what Trello did when building their offline functionality.
However, it occurred to me that there may be a third way. I'm using UUIDs for all tables on the back end. And so this made me realise that I could in theory insert a UUID into the back end that was generated on the front end. The whole point of UUIDs is that they're universally unique so the front end doesn't need to know the server state to generate one. In the unlikely event that they do collide then the uniqueness criteria on the server would prevent a duplicate.
Is this a legitimate approach? The risk seems to be 1. Collisions and 2. any form of security that I haven't anticipated. Collisons seem to be taken care of by the way that UUIDs are generated but I can't tell if there are risks in allowing a client to choose the ID of an inserted object.
However, it occurred to me that there may be a third way. I'm using UUIDs for all tables on the back end. And so this made me realise that I could in theory insert a UUID into the back end that was generated on the front end. The whole point of UUIDs is that they're universally unique so the front end doesn't need to know the server state to generate one. In the unlikely event that they do collide then the uniqueness criteria on the server would prevent a duplicate.
Yes, this is fine. Postgres even has a UUID type.
Set the default ID to be a server-generated UUID if the client does not send one.
Collisions.
UUIDs are designed to not collide.
Any form of security that I haven't anticipated.
Avoid UUIDv1 because...
This involves the MAC address of the computer and a time stamp. Note that UUIDs of this kind reveal the identity of the computer that created the identifier and the time at which it did so, which might make it unsuitable for certain security-sensitive applications.
You can instead use uuid_generate_v1mc which obscures the MAC address.
Avoid UUIDv3 because it uses MD5. Use UUIDv5 instead.
UUIDv4 is simplest, it's a 122 bit random number, and built into Postgres (the others are in the commonly available uuid-osp extension). However, it depends on the strength of the random number generator of each client. But even a bad UUIDv4 generator is better than incrementing an integer.

Hash in the Logical Id of the resources in CDK/Cloudformation

Whenever I generate cloudformation template from CDK, I see that in logical ids, it adds some kind of Hash. What does that Hash mean? Eg.
Test4FCEEF4A
How does this Hash 4FCEEF4A gets generated?
The logical IDs for resources are set using the allocateLogicalId method which you can find here. It calls the makeUniqueId method which you can find here. In the makeUniqueId method, it creates a hash component of the logical ID and a human-readable component of the logical ID. It uses the crypto library to create an md5 hash using path, which it gets from the IDs of the nodes of the CfnElement and returns a hex value. So the Hash 4FCEEF4A you see is the hash component that is created in the makeUniqueId method.

Salesforce.com Id attribute seems to have a 15 and 18 character value, whats the difference?

When using the SOAP API to work with salesforce.com (SFDC) it seems that the primary key in the underlying database is Id. Well there seems to be two representations of this value as either a 15 character version or an 18 character version.
I have been using the 18 since it is clearly more specific, but what is contained in the last three digits, that they can be dropped, seemingly?
Anyone understand what this is all about?
From the Web Services API Developer's Guide:
ID fields in the Salesforce.com user
interface contain 15-character,
base-62, case-sensitive strings. Each
of the 15 characters can be a numeric
digit (0-9), a lowercase letter (a-z),
or an uppercase letter (A-Z). Two
unique IDs may only be different by a
change in case.
Because there are applications like
Access which do not recognize that
50130000000014c is a different ID from
50130000000014C, an 18-digit,
case-safe version of the ID is
returned by all API calls. The 18
character IDs have been formed by
adding a suffix to each ID in the
Force.com API. 18-character IDs can be
safely compared for uniqueness by
case-insensitive applications, and can
be used in all API calls when
creating, editing, or deleting data.
If you need to convert the
18-character ID to a 15-character
version, truncate the last three
characters. Salesforce.com recommends
that you use the 18-character ID.
I know this is an old post, but just in case it is useful to someone...
If you want to do ad-hoc conversions of Id's, rather than programatically, then this Chrome extension makes it easy:
https://chrome.google.com/webstore/detail/sf-15-to-18/cogllpmaoflgaekieefhmglbpgdgmoeg
FYI - I'm the developer. Please use the feedback form on the app if you'd like to suggest any improvements or additional functionality.
Thanks!