Firebase orderByChild security rules - firebase

Given the firebase setup with the dinosaur example I would like to add a security rule for .read. If I add .read:true in the hierarchy like the following the query fails to provide any results.
{
"rules": {
"dinosaurs": {
"$dino": {
".read":true
}
}
}
}
If I use the following the queries work as expected.
{
"rules": {
"dinosaurs": {
".read":true
}
}
}
For my use case I need a setup more like the first example so that I can check each item for a condition before allowing a read to that item. To use the new orderByChild("property") style query however it would seems I have to allow access to the entire subtree. Is this the case?

Related

Filter nested objects in WPGraphQL

I'm using WPGraphQL to interact with a vanilla wordpress backend. gatsby-source-wordpress is used as a client.
What I would like to achieve with my query:
for a list of category ids, give me a list of posts that belong to each category
each list of posts should be filtered (posts not having a certain id, etc), and limited to a certain number. The filter/limit params would be the same for each category.
Now when I'm constructing my query, it seems like I can only filter the outer node (category), but not the attached post node:
// syntax from the gatsby-source-wordpress plugin
// https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-wordpress
query MyQuery {
allWpCategory(filter: {id: {in: ["dGVybTo0Mg=="]}}) {
nodes {
posts { // cannot filter here 🥲
nodes {
title
id
}
}
}
}
}
I tried adding the filter in different locations, without success. Searched for solutions, but didn't find any specific to this GraphQL implementation. Structurally, this looks like what I'm try to achieve, but it's a different platform altogether.
My questions:
is it possible to get this working (it seems like a pretty standard requirement to me)
if yes, how
if no, what's the limiting factor? (GraphQL, WPGraphQL, gatsby-source-wordpress)
🙏
I don't have your data structure and can't test. Does something like this work?
query MyQuery {
allWpCategory(
filter: {
posts: {
elemMatch: {
id: {
ne: "something"
}
}
}, {
id: {
in: ["dGVybTo0Mg=="]
}
}
})
{
nodes {
posts { // cannot filter here 🥲
nodes {
title
id
}
}
}
}
}

GraphQl Query for Node image url without relationships with gatsby-source-drupal

