/** * Copyright (c) 2009 - 2012 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package org.candlepin.resource; import org.candlepin.auth.Access; import org.candlepin.auth.Principal; import org.candlepin.auth.SubResource; import org.candlepin.auth.Verify; import org.candlepin.common.exceptions.ConflictException; import org.candlepin.common.exceptions.GoneException; import org.candlepin.common.exceptions.NotFoundException; import org.candlepin.model.Owner; import org.candlepin.model.OwnerCurator; import org.candlepin.model.Role; import org.candlepin.model.User; import org.candlepin.service.UserServiceAdapter; import com.google.inject.Inject; import org.xnap.commons.i18n.I18n; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import io.swagger.annotations.Authorization; /** * UserResource */ @Path("/users") @Api(value = "users", authorizations = { @Authorization("basic") }) public class UserResource { private UserServiceAdapter userService; private I18n i18n; private OwnerCurator ownerCurator; @Inject public UserResource(UserServiceAdapter userService, I18n i18n, OwnerCurator ownerCurator) { this.userService = userService; this.i18n = i18n; this.ownerCurator = ownerCurator; } @ApiOperation(notes = "Retrieves a list of Users", value = "list") @GET @Produces(MediaType.APPLICATION_JSON) public List<User> list() { return userService.listUsers(); } @ApiOperation(notes = "Retrieves a single User", value = "getUserInfo") @GET @Path("/{username}") @Produces(MediaType.APPLICATION_JSON) public User getUserInfo(@PathParam("username") @Verify(User.class) String username) { return userService.findByLogin(username); } /* * getUserRoles will only return roles for one user. If you want a * full view of a role, use /roles/ instead. */ @ApiOperation(notes = "Retrieves a list of Roles by User", value = "getUserRoles") @GET @Path("/{username}/roles") @Produces(MediaType.APPLICATION_JSON) public List<Role> getUserRoles(@PathParam("username") @Verify(User.class) String username) { User myUser = userService.findByLogin(username); List<Role> roles = new LinkedList<Role>(); Set<User> s = new HashSet<User>(); s.add(myUser); for (Role r : myUser.getRoles()) { // Copy onto a detached role object so we can omit users list, which could // technically leak information here. Role copy = new Role(r.getName()); copy.setId(r.getId()); copy.setPermissions(r.getPermissions()); copy.setUsers(s); roles.add(copy); } return roles; } @ApiOperation(notes = "Creates a User", value = "createUser") // We declare an implict parameter to get the Swagger generated client to submit passwords but not to // expect them back. @ApiImplicitParams({ @ApiImplicitParam(name = "user", paramType = "body", required = true, dataType = "org.candlepin.model.User$UserCreationRequest") }) @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public User createUser(@ApiParam(hidden = true) User user) { if (userService.findByLogin(user.getUsername()) != null) { throw new ConflictException("user " + user.getUsername() + " already exists"); } return userService.createUser(user); } @ApiOperation(notes = "Updates a User", value = "updateUser") @ApiResponses({ @ApiResponse(code = 404, message = "") }) @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Path("/{username}") public User updateUser(@PathParam("username") @Verify(User.class) String username, @ApiParam(name = "user", required = true) User user) { // Note, to change the username, the old username needs to be provided. if (userService.findByLogin(username) == null) { throw new NotFoundException(i18n.tr("User {0} does not exist", username)); } return userService.updateUser(user); } @ApiOperation(notes = "Removes a User", value = "deleteUser") @ApiResponses({ @ApiResponse(code = 410, message = "") }) @DELETE @Path("/{username}") @Produces(MediaType.APPLICATION_JSON) public void deleteUser(@PathParam("username") String username) { User user = userService.findByLogin(username); if (user == null) { throw new GoneException(i18n.tr("User {0} not found", username), username); } else { userService.deleteUser(user); } } @ApiOperation(notes = "Retrieve a list of owners the user can register systems to. " + "Previously this represented owners the user was an admin for. Because the " + "client uses this API call to list the owners a user can register to, when " + "we introduced 'my systems' administrator, we have to change its meaning to " + "listing the owners that can be registered to by default to maintain " + "compatability with released clients.", value = "listUsersOwners") // TODO: should probably accept access level and sub-resource query params someday @GET @Path("/{username}/owners") @Produces(MediaType.APPLICATION_JSON) public Iterable<Owner> listUsersOwners( @PathParam("username") @Verify(User.class) String username, @Context Principal principal) { User user = userService.findByLogin(username); return user.isSuperAdmin() ? this.ownerCurator.listAll() : user.getOwners(SubResource.CONSUMERS, Access.CREATE); } }