@Transactional
 public AccessKey authenticate(@NotNull String key) {
   Optional<AccessKey> accessKeyOpt =
       genericDAO
           .createNamedQuery(AccessKey.class, "AccessKey.getByKey", Optional.of(CacheConfig.get()))
           .setParameter("someKey", key)
           .getResultList()
           .stream()
           .findFirst();
   if (!accessKeyOpt.isPresent()) {
     return null;
   }
   AccessKey accessKey = accessKeyOpt.get();
   final Long expirationPeriod =
       configurationService.getLong(Constants.SESSION_TIMEOUT, Constants.DEFAULT_SESSION_TIMEOUT);
   if (accessKey.getExpirationDate() != null) {
     final Long expiresIn =
         accessKey.getExpirationDate().getTime() - timestampService.getTimestamp().getTime();
     if (AccessKeyType.SESSION == accessKey.getType()
         && expiresIn > 0
         && expiresIn < expirationPeriod / 2) {
       em.refresh(accessKey, LockModeType.PESSIMISTIC_WRITE);
       accessKey.setExpirationDate(
           new Date(timestampService.getTimestamp().getTime() + expirationPeriod));
       return genericDAO.merge(accessKey);
     }
   }
   return accessKey;
 }
 @AroundInvoke
 public Object checkPermissions(InvocationContext context) throws Exception {
   try {
     logger.trace(Thread.currentThread().getName());
     HivePrincipal principal = ThreadLocalVariablesKeeper.getPrincipal();
     AccessKey key = principal.getKey();
     if (key == null) {
       return context.proceed();
     }
     if (key.getUser() == null || !key.getUser().getStatus().equals(UserStatus.ACTIVE)) {
       throw new HiveException(UNAUTHORIZED.getReasonPhrase(), UNAUTHORIZED.getStatusCode());
     }
     Timestamp expirationDate = key.getExpirationDate();
     if (expirationDate != null
         && expirationDate.before(new Timestamp(System.currentTimeMillis()))) {
       throw new HiveException(UNAUTHORIZED.getReasonPhrase(), UNAUTHORIZED.getStatusCode());
     }
     Method method = context.getMethod();
     AllowedKeyAction allowedActionAnnotation = method.getAnnotation(AllowedKeyAction.class);
     List<AllowedKeyAction.Action> actions = Arrays.asList(allowedActionAnnotation.action());
     boolean isAllowed = CheckPermissionsHelper.checkAllPermissions(key, actions);
     if (!isAllowed) {
       throw new HiveException(UNAUTHORIZED.getReasonPhrase(), UNAUTHORIZED.getStatusCode());
     }
     return context.proceed();
   } finally {
     ThreadLocalVariablesKeeper.clean();
   }
 }
 private void deleteAccessKeyPermissions(AccessKey key) {
   logger.debug("Deleting all permission of access key {}", key.getId());
   int deleted =
       genericDAO
           .createNamedQuery(
               "AccessKeyPermission.deleteByAccessKey", Optional.<CacheConfig>empty())
           .setParameter("accessKey", key)
           .executeUpdate();
   logger.info("Deleted {} permissions by access key {}", deleted, key.getId());
 }
  @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;
  }
 @Transactional
 public AccessKey create(@NotNull User user, @NotNull AccessKey accessKey) {
   if (accessKey.getLabel() == null) {
     throw new IllegalParametersException(Messages.LABEL_IS_REQUIRED);
   }
   Optional<AccessKey> akOpt =
       genericDAO
           .createNamedQuery(
               AccessKey.class, "AccessKey.getByUserAndLabel", Optional.<CacheConfig>empty())
           .setParameter("userId", user.getId())
           .setParameter("label", accessKey.getLabel())
           .getResultList()
           .stream()
           .findFirst();
   if (akOpt.isPresent()) {
     logger.error("Access key with label {} already exists", accessKey.getLabel());
     throw new ActionNotAllowedException(Messages.DUPLICATE_LABEL_FOUND);
   }
   if (accessKey.getId() != null) {
     logger.error("Access key id shouldn't be present in request parameters");
     throw new IllegalParametersException(Messages.INVALID_REQUEST_PARAMETERS);
   }
   authenticationUtils.validateActions(accessKey);
   AccessKeyProcessor keyProcessor = new AccessKeyProcessor();
   String key = keyProcessor.generateKey();
   accessKey.setKey(key);
   accessKey.setUser(user);
   genericDAO.persist(accessKey);
   for (AccessKeyPermission current : accessKey.getPermissions()) {
     AccessKeyPermission permission = preparePermission(current);
     permission.setAccessKey(accessKey);
     genericDAO.persist(permission);
   }
   return genericDAO.find(AccessKey.class, accessKey.getId());
 }
  @Transactional(propagation = Propagation.REQUIRED)
  public AccessKey authenticate(@NotNull User user) {
    userService.refreshUserLoginData(user);

    AccessKey accessKey = authenticationUtils.prepareAccessKey(user);

    Set<AccessKeyPermission> permissions = new HashSet<>();
    final AccessKeyPermission permission = authenticationUtils.preparePermission(user.getRole());
    permissions.add(permission);
    accessKey.setPermissions(permissions);
    genericDAO.persist(accessKey);

    permission.setAccessKey(accessKey);
    genericDAO.persist(permission);
    return accessKey;
  }
 @Transactional(propagation = Propagation.SUPPORTS)
 public boolean hasAccessToNetwork(AccessKey accessKey, Network targetNetwork) {
   Set<AccessKeyPermission> permissions = accessKey.getPermissions();
   User user = accessKey.getUser();
   boolean hasNullPermission =
       permissions.stream().anyMatch(perm -> perm.getNetworkIdsAsSet() == null);
   if (hasNullPermission) {
     return userService.hasAccessToNetwork(user, targetNetwork);
   } else {
     Set<Long> allowedNetworks =
         permissions
             .stream()
             .map(AccessKeyPermission::getNetworkIdsAsSet)
             .flatMap(Collection::stream)
             .collect(Collectors.toSet());
     user = userService.findUserWithNetworks(user.getId());
     return allowedNetworks.contains(targetNetwork.getId())
         && (user.isAdmin() || user.getNetworks().contains(targetNetwork));
   }
 }
 @Transactional
 public AccessKey updateAccessKeyFromOAuthGrant(OAuthGrant grant, User user, Date now) {
   AccessKey existing = find(grant.getAccessKey().getId(), user.getId());
   deleteAccessKeyPermissions(existing);
   if (grant.getAccessType().equals(AccessType.ONLINE)) {
     Date expirationDate = new Date(now.getTime() + 600000); // the key is valid for 10 minutes
     existing.setExpirationDate(expirationDate);
   } else {
     existing.setExpirationDate(null);
   }
   existing.setLabel(
       String.format(
           Messages.OAUTH_GRANT_TOKEN_LABEL,
           grant.getClient().getName(),
           System.currentTimeMillis()));
   Set<AccessKeyPermission> permissions = new HashSet<>();
   AccessKeyPermission permission = new AccessKeyPermission();
   permission.setDomainArray(grant.getClient().getDomain());
   permission.setActionsArray(StringUtils.split(grant.getScope(), ' '));
   permission.setSubnetsArray(grant.getClient().getSubnet());
   permission.setNetworkIds(grant.getNetworkIds());
   permissions.add(permission);
   existing.setPermissions(permissions);
   AccessKeyProcessor keyProcessor = new AccessKeyProcessor();
   String key = keyProcessor.generateKey();
   existing.setKey(key);
   for (AccessKeyPermission current : permissions) {
     current.setAccessKey(existing);
     genericDAO.persist(current);
   }
   return existing;
 }
 @Transactional
 public AccessKey createAccessKeyFromOAuthGrant(OAuthGrant grant, User user, Date now) {
   AccessKey newKey = new AccessKey();
   newKey.setType(AccessKeyType.OAUTH);
   if (grant.getAccessType().equals(AccessType.ONLINE)) {
     Date expirationDate = new Date(now.getTime() + 600000); // the key is valid for 10 minutes
     newKey.setExpirationDate(expirationDate);
   }
   newKey.setUser(user);
   newKey.setLabel(
       String.format(
           Messages.OAUTH_GRANT_TOKEN_LABEL,
           grant.getClient().getName(),
           System.currentTimeMillis()));
   Set<AccessKeyPermission> permissions = new HashSet<>();
   AccessKeyPermission permission = new AccessKeyPermission();
   permission.setDomainArray(grant.getClient().getDomain());
   permission.setActionsArray(StringUtils.split(grant.getScope(), ' '));
   permission.setSubnetsArray(grant.getClient().getSubnet());
   permission.setNetworkIds(grant.getNetworkIds());
   permissions.add(permission);
   newKey.setPermissions(permissions);
   create(user, newKey);
   return newKey;
 }
  @Transactional
  public boolean update(@NotNull Long userId, @NotNull Long keyId, AccessKeyUpdate toUpdate) {
    AccessKey existing = find(keyId, userId);
    if (existing == null) {
      return false;
    }
    if (toUpdate == null) {
      return true;
    }

    if (toUpdate.getLabel() != null) {
      existing.setLabel(toUpdate.getLabel().orElse(null));
    }
    if (toUpdate.getExpirationDate() != null) {
      existing.setExpirationDate(toUpdate.getExpirationDate().orElse(null));
    }
    if (toUpdate.getType() != null) {
      existing.setType(toUpdate.getType().map(v -> toUpdate.getTypeEnum()).orElse(null));
    }
    if (toUpdate.getPermissions() != null) {
      if (!toUpdate.getPermissions().isPresent()) {
        logger.error("New permissions shouldn't be empty in request parameters");
        throw new IllegalParametersException(Messages.INVALID_REQUEST_PARAMETERS);
      }

      Set<AccessKeyPermission> permissionsToReplace = toUpdate.getPermissions().get();
      AccessKey toValidate = toUpdate.convertTo();
      authenticationUtils.validateActions(toValidate);
      deleteAccessKeyPermissions(existing);
      for (AccessKeyPermission current : permissionsToReplace) {
        AccessKeyPermission permission = preparePermission(current);
        permission.setAccessKey(existing);
        genericDAO.persist(permission);
      }
    }
    return true;
  }
 @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
 public Network getWithDevicesAndDeviceClasses(
     @NotNull Long networkId, @NotNull HivePrincipal principal) {
   if (principal.getUser() != null) {
     List<Network> found =
         networkDAO.getNetworkList(principal.getUser(), null, Arrays.asList(networkId));
     if (found.isEmpty()) {
       return null;
     }
     List<Device> devices = deviceService.getList(networkId, principal);
     Network result = found.get(0);
     result.setDevices(new HashSet<>(devices));
     return result;
   } else {
     AccessKey key = principal.getKey();
     User user = userService.findUserWithNetworks(key.getUser().getId());
     List<Network> found =
         networkDAO.getNetworkList(user, key.getPermissions(), Arrays.asList(networkId));
     Network result = found.isEmpty() ? null : found.get(0);
     if (result == null) {
       return result;
     }
     // to get proper devices 1) get access key with all permissions 2) get devices for required
     // network
     key = accessKeyService.find(key.getId(), principal.getKey().getUser().getId());
     List<AllowedKeyAction.Action> actions = new ArrayList<>();
     actions.add(AllowedKeyAction.Action.GET_DEVICE);
     if (!CheckPermissionsHelper.checkAllPermissions(key, actions)) {
       result.setDevices(null);
       return result;
     }
     Set<Device> devices = new HashSet<>(deviceService.getList(result.getId(), principal));
     result.setDevices(devices);
     return result;
   }
 }