How to update stored references in Cosmos Document DB? - spring-boot

I am very new to document based databases and am using the Cosmos Document DB from Azure in my Springboot application.
I have a data structure like this:
User:
{
"firstname": "Bob",
"password": "asdf",
"roles": [
{
"rights": [
{
"name": "RIGHT_READ"
},
{
"name": "RIGHT_WRITE"
}
],
"name": "ROLE_ADMIN",
"id": "0d5299e0-836c-494d-9299-e0836c294d55"
}
],
"id": "0a9030f1-30f8-4d23-9030-f130f85d23e7",
"email": "email#mail.com",
"username": "admin",
"lastname": "Martin"
}
Role:
{
"rights": [
{
"name": "RIGHT_READ"
},
{
"name": "RIGHT_WRITE"
}
],
"name": "ROLE_ADMIN",
"id": "0d5299e0-836c-494d-9299-e0836c294d55"
}
The user stores all roles that he is assigned to. In this case, the user stores the role ROLE_ADMIN that contains several rights.
If I am now updating the role ROLE_ADMIN, e.g. by adding a right, and storing this again in the database via documentClient.replaceDocument(docLink, role, null); the reference of this entity that is stored in the user is not updated. User still contains a role with two rights instead of three then.
Do I have to update all references manually or am I missing something?

CosmosDB is a non-relational database. If you are using it as a relational database then you have to do all the cascading updates manually, as CosmosDB itself doesn't know that you are referencing another document from the database. Each document is agnostic from the other.
Based on this example you also have a data integrity issue. You are storing the rights in both the role object but also the user object. What you should do instead is store the rights in the role object and then just use the role id in the user object and query for the rights based on the role id. That that way you only update the roles.

Related

What is the best way to accept multiple objects as input for a CLI?

Let's say I have a CLI which talks to a banking server to create a bank account. A bank account has a few properties, and a list of users associated with the account. If the bank account is represented as a json, it'll be
{
"accountType": "Savings",
"Balance": 500,
"Users": [
{
"firstName": "tony",
"lastName": "stark",
"nickName": "ironman"
},
{
"firstName": "Peter",
"lastName": "Parker",
"nickName": "spiderman"
}
]
}
I want to create this account object using a CLI, and I want to pass all the users at create time. Like
bank-cli account create --acount-type Savings --balance 500 <And the users>
How do I go about adding the users in the CLI? Adding the values like --firstName1 --lastName1 --firstName2 --lastName2 does not seem like a good UX. My current implementation is that this CLI opens up another editor, which accepts multiple lines of these parameters as
--firstName tony --lastName stark --nickname ironman
--firstName peter --lastName parker --nickname spiderman
And this is converted to an array of objects in the code. Is there a better way to do this?
I have considered accepting the parameters as json/toml or other formats. They didn't look too clean.

Strapi + MongoDB not saving password field

I am trying to save a password in password type field in Strapi with MongoDB, but is always empty. I am testing through API calls using Insomnia software. The endpoints are already enable in Strapi configuration and the data is stored, just password is missing. For example, doing a POST API call with this data:
{
"name": "Test",
"Password": "testpassword",
"email": "testmail#hotmail.com"
}
It is stored this way:
{
"_id": "6097eadeb01bb600159d9319",
"name": "Test",
"email": "testmail#hotmail.com",
"published_at": "2021-05-09T13:59:58.204Z",
"createdAt": "2021-05-09T13:59:58.211Z",
"updatedAt": "2021-05-09T13:59:58.211Z",
"__v": 0,
"id": "6097eadeb01bb600159d9319"
}
If I enter to Strapi and check the created user, the password field is missing too, and even if I enter it manually, it is not saved either.
The password field is not displayed on the admin panel for security reasons. but u can update it from the admin panel. you will have to over write the create function without using the sanitize(which removes the password from the response) in order to get the password in response.

Set PrivilegeDepth with Microsoft CDS Web API