I'm using drupal as a headless CMS for a Gatsby site.
Each node Type of Recipe has an associated image.
I'm trying to query for each Recipe image without having to hop through all it's relationships.
Is there a more direct graphql query for an image than through relationships with gatsby-source-drupal?
Gatsby's own gatsby-source-drupal example uses relationships to access a drupal node's images.
query($slug: String!) {
recipe: nodeRecipe(fields: { slug: { eq: $slug } }) {
title
...
relationships {
image: field_image {
localFile { // NodeType: 'File'
childImageSharp {
fluid(maxWidth: 470, maxHeight: 353) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
Context
According to a related question:
"Using Drupal nodes with Gatsby requires you to drill into the relationships between nodes and media entities, then into the relationship between the media entities and the files." #Spanners
I can't help but think there has to be a better way. The query in question yields a node type of 'File', which is a Gatsby built in. But since I need to append fields to the image's node, I'd really rather not do that to the builtin File node. It feels like there should be another node Type associated with the images.
Update:
This is what my localhost:8000/__graphql looks like
allRecipes { // Query.allRecipes: recipesConnection!
nodes { // recipesConnection.nodes: [recipes!]!
id
relationships { // recipes.relationships: recipesRelationships
image { // recipesRelationships.image: images
relationships { // images.relationships: imagesRelationships
imageFile { // imagesRelationships.imageFile: files
localFile { // files.localFile: File ...
url
} ```

Prestashop 1.6.1.4 - Add CSS to CMS Page of Module

I am making a module that adds new tab in product edit page. The installation is Prestashop 1.6.1.4. The module adds a tab with some input fields that send data to mysql tables, but what I want to do is to style the fields a little bit, so that they look good. I am adding this in my module.php file:
public function install() {
if ($this->psversion() == 5 || $this->psversion() == 6)
{
if (parent::install() == false or !$this->registerHook('displayHeader') or !$this->registerHook('productFooter') or !$this->registerHook('displayAdminProductsExtra') or !$this->registerHook('actionProductUpdate') or !$this->registerHook('displayBackOfficeHeader'))
{
return false;
}
}
return true;
}
Then below this I put this code:
public function hookDisplayBackOfficeHeader($params) {
$this->context->controller->addCSS($this->_path.'views/css/adminsportsnutritionfadd.css');
}
But can't make the .css file appear. The file is in the right location, it has proper permissions and the owner of the file is www-data:www-data so this shouldn't be a permission issue. I have disable css combining in Prestashop as well as caching. Before reloading the page I am also deleting Prestashop's cache just in case, as well as I am deleting my brower's cache. Can somebody give me a hand in this?
Do like this:
public function hookBackOfficeHeader()
{
$this->context->controller->addCSS($this->_path.'views/css/adminsportsnutritionfadd.css');
}
For me it works like this:
$this->context->controller->addCSS($this->_path . 'views/css/back.css');
So the only difference is the css file name.
Not sure if you got this sorted or not, but...
I use this function within most of my modules to add
jQuery, Font-awesome, CSS & JS, then have it show ONLY on that module page...
public function hookDisplayBackOfficeHeader($params)
{
if(!(Tools::getValue('controller') == 'AdminModules'
&& Tools::getValue('configure') == 'MyModuleName')
){
return;
}
else
{
if ( method_exists($this->context->controller, 'addJquery') )
{
$this->context->controller->addJquery();
$this->context->controller->addCss('//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
$this->context->controller->addCss($this->_path.'views/css/back.css');
$this->context->controller->addJs($this->_path.'views/js/back.js');
}
}
}

Firebase Database Rules private nodes

I'm doing a groceryItem app where users can add items and only should see their own items.
I add my items by using childByAutoId and get unique key entries for each item (see picture #1).
Each item hast got 3 properties. addedByUser is the UID of an authenticated user and of course a name and the quantity.
I have problems setting the rules so that only users can see their own items. My current rules look like this (see picture #2).
If I log in with another user he can read all items. So my question is:
How I can make items readable for the users who created them?
I think I have a gap between items and addedByUser because I have the childByAutoId between. If you have any solutions or tips how I can structure this in a better way, pls feel free to help me.
Thanks in advance!
The $addedByUser is probably in the wrong spot in this example, as it is not a "nested child" of the items, but an attribute of a child item. I would suggest (not having tested this) that you would be looking for something along the lines of:
"items": {
"$item": {
".read": "data.child('addedByUser').val() === auth.uid"
}
}
This is lifted from the Firebase docs:
With data:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}
The rules could be:
{
"rules": {
"messages": {
"$message": {
// only messages from the last ten minutes can be read
".read": "data.child('timestamp').val() > (now - 600000)",
// new messages must have a string content and a number timestamp
".validate": "newData.hasChildren(['content', 'timestamp']) && newData.child('content').isString() && newData.child('timestamp').isNumber()"
}
}
}
}
This will prevent the incorrect user from reading someone else's (singular) item, and in your example would prevent user SZ825V... from performing a read on "items/-KKTDD...", however if user SZ825V were to perform a read on "items", then the read would fail entirely, because the user is trying to read their own documents and someone else's as well. This is an important concept in firebase with the rules behaving in an atomic way - that is, if one part of the read fails, the entire read does. Another way of putting this is that the rules do not act as a filter.
If this is the functionality you are seeking, it may be required to rearrange your structure. An example could be as follows:
{
"users": {
"abcdef-user-id": {
"items": {
"fjeiwofjewio": {
"name": "apple",
"qty": "23"
}
}
},
"ghijkl-user-id": {
"items": {
"regrewgreh": {
"name": "passionfruit",
"qty": "18"
}
}
}
}
and security rules might be:
.. {
"users": {
"$userId": {
".read": "auth.uid === $userId"
}
}
}
The above approach assumes you only want to allow a user to read the items in their user own data tree, is that no-one else would be able to see any other users' items. If you did want other users to see some of the other users' items, then a different approach again would be required, which would be another SO question.

Run code in specific part of URL in Iron Router

I have an application which makes heavy use of features, separated by specific users, which have different roles.
The problem is that I want to restrict access to some templates, if, for instance, the user is not an Admin.
Currently, I have this:
Router.route('createUser', {
path: '/admin/users/',
onBeforeAction: function() {
if(!isAdmin()) {
Router.go('/');
}
this.next();
}
});
But, specifying that if(isAdmin()) call to every other route is a pain. I want to know if there is any other easy and less error prone way to do it.
Maybe some regex magic would do, but I don't seem to find any examples of use.
First i will recommend you to read this meteor:common-mistakes on the profile editing part
So i will recommend you to better use the alanningroles-meteor package.
Is super easy to use, here is a Online DEMO and the Source Code if you have doubts.
On the router level you can create an onBefore hooks like this.
isAdmin = function(){
var currentUser = Meteor.user()
isUserSuperAdmin = Roles.userIsInRole(currentUser,'Super-Admin'); //using alaning roles.
if(isUserSuperAdmin){ //or use isAdmin();
this.next();
}else{
this.render('accessDenied')
}
}
Router.onBeforeAction('accessDenied', {only: ['admin','otherAdminRoute',etc]});
You can have an onBeforeAction hook combined with only for all routes like so:
var isAdmin = function() {
// Whatever logic you have for checking admin
if (!admin) {
Router.go("/");
}
this.next();
}
Router.onBeforeAction(isAdmin, {
only: ["admin/users"] // Specify other admin templates here
});

Resources