package org.multibit.mbm.resources.user; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.yammer.metrics.annotation.Timed; import org.multibit.mbm.api.hal.HalMediaType; import org.multibit.mbm.api.request.user.WebFormAuthenticationRequest; import org.multibit.mbm.api.request.user.WebFormRegistrationRequest; import org.multibit.mbm.api.response.hal.user.ClientUserBridge; import org.multibit.mbm.auth.Authority; import org.multibit.mbm.auth.annotation.RestrictedTo; import org.multibit.mbm.core.model.*; import org.multibit.mbm.db.dao.RoleDao; import org.multibit.mbm.db.dao.UserDao; import org.multibit.mbm.resources.BaseResource; import org.multibit.mbm.resources.ResourceAsserts; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import java.net.URI; /** * <p>Resource to provide the following to application:</p> * <ul> * <li>Provision of REST endpoints to manage CRUD operations by a Customer</li> * </ul> * * @since 0.0.1 */ @Component @Path("/client/user") @Produces({HalMediaType.APPLICATION_HAL_JSON, HalMediaType.APPLICATION_HAL_XML}) public class ClientUserResource extends BaseResource { @Resource(name = "hibernateUserDao") private UserDao userDao; @Resource(name = "hibernateRoleDao") private RoleDao roleDao; /** * @param clientUser The client application acting as the proxy for this user * * @return A HAL representation of the result */ @POST @Timed @Path("/anonymous") public Response anonymousUser( @RestrictedTo({Authority.ROLE_CLIENT}) User clientUser) { // Retrieve the role by its authority name Optional<Role> optionalRole = roleDao.getByName(Authority.ROLE_PUBLIC.name()); ResourceAsserts.assertPresent(optionalRole,"role"); // Build a new Customer for the anonymous user Customer customer = CustomerBuilder .newInstance() .build(); // Build an anonymous new User User user = UserBuilder .newInstance() .withCustomer(customer) .withRole(optionalRole.get()) .build(); // Persist the User with cascade for the Customer User persistentUser = userDao.saveOrUpdate(user); // Provide a minimal representation to the client ClientUserBridge bridge = new ClientUserBridge(uriInfo, Optional.of(clientUser)); URI location = UriBuilder.fromResource(CustomerUserResource.class).build(); return created(bridge, persistentUser, location); } /** * @param clientUser The client application acting as the proxy for this user * @param registrationRequest The registration request * * @return A HAL representation of the result */ @POST @Timed @Path("/register") public Response registerUser( @RestrictedTo({Authority.ROLE_CLIENT}) User clientUser, WebFormRegistrationRequest registrationRequest) { Preconditions.checkNotNull(registrationRequest); Preconditions.checkNotNull(registrationRequest.getPasswordDigest()); Preconditions.checkNotNull(registrationRequest.getUsername()); // Perform conflict check Optional<User> verificationUser = userDao.getByCredentials( registrationRequest.getUsername(), registrationRequest.getPasswordDigest()); ResourceAsserts.assertNotConflicted(verificationUser, "user"); // Build a new Customer Customer customer = CustomerBuilder .newInstance() .build(); // Build a new User User user = UserBuilder .newInstance() .withUsername(registrationRequest.getUsername()) .withPassword(registrationRequest.getPasswordDigest()) // TODO Fill in the rest of the registration details .withCustomer(customer) .build(); // Persist the User with cascade for the Customer User persistentUser = userDao.saveOrUpdate(user); // Provide a minimal representation to the client ClientUserBridge bridge = new ClientUserBridge(uriInfo, Optional.of(clientUser)); URI location = uriInfo.getAbsolutePathBuilder().path(persistentUser.getApiKey()).build(); return created(bridge, persistentUser, location); } /** * @param clientUser The client application acting as the proxy for this user * @param authenticationRequest The authentication request * * @return A HAL representation of the result */ @POST @Timed @Path("/authenticate") public Response authenticateUser( @RestrictedTo({Authority.ROLE_CLIENT}) User clientUser, WebFormAuthenticationRequest authenticationRequest) { Optional<User> requestedUser = userDao.getByCredentials(authenticationRequest.getUsername(), authenticationRequest.getPasswordDigest()); ClientUserBridge bridge = new ClientUserBridge(uriInfo, Optional.of(clientUser)); // The bridge can handle a null return ok(bridge, requestedUser.orNull()); } public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setRoleDao(RoleDao roleDao) { this.roleDao = roleDao; } }