@Transactional(propagation = Propagation.SUPPORTS)
  public boolean hasAccessToDevice(AccessKey accessKey, String deviceGuid) {
    Set<AccessKeyPermission> permissions = accessKey.getPermissions();
    Set<String> allowedDevices = new HashSet<>();
    Set<Long> allowedNetworks = new HashSet<>();

    User accessKeyUser = userService.findUserWithNetworks(accessKey.getUser().getId());
    Set<AccessKeyPermission> toRemove = new HashSet<>();

    Device device =
        genericDAO
            .createNamedQuery(Device.class, "Device.findByUUID", of(CacheConfig.refresh()))
            .setParameter("guid", deviceGuid)
            .getSingleResult();

    for (AccessKeyPermission currentPermission : permissions) {
      if (currentPermission.getDeviceGuidsAsSet() == null) {
        allowedDevices.add(null);
      } else {
        if (!currentPermission.getDeviceGuidsAsSet().contains(deviceGuid)) {
          toRemove.add(currentPermission);
        } else {
          allowedDevices.addAll(currentPermission.getDeviceGuidsAsSet());
        }
      }
      if (currentPermission.getNetworkIdsAsSet() == null) {
        allowedNetworks.add(null);
      } else {
        if (device.getNetwork() != null) {
          if (!currentPermission.getNetworkIdsAsSet().contains(device.getNetwork().getId())) {
            toRemove.add(currentPermission);
          } else {
            allowedNetworks.addAll(currentPermission.getNetworkIdsAsSet());
          }
        }
      }
    }
    permissions.removeAll(toRemove);
    boolean hasAccess;
    hasAccess =
        allowedDevices.contains(null)
            ? userService.hasAccessToDevice(accessKeyUser, device.getGuid())
            : allowedDevices.contains(device.getGuid())
                && userService.hasAccessToDevice(accessKeyUser, device.getGuid());

    hasAccess =
        hasAccess && allowedNetworks.contains(null)
            ? accessKeyUser.isAdmin() || accessKeyUser.getNetworks().contains(device.getNetwork())
            : (accessKeyUser.isAdmin() || accessKeyUser.getNetworks().contains(device.getNetwork()))
                && allowedNetworks.contains(device.getNetwork().getId());

    return hasAccess;
  }
 public static Set<AccessKeyBasedFilterForNetworks> createExtraFilters(
     Set<AccessKeyPermission> permissionSet) {
   if (permissionSet == null) {
     return null;
   }
   Set<AccessKeyBasedFilterForNetworks> result = new HashSet<>();
   for (AccessKeyPermission akp : permissionSet) {
     result.add(new AccessKeyBasedFilterForNetworks(akp.getNetworkIdsAsSet()));
   }
   return result;
 }
 private AccessKeyPermission preparePermission(AccessKeyPermission current) {
   AccessKeyPermission newPermission = new AccessKeyPermission();
   if (current.getDomainsAsSet() != null) {
     newPermission.setDomains(current.getDomains());
   }
   if (current.getSubnetsAsSet() != null) {
     newPermission.setSubnets(current.getSubnets());
   }
   if (current.getActionsAsSet() != null) {
     newPermission.setActions(current.getActions());
   }
   if (current.getNetworkIdsAsSet() != null) {
     newPermission.setNetworkIds(current.getNetworkIds());
   }
   if (current.getDeviceGuidsAsSet() != null) {
     newPermission.setDeviceGuids(current.getDeviceGuids());
   }
   return newPermission;
 }