cakephp avoid logged in users to access other user's account - cakephp

I'm developing a web with CakePHP 1.3.7. Everything is going fine and I love it, but I just came accross a problem (probably because of my lack of knowledge) that I can't figure out how to fix.
This is my problem:
In the website, there's the typical 'manage my account' area, where users can only access when they're logged in. In this area, there's a link that calls to an action in the same 'users' controller called 'edit_items'. So when a user goes to edit_items, the action receives as a parameter the user's id (something like domain.com/users/edit_items/45, where 45 is the user's id), and shows the information in a form. The problem comes if I go directly to the address bar of the browser and change that 45 for any other user's Id, then the information of that other user is also shown, even if that user is not logged in. This is obviously a big security issue.
I've been trying to avoid passing the user's id as a parameter and getting it from the Auth component (which I'm using) with $this->Auth->User('id'). For whatever reason, I can read the logged user's info into the form fine, but when I try to save the changes on the form, I get an error as if the save action had failed, and I have no clue why.
Is there any other way to avoid my problem? Or to figure out why the save is returning an error?
Thanks!
EDIT
SO the problem comes from the validation, here's the deal: when the user fills out the form to create a new item, there are certain fields, some of them with validation rules applied. However, when the user goes back to edit the item, not all the fields are editable, only some. Is it possible that, since some fields that required validation when creating the item are not available when editing, that causes the error? How can avoid that? Can I change the validation rules only for the edit action?
Example of what's happening: when creating an item,one of the fields is item_name, which has some validation applied to it. When editing the item, its name can not be changed, so it's not shown in the edit form. I believe this what may be causing the error, maybe because the item_name is missing?

You are turned on the right direction - passing user_id on the url is a bad idea when the users need to edit their own details.
You can use following: when saving your form before the actual save you can pass the user_id to the posted data. Something like this:
if (!empty($this->data)) {
$this->data['User']['id'] = $this->Auth->user('id');
... //Some extra stuff
if ($this->User->save($this->data)) {
... //success
} else {
... //error
}
}
This way the logged user will override it's own record always. Check if you have some validation rules in your model which give you this error.

Related

Is there a way to perform react-hook-form validation without showing errors?

I want to be able to validate the entire form and get the validation result, but I want to do it 'silently'(i.e without making my fields go red). I know that formContext.trigger exists, but that doesn't seem to have a softer setting. I don't want to show errors to the user, I just want to check if what they have got so far is valid. Is this possible with react hook form?
Context:
I'm using 'onChange' mode for my form
I need to do this because as a user fills my form in, which is for a pricing page, I want to send requests to get the pricing information which changes based on the form data. I don't want to send a pricing request if the form isn't valid, but I don't want to trigger full validation and make the fields go red when the user hasn't done anything wrong, they're just filling the form out in order.

How to save a recordset without overwritting existing records with Cakephp 3

Is there an easy way to save a recordset, i mean multiple records, but only the "new ones"?
I have a table users and a users form in the view. First field you must enter is passport number, so if user already exists in database the rest of the form will be auto completed and disabled to prevent changes but if passport dont exist then you have to enter all data. As anyone can change those existing users data controls from the browser even if they are disabled, i want to make sure only new records are saved in database. First of all i thought i could find again in database and delete existing users from recordset before save, but i wonder if there is a more elegant approach.
Ty in advance.
I write this here, cause comments are too short:
Thank you for your answer, André. I'm sorry if i didnt explain perfectly, but the form is done by disabling all controls except passport and if passport dont exist (i check it on passport focusout) then the rest of controls are set to enabled. I mean, that is already done. The question was only about the saving.
The validation method you talk about, well i'm actually validating all the controls in the form and i must disable the 'unique' rule so a user can link an existing user to the current bill, otherwise it will fail validation on submit and it wont allow the user to proceed (i did this because it happened to me when testing). The actual setting is much more complicated: the form belongs to a model (bills) which is associated with 4 other models and 2 of those relationships are many to many, bills_users and bills_clients, where users are the persons who do the job and clients pay for it, but I was trying to make the question easier. Anyway, what I am looking for is, in fact, some kind of saving setting which I can't find. In documentation I found "When converting belongsToMany data, you can disable the new entity creation, by using the onlyIds option. When enabled, this option restricts belongsToMany marshalling to only use the _ids key and ignore all other data." The first half of the sentence was promising, but the explanation says different, and I actually tried it without success.
First:
Is there an easy way to save a recordset, i mean multiple records, but only the "new ones"?
Yes there is you can validate it in model, something like this:
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique('passportNumber'));
return $rules;
}
This will prevent to save a duplicate passport number register, but you can different.
I have a table users and a users form in the view. First field you must enter is passport number, so if user already exists in database the rest of the form will be auto completed and disabled to prevent changes but if passport dont exist then you have to enter all data.
There is two different ways to do this:
First you have your form, you develop an ajax function when you fill the first field (passport number) this ajax function do a request to your controller to search for a passport with that number if find something get data and fill others fields and turn them just readable, else just nothing and let user fill the fields by himself
second add a step-by-step where you first do a form to try find by pass number, user fill this only field with a number then submit, on submit this search for a record, if find fill the entire next step fields, else the next step will be the rest of form with the fields to be filled.
This may help you too: https://book.cakephp.org/3.0/en/orm/validation.html
Tell me how you decided to do :)

