Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ call yarn link

cd ..\cloudbeaver\webapp

call yarn link "react-data-grid"
call yarn
call yarn link "react-data-grid"
call lerna bootstrap
call lerna run build --no-bail --stream --scope=@cloudbeaver/product-default &::-- -- --env source-map

Expand Down
2 changes: 1 addition & 1 deletion deploy/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ yarn link

cd ../cloudbeaver/webapp

yarn link "react-data-grid"
yarn
yarn link "react-data-grid"
lerna run bootstrap
lerna run build --no-bail --stream --scope=@cloudbeaver/product-default #-- -- --env source-map
if [[ "$?" -ne 0 ]] ; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
private String lastRemoteAddr;
private String lastRemoteUserAgent;

private WebUser user;
private Set<String> sessionPermissions = null;
private Set<String> accessibleConnectionIds = Collections.emptySet();
private SMCredentials smCredentials = null;

private String locale;
private boolean cacheExpired;
Expand All @@ -116,11 +113,9 @@ public class WebSession extends AbstractSessionPersistent implements SMSession,
private final DBRProgressMonitor progressMonitor = new SessionProgressMonitor();
private ProjectMetadata sessionProject;
private final SessionContextImpl sessionAuthContext;
private SMController securityController;
private SMAdminController adminSecurityController;
private RMController rmController;
private final WebApplication application;
private final Map<String, DBWSessionHandler> sessionHandlers;
private final WebUserContext userContext;

@NotNull
public static Path getUserProjectsFolder() {
Expand All @@ -138,7 +133,7 @@ public WebSession(HttpSession httpSession,
this.sessionAuthContext.addSession(this);
this.application = application;
this.sessionHandlers = sessionHandlers;
this.securityController = application.getSecurityController(this);
this.userContext = new WebUserContext(application);

initNavigatorModel();
}
Expand Down Expand Up @@ -214,10 +209,11 @@ public void setCacheExpired(boolean cacheExpired) {
}

public synchronized WebUser getUser() {
return user;
return this.userContext.getUser();
}

public synchronized Map<String, String> getUserMetaParameters() {
var user = getUser();
if (user == null) {
return Map.of();
}
Expand All @@ -229,39 +225,39 @@ public synchronized Map<String, String> getUserMetaParameters() {
}

public synchronized String getUserId() {
return user == null ? null : user.getUserId();
return userContext.getUserId();
}

public synchronized boolean hasPermission(String perm) {
return getSessionPermissions().contains(perm);
}

public synchronized boolean isAuthorizedInSecurityManager() {
return smCredentials != null;
return userContext.isAuthorizedInSecurityManager();
}

public synchronized Set<String> getSessionPermissions() {
if (sessionPermissions == null) {
if (userContext.getUserPermissions() == null) {
refreshSessionAuth();
}
return sessionPermissions;
return userContext.getUserPermissions();
}

@NotNull
public synchronized SMController getSecurityController() {
return securityController;
return userContext.getSecurityController();
}

@Nullable
public synchronized SMAdminController getAdminSecurityController() {
if (!hasPermission(DBWConstants.PERMISSION_ADMIN)) {
return null;
}
return adminSecurityController;
return userContext.getAdminSecurityController();
}

public synchronized RMController getRmController() {
return rmController;
return userContext.getRmController();
}

public synchronized void refreshUserData() {
Expand All @@ -288,6 +284,7 @@ private void initNavigatorModel() {

String projectName;
Path projectPath;
WebUser user = userContext.getUser();
if (user != null) {
projectName = CommonUtils.escapeFileName(user.getUserId());
projectPath = getUserProjectsFolder().resolve(projectName);
Expand Down Expand Up @@ -375,11 +372,12 @@ private boolean isDataSourceAccessible(DBPDataSourceContainer dataSource) {

@NotNull
private Set<String> readAccessibleConnectionIds() {
WebUser user = getUser();
String subjectId = user == null ?
application.getAppConfiguration().getAnonymousUserRole() : user.getUserId();

try {
return Arrays.stream(securityController
return Arrays.stream(getSecurityController()
.getSubjectConnectionAccess(new String[]{subjectId}))
.map(SMDataSourceGrant::getDataSourceId).collect(Collectors.toSet());
} catch (DBException e) {
Expand Down Expand Up @@ -428,7 +426,7 @@ private synchronized void refreshSessionAuth() {
if (!isAuthorizedInSecurityManager()) {
authAsAnonymousUser();
} else if (getUserId() != null) {
sessionPermissions = securityController.getUserPermissions(getUserId());
userContext.refreshPermissions();
}
refreshAccessibleConnectionIds();

Expand All @@ -444,10 +442,9 @@ private synchronized void refreshAccessibleConnectionIds() {

private synchronized void authAsAnonymousUser() throws DBException {
if (!application.getAppConfiguration().isAnonymousAccessEnabled()) {
this.sessionPermissions = Collections.emptySet();
return;
}
SMAuthInfo authInfo = securityController.authenticateAnonymousUser(this.id, getSessionParameters(), CB_SESSION_TYPE);
SMAuthInfo authInfo = getSecurityController().authenticateAnonymousUser(this.id, getSessionParameters(), CB_SESSION_TYPE);
updateSMAuthInfo(authInfo);
}

Expand Down Expand Up @@ -492,7 +489,7 @@ public synchronized void updateInfo(HttpServletRequest request, HttpServletRespo
if (!application.isConfigurationMode()) {
// Update record
//TODO use generate id from SMController
securityController.updateSession(this.id, getUserId(), getSessionParameters());
getSecurityController().updateSession(this.userContext.getSmSessionId(), getUserId(), getSessionParameters());
}
}
} catch (Exception e) {
Expand Down Expand Up @@ -557,7 +554,7 @@ public void close() {
}
clearAuthTokens();
this.sessionAuthContext.close();
setUser(null);
this.userContext.setUser(null);

if (this.sessionProject != null) {
this.sessionProject.dispose();
Expand Down Expand Up @@ -769,11 +766,11 @@ public void addAuthTokens(@NotNull WebAuthInfo... tokens) throws DBException {
}
newUser = authInfo.getUser();
}
if (application.isConfigurationMode() && this.user == null && newUser != null) {
if (application.isConfigurationMode() && this.userContext.getUser() == null && newUser != null) {
//FIXME hotfix to avoid exception after external auth provider login in easy config
setUser(newUser);
userContext.setUser(newUser);
refreshUserData();
} else if (!CommonUtils.equalObjects(this.user, newUser)) {
} else if (!CommonUtils.equalObjects(this.userContext.getUser(), newUser)) {
throw new DBException("Can't authorize different users in the single session");
}

Expand Down Expand Up @@ -903,37 +900,17 @@ public Map<String, Object> getSessionParameters() {
}

public synchronized void resetAuthToken() {
this.sessionPermissions = null;
this.smCredentials = null;
this.user = null;
this.securityController = application.getSecurityController(this);
this.adminSecurityController = null;
this.rmController = application.getResourceController(this);
this.userContext.reset();
}

public synchronized void updateSMAuthInfo(SMAuthInfo smAuthInfo) throws DBException {
var isNonAnonymousUserAuthorized = isAuthorizedInSecurityManager() && getUser() != null;
var tokenInfo = smAuthInfo.getUserInfo();
if (isNonAnonymousUserAuthorized && !Objects.equals(getUserId(), tokenInfo.getUserId())) {
throw new DBCException("Another user is already logged in");
}
this.smCredentials = new SMCredentials(smAuthInfo.getAuthToken(), tokenInfo.getUserId());
this.sessionPermissions = tokenInfo.getPermissions();
this.securityController = application.getSecurityController(this);
this.adminSecurityController = application.getAdminSecurityController(this);
this.rmController = application.getResourceController(this);

setUser(tokenInfo.getUserId() == null ? null : new WebUser(securityController.getUserById(tokenInfo.getUserId())));
userContext.refresh(smAuthInfo);
refreshUserData();
}

private synchronized void setUser(@Nullable WebUser user) {
this.user = user;
}

@Override
public SMCredentials getActiveUserCredentials() {
return smCredentials;
return userContext.getActiveUserCredentials();
}

private class SessionProgressMonitor extends BaseProgressMonitor {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2022 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.model.session;

import io.cloudbeaver.model.app.WebApplication;
import io.cloudbeaver.model.user.WebUser;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.auth.SMAuthInfo;
import org.jkiss.dbeaver.model.auth.SMCredentials;
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.rm.RMController;
import org.jkiss.dbeaver.model.security.SMAdminController;
import org.jkiss.dbeaver.model.security.SMController;

import java.util.Objects;
import java.util.Set;

/**
* Web user context.
* Contains user state and services based on available permissions
*/
public class WebUserContext implements SMCredentialsProvider {
private final WebApplication application;

private WebUser user;
private Set<String> userPermissions;
private SMCredentials smCredentials = null;
private String smSessionId;

private SMController securityController;
private SMAdminController adminSecurityController;
private RMController rmController;

public WebUserContext(WebApplication application) {
this.application = application;
this.securityController = application.getSecurityController(this);
this.userPermissions = getDefaultPermissions();
}

/**
* refresh context state based on new token from security manager
*
* @param smAuthInfo - auth info from security manager
* @throws DBException - if user already authorized and new token
*/
public void refresh(SMAuthInfo smAuthInfo) throws DBException {
var isNonAnonymousUserAuthorized = isAuthorizedInSecurityManager() && getUser() != null;
var tokenInfo = smAuthInfo.getAuthPermissions();
if (isNonAnonymousUserAuthorized && !Objects.equals(getUserId(), tokenInfo.getUserId())) {
throw new DBCException("Another user is already logged in");
}
this.smCredentials = new SMCredentials(smAuthInfo.getAuthToken(), tokenInfo.getUserId());
this.userPermissions = tokenInfo.getPermissions();
this.securityController = application.getSecurityController(this);
this.adminSecurityController = application.getAdminSecurityController(this);
this.rmController = application.getResourceController(this);
this.smSessionId = smAuthInfo.getAuthPermissions().getSessionId();
setUser(tokenInfo.getUserId() == null ? null : new WebUser(securityController.getUserById(tokenInfo.getUserId())));

}

/**
* reset the state as if the user is not logged in
*/
public void reset() {
this.userPermissions = getDefaultPermissions();
this.smCredentials = null;
this.user = null;
this.securityController = application.getSecurityController(this);
this.adminSecurityController = null;
this.rmController = application.getResourceController(this);
}

@NotNull
public synchronized SMController getSecurityController() {
return securityController;
}

@Nullable
@Override
public synchronized SMCredentials getActiveUserCredentials() {
return smCredentials;
}

public synchronized boolean isAuthorizedInSecurityManager() {
return smCredentials != null;
}

@Nullable
public synchronized WebUser getUser() {
return user;
}

public synchronized String getUserId() {
return user == null ? null : user.getUserId();
}

protected synchronized void setUser(@Nullable WebUser user) {
this.user = user;
}

public synchronized SMAdminController getAdminSecurityController() {
return adminSecurityController;
}

public synchronized RMController getRmController() {
return rmController;
}

public synchronized Set<String> getUserPermissions() {
return userPermissions;
}

/**
* reread the current user's permissions
*/
public synchronized void refreshPermissions() throws DBException {
if (isAuthorizedInSecurityManager()) {
this.userPermissions = securityController.getTokenPermissions(smCredentials.getSmToken()).getPermissions();
} else {
this.userPermissions = getDefaultPermissions();
}
}

public synchronized String getSmSessionId() {
return smSessionId;
}

private Set<String> getDefaultPermissions() {
return application.getAppConfiguration().isAnonymousAccessEnabled() ? null : Set.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ public WebAuthInfo authLogin(
if (curUser == null) {
try {
SMAuthInfo smAuthInfo = securityController.authenticate(webSession.getSessionId(), webSession.getSessionParameters(), WebSession.CB_SESSION_TYPE, authProvider.getId(), userCredentials);
userId = smAuthInfo.getUserInfo().getUserId();
userId = smAuthInfo.getAuthPermissions().getUserId();
if (userId == null) {
throw new SMException("Anonymous authentication restricted");
}
Expand Down Expand Up @@ -253,7 +253,7 @@ private boolean isAdminAuthTry(@NotNull WebSession session, @NotNull AuthProvide
authProvider.getId(),
userCredentials);

isAdmin = authInfo.getUserInfo().getPermissions().contains(DBWConstants.PERMISSION_ADMIN);
isAdmin = authInfo.getAuthPermissions().getPermissions().contains(DBWConstants.PERMISSION_ADMIN);
} catch (DBException e) {
log.error(e);
}
Expand Down
Loading