001package org.intellimate.izou.security;
002
003import org.intellimate.izou.addon.AddOnModel;
004import org.intellimate.izou.main.Main;
005import org.intellimate.izou.security.exceptions.IzouPermissionException;
006import org.intellimate.izou.security.exceptions.IzouSocketPermissionException;
007import ro.fortsoft.pf4j.PluginDescriptor;
008
009import java.net.SocketPermission;
010import java.security.Permission;
011import java.util.ArrayList;
012import java.util.List;
013import java.util.function.Function;
014
015/**
016 * The SocketPermissionModule stores addOns that registered themselves to use socket connections.
017 */
018public final class SocketPermissionModule extends PermissionModule {
019
020    private final List<String> allowedSocketConnections;
021
022    /**
023     * Creates a new PermissionModule
024     *
025     * @param main the instance of main
026     */
027    SocketPermissionModule(Main main, SecurityManager securityManager) {
028        super(main, securityManager);
029        allowedSocketConnections = new ArrayList<>();
030        //TODO: why????? I don't think this is save
031        allowedSocketConnections.add(System.getProperty("host.name"));
032        allowedSocketConnections.add("local");
033        allowedSocketConnections.add("smtp");
034    }
035
036    /**
037     * returns true if able to check permissions
038     *
039     * @param permission the permission to check
040     * @return true if able to, false if not
041     */
042    @Override
043    public boolean canCheckPermission(Permission permission) {
044        return permission instanceof SocketPermission;
045    }
046
047    /**
048     * Checks if the given addOn is allowed to access the requested service and registers them if not yet registered.
049     *
050     * @param permission the Permission to check
051     * @param addon      the identifiable to check
052     * @throws IzouPermissionException thrown if the addOn is not allowed to access its requested service
053     */
054    @Override
055    public void checkPermission(Permission permission, AddOnModel addon) throws IzouPermissionException {
056        for (String socket : allowedSocketConnections) {
057            if (permission.getName().contains(socket)) {
058                return;
059            }
060        }
061
062        if (isRegistered(addon))
063            return;
064
065        Function<PluginDescriptor, Boolean> checkPermission = descriptor -> {
066            if (descriptor.getAddOnProperties() == null)
067                throw new IzouPermissionException("addon_config.properties not found for addon:" + addon);
068            try {
069                return descriptor.getAddOnProperties().getProperty("socket_connection") != null
070                        && descriptor.getAddOnProperties().getProperty("socket_connection").trim().equals("true")
071                        && descriptor.getAddOnProperties().getProperty("socket_usage_descripton") != null
072                        && !descriptor.getAddOnProperties().getProperty("socket_usage_descripton").trim().equals("null")
073                        && !descriptor.getAddOnProperties().getProperty("socket_usage_descripton").trim().isEmpty();
074            } catch (NullPointerException e) {
075                return false;
076            }
077        };
078
079        String exceptionMessage = "Socket Permission Denied: " + addon + "is not registered to "
080                + "use socket connections, please add the required information to the addon_config.properties "
081                + "file of your addOn.";
082        registerOrThrow(addon, () -> new IzouSocketPermissionException(exceptionMessage), checkPermission);
083    }
084}