package com.sparc.knappsack.components.controllers;
import com.sparc.knappsack.components.entities.DomainUserRequest;
import com.sparc.knappsack.components.entities.Group;
import com.sparc.knappsack.components.entities.User;
import com.sparc.knappsack.components.entities.UserDomain;
import com.sparc.knappsack.components.services.*;
import com.sparc.knappsack.components.validators.GroupValidator;
import com.sparc.knappsack.enums.SortOrder;
import com.sparc.knappsack.enums.Status;
import com.sparc.knappsack.enums.UserRole;
import com.sparc.knappsack.exceptions.EntityNotFoundException;
import com.sparc.knappsack.forms.GroupForm;
import com.sparc.knappsack.forms.Result;
import com.sparc.knappsack.models.*;
import com.sparc.knappsack.models.api.v1.Application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@Controller
public class GroupController extends AbstractController {
private static final Logger log = LoggerFactory.getLogger(GroupController.class);
@Autowired(required = true)
private GroupService groupService;
@Autowired(required = true)
private DomainUserRequestService requestService;
@Autowired(required = true)
private UserService userService;
@Autowired(required = true)
private UserDomainService userDomainService;
@Qualifier("groupValidator")
@Autowired(required = true)
private GroupValidator groupValidator;
@Qualifier("applicationService")
@Autowired(required = true)
private ApplicationService applicationService;
@Qualifier("messageSource")
@Autowired(required = true)
private MessageSource messageSource;
@InitBinder("group")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(groupValidator);
}
@RequestMapping(value = "/manager/viewGroups", method = RequestMethod.GET)
public String viewGroups() {
return "manager/groupsTH";
}
@PreAuthorize("isOrganizationAdmin() or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/addGroup", method = RequestMethod.GET)
public String addGroup(Model model) {
if (!model.containsAttribute("group")) {
model.addAttribute("group", new GroupForm());
}
User user = userService.getUserFromSecurityContext();
model.addAttribute("organizations", user.getActiveOrganization());
return "manager/manageGroupTH";
}
@PreAuthorize("isDomainAdmin(#id) or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/editGroup/{id}", method = RequestMethod.GET)
public String editGroup(Model model, @PathVariable Long id) {
checkRequiredEntity(groupService, id);
Group existingGroup = groupService.get(id);
if (existingGroup != null) {
GroupForm groupForm = new GroupForm();
groupService.mapGroupToGroupForm(existingGroup, groupForm);
model.addAttribute("group", groupForm);
model.addAttribute("accessCode", existingGroup.getUuid());
List<DomainUserRequest> requests = requestService.getAll(existingGroup.getId(), Status.PENDING);
List<DomainUserRequestModel> pendingRequests = new ArrayList<DomainUserRequestModel>();
if (requests != null) {
for (DomainUserRequest request : requests) {
DomainUserRequestModel requestModel = new DomainUserRequestModel();
requestModel.setId(request.getId());
UserModel userModel = new UserModel();
userModel.setEmail(request.getUser().getEmail());
userModel.setUserName(request.getUser().getUsername());
userModel.setFirstName(request.getUser().getFirstName());
userModel.setLastName(request.getUser().getLastName());
userModel.setId(request.getUser().getId());
requestModel.setUser(userModel);
pendingRequests.add(requestModel);
}
}
if (pendingRequests.size() > 0) {
model.addAttribute("hasPendingRequests", true);
}
model.addAttribute("pendingRequests", pendingRequests);
List<UserRole> groupUserRoles = new ArrayList<UserRole>();
groupUserRoles.add(UserRole.ROLE_GROUP_USER);
groupUserRoles.add(UserRole.ROLE_GROUP_ADMIN);
model.addAttribute("userRoles", groupUserRoles);
List<UserDomain> groupUsers = userDomainService.getAll(existingGroup.getId());
model.addAttribute("groupUsers", groupUsers);
model.addAttribute("domainStatistics", getDomainStatisticsModel(existingGroup));
}
model.addAttribute("isEdit", true);
return "manager/manageGroupTH";
}
@PreAuthorize("isDomainAdmin(#id) or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/deleteGroup", method = RequestMethod.POST)
public @ResponseBody Result deleteGroup(@RequestParam(required = true) Long id) {
Result result = new Result();
try {
checkRequiredEntity(groupService, id);
} catch (EntityNotFoundException ex) {
log.info(String.format("Attempted to delete non-existent group: %s", id));
result.setResult(false);
return result;
}
groupService.delete(id);
result.setResult(!groupService.doesEntityExist(id));
return result;
}
@PreAuthorize("(#groupForm.id != null ? isDomainAdmin(#groupForm.id) : isOrganizationAdminForActiveOrganization()) or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/uploadGroup", method = RequestMethod.POST)
public String uploadGroup(Model model, @ModelAttribute("group") @Validated GroupForm groupForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return addGroup(model);
}
Long groupId = groupForm.getId();
if (groupForm.getId() != null && groupForm.getId() > 0) {
groupService.editGroup(groupForm);
} else {
Group group = groupService.createGroup(groupForm);
if (group == null || group.getId() == null || group.getId() <= 0) {
String[] codes = {"desktop.manager.group.create.error"};
ObjectError error = new ObjectError("groupForm", codes, null, null);
bindingResult.addError(error);
return addGroup(model);
}
groupId = group.getId();
}
if (groupId == null || groupId <= 0) {
return "redirect:/manager/viewGroups";
}
return "redirect:/manager/editGroup/" + groupId;
}
@PreAuthorize("isDomainAdmin(#groupId) or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/removeUsers", method = RequestMethod.POST)
public
@ResponseBody
Result removeUsers(@RequestParam Long groupId, @RequestParam(value = "userIds[]") List<Long> userIds) {
Result result = new Result();
if (groupId != null && groupId > 0 && userIds != null) {
for (Long userId : userIds) {
groupService.removeUserFromGroup(groupId, userId);
}
result.setResult(true);
} else {
result.setResult(false);
}
return result;
}
@PreAuthorize("isDomainAdmin() or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/getGroupsForUser", method = RequestMethod.GET)
public @ResponseBody List<GroupModel> getGroupsForUser() {
User user = userService.getUserFromSecurityContext();
List<GroupModel> models = new ArrayList<GroupModel>();
for (Group group : userService.getAdministeredGroups(user, SortOrder.ASCENDING)) {
models.add(groupService.createGroupModelWithOrganization(group, false, false));
}
return models;
}
@PreAuthorize("isOrganizationAdminForActiveOrganization() or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/createGroup", method = RequestMethod.POST)
public @ResponseBody Result createGroupAJAX(final HttpServletRequest request, @RequestParam(required = true) String name) {
Result result = new Result();
GroupForm groupForm = new GroupForm();
groupForm.setName(StringUtils.trimTrailingWhitespace(name));
boolean isValid = false;
// Validate
Errors errors = new BeanPropertyBindingResult(groupForm, "groupForm");
groupValidator.validate(groupForm, errors);
if (!errors.hasErrors()) {
isValid = true;
}
// Only attempt to create group if validation passed
if (isValid) {
Group group = groupService.createGroup(groupForm);
// Check if group was actually created or not
if (group == null || group.getId() == null || group.getId() <= 0) {
// Add generic error
errors.reject("groupValidator.generic");
result.setResult(false);
} else {
// Group created successfully so add groupModel to result
result.setResult(true);
result.setValue(groupService.createGroupModel(group));
}
}
// If result is false then loop over errors and add Internationalized objects to result
if (!result.getResult()) {
result.setValue(new ArrayList<InternationalizedObject>());
for (ObjectError error : errors.getAllErrors()) {
try {
((List)result.getValue()).add(new InternationalizedObject(error.getCode(), messageSource.getMessage(error.getCode(), null, request.getLocale())));
} catch (NoSuchMessageException ex) {
log.error(String.format("No message for error with code: %s", error.getCode()), ex);
// Put the applicationType name so that the application doesn't error out.
((List)result.getValue()).add(new InternationalizedObject(error.getCode(), error.getCode()));
}
}
}
return result;
}
@PreAuthorize("isDomainAdmin(#groupId) or hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/manager/getOwnedApplicationsForGroup", method = RequestMethod.GET)
public @ResponseBody List<Application> getOwnedApplicationsForGroup(@RequestParam(value = "grp", required = true) Long groupId) {
List<Application> applicationModels = new ArrayList<Application>();
Group group = groupService.get(groupId);
if (group == null) {
return applicationModels;
}
return applicationService.getApplicationModels(group.getOwnedApplications(), Application.class);
}
private DomainStatisticsModel getDomainStatisticsModel(Group group) {
DomainStatisticsModel domainStatisticsModel = new DomainStatisticsModel();
domainStatisticsModel.setTotalApplications(groupService.getTotalApplications(group));
domainStatisticsModel.setTotalApplicationVersions(groupService.getTotalApplicationVersions(group));
domainStatisticsModel.setTotalUsers(groupService.getTotalUsers(group));
domainStatisticsModel.setTotalPendingInvitations(groupService.getTotalPendingInvitations(group));
domainStatisticsModel.setTotalMegabyteStorageAmount(groupService.getTotalMegabyteStorageAmount(group));
return domainStatisticsModel;
}
}