Adding ACL for nested field object in JSON schema object - python-3.x

I am working on specify ACL fields for fields inside objects. I have the validator to check for permission to edit a specific field. For example, the schema looks like this:
"basic_info": {
"properties": {
"cadi_id": {
...
},
"analysis_keywords": {
...
},
"abstract": {
"type": "string",
"title": "Abstract",
"acl": {
"users": ["test#test.org", "test1#test.org"]
}
},
"ana_notes": {
...
},
"conclusion": {
...
}
},
"title": "Basic Information",
"type": "object",
"id": "basic_info",
"required": ["cadi_id"]
}
I have the abstract field with acl. It works fine when the user(not in acl) is editing the abstract field and the validation error is thrown when the user is not in acl.
The problem comes when user(not in acl) is editing other field like conclusion and have the same ValidationError.
When editing any field in basic_info, for example conclusion field, the whole basic_info object is processed in the validator beacuse it's the parent field and now user should be able to edit the conclusion field because there is no acl set. but it gives the ValidationError because we also receive the abstract (which is unchanged) in the basic_info and it goes to validate method and since the user is not in acl it gives ValidationError .
Please let me know what I am missing here to let the user(not in acl) to edit the non acl field?
I tried to get the previous value from the db and check if the controlled field is edited by user or not, but it doesn't seems efficient for this use case and I want to know if there is any native way to do the field level validation. I could not find anything in the docs.

Related

Sequelize "raw = true" changes json model attribute name with dot

I have Content model and it has many sub ContentImage item, like this;
const content = await db.Content.findOne({
where: {
permalink: req.params.permalink
},
include: [{
model: db.ContentImages
}]
raw: true
});
As you know raw:true covert SequelizeInstance to Object model. I have some problem in this point.
If I use raw:true, json model show me like this;
{
"id": 4706,
"name": "Content Title",
"content": "Content detail",
"t_content_images.id": 7633,
"t_content_images.content_id": 4706,
"t_content_images.image": "content-image-1.jpg",
"t_content_images.order_no": 1
}
Because of expressjs, I need like this model instead of SequelizeInstance;
{
"id": 4706,
"name": "Content Title",
"content": "Content detail",
"t_content_images": {
"id": 7633,
"content_id": 4706,
"image": "content-image-1.jpg",
"order_no": 1
}
}
Another problem, I have multiple content image and if I use like above first sample, it returns me just first content image.
You are thinking about it a bit backwards - when you use raw: true it doesn't convert it from a JSON object to a Model Instance.
If you think of how SQL results are structured, they always come back flat. This means that for joins where you have one base record linked to multiple children (Content -< ContentImages in this case) then the SQL results will repeat the info for the base record for each of the children. Sequelize will parse this into a JSON object, which is what you are seeing in the first example in your question. If you leave out raw: true then it will take it a step further and parse it into an instance of your model. You can then call Model.toJSON() to get a JSON representation of the parsed object.
Given the above, if you are fetching lots of children then it can be more efficient to get the data into two queries instead of one so you don't have to send the repeating data to the client.

Cannot change workitem's parent through the azure devops api

I'm trying to programatically change a workitem's parent using the azure devops api but it's not working as expected.
I tried using update link endpoint and also remove link endpoint but none of them seem to be the correct one given that there is no way I can get a relation ID for the parent-child relationship to use in the request path.
The "relation ID" to send in path: is just the index of the relation being changed or removed in the WorkItemRelation[] on the Work Item being PATCHed.
Use the $expand=Relations argument in the query string of the GET operation for the work item whose parentage you want to change (Get Work Item).
https://dev.azure.com/{YOUR_ORG}/{YOUR_PROJ}/_apis/wit/workitems/{Child_ID}?$expand=Relations&api-version=5.0-preview.2
note: I'm not exactly sure, but I think the {YOUR_PROJ} value can be omitted.
With the resulting workitem object, get the index of the relation where the relation type is Hierarchy-Reverse, and use this as the leaf of the "path": "/relations/{index}" property sent in the PATCH body with op: "remove".
Get response (abbreviated):
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "https://dev.azure.com/{YOUR_ORG}/_apis/wit/workItems/{Parent_ID}",
"attributes": {
"isLocked": false
}
}
Patch request (body):
[
{
"op": "test",
"path": "/rev",
"value": 1
},
{
"op": "remove",
"path": "/relations/0"
}
]
The examples in the documentation tend to perform a test on the revision of the work item before executing the remove or add operation. This isn't necessary, but it's probably a good idea.

Mongoose and nodejs: about schema and query

