@Override
  protected boolean canDoAction() {
    Permissions perm = getParameters().getPermission();
    if (perm == null) {
      addCanDoActionMessage(VdcBllMessages.PERMISSION_ADD_FAILED_PERMISSION_NOT_SENT);
      return false;
    }

    Role role = getRoleDao().get(perm.getrole_id());
    Guid adElementId = perm.getad_element_id();

    if (role == null) {
      addCanDoActionMessage(VdcBllMessages.PERMISSION_ADD_FAILED_INVALID_ROLE_ID);
      return false;
    }

    if (perm.getObjectType() == null || getVdcObjectName() == null) {
      addCanDoActionMessage(VdcBllMessages.PERMISSION_ADD_FAILED_INVALID_OBJECT_ID);
      return false;
    }

    // if user and group not sent check user/group is in the db in order to
    // give permission
    if (getParameters().getUser() == null
        && getParameters().getGroup() == null
        && getDbUserDAO().get(adElementId) == null
        && getAdGroupDAO().get(adElementId) == null) {
      getReturnValue()
          .getCanDoActionMessages()
          .add(VdcBllMessages.USER_MUST_EXIST_IN_DB.toString());
      return false;
    }

    // only system super user can give permissions with admin roles
    if (!isSystemSuperUser() && role.getType() == RoleType.ADMIN) {
      addCanDoActionMessage(
          VdcBllMessages.PERMISSION_ADD_FAILED_ONLY_SYSTEM_SUPER_USER_CAN_GIVE_ADMIN_ROLES);
      return false;
    }

    // don't allow adding permissions to vms from pool externally
    if (!isInternalExecution() && perm.getObjectType() == VdcObjectType.VM) {
      VM vm = getVmDAO().get(perm.getObjectId());
      if (vm != null && vm.getVmPoolId() != null) {
        addCanDoActionMessage(VdcBllMessages.PERMISSION_ADD_FAILED_VM_IN_POOL);
        return false;
      }
    }

    return true;
  }
 @Override
 public List<PermissionSubject> getPermissionCheckSubjects() {
   Permissions permission = getParameters().getPermission();
   List<PermissionSubject> permissionsSubject = new ArrayList<>();
   permissionsSubject.add(
       new PermissionSubject(
           permission.getObjectId(),
           permission.getObjectType(),
           getActionType().getActionGroup()));
   initUserAndGroupData();
   // if the user does not exist in the database we need to
   // check if the logged in user has permissions to add another
   // user from the directory service
   if ((getParameters().getUser() != null && dbUser == null)
       || (getParameters().getGroup() != null && dbGroup == null)) {
     permissionsSubject.add(
         new PermissionSubject(
             permission.getObjectId(),
             permission.getObjectType(),
             ActionGroup.ADD_USERS_AND_GROUPS_FROM_DIRECTORY));
   }
   return permissionsSubject;
 }
  @Override
  protected void executeCommand() {
    // Get the parameters:
    T parameters = getParameters();

    // The user or group given in the parameters may haven't been added to the database yet, if this
    // is the case
    // then they need to be added to the database now, before the permission:
    DbUser user = parameters.getUser();
    if (user != null) {
      Guid id = user.getId();
      String directory = user.getDomain();
      String externalId = user.getExternalId();
      DbUser existing = getDbUserDAO().getByIdOrExternalId(id, directory, externalId);
      if (existing != null) {
        user = existing;
      } else {
        user = addUser(user);
        if (user == null) {
          setSucceeded(false);
          return;
        }
      }
    }
    DbGroup group = parameters.getGroup();
    if (group != null) {
      Guid id = group.getId();
      String directory = group.getDomain();
      String externalId = group.getExternalId();
      DbGroup existing = getAdGroupDAO().getByIdOrExternalId(id, directory, externalId);
      if (existing != null) {
        group = existing;
      } else {
        group = addGroup(group);
        if (group == null) {
          setSucceeded(false);
          return;
        }
      }
    }

    // The identifier of the principal of the permission can come from the parameters directly or
    // from the
    // user/group objects:
    Guid principalId;
    if (user != null) {
      principalId = user.getId();
    } else if (group != null) {
      principalId = group.getId();
    } else {
      principalId = parameters.getPermission().getad_element_id();
    }

    final Permissions paramPermission = parameters.getPermission();

    Permissions permission =
        getPermissionDAO()
            .getForRoleAndAdElementAndObject(
                paramPermission.getrole_id(), principalId, paramPermission.getObjectId());

    if (permission == null) {
      paramPermission.setId(Guid.newGuid());
      paramPermission.setad_element_id(principalId);

      TransactionSupport.executeInNewTransaction(
          new TransactionMethod<Void>() {
            @Override
            public Void runInTransaction() {
              getPermissionDAO().save(paramPermission);
              getCompensationContext().snapshotNewEntity(paramPermission);
              getCompensationContext().stateChanged();
              return null;
            }
          });
      permission = paramPermission;
    }

    getReturnValue().setActionReturnValue(permission.getId());

    if (user != null) {
      updateAdminStatus(permission);
    }
    setSucceeded(true);
  }