Injecting CurrentAuthentication into Action

Hello there,

I’ve got a question regarding CurrentAuthentication and custom Actions.
I’ve already read that currently it is not really possible to cleanly and easily set permission checks on actions based on user roles, so as a workaround I currently use a set of custom EnabledRules and at Screen init I set on every action a rule that takes as constructor argument the injected currentAuthentication:

public class EditorEnabledRule implements BaseAction.EnabledRule {

    private final CurrentAuthentication auth;

    public EditorEnabledRule(CurrentAuthentication auth){ this.auth = auth; }

    @Override
    public boolean isActionEnabled() {
        return auth.getAuthentication().getAuthorities().stream().anyMatch(
                grantedAuthority -> EditorRole.CODE.equals(grantedAuthority.getAuthority()) ||
                        FullAccessRole.CODE.equals(grantedAuthority.getAuthority()));
    }
}

public final class MyScreenBrowse extends Screen {
    @Named("myTable.edit")
    private EditAction<MyEntity> editAction;
    @Autowired
    private CurrentAuthentication currentAuthentication;

   @Subscribe
    public void onInit(InitEvent event) {
       editAction.addEnabledRule(new EditorEnabledRule(currentAuthentication));
    }

I was asking then myself if I could clean this up by extending the actions and setting automatically the EnabledRule. Something like this:

@ActionType(PermissionedEditAction.ID)
@Primary
public class PermissionedEditAction<E> extends EditAction<E> {

    public static final String ID = "edit";

    @Autowired
    private CurrentAuthentication currentAuthentication;

    public PermissionedEditAction(String id){
        super(id);
        addEnabledRule(new EditorEnabledRule(currentAuthentication));
    }
}

This allows me to avoid having to set the custom EnabledRules at each screen init. But sadly, currentAuthentication is always null. I tried using @PostConstruct but it didn’t help. Am I missing something? Should I even be able to inject CurrentAuthentication in an Action? Having a look at the GitHub repo it looks like injections of other components such as Icons work, so I don’t understand what’s going on here.

Thanks to anyone who will have a look at this,
Lorenzo

Hi Lorenzo,

The field injection happens after the constructor is executed, so in the constructor the field is null.

Rework your action to inject the bean using a setter, for example:

@ActionType(MyEditAction.ID)
public class MyEditAction<E> extends EditAction<E> {

    public static final String ID = "edit";

    private CurrentAuthentication currentAuthentication;

    public MyEditAction(String id) {
        super(id);
    }

    @Autowired
    public void setCurrentAuthentication(CurrentAuthentication currentAuthentication) {
        this.currentAuthentication = currentAuthentication;
        addEnabledRule(() -> {
            System.out.println("User: " + currentAuthentication.getUser().getUsername());
            return true;
        });
    }
}

Regards,
Konstantin