Search in sources :

Example 1 with LoginTicket

use of org.alfresco.rest.api.model.LoginTicket in project alfresco-remote-api by Alfresco.

the class AuthenticationsTest method testCreateValidateDeleteTicket.

/**
 * Tests login (create ticket), logout (delete ticket), and validate (get ticket).
 *
 * <p>POST:</p>
 * {@literal <host>:<port>/alfresco/api/<networkId>/public/authentication/versions/1/tickets}
 *
 * <p>GET:</p>
 * {@literal <host>:<port>/alfresco/api/<networkId>/public/authentication/versions/1/tickets/-me-}
 *
 * <p>DELETE:</p>
 * {@literal <host>:<port>/alfresco/api/<networkId>/public/authentication/versions/1/tickets/-me-}
 */
@Test
public void testCreateValidateDeleteTicket() throws Exception {
    Paging paging = getPaging(0, 100);
    setRequestContext(null);
    // Unauthorized call
    getAll(SiteEntityResource.class, paging, null, 401);
    /*
         *  user1 login - via alf_ticket parameter
         */
    // User1 login request
    LoginTicket loginRequest = new LoginTicket();
    // Invalid login details
    post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 400);
    loginRequest.setUserId(null);
    loginRequest.setPassword("user1Password");
    // Invalid login details
    post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 400);
    loginRequest.setUserId(user1);
    loginRequest.setPassword(null);
    // Invalid login details
    post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 400);
    loginRequest.setUserId(user1);
    loginRequest.setPassword("user1Password");
    // Authenticate and create a ticket
    HttpResponse response = post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 201);
    LoginTicketResponse loginResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
    assertNotNull(loginResponse.getId());
    assertNotNull(loginResponse.getUserId());
    // Get list of sites by appending the alf_ticket to the URL
    // e.g. .../alfresco/versions/1/sites/?alf_ticket=TICKET_57866258ea56c28491bb3e75d8355ebf6fbaaa23
    Map<String, String> ticket = Collections.singletonMap("alf_ticket", loginResponse.getId());
    getAll(SiteEntityResource.class, paging, ticket, 200);
    // Unauthorized - Invalid ticket
    getAll(SiteEntityResource.class, paging, Collections.singletonMap("alf_ticket", "TICKET_" + System.currentTimeMillis()), 401);
    // Validate ticket - Invalid parameter. Only '-me-' is supported
    getSingle(TICKETS_URL, loginResponse.getId(), ticket, null, TICKETS_API_NAME, 400);
    // Validate ticket
    response = getSingle(TICKETS_URL, People.DEFAULT_USER, ticket, null, TICKETS_API_NAME, 200);
    LoginTicketResponse validatedTicket = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
    assertEquals(loginResponse.getId(), validatedTicket.getId());
    // Validate ticket - Invalid parameter. Only '-me-' is supported
    getSingle(TICKETS_URL, loginResponse.getId(), ticket, null, TICKETS_API_NAME, 400);
    // Delete the ticket  - Logout
    delete(TICKETS_URL, People.DEFAULT_USER, ticket, null, TICKETS_API_NAME, 204);
    // Validate ticket - 401 as ticket has been invalidated so the API call is unauthorized
    getSingle(TICKETS_URL, People.DEFAULT_USER, ticket, null, TICKETS_API_NAME, 401);
    setRequestContext(user1);
    // Check the ticket has been invalidated - the difference with the above is that the API call is authorized
    response = getSingle(TICKETS_URL, People.DEFAULT_USER, ticket, null, TICKETS_API_NAME, 404);
    PublicApiClient.ExpectedErrorResponse error = RestApiUtil.parseErrorResponse(response.getJsonResponse());
    // Double check that we've retrieved a standard error response (REPO-1773)
    assertEquals(404, error.getStatusCode());
    // Ticket has already been invalidated
    delete(TICKETS_URL, People.DEFAULT_USER, ticket, null, TICKETS_API_NAME, 404);
    setRequestContext(null);
    // Get list of site by appending the invalidated ticket
    getAll(SiteEntityResource.class, paging, ticket, 401);
    /*
         *  user2 login - Via Authorization header
         */
    setRequestContext(user2);
    // User2 create a folder within his home folder (-my-)
    Folder folderResp = createFolder(Nodes.PATH_MY, "F2", null);
    assertNotNull(folderResp.getId());
    setRequestContext(null);
    getAll(getNodeChildrenUrl(Nodes.PATH_MY), paging, 401);
    // User2 login request
    loginRequest = new LoginTicket();
    loginRequest.setUserId(user2);
    loginRequest.setPassword("wrongPassword");
    // Authentication failed - wrong password
    post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 403);
    loginRequest.setUserId(user1);
    loginRequest.setPassword("user2Password");
    // Authentication failed - userId/password mismatch
    post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 403);
    // Set the correct details
    loginRequest.setUserId(user2);
    loginRequest.setPassword("user2Password");
    // Authenticate and create a ticket
    response = post(TICKETS_URL, RestApiUtil.toJsonAsString(loginRequest), null, null, TICKETS_API_NAME, 201);
    loginResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
    assertNotNull(loginResponse.getId());
    assertNotNull(loginResponse.getUserId());
    String encodedTicket = encodeB64(loginResponse.getId());
    // Set the authorization (encoded ticket only) header rather than appending the ticket to the URL
    Map<String, String> header = Collections.singletonMap("Authorization", "Basic " + encodedTicket);
    // Get children of user2 home folder
    response = getAll(getNodeChildrenUrl(Nodes.PATH_MY), paging, null, header, 200);
    List<Document> nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Document.class);
    assertEquals(1, nodes.size());
    // Validate ticket - Invalid parameter. Only '-me-' is supported
    getSingle(TICKETS_URL, loginResponse.getId(), null, header, TICKETS_API_NAME, 400);
    // Validate ticket - user2
    response = getSingle(TICKETS_URL, People.DEFAULT_USER, null, header, TICKETS_API_NAME, 200);
    validatedTicket = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
    assertEquals(loginResponse.getId(), validatedTicket.getId());
    // Try list children for user2 again.
    // Encode Alfresco predefined userId for ticket authentication, ROLE_TICKET, and the ticket
    String encodedUserIdAndTicket = encodeB64("ROLE_TICKET:" + loginResponse.getId());
    // Set the authorization (encoded userId:ticket) header rather than appending the ticket to the URL
    header = Collections.singletonMap("Authorization", "Basic " + encodedUserIdAndTicket);
    // Get children of user2 home folder
    response = getAll(getNodeChildrenUrl(Nodes.PATH_MY), paging, null, header, 200);
    nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Document.class);
    assertEquals(1, nodes.size());
    // Try list children for user2 again - appending ticket
    ticket = Collections.singletonMap("alf_ticket", loginResponse.getId());
    response = getAll(getNodeChildrenUrl(Nodes.PATH_MY), paging, ticket, 200);
    nodes = RestApiUtil.parseRestApiEntries(response.getJsonResponse(), Document.class);
    assertEquals(1, nodes.size());
    setRequestContext(user2);
    // Try to validate the ticket without supplying the Authorization header or the alf_ticket param
    getSingle(TICKETS_URL, People.DEFAULT_USER, null, null, TICKETS_API_NAME, 400);
    setRequestContext(null);
    // Delete the ticket  - Invalid parameter. Only '-me-' is supported
    header = Collections.singletonMap("Authorization", "Basic " + encodedUserIdAndTicket);
    delete(TICKETS_URL, loginResponse.getId(), null, header, TICKETS_API_NAME, 400);
    // Delete the ticket  - Logout
    delete(TICKETS_URL, People.DEFAULT_USER, null, header, TICKETS_API_NAME, 204);
    // Get children of user2 home folder - invalidated ticket
    getAll(getNodeChildrenUrl(Nodes.PATH_MY), paging, null, header, 401);
}
Also used : LoginTicketResponse(org.alfresco.rest.api.model.LoginTicketResponse) Paging(org.alfresco.rest.api.tests.client.PublicApiClient.Paging) HttpResponse(org.alfresco.rest.api.tests.client.HttpResponse) PublicApiClient(org.alfresco.rest.api.tests.client.PublicApiClient) Folder(org.alfresco.rest.api.tests.client.data.Folder) Document(org.alfresco.rest.api.tests.client.data.Document) LoginTicket(org.alfresco.rest.api.model.LoginTicket) Test(org.junit.Test) AbstractSingleNetworkSiteTest(org.alfresco.rest.AbstractSingleNetworkSiteTest)

