How to execute @Before from Aspect depending on passed parameter to method

Viewed 37

I have had an implemented aspect which checks whether a user is a premium user and depending on that I could throw a matching exception. I would check with a custom annotation on a method. I would fetch the user from the securityContext and do like so:

@Before(value = "@annotation(com.selfcast.annotation.RequiresBasic)")
public void requirePremiumForAction() {
    var talent = Optional.of((JwtAuthentication) SecurityContextHolder.getContext()
            .getAuthentication())
            .map(authUtil::getCredentials)
            .map(x -> userService.whoAmTalent(x.getEmail()))
            .orElseThrow(NoSuchTalent::new);

        if (
                paymentLaunchService.hasPaymentLaunchedInCountry(talent.getCountry().getId()) &&
                !talent.getAccountKind().equals(AccountKind.BASIC) &&
                !talent.getAccountKind().equals(AccountKind.FREEMIUM)
        ) {
            throw new ActionRequiresPremium();
        }
}

How do I proceed when I want to execute this depending on a parameter a method receives? I would need to fetch an object based on its ID, check a property of that object and only then return an ActionRequiresPremium exception. Like so:

@RequiresBasic
public Object doSomething(String Id){
  
}

Is this even possible? As far as I could research it is not. However using something like an @After seems pointless. What are good alternatives if this isn't possible?

1 Answers

You can use the JoinPoint as an argument in your advice. When you have that you can use the getArgs method to obtain the arguments of the method being called.

@Before(value = "@annotation(com.selfcast.annotation.RequiresBasic)")
public void requirePremiumForAction(JoinPoint jp) {
    var args = jp.getArgs(); // Now do your thing with the arguments as needed
    ... Remainder ommitted
}
Related