How to introduce a special case in the API design? - java

I'm developing API for a library which will be used by a customer.
The library should provide single interface to access several remote resources. So, I should create API and several its implementations (correspondent to the number of remote resources).
I met the next problem: all resources except one has API for logging in. So, I can create method
void authenticate (String login, String password) throws AuthenticationException;
But I can't pass authentication to that one resource with this method.
To pass authentication on that resource I need to perform some actions and receive URL for authentication, then I should give this URL to the caller, caller program use some magic to pass authentication, and after that it should give me back "the flow".
So now I need 2 more methods to achieve necessary result:
String getAuthenticationURL () throws AuthenticationException;
void postAuthentication () throws AuthenticationException;
If I add these methods to the API then I'll have to create their empty implementations (or implementations which throws RuntimeException) in all API implementations for 'normal' resources.
If I do not add them to the API but add them only to one concrete implementation then I'll break the whole idea of unified API.
The approach with these 2 methods is only one of at least several possible solutions. So, any advices and suggestions are welcome.

You could have an abstract base class with two concrete child classes--each child containing a different authentication mechanism.
The other (probably better) method, however, might be to create an abstract "Authentication" object with two APIs (two concrete implementations). One would have your authenticate method, the other would have your get/post.
The advantage here is that your authenticate class contains all the functionality specific to authentication.. might even have some of the code in the class that is an abstract parent of your two authentication objects.
You can still keep your authenticate method if you like, it's implementation would simply be delegated to the authenticate object.
Note that this also gives your user a more "Minimal" api whereas extending your original interface gives you an entire second copy & paste class to consider.
Also, consider passing the correctly constructed authentication object to the constructor of your original class. Makes for a nice, clean system.
Whenever I break a piece of functionality into it's own class like this I always gain some great refactoring possibilities.

I love Bill K solution, but you could also have your authentication classes work like some kind of factory, providing you with a logged in resource when the authentication is done.
This way the first step for the user would be to chose the right authentication method, authenticate and get it's resource ready for use.

Related

How to prevent client from seeing internal private classes in Android library ?

I have a library with several packages-
lets say
package a;
package b;
inside package a I have public a_class
inside package b I have public b_class
a_class uses b_class.
I need to generate a library from this , but I do not want the Client to see b_class.
The only solution I know of is to flatten my beautifully understandable packages to single package and to use default package access for b_class.
Is there another way to do so ? maybe using interfaces or some form of design pattern ??
If you reject to move the code to an individual, controlled server, all you can do is to hinder the client programmer when trying to use your APIs. Let's begin applying good practices to your design:
Let your packages organized as they are now.
For every class you want to "hide":
Make it non-public.
Extract its public API to a new, public interface:
public interface MyInterface {...}
Create a public factory class to get an object of that interface type.
public class MyFactory
{
public MyInterface createObject();
}
So far, you have now your packages loosely coupled, and the implementation classes are now private (as good practices preach, and you already said). Still, they are yet available through the interfaces and factories.
So, how can you avoid that "stranger" clients execute your private APIs? What comes next is a creative, a little complicated, yet valid solution, based on hindering the client programmers:
Modify your factory classes: Add to every factory method a new parameter:
public class MyFactory
{
public MyInterface createObject(Macguffin parameter);
}
So, what is Macguffin? It is a new interface you must define in your application, with at least one method:
public interface Macguffin
{
public String dummyMethod();
}
But do not provide any usable implementation of this interface. In every place of your code you need to provide a Macguffin object, create it through an anonymous class:
MyFactory.getObject(new Macguffin(){
public String dummyMethod(){
return "x";
}
});
Or, even more advanced, through a dynamic proxy object, so no ".class" file of this implementation would be found even if the client programmer dares to decompile the code.
What do you get from this? Basically is to dissuade the programmer from using a factory which requires an unknown, undocumented, ununderstandable object. The factory classes should just care not to receive a null object, and to invoke the dummy method and check the return value it is not null either (or, if you want a higher security level, add an undocumented secret-key-rule).
So this solution relies upon a subtle obfuscation of your API, to discourage the client programmer to use it directly. The more obscure the names of the Macguffin interface and its methods, the better.
I need to generate a library from this , but I do not want the Client to see b_class. The only solution I know of is to flatten my beautifully understandable packages to single package and to use default package access for b_class. Is there another way to do so ?
Yes, make b_class package-private (default access) and instantiate it via reflection for use in a_class.
Since you know the full class name, reflectively load the class:
Class<?> clz = Class.forName("b.b_class")
Find the constructor you want to invoke:
Constructor<?> con = clz.getDeclaredConstructor();
Allow yourself to invoke the constructor by making it accessible:
con.setAccessible(true);
Invoke the constructor to obtain your b_class instance:
Object o = con.newInstance();
Hurrah, now you have an instance of b_class. However, you can't call b_class's methods on an instance of Object, so you have two options:
Use reflection to invoke b_class's methods (not much fun, but easy enough and may be ok if you only have a few methods with few parameters).
Have b_class implement an interface that you don't mind the client seeing and cast your instance of b_class to that interface (reading between the lines I suspect you may already have such an interface?).
You'll definitely want to go with option 2 to minimise your pain unless it gets you back to square one again (polluting the namespace with types you don't want to expose the client to).
For full disclosure, two notes:
1) There is a (small) overhead to using reflection vs direct instantiation and invocation. If you cast to an interface you'll only pay the cost of reflection on the instantiation. In any case it likely isn't a problem unless you make hundreds of thousands of invocations in a tight loop.
2) There is nothing to stop a determined client from finding out the class name and doing the same thing, but if I understand your motivation correctly you just want expose a clean API, so this isn't really a worry.
When using Kotlin, you can use the internal modifier for your library classes.
If I understand correctly you are asking about publishing your library for 3rd party usage without disclosing part of your source? If that's the case you can use proguard, which can obfuscate your library. By default everything will be excluded/obfuscated, unless you specify things you want to exclude from being obfuscated/excluded.
If you want to distribute [part of] your code without the client being able to access it at all, that means that the client won't be able to execute it either. :-O
Thus, you just have one option: Put the sensible part of your code into a public server and distribute a proxy to access it, so that your code would be kept and executed into your server and the client would still be able to execute it through the proxy but without accessing it directly.
You might use a servlet, a webservice, a RMI object, or a simple TCP server, depending on the complexity level of your code.
This is the safest approach I can think of, but it also deserves a price to pay: In addition to complexing your system, it would introduce a network delay for each remote operation, which might be big deal depending on the performance requirements. Also, you should securize the server itself, to avoid hacker intrussions. This could be a good solution if you already have a server that you could take advantage of.

Can I load a Java class in a way that automatically removes its privileges?

I am working on developing a library that needs to instantiate and return untrusted objects downloaded from an external website. At a high-level, the library works as follows:
Clients of the library requests a class from a remote source.
My library instantiates that object, then returns it to the user.
This is a major security risk, since the untrusted code can do just about anything. To address this, my library has the following design:
I enable the SecurityManager and, when instantiating the untrusted object, I use an AccessController to handle the instantiation in a context where there are no privileges.
Before returning the object back to the client, I wrap the object in a decorator that uses an AccessController to forward all method requests to the underlying object in a way that ensures that the untrusted code is never run with any permissions.
It occurs to me, though, that this might not be the most elegant solution. Fundamentally, I want to strip away all permissions from any object of any type downloaded from the remote source. My current use of AccessController is simply a way of faking this up by intercepting all requests and dropping privileges before executing them. The AccessController approach also has its own issues:
If the wrapped object has any methods that return objects, those returned objects have to themselves be wrapped.
The wrapper code will potentially be thousands of lines long, since every exported method has to be secured.
All of the methods exported by the downloaded object have to be known in advance in order to be wrapped.
My question is this: is there a way to load classes into the JVM (probably using a custom ClassLoader) such that any instances of those classes execute their methods with no permissions?
Thanks!
You will want to call defineClass with an untrusted ProtectionDomain.
Your current solution has a number of problems. It doesn't appear to cover the static initialiser. It may be possible to install code into some mutable arguments. Methods that use the immediate caller will still be privileged (AccessController.doPrivileged, say). But most of all, it falls about when rubbing up against any kind of global - for instance running a finaliser.
Don't know if there's a way to directly do what you asked, but I think your approach can be simplified by using interfaces and dynamic proxies. Basically, if you have an interface for the object to be returned, and all its methods return either simple types or interfaces, then you can wrap all the methods and their return values automatically, without knowing the methods in advance. Just implement an InvocationHandler that does the AccessController magic in its invoke method, and create proxies using Proxy.newProxyInstance(...).

Provide data to a method using aspect oriented programming

I'm learning AOP and am comfortable with Pointcuts, Advices etc.
What am going to ask, am pretty sure is not possible, but want to ask anyways.
I have a method which takes a userId, fetches the user's record from a database and then does something to the record. I have like twenty different methods that do different things, but all of them take the userId as input and fetch the record from database. This to me looks like a cross cutting concern that can be pulled into an aspect.
But how? I know I can access the arguments (userId in this case), access the return value of the method and catch the methods exception. But how do I give the method something to work with (record in the database in this case?)
public String printUserDetails(String userId)
{
Record record = Database.fetchRecord(userId);
System.out.println(record.getDetails());
return record.getTitle();
}
So, is there a way to pull that database accessing code into an aspect?
One way I can think of is declare something like the following for input
class RequestObject
{
String userId;
Record record;
}
and inject the record in the Aspect and then call proceed(). But this somehow feels wrong.
IMO, resolving a user, using the userid, is not a cross-cutting concern and hence aspect is not the right way. The first landing page that receives a userId should actually resolve it to UserRecord and from then on, the userRecord should be the one moving around in the application.
A simple analogy I can draw to your scenario from one of my applications is, all authenticated servlets expect the servletRequest.getRemoteUser() to return the valid user login corresponding to the user sending the request. We decorated the HttpServletRequest to resolve this to a User object in our application and all the authenticated servlets downcast the HttpServletRequest to AuthenticatedServletRequest and extract this object. No one else within the application tries to resolve a user login anymore.
You cannot access a method's local variables from AspectJ if this is what you wanted to know.
The rest of the question is rather about design and the answer dependent on what you want to achieve. You can avoid code duplication in multiple methods using a template method design pattern. You can inject real or mock objects into classes if you refactor them to have a member instead of local variables. It is another question if you create the member by directly refactoring your classes or via AspectJ's (ITD)[http://www.eclipse.org/aspectj/doc/next/progguide/starting-aspectj.html#inter-type-declarations] mechanism. A third question would be if you possibly want to use an aspect for caching in order to avoid fetching the same object from the database multiple times.
I am not sure what exactly you want to achieve, so I cannot answer more specifically.

On properly implementing complex service layers

