package com.devicehive.auth;

import com.devicehive.model.AccessKeyPermission;
import com.devicehive.model.Subnet;
import com.google.common.collect.Sets;

import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;

public class CheckPermissionsHelper {

    public static void filterActions(AllowedKeyAction.Action allowedAction,
                                     Set<AccessKeyPermission> permissions) {
        Set<AccessKeyPermission> permissionsToRemove = new HashSet<>();
        for (AccessKeyPermission currentPermission : permissions) {
            boolean isCurrentPermissionAllowed = false;
            Set<String> actions = currentPermission.getActionsAsSet();
            if (actions != null) {
                for (String accessKeyAction : currentPermission.getActionsAsSet()) {
                    isCurrentPermissionAllowed = accessKeyAction.equalsIgnoreCase(allowedAction.getValue());
                    if (isCurrentPermissionAllowed) {
                        break;
                    }
                }
            }
            if (!isCurrentPermissionAllowed) {
                permissionsToRemove.add(currentPermission);
            }
        }
        permissions.removeAll(permissionsToRemove);
    }

    public static void filterIP(InetAddress clientIp, Set<AccessKeyPermission> permissions) {
        Set<AccessKeyPermission> permissionsToRemove = new HashSet<>();
        for (AccessKeyPermission currentPermission : permissions) {
            Set<Subnet> subnetsAsSet = currentPermission.getSubnetsAsSet();
            if (subnetsAsSet != null) {
                boolean isCurrentPermissionAllowed = false;
                for (Subnet subnet : currentPermission.getSubnetsAsSet()) {
                    isCurrentPermissionAllowed = subnet.isAddressFromSubnet(clientIp);
                    if (isCurrentPermissionAllowed) {
                        break;
                    }
                }
                if (!isCurrentPermissionAllowed) {
                    permissionsToRemove.add(currentPermission);
                }
            }
        }
        permissions.removeAll(permissionsToRemove);
    }

    public static void filterDomains(String clientDomain, Set<AccessKeyPermission> permissions) {
        if (clientDomain == null) {
            return;
        }
        Set<AccessKeyPermission> permissionsToRemove = new HashSet<>();
        for (AccessKeyPermission currentPermission : permissions) {
            Set<String> domainsAsSet = currentPermission.getDomainsAsSet();
            if (domainsAsSet != null) {
                boolean isCurrentPermissionAllowed = false;
                for (String currentDomain : domainsAsSet) {
                    isCurrentPermissionAllowed = clientDomain.endsWith(currentDomain);
                    if (isCurrentPermissionAllowed) {
                        break;
                    }
                }
                if (!isCurrentPermissionAllowed) {
                    permissionsToRemove.add(currentPermission);
                }
            }
        }
        permissions.removeAll(permissionsToRemove);
    }

    public static void filterNetworks(Set<AccessKeyPermission> permissions) {
        Set<AccessKeyPermission> permissionToRemove = new HashSet<>();
        for (AccessKeyPermission currentPermission : permissions) {
            Set<Long> currentNetworkIds = currentPermission.getNetworkIdsAsSet();
            if (currentNetworkIds != null && currentNetworkIds.isEmpty()) {
                permissionToRemove.add(currentPermission);
            }
        }
        permissions.removeAll(permissionToRemove);
    }

    public static void filterDeviceGuids(Set<AccessKeyPermission> permissions) {
        Set<AccessKeyPermission> permissionToRemove = new HashSet<>();
        for (AccessKeyPermission currentPermission : permissions) {
            Set<String> currentDeviceGuids = currentPermission.getDeviceGuidsAsSet();
            if (currentDeviceGuids != null && currentDeviceGuids.isEmpty()) {
                permissionToRemove.add(currentPermission);
            }
        }
        permissions.removeAll(permissionToRemove);
    }

    public static Set<AccessKeyPermission> filterPermissions(Set<AccessKeyPermission> permissions, AllowedKeyAction.Action action, InetAddress clientIP, String clientDomain) {
        Set<AccessKeyPermission> filtered = Sets.newHashSet(permissions);
        filterActions(action, filtered);
        filterIP(clientIP, filtered);
        filterDomains(clientDomain, filtered);
        filterNetworks(filtered);
        filterDeviceGuids(filtered);
        return filtered;
    }
}

@@ -72,16 +72,52 @@
 ission;%0A
+import com.devicehive.model.Device;%0A
 import c
@@ -4679,11 +4679,705 @@
 d;%0A    %7D
+%0A%0A    public static boolean checkFilteredPermissions(Set%3CAccessKeyPermission%3E permissions, Device device) %7B%0A        Set%3CAccessKeyPermission%3E filtered = Sets.newHashSet(permissions);%0A        for (AccessKeyPermission permission : permissions) %7B%0A            Set%3CLong%3E networks = permission.getNetworkIdsAsSet();%0A            if (networks != null && !networks.contains(device.getNetwork().getId())) %7B%0A                continue;%0A            %7D%0A            Set%3CString%3E deviceGuids = permission.getDeviceGuidsAsSet();%0A            if (deviceGuids != null && !deviceGuids.contains(device.getGuid())) %7B%0A                continue;%0A            %7D%0A            return true;%0A        %7D%0A        return false;%0A    %7D%0A%0A
 %0A%7D%0A

Check method is added