mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
#8 Permission check
This commit is contained in:
@@ -57,6 +57,11 @@ public class DBWebException extends DBException implements GraphQLError {
|
||||
super(makeMessage(message, cause), cause);
|
||||
}
|
||||
|
||||
public DBWebException(String message, String errorCode, Throwable cause) {
|
||||
this(message, cause);
|
||||
this.webErrorCode = errorCode;
|
||||
}
|
||||
|
||||
public DBWebException(Throwable cause, DBPDataSource dataSource) {
|
||||
super(cause, dataSource);
|
||||
}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2020 DBeaver Corp and others
|
||||
*
|
||||
* 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.cloudbeaver;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class DBWebExceptionAccessDenied extends DBWebException {
|
||||
|
||||
public static final String ERROR_CODE_ACCESS_DENIED = "accessDenied";
|
||||
|
||||
public DBWebExceptionAccessDenied(String message) {
|
||||
super(message, ERROR_CODE_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
public DBWebExceptionAccessDenied(String message, Throwable cause) {
|
||||
super(message, ERROR_CODE_ACCESS_DENIED, cause);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,16 @@
|
||||
|
||||
package io.cloudbeaver;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Object association annotation
|
||||
*/
|
||||
@Target(value = {ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface WebAction {
|
||||
|
||||
String[] requirePermissions() default { DBWConstants.PERMISSION_PUBLIC };
|
||||
|
||||
+10
-7
@@ -66,8 +66,8 @@ public class WebSession {
|
||||
|
||||
private static final AtomicInteger TASK_ID = new AtomicInteger();
|
||||
|
||||
private String id;
|
||||
private long createTime;
|
||||
private final String id;
|
||||
private final long createTime;
|
||||
private long lastAccessTime;
|
||||
|
||||
private WebUser user;
|
||||
@@ -122,23 +122,26 @@ public class WebSession {
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLastAccessTime() {
|
||||
public synchronized String getLastAccessTime() {
|
||||
return CBConstants.ISO_DATE_FORMAT.format(lastAccessTime);
|
||||
}
|
||||
|
||||
public long getLastAccessTimeMillis() {
|
||||
public synchronized long getLastAccessTimeMillis() {
|
||||
return lastAccessTime;
|
||||
}
|
||||
|
||||
public WebUser getUser() {
|
||||
public synchronized WebUser getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public Set<String> getSessionPermissions() {
|
||||
public synchronized Set<String> getSessionPermissions() throws DBCException {
|
||||
if (sessionPermissions == null) {
|
||||
refreshSessionAuth();
|
||||
}
|
||||
return sessionPermissions;
|
||||
}
|
||||
|
||||
public void setUser(WebUser user) {
|
||||
public synchronized void setUser(WebUser user) {
|
||||
if (CommonUtils.equalObjects(this.user, user)) {
|
||||
return;
|
||||
}
|
||||
|
||||
+7
-20
@@ -17,9 +17,9 @@
|
||||
package io.cloudbeaver.model.session;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
@@ -49,11 +49,6 @@ public class WebSessionManager {
|
||||
public WebSessionManager() {
|
||||
}
|
||||
|
||||
public WebSession getWebSession(@NotNull HttpServletRequest request, boolean errorOnNoFound) throws DBWebException {
|
||||
HttpSession session = getOrCreateHttpSession(request);
|
||||
return getWebSession(session, true, errorOnNoFound);
|
||||
}
|
||||
|
||||
public boolean closeSession(@NotNull HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
if (session != null) {
|
||||
@@ -80,20 +75,12 @@ public class WebSessionManager {
|
||||
return getWebSession(request, true);
|
||||
}
|
||||
|
||||
private HttpSession getOrCreateHttpSession(@NotNull HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
if (session == null) {
|
||||
session = request.getSession(true);
|
||||
log.debug("New session: " + session.getId());
|
||||
}
|
||||
return session;
|
||||
public WebSession getWebSession(@NotNull HttpServletRequest request, boolean errorOnNoFound) throws DBWebException {
|
||||
return getWebSession(request, true, errorOnNoFound);
|
||||
}
|
||||
|
||||
public WebSession getWebSession(HttpServletRequest request, boolean updateInfo, boolean errorOnNoFound) throws DBWebException {
|
||||
return getWebSession(getOrCreateHttpSession(request), updateInfo, errorOnNoFound);
|
||||
}
|
||||
|
||||
public WebSession getWebSession(HttpSession httpSession, boolean updateInfo, boolean errorOnNoFound) throws DBWebException {
|
||||
HttpSession httpSession = request.getSession(true);
|
||||
String sessionId = httpSession.getId();
|
||||
WebSession webSession;
|
||||
synchronized (sessionMap) {
|
||||
@@ -113,11 +100,11 @@ public class WebSessionManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
return webSession;
|
||||
return webSession;
|
||||
}
|
||||
|
||||
public WebSession tryGetWebSession(HttpSession httpSession) {
|
||||
String sessionId = httpSession.getId();
|
||||
public WebSession findWebSession(HttpServletRequest request) {
|
||||
String sessionId = request.getSession().getId();
|
||||
synchronized (sessionMap) {
|
||||
return sessionMap.get(sessionId);
|
||||
}
|
||||
|
||||
+46
-3
@@ -21,9 +21,13 @@ import graphql.schema.idl.SchemaParser;
|
||||
import graphql.schema.idl.TypeDefinitionRegistry;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.DBWService;
|
||||
import io.cloudbeaver.DBWebExceptionAccessDenied;
|
||||
import io.cloudbeaver.WebAction;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.server.graphql.GraphQLEndpoint;
|
||||
import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
@@ -34,6 +38,7 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Web service implementation
|
||||
@@ -63,7 +68,7 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
* Creates proxy for permission checks and other general API calls validation/logging.
|
||||
*/
|
||||
protected API_TYPE getService(DataFetchingEnvironment env) {
|
||||
Object proxyImpl = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{apiInterface}, new ServiceInvocationHandler(serviceImpl));
|
||||
Object proxyImpl = Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{apiInterface}, new ServiceInvocationHandler(serviceImpl, env));
|
||||
return apiInterface.cast(proxyImpl);
|
||||
}
|
||||
|
||||
@@ -89,7 +94,13 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
}
|
||||
|
||||
protected static WebSession getWebSession(DataFetchingEnvironment env) throws DBWebException {
|
||||
return getBindingContext(env).getSessionManager().getWebSession(getServletRequest(env));
|
||||
return getBindingContext(env).getSessionManager().getWebSession(
|
||||
getServletRequest(env));
|
||||
}
|
||||
|
||||
protected static WebSession findWebSession(DataFetchingEnvironment env) {
|
||||
return getBindingContext(env).getSessionManager().findWebSession(
|
||||
getServletRequest(env));
|
||||
}
|
||||
|
||||
protected static WebConnectionInfo getWebConnection(DataFetchingEnvironment env) throws DBWebException {
|
||||
@@ -98,18 +109,50 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
|
||||
|
||||
private class ServiceInvocationHandler implements InvocationHandler {
|
||||
private final API_TYPE impl;
|
||||
private final DataFetchingEnvironment env;
|
||||
|
||||
ServiceInvocationHandler(API_TYPE impl) {
|
||||
ServiceInvocationHandler(API_TYPE impl, DataFetchingEnvironment env) {
|
||||
this.impl = impl;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
try {
|
||||
WebAction webAction = method.getAnnotation(WebAction.class);
|
||||
if (webAction != null) {
|
||||
checkPermissions(webAction);
|
||||
}
|
||||
return method.invoke(impl, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getTargetException();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkPermissions(WebAction webAction) throws DBWebExceptionAccessDenied {
|
||||
String[] reqPermissions = webAction.requirePermissions();
|
||||
if (reqPermissions.length == 0) {
|
||||
return;
|
||||
}
|
||||
WebSession session = findWebSession(env);
|
||||
if (session == null) {
|
||||
throw new DBWebExceptionAccessDenied("Anonymous access restricted");
|
||||
}
|
||||
Set<String> sessionPermissions;
|
||||
try {
|
||||
sessionPermissions = session.getSessionPermissions();
|
||||
} catch (DBCException e) {
|
||||
throw new DBWebExceptionAccessDenied("Can't retrieve session permissions", e);
|
||||
}
|
||||
if (CommonUtils.isEmpty(sessionPermissions)) {
|
||||
throw new DBWebExceptionAccessDenied("Anonymous access restricted");
|
||||
}
|
||||
for (String rp : reqPermissions) {
|
||||
if (!sessionPermissions.contains(rp)) {
|
||||
throw new DBWebExceptionAccessDenied("Access denied");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class WebDataTransferServlet extends HttpServlet {
|
||||
dataFileId = dataFileId.substring(1);
|
||||
}
|
||||
|
||||
WebSession webSession = CBPlatform.getInstance().getSessionManager().tryGetWebSession(request.getSession());
|
||||
WebSession webSession = CBPlatform.getInstance().getSessionManager().findWebSession(request);
|
||||
if (webSession == null) {
|
||||
throw new DBWebException("No active session");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user