package org.intellimate.izou.security;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.intellimate.izou.main.Main;
import org.intellimate.izou.support.SystemMail;
import org.intellimate.izou.util.IzouModule;
import java.io.File;
import java.util.function.Supplier;
/**
* SecureAccess allows the {@link SecurityManager} to access anything with full permission. If the secure access
* class is found in the current class context, any action will be allowed. However, only the security manager has
* access to this class
*/
final class SecureAccess extends IzouModule {
private static boolean exists = false;
private final SecurityBreachHandler breachHandler;
private final SystemMail systemMail;
private final Logger logger = LogManager.getLogger(this.getClass());
/**
* Creates an SecureAccess. There can only be one single SecureAccess, so calling this method twice
* will cause an illegal access exception.
*
* @param main the main instance of izou
* @param systemMail the system mail object in order to send e-mails to owner in case of emergency
* @return a SecureAccess object
* @throws IllegalAccessException thrown if this method is called more than once
*/
static SecureAccess createSecureAccess(Main main, SystemMail systemMail) throws IllegalAccessException {
if (!exists) {
SecureAccess secureAccess = new SecureAccess(main, systemMail);
exists = true;
return secureAccess;
}
throw new IllegalAccessException("Cannot create more than one instance of IzouSecurityManager");
}
/**
* Creates a new SecureAccess instance if and only if none has been created yet
* @param main the main instance of izou
* @throws IllegalAccessException thrown if this method is called more than once
*/
private SecureAccess(Main main, SystemMail systemMail) throws IllegalAccessException {
super(main);
if (exists) {
throw new IllegalAccessException("Cannot create more than one instance of IzouSecurityManager");
}
this.systemMail = systemMail;
SecurityBreachHandler tempBreachHandler = null;
try {
tempBreachHandler = SecurityBreachHandler.createBreachHandler(main, systemMail, "intellimate.izou@gmail.com");
} catch (IllegalAccessException e) {
logger.fatal("Unable to create a SecurityBreachHandler because Izou might be under attack. "
+ "Exiting now.", e);
exitIzou();
}
breachHandler = tempBreachHandler;
}
/**
* Gets the SecurityBreachHandler
*
* @return the SecurityBreachHandler
*/
SecurityBreachHandler getBreachHandler() {
return breachHandler;
}
/**
* Securely exits Izou
*/
void exitIzou() {
System.exit(1);
}
/**
* Securely checks if the given string {@code dir} is a directory, then returns true if so, else false
*
* @param dir the string to check for a directory
* @return true if the given string {@code dir} is a directory, else false
*/
boolean checkForDirectory(String dir) {
return new File(dir).isDirectory();
}
/**
* Securely checks if the given string {@code dir} is exists, then returns true if so, else false
*
* @param dir the string to check for existence
* @return true if the given string {@code dir} exists, else false
*/
boolean checkForExistingFileOrDirectory(String dir) {
return new File(dir).exists();
}
/**
* computes the supplier with an elevated security level (eliminates checks).
* <p>
* Be careful not to expose this method to addons or call method from addons inside this supplier as
* they would also gain the elevated security level.
* </p>
* @param supplier the supplier to call
* @param <T> the Type
* @return the result
*/
<T> T doElevated(Supplier<T> supplier) {
return supplier.get();
}
/**
* runs the runnable with an elevated security level (eliminates checks).
* @param run the runnable to run.
*/
void doElevated(Runnable run) {
run.run();
}
}