3
votes

I'd like to generate user accounts in Zend Framework 2 with ZfcUser arbitrarily that I could then email to the user with either an activation link or some temporary credentials. I'm not sure if ZfcUser can be extended to do this securely, so I'm looking for help and suggestions.

I need to do this in my application for a letter of recommendation feature. It works by an existing user (someone who registered using ZfcUser the 'normal' way) requesting a letter of recommendation from someone by providing an email address for that person. At that point I would like to generate an account using ZfcUser with that given email and notify the person that someone has requested a letter of recommendation from them and that they should log in and complete it.

I gave some though to a one-time-use link for each letter request but I feel like it would make more sense to create an account for each email and the associated user so that someone who receives multiple request for letters can log in and be presented with all of their requests in a single place. I also think it may be wise to separate these sorts of user accounts into a different users table in my database, or at least append a flag field to my current users table schema.

I should note that I'm also currently using CdliTwoStageSignup in conjunction with ZfcUser. I don't necessarily need to use it for this as well, but it's in the tool bag.

I think the ZfcUser 'state' flag could be useful here but it's not really the tough part of what I'm trying to accomplish.

I've also found another clue as to how I could do this in the ZfcUser wiki on Github.

I'm looking for technical help in accomplishing this using ZfcUser but am definitely open to design ideas or improvements in general.

1
Well you name it: it's certainly possible, but quite complex and not just easy to do. The "state" flag is there, but you could also extend the user-entity. It's all up to you how to do it, but it's not easy to "quickly do it here on SO" ;)Sam
An easier way could be to have separate table which you store these requests with an email. You could then just send an email to the email address and they could register normally. You would be able to get all their requests as they are tied to the same email.Aydin Hassan
Thanks @Sam. I understand there's a few levels to go through here but I'm looking more for suggestions on to how to approach this rather than code for a complete solution. I'll look into extending the user-entity now.dperjar
@AydinHassan that's a possibility - thanks for the suggestion. It might be more practical than what I had in mind. I guess I was thinking of having an account in place so that all the requests would be associated when they were created, but it doesn't really matter in the end I suppose. I'd just have to look through the requests table and find all pending requests when the user gets around to creating an account.dperjar

1 Answers

8
votes

If anyone is looking for how to create a generic user that can be authenticated using ZfcUser it's just a matter of creating a new user, using $bcrypt to turn a plaintext password into a hash and saving it all to your user table. The basics are outlined below:

$newUser = new User();
$newUser->user_id = 'newUserId';
$newUser->email = '[email protected]';
$password = 'newUserPassword'//This is extremely bad form, don't do it. You don't want any passwords hanging out in plaintext.

$bcrypt = new Bcrypt();
$bcrypt->setCost(14); 
$newUser->password = $bcrypt->create($password);
$userTable->saveUser($newUser);

The Bcrypt cost I used here was 14. You can use whatever is appropriate for your application but it would be a good idea to pull your setting from the ZfcUser configuration file. You may also use a different value and Bcrypt will handle it without issue.

I don't suggest creating accounts and leaving passwords in plaintext in your code like I do in the example. You'd usually be getting user input and hashing that right away without storing it.

I've left out some important bits like user state and options like username and displayname for brevity. Don't forget about a user role if you're using BjyAuthorize too.