I have a form in Symfony2 where an Admin have to write the username of another user.
Is it possible to check before to send the form, if the username exist in my database? I use doctrine.
Thanks!
You could write a custom constraint, which is injected with your Entity Manager and checks if the username exists. See the documentation for creating a custom constraint here.
Another option would be to write a data transformer which converts a username string into a User object, which should ensure that user existed throwing a TransformationFailedException if she doesn't. This might be a bit easier because the example in the docs already creates the transformer as a service and shows you how to inject the entity manager.
Also, depending on how many users you have in your app, you could make the username option an entity choice type, and allow symfony to create a drop down with all of your users already in there.
EDIT:
Sorry, I missed the part about checking before you submit the form. The ideas above are still how you could implement on the server, but for the first two options you would need to use an Ajax request to test if the username was valid.
Related
I'm working on building an API backend with Symfony3 and have a question about how to apply field level permissions to the PUT endpoint for updating an object (User in this example).
My User entity has multiple fields, firstName, lastName, username, etc.
If a PUT request is sent to the /users/{userId} endpoint, I deserialize the request JSON into an array, pass the array (and the User fetched from the database) into a normalizer which applies the request data to the User properties.
I would like an ADMIN to be able to update all fields, but the user themselves to only be able to update their first and last names.
So somewhere in my code I need to check before I apply the updates to the User object, e.g. if the username field is present in the PUT request, I need to check if the requesting user is an admin before applying that update to the user object.
Injecting security into the normalizer seems like an obvious solution, but feels like security should not be a concern of the normalizer.
I could check the permissions after deserializing the request, and before passing to the normalizer, and then just remove fields from the array if the user does not have access, e.g. if not admin remove [username] from array.
Looking for thoughts/suggestions on the right way to accomplish this....
Thanks!
Wanted to post some feedback I got in #symfony IRC:
I would not have the normalizer write into the user. I'd have the
normalizer generate a DTO, which you would then validate given the
permissions of the target user and user taking the action.
If that validator fails, throw the whole thing out and return a
permission denied error, otherwise apply the DTO to the user and
persist it.
the "validator" could be a form (build a form with acceptable to
modify fields given active and target user; form is not valid if there
are extra fields submitted). Or it could be a security voter, or your
own custom mechanism.
I'm trying to implement a very simple login form with Zend framework; however I'm having trouble in understanding how it works.
I have my HTML form with a username field, password and submit elements. I don't know how to validate the username and password.
How do I do this without using Zend Form?
When a browser posts the completed form to the server you can obtain the posted values with your controller like this;
$username = $this->params()->fromPost('username');
$password = $this->params()->fromPost('password');
It's then down to you to pass these values to whatever authentication mechanism you want to use. For example you could perform a simple database lookup against your user table.
However, life is not simple. You need to think about security. Validating and filtering the values passed from the form, hashing passwords, etc.
You also need to think about how to handle an invalid login, such as re-rendering the form with extra display explaining the failure. Zend\Form can help you with some of these issues.
I would start my taking a look the zfcUser Module, which can be found here;
https://github.com/ZF-Commons/ZfcUser
I have a question regarding Domain Driven Design. Let's imagine a simple scenario.
I have an Entity called "User" that has some properties. One of these properties is "date_created", "date_modified" and "last_login_ip".
Let's say we have a form that creates a user and if the create is successful, it authenticates him.
The controller gets the POST data
Sends the post data to a UsersService via the method "createAndAuthenticateUser"
The service receives the data, validates it (doing it here and NOT in the entity because the validation is tied to repositories, such as to validate if the email already exists, etc).
If the validation is OK, it creates a new Entity, assigns the data to it and then sends the entity to the repository to save it. The repository then saves this user in a datasource.
So far so good. The problem here is that, the date_created/date_modified/last_login_ip have to be set in this service method.
What if I want to set the date_modified ANYTIME when the user object is updated (for instance,at login I want to update the date_modified, at user update i want it again, at user creation I want it again.
Logically, my own answer would be to put this in the repository like...
(meta code here sort of, the syntax doesn't matter)
function save($User) {
if (!$User->id) $User->date_created = 'YYYY-MM-DD HH:II:SS';
$User->date_modified = 'YYYY-MM-DD HH:II:SS';
$DataSource->Save($User);
return $User;
}
However, from what I've been reading, the repository should always just map data between the caller and the datasource (and the reverse) and that's it. It should never SET data or anything like that.
Of course, you could tell me this is a behavior, so I could have a behavior that says $User->markAsUpdated() which would just set the date_modified property. But again, this means that this method must be called from more than one place, instead of having a centralized place to do it. I don't see the benefit of NOT having this code in the repository.
Any ideas?
If the concept of last login ip is actually central to your user for some reason, then it's valid to update the user on login. The fact that you're expressing concern about performing that update to save the last login IP implies that it's not really a user concept, but a security, audit, or otherwise-external-to-user concept.
As for setting the modify and create dates, I'd make the same argument. If it's a requirement of the system that the user both maintain and expose that information, then create a private method on the user that each public method calls when it modifies the state, which will set the modify date. If it's not, then you pretty much have two options - either create an auditing service that is notified of the update and keeps its own audit record, or have the repository set the fields when it updates the record.
So I have a User model and when someone goes to create a user, I want the username field to turn green if it isn't a duplicate username in the DB and red otherwise stating that duplicate usernames are not allowed. Is there a way to do this with the framework or does this have to be done from scratch?
I imagine the easiest route would be to create a validation function on the user model which looks it up and returns true or false.
You can then use the usual and well documented methods of setting up a model-form with AJAX validation, and specify username must pass your new validation rule.
If you need more assistance edit your question to give some sense of how far you've get with this, level of knowledge currently and some code if there's something breaking.
How can I add user register form to node create form in Drupal? There is a module http://drupal.org/project/inline_registration , but it has some bugs. I think I saw alternative one, but I cant find it now.
Beware the many security problems possible when giving essentially anonymous users access to node creation. That said, here are some thoughts.
If you can live without having the form registration on the same page, a much easier solution would be to redirect the user to the node create form after successful login. This amounts to perhaps just one line of code (more if you only want to redirect on certain conditions - e.g. the user registers for a certain type of account). That way you can use the built-in validation and submit handlers of the user module.
If you must have both on the same page, you could use hook_form_FORM_ID_alter, and output the user registration form fields if $form['#node']->nid isn't set. Be sure to validate the input as well.