use of uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException in project isaac-api by isaacphysics.
the class UserAccountManager method authenticateCallback.
/**
* Authenticate Callback will receive the authentication information from the different provider types. (e.g. OAuth
* 2.0 (IOAuth2Authenticator) or bespoke)
*
* This method will either register a new user and attach the linkedAccount or locate the existing account of the
* user and create a session for that.
*
* @param request
* - http request from the user - should contain url encoded token details.
* @param response
* to store the session in our own segue cookie.
* @param provider
* - the provider who has just authenticated the user.
* @param rememberMe
* - Boolean to indicate whether or not this cookie expiry duration should be long or short
* @return Response containing the user object. Alternatively a SegueErrorResponse could be returned.
* @throws AuthenticationProviderMappingException
* - if we cannot locate an appropriate authenticator.
* @throws SegueDatabaseException
* - if there is a local database error.
* @throws IOException
* - Problem reading something
* @throws NoUserException
* - If the user doesn't exist with the provider.
* @throws AuthenticatorSecurityException
* - If there is a security probably with the authenticator.
* @throws CrossSiteRequestForgeryException
* - as per exception description.
* @throws CodeExchangeException
* - as per exception description.
* @throws AuthenticationCodeException
* - as per exception description.
*/
public RegisteredUserDTO authenticateCallback(final HttpServletRequest request, final HttpServletResponse response, final String provider, final boolean rememberMe) throws AuthenticationProviderMappingException, AuthenticatorSecurityException, NoUserException, IOException, SegueDatabaseException, AuthenticationCodeException, CodeExchangeException, CrossSiteRequestForgeryException {
IAuthenticator authenticator = this.userAuthenticationManager.mapToProvider(provider);
// get the auth provider user data.
UserFromAuthProvider providerUserDO = this.userAuthenticationManager.getThirdPartyUserInformation(request, provider);
// if the UserFromAuthProvider exists then this is a login request so process it.
RegisteredUser userFromLinkedAccount = this.userAuthenticationManager.getSegueUserFromLinkedAccount(authenticator.getAuthenticationProvider(), providerUserDO.getProviderUserId());
if (userFromLinkedAccount != null) {
return this.logUserIn(request, response, userFromLinkedAccount, rememberMe);
}
RegisteredUser currentUser = getCurrentRegisteredUserDO(request);
// if the user is currently logged in and this is a request for a linked account, then create the new link.
if (null != currentUser) {
Boolean intentionToLinkRegistered = (Boolean) request.getSession().getAttribute(LINK_ACCOUNT_PARAM_NAME);
if (intentionToLinkRegistered == null || !intentionToLinkRegistered) {
throw new SegueDatabaseException("User is already authenticated - " + "expected request to link accounts but none was found.");
}
List<AuthenticationProvider> usersProviders = this.database.getAuthenticationProvidersByUser(currentUser);
if (!usersProviders.contains(authenticator.getAuthenticationProvider())) {
// create linked account
this.userAuthenticationManager.linkProviderToExistingAccount(currentUser, authenticator.getAuthenticationProvider(), providerUserDO);
// clear link accounts intention until next time
request.removeAttribute(LINK_ACCOUNT_PARAM_NAME);
}
return this.convertUserDOToUserDTO(getCurrentRegisteredUserDO(request));
} else {
if (providerUserDO.getEmail() != null && !providerUserDO.getEmail().isEmpty() && this.findUserByEmail(providerUserDO.getEmail()) != null) {
log.warn("A user tried to use unknown provider '" + capitalizeFully(provider) + "' to log in to an account with matching email (" + providerUserDO.getEmail() + ").");
throw new DuplicateAccountException("You do not use " + capitalizeFully(provider) + " to log on to Isaac." + " You may have registered using a different provider, or a username and password.");
}
// this must be a registration request
RegisteredUser segueUserDO = this.registerUserWithFederatedProvider(authenticator.getAuthenticationProvider(), providerUserDO);
RegisteredUserDTO segueUserDTO = this.logUserIn(request, response, segueUserDO, rememberMe);
segueUserDTO.setFirstLogin(true);
try {
ImmutableMap<String, Object> emailTokens = ImmutableMap.of("provider", capitalizeFully(provider));
emailManager.sendTemplatedEmailToUser(segueUserDTO, emailManager.getEmailTemplateDTO("email-template-registration-confirmation-federated"), emailTokens, EmailType.SYSTEM);
} catch (ContentManagerException e) {
log.error("Registration email could not be sent due to content issue: " + e.getMessage());
}
return segueUserDTO;
}
}
use of uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException in project isaac-api by isaacphysics.
the class UserAuthenticationManager method sendFederatedAuthenticatorResetMessage.
/**
* This method will send a message to a user explaining that they only use a federated authenticator.
*
* @param user
* - a user with the givenName, email and token fields set
* @param userAsDTO
* - A user DTO object sanitised so that we can send it to the email manager.
* @param additionalEmailValues
* - Additional email values to find and replace including any password reset urls.
* @throws SegueDatabaseException
* - If there is an internal database error.
*/
private void sendFederatedAuthenticatorResetMessage(final RegisteredUser user, final RegisteredUserDTO userAsDTO, final Map<String, Object> additionalEmailValues) throws SegueDatabaseException {
Validate.notNull(user);
// Get the user's federated authenticators
List<AuthenticationProvider> providers = this.database.getAuthenticationProvidersByUser(user);
List<String> providerNames = new ArrayList<>();
for (AuthenticationProvider provider : providers) {
IAuthenticator authenticator = this.registeredAuthProviders.get(provider);
if (!(authenticator instanceof IFederatedAuthenticator)) {
continue;
}
String providerName = provider.name().toLowerCase();
providerName = providerName.substring(0, 1).toUpperCase() + providerName.substring(1);
providerNames.add(providerName);
}
String providersString;
if (providerNames.size() == 1) {
providersString = providerNames.get(0);
} else {
StringBuilder providersBuilder = new StringBuilder();
for (int i = 0; i < providerNames.size(); i++) {
if (i == providerNames.size() - 1) {
providersBuilder.append(" and ");
} else if (i > 1) {
providersBuilder.append(", ");
}
providersBuilder.append(providerNames.get(i));
}
providersString = providersBuilder.toString();
}
String providerWord = "provider";
if (providerNames.size() > 1) {
providerWord += "s";
}
try {
Map<String, Object> emailTokens = Maps.newHashMap();
emailTokens.putAll(ImmutableMap.of("providerString", providersString, "providerWord", providerWord));
emailTokens.putAll(additionalEmailValues);
emailManager.sendTemplatedEmailToUser(userAsDTO, emailManager.getEmailTemplateDTO("email-template-federated-password-reset"), emailTokens, EmailType.SYSTEM);
} catch (ContentManagerException contentException) {
log.error(String.format("Error sending federated email verification message - %s", contentException.getMessage()));
}
}
use of uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException in project isaac-api by isaacphysics.
the class EmailManagerTest method sendFederatedPasswordReset_checkForTemplateCompletion_emailShouldBeSentWithTemplateTagsFilledIn.
/**
* Verifies that email templates are parsed and replaced correctly.
*
* @throws CommunicationException
*/
@Test
public final void sendFederatedPasswordReset_checkForTemplateCompletion_emailShouldBeSentWithTemplateTagsFilledIn() {
EmailTemplateDTO template = createDummyEmailTemplate("Hello, {{givenName}}.\n\nYou requested a " + "password reset. However you use {{providerString}} to log in to our site. You need" + " to go to your authentication {{providerWord}} to reset your password.\n\nRegards,\n\n{{sig}}");
ContentDTO htmlTemplate = createDummyContentTemplate("{{content}}");
try {
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-federated-password-reset")).andReturn(template);
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-html")).andReturn(htmlTemplate);
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-ascii")).andReturn(htmlTemplate);
EasyMock.expect(mockContentManager.getCurrentContentSHA()).andReturn(CONTENT_VERSION).atLeastOnce();
EasyMock.replay(mockContentManager);
} catch (ContentManagerException e) {
e.printStackTrace();
Assert.fail();
}
EmailManager manager = new EmailManager(emailCommunicator, userPreferenceManager, mockPropertiesLoader, mockContentManager, logManager, generateGlobalTokenMap());
try {
Map<String, Object> emailTokens = ImmutableMap.of("providerString", "testString", "providerWord", "testWord");
manager.sendTemplatedEmailToUser(userDTO, manager.getEmailTemplateDTO("email-template-federated-password-reset"), emailTokens, EmailType.SYSTEM);
} catch (ContentManagerException e) {
e.printStackTrace();
Assert.fail();
log.debug(e.getMessage());
} catch (SegueDatabaseException e) {
e.printStackTrace();
log.debug(e.getMessage());
Assert.fail();
}
final String expectedMessage = "Hello, tester.\n\nYou requested a password reset. " + "However you use testString to log in to our site. You need to go to your " + "authentication testWord to reset your password.\n\nRegards,\n\nIsaac Physics Project";
// Wait for the emailQueue to spin up and send our message
int i = 0;
while (!capturedArgument.hasCaptured() && i < 5) {
try {
Thread.sleep(100);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
Assert.fail();
}
}
email = capturedArgument.getValue();
assertNotNull(email);
assertEquals(expectedMessage, email.getPlainTextMessage());
System.out.println(email.getPlainTextMessage());
}
use of uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException in project isaac-api by isaacphysics.
the class EmailManagerTest method sendPasswordReset_checkForTemplateCompletion_emailShouldBeSentWithTemplateTagsFilledIn.
/**
* Verifies that email templates are parsed and replaced correctly.
*
* @throws CommunicationException
*/
@Test
public final void sendPasswordReset_checkForTemplateCompletion_emailShouldBeSentWithTemplateTagsFilledIn() {
EmailTemplateDTO template = createDummyEmailTemplate("Hello, {{givenName}}.\n\nA request has been " + "made to reset the password for the account: </a href='mailto:{{email}}'>{{email}}<a>" + ".\n\nTo reset your password <a href='{{resetURL}}'>Click Here</a>\n\nRegards,\n\n{{sig}}");
ContentDTO htmlTemplate = createDummyContentTemplate("{{content}}");
try {
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-password-reset")).andReturn(template).once();
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-html")).andReturn(htmlTemplate).once();
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-ascii")).andReturn(htmlTemplate);
EasyMock.expect(mockContentManager.getCurrentContentSHA()).andReturn(CONTENT_VERSION).atLeastOnce();
EasyMock.replay(mockContentManager);
} catch (ContentManagerException e) {
e.printStackTrace();
Assert.fail();
}
EmailManager manager = new EmailManager(emailCommunicator, userPreferenceManager, mockPropertiesLoader, mockContentManager, logManager, generateGlobalTokenMap());
try {
Map<String, Object> emailValues = ImmutableMap.of("resetURL", "https://dev.isaacphysics.org/resetpassword/resetToken");
manager.sendTemplatedEmailToUser(userDTO, manager.getEmailTemplateDTO("email-template-password-reset"), emailValues, EmailType.SYSTEM);
} catch (ContentManagerException e) {
e.printStackTrace();
Assert.fail();
} catch (SegueDatabaseException e) {
e.printStackTrace();
Assert.fail();
}
final String expectedMessage = "Hello, tester.\n\nA request has been " + "made to reset the password for the account: </a href='mailto:test@test.com'>test@test.com<a>" + ".\n\nTo reset your password <a href='https://dev.isaacphysics.org/resetpassword/resetToken'>" + "Click Here</a>\n\nRegards,\n\nIsaac Physics Project";
// Wait for the emailQueue to spin up and send our message
int i = 0;
while (!capturedArgument.hasCaptured() && i < 5) {
try {
Thread.sleep(100);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
Assert.fail();
}
}
email = capturedArgument.getValue();
assertNotNull(email);
assertEquals(expectedMessage, email.getPlainTextMessage());
}
use of uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException in project isaac-api by isaacphysics.
the class EmailManagerTest method sendCustomContentEmail_checkNullProperties_replacedWithEmptyString.
/**
* Check we don't send custom content emails to users with null / preference
*/
@Test
public void sendCustomContentEmail_checkNullProperties_replacedWithEmptyString() {
EmailManager manager = new EmailManager(emailCommunicator, userPreferenceManager, mockPropertiesLoader, mockContentManager, logManager, generateGlobalTokenMap());
List<RegisteredUserDTO> allSelectedUsers = Lists.newArrayList();
allSelectedUsers.add(userDTOWithNulls);
allSelectedUsers.add(userDTOWithNulls);
UserPreference userPreference = new UserPreference(userDTOWithNulls.getId(), SegueUserPreferences.EMAIL_PREFERENCE.name(), "ASSIGNMENTS", false);
try {
EasyMock.expect(userPreferenceManager.getUserPreference(SegueUserPreferences.EMAIL_PREFERENCE.name(), "ASSIGNMENTS", userDTOWithNulls.getId())).andReturn(userPreference);
EasyMock.expect(userPreferenceManager.getUserPreference(SegueUserPreferences.EMAIL_PREFERENCE.name(), "ASSIGNMENTS", userDTOWithNulls.getId())).andReturn(userPreference);
} catch (SegueDatabaseException e1) {
e1.printStackTrace();
Assert.fail();
}
EasyMock.replay(userPreferenceManager);
ContentDTO htmlTemplate = createDummyContentTemplate("{{content}}");
String htmlContent = "hi {{givenName}}<br><br>This is a test";
String plainTextContent = "hi {{givenName}}\n\nThis is a test";
String subject = "Test email";
EmailTemplateDTO emailTemplate = new EmailTemplateDTO();
emailTemplate.setHtmlContent(htmlContent);
emailTemplate.setPlainTextContent(plainTextContent);
emailTemplate.setSubject(subject);
try {
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-html")).andReturn(htmlTemplate).times(allSelectedUsers.size());
EasyMock.expect(mockContentManager.getContentById(CONTENT_VERSION, "email-template-ascii")).andReturn(htmlTemplate).times(allSelectedUsers.size());
EasyMock.expect(mockContentManager.getCurrentContentSHA()).andReturn(CONTENT_VERSION).atLeastOnce();
EasyMock.replay(mockContentManager);
} catch (ContentManagerException e) {
e.printStackTrace();
Assert.fail();
}
try {
manager.sendCustomContentEmail(userDTOWithNulls, emailTemplate, allSelectedUsers, EmailType.ASSIGNMENTS);
} catch (SegueDatabaseException e) {
Assert.fail();
} catch (ContentManagerException e) {
Assert.fail();
}
}
Aggregations