I'm trying to create an application user, along with its Security Role, for my Common Data Service environment using only the Web API. I've managed to create both the User, the Role and associate some Privileges to the Role. The only thing I can't do, is set the PrivilegeDepth of the RolePrivilege association.
This is the request payload I'm using to create the role with a few privileges:
{
"businessunitid#odata.bind": "/businessunits(6efad0b7-160b-eb11-a812-000d3ab2a6be)",
"name": "Security Role Test",
"iscustomizable": {
"Value": true,
"CanBeChanged": true,
"ManagedPropertyLogicalName": "iscustomizableanddeletable"
},
"canbedeleted": {
"Value": true,
"CanBeChanged": true,
"ManagedPropertyLogicalName": "canbedeleted"
},
"roleprivileges_association#odata.bind": [
"/privileges(2493b394-f9d7-4604-a6cb-13e1f240450d)",
"/privileges(707e9700-19ed-4cba-be06-9d7f6e845383)",
"/privileges(e62439f6-3666-4c0a-a732-bde205d8e938)",
"/privileges(e3f45b8e-4872-4bb5-8b84-01ee8f9c9da1)",
"/privileges(f36ff7e9-72b9-4882-afb6-f947de984f72)",
"/privileges(886b280c-6396-4d56-a0a3-2c1b0a50ceb0)"
]
}
The RolePrivileges are all created with the lowest depth (User). Anyone knows how to set different depths?
Also, is there a better way to assign privileges to the role? Like, upload an XML with the desired privileges to an endpoint which associates it with the role? And is there a better way to specify the privileges without having to know their GUIDs?
I would really appreciate it if you could help me with this. Thanks!
This should be the payload for setting depth like user, local, etc. Make sure to test this, I didn’t get a chance to test it now. Read more
"roleprivileges_association#odata.bind": [
{
"privilegeid#odata.bind" : "/privileges(2493b394-f9d7-4604-a6cb-13e1f240450d)",
"depth" : 1
},
]
Regarding the dynamic guid values instead of hard coding, just make another service call to pull all the privileges and iterate them. Read more
So I found the solution to set the Privilege depth. There's an action for that, AddPrivelegesRole.
Example:
POST https://org12345.crm4.dynamics.com/api/data/v9.0/roles(1b3df93a-070f-eb11-a813-000d3a666701)/Microsoft.Dynamics.CRM.AddPrivilegesRole
{
"Privileges": [
{
"Depth": "0",
"PrivilegeId": "886b280c-6396-4d56-a0a3-2c1b0a50ceb0",
"BusinessUnitId": "6efad0b7-160b-eb11-a812-000d3ab2a6be"
},
{
"Depth": "1",
"PrivilegeId": "7863e80f-0ab2-4d67-a641-37d9f342c7e3",
"BusinessUnitId": "6efad0b7-160b-eb11-a812-000d3ab2a6be"
},
{
"Depth": "2",
"PrivilegeId": "d26fe964-230b-42dd-ad93-5cc879de411e",
"BusinessUnitId": "6efad0b7-160b-eb11-a812-000d3ab2a6be"
},
{
"Depth": "3",
"PrivilegeId": "ca6c7690-c935-46b3-bfd2-abb306c2acc0",
"BusinessUnitId": "6efad0b7-160b-eb11-a812-000d3ab2a6be"
}
]
}

What is the proper format to expect when using an api to create a resource that references another resource

I am adding a feature that allows users to select from a list of people of a certain type, Type1 and Type2. A type would be chosen from a dropdown, and the data from the API would look like
{
"id": 1,
"name": "TYPE1",
"desc": "Type 1 Person"
}
I am creating a POST endpoint that allows an admin user to insert more people into the list, but I'm unsure on the best way for the admin to include the person's type. In other languages/frameworks, I would do something like this:
{
"first_name": "John",
"last_name": "Doe",
"type_id": 1
}
then handle adding the entry in my own SQL. In Spring though, I'm trying to leverage an object being created from the data automatically. For this to be successful, I've need to send the data as:
{
"first_name": "John",
"last_name": "Doe",
"type": {
"id": 1,
"name": "TYPE1",
"desc": "Type 1 Person"
}
}
My question is in two parts.
In Spring, is there anything I can leverage that would allow me to just pass an identifier for person type when creating a new person entry? (I've looked into DTOs, but I've never used them, so I don't know if that is the proper solution)
In REST in general, how much data should be required when adding a resource that references another resource?

Slack API: How to determine which human user owns a Legacy API token

When using a legacy token in slack I want to determine which user account owns this application. The information is not directly in the bot.info:
{
"ok": true,
"bot": {
"id": "foobar",
"deleted": false,
"name": "Slack API Tester",
"updated": 123456789,
"app_id": "A123"
}
}
Could I use the bot.id or bot.app_id objects to find who owns this application? If so which api call would I use.
To determine which user owns any token (incl. legacy token) just call the auth.test endpoint with that token. You will get the user ID and name of the token owner.
Example response from documentation:
{
"ok": true,
"url": "https://subarachnoid.slack.com/",
"team": "Subarachnoid Workspace",
"user": "grace",
"team_id": "T12345678",
"user_id": "W12345678"
}
If you need more info about the user you can call users.info for that user with his ID. Since you are using a legacy token you will have the necessary permissions.

Resources