/* * Copyright (c) 2015-2018 Open Baton (http://openbaton.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.openbaton.nfvo.api.admin; import com.google.gson.Gson; import com.google.gson.JsonObject; import io.swagger.annotations.ApiOperation; import java.util.List; import javax.validation.Valid; import org.openbaton.catalogue.security.Role; import org.openbaton.catalogue.security.User; import org.openbaton.exceptions.BadRequestException; import org.openbaton.exceptions.NotAllowedException; import org.openbaton.exceptions.NotFoundException; import org.openbaton.exceptions.PasswordWeakException; import org.openbaton.nfvo.core.interfaces.UserManagement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.oauth2.common.exceptions.UnauthorizedUserException; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/v1/users") public class RestUsers { private Logger log = LoggerFactory.getLogger(this.getClass()); @Autowired private UserManagement userManagement; @Autowired private Gson gson; /** * Adds a new User to the Users repository * * @param user * @return user */ @ApiOperation( value = "Adding a User", notes = "The User data is passed as JSON in the Request Body") @RequestMapping( method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.CREATED) @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public User create(@RequestBody @Valid User user) throws PasswordWeakException, NotAllowedException, BadRequestException, NotFoundException { log.info("Adding user: " + user.getUsername()); if (isAdmin()) { user = userManagement.add(user); // user.setPassword(null); } else { throw new NotAllowedException("Forbidden to create a new user"); } return user; } /** * Removes the User from the Users repository * * @param id : the id of user to be removed */ @ApiOperation( value = "Remove a User", notes = "Removes the user with the id specified in the URL. Admin privileges needed!") @RequestMapping(value = "{id}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public void delete(@PathVariable("id") String id) throws NotAllowedException, NotFoundException { log.info("Removing user with id " + id); if (isAdmin()) { if (!userManagement.getCurrentUser().getId().equals(id)) { User user = userManagement.query(id); userManagement.delete(user); } else { throw new NotAllowedException("You can't delete yourself. Please ask another admin."); } } else { throw new NotAllowedException("Forbidden to delete a user"); } } @ApiOperation( value = "Remove multiple Users", notes = "Removes all users part of the List of ids passed in the Request Body") @RequestMapping( value = "/multipledelete", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.NO_CONTENT) public void multipleDelete(@RequestBody @Valid List<String> ids) throws NotFoundException { if (userManagement != null) { for (String id : ids) { log.info("removing User with id " + id); userManagement.delete(userManagement.query(id)); } } } /** * Returns the list of the Users available * * @return List<User>: The list of Users available */ @ApiOperation(value = "Retrieve all Users", notes = "Returns all registered users") @RequestMapping(method = RequestMethod.GET) public List<User> findAll() { log.trace("Find all Users"); return (List<User>) userManagement.query(); } /** * Returns the User selected by username * * @param username : The username of the User * @return User: The User selected */ @ApiOperation( value = "Retrieve a User", notes = "Retrieves a user based on the username specified in the URL") @RequestMapping(value = "{username}", method = RequestMethod.GET) public User findById(@PathVariable("username") String username) throws NotFoundException { log.trace("find User with username " + username); User user = userManagement.query(username); log.trace("Found User: " + user); return user; } @ApiOperation(value = "Retrieve the current User", notes = "Returns the user currently accessing") @RequestMapping(value = "current", method = RequestMethod.GET) public User findCurrentUser() throws NotFoundException { User user = userManagement.getCurrentUser(); log.trace("Found User: " + user); return user; } /** * Updates the User * * @param new_user : The User to be updated * @return User The User updated */ @ApiOperation( value = "Update a User", notes = "Updates a user based on the username specified in the url and the updated user body in the request") @RequestMapping( value = "{username}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.ACCEPTED) @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public User update(@RequestBody @Valid User new_user) throws NotAllowedException, BadRequestException, NotFoundException { return userManagement.update(new_user); } @ApiOperation( value = "Changing the current User's password", notes = "The current user can change his password by providing a new one") @RequestMapping( value = "changepwd", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.ACCEPTED) public void changePassword(@RequestBody /*@Valid*/ JsonObject newPwd) throws UnauthorizedUserException, PasswordWeakException { log.debug("Changing password"); JsonObject jsonObject = gson.fromJson(newPwd, JsonObject.class); userManagement.changePassword( jsonObject.get("old_pwd").getAsString(), jsonObject.get("new_pwd").getAsString()); } @ApiOperation( value = "Changing a User's password", notes = "If you want to change another User's password, you have to be an admin") @RequestMapping( value = "changepwd/{username}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseStatus(HttpStatus.ACCEPTED) @PreAuthorize("hasAnyRole('ROLE_ADMIN')") public void changePasswordOf( @PathVariable("username") String username, @RequestBody /*@Valid*/ JsonObject newPwd) throws UnauthorizedUserException, PasswordWeakException, NotFoundException, NotAllowedException { log.debug("Changing password of user " + username); if (isAdmin()) { JsonObject jsonObject = gson.fromJson(newPwd, JsonObject.class); userManagement.changePasswordOf(username, jsonObject.get("new_pwd").getAsString()); } else { throw new NotAllowedException( "Forbidden to change password of other users. Only admins can do this."); } } public boolean isAdmin() throws NotFoundException { User currentUser = userManagement.getCurrentUser(); log.trace("Check user if admin: " + currentUser.getUsername()); for (Role role : currentUser.getRoles()) { if (role.getRole().ordinal() == Role.RoleEnum.ADMIN.ordinal()) { return true; } } return false; } }