Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CB-3971 validate main session #2106

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
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ CREATE TABLE {table_prefix}CB_AUTH_ATTEMPT
SESSION_ID VARCHAR(64),
SESSION_TYPE VARCHAR(64) NOT NULL,
APP_SESSION_STATE TEXT NOT NULL,

IS_MAIN_AUTH CHAR(1) DEFAULT 'Y' NOT NULL,
CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,

PRIMARY KEY (AUTH_ID),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE {table_prefix}CB_AUTH_ATTEMPT
ADD COLUMN IS_MAIN_AUTH CHAR(1) DEFAULT 'Y' NOT NULL;
Original file line number Diff line number Diff line change
Expand Up @@ -1289,9 +1289,9 @@ public SMAuthInfo authenticate(
throw new SMException("Unsupported authentication provider: " + authProviderId);
}
var authProgressMonitor = new LoggingProgressMonitor(log);
boolean isMainSession = previousSmSessionId == null;
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
boolean isMainSession = previousSmSessionId == null;
Map<String, Object> securedUserIdentifyingCredentials = userCredentials;
WebAuthProviderDescriptor authProviderDescriptor = getAuthProvider(authProviderId);
var authProviderInstance = authProviderDescriptor.getInstance();
Expand Down Expand Up @@ -1334,15 +1334,17 @@ public SMAuthInfo authenticate(
String signOutLink = authProviderFederated.getSignOutLink(authProviderConfigurationId, Map.of());
Map<SMAuthConfigurationReference, Object> authData = Map.of(new SMAuthConfigurationReference(authProviderId,
authProviderConfigurationId), filteredUserCreds);
return SMAuthInfo.inProgress(authAttemptId, signInLink, signOutLink, authData);
return SMAuthInfo.inProgress(authAttemptId, signInLink, signOutLink, authData, isMainSession);
}
txn.commit();
return finishAuthentication(
SMAuthInfo.inProgress(
authAttemptId,
null,
null,
Map.of(new SMAuthConfigurationReference(authProviderId, authProviderConfigurationId), securedUserIdentifyingCredentials)
Map.of(new SMAuthConfigurationReference(authProviderId, authProviderConfigurationId),
securedUserIdentifyingCredentials),
isMainSession
),
true,
false
Expand Down Expand Up @@ -1385,8 +1387,9 @@ private String createNewAuthAttempt(
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames(
"INSERT INTO {table_prefix}CB_AUTH_ATTEMPT" +
"(AUTH_ID,AUTH_STATUS,APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID) " +
"VALUES(?,?,?,?,?,?)"
"(AUTH_ID,AUTH_STATUS,APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE," +
"SESSION_ID,IS_MAIN_AUTH) " +
"VALUES(?,?,?,?,?,?,?)"
)
)) {
dbStat.setString(1, authAttemptId);
Expand All @@ -1399,6 +1402,7 @@ private String createNewAuthAttempt(
} else {
dbStat.setNull(6, Types.VARCHAR);
}
dbStat.setString(7, isMainSession ? CHAR_BOOL_TRUE : CHAR_BOOL_FALSE);
dbStat.execute();
}

Expand Down Expand Up @@ -1518,9 +1522,11 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData
SMAuthStatus smAuthStatus;
String authError;
String smSessionId;
boolean isMainAuth;
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames(
"SELECT AUTH_STATUS,AUTH_ERROR,SESSION_ID FROM {table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?"
"SELECT AUTH_STATUS,AUTH_ERROR,SESSION_ID,IS_MAIN_AUTH FROM {table_prefix}CB_AUTH_ATTEMPT WHERE " +
"AUTH_ID=?"
)
)) {
dbStat.setString(1, authId);
Expand All @@ -1531,6 +1537,7 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData
smAuthStatus = SMAuthStatus.valueOf(dbResult.getString(1));
authError = dbResult.getString(2);
smSessionId = dbResult.getString(3);
isMainAuth = CHAR_BOOL_TRUE.equals(dbResult.getString(4));
}
}
Map<SMAuthConfigurationReference, Object> authData = new LinkedHashMap<>();
Expand Down Expand Up @@ -1571,28 +1578,33 @@ private SMAuthInfo getAuthStatus(@NotNull String authId, boolean readExpiredData
if (smAuthStatus != SMAuthStatus.SUCCESS) {
switch (smAuthStatus) {
case IN_PROGRESS:
return SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData);
return SMAuthInfo.inProgress(authId, signInLink, signOutLink, authData, isMainAuth);
case ERROR:
return SMAuthInfo.error(authId, authError);
return SMAuthInfo.error(authId, authError, isMainAuth);
case EXPIRED:
return SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of());
return SMAuthInfo.expired(authId, readExpiredData ? authData : Map.of(), isMainAuth);
default:
throw new SMException("Unknown auth status:" + smAuthStatus);
}
}