Example 2 with LoginTicket

use of org.alfresco.rest.api.model.LoginTicket in project alfresco-remote-api by Alfresco.

the class TestPeople method testResetPassword.

/**
 * Tests reset password.
 * <p>POST:</p>
 * <ul>
 * <li> {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/people/<userId>/request-password-reset} </li>
 * <li> {@literal <host>:<port>/alfresco/api/<networkId>/public/alfresco/versions/1/people/<userId>/reset-password} </li>
 * </ul>
 */
@Test
public void testResetPassword() throws Exception {
    // As Admin, create a user
    setRequestContext(account1.getId(), account1Admin, "admin");
    Person person = new Person();
    person.setUserName("john.doe@" + account1.getId());
    person.setFirstName("John");
    person.setLastName("Doe");
    person.setEmail("john.doe@alfresco.com");
    person.setEnabled(true);
    person.setEmailNotificationsEnabled(true);
    person.setPassword("password");
    people.create(person);
    // un-authenticated API
    setRequestContext(account1.getId(), null, null);
    // Just try to login, to test the new created user credential
    LoginTicket loginRequest = new LoginTicket();
    loginRequest.setUserId(person.getUserName());
    loginRequest.setPassword(person.getPassword());
    // Authenticate and create a ticket
    HttpResponse response = post("tickets", RestApiUtil.toJsonAsString(loginRequest), null, null, "authentication", 201);
    LoginTicketResponse loginResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
    assertNotNull(loginResponse.getId());
    assertNotNull(loginResponse.getUserId());
    /**
     * Reset Password
     */
    // First make the service to send a synchronous email
    ResetPasswordServiceImpl passwordService = applicationContext.getBean("resetPasswordService", ResetPasswordServiceImpl.class);
    passwordService.setSendEmailAsynchronously(false);
    // Get the 'mail' bean in a test mode.
    EmailUtil emailUtil = new EmailUtil(applicationContext);
    try {
        // Un-authenticated API
        setRequestContext(account1.getId(), null, null);
        // Reset email (just in case other tests didn't clean up...)
        emailUtil.reset();
        // Request reset password
        Client client = new Client().setClient("share");
        post(getRequestResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(client), 202);
        assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
        MimeMessage msg = emailUtil.getLastEmail();
        assertNotNull("There should be an email.", msg);
        assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
        // Check the recipient is the person who requested the reset password
        assertEquals(person.getEmail(), msg.getAllRecipients()[0].toString());
        // There should be a subject
        assertNotNull("There should be a subject.", msg.getSubject());
        // Check the reset password url.
        String resetPasswordUrl = (String) emailUtil.getLastEmailTemplateModelValue("reset_password_url");
        assertNotNull("Wrong email is sent.", resetPasswordUrl);
        // Get the workflow id and key
        org.alfresco.util.Pair<String, String> pair = getWorkflowIdAndKeyFromUrl(resetPasswordUrl);
        assertNotNull("Workflow Id can't be null.", pair.getFirst());
        assertNotNull("Workflow Key can't be null.", pair.getSecond());
        // Reset the email helper, to get rid of the request reset password email
        emailUtil.reset();
        // Un-authenticated APIs as we are still using the 'setRequestContext(account1.getId(), null, null)' set above.
        // Reset the password
        PasswordReset passwordReset = new PasswordReset().setPassword("changed").setId(pair.getFirst()).setKey(pair.getSecond());
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordReset), 202);
        assertEquals("A reset password confirmation email should have been sent.", 1, emailUtil.getSentCount());
        msg = emailUtil.getLastEmail();
        assertNotNull("There should be an email.", msg);
        assertEquals("Should've been only one email recipient.", 1, msg.getAllRecipients().length);
        assertEquals(person.getEmail(), msg.getAllRecipients()[0].toString());
        // There should be a subject
        assertNotNull("There should be a subject.", msg.getSubject());
        // Try to login with old credential
        post("tickets", RestApiUtil.toJsonAsString(loginRequest), null, null, "authentication", 403);
        // Set the new password
        loginRequest.setPassword(passwordReset.getPassword());
        response = post("tickets", RestApiUtil.toJsonAsString(loginRequest), null, null, "authentication", 201);
        loginResponse = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), LoginTicketResponse.class);
        assertNotNull(loginResponse.getId());
        assertNotNull(loginResponse.getUserId());
        /*
             * Negative tests
             */
        // First, reset the email helper
        emailUtil.reset();
        // Try reset with the used workflow
        // Note: we still return 202 response for security reasons
        passwordReset.setPassword("changedAgain");
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordReset), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
        // Request reset password - Invalid user (user does not exist)
        post(getRequestResetPasswordUrl(System.currentTimeMillis() + "noUser"), RestApiUtil.toJsonAsString(client), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
        // As Admin disable the user
        setRequestContext(account1.getId(), account1Admin, "admin");
        Map<String, String> params = Collections.singletonMap("fields", "enabled");
        Person updatedPerson = people.update(person.getUserName(), qjson("{`enabled`:" + false + "}"), params, 200);
        assertFalse(updatedPerson.isEnabled());
        // Un-authenticated API
        setRequestContext(account1.getId(), null, null);
        // Request reset password - Invalid user (user is disabled)
        post(getRequestResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(client), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
        // Client is not specified
        client = new Client();
        post(getRequestResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(client), 400);
        // Reset password
        // First, reset the email helper and enable the user
        emailUtil.reset();
        // As Admin enable the user
        setRequestContext(account1.getId(), account1Admin, "admin");
        params = Collections.singletonMap("fields", "enabled");
        updatedPerson = people.update(person.getUserName(), qjson("{`enabled`:" + true + "}"), params, 200);
        assertTrue(updatedPerson.isEnabled());
        // Un-authenticated API
        setRequestContext(account1.getId(), null, null);
        client = new Client().setClient("share");
        post(getRequestResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(client), 202);
        assertEquals("A reset password email should have been sent.", 1, emailUtil.getSentCount());
        resetPasswordUrl = (String) emailUtil.getLastEmailTemplateModelValue("reset_password_url");
        // Check the reset password url.
        assertNotNull("Wrong email is sent.", resetPasswordUrl);
        // Get the workflow id and key
        pair = getWorkflowIdAndKeyFromUrl(resetPasswordUrl);
        assertNotNull("Workflow Id can't be null.", pair.getFirst());
        assertNotNull("Workflow Key can't be null.", pair.getSecond());
        // Reset the email helper, to get rid of the request reset password email
        emailUtil.reset();
        // Invalid request - password is not provided
        PasswordReset passwordResetInvalid = new PasswordReset().setId(pair.getFirst()).setKey(pair.getSecond());
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordResetInvalid), 400);
        // Invalid request - workflow id is not provided
        passwordResetInvalid.setPassword("changedAgain").setId(null);
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordResetInvalid), 400);
        // Invalid request - workflow key is not provided
        passwordResetInvalid.setId(pair.getFirst()).setKey(null);
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordResetInvalid), 400);
        // Invalid request - Invalid workflow id
        // Note: we still return 202 response for security reasons
        passwordResetInvalid = new PasswordReset().setPassword("changedAgain").setId(// Invalid Id
        "activiti$" + System.currentTimeMillis()).setKey(pair.getSecond());
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordResetInvalid), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
        // Invalid request - Invalid workflow key
        // Note: we still return 202 response for security reasons
        passwordResetInvalid = new PasswordReset().setPassword("changedAgain").setId(pair.getFirst()).setKey(// Invalid Key
        GUID.generate());
        post(getResetPasswordUrl(person.getUserName()), RestApiUtil.toJsonAsString(passwordResetInvalid), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
        // Invalid request (not the same user) - The given user id 'user1' does not match the person's user id who requested the password reset.
        // Note: we still return 202 response for security reasons
        passwordResetInvalid = new PasswordReset().setPassword("changedAgain").setId(pair.getFirst()).setKey(pair.getSecond());
        post(getResetPasswordUrl(user1), RestApiUtil.toJsonAsString(passwordResetInvalid), 202);
        assertEquals("No email should have been sent.", 0, emailUtil.getSentCount());
    } finally {
        passwordService.setSendEmailAsynchronously(true);
        emailUtil.reset();
    }
}
Also used : HttpResponse(org.alfresco.rest.api.tests.client.HttpResponse) EmailUtil(org.alfresco.util.email.EmailUtil) ResetPasswordServiceImpl(org.alfresco.repo.security.authentication.ResetPasswordServiceImpl) LoginTicket(org.alfresco.rest.api.model.LoginTicket) LoginTicketResponse(org.alfresco.rest.api.model.LoginTicketResponse) MimeMessage(javax.mail.internet.MimeMessage) PasswordReset(org.alfresco.rest.api.model.PasswordReset) Client(org.alfresco.rest.api.model.Client) PublicApiClient(org.alfresco.rest.api.tests.client.PublicApiClient) Person(org.alfresco.rest.api.tests.client.data.Person) Test(org.junit.Test)

Aggregations

LoginTicket (org.alfresco.rest.api.model.LoginTicket)2 LoginTicketResponse (org.alfresco.rest.api.model.LoginTicketResponse)2 HttpResponse (org.alfresco.rest.api.tests.client.HttpResponse)2 PublicApiClient (org.alfresco.rest.api.tests.client.PublicApiClient)2 Test (org.junit.Test)2 MimeMessage (javax.mail.internet.MimeMessage)1 ResetPasswordServiceImpl (org.alfresco.repo.security.authentication.ResetPasswordServiceImpl)1 AbstractSingleNetworkSiteTest (org.alfresco.rest.AbstractSingleNetworkSiteTest)1 Client (org.alfresco.rest.api.model.Client)1 PasswordReset (org.alfresco.rest.api.model.PasswordReset)1 Paging (org.alfresco.rest.api.tests.client.PublicApiClient.Paging)1 Document (org.alfresco.rest.api.tests.client.data.Document)1 Folder (org.alfresco.rest.api.tests.client.data.Folder)1 Person (org.alfresco.rest.api.tests.client.data.Person)1 EmailUtil (org.alfresco.util.email.EmailUtil)1