use of org.alfresco.rest.api.model.LoginTicketResponse 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);
}
use of org.alfresco.rest.api.model.LoginTicketResponse in project alfresco-remote-api by Alfresco.
the class InterceptingIdentityRemoteUserMapper method testCreateValidateDeleteTicketAlfTicketParameter.
/**
* 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 testCreateValidateDeleteTicketAlfTicketParameter() 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);
}
use of org.alfresco.rest.api.model.LoginTicketResponse in project alfresco-remote-api by Alfresco.
the class AuthenticationsImpl method createTicket.
@Override
public LoginTicketResponse createTicket(LoginTicket loginRequest, Parameters parameters) {
validateLoginRequest(loginRequest);
try {
// get ticket
authenticationService.authenticate(loginRequest.getUserId(), loginRequest.getPassword().toCharArray());
LoginTicketResponse response = new LoginTicketResponse();
response.setUserId(loginRequest.getUserId());
response.setId(authenticationService.getCurrentTicket());
return response;
} catch (AuthenticationException e) {
throw new PermissionDeniedException("Login failed");
} finally {
AuthenticationUtil.clearCurrentSecurityContext();
}
}
use of org.alfresco.rest.api.model.LoginTicketResponse in project alfresco-remote-api by Alfresco.
the class AuthenticationsImpl method validateTicket.
@Override
public LoginTicketResponse validateTicket(String me, Parameters parameters, WithResponse withResponse) {
if (!People.DEFAULT_USER.equals(me)) {
throw new InvalidArgumentException("Invalid parameter: " + me);
}
final String ticket = getTicket(parameters);
try {
final String ticketUser = ticketComponent.validateTicket(ticket);
final String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
// or the user is not fully authenticated
if (currentUser == null || !currentUser.equals(ticketUser)) {
throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[] { ticket });
}
} catch (AuthenticationException e) {
throw new NotFoundException(NotFoundException.DEFAULT_MESSAGE_ID, new String[] { ticket });
}
LoginTicketResponse response = new LoginTicketResponse();
response.setId(ticket);
return response;
}
use of org.alfresco.rest.api.model.LoginTicketResponse 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();
}
}
Aggregations