SMTokens smTokens = findTokenBySmSession(smSessionId);
SMAuthPermissions authPermissions = getTokenPermissions(smTokens.getSmAccessToken());
String authRole = readTokenAuthRole(smTokens.getSmAccessToken());
var successAuthStatus = SMAuthInfo.successMainSession(
authId,
smTokens.getSmAccessToken(),
smTokens.getSmRefreshToken(),
authPermissions,
authData,
authRole
);
return successAuthStatus;

if (isMainAuth) {
String authRole = readTokenAuthRole(smTokens.getSmAccessToken());
return SMAuthInfo.successMainSession(
authId,
smTokens.getSmAccessToken(),
smTokens.getSmRefreshToken(),
authPermissions,
authData,
authRole
);
} else {
//TODO remove permissions from child session
return SMAuthInfo.successChildSession(authId, authPermissions, authData);
}
} catch (SQLException e) {
throw new DBException("Error while read auth info", e);
}
Expand Down Expand Up @@ -1792,7 +1804,7 @@ private SMAuthInfo finishAuthentication(

DBRProgressMonitor finishAuthMonitor = new LoggingProgressMonitor(log);
AuthAttemptSessionInfo authAttemptSessionInfo = readAuthAttemptSessionInfo(authId);
boolean isMainAuthSession = authAttemptSessionInfo.getSmSessionId() == null;
boolean isMainAuthSession = authAttemptSessionInfo.isMainAuth();

SMTokens smTokens = null;
SMAuthPermissions permissions = null;
Expand Down Expand Up @@ -1850,7 +1862,7 @@ private SMAuthInfo finishAuthentication(
if (userIdFromCreds == null) {
var error = "Invalid user credentials";
updateAuthStatus(authId, SMAuthStatus.ERROR, storedUserData, error);
return SMAuthInfo.error(authId, error);
return SMAuthInfo.error(authId, error, isMainAuthSession);
}

if (autoAssign != null && !CommonUtils.isEmpty(autoAssign.getExternalTeamIds())) {
Expand Down Expand Up @@ -2036,8 +2048,9 @@ protected String updateUserAuthRoleIfNeeded(@Nullable String userId, @Nullable S
private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId) throws DBException {
try (Connection dbCon = database.openConnection()) {
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("SELECT APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID FROM " +
"{table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?")
database.normalizeTableNames(
"SELECT APP_SESSION_ID,SESSION_TYPE,APP_SESSION_STATE,SESSION_ID,IS_MAIN_AUTH " +
"FROM {table_prefix}CB_AUTH_ATTEMPT WHERE AUTH_ID=?")
)) {
dbStat.setString(1, authId);
try (ResultSet dbResult = dbStat.executeQuery()) {
Expand All @@ -2050,8 +2063,15 @@ private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId
dbResult.getString(3), MAP_STRING_OBJECT_TYPE
);
String smSessionId = dbResult.getString(4);

return new AuthAttemptSessionInfo(appSessionId, smSessionId, sessionType, sessionParams);
boolean isMainAuth = CHAR_BOOL_TRUE.equals(dbResult.getString(5));

return new AuthAttemptSessionInfo(
appSessionId,
smSessionId,
sessionType,
sessionParams,
isMainAuth
);
}
}
} catch (SQLException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public class CBDatabase {
public static final String SCHEMA_UPDATE_SQL_PATH = "db/cb_schema_update_";

private static final int LEGACY_SCHEMA_VERSION = 1;
private static final int CURRENT_SCHEMA_VERSION = 13;
private static final int CURRENT_SCHEMA_VERSION = 14;

private static final String DEFAULT_DB_USER_NAME = "cb-data";
private static final String DEFAULT_DB_PWD_FILE = ".database-credentials.dat";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@ public class AuthAttemptSessionInfo {
private final SMSessionType sessionType;
@NotNull
private final Map<String, Object> sessionParams;
private final boolean mainAuth;

public AuthAttemptSessionInfo(
@NotNull String appSessionId,
@Nullable String smSessionId,
@NotNull SMSessionType sessionType,
@NotNull Map<String, Object> sessionParams
@NotNull Map<String, Object> sessionParams,
boolean mainAuth
) {
this.appSessionId = appSessionId;
this.smSessionId = smSessionId;
this.sessionType = sessionType;
this.sessionParams = sessionParams;
this.mainAuth = mainAuth;
}

@NotNull
Expand All @@ -65,4 +68,8 @@ public Map<String, Object> getSessionParams() {
public String getSmSessionId() {
return smSessionId;
}

public boolean isMainAuth() {
return mainAuth;
}
}
Loading