Skip to content

Commit

Permalink
CB-3834 profile management api
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-skoblikov committed Jan 25, 2024
1 parent 938033d commit 91f5b10
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public abstract class BaseWebAppConfiguration implements WebAppConfiguration {

protected final Map<String, Object> plugins;
protected String defaultUserTeam;
protected String defaultUserCredentialsProfile;
protected boolean resourceManagerEnabled;
protected boolean showReadOnlyConnectionInfo;
protected String[] enabledFeatures;
Expand Down Expand Up @@ -105,4 +106,9 @@ public void setEnabledFeatures(String[] enabledFeatures) {
public boolean isShowReadOnlyConnectionInfo() {
return showReadOnlyConnectionInfo;
}


public String getDefaultUserCredentialsProfile() {
return defaultUserCredentialsProfile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.cloudbeaver.model.app;

import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;

import java.util.Map;

Expand All @@ -32,6 +33,9 @@ public interface WebAppConfiguration {

String getDefaultUserTeam();

@Nullable
String getDefaultUserCredentialsProfile();

<T> T getPluginOption(@NotNull String pluginId, @NotNull String option);

Map<String, Object> getPluginConfig(@NotNull String pluginId, boolean create);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,9 @@ public String toString() {
public String getAuthRole() {
return user.getAuthRole();
}

public String getCredentialsProfileId() {
return user.getCredentialsProfileId();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type AdminUserInfo {
linkedAuthProviders: [String!]!
enabled: Boolean!
authRole: String
credentialsProfileId: String @since(version: "23.3.4")
}

type AdminTeamInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public String getAuthRole() {
return user.getAuthRole();
}

@Property
public String getCredentialsProfileId() {
return user.getCredentialsProfileId();
}


@Property
public Map<String, String> getMetaParameters() {
return user.getMetaParameters();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class CBEmbeddedSecurityController<T extends WebAuthApplication>

private static final String SUBJECT_USER = "U";
private static final String SUBJECT_TEAM = "R";
private static final String SUBJECT_PROFILE = "P";
private static final Type MAP_STRING_OBJECT_TYPE = new TypeToken<Map<String, Object>>() {
}.getType();
private static final Gson gson = new GsonBuilder().create();
Expand Down Expand Up @@ -300,15 +301,18 @@ public SMUser getUserById(String userId) throws DBException {
try (Connection dbCon = database.openConnection()) {
SMUser user;
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("SELECT USER_ID,IS_ACTIVE,DEFAULT_AUTH_ROLE FROM {table_prefix}CB_USER WHERE USER_ID=?")
database.normalizeTableNames(
"SELECT USER_ID,IS_ACTIVE,DEFAULT_AUTH_ROLE,CREDENTIALS_PROFILE_ID FROM {table_prefix}CB_USER " +
"WHERE USER_ID=?")
)) {
dbStat.setString(1, userId);
try (ResultSet dbResult = dbStat.executeQuery()) {
if (dbResult.next()) {
String userName = dbResult.getString(1);
String active = dbResult.getString(2);
String authRole = dbResult.getString(3);
user = new SMUser(userName, CHAR_BOOL_TRUE.equals(active), authRole);
String credentialsProfileId = dbResult.getString(4);
user = new SMUser(userName, CHAR_BOOL_TRUE.equals(active), authRole, credentialsProfileId);
} else {
return null;
}
Expand Down Expand Up @@ -373,16 +377,18 @@ public SMUser[] findUsers(@NotNull SMUserFilter filter)
Map<String, SMUser> result = new LinkedHashMap<>();
// Read users
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("SELECT USER_ID,IS_ACTIVE,DEFAULT_AUTH_ROLE FROM {table_prefix}CB_USER"
database.normalizeTableNames("SELECT USER_ID,IS_ACTIVE,DEFAULT_AUTH_ROLE,CREDENTIALS_PROFILE_ID FROM " +
"{table_prefix}CB_USER"
+ buildUsersFilter(filter) + "\nORDER BY USER_ID " + getOffsetLimitPart(filter)))) {
int parameterIndex = setUsersFilterValues(dbStat, filter, 1);

try (ResultSet dbResult = dbStat.executeQuery()) {
while (dbResult.next()) {
String userId = dbResult.getString(1);
String active = dbResult.getString(2);
String authRole = dbResult.getString(3);
result.put(userId, new SMUser(userId, CHAR_BOOL_TRUE.equals(active), authRole));
String credentialsProfileId = dbResult.getString(4);
result.put(userId,
new SMUser(userId, CHAR_BOOL_TRUE.equals(active), authRole, credentialsProfileId));
}
}
}
Expand Down Expand Up @@ -971,7 +977,10 @@ private SMTeam fetchTeam(ResultSet dbResult) throws SQLException {
}

@Override
public void createTeam(String teamId, String name, String description, String grantor) throws DBCException {
public void createTeam(
@NotNull String teamId, @Nullable String name, @Nullable String description,
@NotNull String grantor
) throws DBCException {
if (CommonUtils.isEmpty(teamId)) {
throw new DBCException("Empty team name is not allowed");
}
Expand Down Expand Up @@ -1000,7 +1009,7 @@ public void createTeam(String teamId, String name, String description, String gr
txn.commit();
}
} catch (SQLException e) {
throw new DBCException("Error saving tem in database", e);
throw new DBCException("Error saving team in database", e);
}
}

Expand Down Expand Up @@ -1078,6 +1087,104 @@ public void deleteTeam(String teamId, boolean force) throws DBCException {
}
}

@Override
@NotNull
public SMCredentialsProfile[] readAllCredentialsProfiles() throws DBCException {
List<SMCredentialsProfile> profiles = new ArrayList<>();
try (var dbCon = database.openConnection();
var dbStat = dbCon.prepareStatement(database.normalizeTableNames(
"SELECT PROFILE_ID, PROFILE_NAME, PROFILE_DESCRIPTION, PARENT_PROFILE_ID FROM " +
"{table_prefix}CB_CREDENTIALS_PROFILE ORDER BY PROFILE_ID"
));
var dbResult = dbStat.executeQuery();
) {
while (dbResult.next()) {
String profileId = dbResult.getString(1);
String name = dbResult.getString(2);
String description = dbResult.getString(3);
String parentProfile = dbResult.getString(4);
profiles.add(new SMCredentialsProfile(profileId, name, description, parentProfile));
}
return profiles.toArray(SMCredentialsProfile[]::new);
} catch (SQLException e) {
throw new DBCException("Error reading credentials profiles from database", e);
}
}

@Override
public void createCredentialsProfile(@NotNull SMCredentialsProfile credentialsProfile) throws DBCException {
if (isSubjectExists(credentialsProfile.getCredentialsProfileId())) {
throw new DBCException("User, team or credentials profile '" + credentialsProfile.getCredentialsProfileId() + "' already " +
"exists");
}

try (var dbCon = database.openConnection();
var txn = new JDBCTransaction(dbCon)) {
createAuthSubject(dbCon, credentialsProfile.getCredentialsProfileId(), SUBJECT_TEAM);
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("INSERT INTO {table_prefix}CB_CREDENTIALS_PROFILE" +
"(PROFILE_ID,PROFILE_NAME,PROFILE_DESCRIPTION,PARENT_PROFILE_ID) VALUES(?,?,?,?)"))) {
dbStat.setString(1, credentialsProfile.getCredentialsProfileId());
dbStat.setString(2, CommonUtils.notEmpty(credentialsProfile.getName()));
dbStat.setString(3, CommonUtils.notEmpty(credentialsProfile.getProfileDescription()));
if (CommonUtils.isNotEmpty(credentialsProfile.getParentProfileId())) {
dbStat.setString(4, credentialsProfile.getParentProfileId());
} else {
dbStat.setNull(4, Types.VARCHAR);
}
dbStat.execute();
}
txn.commit();
} catch (SQLException e) {
throw new DBCException("Error saving credentials profile in database", e);
}
}

@Override
public void deleteCredentialsProfile(@NotNull String credentialsProfileId) throws DBCException {
String defaultUserCredentialsProfile = application.getAppConfiguration().getDefaultUserCredentialsProfile();
if (CommonUtils.isNotEmpty(defaultUserCredentialsProfile)
&& defaultUserCredentialsProfile.equals(credentialsProfileId)) {
throw new DBCException("Default credentials profile cannot be deleted");
}

try (var dbCon = database.openConnection();
var txn = new JDBCTransaction(dbCon)) {
deleteAuthSubject(dbCon, credentialsProfileId);
JDBCUtils.executeStatement(
dbCon,
database.normalizeTableNames("DELETE FROM {table_prefix}CB_CREDENTIALS_PROFILE WHERE PROFILE_ID=?"),
credentialsProfileId
);
txn.commit();
} catch (SQLException e) {
throw new DBCException("Error deleting credentials profile from database", e);
}
}

@Override
public void setUserCredentialsProfile(@NotNull String userId, @Nullable String credentialsProfileId)
throws DBCException {
try (var dbCon = database.openConnection();
PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames(
"UPDATE {table_prefix}CB_USER SET CREDENTIALS_PROFILE_ID=? WHERE USER_ID=?"))
) {
if (CommonUtils.isEmpty(credentialsProfileId)) {
String defaultCredentialsProfile = application.getAppConfiguration().getDefaultUserCredentialsProfile();
if (defaultCredentialsProfile == null) {
dbStat.setNull(1, Types.VARCHAR);
} else {
dbStat.setString(1, defaultCredentialsProfile);
}
} else {
dbStat.setString(1, credentialsProfileId);
}
} catch (SQLException e) {
throw new DBCException("Error saving credentials profile for user", e);
}
}

///////////////////////////////////////////
// Subject functions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ private SMUser createAdminUser(
SMUser adminUser = adminSecurityController.getUserById(adminName);

if (adminUser == null) {
adminUser = new SMUser(adminName, true, "ADMINISTRATOR");
adminUser = new SMUser(adminName, true, "ADMINISTRATOR", null);
adminSecurityController.createUser(adminUser.getUserId(), adminUser.getMetaParameters(), true, adminUser.getAuthRole());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package io.cloudbeaver.service.security.db;

import org.jkiss.dbeaver.model.security.user.SMCredentialsProfile;
import org.jkiss.dbeaver.model.security.user.SMTeam;

import java.util.List;
Expand All @@ -24,6 +25,7 @@ class CBDatabaseInitialData {
private String adminName;
private String adminPassword;
private List<SMTeam> teams;
private List<SMCredentialsProfile> credentialsProfiles;

public String getAdminName() {
return adminName;
Expand All @@ -37,6 +39,10 @@ public List<SMTeam> getTeams() {
return teams;
}

public List<SMCredentialsProfile> getCredentialsProfiles() {
return credentialsProfiles;
}

public void setTeams(List<SMTeam> teams) {
this.teams = teams;
}
Expand Down

0 comments on commit 91f5b10

Please sign in to comment.