Package org.ngrinder.user.controller

Source Code of org.ngrinder.user.controller.UserController

/*
* 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.ngrinder.user.controller;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.gson.annotations.Expose;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.lang.StringUtils;
import org.ngrinder.common.constant.ControllerConstants;
import org.ngrinder.common.controller.BaseController;
import org.ngrinder.common.controller.RestAPI;
import org.ngrinder.infra.config.Config;
import org.ngrinder.model.Permission;
import org.ngrinder.model.Role;
import org.ngrinder.model.User;
import org.ngrinder.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefaults;
import org.springframework.http.HttpEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;

import static org.ngrinder.common.util.CollectionUtils.newArrayList;
import static org.ngrinder.common.util.ObjectUtils.defaultIfNull;
import static org.ngrinder.common.util.Preconditions.*;

/**
* User management controller.
*
* @author JunHo Yoon
* @author Alex Quin
* @since 3.0
*/
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {

  @Autowired
  private UserService userService;

  @Autowired
  protected Config config;

  private ServletContext servletContext;


  /**
   * Get user list on the given role.
   *
   * @param model    model
   * @param role     role
   * @param pageable page info
   * @param keywords search keyword.
   * @return user/userList
   */
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping({"", "/"})
  public String getAll(ModelMap model, @RequestParam(required = false) Role role,
                       @PageableDefaults Pageable pageable,
                       @RequestParam(required = false) String keywords) {

    pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(),
        defaultIfNull(pageable.getSort(),
            new Sort(Direction.ASC, "userName")));
    Page<User> pagedUser;
    if (StringUtils.isEmpty(keywords)) {
      pagedUser = userService.getPagedAll(role, pageable);
    } else {
      pagedUser = userService.getPagedAll(keywords, pageable);
      model.put("keywords", keywords);
    }
    model.addAttribute("users", pagedUser);
    EnumSet<Role> roleSet = EnumSet.allOf(Role.class);
    model.addAttribute("roleSet", roleSet);
    model.addAttribute("role", role);
    putPageIntoModelMap(model, pageable);
    return "user/list";
  }


  /**
   * Get user creation form page.
   *
   * @param user  current user
   * @param model mode
   * @return "user/detail"
   */
  @RequestMapping("/new")
  @PreAuthorize("hasAnyRole('A') or #user.userId == #userId")
  public String openForm(User user, final ModelMap model) {
    User one = User.createNew();
    model.addAttribute("user", one);
    model.addAttribute("allowUserIdChange", true);
    model.addAttribute("allowPasswordChange", true);
    model.addAttribute("allowRoleChange", false);
    model.addAttribute("newUser", true);
    model.addAttribute("roleSet", EnumSet.allOf(Role.class));
    model.addAttribute("showPasswordByDefault", true);
    attachCommonAttribute(one, model);
    return "user/detail";
  }

  /**
   * Get user detail page.
   *
   * @param model  mode
   * @param userId user to get
   * @return "user/detail"
   */
  @RequestMapping("/{userId}")
  @PreAuthorize("hasAnyRole('A')")
  public String getOne(@PathVariable final String userId, ModelMap model) {
    User one = userService.getOne(userId);
    model.addAttribute("user", one);
    model.addAttribute("allowPasswordChange", true);
    model.addAttribute("allowRoleChange", true);
    model.addAttribute("roleSet", EnumSet.allOf(Role.class));
    model.addAttribute("showPasswordByDefault", false);
    attachCommonAttribute(one, model);
    return "user/detail";
  }

  /**
   * Get the current user profile.
   *
   * @param user  current user
   * @param model model
   * @return "user/info"
   */
  @RequestMapping("/profile")
  public String getOne(User user, ModelMap model) {
    checkNotEmpty(user.getUserId(), "UserID should not be NULL!");
    User one = userService.getOne(user.getUserId());
    model.addAttribute("user", one);
    model.addAttribute("allowPasswordChange", !config.isDemo());
    model.addAttribute("allowRoleChange", false);
    model.addAttribute("showPasswordByDefault", false);
    attachCommonAttribute(one, model);
    return "user/info";
  }

  /**
   * Save or Update user detail info.
   *
   * @param user        current user
   * @param model       model
   * @param updatedUser user to be updated.
   * @return "redirect:/user/list" if current user change his info, otherwise return "redirect:/"
   */
  @RequestMapping("/save")
  @PreAuthorize("hasAnyRole('A') or #user.id == #updatedUser.id")
  public String save(User user, @ModelAttribute("user") User updatedUser, ModelMap model) {
    checkArgument(updatedUser.validate());
    if (user.getRole() == Role.USER) {
      // General user can not change their role.
      User updatedUserInDb = userService.getOne(updatedUser.getUserId());
      checkNotNull(updatedUserInDb);
      updatedUser.setRole(updatedUserInDb.getRole());

      // prevent user to modify with other user id
      checkArgument(updatedUserInDb.getId().equals(updatedUser.getId()), "Illegal request to update user:%s",
          updatedUser);
    }
    save(updatedUser);
    model.clear();
    if (user.getId().equals(updatedUser.getId())) {
      return "redirect:/";
    } else {
      return "redirect:/user/";
    }
  }

  private User save(User user) {
    if (StringUtils.isBlank(user.getPassword())) {
      return userService.saveWithoutPasswordEncoding(user);
    } else {
      return userService.save(user);
    }
  }

  /**
   * Delete users.
   *
   * @param model   model
   * @param userIds comma separated user ids.
   * @return "redirect:/user/"
   */
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping("/delete")
  public String delete(User user, @RequestParam String userIds, ModelMap model) {
    String[] ids = userIds.split(",");
    for (String eachId : Arrays.asList(ids)) {
      if (!user.getUserId().equals(eachId)) {
        userService.delete(eachId);
      }
    }
    model.clear();
    return "redirect:/user/";
  }


  /**
   * Get the follower list.
   *
   * @param user     current user
   * @param keywords search keyword.
   * @return json message
   */
  @RestAPI
  @RequestMapping("/api/switch_options")
  public HttpEntity<String> switchOptions(User user,
                                          @RequestParam(required = true) final String keywords) {
    return toJsonHttpEntity(getSwitchableUsers(user, keywords));
  }

  /**
   * Get the follower list.
   *
   * @param user  current user
   * @param model model
   * @return json message
   */
  @RequestMapping("/switch_options")
  public String switchOptions(User user,
                              ModelMap model) {
    model.addAttribute("switchableUsers", getSwitchableUsers(user, ""));
    return "user/switch_options";
  }


  private List<UserSearchResult> getSwitchableUsers(User user, String keywords) {
    List<UserSearchResult> result = newArrayList();
    if (user.getRole().hasPermission(Permission.SWITCH_TO_ANYONE)) {
      for (User each : userService.getPagedAll(keywords, new PageRequest(0, 10))) {
        result.add(new UserSearchResult(each));
      }
    } else {
      User currUser = userService.getOne(user.getUserId());
      for (User each : currUser.getOwners()) {
        result.add(new UserSearchResult(each));
      }
    }
    return result;
  }


  /**
   * Switch user identity.
   *
   * @param model    model
   * @param to       the user to whom a user will switch
   * @param response response
   * @return redirect:/perftest/
   */
  @RequestMapping("/switch")
  public String switchUser(@RequestParam(required = false, defaultValue = "") String to,
                           HttpServletRequest request, HttpServletResponse response, ModelMap model) {
    Cookie cookie = new Cookie("switchUser", to);
    cookie.setPath("/");
    // Delete Cookie if empty switchUser
    if (StringUtils.isEmpty(to)) {
      cookie.setMaxAge(0);
    }

    response.addCookie(cookie);
    model.clear();
    final String referer = request.getHeader("referer");
    return "redirect:" + StringUtils.defaultIfBlank(referer, "/");
  }

  /**
   * Get user list that current user will be shared, excluding current user.
   *
   * @param user  current user
   * @param model model
   */
  protected void attachCommonAttribute(User user, ModelMap model) {
    List list = user.getFollowers() == null ? Lists.newArrayList() : user.getFollowers();
    model.addAttribute("followers", Lists.transform(list, new Function<User, UserSearchResult>() {
      public UserSearchResult apply(User user) {
        return new UserSearchResult(user);
      }
    }));
    model.addAttribute("allowShareChange", true);
    model.addAttribute("userSecurityEnabled", config.isUserSecurityEnabled());
  }

  /**
   * Check if the given user id already exists.
   *
   * @param userId userId to be checked
   * @return success json if true.
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping("/api/{userId}/check_duplication")
  public HttpEntity<String> checkDuplication(@PathVariable String userId) {
    User user = userService.getOne(userId);
    return (user == null) ? successJsonHttpEntity() : errorJsonHttpEntity();
  }

  /**
   * Get users by the given role.
   *
   * @param role user role
   * @return json message
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping(value = {"/api/", "/api"}, method = RequestMethod.GET)
  public HttpEntity<String> getAll(Role role) {
    return toJsonHttpEntity(userService.getAll(role));
  }

  /**
   * Get the user by the given user id.
   *
   * @param userId user id
   * @return json message
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping(value = "/api/{userId}", method = RequestMethod.GET)
  public HttpEntity<String> getOne(@PathVariable("userId") String userId) {
    return toJsonHttpEntity(userService.getOne(userId));
  }

  /**
   * Create an user.
   *
   * @param newUser new user
   * @return json message
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping(value = {"/api/", "/api"}, method = RequestMethod.POST)
  public HttpEntity<String> create(@ModelAttribute("user") User newUser) {
    checkNull(newUser.getId(), "User DB ID should be null");
    return toJsonHttpEntity(save(newUser));
  }

  /**
   * Update the user.
   *
   * @param userId user id
   * @param update update user
   * @return json message
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping(value = "/api/{userId}", method = RequestMethod.PUT)
  public HttpEntity<String> update(@PathVariable("userId") String userId, User update) {
    update.setUserId(userId);
    checkNull(update.getId(), "User DB ID should be null");
    return toJsonHttpEntity(save(update));
  }

  /**
   * Delete the user by the given userId.
   *
   * @param userId user id
   * @return json message
   */
  @RestAPI
  @PreAuthorize("hasAnyRole('A')")
  @RequestMapping(value = "/api/{userId}", method = RequestMethod.DELETE)
  public HttpEntity<String> delete(User user, @PathVariable("userId") String userId) {
    if (!user.getUserId().equals(userId)) {
      userService.delete(userId);
    }
    return successJsonHttpEntity();
  }

  /**
   * Search user list on the given keyword.
   *
   * @param pageable page info
   * @param keywords search keyword.
   * @return json message
   */
  @RestAPI
  @RequestMapping(value = "/api/search", method = RequestMethod.GET)
  public HttpEntity<String> search(User user, @PageableDefaults Pageable pageable,
                                   @RequestParam(required = true) String keywords) {
    pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(),
        defaultIfNull(pageable.getSort(),
            new Sort(Direction.ASC, "userName")));
    Page<User> pagedUser = userService.getPagedAll(keywords, pageable);
    List<UserSearchResult> result = newArrayList();
    for (User each : pagedUser) {
      result.add(new UserSearchResult(each));
    }

    final String currentUserId = user.getUserId();
    CollectionUtils.filter(result, new Predicate() {
      @Override
      public boolean evaluate(Object object) {
        UserSearchResult each = (UserSearchResult) object;
        return !(each.getId().equals(currentUserId) || each.getId().equals(ControllerConstants.NGRINDER_INITIAL_ADMIN_USERID));
      }
    });

    return toJsonHttpEntity(result);
  }

  public static class UserSearchResult {
    @Expose
    final private String id;

    @Expose
    final private String text;

    public UserSearchResult(User user) {
      id = user.getUserId();
      final String email = user.getEmail();
      final String userName = user.getUserName();
      if (StringUtils.isEmpty(email)) {
        this.text = userName + " (" + id + ")";
      } else {
        this.text = userName + " (" + email + " / " + id + ")";
      }
    }

    public String getText() {
      return text;
    }

    public String getId() {
      return id;
    }
  }
}
TOP

Related Classes of org.ngrinder.user.controller.UserController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.