Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create maker for symfony casts reset password bundle #567

Merged
merged 1 commit into from
Apr 5, 2020

Conversation

jrushlow
Copy link
Collaborator

@jrushlow jrushlow commented Mar 27, 2020

Adds a make:reset-password maker to create the classes, entities, and twig templates required by Symfony Casts Reset Password Bundle. This complements the bundle by doing the leg work to provide a true out-of-the-box solution for handling forgotten passwords in traditional Symfony applications.

@jrushlow jrushlow force-pushed the feature/reset-password-bundle branch 2 times, most recently from 3649444 to bb9ffce Compare March 28, 2020 13:15
@jrushlow jrushlow force-pushed the feature/reset-password-bundle branch from 49dd1d8 to 795bab5 Compare March 29, 2020 16:37
@@ -167,6 +167,15 @@ public static function validateDoctrineFieldName(string $name, ManagerRegistry $
return $name;
}

public static function validateEmailAddress(string $email): string
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method name could be as is or just emailAddress. As a whole, the class has functions like validate.. and notBlank. Although Validator::class naming conventions are outside the scope of this PR, may be worth considering which name would be appropriate for this method.

->addArgument('password-setter')
;

$io->section('- Email Templates -');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My initial instinct is that this is cool :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, off the top of my head, all of these args are "required". Do we need InputArgument::REQUIRED for the last 4 even though the interactive security guesser sort of "enforces" this..

throw new RuntimeCommandException(sprintf('The file "%s" does not exist. This command needs that file to accurately build the reset password config.', $path));
}

$manipulator = new YamlSourceManipulator($this->fileManager->getFileContents($path));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a "funny" situation. We sorta don't want to "update" this file (and leave the old comments). We probably want to completely override the file contents with the new ones. Specifically, we don't want our "Replace symfonycasts.reset_password.fake_request_repository with the full..." text to be in this file when we finish.

Perhaps we could check if request_password_repository: symfonycasts.reset_password.fake_request_repository is the only config in that file. And:

A) If it is, use the normal Yaml file to completely dump new contents
B) If not for some reasons, then use the manipulator to update the file more carefully

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done,

  1. if the config file doesn't exist, we assume dev is using a customized config. Remind dev to set correct repository and move on.

  2. if the config exists with only 1 key, assume config was created by flex; create a new config file.

  3. if config exists with more than 1 key, assume the dev modified the config before running maker. Replace repository value and preserve everything else.

{% block title %}Password Reset Email Sent{% endblock %}

{% block body %}
<p>An email has been sent that contains a link you can click to reset your password. This link will expire in {{ tokenLifetime|date('g') }} hour.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... a link that you can click...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I guess we should say "hour(s)" on the end. I don't think we should try to introduce the translator so that we can "translate" hour versus hours. Or we could add the proper logic, though it's a little ugly:

{{ tokenLifetime|date('g') }} hour{{ tokenLifetime|date('g') != 1 ? 's' }} hour

If we did that, I might also pass tokenLifetimeHours into the template for convenience.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with hours(s).

From a technical stand point, using the proper logic makes sense. But, I suspect most people will be changing the format of this template to suite their needs (match UI/business themes, etc..). So perhaps we would introduce the "proper logic" at a later time if it is requested..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@jrushlow jrushlow force-pushed the feature/reset-password-bundle branch 2 times, most recently from 4aa1446 to 43b6070 Compare April 3, 2020 13:36
'repository_class_name' => $repositoryClassNameDetails->getFullName(),
'user_full_class_name' => $userClassNameDetails->getFullName(),
]
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's save this for later (cause I think it will take some work), but:

It would be ideal if we could use EntityClassGenerator to generate the entity and repository classes. That's our centralized entry point for creating these classes and making sure they all look uniform. We would use that class and then use the ClassSourceManipulator to add in our custom code (that's the tricky part - writing PHP Parser code to add methods, etc take a bit of work to get right).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made a note on the board to implement in the near future..

class User implements UserInterface
{

private $email;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No setter for this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

off the top of my head, the bundle doesn't care about the setter, just that it is able to get the email, same holds true for guesser.

'app_home',
])
->addExtraDependencies('security-bundle')
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeResetPassword'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be a functional test inside the skeleton. For simplicity, it could just go to /reset-password and check for a 200 status code. The gold standard would be to actually fill out the form, capture the reset password link somehow, then go to THAT URL and reset the password :). We could do that "gold standard" never or later ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

I added a test to check /reset-password and grab the status. I need to add tests for the other routes as well before the merge.

Ultimately I would like to get to the "gold standard." Perhaps after the merge and before the 1.x bundle release..

@jrushlow
Copy link
Collaborator Author

jrushlow commented Apr 3, 2020

TODO - I keep deleting tests/tmp/.gitignore locally between tests. Storm auto magically adds that change on ctrl+k, not to self: remember to put that back when all is said and done....

@jrushlow jrushlow force-pushed the feature/reset-password-bundle branch from 67f2e2b to bde2158 Compare April 4, 2020 21:18
@jrushlow jrushlow changed the title WIP - reset password create maker for symfony casts reset password bundle Apr 5, 2020
@jrushlow jrushlow marked this pull request as ready for review April 5, 2020 03:25
@weaverryan weaverryan force-pushed the feature/reset-password-bundle branch from aed2a50 to bb1438b Compare April 5, 2020 10:49
@weaverryan
Copy link
Member

Merged! A HUGE thanks to @jrushlow for his MASSIVE work on this feature and also @romaricdrigon who kick-started this a long time ago and kept pushing on it. I'm super happy to not only have this feature in Maker, but for it to be really, really nice. ❤️

@weaverryan weaverryan closed this in 01c4dd1 Apr 5, 2020
@weaverryan weaverryan merged commit 01c4dd1 into symfony:master Apr 5, 2020
@jrushlow jrushlow deleted the feature/reset-password-bundle branch April 16, 2020 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants