CB-253 Check connection permissions

This commit is contained in:
Serge Rider
2020-09-09 11:51:08 +03:00
parent 6e81806598
commit 28ea689652
6 changed files with 93 additions and 34 deletions
@@ -303,6 +303,9 @@ extend type Mutation {
# Refreshes session on server and returns its state
touchSession: Boolean
# Refresh session connection list
refreshSessionConnections: Boolean
# Refreshes session on server and returns its state
changeSessionLanguage(locale: String): Boolean
@@ -16,6 +16,8 @@
*/
package io.cloudbeaver.model.session;
import io.cloudbeaver.DBWConnectionGrant;
import io.cloudbeaver.DBWConstants;
import io.cloudbeaver.DBWSecurityController;
import io.cloudbeaver.DBWebException;
import io.cloudbeaver.model.WebAsyncTaskInfo;
@@ -52,6 +54,7 @@ import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Web session.
@@ -153,7 +156,11 @@ public class WebSession implements DBASession {
return user;
}
public synchronized Set<String> getSessionPermissions() throws DBCException {
public synchronized boolean hasPermission(String perm) {
return getSessionPermissions().contains(perm);
}
public synchronized Set<String> getSessionPermissions() {
if (sessionPermissions == null) {
refreshSessionAuth();
}
@@ -172,11 +179,7 @@ public class WebSession implements DBASession {
} catch (DBCException e) {
log.error(e);
}
try {
refreshSessionAuth();
} catch (DBCException e) {
log.error(e);
}
refreshSessionAuth();
}
private void initNavigatorModel() {
@@ -189,17 +192,59 @@ public class WebSession implements DBASession {
this.databases = projectNode.getDatabases();
this.locale = Locale.getDefault().getLanguage();
try {
this.refreshConnections();
} catch (Exception e) {
log.error("Error getting connection list", e);
}
}
public void refreshConnections() {
// Add all provided datasources to the session
List<WebConnectionInfo> connList = new ArrayList<>();
for (DBPDataSourceContainer ds : databases.getDataSourceRegistry().getDataSources()) {
if (ds.isProvided()) {
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, ds);
connList.add(connectionInfo);
}
}
filterAccessibleConnections(connList);
// Add all provided datasources to the session
synchronized (connections) {
for (DBPDataSourceContainer ds : databases.getDataSourceRegistry().getDataSources()) {
if (ds.isProvided()) {
WebConnectionInfo connectionInfo = new WebConnectionInfo(this, ds);
connections.put(connectionInfo.getId(), connectionInfo);
}
connections.clear();
for (WebConnectionInfo connectionInfo : connList) {
connections.put(connectionInfo.getId(), connectionInfo);
}
}
}
public void filterAccessibleConnections(List<WebConnectionInfo> connections) {
if (this.hasPermission(DBWConstants.PERMISSION_ADMIN)) {
// All connections are accessible
return;
}
Set<String> allowedConnections = getAccessibleConnectionIds();
connections.removeIf(c -> !allowedConnections.contains(c.getId()));
}
@NotNull
public Set<String> getAccessibleConnectionIds() {
CBApplication application = CBApplication.getInstance();
String subjectId = user == null ?
application.getAppConfiguration().getAnonymousUserRole() : user.getUserId();
try {
return Arrays.stream(application.getSecurityController()
.getSubjectConnectionAccess(new String[]{subjectId}))
.map(DBWConnectionGrant::getConnectionId).collect(Collectors.toSet());
} catch (DBCException e) {
log.error("Error reading connection grants", e);
return Collections.emptySet();
}
}
private void resetSessionCache() throws DBCException {
// Clear attributes
synchronized (attributes) {
@@ -230,17 +275,21 @@ public class WebSession implements DBASession {
this.databases = null;
}
private void refreshSessionAuth() throws DBCException {
CBApplication application = CBPlatform.getInstance().getApplication();
if (this.user == null) {
if (application.getAppConfiguration().isAnonymousAccessEnabled()) {
sessionPermissions = application.getSecurityController().getSubjectPermissions(
application.getAppConfiguration().getAnonymousUserRole());
private void refreshSessionAuth() {
try {
CBApplication application = CBPlatform.getInstance().getApplication();
if (this.user == null) {
if (application.getAppConfiguration().isAnonymousAccessEnabled()) {
sessionPermissions = application.getSecurityController().getSubjectPermissions(
application.getAppConfiguration().getAnonymousUserRole());
} else {
sessionPermissions = Collections.emptySet();
}
} else {
sessionPermissions = Collections.emptySet();
sessionPermissions = application.getSecurityController().getUserPermissions(this.user.getUserId());
}
} else {
sessionPermissions = application.getSecurityController().getUserPermissions(this.user.getUserId());
} catch (Exception e) {
log.error("Error reading session permissions", e);
}
}
@@ -28,7 +28,6 @@ import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.server.CBApplication;
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.server.graphql.GraphQLEndpoint;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.utils.CommonUtils;
import javax.servlet.http.HttpServletRequest;
@@ -147,12 +146,7 @@ public abstract class WebServiceBindingBase<API_TYPE extends DBWService> impleme
}
if (!CBApplication.getInstance().isConfigurationMode()) {
// Check permissions
Set<String> sessionPermissions;
try {
sessionPermissions = session.getSessionPermissions();
} catch (DBCException e) {
throw new DBWebExceptionAccessDenied("Can't retrieve session permissions", e);
}
Set<String> sessionPermissions = session.getSessionPermissions();
if (CommonUtils.isEmpty(sessionPermissions)) {
throw new DBWebExceptionAccessDenied("Anonymous access restricted");
}
@@ -69,6 +69,9 @@ public interface DBWServiceCore extends DBWService {
@WebAction(requirePermissions = {})
boolean touchSession(HttpServletRequest request) throws DBWebException;
@WebAction(requirePermissions = {})
boolean refreshSessionConnections(HttpServletRequest request) throws DBWebException;
@WebAction
boolean changeSessionLanguage(WebSession webSession, String locale) throws DBWebException;
@@ -66,6 +66,7 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
.dataFetcher("openSession", env -> getService(env).openSession(sessionManager.getWebSession(GraphQLEndpoint.getServletRequest(env), false)))
.dataFetcher("closeSession", env -> getService(env).closeSession(GraphQLEndpoint.getServletRequest(env)))
.dataFetcher("touchSession", env -> getService(env).touchSession(GraphQLEndpoint.getServletRequest(env)))
.dataFetcher("refreshSessionConnections", env -> getService(env).refreshSessionConnections(GraphQLEndpoint.getServletRequest(env)))
.dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale")))
.dataFetcher("openConnection", env -> getService(env).openConnection(getWebSession(env), getConnectionConfig(env)))
@@ -33,7 +33,6 @@ import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNative;
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
@@ -101,10 +100,13 @@ public class WebServiceCore implements DBWServiceCore {
public List<WebConnectionInfo> getTemplateConnections(WebSession webSession) throws DBWebException {
List<WebConnectionInfo> result = new ArrayList<>();
for (DBPDataSourceContainer ds : WebServiceUtils.getDataSourceRegistry().getDataSources()) {
if (ds.isTemplate() && CBPlatform.getInstance().getApplicableDrivers().contains(ds.getDriver())) {
if (ds.isTemplate() &&
CBPlatform.getInstance().getApplicableDrivers().contains(ds.getDriver()))
{
result.add(new WebConnectionInfo(webSession, ds));
}
}
webSession.filterAccessibleConnections(result);
return result;
}
@@ -117,11 +119,7 @@ public class WebServiceCore implements DBWServiceCore {
DBWConstants.PERMISSION_ADMIN
};
}
try {
return webSession.getSessionPermissions().toArray(new String[0]);
} catch (DBCException e) {
throw new DBWebException("Error reading session permissions", e);
}
return webSession.getSessionPermissions().toArray(new String[0]);
}
@Override
@@ -149,6 +147,17 @@ public class WebServiceCore implements DBWServiceCore {
return CBPlatform.getInstance().getSessionManager().touchSession(request);
}
@Override
public boolean refreshSessionConnections(HttpServletRequest request) throws DBWebException {
WebSession session = CBPlatform.getInstance().getSessionManager().getWebSession(request);
if (session == null) {
return false;
} else {
session.refreshConnections();
return true;
}
}
@Override
public boolean changeSessionLanguage(WebSession webSession, String locale) {
webSession.setLocale(locale);