Search in sources :

Example 1 with ContentManagerException

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;
    }
}
Also used : IAuthenticator(uk.ac.cam.cl.dtg.segue.auth.IAuthenticator) SegueDatabaseException(uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException) AuthenticationProvider(uk.ac.cam.cl.dtg.segue.auth.AuthenticationProvider) RegisteredUser(uk.ac.cam.cl.dtg.isaac.dos.users.RegisteredUser) RegisteredUserDTO(uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO) UserFromAuthProvider(uk.ac.cam.cl.dtg.isaac.dos.users.UserFromAuthProvider) ContentManagerException(uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException)

Example 2 with ContentManagerException

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()));
    }
}
Also used : IFederatedAuthenticator(uk.ac.cam.cl.dtg.segue.auth.IFederatedAuthenticator) IAuthenticator(uk.ac.cam.cl.dtg.segue.auth.IAuthenticator) AuthenticationProvider(uk.ac.cam.cl.dtg.segue.auth.AuthenticationProvider) ArrayList(java.util.ArrayList) ContentManagerException(uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException)

Example 3 with ContentManagerException

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());
}
Also used : EmailTemplateDTO(uk.ac.cam.cl.dtg.isaac.dto.content.EmailTemplateDTO) ContentDTO(uk.ac.cam.cl.dtg.isaac.dto.content.ContentDTO) SegueDatabaseException(uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException) ContentManagerException(uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException) Test(org.junit.Test)

Example 4 with ContentManagerException

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());
}
Also used : EmailTemplateDTO(uk.ac.cam.cl.dtg.isaac.dto.content.EmailTemplateDTO) ContentDTO(uk.ac.cam.cl.dtg.isaac.dto.content.ContentDTO) SegueDatabaseException(uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException) ContentManagerException(uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException) Test(org.junit.Test)

Example 5 with ContentManagerException

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();
    }
}
Also used : ContentDTO(uk.ac.cam.cl.dtg.isaac.dto.content.ContentDTO) EmailTemplateDTO(uk.ac.cam.cl.dtg.isaac.dto.content.EmailTemplateDTO) RegisteredUserDTO(uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO) SegueDatabaseException(uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException) UserPreference(uk.ac.cam.cl.dtg.isaac.dos.UserPreference) ContentManagerException(uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException) Test(org.junit.Test)

Aggregations

ContentManagerException (uk.ac.cam.cl.dtg.segue.dao.content.ContentManagerException)92 SegueDatabaseException (uk.ac.cam.cl.dtg.segue.dao.SegueDatabaseException)60 SegueErrorResponse (uk.ac.cam.cl.dtg.isaac.dto.SegueErrorResponse)59 RegisteredUserDTO (uk.ac.cam.cl.dtg.isaac.dto.users.RegisteredUserDTO)57 Path (javax.ws.rs.Path)56 Produces (javax.ws.rs.Produces)56 ApiOperation (io.swagger.annotations.ApiOperation)55 GZIP (org.jboss.resteasy.annotations.GZIP)50 NoUserLoggedInException (uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserLoggedInException)44 GET (javax.ws.rs.GET)35 ContentDTO (uk.ac.cam.cl.dtg.isaac.dto.content.ContentDTO)30 POST (javax.ws.rs.POST)27 ArrayList (java.util.ArrayList)23 Date (java.util.Date)23 List (java.util.List)22 NoUserException (uk.ac.cam.cl.dtg.segue.auth.exceptions.NoUserException)21 ImmutableMap (com.google.common.collect.ImmutableMap)20 Map (java.util.Map)20 Response (javax.ws.rs.core.Response)19 IsaacEventPageDTO (uk.ac.cam.cl.dtg.isaac.dto.IsaacEventPageDTO)18