I'm building a rest api that allows users to submit and retrieve data produced by surveys: questions are not mandatory and each "submit" could be different from each other. Each submit is a json with data and a "survey id":
{
id: abc123,
surveyid: 123,
array: [],
object: {}
...
}
I have to store this data and allow retrieving and querying.
First approach: going without schema and putting everything in a single collection: it works, but each json field is treated as a "String" and making queries on numeric values is problematic.
Second approach: get questions datatypes for each survey, make/save a mongoose schema on a json file and then keep updated this file.
Something like this, where entry "schema : {}" represent a mongoose schema used for inserting and querying/retrieving data.
[
{
"surveyid" : "123",
"schema" : {
"name": "string",
"username" : "string",
"value" : "number",
"start": "date",
"bool" : "boolean",
...
}
},
{ ... }
]
Hoping this is clear, I've some questions:
Right now I've a single collection for all "submits" and everything is treated as a string. Can I use a mongoose schema, without other modifications, in order to specify that some fields are numeric (or date or whatever)? Is it allowed or is it even a good idea?
Are there any disadvantage using an external json file? Mongoose schemas are loaded at run time when requested or does the service need to be restart when this file is updated?
How to store data with a "schema" that could change often ?
I hope it's clear!
Thank you!

Model relation not working

I'm am trying to figure out how to make the model relation to work in loopback.
I already managed to make one work (with Country hasMany CountryLanguage), this one shows up in the Countries URL.
But When I tried to do another one it doesn't work.
Here is what I'm trying to do :
I have a User model and an Event model, and I want the Event model to be linked with the users that created the event, but I also want an many-to-many relationship to manage the user's subscription to an event. I already tried the hasMany and it doesnt work, well it doesn't show up in the explorer.
About the ownership relation is it just a Event hasOne User ?
UPDATE :
Here is my relation for the users :
"relations": {
"publicEvents": {
"type": "hasAndBelongsToMany",
"model": "PublicEvent",
"foreignKey": ""
},
"privateEvents": {
"type": "hasAndBelongsToMany",
"model": "PrivateEvent",
"foreignKey": ""
}
},
So now the relation for the event is working as in a User can be an owner of an Event, and I also don't know if I chose the correct relation is hasMany enough in this case? (Also there are no relation declared in the event model)
But know I want also the user to be able to subscribe to an Event, I created two model for this PublicSubscriptions and PrivateSubscriptions in which I put:
"properties": {
"userId": {
"type": "string",
"required": true
},
"privateEventId": {
"type": "string",
"required": true
}
},
But I don't know it this the way to do it, I suppose these fields are not required and relation can work this out for me but I don't know which one to choose.
Rather than creating two models for Event you could have a single Event model, and two relations
relation createdEvents : User hasMany Event
relation subscribedEvents : User hasMany Event
Then, you should have some User with specific custom role ("eventCreator" for instance) for the first relation. Users under this role have more rights (like creating an event).
Standard users will only be able to subscribe. Subscriptions can thus be tracked using the second relation.
Hope this helps

Saving a Person or Group field using REST

Does anyone know how to save a Person field using REST?
I have tried the following and it works:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonFieldId" : 1
}
But this only works if you know the ID. I don't have that! How can I get it? I have the key which is i.0#w|domain\userName.
I tried the following and it doesnt work either:
{
"__metadata": { "type": "SP.Data.SomeListListItem" } ,
"MyPersonField" : { "__metadata": { "type": "SP.Data.UserInfoItem" }, "Name": "i.0#w|domain\userName" }
}
Any ideas?? Thanks!
I haven't done this with a Person field, but I did do something similar with a managed metadata field. I basically had to pass in additional information as an object to create the value in the field.
See if passing in the ID of the user along with the name works. I'm about to try this myself as I have the same need.
{
"MyPersonField": { "Name": "i.0#w|domain\userName", "ID": 1 }
}
EDIT: Ok, updating this field is easier than I thought. I was able to perform the update by simply passing in the ID of the user to the Id field:
{
"MyPersonFieldId": 1
}
This means the user should already be in the site collection, so if the user doesn't exist the request will fail.
Use the below code to get Current User ID to save user under People and group column. People column name is Requestor. But to save user we have to specify column name as RequestorId
var userid = _spPageContextInfo.userId; // To get current user ID
var itemProperties={'Title':vTitle,'RequestorId':userid};
The thing is that User information is a lookup field thereby MyPersonField does not exist on your SharePoint list if you use an OData endpoint, I really don't know how to save data but same problem happened to me when I tried to read a user.
for example {server}/{api}/list/getbytitle('mylist')/items does not return MyPersonField instead return MyPersonFieldId.
But if we use:
{server}/{api}/list/getbytitle('mylist')/items/?$select=*,MyPersonField/Name&$expand=MyPersonField
We are able to work with MyPersonField lookup values.

Resources