I am attempting to use RavenDB's authorization bundle to limit the results of a query (on WorkItems) by the permissions that have been explicitly set on WorkItem documents.
For example:
I have a user bob#bob.com with a userId of /users/1 and a WorkItem that has the following permissions set in the Meta-Data:
"Raven-Document-Authorization": {
"Tags": [],
"Permissions": [
{
"Operation": "/Operations/WorkItem/Search",
"User": "users/1",
"Role": null,
"Allow": true,
"Priority": 1
}
]
}
I would then expect the following code to limit a query (from Bob's perspective) to this one WorkItem, because that is all he has permission to.
using (var session = documentStore.OpenSession())
{
session.SecureFor("raven/authorization/users/1", "/Operations/WorkItem/Search");
var workItemsQuery = from wi in session.Query<WorkItem>()
select wi;
var debts = workItemsQuery.ToList();
// do something with the work items
}
I based my code on the following example from RavenDB's documentation (Context & User section): http://ravendb.net/docs/2.5/server/extending/bundles/authorization-bundle-design
What I am getting instead is WorkItems that have no explicit permissions set. This is very puzzling to me because if I run the following code:
using (var session = mDocumentStore.OpenSession())
{
var answer = session.Advanced.IsOperationAllowedOnDocument(userId, operation, securableId);
var allowed = answer.IsAllowed;
}
allowed is true.
One additional item of note, I am attempting to ignore or simply not use the authorization bundle's concept of role and I wonder if this is having some unintended effect.
It is very possible that I am misunderstanding their example, could anyone shed any light on this subject for me? Thanks in advance.
Also, I wondered if the issue I am encountering was related to this StackOverflow question: RavenDB: Raven Query not returning correct count with document authorization, but their issue seems to be with the count and not necessarily the actual results.
Just to tiddy up this question, I will provide an answer to what was causing my problem. The issue was related to the use of "raven/authorization/users/1" syntax. When I changed the search command to simply use, "users/1" it worked correctly.
Related
Like many others I've been getting this error when using Sequelize with Express and Express-handlebars:
Handlebars: Access has been denied to resolve the property "first_name" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
Handlebars: Access has been denied to resolve the property "last_name" because it is not an "own property" of its parent.
You can add a runtime option to disable the check or this warning:
See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details
I have found some answers on how to get around this. ie: allowProtoMethods, or adding npm install #handlebars/allow-prototype-access
What I'm curious about is, is there a proper way to handle the data or exclude the proto methods from the sequelize response?
I may not be understanding the issue at hand properly, so if that's the case I apologize. I'm just looking for the "right" way to deal with this.
Edit: To clarify a little further, I'm seeking to do things in a way that will produce the most secure application.
From handlebarsjs.com:
Using these properties may open security holes.
UPDATE!
I'm still trying to work this issue out, but I've noticed an interesting behavior.
Nested objects seem to trigger this issue.
It seems to trigger when the data in a nested object is accessed/rendered on the html page (exa: {{contact.first_name}}
sometimes it will have nested dataValues objects within the object and sometimes it won't.
I'd provide an example including dataValues, but it hasn't displayed like that for a while.
Object being returned:
{
"id": 3,
"email": "email2#email.com",
"password": "$2b$10$fOGiJC6NgUTR4qIt7/R7vuwpaFb3PUl9ks2vHBEkLnOUmRN0tEFue",
"kind": "user",
"createdAt": "2020-08-16T04:37:58.000Z",
"updatedAt": "2020-08-16T04:37:58.000Z",
"Contact": {
"id": 3,
"first_name": "Jane",
"last_name": "Doe",
"gender": "female",
"city": "Long Beach",
"state": "CA",
"zip": 12345,
"phone_number": 1234567891,
"createdAt": "2020-08-16T04:37:58.000Z",
"updatedAt": "2020-08-16T04:37:58.000Z",
"UserId": 3
},
"Props": []
}
I'm not necessarily seeing any other explicit types of data that trigger this error message. (That's not to say that there aren't any, but so far every data type and script that I've passed hasn't caused a problem.)
Data I was having a problem with: This data is from a Sequelize query response shown above.
let hbsObject = {
user: data[0],
contact: data[0].Contact
};
Notes about what happened with this data:
I used a promise to chain several queries at once.
User was queried, and contact was included in that query, so there were nested objects/data in the response. (obviously)
When I tried to render the first and last names from the data I was receiving the error message.
Data that seems to have solved my error:
let user = {
id: data[0].id,
email: data[0].email,
kind: data[0].kind,
createdAt: data[0].createdAt,
updatedAt: data[0].updatedAt,
};
let hbsObject = {
user: user,
contact: data[0].Contact.dataValues,
};
It's strange because sometimes when you view the data in the console, dataValues will be visible, and sometimes it won't. However, when you access it as I showed above the error is removed.
Current Conclusion
The data you are seeking to access on the handlebars page via the handlebars object must not be in a nested object.
What does that mean?
It seems to mean that you must either deconstruct it prior to passing the data to the page either manually (like I did with user) or by sending the data from the object 1 level at a time (like I did with contact).
If anyone can build on this or expand additional information I would greatly appreciate it! I'll edit again if more information becomes available.
UPDATE2
An array of objects is inaccessible as it is a list of objects nested in an array. This makes {{#each x}} a challenge. Individual data has been accessible with the method above.
UPDATE3
I was unable to find any clear solution to this issue. In the end I just allowed the proto methods with the handlebars/allow-prototype-access package.
As long as you're the only one that has access to your template/you absolutely 100% trust whoever also has access to your template, then it shouldn't really be a problem. If that isn't the case, I'd suggest using something other than handlebars for now.
0
If you are using MySQL, sequelize, use raw query options {raw: true} and if you are using relationships, you can use {nest: true}, eg:
users = await User.findAll({
where: { username: "SimonAngatia" },
include: [{ model: Tweet, as: "Tweets" }],
raw: true,
nest: true,
}).catch(errorHandler);
refer here: Sequelize, convert entity to plain object
Could not find this answer online, so decided to post the question then the answer.
I created a table in the capabilities.json file:
"dataRoles": [
{
"displayName": "Stakeholders",
"name": "roleIwant",
"kind": "GroupingOrMeasure"
}
...
"dataViewMappings": [
{
"table": {
"rows": {
"select": [
{
"for": {
"in": "roleIwant"
}
}
]
}
}
}
]
I realized that I could not simply set, for instance, legend data from the first category, because the first category comes from the first piece of data the user drags in, regardless of position. So if they set a bunch of different pieces of data in Power BI online, for instance, then remove one, the orders of everything get messed up. I thought the best way to settle this would be to identify the role of each column and go from there.
When you click on show Dataview, the hierarchy clearly shows:
...table->columns[0]->roles: { "roleIwant": true }
So I thought I could access it like:
...table.columns[0].roles.roleIwant
but that is not the case. I was compiling using pbiviz start from the command prompt, which gives me an error:
error TYPESCRIPT /src/visual.ts : (56,50) Property 'roleIwant' does not exist on type '{ [name: string]: boolean; }'.
Why can I not access this in this way? I was thinking because natively, roles does not contain the property roleIwant, which is true, but that shouldn't matter...
The solution is actually pretty simple. I got no 'dot' help (typing a dot after roles for suggestions), but you can use regular object properties for roles. The command for this case would be:
...table.columns[0].roles.hasOwnProperty("roleIwant")
And the functional code portion:
...
columns.forEach((column) =>{
if(column.roles.hasOwnProperty("roleIwant")){
roleIwantData = dataview.categorical.categories[columns.indexOf(column)].values;
})
If it has the property, it belongs to that role. From here, the data saved will contain the actual values of that role! The only thing I would add on here is that if a column is used for multiple roles, depending on how you code, you may want to do multiple if's to check for the different roles belonging to a column instead of if else's.
If anyone has any further advice on the topic, or a better way to do it, by all means. I searched for the error, all over for ways to access columns' roles, and got nothing, so hopefully this topic helps someone else. And sorry for the wordiness - I tend to talk a lot.
I find ObjectFilter doesn't work in SoftLayer.
I even tried the example provided in the SoftLayer webpage here:
https://sldn.softlayer.com/article/object-filters
REST:
List the ID and hostname of all servers in dal05
https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname]&objectFilter={"datacenter":{"name":{"operation":"dal05"}}}
When I ran this command, it still returns all the virtual guests, regardless what data center that virtual guest belongs to.
try this request:
GET https://api.softlayer.com/rest/v3/SoftLayer_Account/getVirtualGuests?objectMask=mask[id,hostname,datacenter]&objectFilter={"virtualGuests":{"datacenter":{"name":{"operation":"dal05"}}}}
The issue with your request is that you are missing the "virtualGuests" property, keep in mind that the objectFilter is filtering over the data in the database, so you need to tell it over what table work and over what record of the table work. e.g. using the "SoftLayer_Account" that implies that all the work will be over the "SoftLayer_Account" table now you need to tell id over what property/record of that table work in this case you need to work over the "virtualGuests" and so on. Please keep in mind that and you review the documentation about the valid properties/records e.g. these are the valid properties/record for Softlayer_Account:
http://sldn.softlayer.com/reference/datatypes/SoftLayer_Account
Regards
Maybe you can try adding virtualGuestsin the filter, something like this:
objectFilter={ "virtualGuests": { "datacenter": { "longName": { "operation": "Dallas 6" } } } }
or please see the first examples of https://sldn.softlayer.com/article/object-filters, like this:
object_filter = {
'virtualGuests': {
'datacenter': {
'name': {'operation': 'dal05'}
}
}
}
I'm trying to create a simple todo or blog system based on React + ReactFire.
And after a hour of reading firebase tutorial confused about configuring firebase security rules.
Code for saving element :
this.props.itemsStore.push({
text : this.state.text,
done : false,
user : this.props.user.uid
})
Everything ok, but how i can get all records what owns only but authorized user?
This rules doesn't works :
"rules": {
"items" : {
".write" : "auth !== null",
"$item" : {
".read": "data.child('user').val() == auth.uid"
}
}
}
Seems to there no way to get all records only for one user, with security rules, instead of this, i should use something like filter. But again, i don't know how to filter elements in ReactFire, and in manuals no information.
As example how does it work in Parse http://i.stack.imgur.com/l9iXM.png
The Firebase security model has two common pitfalls:
permissions cascade: once you've granted a read or write permission on a specific level, you cannot take this permission away at a lower level
rules are not filters: (this is essentially a consequence of the previous pitfall) you cannot use security rules to return a different subset of children for specific users. Either a user has access to a node, or they don't have access to it.
You seem to be falling for that second pitfall. While the user can access each specific message that they are the user for, they cannot query the higher-level items node since they don't have read access to it.
If you want to secure a list of messages/todos for a specific user, you will need to store that data for that specific user.
items_per_user
$uid
$itemid: true
This is quite common in NoSQL database and is often called denormalizing. See this article called "denormalization is normal" on the Firebase web site. It's a bit outdated as far as the Firebase API goes, but the architectural principles on denormalizing still apply.
To then show the items for a user, you'd do:
ref.child('items_per_user')
.child(ref.getAuth().uid)
.on('child_added', function(snapshot) {
ref.child('items')
.child(itemId.key())
.once('value', function(itemSnapshot) {
console.log(itemSnapshot.val());
});
})
Many developer new to Firebase think that the inner loop will be too slow to load their data. But Firebase is very efficient when it comes to handling multiple requests, since it only opens a connection once per client and pipelines all the requests in the inner loop.
Keep in mind, Rules are not filters. They allow access to nodes based on criteria.
Here's an example simple structure where users 0 and 1 have stored text data within their node.
Data Structure
ToDo
a_user_id_0
text: "some text"
done: yes
a_user_id_1
text: "another text"
done: no
Rules
In this example rule, users can only read/write from nodes that belong to them within the ToDo node, so the path $user_id would be equal to their auth.id. It assumes the users has authenticated as well.
"ToDo": {
"$user_id": {
".read": "auth != null && $user_id == auth.uid",
".write": "auth != null && $user_id == auth.uid"
}
}
If user_0 was auth'd and attempted to read/write data from a_user_id_1 node, it would fail.
I am trying to use the Asana API to create a task that is assigned to me and added to an existing project.
I have tried by not specifying the workspace as suggested by someone else but the task creation still fails.
The jSon I am using is the following;
{ "data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": 1234
}
}
If I create the task and then send another call to the API with the following jSon it works, but this means I need to make 2 API calls every time I create a task.
{
"project": 1234
}
Rather old question but it might help someone. Yes, you can attach a task to a project during creation using the 'projects' (not 'project' as stated above) param, passing its id.
You can also attach the task to many projects stating an array at 'projects' => {22, 33, 44}.
It's all here at https://asana.com/developers/api-reference/tasks
(I work for Asana)
The specification for Tasks can be found here: https://asana.com/developers/api-reference/tasks
Notably, you cannot specify a project during creation - you must go through the addProject call for each project you wish to add.
If there is contradictory information on another SO question, I apologize as that may have been written without first double-checking the implementation.
The actual problem is that you are passing an int instead of an string for "projects". Some attributes work well as string or int (e.g. "assignee" or "workspace") but not "projects".
..so correct your json to the following:
{
"data":
{
"name":"Testing Project",
"followers":[10112, 141516],
"workspace":6789,
"assignee":12345,
"project": "1234"
}
}
I wasted half a day -.-'