Link handlers / login screen extension in release 7

Hi,

We have a link handler that we implemented in release 6 that actually extends the login screen, it’s something of a backdoor login. It turns out that this approach doesn’t work anymore in release 7.

I will try to provide the outline of our implementation and then indicate the problem that we face.

In web-app.properties

cuba.web.linkHandlerActions = open|o|login

The custom link handler:

public class LoginLinkHandler extends LinkHandler {
    // Default override
    public LoginLinkHandler(App app, String action, Map<String, String> requestParams) {
        super(app, action, requestParams);
    }

    /**
     * Indicate that we are able to handle the following links:
     *      /login      Enforces default login (based on username/password
     * @return true if conditions above apply, otherwise the call is passed through.
     */
    @Override
    public boolean canHandleLink() {
        if ("login".equals(action))
            return true;

        return super.canHandleLink();
    }

    /**
     * Actual handler for the link
     */
    @Override
    public void handle() {
        switch (action) {
            // Do a default login
            case "login":
                try {
                    // Always try and open login window
                    AppUI.getCurrent().getScreens().create(BackdoorLoginWindow.class, OpenMode.ROOT).show();
                    // In release 6 we had this: 
                    // app.navigateTo("backdoorLoginWindow");
                } finally {
                    VaadinRequest request = VaadinService.getCurrentRequest();
                    WrappedSession wrappedSession = request.getWrappedSession();
                    wrappedSession.removeAttribute(AppUI.LAST_REQUEST_PARAMS_ATTR);
                    wrappedSession.removeAttribute(AppUI.LAST_REQUEST_ACTION_ATTR);
                }
                break;

            // In all other cases continue to the default handler
            default:
                super.handle();
        }
    }
}

And the backdoor login (controller):

public class BackdoorLoginWindow extends AppLoginWindow {
      // What happens here doesn't really matter with regard to the issue
}

As you can see, when the base url is extended with /login, the backdoor login is loaded instead of the default login. This backdoor extends the normal login but does a few things differently.

When we want to utilize this backdoor link (so something like http://localhost:8080/app/login), we get this error:

java.lang.IllegalArgumentException: No @UiController annotation for class class com.company.app.web.core.login.BackdoorLoginWindow
	at com.haulmont.cuba.web.sys.WebScreens.getScreenInfo(WebScreens.java:1031) ~[cuba-web-7.0.12.jar:7.0.12]
	at com.haulmont.cuba.web.sys.WebScreens.create(WebScreens.java:161) ~[cuba-web-7.0.12.jar:7.0.12]
	at com.haulmont.cuba.gui.Screens.create(Screens.java:60) ~[cuba-gui-7.0.12.jar:7.0.12]
	at com.compancy.app.web.core.login.LoginLinkHandler.handle(LoginLinkHandler.java:66) ~[app-web-0.1-SNAPSHOT.jar:na]
        ....

Apparently, in release 7.0, the override of the login screen using a link handler doesn’t work anymore. Somehow, a new Screen controller is expected. So, we tried to migrate the backdoor login controller to the new Screen approach but we ran into problems as we need to extend the original login screen.

We also tried to migrate to release 7.2 which seems to have an updated login screen but that gave us a lot of migration issues which we are unable to handle at this time. And we are not sure that it will solve our issue.

Are we missing something or is there some alternative that we can explore given that we are currently on release 7.0 ?

Thanks for any help, it is much appreciated.

Regards,
-b

Hi,

Any suggestions on this problem? Thanks in advance.

Regards
-b

Hello @b.tel,

do you use 7.0.x version of CUBA? As your BackdoorLoginWindow is legacy screen, try to create by its id:

AppUI.getCurrent().getScreens().create("backdoorLoginId", OpenMode.ROOT).show();

In CUBA 7+ versions there is API for a URL screen navigation. So for your BackdoorLoginWindow we need to specify route in order to avoid NPE with null state. Add in the web-screen.xml:

<screen id="backdoorLoginWindow"
        template="..."
        route="path-to-backdoorLogin"/>

You can try the example: flink.zip (82.7 KB)
http://localhost:8080/app/ - will open main login window;
http://localhost:8080/app//login will open ext-login window;

If you don’t need URL screen navigation set cuba.web.urlHandlingMode in the web-app.properties:

cuba.web.urlHandlingMode=NONE

And your LinkHandler will work without adding route to your login screen.

1 Like

Hi @Pinyazhin,

Thanks for your follow-up. Turns out that the main reason it wasn’t working was because we called the screen by its class rather than by its id:

AppUI.getCurrent().getScreens().create("backdoorLoginId", OpenMode.ROOT).show();

After that, everything worked as expected (we already had the urlHandlingMode set to NONE but that didn’t do the trick by it’s own.

Again, many thanks for helping out on this pressing issue we had!

Regards,
-b