Symfony2/DC2/PHP: prevent the user from creating someone elses entity - php

I have the entities Floor and LeaseTerm. Floor can have many LeaseTerms.
In my LeaseTerm CREATE form, I have a hidden floor_id field.
My question is: how can i effectively prevent the user from changing the floor_id field himself and creating LeaseTerms for floors he doesnt own (each floor has it's owner)?

Conceptually the 'how' is to validate the floor_id upon submission, ensuring that the current user owns/has access to the floor. Theoretically even if they do change it, so long as it's still an id they have access to, the operation is probably still valid (if not, additional validations on the submission context would be necessary).
In Symfony 2 as a specific implementation this could be achieved with the logic directly in a controller, or perhaps alternatively with help from a 'Data Transformer' and/or Custom Validator.
Hope this helps.

Related

Complex object validation with Symfony Validator

I have an object (a person) which is being edited (and validated) over several forms:
personal data form
first name
last name
file input for photo upload
account data form
email
publishing form
can publish only if all required fields have been filled
What I need is to have validations that I can use per-form and also for the whole person, e.g the errors would be:
personal data form - “please fill your first name”, …
whole person - “please fill your personal data”, …
If I define validations in Entity, there might still be some rules that are form-only (file upload, password repeat); it seems kinda wrong anyway because I might have different rules for web form and for API. Then again if I define validations in Form classes, then the rules are scattered around, also how can I initiate validation without form submission (which seems a hackish thing to do anyway).
Most elegant solution seems to me a separate validator which I can divide into validation groups and call it per-form and for whole object. How to do that using compound validator so that I can use other validators?
Or is there another way? Thank you.
Symfony verson is 6.

Keeping track of data in multipage form validation through PHP

I am working on a PHP project where the client wants multipage form data submitted. For instance, here is the process the form follows:
Create new entity.
Determine entity type.
Fill in entity-specific fields.
On each page, the form is POSTed to the current page. Validation is performed server-side, and if validation is successful the user is redirected to the next step.
I've determined that, in order to keep track of the user's progress, session data should be used. However, my concern is that, if the user opens two tabs and goes through the form in parallel, how can I keep track of what entity is being processed in each tab? Is this a scenario that can even be handled at all?
There are different 2 approaches.
If a user allowed to fill 2 forms at once, just add an unique identifier to each, and keep track them in the session.
If not - the things become simpler: just keep track of the steps passed and just show a warning in case of the previously passed step submitted.
This is a page flow issue. Do NOT use session to deal with it. You are correct that tabs or new windows would cause you trouble.
I don't really understand the point of this bit:
On each page, the form is POSTed to the current page. Validation is
performed server-side, and if validation is successful the user is
redirected to the next step.
Sounds like a "post-back", but why? POST the data from the page to a controller (or script) that does the necessary ss validation. After validation, deal with the data how you need and determine what the next step should contain. Then send the input form for that next step down in the response. Repeat until you are finished.

User Friendly Registration System

I need to build a registration system which requires the collection of large data (many fields) from the user registering which is then inserted into a couple of tables in a database.
I don't really want to display a very long form to the user for the purposes of better UX.
This system will not run online, it is just a web app to run on the desktop.
I need help, pointers, references, etc on how I can better organize the registration process to make it more user friendly.
This How to encourage a user to fill in long application forms? has been helpful so far
As long as you don't mind requiring your user has Javascript, I would use AJAX. Let's say that you have 50 fields that you can logically combine into 4 different sets - the first may be about the person asking for name, email, etc., while the next set asks for historical information or employment information - like on an application.
Make one form for each set, and then present a new user with the first. When he completes the first page, instead of a "Submit" or "Register" button, use an AJAX call and a "Next" button to get the info and switch to the next page of the form with the next set of fields. You could use the AJAX calls to hold the information in a temp table in your database, and then, once the entire process is complete, you can write it to your member/users table.
You could do like other surveys or checkouts do and add a "title" for each page of the form above the form fields so that as a user moves through registration, they can monitor their own progress.
I'd recommend checking out the Amazon checkout, or really any multi-page survey (you may even be able to set one up yourself on Survey Monkey) to see how a large number of form fields can be broken down logically in a user friendly way.
Hope it helps.
Check out this link: http://www.smashingmagazine.com/2011/05/05/innovative-techniques-to-simplify-signups-and-logins/
It's talking about login- and registration-forms and how to make them more user-friendly. A suggestion which is also included in this article is as follows:
At registration don't ask the user to many questions. Only the basic data like their name for example. Then ask him about more detailed data when the user logs in the first time. This way the registration won't take too long.
Maybe this helps you out :)

Human verification without user action

