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
Get/create user by login instead of mail address #449
Comments
If you write your own custom delivery handler, you could use the UserManager#getUser(String login) ? Example:
|
@marcelmay Thanks for the example. Maybe I misunderstand, but where does the
=> One server, multiple users, and mails should be delivered to the user derived from the username that was used to authenticate. This could also be solved by trying to ensure the application always uses the same sender address, or by starting a new mail server for each test. Although I'd prefer the above as it feels cleaner. Before I found Greenmail I was trying subetha SMTP, and while great, it lacks POP3 / IMAP servers. For reference, it has a MessageHandlerFactory which receives a MessageContext containing not only the mail address but also the authentication information. Hence my idea that perhaps we could pass on the data from the authentication to the message delivery handler (which I hope shouldn't be too hard). |
If I understand you correctly, this is the default behaviour by GreenMail. The use case for the delivery handler is if you want to do something non standard:
The GreenMailUser (identified by the received message header TO email) holds also login etc.: greenmail/greenmail-core/src/main/java/com/icegreen/greenmail/user/UserManager.java Line 34 in 4d40b42
When the server receives an email, the default delivery handler tries to create a user unless it already exists: ...
private MessageDeliveryHandler messageDeliveryHandler = new MessageDeliveryHandler(){
public GreenMailUser handle(MovingMessage msg, MailAddress mailAddress) throws UserException {
GreenMailUser user = getUserByEmail(mailAddress.getEmail()); // TO
if(null==user) {
String login = mailAddress.getEmail();
String email = mailAddress.getEmail();
String password = mailAddress.getEmail();
user = createUser(email, login, password);
...
}
return user;
}
};
... Could you provide an example how you would change the default / use a login? |
Yes, by default it tries to find a user based on the address to which the mail is sent. What I'd like to do, is to use a user based on the First, we create new user Greenmail account
Now we enter the SMTP settings into our application that's being tested
And finally, we start a test and our application sents an email to What happens now is:
What I'd like to happen is
This would ensure that all mails are directed to the same user account, as long as the SMTP connection has the correct username/password. This would make (1) easier to find mails and (2) would allow a single mail server to be used for different tests. The message delivery handler could look something like this private MessageDeliveryHandler messageDeliveryHandler = new MessageDeliveryHandler(){
public GreenMailUser handle(MovingMessage msg, MailAddress mailAddress) throws UserException {
// msg.getAuth() returns the username/password from the PLAIN AUTH, if available
GreenMailUser user = getUserByLogin(msg.getAuth().getUsername());
if(null==user) {
String login = msg.getAuth().getUsername();
String email = msg.getAuth().getUsername() + "@example.com"; // or some other host
String password = msg.getAuth().getUsername();
user = createUser(email, login, password);
}
return user;
}
}; |
I still hope that your use case could be handled by matching eg the msg FROM/TO/SUBJECT . Regarding (1) and (2), you can also fetch all messages via Users login and email should be uniqe, too. If you really need the extension, this would require adding the user identity (or GreenMailUser?) to SmtpState and MovingMessage, see the SmtpConnection.setAuthenticated uses. |
First of all, I appreciate the quick responses and that you're taking your time to read all of this. It's not something everybody does for other open source projects.
That's pretty much what I'm doing for now, I try to make sure that every tests use the correct FROM address. This kinda works, but it's not ideal, since the application being tested lets users of the application configure "email actions" and lets them change all of TO/FROM/SUBJECT/... for the email to send (in principle). So making sure all mails for a particular test case are redirected to a particular user, regardless of the mail's contents, would simplify things quite a bit.
That might work, but we really don't have any particular identifier we could use for that.
If possible, I think this would be a cleaner approach. Also, tests are written by different persons, and it'd help if we didn't have to require them to use specific values for TO/FROM/SUBJECT.
If you think it doesn't fit Greenmail from an architectural point of view, we could probably make do somehow with the current test setup. Otherwise, I'd like to take a shot at this, from what I've seen this shouldn't be too hard to implement. And it shouldn't change any of the current behavior. |
…ble in MovingMessage * Implements greenmail-mail-test#449: Stores the authentication details in the moving message so that it is available in e.g. MessageDeliveryHandler * Since different authentication methods have different details, there's a AuthenticationState base interface with PlainAuthenticationState (with an additional authorizationId) and LoginAuthenticationState POJOs for the currently supported AUTH mechanisms LOGIN and AUTH. Other AUTH mechanisms may or may not have a username and/or password. * What I don't fully understand is why the SMTPState needs to be cleared so often. It's also cleared by the MailCommand, which removes the authentication details from the MovingMessage. I modfied the MailCommand so that it clears the SMTPState, but transfers the authentication details from the old moving message to the new one. We could also store the authentication details in the SMTPState as well, but that feels a bit redundant. * When I run the tests locally, the DummySSLServerSocketFactoryTest#testLoadKeyStoreViaSystemProperty fails, but that's because I don't have a certificate with an `amazonrootca1` in my system root key store (there is, e.g. a `debian:amazon_root_ca_1.pem` certificate and when I change the test to use that, it passes)
* Implements #449: Stores the authentication details in the moving message so that it is available in e.g. MessageDeliveryHandler * Since different authentication methods have different details, there's a AuthenticationState base interface with PlainAuthenticationState (with an additional authorizationId) and LoginAuthenticationState POJOs for the currently supported AUTH mechanisms LOGIN and AUTH. Other AUTH mechanisms may or may not have a username and/or password. * What I don't fully understand is why the SMTPState needs to be cleared so often. It's also cleared by the MailCommand, which removes the authentication details from the MovingMessage. I modfied the MailCommand so that it clears the SMTPState, but transfers the authentication details from the old moving message to the new one. We could also store the authentication details in the SMTPState as well, but that feels a bit redundant. * When I run the tests locally, the DummySSLServerSocketFactoryTest#testLoadKeyStoreViaSystemProperty fails, but that's because I don't have a certificate with an `amazonrootca1` in my system root key store (there is, e.g. a `debian:amazon_root_ca_1.pem` certificate and when I change the test to use that, it passes)
#451) * Implements #449: Stores the authentication details in the moving message so that it is available in e.g. MessageDeliveryHandler * Since different authentication methods have different details, there's a AuthenticationState base interface with PlainAuthenticationState (with an additional authorizationId) and LoginAuthenticationState POJOs for the currently supported AUTH mechanisms LOGIN and AUTH. Other AUTH mechanisms may or may not have a username and/or password. * What I don't fully understand is why the SMTPState needs to be cleared so often. It's also cleared by the MailCommand, which removes the authentication details from the MovingMessage. I modfied the MailCommand so that it clears the SMTPState, but transfers the authentication details from the old moving message to the new one. We could also store the authentication details in the SMTPState as well, but that feels a bit redundant. * When I run the tests locally, the DummySSLServerSocketFactoryTest#testLoadKeyStoreViaSystemProperty fails, but that's because I don't have a certificate with an `amazonrootca1` in my system root key store (there is, e.g. a `debian:amazon_root_ca_1.pem` certificate and when I change the test to use that, it passes)
Thanks alot, @blutorange ! I plan a 1.6.x release this weekend |
You're welcome, and thanks for merging, Yes, a release this week is more than enough for us. |
Just tried with the release and it works great, thanks! |
The default implementation of
MessageDeliveryHandler
attempts to find a user by the mail address.For testing, it would be helpful if we could get the user by their login (AUTH) credentials instead. This way, as long as the SMTP connection with the username and password is configured correctly, all mails would be sent to the same inbox, irrespective of the recipient's mail address.
From a quick look at the code, I think the easiest way to enable this might be to add the login information to
MovingMessage
. Then we can set our own MessageDeliveryHandler to implement the mapping from the login to a user.If you're open for PRs, I'd be happy to take a look at this.
The text was updated successfully, but these errors were encountered: