Reputation: 509
I'm looking for a design pattern or a approach to tidy up my code. This is in the context of security and checking permissions for a given subject. Here is a simplified example:
public Pizza bakePizza() throws UnauthorizedException{
if (subject.isPermitted("BAKE_PIZZA")){
return new Pizza();
} else {
throw new UnauthorizedException();
}
}
Is there a way to make this a bit more clean because this can get quite messy when I have a lot of different kinds of methods like this.
Upvotes: 4
Views: 1785
Reputation: 63955
One approach is to move the check logic into a method that throws and thereby ends the program flow of the calling method early.
public Pizza bakePizza() throws UnauthorizedException{
ensurePermission("BAKE_PIZZA");
return new Pizza();
}
private void ensurePermission(String permission) throws UnauthorizedException {
if (!subject.isPermitted(permission))
throw new UnauthorizedException();
}
Upvotes: 0
Reputation: 49612
I think splitting security constraints and bussines logic by using something like the decorator pattern would be a good start.
How about something like this:
// an interface defines the operations
public interface PizzaService {
Pizza bakePizza();
}
// standard implementation that contains the business logic
public class PizzaServiceImpl implements PizzaService {
@Override
public Pizza bakePizza() {
// implementation ..
}
}
// implementation with security constraints that delegates to the real implementation
public class SecurePizzaService implements PizzaService {
private PizzaService service;
public SecurePizzaService(PizzaService service) {
this.service = service;
}
@Override
public Pizza bakePizza() {
if (!subject.isPermitted("BAKE_PIZZA")){
throw new UnauthorizedException();
}
service.bakePizza()
}
}
// usage
PizzaService pizzaService = new SecurePizzaService(new PizzaServiceImpl());
...
Pizza pizza = pizzaService.bakePizza();
This way you could change security constraints without touching business logic and vice versa.
If you have a lot of situations like this you should have a look at AOP frameworks like AspectJ
Upvotes: 4