For a system I'm working on I've got a bit of a problem: I'm messing with one of the basic rules of HTTP and I'm allowing users to post data through a GET request.
Don't get mad at me yet: I've got a reason for this: Users arrive in my application from an external environment and I can't prompt them for any extra input (so all necessary data is in the GET query). They should be able to close the browser window right after it opens and the input should be saved. And no, I can't do this through AJAX, an API or other under-the-hood method.
These requirements kind of rule out captcha, calculations, forms etc. So I'm left with the problem that I really do want some type of verification to prevent bots/crawlers from "accidentally" submitting something.
One of the solutions I am looking into is making a very lightweight landing page that submits itself through javascript onload but it would be the ugliest thing in my application so I'm trying to prevent it. Another is to let the landingpage not do any of the processing but instead use an AJAX-call to do this. This would however mean that older browsers (and many mobile phones) would have to use another solution.
Background: Application written in PHP5.3, built on Yii Framework, 100% cross-browser compatible (this includes pretty much every mobile phone out there).
Some more background: The "exteral environments" I'm talking about vary from e-mail clients to websites. Manipulation of our content at runtime isn't possible.
Update: Here's what I'm going to do: I'm probably going to combine solutions posted here in a fallback mechanism so that a chain of verifications will be attempted:
1. Ajax verification
2. Non-Ajax javascript verification (automatic form submission)
3. Prompt for user input (user has to click a confirm button)
Besides this I'm going to implement a bot trap as descripbed by http://www.kloth.net/internet/bottrap.php
After I'm done with building this I'll update the post if I did anything different.
Hard to understand where you app is and where external environment really are. But one simple bot-removal technique I use is to put an hidden field named 'login' or 'name' and give it an empty value.
Human people will never fill this hidden field, but spam bots are always filling it. So you can discard any request with that field being not empty.
Now you must prevent crawlers and not only spam bots. Never did it, but here are some thoughts. You could add a hidden 'human' hidden input in the form on first mouseMove events (but keyboard-only -- and think about blind people -- users will be considered as robots). So maybe if this field is not there you can launch a javascript 'confirm' where you ask "Confirm that you are a robot or click cancel if you are human".
You can make your anchor link containing a default value that this hidden field values will overwrite in js. Most crawlers will not overwrite the values, especially if you must cancel a confirmation to get the right behavior (and avoid confirmation with mouseMove event for most users).
If you are able to modify the place that your users are coming fro, you could try including a checksum. Calculate some kind of checksum or hash of all the fields in the GET request and add it to the GET request itself (i.e. through javascript, but do it in the place your users are coming from, not where they are landing). Then, in your application, reject all hits with an incorrect checksum.

Best way to track the stages of a form across different controllers - $_GET or routing

I am in a bit of a dilemma about how best to handle the following situation. I have a long registration process on a site, where there are around 10 form sections to fill in. Some of these forms relate specifically to the user and their own personal data, while most of them relate to the user's pets - my current set up handles user specific forms in a User_Controller (e.g via methods like user/profile, user/household etc), and similarly the pet related forms are handled in a Pet_Controller (e.g pet/health). Whether or not all of these methods should be combined into a single Registration_Controller, I'm not sure - I'm open to any advice on that.
Anyway, my main issue is that I want to generate a progress bar which shows how far along in the registration process each user is. As the urls in each form section can potentially be mapping to different controllers, I'm trying to find a clean way to extract which stage a person is at in the overall process. I could just use the query string to pass a stage parameter with each request, e.g user/profile?stage=1. Another way to do it potentially is to use routing - e.g the urls for each section of the form could be set up to be registration/stage/1, registration/stage/2 - then i could just map these urls to the appropriate controller/method behind the scenes.
If this makes any sense at all, does anyone have any advice for me?
I think creating a SignupController is a fine idea. The initial user registration is a distinct process, and ought to be separate from general profile management tasks.
If you've been a good developer and keeping your controllers thin and your models fat, you ought to be able to avoid any code duplication. If you find yourself duplicating, it's probably a good idea to think about refactoring.
As a concrete example, consider your user's email address. Let's say you're pretty strict, and any time a user changes their email address, they have to do a little confirmation-email dance. During signup, you'll want the user to return to the signup process after they click their confirmation link. When an existing user is changing their email address, you'll want them to land somewhere else (like their profile). It's likely that you'll want different content in the body of the confirmation email is each case. Trying to make /user/profile handle both cases is going to start creating a bunch of complexity where the action needs to figure out context and behave accordingly.
The better solution is to decide that signup is it's own mode of interaction, distinct from general profile management. Therefore, it gets its own controller, which shares model and view resources with other controllers.
That's my take, anyway.

Categories