A service that knits together user identities from various sources.
Owned by Security
The header X-WIW-AUTHOR
is required for all requests. Please set it to your email address.
-
/all
(GET) -- lists all items (same as/alias
and/list
) -
/alias
(GET) -- lists all items (same as/all
and/list
) -
/alias/:key
(GET) -- lists all users who have any value set forkey
(same as/list/:key
) -
/alias/:key/:value
(GET) -- If there is exactly one user matching{key:value}
, return that user. Otherwise, error. (For 0 or more than 1 user, use/list/:key/:value
). -
/alias/:key/:value
(POST) -- Requires a JSON object in the body and exactly one user matching{key:value}
. Sets each key present in body to the value provided in body, leaving any other keys alone. -
/alias/:key/:value/data/:path...
(GET) -- Gets the value of a single key for the single matching user. For example,/alias/key/value/data/key2/innerkey
returns the value ofuser.key2.innerkey
. -
/alias/:key/:value/data/:path...
(POST) -- Requires a body. Sets the value of matching user's path to an object in body. Good for setting the value of a nested key without touching Body must be a JSON object (not a scalar), so it isn't fully featured. It is often simpler to usePOST /alias/:key/:value
, where if you are setting a nested key, copying the parts of the current value that you aren't changing. Example: given thatGET /alias/key/value/
returns{"key": "value", "key2": {"innerkey": "value2"}
, thenPOST /alias/key/value/data/path/key2/newinnerkey
with body{"key": "value"}
will return{"key": "value", "key2": {"innerkey": "value3", "newinnerkey":{"key":"value"}}}
and make the appropriate updates. -
/alias/:key/:value/history/:path...
(GET) -- Gets the full history of the given path for the single matching user. -
/list
(GET) -- lists all items (same as/all
and/alias
) -
/list/:key
(GET) -- lists all users who have any value set forkey
(same as/alias/:key
) -
/list/:key/:value
(GET) -- returns an array (possibly empty) of all users matching{key:value}
. -
/list/:key/:value/data/:path...
(GET) -- returns an array consisting of the value of path for each matching user. For example,/list/active/true/data/email
returns an array of the emails of all active users.
who-is-who
is backed by three DynamoDB tables. While these can be edited by hand via AWS console or CLI, please be very careful. The full specs can be found here.
whoswho-objects
is a full collection of each user along with arbitrary key-value data about them. It uses a UUID field named_whoid
as the primary key. Email is required field, although this is not enforced on the database level.whoswho-paths
serves sort-of like a very general index overwhoswho-objects
. It uses a composite primary key consisting of a partition keypath
for the field and a sort key consisting of the value of that field for a particular user, then the null character\u0000
, then that user's_whoid
. Each item also has_whoid
as a separate field. For example, for a user inwhoswho-objects
{ "_whoid": "ID", "email": "[email protected]", "slack": "user"}
if everything is in sync, there would be the following items inwhoswho-paths
{ "path": "email", "val_whoid": "[email protected]\u0000ID", "_whoid": "ID"}
{ "path": "slack", "val_whoid": "user\u0000ID", "_whoid": "ID"}
whoswho-history
keeps a change log.
If there's an issue, it's likely that whoswho-objects
and whoswho-paths
are out of sync. This likely needs to be fixed by manually changing the tables. You can use the AWS DynamoDB CLI to put the \u0000
into whoswho-paths
. For example:
aws dynamodb put-item --table whoswho-paths --item file://item.json
and
{
"path": {
"S": "email"
},
"_whoid": {
"S": "id"
},
"val_whoid": {
"S": "[email protected]\u0000id"
}
}
There are no API endpoints at the moment for deleting keys, but if you set the value of a key to the empty string (e.g. using POST /alias/:key/:value
, it will be deleted. The preferred way to delete a user is to set their active
to false
.