FOS Disable Single Password Request Functionality - symfony

I am using the FOS user bundle in Symfony and I really dont like the fact that a user can only request their password 1 time in 24 hours. Is there any way to disable this feature to enable the user the ability to request their password multiple times. I mean what happens if their reset email never reaches their inbox and they cannot reset the pw again, whats the best way to handle this.
Thanks.

In FOSUserBundle configuration exists parameter token_ttl which have default value 86400. This is a number of seconds and It is used to determine the time to live for the token and the time the user must wait before retrying the request.
You can try to set 0 or false, it should work.
fos_user:
resetting:
token_ttl: 0

I found an issue with the below changes to the config.yml
app/config/config.yml
fos_user:
resetting:
token_ttl: 0
This will allow the user to request a new password as many times as they wish (no 24 hour limit) however due to the zero 'time to live' of the token it will automatically reroute you from
/resetting/reset/{token}
to
resetting/request
So the user will never be actually given the option to change their password.
This was tested on Symfony 2.6

Long ago, you could just configure this in config.yml
fos_user:
resetting:
token_ttl: 0
but in recent versions, since the token_ttl is both the retry time and the lifetime of the token, if you set it to 0, as soon as you create it, it expires.
You can follow the issue in Github
If you need it fixed ASAP, as a hacky workaround, you can implement the resetAction() by copy-pasting vendor/friendsofsymfony/user-bundle/Controller/RegistrationController.php in your AppBundle (or whatever bundle, doesn't really matter) and make the router point to your overriden function, like this (routing.yml):
fos_user_resetting_reset:
path: /resetting/reset/{token}
defaults: {_controller: AcmeUserBundle:Resetting:reset }
Now, in your resetAction() method you can comment out this lines:
// if (null !== $event->getResponse()) {
// return $event->getResponse();
// }
There are less hacky ways, of course, like creating your own listener but... this is how I quickly and dirtily did it, since I was in a hurry and I already had the resetAction overriden.

Related

How to achieve an authentication level that allows me to pass "Full authentication is required to access this resource"

I am trying to debug a Resque setup in an (inherited) app, and so I found that there is a route for resque at /hidden/resque that would be nifty to access, but I am unable to access the route. I am wondering what I need to do ... When I try to access that route I get a HTTP 500 due to this error being thrown:
Symfony\Component\Security\Core\Exception\InsufficientAuthenticationException: Full authentication is required to access this resource.
I have tried accessing it both as a web page (after authenticating as an admin role on a different route) and using curl -H 'Authorization: Basic 9339034147964aebec6716c0110311d1' 'https://web.mysite/hidden/resque' -v. No go.
So what constitues "full authentication"? I am already logged in as an admin user on one of the other routes. Would I need to add anything more to the below config? This has not been setup by me, so I would not know if it ever worked.
app/config/routing.yml
ResqueBundle:
resource: "#ResqueBundle/Resources/config/routing.xml"
prefix: /hidden/resque
app/config/security.yml
access_control:
- { path: ^/hidden, roles: ROLE_ADMIN }
According to the docs:
IS_AUTHENTICATED_FULLY: This is similar to IS_AUTHENTICATED_REMEMBERED, but stronger. Users who are logged in only because of a "remember me cookie" will have IS_AUTHENTICATED_REMEMBERED but will not have IS_AUTHENTICATED_FULLY.
How can I be "more logged in" than using a cookie? Should I send a basic auth header with username and password base64 encoded?
If you ask for full authentication.
I.E:
/**
* Requiring IS_AUTHENTICATED_FULLY
*
* #IsGranted("IS_AUTHENTICATED_FULLY", message="Nope, no access")
*/
Then when you are logging in with an user, your Authorization Checker must have granted you the IS_AUTHENTICATED_FULLY status in order to have access.
As explained in the docs:
IS_AUTHENTICATED_FULLY: This is similar to IS_AUTHENTICATED_REMEMBERED, but stronger. Users who are logged in only because of a "remember me cookie" will have IS_AUTHENTICATED_REMEMBERED but will not have IS_AUTHENTICATED_FULLY.
You will be completely Authenticated if you manually log in, and not via a cookie. If you are using a command that remembers your credentials, that might be the issue.
Check Doc nº3 to see whether your actual way of entering that route falls inside the IS_REMEMBERED status. Even maybe you end up prefering using the less restrictive IS_AUTHENTICATED_REMEMBERED
Check the different documentations here:
https://symfony.com/doc/3.4/security.html#checking-to-see-if-a-user-is-logged-in-is-authenticated-fully
https://symfony.com/doc/3.4/security.html#learn-more
https://symfony.com/doc/3.4/security/remember_me.html
https://symfony.com/doc/3.4/components/security/authorization.html#authorization-checker
https://github.com/symfony/symfony/blob/3.4/src/Symfony/Component/Security/Core/Authorization/AuthorizationChecker.php

Is there a proper way to check is a token is already used using FosUserBundle?

I'm using the FosUserBundle in order to reset a password by sending an e-mail and a confirmation token.
I configure the retry_ttl and token_ttl in config.yml to set the duration of the token.
fos_user:
...
resetting:
retry_ttl: 60 # Value in seconds, logic will use as hours
token_ttl: 86400
These parameters work well. But i want to add a paramter that check if a token is already used or not. I mean if the user has already clicked on the confirm e-mail, the token will be available one and only one time. Then it will be destroyed.
How may I process ?
Thank you for your replies.
It's already the case with fos user bundle...
Confirmation token + password requested at fields are set to null when the reset of the password is completely done.
PS: copy/pasted comment as an answer for future visibility

FOSUserBundle sending bad confirmation links

1 or 2% of users registering seem to get no confirmation email or they get a bad token appended to the confirmation link in the email. I can't determine why or where this wrong token comes from. It doesn't look like a truncated version of the correct one. It's totally different. Clicking it yields a 404 response.
I am not overriding the RegistrationController.
Could it be the mailer settings?
swiftmailer:
~
spool: { type: memory }
The only other changes I've made were in validation of a few custom fields.
registration:
form:
type: acme_user_registration
validation_groups: [MyRegistration]
confirmation:
enabled: true
Any ideas what's going on?
Thanks.
I found a problem while viewing a confirmation email in outlook.com. I turns out that outlook.com is 'previewing' the link to show some expanded metadata in the email message. This has the side effect of enabling the user and deleting the token. Once the user actually clicks the link, they get a token not found error, but their account is enabled.

Behat step definition sometimes executed, sometimes not

I have the following scenario's:
#wip
Scenario: Attempt to get account information of an activator without credentials
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
When I send a GET request to "/activators/1"
Then the response code should be 401
#wip
Scenario: Attempt to get account information of another activator then myself
Given an activator with e-mail "dietervds#email.com" and password "testpassword" already exists
And an activator with e-mail "eviltwin#email.com" and password "testpassword" already exists
And I am authenticating as "eviltwin#email.com" with "testpassword" password
When I send a GET request to "/activators/1"
Then the response code should be 401
The database is dropped and re-created from schema before every scenario.
The step 'given an activator with ...' inserts a new user into the database.
However! It doesn't always do that for both users.
This is the step implementation:
/**
* #Given /^an activator with e-mail "([^"]*)" and password "([^"]*)" already exists$/
*/
public function anActivatorWithEMailAndPasswordAlreadyExists($email, $password)
{
$activatorManager = $this->getContainer()->get('am.manager.activator');
#$logger = $this->getContainer()->get('logger');
#$logger->debug("Email: $email, password: $password");
$activator = $activatorManager->createActivator($email, $password);
$activatorManager->save($activator);
}
Now the weird thing:
In that last step, I should be getting two inserts: one for dietervds, one of eviltwin.
I get the two inserts when I:
Run only one scenario
Output something in logging (creating the 'logger' doesn't help, I need to output something. What I output doesn't have to be dynamic, it can just be a fixed string)
I only get one insert (for dietervds) when I:
Run the two scenarios together
Or when I don't output any logging in the step implementation
I am completely baffled by this.
Is there something obvious that's missing? Might it be some sort of caching problem in the step definitions? (the logging might change the signature or something, not sure)
Any feedback is welcome :-)
Cheers!
Dieter
Does this step def do an ajax call?
When I send a GET request to "/activators/1"
if it does you could try adding some wait time in there to give your dom time to load the result
Whens to Thens work best when you are submitting forms with press or following links or doing go to's to redirect the browser which initiates a full request response cycle that triggers the robot to wait for a new dom to load.
With ajax that doesn't happen exactly the same way.
If you aren't doing ajax I recommend you just use the built in step defs of
When I follow "/activators/1" instead
There is a way to prevent caching in your yaml config. Here is an example config we use for chrome but it should work the same for any browser driver
default:
extensions:
Behat\MinkExtension\Extension:
base_url: https://yurwebsite.com
goutte: ~
browser_name: "googlechrome"
selenium2:
capabilities: { "browser": "googlechrome", "version": "23", "applicationCacheEnabled": false }
The last boolean param does the trick for our browser caching issues

sfDoctrineGuardPlugin - increase session time

I am developing a site using sfDoctrineGuardPlugin and I was wondering if there is a way to increase the time that someone is logged in before they are signed out?
I would like to increase the time that the session is stored when a user is logged in, but is idle, but cannot seem to find the right place in the plugin to increase this.
Thanks
The default configuration for the sfUser class is like this:
user:
class: myUser
param:
timeout: 1800
logging: %SF_LOGGING_ENABLED%
use_flash: true
default_culture: %SF_DEFAULT_CULTURE%
(found in lib/vendor/symfony/lib/config/config/factories.yml).
You can override this in your own application, by adding something like this to your apps/app/config/factories.yml:
user:
class: myUser
param:
timeout: 3600
I expect the timeout to be in seconds.

Resources