I have a problem while updating my document field in firestore - arrays

I have a problem related to firestore updating in fields .
allow update, delete: if request.auth != null && resource.data.id == request.auth.uid;
In the above security rule i am able to update my all documents field except when i change my image array which store link of all my images in storage. if i cannot change images array then update work successfully for me. otherwise permission error occurs on the console and when i call update method all other fields except image array deleted
allow update, delete: if request.auth != null;
But when i change my security rules to the above line, I did not get permission error and update work successfully. But i don't want to change my security as it is necessary for my application.
My code look like this
let projectData = {
projectName,
images,
}
await db.collection('projects').doc(projectUid).update(projectData);
there is another field of id which added to document when creation so i am not updating it
so anybody knows why error occurs when i am trying to update my images array field ?

Related

Can I make a collection append-only in Cloud Firestore?

I want to write game events and audit logs from my app to Cloud Firestore. Once written, I don't want the user to be able to modify or delete these events/logs.
How can I do this?
Rules in Cloud Firestore makes it quite simply to make a collection, or even the entire database, into an append-only system from the mobile & web clients.
Example
Below is a set of rules that will turn the root collection audit_logs into an append-only collection.
service cloud.firestore {
match /databases/{database}/documents/ {
function permission_granted() {
return request.auth != null; // Change this to your logic.
}
match /audit_logs/{log} {
allow update,delete: if false;
allow read, create, list: if permission_granted();
}
}
}
Let's break down the most important pieces.
Function: permission_granted()
function permission_granted() {
return request.auth != null; // Change this to your logic.
}
This one is just a placeholder for however you want to restrict insert new documents or reading existing documents in the collection. In this case it's letting anyone who has signed in using Firebase Auth -> You might want it more restrictive.
It just returns true or false, which we'll use later to actually enforce.
Match: Root collection audit_log
match /audit_logs/{log} {
...
}
This one's simple, we're just matching against any requests regarding for the root collect called audit_logs. The document Id in questions is made available via $(log) due to the {log} piece.
Blocking any modification that is append-only
allow update,delete: if false;
The 2 write methods that are not append-only are update and delete, so here we just universally disallow any mobile & web SDK from performing them.
Allow the rest
allow read, create, list: if permission_granted();
Lastly, using the permission_granted function we set up earlier, we allow reading, listing, and creating new documents in the collection.

How to validate a related entity still exists in database, on form submit?

I have an entity Activity, with a CRUD in one part of my app.
In another part of the app, I have a form representing a UserData entity, with a #ManyToOne relation to Activity.
When submitting this form, I want to validate that chosen Activity still exists in database (because of CRUD, it could be deleted between the form loading and the form submit).
I dug a lot into symfony core files, and found that this validation is done the Form component, in viewToNorm() method which throw a TransformationFailedException, which is then silenced by the submit() method :
public function submit($submittedData, $clearMissing = true)
{
try {
[...]
// Normalize data to unified representation
$normData = $this->viewToNorm($viewData);
[...]
} catch (TransformationFailedException $e) {
$this->transformationFailure = $e;
// If $viewData was not yet set, set it to $submittedData so that
// the erroneous data is accessible on the form.
// Forms that inherit data never set any data, because the getters
// forward to the parent form's getters anyway.
if (null === $viewData && !$this->config->getInheritData()) {
$viewData = $submittedData;
}
}
}
I tried to build a custom Constraint with a custom Validator, but it doesn't work, because in case of Transformation failure, Symfony reset the data to it's original form value, so my validator receive a NULL value instead of the deleted entity.
I could build a DataTransformer and catch this exception manually, but DataTransformer are not meant to perform validation.
Is there any other way to check a relation still exists in database and at the end, customize the message displayed in FormError ?

CRUD Delete salesforce security issue

when received a scan results how salesforce-Checkmarx will do code scan, so my question is, as per some blogs and salesforce standard documentation I checked delete permission before deleting a record, but still I am getting CURD Delete Issue, (security submission done 2 time, got same results). I am specifying a my code
if(Schema.SobjectType.Tracking_path__c.isdeletable())
{
Delete tpList;
}
else
{
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.FATAL, system.label.delete_access));
return null;
}
Got the fix for this issue. If you change your code like below you will get it fixed in review report.
List<CustomObject__c> listOfCustomObject = [Select Fields from CustomObject__c];
if(CustomObject__c.sObjectType.getDescribe().isDeletable()){
delete listOfCustomObject;
}

Securing system-generated nodes in firebase

I've been going through the rules guide but haven't found an answer to this.
App users are able to submit "scores" of different types, which are then processed in JS and written to a "ranking" node. I have it set up so that every time a new score is submitted, the rankings are automatically recalculated and a new child is written if the user doesn't exist or updated if the user exists.
My question is how to secure this "ranking" node. Everyone should be able to read it, nobody except the system should be able to write it. This would prevent people from submitting their own rankings and aggregate scores.
EDIT
This is the operation:
Ref.child('rankings').child(uid).once('value', function (snapshot) {
if (snapshot.exists()) {
snapshot.ref().update(user); //user object created upstream
} else {
var payload = {};
payload[uid] = user;
snapshot.ref().parent().update(payload);
}
});
How would I add custom authentication to this call? Also, since I'm using AngularJS, is there any way to hide this custom token or would I have to route it through a backend server?
The key part of your problem definition is:
only the system should be able to write it.
This requires that you are able to recognize "the system" in your security rules. Since Firebase security is user-based, you'll have to make your "system" into a user. You can do this by either recording the uid from a regular user account or by minting a custom token for your "system".
Once you have that, the security for your ranking node becomes:
".read": true,
".write": "auth.uid == 'thesystem'"
In the above I assume you mint a custom token and specify thesystem as the uid.

Update user's email in Orchard

I want to allow users to update their email, so I have controller :
[HttpPost]
public ActionResult ChangeEmail(string newEmail) {
IUser user = _services.WorkContext.CurrentUser;
if (!user.Is<UserPart>())
throw new InvalidCastException();
var userRecord = user.As<UserPart>().Record;
userRecord.Email = newEmail;
return null;
}
Everything builds and runs OK except that the database doesn't update new email.
What should I do ?
Thanks all !
I think your problem is that you are trying to update the Record directly instead of setting the value of the Part and letting Orchard save your changes:
user.As<UserPart>().Email = newEmail;
Your change will be automatically committed to the db at the end of the request.
As a side note the reason your changes are not saving is that when you update a record you need explicitly update it using an injected repository e.g. _userRepository.Update(user.Record) where _userRepository is an injected IRepository<UserPartRecord>, but just updating the part is the way to go.

Resources