mvysny / karibu-testing

Vaadin Server-Side Browserless Containerless Unit Testing
Apache License 2.0
105 stars 14 forks source link

@PermiAll annotation breaks navigateTo #139

Closed vlipovetskii closed 1 year ago

vlipovetskii commented 1 year ago

naviagteTo doesn't work (Vaadin UI uncaught exception com.vaadin.flow.router.NotFoundException), if to put @PermiAll on a class with @Route annotation.

Removing @PermiAll doesn't help.

To allow naviagteTo to work, I need to replace @PermiAll with @AnonymousAllowed temporarily.

spring-boot: 2.7.7 Vaadin: 23.3.2 karibu: 1.1.3 karibu-tools: 0.13 karibu-testing: 1.3.23

mvysny commented 1 year ago

Hi, hmmm, that's interesting. Perhaps you're running the tests in production mode and the access is rejected to given route? In such case Vaadin responds with NotFoundException, in order to not to reveal to the potential attacker that the route in fact exists.

Could you also provide an example project please?

vlipovetskii commented 1 year ago

Yes, the tests are run in the production mode. I have investigated, how Vaadin checks the access to views.

Several classes participate in the check process: SpringViewAccessChecker extends ViewAccessChecker and uses AccessAnnotationChecker to check the access.

As a workaround, I have created my own custom implementation of AccessAnnotationChecker, which bypasses annotation checks if setting isProdEnvironment=false. So, the issue can be closed.

` open class KVdAccessAnnotationChecker( env: Environment, prefix: String = defaultPrefix, ) : AccessAnnotationChecker(), KServiceHasLoggingEnabledA by KServiceHasLoggingEnabled(env, prefix) {

companion object : KLoggerA {

    const val defaultPrefix = "KAccessAnnotationChecker"

    private val log by lazy { classLogger }
}

@Suppress("MemberVisibilityCanBePrivate")
protected val isProdEnvironment = env.getRequiredProperty<Boolean>("$prefix.isProdEnvironment", log)

override fun hasAccess(method: Method?, principal: Principal?, roleChecker: Function<String, Boolean>?): Boolean {
    if (isServiceLoggingEnabled) log.info("hasAccess($method, $principal, roleChecker)")
    return if (isProdEnvironment) {
        super.hasAccess(method, principal, roleChecker).also {
            if (isServiceLoggingEnabled) log.info("super.hasAccess(method, principal, roleChecker) -> $it")
        }

    } else {
        true.also {
            if (isServiceLoggingEnabled) log.info("true")
        }
    }
}

override fun hasAccess(cls: Class<*>?, principal: Principal?, roleChecker: Function<String, Boolean>?): Boolean {
    if (isServiceLoggingEnabled) log.info("hasAccess($cls, $principal, roleChecker)")

    return if (isProdEnvironment) {
        super.hasAccess(cls, principal, roleChecker).also {
            if (isServiceLoggingEnabled) log.info("super.hasAccess(cls, principal, roleChecker) -> $it")
        }
    }else {
        true.also {
            if (isServiceLoggingEnabled) log.info("true")
        }
    }
}

} `

mvysny commented 1 year ago

Thank you for letting me know; closing as fixed then. However, perhaps Karibu should offer some support out-of-the-box for this? If yes, we can brainstorm on the best way.