CakePHP pre-filling form data doesn't seem to work

Here's what I am trying to accomplish:
A user fills out a form, saves a record. At some later date they wish to "clone" this record, but may want to make a few tweaks. This "clone" functionality should direct them to a form that is pre-filled with the previous record's data so that they can review it, edit as needed, and submit it as a new record.
What I'm trying:
I've modified my add() function to accept a parameters:
function add($cloneid = NULL)
Then created a Clone link that sends them to siteurl/model/add/id_to_clone
Then, I get the data from that model:
$clone_source = $this->Model->findById($cloneid);
$this->data['Model']['field1'] = $clone_source['Model']['field1'];
and so on. Based on Google searching and other posts, this should work. But what actually happens is that upon clicking the 'Clone' link, the user is directed and the form submits itself immediately (failing to save the record, since it fails validation) and the user never actually sees the form.
What am I doing wrong? (Also I should note, there are relational models present, but I don't think this should be the cause of any problems...I hope).
Forms are pre-populated using the $this->request->data array.
In order for your form to be populated you will need to set some data to the request.
So you'll be better off with the following.
$this->request->data = $this->Model->findById($id);

Redirect to desired page on data validation failure

In normal scenario user enters details into form fields and submits data. On submission model validates the data and if validation fails user is redirected to same page with error notifications.
I have a particular scenario in which if the validation fails user should be redirected to a specified page. I DONT want the user be redirected to the same page from where he posted the data.
I went through the cake documentation. But couldnt find anything that mentions a redirect on data validation failure. It can be achieved if im using validating from controller. But here im validating using rules in model only.
Will it be possible?
By default, if data validation fails, the user is not 'redirected' anywhere. Cake displays the same view, without any redirecting. The view always shows validation errors, if they exist. So, of course the first time you load the form, there are no errors, but after submitting incorrect data, there are errors. But it's the exact same view both times, and no redirection is used.
To fix your problem, modifying the example here: http://book.cakephp.org/2.0/en/models/saving-your-data.html you should be able to do something like:
// If the form data can be validated and saved...
if ($this->Recipe->save($this->request->data)) {
$this->Session->setFlash("Recipe Saved!");
$this->redirect('/success-page');
} else {
$this->Session->setFlash("We Have Errors!");
$this->redirect('/my-custom-error-page'); // REDIRECT TO YOUR PAGE HERE
}
Is there any reason that won't work for you?

Display Alert box through the trigger - salesforce

Is it possible to display an alert message (not error message) through a trigger? I have written a trigger that checks for duplicate accounts in the system. The trigger at the moment gives an error message to the user telling that there is a duplicate account. But, if the user changes the value of a field "Is record near to duplicate?" to YES, the trigger allows the user to save the record.
But, I want to display the error message in an alert pop up box like "Account with this Name exists,are you sure you want to continue" and then user clicks Yes and the record gets created. Any thoughts on how I can do this. My code is below:
for(Account account: System.Trigger.New)
{
if(accountMap.containsKey(account.Physical_Street__c)==accountMap2.containsKey(account.Phone))
if(accountMap.containsKey(account.Physical_Street__c)==accountMap3.containsKey(account.Name))
if(account.Is_record_near_to_duplicate__c.equals('No'))
{
account.addError('Account with this Name,Street and Phone Number already exists. If you still wish to create the agency change the value of field "Is Record Near To Duplicate" to YES');
}
}
If you really need an alert box then you could create a custom javascript button that uses the ajax toolkit to replace the standard save button.
However, as Baxter said you are getting pretty far from standard salesforce look and feel. I would recommend instead to add an error on the checkbox field instead of the object so it is clear to the user what they need to select.
if(account.Is_record_near_to_duplicate__c.equals('No'))
{
account.Is_record_near_to_duplicate__c.addError('Agency with this Name, Physical Street and Phone Number already exists. If you still wish to create the agency change the value of field "Is Record Near To Duplicate" to YES');
}
Unless you write a custom visualforce page that processes the error message and then displays it as a popup there's no way to do this.
If you wanted the alert to modify the data you may look at using the ajax api to set the Is_record_near_to_duplicate__c field to 'Yes' but either way you're getting pretty far from the standard functionality and interface with this.
It is not straight forward to implement a pop-up alert for a trigger error, and pop-ups went out-of-fashion a long time ago. If you are going through the hassle, you might as well implement a custom soultion on a VF page.
Throw a custom exception(for dupe accounts) from the trigger, and catch it in your controller. When you catch this exception, you can dynamically displayed section on the page which asks the user to confirm his/her action. When the user confirms the action, the page will do the rest.
Hope this makes sense!
Anup

Resources