Our account form allows users to edit their usernames.  Actually, it's the
email address, but because we also have them login with their email, if
effectively the username.

One thing I've noticed for some time is that when editing a user, you want
to use the object from the database, and not the user object from your
session (e.g. in Security component's current token).  Hypothetically, if
uniqueness validation fails after binding request data, and you redisplay
the form with its bad username... anything else on the page that tries to
reference the current security user (e.g. the Profiler toolbar) will be
pointing to the same object, that Form::bind() just tainted.  Because
Security component likes to carry a serialized User object, which is
unmanaged by Doctrine, I'm safe if I fetch a freshly managed User from the
database for my account form.  But I believe there was something in the
works that would refresh the serialized User object from the database on
each request.  Lukas told me this already exists, but I don't see how it
could be functioning right now.  If the User object in the security token
was a managed Doctrine object, both it and the result from a fresh DB query
would surely reference the same object (and my "solution" above wouldn't
have worked).  Doctrine is very strict about ensuring only a single
reference exists unique entities/documents.

But I digress.  The real caveat is that after an account form is
successfully submitted, and a user changes their username, the token has to
be updated.  I can't just call setUser() to update its user, since the token
is immutable.  I could cheat and dive into the token's User object and
update the username myself.  The other alternative, which the FOS UserBundle
does, is create a new authenticated token with my freshly-updated and
Doctrine-managed User object.

And that's where SwitchUserListener comes in.  Switching users depends on
creating its own UsernamePasswordToken with whatever User I want to
impersonate, and then that User gets a special SwitchUserRole that
encapsulates my original (admin) User object.  If we utilize the "reset
token after updating username" behavior, we ruin the SwitchUserListener's
ability to "exit" out of an impersonation.  I suppose one solution here is
to check for the SwitchUserRole and re-inject it if necessary?

I realize AccountInterface does not dictate a field for a unique identifier,
and internally Security component does its account-loading by username (a
possibly change-able field for a fair number of projects).  For anyone
working with Doctrine, an ID will be a required field - so ideally I would
expect an account's ID to be the preferred field for refreshing
token-contained User objects (assuming that feature does exist, as Lukas
said :).

--

I just wanted to throw these topics out there for discussion, as I think it
relates to something most all developers are bound to experience at some
point while working with User objects.  The SwitchUserListener business less
so, as that's admittedly an edge case for most.

-- 
jeremy mikola

-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-devs?hl=en

Reply via email to