Temporary Variables in Firebase Security rules - firebase

So I'm setting up the firebase security rules for my project and for the user to have read access to a room, we need to make sure they are part of that organization. So I have a security rule like this:
root.child('organizations').child(data.child('organization_id').val()).child('user_ids').hasChild(auth.uid)
Not only is this really ugly, there are several other rules in the same statement (separated by &&/||) which have start with root.child('organizations').child(data.child('organization_id').val()) to access data from the organization variable associated with this room.
This leads to some UGLY security rules, is there any way I can make temporary variables or something like that so I can make this a lot more readable? Thank you!

Nope. The Firebase Security rules language doesn't have support for custom variables. This indeed leads to lots of duplication between rules.
The best solution is to write your rules in a higher-level language, that compiles into Firebase Security rules. The most well-known ones are Blaze (the grand-daddy of them all), Butane (not from Firebase itself) and Bolt (new and under very active development).
Bolt for example allows you to define (global) functions, which can easily encapsulate the repeated snippet and much more.

Since June 2020 the answer is Yes, you can have local variables (answering in case it's helpful to others)
From the firebase blog linked above
Local variables have been one of the most requested features in Rules, and they're now available within functions.

In Bolt, you could write your rule like this:
type Room {
organization_id: String,
read() { isUserInOrg(this.organization_id) }
}
isUserInOrg(org_id) { root.organizations[org_id].user_ids[auth.uid] }

Related

Can I add custom rules to coverity?

I am using coverity for java static code analysis, I need to add some custom rules so that scan happens according to the custom rule set.
Yes, you can write custom rules with Coverity. There are two APIs you can use:
"Extend" is the older API. Extend rules are written in C++ (regardless of what language you are scanning).
"CodeXM" is the newer API. CodeXM is a domain-specific language designed for writing static analysis rules.
Both APIs are explained in the product documentation, although that is not publicly available. My recollection is both APIs support the same set of scanned languages, specifically, C, C++, Java, and Javascript.
There are a couple Synopsys blog posts about CodeXM that might help you get started:
Getting started with writing checkers using CodeXM
Let’s write a CodeXM checker (it’s not rocket science!)
Additionally, as noted in an answer to How can we add custom rules for coverity tool?, sometimes the customization you want to do can be accomplished simply by changing the options to existing checkers. (I do not consider this question to be a duplicate of that one because the other question seems to be more about adjusting the behavior of existing checkers, despite its title.)
Disclosure: I'm a former Coverity/Synopsys employee.

Optimising network connections of firebase cloud function

Firebase documentation recommends including code snippet given at (https://firebase.google.com/docs/functions/networking#https_requests) to optimize the networking, but few details are missing. Like
How exactly does this help?
Are we supposed to call the function defined as per of recommendation
or include this snippet deploy?
Any documentation around this would be of great help.
this is an example showing you how you would make this request, the key part in this example is the agent field which by nature isn't normally managed within your app. By injecting a reference to it manually, you are able to micro-manage it and it's events directly.
As for the second question, it really depends on your cloud function needs - some users set it in a global object that they manage with all cloud functions but it's on a by-use case basis. but ultimately isn't required.
You can read more about HTTP.Agent's and their usage below:
https://nodejs.org/api/http.html
https://www.tabnine.com/code/javascript/functions/http/Agent
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent

Split up Firebase Firestore Security Rules into separate Files?

Is there a way to split Firestore Security Rules (firestore.rules) into separate / multiple files?
I would like to do a structure like so:
index.rules // imports all the rules
users.rules
posts.rules
comments.rules
helperFunctions.rules
// ... and so on
My firestore.rules file is getting quite big and this would make working with it much, much easier.
Unfortunately, I don't think it's possible at this time out of the box. However, I'm with you 100% with this issue.
There may be a rough workaround using npm (or whatever cli tool). Following this answer, you may be able to have a head, multiple inserts, and a foot. If you're able to find all files matching a pattern, you can concat them to the head, then concat the foot, ultimately naming this file firestore.rules.
OneLunch Man's answer inspired me to sit down and write a small Node.js module that shall make live easier organizing your Firestore rules:
https://github.com/lupas/firestore-rulez
As #OneLunch Man proposed above, this combines the different files into one single firestore.rules file. Additionally, and if configured, it adds some helper functions that you don't have to define yourself.
Hope it helps someone :)
I love the simplicity of security rules, though I hope organizing them will be even easier in the near future. But I'm very sure it will, right Frank? ;-)
Btw: I'll leave the question unanswered, maybe there's even better solutions?

Firebase data validation

I'm considering to use Firebase for a project but can't seem to find any informations on server-side data validation.
Lets say i'm making a game and a player deals damage to another player i would like to validate the following:
That the players are actually close to eachother
That the damage points corresponds to the attack given
That the data has not been
tampered from the client to the server
ETC.
Is it possible to validate this kind of stuff /Adding serverside logic directly with Firebase or do i have to make an intermediate-server, basically smashing the whole point in using Firebase in the first place?
Thanks in advance
Jonas
Validating data is definitely possible with Firebase. It is part of its "security" rules, for which the documentation can be found here and here.
A simple example from that last documentation link:
a sample .validate rule definition which only allows dates in the format YYYY-MM-DD between the years 1900-2099, which is checked using a regular expression.
".validate": "newData.isString() &&
newData.val().matches(/^(19|20)[0-9][0-9][-\\/. ](0[1-9]|1[012])[-\\/. ](0[1-9]|[12][0-9]|3[01])$/)"
You can build pretty complicated validation rules. In case you need those, you might want to have a look at Firebase's blaze compiler. It translates a higher-level language into Firebase's relatively low-level rules. The author of the blaze compiler originally wrote it for your second and third use-case and wrote an article about it here.
I hope these are enough to get you started. If you get stuck, just post a question with the rules you tried.

node_load or direct query?

What rule of thumb do you use for deciding to use node_load() or just writing a direct db_query()?
In a situation I'm looking at right now I need to get some node data and resolve data on two nodereference fields. So that would be 3 calls to node_load(). At some point here, would it be more efficient to construct the query with Joins directly?
This is for use in a self contained module that won't be distributed or used anywhere else, so I don't believe I need to worry about subverting node modification hooks (or do I?).
Edit:
Thinking about my question more, node_load() is only really applicable when you have one node to grab (and then maybe drilling down further into nodereferences like in my example). But as soon as you need to return more than one node based on some criteria, you're pretty much forced to use db_query right? Does Drupal have any abstracted API for writing queries like this?
Not a full answer (Not sure myself), just some hints.
node_load() is using a static cache (in Drupal 7, you can even use the entity_cache module to make it a permanent cache). If the nodes you are loading are being used a second time on the same page, that call will be free.
Querying CCK-tables is tricky. The schema structure can change completely based on configuration, for example when using a single or multiple values.
The reasoning behind using API methods for DB calls over direct DB calls is to provide a DB abstraction layer so that your app could move between supported database engines etc, also it enables your app to gracefully handle any schema changes (however unlikely) that core/module may make to the tables in question. It's also likely easier as #Berdir says for CCK fields and Node_Ref fields, but that depends on which you are more confident with Drupal API& PHP or MySQL...the payoff of doing it the Drupal way is increased future productivity and understanding of the codebase and what is possible :)
Oh and my rule of thumb is - Do it the Drupal way if at all possible (possible being variable depending on app time/cost/performance/whatever requirements)

Resources