I have the following situation:
Three concrete service classes implement a service interface: one is for persistence, the other deals with notifications, the third deals with adding points to specific actions (gamification). The interface has roughly the following structure:
public interface IPhotoService {
void upload();
Photo get(Long id);
void like(Long id);
//etc...
}
I did not want to mix the three types of logic into one service (or even worse, in the controller class) because I want to be able to change them (or shut them) without any problems. The problem comes when I have to inject a concrete service into the controller to use. Usually, I create a fourth class, named roughly ApplicationNamePhotoService, which implements the same interface, and works as a wrapper (mediator) between the other three services, which gets input from the controller, and calls each service correspondingly. It is a working approach, though one, which creates a lot of boilerplate code.
Is this the right approach? Currently, I am not aware of a better one, although I will highly appreciate to know if it is possible to declare the execution sequence declaratively (in the context) and to inject the controller with and on-the fly generated wrapper instance.
Also, it would be nice to cache some stuff between the three services. For example, all are using DAOs, i.e. making sometimes the same calls to the DB over and over again. If all the logic were into one place that could have been avoided, but now... I know that it is possible to enable some request or session based caching. Can you suggest me some example code? BTW, I am using Hibernate for the persistence part. Is there already some caching provided (probably, if they reside in the same transaction or something - with that one I am totally lost)
The service layer should consist of classes with methods that are units of work with actions that belong in the same transaction. It sounds like you are mixing service classes when they could be in the same class and method. You can inject service classes into one another when required too, rather than create another "mediator".
It is perfectly acceptable to "mix the three types of logic", in fact it is preferable if they form an expected use case/unit of work
Cache-ing I would look to use eh cache which is, I believe, well integrated with hibernate.

Java custom annotation to restricted access to method

I am building an application on two layer. Web layer and business layer.
Inside the business layer I have some public method that can be called within the business layer or from the web layer.
I only want some of these methods being called from the web layer (the safe one).
I was wondering if I can create a annotation in my business layer, for example #Public which means I can call this method from the web layer, and #Private so I should not use this method from the web layer.
And when I try to call a #private method from the web layer (in eclipse) it gives me a warning?
As well: Can I have a way to list automatically all this method private and public?
AFAIK you can't make Eclipse use annotation to determine whether you can access a method from a certain file. For this to be possible Eclipse would have to know whether the file is part of the web layer or the business layer.
In order to list all methods having a certain annotation, you could use reflection at runtime. In Eclipse there might be filters, but I don't know of any annotation based filters.
Maybe you should choose another approach, I'll shortly describe how we do that:
We have two interfaces that our services may implement:
one public interface that contains all the methods the web layer may see
one private interface that contains all the methods internal to the business logic
We split those interfaces into two eclipse projects - one public api project and one implementation project that contains the services and internal api - and just allow access to the public api project from the web layer.
Since our services (EJB 3.0) need an interface, we have to add the internal one, if we have internal methods. However, with other technology (like EJB 3.1) you might also just provide the public interface.
Another approach might be to split the interfaces into two packages, e.g. myproject.api.pub (public is a keyword) and myproject.api.internal, and then use package based filters in Eclipse.
The first thing that comes up in my mind is that this would only be needed in a bad-designed two-layer app.
You can use access control to make sure that the web gui can only access the safe methods, and keep other methods to the business layer.
It is probably possible to just make those "public" methods that you don't want to be used by the web interface private; that way you can use them in the public, safe, methods in the business logic.
Though without knowing how your project is set up, giving concrete examples is kind of impossible.
But say; you can have:
com.somecompany.gui > contains all web-gui stuff
com.somecompany.logic > contains business logic.
In the logic package, you create classes that have public methods to be used from gui, and private or - if needed by other logic components - package private (protected) methods that cannot be accessed from the gui package. That way you can separate your logic from the interface without having a need for the annotation you want to make.
In general I'd say: yes, it could work. At least to produce compiler warnings.
We have the #Override annotation for methods. This annotation is used for a similar reason: verify at compile time, that certain conditions are met. In this case: the annotated methods overrides a method from a superclass or it implements an interface method or an abstract method. If the verifier finds out, the this is not the case, then the compiler will produce a compile time error.
So it should be possible here too. We could think of an annotations like
#Layer("servicelayer") // class annotation
#Private(layer="servicelayer") // method annotation
And now we could verify at compile time, that annotated methods can only be called from classes that have the same layer annotation. If the condition is not met, the compiler could produce a warning (iaw: the compiler could detect, if we accidentally call an internal service layer method from a web layer class.

Categories

Resources