I am trying to build a Plugin System in java without resorting to special libraries.
As of now, I am able to load and process my plugins. However, I need to define a special Security Manager which disables any access to file deletion and others.
This Security Manager should only keep plugins in place, because the core of my system has to perform some actions plugins can't. As a result, I cannot set the Security Manager using the System class, or it will affect my system's core as well.
I've tried to "reset" the default Security Manager after loading the plugins, but I was unable to do that. Even if I was able, the plugins would end up executing the system's current Security Manager, not their own.
I would like to know if there is a way to encapsulate classes to specific Security Managers.
On top of my head, I was thinking on looking the stack trace and, if a plugin class is found as a caller, forbid the actions they should not perform, but I fear this will prove to be a little ineffective performance-wise.
As soon as I am able, I will post the code to my Security Manager in order to help with ideas.
Here is the code for my Security Manager:
package org.zeh.filemanager.core.controllers.util;
import java.io.FileDescriptor;
/**
* #author José Ricardo Carvalho Prado de Almeida
*/
public class PluginSecurityManager extends SecurityManager {
#Override
public void checkRead(FileDescriptor filedescriptor) {
super.checkRead(filedescriptor);
}
#Override
public void checkRead(String filename) {
super.checkRead(filename);
}
#Override
public void checkRead(String filename,
Object executionContext) {
//
super.checkRead(filename,
executionContext);
}
#Override
public void checkWrite(FileDescriptor filedescriptor) {
throw new SecurityException("Plugin is trying to write files.");
}
#Override
public void checkWrite(String filename) {
throw new SecurityException("Plugin is trying to write files.");
}
#Override
public void checkDelete(String file) {
super.checkDelete(file);
throw new SecurityException("Plugin is trying to delete files.");
}
#Override
public void checkExec(String cmd) {
super.checkExec(cmd);
throw new SecurityException("Plugin is trying to create subprocesses.");
}
#Override
public void checkExit(int status) {
super.checkExit(status);
throw new SecurityException("Plugin is trying to finalize the JVM.");
}
#Override
public void checkCreateClassLoader() {
super.checkCreateClassLoader();
throw new SecurityException("Plugin is trying to create ClassLoaders.");
}
}
I have found a question (How to implement Java plugin security safely?), that is very similar to mine but the answers do not really fit in my context, where external libraries are not desired.
I forgot to mention that I do have a custom Class Loader that is working perfectly as of now.
I've designed the program so each kind of plugin would have a special Class Loader and such loader would have it's own Security Manager, to restrict different plugins based on functionality.
The only reason this design does not work is because of those Security Managers. If I ignore the use of Security Managers, the system does everything it is supposed to, although it is not secure.
Does anyone have a probable solution for this problem?
Thank you.
Related
I am looking to disable the swagger functionality / endpoint in a production environment based on a config value.
How would I go about this?
I believe the best way to achieve this is not to add the bundle during the execution of the initialize method when a DropWizard application first starts.
The issue with this solution is that you cannot access the configuration get methods that are populated from the values in the YAML/YML file. These values are available are available when we the application gets to the run method.
Here is my initialise method from the application class
#Override
public void initialize(Bootstrap<Configuration> bootstrap) {
LOGGER.debug("initialize");
bootstrap.setConfigurationSourceProvider(new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(),
new EnvironmentVariableSubstitutor(false)));
bootstrap.addBundle(new SwaggerBundle<Configuration>() {
#Override
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(Configuration configuration) {
return configuration.swaggerBundleConfiguration;
}
});
}
If I need to clarify more please let me know.
Thanks in advance.
You can set an environment variable in production and use it to decide whether to include SwaggerBundle or not. For example:
if (!"prod".equalsIgnoreCase(System.getenv("ENVIRONMENT"))) {
bootstrap.addBundle(new SwaggerBundle<Configuration>() { ... }
}
I was using an older version of DropWizard at the time.
After updating, there were new methods available including setIsEnabled()
This is what was added to solve the issue.
bootstrap.addBundle(new SwaggerBundle<Configuration>() {
#Override
protected SwaggerBundleConfiguration getSwaggerBundleConfiguration(Configuration configuration) {
if(!configuration.getSwaggerEnabled()){
configuration.swaggerBundleConfiguration.setIsEnabled(false);
}
return configuration.swaggerBundleConfiguration;
}
});
}
Thanks,
Let's say I've an implementation of fund transfer. Now I want to add authentication functionality which should be done before fund transfer (considering we are already receiving username and password in existing request). Which pattern should we use and how we can achieve this without modifying calling class and existing implementation?
What I can think of at this moment is using decorator pattern after extending implementation class, but I believe still we will be required to modify the calling class.
Please find existing Interface and classes.
package sb.test.demo.fundtransfer;
public interface FundTransferService {
public boolean makeTransfer(TransferRequest request) throws Exception;
}
package sb.test.demo.fundtransfer;
public class FundTransferServiceImpl implements FundTransferService {
#Override
public boolean makeTransfer(TransferRequest request) throws Exception {
//Dummy Code
System.out.println("TransferDone");
return true;
}
}
package sb.test.demo.fundtransfer;
public class TestTransfer {
public static void main(String[] args) throws Exception {
TransferRequest request = new TransferRequest();
request.setSourceAccount(123456);
request.setDestinationAccount(654321);
request.setTranserAmount(1000);
request.setUserName("user1");
request.setPassword("pass1");
FundTransferService fts = new FundTransferServiceImpl();
fts.makeTransfer(request);
}
}
Now, I want want extend FundTransferServiceImpl to createFundTransferServiceNEWImpl which will add authentication.
package sb.test.demo.fundtransfer;
public class FundTransferServiceNEWImpl extends FundTransferServiceImpl {
#Override
public boolean makeTransfer(TransferRequest request) throws Exception {
//Dummy Code
System.out.println("Authenticating..");
super.makeTransfer(request);
System.out.println("TransferDone from NEW..");
return true;
}
}
Now, without changing TestTransfer.java and FundTransferServiceImpl.java how can I invoke makeTransfer of FundTransferServiceNEWImpl to add authentication? Or, is there any other way to achieve the same?
Please can anyone help me on this?
Thanks in advance!
you can make "FundTransferServiceNEWImpl" also implement the interface "FundTransferService" and provide the implementation that you wish in this only, if this was what you asked for!!
Now, without changing TestTransfer.java and FundTransferServiceImpl.java how can I invoke makeTransfer of FundTransferServiceNEWImpl to add authentication?
You can't without changing the bytecode of either TestTransfer (the caller) or FundTransferServiceImpl (the callee).
There are two ways to change the bytecode.
You can
edit the source file and compile
edit the bytecode before the class is loaded
Edit the source file
I would suggest to edit the TestTransfer class. The problematic line is
FundTransferService fts = new FundTransferServiceImpl();
because this line introduces the dependency from TestTransfer to FundTransferServiceImpl.
I would also suggest to implement the decorator by composition and not inheritence. E.g.
public class AuthenticationFundTransferServiceWrapper implements FundTransferService {
private FundTransferService fundTransferService;
public AuthenticationFundTransferServiceWrapper(FundTransferService fundTransferService){
this.fundTransferService = fundTransferService;
}
public boolean makeTransfer(TransferRequest request) throws Exception {
//Dummy Code
System.out.println("Authenticating..");
fundTransferService.makeTransfer(request);
System.out.println("TransferDone from NEW..");
return true;
}
}
The advantage is that the AuthenticationFundTransferServiceWrapper does only depend on the interface FundTransferService and not the implementation. This reduces dependencies and makes the class more flexible.
Editing the byte code
Editing the bytecode before the class is loaded is possible.
Take a look at
AOP (aspect oriented programming)
AspectJ
ASM (bytecode manipulation)
cglib
So you've identified decorator pattern and this answer implemented decorator correctly, but as this is a SOLID principles question I'm going to point out the flaw in that option.
To see the flaw in either inheritance or decorator, consider what happens when the authorization fails. If it throws a new exception type, that is a Liskov Substitution Principle Violation. If it changes the behavior by silently not transferring the funds, that is also an LSP violation. If you're going to rely on the boolean returned, you're not going to get a useful failure message back to the user or system admin.
As I see it, there is no way the client code can avoid knowing that the new implementation is checking authorized as it needs to handle either a new exception, or different return values.
Given that, I would recommend you add a new class, like this:
public final class TransactionAuthorizationService {
private final FundTransferService fundTransferService;
public AuthenticationFundTransferServiceWrapper(FundTransferService fundTransferService){
this.fundTransferService = fundTransferService;
}
public boolean authorizeAndMakeAndTransfer(TransferRequest request) throws Exception {
//Dummy Code
System.out.println("Authenticating..");
fundTransferService.makeTransfer(request);
System.out.println("TransferDone from NEW..");
return true;
}
}
Advantages:
Where before client code dealt with the interface FundTransferService you would have no idea until runtime which implementation they had and whether they would be authorizing transactions, now the client code now deals with the TransactionAuthorizationService and they call authorizeAndMakeAndTransfer so it is very clear.
As our new class is not implementing an existing interface, there is no Liskov Substitution Violation and is free to return different values or throw different exceptions.
Other tips:
Stop decorating methods with throw alls: throws Exception
Don't use InterfaceImpl as class names, look for what makes them concrete over the abstract interface.
I'm developing a java component that needs to run both on the command line and as a Eclipse job. The execution can take a few minutes, so I want to inform the user what's happening. I don't want to have a dependency to the Eclipse progress monitor package in my "pure" java code.
How can I provide progress monitoring in the Eclipse job without "polluting" my java code with Eclipse depenendcies?
Write your own progress monitor interface that you use in your code, something like:
interface MyProgressMonitor
{
public void beginTask(String name, int totalWork);
public void done();
public boolean isCanceled();
public void worked(int work);
}
For the Java application you can use an implementation of this that does nothing.
For the Eclipse job use an implementation that delegates to the Eclipse IProgressMonitor:
class EclipseMyProgressMonitor implements MyProgressMonitor
{
private final IProgressMonitor monitor;
EclipseMyProgressMonitor(IProgressMonitor theMonitor)
{
monitor = theMonitor;
}
public void beginTask(String name, int totalWork)
{
monitor.beginTask(name, totalWork);
}
public void done()
{
monitor.done();
}
public boolean isCanceled()
{
return monitor.isCanceled();
}
public void worked(int work)
{
monitor.worked(work);
}
}
It shouldn't be that difficult. Create the java component in a separate project using just pure java. Then create the eclipse functionality responsible for starting the job, see this article for assistance. You eclise code will start a job, this will in turn call your java component.
Issues that will be difficult to handle:
The user may want to abort the operation, you should try to handle this gracefully in your component. If you are just doing computations, you could kill the job, but if you do something that may require clean up, such as writing a file, you will need some other way to deal with it.
Ideally you would like to report a correct and realiable progress to the user, but that will introduce a dependency to org.eclipse.core.runtime.IProgressMonitor which you may not want.
I am somewhat new to the OSGi world. And some concepts still elude me.
I'm trying to create a graphical OSGi application using Swing, Equinox and Declarative Services. The goal is to ease the creation of plugins and extensions for the application.
I have stumbled with a design problem and, since I am doing this from the ground up, I want to use all the best practices I can.
I do have a bundle that contains the API and only exposes interfaces to be implemented as services.
public class SomeClass {
}
public interface Manager<T> {
void add(T obj);
void update(T obj);
void remove(T obj);
}
public interface SomeClassManager extends Manager<SomeClass> {
}
public interface Listener<T> {
void added(T obj);
void updated(T obj);
void removed(T obj);
}
public interface SomeClassListener extends Listener<SomeClass> {
}
Let's say I have a bundle (Core) that provides a service that is a manager of certain types of objects (It basically contains an internal List and adds, removes and updates it).
public class SomeClassCoreManager implements SomeClassManager {
private ArrayList<SomeClass> list = new ArrayList<SomeClass>();
private ArrayList<SomeListener> listeners = new ArrayList<SomeListener>();
protected void bindListener(SomeListener listener) {
listeners.add(listener);
}
protected void undindListener(SomeListener listener) {
listeners.remove(listener);
}
public void add(SomeClass obj) {
// Adds the object to the list
// Fires all the listeners with "added(obj)"
}
public void update(SomeClass obj) {
// Updates the object in the list.
// Fires all the listeners with "updated(obj)"
}
public void remove(SomeClass obj) {
// Removes the object from the list.
// Fires all the listeners with "removed(obj)"
}
}
I also have a second bundle (UI) that takes care of the main UI. It should not "care" for the object managing itself, but should be notified when an object is added, removed or changed in order to update a JTree. For that purpose I used a Whiteboard pattern: The UI bundle implements a service that is used by the Core bundle to fire object change events.
public class MainWindow extends JFrame {
private JTree tree = new JTree();
private SomeClassManager manager;
protected void activate() {
// Adds the tree and sets its model and creates the rest of the UI.
}
protected void bindManager(SomeClassManager manager) {
this.manager = manager;
}
protected unbindManager(SomeClassManager manager) {
this.manager = null;
}
}
public class SomeClassUIListener implements SomeClassListener {
public void added(SomeClass obj) {
// Should add the object to the JTree.
}
public void updated(SomeClass obj) {
// Should update the existing object in the JTree.
}
public void removed(SomeClass obj) {
// Should remove the existing object from the JTree.
}
}
My problem here is the following:
The MainWindow is a DS component. I am using its activator to initiate the whole UI. The instance creation is handled by OSGi.
In order to get the updates from the manager, I am exposing the SomeClassUIListener as a Declarative Service. Its instance is also handled by OSGi.
How should I access the instance of the JTree model from the SomeClassUIListener?
I have come up with several options but I am not sure which to use:
Option 1:
Use some kind of internal DI system for the UI bundle (like Guice or Pico) and put it in a class with a static method to get it and use it all over the bundle.
This approach seems to be frowned upon by some.
Option 2:
Inject a reference to the MainWindow (by turning it into a service) in the SomeClassUIListener through OSGi and go from there. Is this possible or advisable? Seems to me that it is the simpler solution. But, on the other hand, wouldn't this clutter the bundle with component config files as the UI got more and more complex?
Option 3:
Create a separate bundle only for listeners and use OSGi to update the MainWindow. This seems to me a bit extreme, as I would have to create an enormous amount of bundles as the UI complexity grows.
Option 4:
Use the MainWindow class to implement the Listener. But, the more services in the main UI bundle, the bigger the MainWindow class would be. I think this would not be a good option.
I cannot think of more options. Is any of the above the way to go? Or is there another option?
Thank you in advance.
Edit:
Just to clarify as Peter Kriens had some doubts about this question.
My goal here is to decouple the user interface from the Manager. By Manager I mean a kind of repository in which I store a certain type of objects (For instance, if you consider the Oracle's JTree tutorial at http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html, the manager would contain instances of Books).
The Manager may be used by any other bundle but, according to my current plan, it would notify any listener registered in it. The listener may be the main UI bundle but may also be any other bundle that chooses to listen for updates.
I am not sure I completely grasp your proposal, and it feels like you are on your way to create a whole load of infrastructure. In OSGi this is generally not necessary, so why not start small and simple.
Your basic model is a manager and an extension. This is the domain model and I would try to flow things around here:
#Component(immediate)
public class ManagerImpl { // No API == immediate
List<Extension> extensions = new CopyOnWriteArrayList<Extension>();
JFrame frame = new JFrame();
#Reference(cardinality=MULTIPLE)
void addExtension( Extension e ) {
addComponent(frame, e.getName(), e.getComponent());
extensions.add(e);
}
void removeExtension( Extension e) {
if ( extensions.remove(e) ) {
removeComponent(frame, e.getName());
}
}
#Component
public class MyFirstExtension implements Extension {
public String getName() { return "My First Extension";}
public Component getComponent() { return new MyFirstExtensionComponent(this); }
}
Isn't this what you're looking for? Be very careful not to create all kinds of listeners, in general you find the events already in the OSGi registry.
Some option here would be to pass the tree model instance as the argument in the listeners methods.
public void added(JTree tree, SomeClass obj)
This way listeners manager would be responsible only for listeners logic, not for the tree state.
Another nice option would be to create a separated TreeProviderService, responsible for holding and serving singleton JTree instance for the application. In such case you would consume TreeProviderService directly from the listeners.
I propose to simply also use DS for the UI creation and wiring. If you use the annotations Peter mentioned you will not clutter your bundles with component descriptors in XML form.
So your listener is a #Component and you inject the UI elements it needs to update into it.
Btw. what you plan to do sounds a bit like databinding to me so you should also investigate what these offer already.
See: Swing data binding frameworks
Btw. you may also want to look for more advanced frameworks than swing. For example some time ago I did a small tutorial for vaadin: https://github.com/cschneider/Karaf-Tutorial/tree/master/vaadin
It already has a databinding for java beans. So this made it really easy for me to code the UI. The full UI is just this little class: https://github.com/cschneider/Karaf-Tutorial/blob/master/vaadin/tasklist-ui-vaadin/src/main/java/net/lr/tutorial/karaf/vaadin/ExampleApplication.java
In the old version I still needed a bridge to run vaadin in OSGi but version 7 should be quite OSGi ready.
I am developing an eclipse plugin that shows the user links to test logs. In the current implementation we register a jUnit run listener that updates the view whenever a suite has been run and this works fine, problem is that the test framework now also support TestNG and we will need the equivalent functionality from the TestNG plugin if the user runs a TestNG testcase.
I found this feature request http://jira.opensymphony.com/browse/TESTNG-313 which suggests that the functionality I am looking for is there to use, at least that´s how I interpret it. Anyway, I can´t seem to get it to work. I try to create and define different objects in the view setup that should listen for ng-runs and calls to for example onFinish() but I have not found a way to "register" the listening class the way you are if you are defining a regular listener from the suite.xml or code. The TestNG class seems to be a singleton but only for every testrun, not for monitoring the plugin for whenever a suite is run. The TestNGPlugin class does not seem to have appropriate methods. Just implementing a TestListenerAdapter or ITestListener interface as a private class does not do the trick.
Does anyone know which is the most appropriate class or interface to implement for this and if needed, how they should be registered?
Btw I am using Eclipse 3.7.0 and TestNG 6.1.1.
I found another way around the problem, probably a better solution in the end. I monitor the org.eclipse.debug.core.DebugPlugin for any launch of any kind and do the update depending on that. This little piece of code made it work.
ILaunchesListener2 runListener = new ILaunchesListener2() {
#Override
public void launchesAdded(ILaunch[] arg0) {
}
#Override
public void launchesChanged(ILaunch[] arg0) {
}
#Override
public void launchesRemoved(ILaunch[] arg0) {
}
#Override
public void launchesTerminated(ILaunch[] arg0) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
updateTestRunList();
viewer.setInput(testRuns);
viewer.refresh();
}
});
}
};
DebugPlugin.getDefault().getLaunchManager().addLaunchListener(runListener);