Skip to content

Commit 9cf3b9d

Browse files
authored
feat: Implement production mode license verification in VaadinServlet (#23864)
Add runtime license verification for production mode. License check failure is only logged, it does not prevent the application from running.
1 parent dfc0ec5 commit 9cf3b9d

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

flow-data/src/test/java/com/vaadin/flow/data/provider/DataCommunicatorAsyncTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
import org.junit.runner.RunWith;
2626
import org.junit.runners.Parameterized;
2727
import org.mockito.Mock;
28+
import org.mockito.Mockito;
2829
import org.mockito.MockitoAnnotations;
2930

3031
import com.vaadin.flow.component.UI;
3132
import com.vaadin.flow.dom.Element;
33+
import com.vaadin.flow.function.DeploymentConfiguration;
3234
import com.vaadin.flow.internal.Range;
3335
import com.vaadin.flow.server.VaadinRequest;
3436
import com.vaadin.flow.server.VaadinService;
@@ -261,8 +263,9 @@ protected void init(VaadinRequest request) {
261263
private static VaadinSession findOrcreateSession() {
262264
VaadinSession session = VaadinSession.getCurrent();
263265
if (session == null) {
266+
DeploymentConfiguration conf = Mockito.mock(DeploymentConfiguration.class);
264267
session = new AlwaysLockedVaadinSession(
265-
new VaadinServletService(new VaadinServlet(), null));
268+
new VaadinServletService(new VaadinServlet(), conf));
266269
VaadinSession.setCurrent(session);
267270
}
268271
return session;

flow-server/src/main/java/com/vaadin/flow/server/VaadinServlet.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
import javax.servlet.http.HttpServletRequest;
1717
import javax.servlet.http.HttpServletResponse;
1818

19-
import com.vaadin.pro.licensechecker.BuildType;
20-
import com.vaadin.pro.licensechecker.LicenseChecker;
2119
import org.slf4j.Logger;
2220
import org.slf4j.LoggerFactory;
2321

@@ -40,6 +38,9 @@
4038
import com.vaadin.flow.server.HandlerHelper.RequestType;
4139
import com.vaadin.flow.server.startup.ApplicationConfiguration;
4240
import com.vaadin.flow.shared.JsonConstants;
41+
import com.vaadin.pro.licensechecker.BuildType;
42+
import com.vaadin.pro.licensechecker.LicenseChecker;
43+
import com.vaadin.pro.licensechecker.LicenseException;
4344

4445
/**
4546
* The main servlet, which handles all incoming requests to the application.
@@ -59,6 +60,8 @@ public class VaadinServlet extends HttpServlet {
5960

6061
public static final String INTERNAL_VAADIN_SERVLET_VITE_DEV_MODE_FRONTEND_PATH = "VAADIN_SERVLET_VITE_DEV_MODE_FRONTEND_PATH";
6162

63+
private static final String PROJECT_NAME = "flow";
64+
6265
private VaadinServletService servletService;
6366
private StaticFileHandler staticFileHandler;
6467

@@ -123,7 +126,8 @@ public void init(ServletConfig servletConfig) throws ServletException {
123126

124127
try {
125128
servletService = createServletService();
126-
validateLicense(servletService.getDeploymentConfiguration());
129+
verifyLicense(servletService.getDeploymentConfiguration()
130+
.isProductionMode());
127131
} catch (ServiceException e) {
128132
throw new ServletException("Could not initialize VaadinServlet",
129133
e);
@@ -142,6 +146,25 @@ public void init(ServletConfig servletConfig) throws ServletException {
142146
}
143147
}
144148

149+
private void verifyLicense(boolean productionMode) {
150+
String frameworkVersion = Version.getFullVersion();
151+
if (productionMode) {
152+
try {
153+
LicenseChecker.checkLicense(PROJECT_NAME, frameworkVersion,
154+
BuildType.PRODUCTION, null);
155+
} catch (LicenseException e) {
156+
getLogger().error(
157+
"This Vaadin version requires an extended maintenance subscription."
158+
+ "Provide either a server key or an online license checking key,"
159+
+ "which you can get from: https://vaadin.com/myaccount/licenses#latest.",
160+
e);
161+
}
162+
} else {
163+
LicenseChecker.checkLicense(PROJECT_NAME, frameworkVersion,
164+
BuildType.DEVELOPMENT);
165+
}
166+
}
167+
145168
private void detectFrontendMapping() {
146169
synchronized (VaadinServlet.class) {
147170
if (frontendMapping != null) {
@@ -622,13 +645,4 @@ private VaadinServletContext initializeContext() {
622645
public static String getFrontendMapping() {
623646
return frontendMapping;
624647
}
625-
626-
private void validateLicense(
627-
DeploymentConfiguration deploymentConfiguration) {
628-
// Check the license at runtime if in development mode
629-
if (!deploymentConfiguration.isProductionMode()) {
630-
LicenseChecker.checkLicense("flow", Version.getFullVersion(),
631-
BuildType.DEVELOPMENT);
632-
}
633-
}
634648
}

flow-server/src/test/java/com/vaadin/flow/server/VaadinServletTest.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.vaadin.flow.internal.VaadinContextInitializer;
2525
import com.vaadin.pro.licensechecker.BuildType;
2626
import com.vaadin.pro.licensechecker.LicenseChecker;
27+
import com.vaadin.pro.licensechecker.LicenseException;
2728
import net.jcip.annotations.NotThreadSafe;
2829
import org.junit.After;
2930
import org.junit.Assert;
@@ -384,11 +385,27 @@ public void checkLicense_devMode_licenseIsChecked()
384385
}
385386

386387
@Test
387-
public void checkLicense_prodMode_licenseIsNotChecked()
388+
public void checkLicense_prodMode_licenseIsChecked()
388389
throws ServletException {
389390
Mockito.when(configuration.isProductionMode()).thenReturn(true);
390391
triggerLicenseChecking();
391-
licenseChecker.verifyNoInteractions();
392+
licenseChecker.verify(() -> LicenseChecker.checkLicense("flow",
393+
Version.getFullVersion(), BuildType.PRODUCTION, null));
394+
}
395+
396+
@Test
397+
public void checkLicense_prodModeCheck_notFails()
398+
throws ServletException {
399+
licenseChecker
400+
.when(() -> LicenseChecker.checkLicense("flow",
401+
Version.getFullVersion(), BuildType.PRODUCTION, null))
402+
.thenThrow(new LicenseException("Test exception"));
403+
try {
404+
triggerLicenseChecking();
405+
} catch (LicenseException e) {
406+
Assert.fail(
407+
"License check should not throw exception in prod mode");
408+
}
392409
}
393410

394411
private ServletConfig mockConfig() {

0 commit comments

Comments
 (0)