
io.devbench.uibuilder.data.common.dataprovidersupport.DataProviderRequestHandler Maven / Gradle / Ivy
/*
*
* Copyright © 2018 Webvalto Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.devbench.uibuilder.data.common.dataprovidersupport;
import com.google.gson.GsonBuilder;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.server.*;
import com.vaadin.flow.shared.JsonConstants;
import io.devbench.uibuilder.data.api.DataErrorEvent;
import io.devbench.uibuilder.data.common.dataprovidersupport.requestresponse.DataProviderRequest;
import io.devbench.uibuilder.data.common.dataprovidersupport.requestresponse.DataResponse;
import io.devbench.uibuilder.data.common.exceptions.UINotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
@Slf4j
public class DataProviderRequestHandler implements RequestHandler {
public static final String CSRF_TOKEN_ERROR = "WRONG CSRF TOKEN";
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) {
String pathInfo = request.getPathInfo();
if (pathInfo != null && pathInfo.startsWith("/datasource-api")) {
String endpointId = pathInfo.substring(pathInfo.lastIndexOf("/") + 1);
try {
UI currentUI = findUI(session, request);
DataProviderRequest dataProviderRequest = new GsonBuilder().create().fromJson(request.getReader(), DataProviderRequest.class);
dataProviderRequest.setEndpointId(endpointId);
response.setHeader("Cache-Control", "no-cache");
byte[] responseContent;
if (isCsrfTokenValid(currentUI, dataProviderRequest)) {
responseContent = handleValidRequest(session, response, dataProviderRequest);
} else {
response.setContentType("text/plain");
responseContent = CSRF_TOKEN_ERROR.getBytes(StandardCharsets.UTF_8);
getLog().warn("Invalid security key received from {}, on endpoint: {}", request.getRemoteHost(), pathInfo);
}
response.setContentLength(responseContent.length);
response.getOutputStream().write(responseContent);
response.getOutputStream().flush();
} catch (Throwable ex) {
handleExceptionUsingEndpointId(ex);
}
return true;
}
return false;
}
private UI findUI(VaadinSession session, VaadinRequest request) throws UINotFoundException {
session.lock();
try {
UI ui = session.getService().findUI(request);
if (ui == null) {
throw new UINotFoundException("UI cannot be found by request");
}
UI.setCurrent(ui);
return ui;
} finally {
session.unlock();
}
}
private void handleExceptionUsingEndpointId(Throwable throwable) {
Optional ui = Optional.ofNullable(UI.getCurrent());
if (ui.isPresent()) {
ui.get().access(() -> handleExceptionWithErrorHandler(throwable));
} else {
getLog().error("Cannot access UI", throwable);
}
}
private void handleExceptionWithErrorHandler(Throwable throwable) {
VaadinSession session = UI.getCurrent().getSession();
ErrorHandler errorHandler;
try {
session.lock();
errorHandler = session.getErrorHandler();
} finally {
session.unlock();
}
if (errorHandler != null) {
errorHandler.error(new DataErrorEvent(throwable));
}
}
private boolean isCsrfTokenValid(UI ui, DataProviderRequest dataProviderRequest) {
VaadinSession session = ui.getSession();
try {
session.lock();
return VaadinService.isCsrfTokenValid(ui, dataProviderRequest.getCsrfId());
} finally {
session.unlock();
}
}
/**
* For easier log testing.
*/
protected Logger getLog() {
return log;
}
private byte[] handleValidRequest(VaadinSession session, VaadinResponse response, DataProviderRequest dataProviderRequest) {
byte[] responseContent;
synchronized (session) {
try {
session.lock();
switch (dataProviderRequest.getRequestType()) {
case FETCH_DATA:
response.setContentType(JsonConstants.JSON_CONTENT_TYPE);
DataResponse dataResponse = DataProviderEndpointManager.getInstance().processFetchDataRequest(dataProviderRequest);
responseContent = dataResponse.asString().getBytes(StandardCharsets.UTF_8);
break;
case FETCH_SIZE:
response.setContentType("text/plain");
Long size = DataProviderEndpointManager.getInstance().processFetchSizeRequest(dataProviderRequest);
String sizeString = size == null ? "0" : String.valueOf(size);
responseContent = sizeString.getBytes();
break;
default:
responseContent = new byte[0]; //TODO error handling?
break;
}
} finally {
session.unlock();
}
}
return responseContent;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy