mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
Merge remote-tracking branch 'origin/devel' into CB-2194-support-events-pulling
This commit is contained in:
@@ -22,6 +22,12 @@ You can see live demo of CloudBeaver here: https://demo.cloudbeaver.io
|
||||
|
||||
## Changelog
|
||||
|
||||
### CloudBeaver 22.2.2 - 2022-10-10
|
||||
- Administrators now:
|
||||
- have permission to create connections in both projects, Shared and Private, when it’s restricted for other users,
|
||||
- can enable a reverse proxy for user authentication in the Administration.
|
||||
- Different bugs have been fixed.
|
||||
|
||||
### CloudBeaver 22.2.1 - 2022-09-26
|
||||
|
||||
- Connection:
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
roles: [
|
||||
teams: [
|
||||
{
|
||||
roleId: "admin",
|
||||
teamId: "admin",
|
||||
name: "Admin",
|
||||
description: "Administrative access. Has all permissions.",
|
||||
permissions: [ "public", "admin" ]
|
||||
},
|
||||
{
|
||||
roleId: "user",
|
||||
teamId: "user",
|
||||
name: "User",
|
||||
description: "Standard user",
|
||||
permissions: [ "public" ]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM eclipse-temurin:11.0.14.1_1-jre-focal
|
||||
FROM eclipse-temurin:17.0.4.1_1-jre
|
||||
#adoptopenjdk/openjdk11:jdk-11.0.12_7-ubuntu-slim
|
||||
|
||||
COPY cloudbeaver /opt/cloudbeaver
|
||||
|
||||
+6
-6
@@ -26,30 +26,30 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class BaseWebAppConfiguration implements WebAppConfiguration {
|
||||
public static final String DEFAULT_APP_ANONYMOUS_ROLE_NAME = "user";
|
||||
public static final String DEFAULT_APP_ANONYMOUS_TEAM_NAME = "user";
|
||||
|
||||
protected final Map<String, Object> plugins;
|
||||
protected String defaultUserRole;
|
||||
protected String defaultUserTeam;
|
||||
protected boolean resourceManagerEnabled;
|
||||
protected String[] enabledFeatures;
|
||||
|
||||
public BaseWebAppConfiguration() {
|
||||
this.plugins = new LinkedHashMap<>();
|
||||
this.defaultUserRole = DEFAULT_APP_ANONYMOUS_ROLE_NAME;
|
||||
this.defaultUserTeam = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
this.resourceManagerEnabled = true;
|
||||
this.enabledFeatures = null;
|
||||
}
|
||||
|
||||
public BaseWebAppConfiguration(BaseWebAppConfiguration src) {
|
||||
this.plugins = new LinkedHashMap<>(src.plugins);
|
||||
this.defaultUserRole = src.defaultUserRole;
|
||||
this.defaultUserTeam = src.defaultUserTeam;
|
||||
this.resourceManagerEnabled = src.resourceManagerEnabled;
|
||||
this.enabledFeatures = src.enabledFeatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDefaultUserRole() {
|
||||
return defaultUserRole;
|
||||
public String getDefaultUserTeam() {
|
||||
return defaultUserTeam;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -24,13 +24,13 @@ import java.util.Map;
|
||||
* Application configuration
|
||||
*/
|
||||
public interface WebAppConfiguration {
|
||||
String getAnonymousUserRole();
|
||||
String getAnonymousUserTeam();
|
||||
|
||||
boolean isAnonymousAccessEnabled();
|
||||
|
||||
<T> T getResourceQuota(String quotaId);
|
||||
|
||||
String getDefaultUserRole();
|
||||
String getDefaultUserTeam();
|
||||
|
||||
<T> T getPluginOption(@NotNull String pluginId, @NotNull String option);
|
||||
|
||||
|
||||
+2
@@ -167,6 +167,7 @@ public class LocalResourceController implements RMController {
|
||||
RMProjectType.SHARED, true)
|
||||
)
|
||||
.filter(Objects::nonNull)
|
||||
.sorted(Comparator.comparing(RMProject::getDisplayName))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -364,6 +365,7 @@ public class LocalResourceController implements RMController {
|
||||
) throws IOException {
|
||||
try (Stream<Path> files = Files.list(folderPath)) {
|
||||
return files.filter(path -> !path.getFileName().toString().startsWith(".")) // skip hidden files
|
||||
.sorted(Comparator.comparing(path -> path.getFileName().toString(), String.CASE_INSENSITIVE_ORDER))
|
||||
.map((Path path) -> makeResourceFromPath(projectId, path, readProperties, readHistory, recursive))
|
||||
.filter(Objects::nonNull)
|
||||
.toArray(RMResource[]::new);
|
||||
|
||||
+1
-1
@@ -410,7 +410,7 @@ public class WebSession extends AbstractSessionPersistent
|
||||
private Set<String> readAccessibleConnectionIds() {
|
||||
WebUser user = getUser();
|
||||
String subjectId = user == null ?
|
||||
application.getAppConfiguration().getAnonymousUserRole() : user.getUserId();
|
||||
application.getAppConfiguration().getAnonymousUserTeam() : user.getUserId();
|
||||
|
||||
try {
|
||||
return getSecurityController()
|
||||
|
||||
+1
-1
@@ -161,7 +161,7 @@ public class WebSessionAuthProcessor {
|
||||
providerConfig,
|
||||
userCredentials);
|
||||
|
||||
if (!configMode && securityController.getUserPermissions(userId).isEmpty()) {
|
||||
if (!configMode && securityController.getUserPermissions(userId, authInfo.getAuthRole()).isEmpty()) {
|
||||
throw new DBWebException("Access denied (no permissions)");
|
||||
}
|
||||
if (!configMode && !securityController.getUserById(userId).isEnabled()) {
|
||||
|
||||
@@ -17,38 +17,26 @@
|
||||
package io.cloudbeaver.model.user;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMUser;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Web user.
|
||||
*/
|
||||
public class WebUser {
|
||||
@NotNull
|
||||
private final String userId;
|
||||
private final SMUser user;
|
||||
private String displayName;
|
||||
|
||||
private final Map<String, String> metaParameters = new LinkedHashMap<>();
|
||||
private final Map<String, Object> configurationParameters = new LinkedHashMap<>();
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
private SMRole[] roles = null;
|
||||
|
||||
private String activeAuthModel;
|
||||
private final Map<String, Map<String, Object>> authCredentials = new HashMap<>();
|
||||
|
||||
public WebUser(@NotNull SMUser smUser) {
|
||||
this.userId = smUser.getUserId();
|
||||
this.metaParameters.putAll(smUser.getMetaParameters());
|
||||
this.enabled = smUser.isEnabled();
|
||||
this.user = smUser;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
return user.getUserId();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,61 +51,41 @@ public class WebUser {
|
||||
}
|
||||
|
||||
public boolean getEnabled() {
|
||||
return enabled;
|
||||
return user.isEnabled();
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String[] getGrantedRoles() {
|
||||
return Arrays.stream(roles).map(SMRole::getRoleId).toArray(String[]::new);
|
||||
}
|
||||
|
||||
public boolean hasRole(String roleId) {
|
||||
return Arrays.stream(roles).anyMatch(r -> r.getRoleId().equals(roleId));
|
||||
user.enableUser(enabled);
|
||||
}
|
||||
|
||||
public Map<String, String> getMetaParameters() {
|
||||
return Collections.unmodifiableMap(metaParameters);
|
||||
}
|
||||
|
||||
public String getMetaParameter(String name) {
|
||||
return metaParameters.get(name);
|
||||
return Collections.unmodifiableMap(user.getMetaParameters());
|
||||
}
|
||||
|
||||
public void setMetaParameter(String name, String value) {
|
||||
metaParameters.put(name, value);
|
||||
}
|
||||
|
||||
public void removeMetaParameter(String name) {
|
||||
metaParameters.remove(name);
|
||||
user.setMetaParameter(name, value);
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfigurationParameters() {
|
||||
return Collections.unmodifiableMap(configurationParameters);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public SMRole[] getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(SMRole[] roles) {
|
||||
this.roles = roles;
|
||||
public String[] getTeams() {
|
||||
return user.getUserTeams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return userId.hashCode();
|
||||
return user.getUserId().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof WebUser && ((WebUser) obj).userId.equals(this.userId);
|
||||
return obj instanceof WebUser && ((WebUser) obj).user.getUserId().equals(this.user.getUserId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return userId;
|
||||
return user.getUserId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,9 @@ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthC
|
||||
|
||||
private boolean redirectOnFederatedAuth;
|
||||
private boolean anonymousAccessEnabled;
|
||||
@Deprecated
|
||||
private String anonymousUserRole;
|
||||
private String anonymousUserTeam;
|
||||
|
||||
private String[] enabledDrivers;
|
||||
private String[] disabledDrivers;
|
||||
@@ -61,7 +63,8 @@ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthC
|
||||
public CBAppConfig() {
|
||||
super();
|
||||
this.anonymousAccessEnabled = false;
|
||||
this.anonymousUserRole = DEFAULT_APP_ANONYMOUS_ROLE_NAME;
|
||||
this.anonymousUserRole = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
this.anonymousUserTeam = DEFAULT_APP_ANONYMOUS_TEAM_NAME;
|
||||
this.supportsCustomConnections = true;
|
||||
this.supportsConnectionBrowser = false;
|
||||
this.supportsUserWorkspaces = false;
|
||||
@@ -81,6 +84,7 @@ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthC
|
||||
super(src);
|
||||
this.anonymousAccessEnabled = src.anonymousAccessEnabled;
|
||||
this.anonymousUserRole = src.anonymousUserRole;
|
||||
this.anonymousUserTeam = src.anonymousUserTeam;
|
||||
this.supportsCustomConnections = src.supportsCustomConnections;
|
||||
this.supportsConnectionBrowser = src.supportsConnectionBrowser;
|
||||
this.supportsUserWorkspaces = src.supportsUserWorkspaces;
|
||||
@@ -102,8 +106,8 @@ public class CBAppConfig extends BaseAuthWebAppConfiguration implements WebAuthC
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnonymousUserRole() {
|
||||
return anonymousUserRole;
|
||||
public String getAnonymousUserTeam() {
|
||||
return CommonUtils.notNull(anonymousUserTeam, anonymousUserRole);
|
||||
}
|
||||
|
||||
public void setAnonymousAccessEnabled(boolean anonymousAccessEnabled) {
|
||||
|
||||
@@ -820,15 +820,15 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat
|
||||
|
||||
private void grantAnonymousAccessToConnections(CBAppConfig appConfig, String adminName) {
|
||||
try {
|
||||
String anonymousRoleId = appConfig.getAnonymousUserRole();
|
||||
String anonymousTeamId = appConfig.getAnonymousUserTeam();
|
||||
var securityController = getSecurityController();
|
||||
for (DBPDataSourceContainer ds : WebServiceUtils.getGlobalDataSourceRegistry().getDataSources()) {
|
||||
var datasourcePermissions = securityController.getObjectPermissions(anonymousRoleId, ds.getId(), SMObjects.DATASOURCE);
|
||||
var datasourcePermissions = securityController.getObjectPermissions(anonymousTeamId, ds.getId(), SMObjects.DATASOURCE);
|
||||
if (CommonUtils.isEmpty(datasourcePermissions.getPermissions())) {
|
||||
securityController.setObjectPermissions(
|
||||
Set.of(ds.getId()),
|
||||
SMObjects.DATASOURCE,
|
||||
Set.of(anonymousRoleId),
|
||||
Set.of(anonymousTeamId),
|
||||
Set.of(SMConstants.DATA_SOURCE_ACCESS_PERMISSION),
|
||||
adminName
|
||||
);
|
||||
|
||||
@@ -58,7 +58,7 @@ public class CBConstants {
|
||||
public static final String DEFAULT_WORKSPACE_LOCATION = DEFAULT_DEPLOY_LOCATION + "/workspace";
|
||||
public static final String DEFAULT_PRODUCT_CONFIGURATION = "conf/product.conf";
|
||||
public static final String DEFAULT_ADMIN_NAME = "cbadmin";
|
||||
public static final String DEFAULT_ADMIN_ROLE = "admin";
|
||||
public static final String DEFAULT_ADMIN_TEAM = "admin";
|
||||
|
||||
// Default max idle time (10 minutes)
|
||||
public static final long MAX_SESSION_IDLE_TIME = 10 * 60 * 1000;
|
||||
|
||||
+4
@@ -364,6 +364,10 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
webSession.addInfoMessage("Create new connection");
|
||||
DBPDataSourceRegistry sessionRegistry = webSession.getProjectById(projectId).getDataSourceRegistry();
|
||||
|
||||
// we don't need to save credentials for templates
|
||||
if (connectionConfig.isTemplate()) {
|
||||
connectionConfig.setSaveCredentials(false);
|
||||
}
|
||||
DBPDataSourceContainer newDataSource = WebServiceUtils.createConnectionFromConfig(connectionConfig, sessionRegistry);
|
||||
if (CommonUtils.isEmpty(newDataSource.getName())) {
|
||||
newDataSource.setName(CommonUtils.notNull(connectionConfig.getName(), "NewConnection"));
|
||||
|
||||
+2
-1
@@ -82,7 +82,8 @@ public class WebNavigatorNodeInfo {
|
||||
|
||||
@Property
|
||||
public String getProjectId() {
|
||||
return node.getOwnerProject().getId();
|
||||
DBPProject ownerProject = node.getOwnerProject();
|
||||
return ownerProject == null ? null : ownerProject.getId();
|
||||
}
|
||||
|
||||
@Property
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
enum AdminSubjectType {
|
||||
user,
|
||||
role
|
||||
team
|
||||
}
|
||||
|
||||
type AdminConnectionGrantInfo {
|
||||
@@ -35,7 +35,7 @@ type AdminUserInfo {
|
||||
|
||||
metaParameters: Object!
|
||||
configurationParameters: Object!
|
||||
grantedRoles: [ID!]!
|
||||
grantedTeams: [ID!]!
|
||||
grantedConnections: [AdminConnectionGrantInfo!]!
|
||||
|
||||
origins: [ObjectOrigin!]!
|
||||
@@ -44,15 +44,15 @@ type AdminUserInfo {
|
||||
enabled: Boolean!
|
||||
}
|
||||
|
||||
type AdminRoleInfo {
|
||||
roleId: ID!
|
||||
roleName: String
|
||||
type AdminTeamInfo {
|
||||
teamId: ID!
|
||||
teamName: String
|
||||
description: String
|
||||
|
||||
grantedUsers: [ID!]!
|
||||
grantedConnections: [AdminConnectionGrantInfo!]!
|
||||
|
||||
rolePermissions: [ID!]!
|
||||
teamPermissions: [ID!]!
|
||||
}
|
||||
|
||||
type AdminPermissionInfo {
|
||||
@@ -113,23 +113,23 @@ input ServerConfigInput {
|
||||
|
||||
extend type Query {
|
||||
|
||||
#### Users and roles
|
||||
#### Users and teams
|
||||
|
||||
listUsers(userId: ID): [AdminUserInfo!]!
|
||||
listRoles(roleId: ID): [AdminRoleInfo!]!
|
||||
listTeams(teamId: ID): [AdminTeamInfo!]!
|
||||
listPermissions: [AdminPermissionInfo!]!
|
||||
|
||||
createUser(userId: ID!, enabled: Boolean!): AdminUserInfo!
|
||||
deleteUser(userId: ID!): Boolean
|
||||
|
||||
createRole(roleId: ID!, roleName: String, description: String): AdminRoleInfo!
|
||||
updateRole(roleId: ID!, roleName: String, description: String): AdminRoleInfo!
|
||||
deleteRole(roleId: ID!): Boolean
|
||||
createTeam(teamId: ID!, teamName: String, description: String): AdminTeamInfo!
|
||||
updateTeam(teamId: ID!, teamName: String, description: String): AdminTeamInfo!
|
||||
deleteTeam(teamId: ID!): Boolean
|
||||
|
||||
grantUserRole(userId: ID!, roleId: ID!): Boolean
|
||||
revokeUserRole(userId: ID!, roleId: ID!): Boolean
|
||||
grantUserTeam(userId: ID!, teamId: ID!): Boolean
|
||||
revokeUserTeam(userId: ID!, teamId: ID!): Boolean
|
||||
|
||||
setSubjectPermissions(roleId: ID!, permissions: [ID!]!): [AdminPermissionInfo!]!
|
||||
setSubjectPermissions(subjectId: ID!, permissions: [ID!]!): [AdminPermissionInfo!]!
|
||||
|
||||
setUserCredentials(userId: ID!, providerId: ID!, credentials: Object!): Boolean
|
||||
|
||||
|
||||
+20
-20
@@ -21,54 +21,54 @@ import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.security.SMDataSourceGrant;
|
||||
import org.jkiss.dbeaver.model.security.SMObjects;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMTeam;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Web role info
|
||||
* Web team info
|
||||
*/
|
||||
public class AdminRoleInfo {
|
||||
public class AdminTeamInfo {
|
||||
|
||||
private final WebSession session;
|
||||
private final SMRole role;
|
||||
private List<String> rolePermissions;
|
||||
private final SMTeam team;
|
||||
private List<String> teamPermissions;
|
||||
|
||||
public AdminRoleInfo(WebSession session, SMRole role) {
|
||||
this.role = role;
|
||||
public AdminTeamInfo(WebSession session, SMTeam team) {
|
||||
this.team = team;
|
||||
this.session = session;
|
||||
this.rolePermissions = new ArrayList<>(role.getPermissions());
|
||||
this.teamPermissions = new ArrayList<>(team.getPermissions());
|
||||
}
|
||||
|
||||
public String getRoleId() {
|
||||
return role.getRoleId();
|
||||
public String getTeamId() {
|
||||
return team.getTeamId();
|
||||
}
|
||||
|
||||
public String getRoleName() {
|
||||
return role.getName();
|
||||
public String getTeamName() {
|
||||
return team.getName();
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return role.getDescription();
|
||||
return team.getDescription();
|
||||
}
|
||||
|
||||
public List<String> getRolePermissions() {
|
||||
return rolePermissions;
|
||||
public List<String> getTeamPermissions() {
|
||||
return teamPermissions;
|
||||
}
|
||||
|
||||
public void setRolePermissions(List<String> rolePermissions) {
|
||||
this.rolePermissions = rolePermissions;
|
||||
public void setTeamPermissions(List<String> teamPermissions) {
|
||||
this.teamPermissions = teamPermissions;
|
||||
}
|
||||
|
||||
@Property
|
||||
public SMDataSourceGrant[] getGrantedConnections() throws DBException {
|
||||
return session.getAdminSecurityController()
|
||||
.getSubjectObjectPermissionGrants(getRoleId(), SMObjects.DATASOURCE)
|
||||
.getSubjectObjectPermissionGrants(getTeamId(), SMObjects.DATASOURCE)
|
||||
.stream()
|
||||
.map(objectPermission -> new SMDataSourceGrant(
|
||||
objectPermission.getObjectPermissions().getObjectId(),
|
||||
getRoleId(),
|
||||
getTeamId(),
|
||||
objectPermission.getSubjectType()
|
||||
))
|
||||
.toArray(SMDataSourceGrant[]::new);
|
||||
@@ -76,7 +76,7 @@ public class AdminRoleInfo {
|
||||
|
||||
@Property
|
||||
public String[] getGrantedUsers() throws DBException {
|
||||
return session.getAdminSecurityController().getRoleSubjects(getRoleId());
|
||||
return session.getAdminSecurityController().getTeamMembers(getTeamId());
|
||||
}
|
||||
|
||||
}
|
||||
+2
-7
@@ -25,7 +25,6 @@ import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.dbeaver.model.security.SMDataSourceGrant;
|
||||
import org.jkiss.dbeaver.model.security.SMObjects;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry;
|
||||
|
||||
@@ -71,12 +70,8 @@ public class AdminUserInfo {
|
||||
}
|
||||
|
||||
@Property
|
||||
public String[] getGrantedRoles() throws DBException {
|
||||
if (user.getRoles() == null) {
|
||||
SMRole[] userRoles = session.getSecurityController().getUserRoles(getUserId());
|
||||
user.setRoles(userRoles);
|
||||
}
|
||||
return user.getGrantedRoles();
|
||||
public String[] getGrantedTeams() {
|
||||
return user.getTeams();
|
||||
}
|
||||
|
||||
@Property
|
||||
|
||||
+7
-7
@@ -45,7 +45,7 @@ public interface DBWServiceAdmin extends DBWService {
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
@NotNull
|
||||
List<AdminRoleInfo> listRoles(@NotNull WebSession webSession, @Nullable String roleName) throws DBWebException;
|
||||
List<AdminTeamInfo> listTeams(@NotNull WebSession webSession, @Nullable String teamName) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
@NotNull
|
||||
@@ -60,23 +60,23 @@ public interface DBWServiceAdmin extends DBWService {
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
@NotNull
|
||||
AdminRoleInfo createRole(@NotNull WebSession webSession, String roleId, String roleName, String description) throws DBWebException;
|
||||
AdminTeamInfo createTeam(@NotNull WebSession webSession, String teamId, String teamName, String description) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
@NotNull
|
||||
AdminRoleInfo updateRole(@NotNull WebSession webSession, String roleId, String roleName, String description) throws DBWebException;
|
||||
AdminTeamInfo updateTeam(@NotNull WebSession webSession, String teamId, String teamName, String description) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
boolean deleteRole(@NotNull WebSession webSession, String roleId) throws DBWebException;
|
||||
boolean deleteTeam(@NotNull WebSession webSession, String teamId) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
boolean grantUserRole(@NotNull WebSession webSession, String user, String role) throws DBWebException;
|
||||
boolean grantUserTeam(@NotNull WebSession webSession, String user, String team) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
boolean revokeUserRole(@NotNull WebSession webSession, String user, String role) throws DBWebException;
|
||||
boolean revokeUserTeam(@NotNull WebSession webSession, String user, String team) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
List<AdminPermissionInfo> setSubjectPermissions(@NotNull WebSession webSession, String roleID, List<String> permissions) throws DBWebException;
|
||||
List<AdminPermissionInfo> setSubjectPermissions(@NotNull WebSession webSession, String subjectID, List<String> permissions) throws DBWebException;
|
||||
|
||||
@WebAction(requirePermissions = DBWConstants.PERMISSION_ADMIN)
|
||||
boolean setUserCredentials(@NotNull WebSession webSession, @NotNull String userID, @NotNull String providerId, @NotNull Map<String, Object> credentials) throws DBWebException;
|
||||
|
||||
+17
-17
@@ -45,35 +45,35 @@ public class WebServiceBindingAdmin extends WebServiceBindingBase<DBWServiceAdmi
|
||||
model.getQueryType()
|
||||
.dataFetcher("listUsers",
|
||||
env -> getService(env).listUsers(getWebSession(env), env.getArgument("userId")))
|
||||
.dataFetcher("listRoles",
|
||||
env -> getService(env).listRoles(getWebSession(env), env.getArgument("roleId")))
|
||||
.dataFetcher("listTeams",
|
||||
env -> getService(env).listTeams(getWebSession(env), env.getArgument("teamId")))
|
||||
.dataFetcher("listPermissions",
|
||||
env -> getService(env).listPermissions(getWebSession(env)))
|
||||
.dataFetcher("createUser",
|
||||
env -> getService(env).createUser(getWebSession(env), env.getArgument("userId"), env.getArgument("enabled")))
|
||||
.dataFetcher("deleteUser",
|
||||
env -> getService(env).deleteUser(getWebSession(env), env.getArgument("userId")))
|
||||
.dataFetcher("createRole",
|
||||
env -> getService(env).createRole(
|
||||
.dataFetcher("createTeam",
|
||||
env -> getService(env).createTeam(
|
||||
getWebSession(env),
|
||||
env.getArgument("roleId"),
|
||||
env.getArgument("roleName"),
|
||||
env.getArgument("teamId"),
|
||||
env.getArgument("teamName"),
|
||||
env.getArgument("description")))
|
||||
.dataFetcher("updateRole",
|
||||
env -> getService(env).updateRole(
|
||||
.dataFetcher("updateTeam",
|
||||
env -> getService(env).updateTeam(
|
||||
getWebSession(env),
|
||||
env.getArgument("roleId"),
|
||||
env.getArgument("roleName"),
|
||||
env.getArgument("teamId"),
|
||||
env.getArgument("teamName"),
|
||||
env.getArgument("description")))
|
||||
.dataFetcher("deleteRole",
|
||||
env -> getService(env).deleteRole(getWebSession(env), env.getArgument("roleId")))
|
||||
.dataFetcher("deleteTeam",
|
||||
env -> getService(env).deleteTeam(getWebSession(env), env.getArgument("teamId")))
|
||||
|
||||
.dataFetcher("grantUserRole",
|
||||
env -> getService(env).grantUserRole(getWebSession(env), env.getArgument("userId"), env.getArgument("roleId")))
|
||||
.dataFetcher("revokeUserRole",
|
||||
env -> getService(env).revokeUserRole(getWebSession(env), env.getArgument("userId"), env.getArgument("roleId")))
|
||||
.dataFetcher("grantUserTeam",
|
||||
env -> getService(env).grantUserTeam(getWebSession(env), env.getArgument("userId"), env.getArgument("teamId")))
|
||||
.dataFetcher("revokeUserTeam",
|
||||
env -> getService(env).revokeUserTeam(getWebSession(env), env.getArgument("userId"), env.getArgument("teamId")))
|
||||
.dataFetcher("setSubjectPermissions",
|
||||
env -> getService(env).setSubjectPermissions(getWebSession(env), env.getArgument("roleId"), env.getArgument("permissions")))
|
||||
env -> getService(env).setSubjectPermissions(getWebSession(env), env.getArgument("subjectId"), env.getArgument("permissions")))
|
||||
.dataFetcher("setUserCredentials",
|
||||
env -> getService(env).setUserCredentials(getWebSession(env), env.getArgument("userId"), env.getArgument("providerId"), env.getArgument("credentials")))
|
||||
.dataFetcher("enableUser",
|
||||
|
||||
+60
-60
@@ -53,7 +53,7 @@ import org.jkiss.dbeaver.model.security.SMAuthProviderCustomConfiguration;
|
||||
import org.jkiss.dbeaver.model.security.SMConstants;
|
||||
import org.jkiss.dbeaver.model.security.SMDataSourceGrant;
|
||||
import org.jkiss.dbeaver.model.security.SMObjects;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMTeam;
|
||||
import org.jkiss.dbeaver.model.security.user.SMUser;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
|
||||
@@ -95,22 +95,22 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AdminRoleInfo> listRoles(@NotNull WebSession webSession, String roleId) throws DBWebException {
|
||||
public List<AdminTeamInfo> listTeams(@NotNull WebSession webSession, String teamName) throws DBWebException {
|
||||
try {
|
||||
List<AdminRoleInfo> roles = new ArrayList<>();
|
||||
if (CommonUtils.isEmpty(roleId)) {
|
||||
for (SMRole role : webSession.getAdminSecurityController().readAllRoles()) {
|
||||
roles.add(new AdminRoleInfo(webSession, role));
|
||||
List<AdminTeamInfo> teams = new ArrayList<>();
|
||||
if (CommonUtils.isEmpty(teamName)) {
|
||||
for (SMTeam team : webSession.getAdminSecurityController().readAllTeams()) {
|
||||
teams.add(new AdminTeamInfo(webSession, team));
|
||||
}
|
||||
} else {
|
||||
SMRole role = webSession.getAdminSecurityController().findRole(roleId);
|
||||
if (role != null) {
|
||||
roles.add(new AdminRoleInfo(webSession, role));
|
||||
SMTeam team = webSession.getAdminSecurityController().findTeam(teamName);
|
||||
if (team != null) {
|
||||
teams.add(new AdminTeamInfo(webSession, team));
|
||||
}
|
||||
}
|
||||
return roles;
|
||||
return teams;
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error reading roles", e);
|
||||
throw new DBWebException("Error reading teams", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,126 +158,126 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AdminRoleInfo createRole(@NotNull WebSession webSession, String roleId, String roleName, String description) throws DBWebException {
|
||||
if (roleId.isEmpty()) {
|
||||
throw new DBWebException("Empty role ID");
|
||||
public AdminTeamInfo createTeam(@NotNull WebSession webSession, String teamId, String teamName, String description) throws DBWebException {
|
||||
if (teamId.isEmpty()) {
|
||||
throw new DBWebException("Empty team ID");
|
||||
}
|
||||
webSession.addInfoMessage("Create new role - " + roleId);
|
||||
webSession.addInfoMessage("Create new team - " + teamId);
|
||||
try {
|
||||
webSession.getAdminSecurityController().createRole(roleId, roleName, description, webSession.getUser().getUserId());
|
||||
SMRole newRole = webSession.getAdminSecurityController().findRole(roleId);
|
||||
return new AdminRoleInfo(webSession, newRole);
|
||||
webSession.getAdminSecurityController().createTeam(teamId, teamName, description, webSession.getUser().getUserId());
|
||||
SMTeam newTeam = webSession.getAdminSecurityController().findTeam(teamId);
|
||||
return new AdminTeamInfo(webSession, newTeam);
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error creating new role", e);
|
||||
throw new DBWebException("Error creating new team", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public AdminRoleInfo updateRole(@NotNull WebSession webSession, String roleId, String roleName, String description) throws DBWebException {
|
||||
if (roleId.isEmpty()) {
|
||||
throw new DBWebException("Empty role ID");
|
||||
public AdminTeamInfo updateTeam(@NotNull WebSession webSession, String teamId, String teamName, String description) throws DBWebException {
|
||||
if (teamId.isEmpty()) {
|
||||
throw new DBWebException("Empty team ID");
|
||||
}
|
||||
|
||||
webSession.addInfoMessage("Update role - " + roleId);
|
||||
webSession.addInfoMessage("Update team - " + teamId);
|
||||
|
||||
try {
|
||||
webSession.getAdminSecurityController().updateRole(roleId, roleName, description);
|
||||
SMRole newRole = webSession.getAdminSecurityController().findRole(roleId);
|
||||
return new AdminRoleInfo(webSession, newRole);
|
||||
webSession.getAdminSecurityController().updateTeam(teamId, teamName, description);
|
||||
SMTeam newTeam = webSession.getAdminSecurityController().findTeam(teamId);
|
||||
return new AdminTeamInfo(webSession, newTeam);
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error updating role " + roleId, e);
|
||||
throw new DBWebException("Error updating team " + teamId, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteRole(@NotNull WebSession webSession, String roleId) throws DBWebException {
|
||||
public boolean deleteTeam(@NotNull WebSession webSession, String teamId) throws DBWebException {
|
||||
try {
|
||||
webSession.addInfoMessage("Delete role - " + roleId);
|
||||
webSession.addInfoMessage("Delete team - " + teamId);
|
||||
|
||||
var adminSecurityController = webSession.getAdminSecurityController();
|
||||
SMRole[] userRoles = adminSecurityController.getUserRoles(webSession.getUser().getUserId());
|
||||
if (Arrays.stream(userRoles).anyMatch(DBRole -> DBRole.getRoleId().equals(roleId))) {
|
||||
throw new DBWebException("You can not delete your own role");
|
||||
SMTeam[] userTeams = adminSecurityController.getUserTeams(webSession.getUser().getUserId());
|
||||
if (Arrays.stream(userTeams).anyMatch(team -> team.getTeamId().equals(teamId))) {
|
||||
throw new DBWebException("You can not delete your own team");
|
||||
}
|
||||
adminSecurityController.deleteRole(roleId);
|
||||
adminSecurityController.deleteTeam(teamId);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error deleting role", e);
|
||||
throw new DBWebException("Error deleting team", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean grantUserRole(@NotNull WebSession webSession, String user, String role) throws DBWebException {
|
||||
public boolean grantUserTeam(@NotNull WebSession webSession, String user, String team) throws DBWebException {
|
||||
WebUser grantor = webSession.getUser();
|
||||
if (grantor == null) {
|
||||
throw new DBWebException("Cannot grant role in anonymous mode");
|
||||
throw new DBWebException("Cannot grant team in anonymous mode");
|
||||
}
|
||||
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
|
||||
throw new DBWebException("You cannot edit your own permissions");
|
||||
}
|
||||
try {
|
||||
var adminSecurityController = webSession.getAdminSecurityController();
|
||||
SMRole[] userRoles = adminSecurityController.getUserRoles(user);
|
||||
List<String> roleIds = Arrays.stream(userRoles).map(SMRole::getRoleId).collect(Collectors.toList());
|
||||
if (!roleIds.contains(role)) {
|
||||
roleIds.add(role);
|
||||
adminSecurityController.setUserRoles(user, roleIds.toArray(new String[0]), grantor.getUserId());
|
||||
SMTeam[] userTeams = adminSecurityController.getUserTeams(user);
|
||||
List<String> teamIds = Arrays.stream(userTeams).map(SMTeam::getTeamId).collect(Collectors.toList());
|
||||
if (!teamIds.contains(team)) {
|
||||
teamIds.add(team);
|
||||
adminSecurityController.setUserTeams(user, teamIds.toArray(new String[0]), grantor.getUserId());
|
||||
} else {
|
||||
throw new DBWebException("User '" + user + "' already has role '" + role + "'");
|
||||
throw new DBWebException("User '" + user + "' already has team '" + team + "'");
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error granting role", e);
|
||||
throw new DBWebException("Error granting team", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean revokeUserRole(@NotNull WebSession webSession, String user, String role) throws DBWebException {
|
||||
public boolean revokeUserTeam(@NotNull WebSession webSession, String user, String team) throws DBWebException {
|
||||
WebUser grantor = webSession.getUser();
|
||||
if (grantor == null) {
|
||||
throw new DBWebException("Cannot grant role in anonymous mode");
|
||||
throw new DBWebException("Cannot revoke team in anonymous mode");
|
||||
}
|
||||
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
|
||||
throw new DBWebException("You cannot edit your own permissions");
|
||||
}
|
||||
try {
|
||||
var adminSecurityController = webSession.getAdminSecurityController();
|
||||
SMRole[] userRoles = adminSecurityController.getUserRoles(user);
|
||||
List<String> roleIds = Arrays.stream(userRoles).map(SMRole::getRoleId).collect(Collectors.toList());
|
||||
if (roleIds.contains(role)) {
|
||||
roleIds.remove(role);
|
||||
adminSecurityController.setUserRoles(user, roleIds.toArray(new String[0]), grantor.getUserId());
|
||||
SMTeam[] userTeams = adminSecurityController.getUserTeams(user);
|
||||
List<String> teamIds = Arrays.stream(userTeams).map(SMTeam::getTeamId).collect(Collectors.toList());
|
||||
if (teamIds.contains(team)) {
|
||||
teamIds.remove(team);
|
||||
adminSecurityController.setUserTeams(user, teamIds.toArray(new String[0]), grantor.getUserId());
|
||||
} else {
|
||||
throw new DBWebException("User '" + user + "' doesn't have role '" + role + "'");
|
||||
throw new DBWebException("User '" + user + "' doesn't have team '" + team + "'");
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error revoking role", e);
|
||||
throw new DBWebException("Error revoking team", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdminPermissionInfo> setSubjectPermissions(@NotNull WebSession webSession, String roleID, List<String> permissions) throws DBWebException {
|
||||
public List<AdminPermissionInfo> setSubjectPermissions(@NotNull WebSession webSession, String subjectID, List<String> permissions) throws DBWebException {
|
||||
validatePermissions(SMConstants.SUBJECT_PERMISSION_SCOPE, permissions);
|
||||
WebUser grantor = webSession.getUser();
|
||||
if (grantor == null) {
|
||||
throw new DBWebException("Cannot change permissions in anonymous mode");
|
||||
}
|
||||
if (CommonUtils.equalObjects(roleID, CBConstants.DEFAULT_ADMIN_ROLE)) {
|
||||
throw new DBWebException("Cannot change permissions for role '" + roleID + "'");
|
||||
if (CommonUtils.equalObjects(subjectID, CBConstants.DEFAULT_ADMIN_TEAM)) {
|
||||
throw new DBWebException("Cannot change permissions for team '" + subjectID + "'");
|
||||
}
|
||||
webSession.addInfoMessage("Set permissions to subject - " + roleID);
|
||||
webSession.addInfoMessage("Set permissions to subject - " + subjectID);
|
||||
|
||||
try {
|
||||
webSession.getAdminSecurityController().setSubjectPermissions(roleID, permissions, grantor.getUserId());
|
||||
Set<String> subjectPermissions = webSession.getAdminSecurityController().getSubjectPermissions(roleID);
|
||||
webSession.getAdminSecurityController().setSubjectPermissions(subjectID, permissions, grantor.getUserId());
|
||||
Set<String> subjectPermissions = webSession.getAdminSecurityController().getSubjectPermissions(subjectID);
|
||||
webSession.refreshUserData();
|
||||
return listPermissions(webSession).stream()
|
||||
.filter(p -> subjectPermissions.contains(p.getId()))
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error setting role permissions", e);
|
||||
throw new DBWebException("Error setting subject permissions", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,7 +690,7 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
}
|
||||
WebUser grantor = webSession.getUser();
|
||||
if (grantor == null) {
|
||||
throw new DBWebException("Cannot grant role in anonymous mode");
|
||||
throw new DBWebException("Cannot grant connection access in anonymous mode");
|
||||
}
|
||||
try {
|
||||
var adminSM = webSession.getAdminSecurityController();
|
||||
|
||||
+3
-3
@@ -67,14 +67,14 @@ public class RPSessionHandler implements DBWSessionHandler {
|
||||
}
|
||||
SMAuthProviderExternal<?> authProviderExternal = (SMAuthProviderExternal<?>) authProvider.getInstance();
|
||||
String userName = request.getHeader(RPAuthProvider.X_USER);
|
||||
String roles = request.getHeader(RPAuthProvider.X_ROLE);
|
||||
List<String> userRoles = roles == null ? Collections.emptyList() : List.of(roles.split("\\|"));
|
||||
String teams = request.getHeader(RPAuthProvider.X_ROLE);
|
||||
List<String> userTeams = teams == null ? Collections.emptyList() : List.of(teams.split("\\|"));
|
||||
if (userName != null) {
|
||||
try {
|
||||
Map<String, Object> credentials = new HashMap<>();
|
||||
credentials.put("user", userName);
|
||||
Map<String, Object> sessionParameters = webSession.getSessionParameters();
|
||||
sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES, userRoles);
|
||||
sessionParameters.put(SMConstants.SESSION_PARAM_TRUSTED_USER_TEAMS, userTeams);
|
||||
Map<String, Object> userCredentials = authProviderExternal.authExternalUser(
|
||||
webSession.getProgressMonitor(), sessionParameters, credentials);
|
||||
String currentSmSessionId = webSession.getUser() == null ? null : webSession.getUserContext().getSmSessionId();
|
||||
|
||||
@@ -99,6 +99,7 @@ CREATE TABLE CB_USER
|
||||
|
||||
IS_ACTIVE CHAR(1) NOT NULL,
|
||||
CREATE_TIME TIMESTAMP NOT NULL,
|
||||
DEFAULT_AUTH_ROLE VARCHAR(32) NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_AUTH_SUBJECT (SUBJECT_ID) ON DELETE CASCADE
|
||||
@@ -125,29 +126,39 @@ CREATE TABLE CB_USER_PARAMETERS
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE CB_ROLE
|
||||
CREATE TABLE CB_TEAM
|
||||
(
|
||||
ROLE_ID VARCHAR(128) NOT NULL,
|
||||
ROLE_NAME VARCHAR(100) NOT NULL,
|
||||
ROLE_DESCRIPTION VARCHAR(255) NOT NULL,
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
TEAM_NAME VARCHAR(100) NOT NULL,
|
||||
TEAM_DESCRIPTION VARCHAR(255) NOT NULL,
|
||||
|
||||
CREATE_TIME TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (ROLE_ID),
|
||||
FOREIGN KEY (ROLE_ID) REFERENCES CB_AUTH_SUBJECT (SUBJECT_ID) ON DELETE CASCADE
|
||||
PRIMARY KEY (TEAM_ID),
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_AUTH_SUBJECT (SUBJECT_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE CB_USER_ROLE
|
||||
CREATE TABLE CB_EXTERNAL_TEAM
|
||||
(
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
EXTERNAL_TEAM_ID VARCHAR(128) NOT NULL,
|
||||
|
||||
PRIMARY KEY (TEAM_ID,EXTERNAL_TEAM_ID),
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_TEAM (TEAM_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE CB_USER_TEAM
|
||||
(
|
||||
USER_ID VARCHAR(128) NOT NULL,
|
||||
ROLE_ID VARCHAR(128) NOT NULL,
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
|
||||
GRANT_TIME TIMESTAMP NOT NULL,
|
||||
GRANTED_BY VARCHAR(128) NOT NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID, ROLE_ID),
|
||||
PRIMARY KEY (USER_ID, TEAM_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE,
|
||||
FOREIGN KEY (ROLE_ID) REFERENCES CB_ROLE (ROLE_ID) ON DELETE CASCADE
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_TEAM (TEAM_ID) ON DELETE NO ACTION
|
||||
);
|
||||
|
||||
CREATE TABLE CB_AUTH_PROVIDER
|
||||
@@ -175,7 +186,7 @@ CREATE TABLE CB_USER_CREDENTIALS
|
||||
CRED_ID VARCHAR(32) NOT NULL,
|
||||
CRED_VALUE VARCHAR(1024) NOT NULL,
|
||||
|
||||
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UPDATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID, PROVIDER_ID, CRED_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE
|
||||
@@ -189,7 +200,7 @@ CREATE TABLE CB_USER_STATE
|
||||
|
||||
USER_CONFIGURATION TEXT NULL,
|
||||
|
||||
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UPDATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE
|
||||
@@ -242,14 +253,15 @@ CREATE TABLE CB_AUTH_TOKEN
|
||||
REFRESH_TOKEN_ID VARCHAR(128),
|
||||
SESSION_ID VARCHAR(64) NOT NULL,
|
||||
USER_ID VARCHAR(128),
|
||||
AUTH_ROLE VARCHAR(32),
|
||||
|
||||
EXPIRATION_TIME TIMESTAMP NOT NULL,
|
||||
REFRESH_TOKEN_EXPIRATION_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
REFRESH_TOKEN_EXPIRATION_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (TOKEN_ID),
|
||||
FOREIGN KEY (SESSION_ID) REFERENCES CB_SESSION (SESSION_ID) ON DELETE CASCADE,
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE NO ACTION
|
||||
);
|
||||
|
||||
CREATE TABLE CB_AUTH_ATTEMPT
|
||||
@@ -262,7 +274,7 @@ CREATE TABLE CB_AUTH_ATTEMPT
|
||||
SESSION_TYPE VARCHAR(64) NOT NULL,
|
||||
APP_SESSION_STATE TEXT NOT NULL,
|
||||
|
||||
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (AUTH_ID),
|
||||
FOREIGN KEY (SESSION_ID) REFERENCES CB_SESSION (SESSION_ID) ON DELETE CASCADE
|
||||
@@ -275,7 +287,7 @@ CREATE TABLE CB_AUTH_ATTEMPT_INFO
|
||||
AUTH_PROVIDER_CONFIGURATION_ID VARCHAR(128),
|
||||
AUTH_STATE TEXT NOT NULL,
|
||||
|
||||
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CREATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (AUTH_ID, AUTH_PROVIDER_ID),
|
||||
FOREIGN KEY (AUTH_ID) REFERENCES CB_AUTH_ATTEMPT (AUTH_ID) ON DELETE CASCADE
|
||||
@@ -287,18 +299,15 @@ CREATE INDEX CB_SESSION_LOG_INDEX ON CB_SESSION_LOG (SESSION_ID, LOG_TIME);
|
||||
|
||||
CREATE TABLE CB_USER_SECRETS
|
||||
(
|
||||
USER_ID VARCHAR(128) NOT NULL,
|
||||
SECRET_ID VARCHAR(512) NOT NULL,
|
||||
SECRET_VALUE VARCHAR(65000) NOT NULL,
|
||||
USER_ID VARCHAR(128) NOT NULL,
|
||||
SECRET_ID VARCHAR(512) NOT NULL,
|
||||
SECRET_VALUE TEXT NOT NULL,
|
||||
|
||||
SECRET_LABEL VARCHAR(128),
|
||||
SECRET_DESCRIPTION VARCHAR(1024),
|
||||
|
||||
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UPDATE_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID, SECRET_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX CB_USER_SECRETS_ID ON CB_USER_SECRETS (USER_ID,SECRET_ID);
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
ALTER TABLE CB_AUTH_TOKEN ADD COLUMN AUTH_ROLE VARCHAR(32);
|
||||
|
||||
ALTER TABLE CB_USER ADD COLUMN DEFAULT_AUTH_ROLE VARCHAR(32) NULL;
|
||||
|
||||
CREATE TABLE CB_TEAM
|
||||
(
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
TEAM_NAME VARCHAR(100) NOT NULL,
|
||||
TEAM_DESCRIPTION VARCHAR(255) NOT NULL,
|
||||
|
||||
CREATE_TIME TIMESTAMP NOT NULL,
|
||||
|
||||
PRIMARY KEY (TEAM_ID),
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_AUTH_SUBJECT (SUBJECT_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO CB_TEAM (TEAM_ID, TEAM_NAME, TEAM_DESCRIPTION, CREATE_TIME)
|
||||
SELECT ROLE_ID, ROLE_NAME, ROLE_DESCRIPTION, CREATE_TIME FROM CB_ROLE;
|
||||
|
||||
CREATE TABLE CB_USER_TEAM
|
||||
(
|
||||
USER_ID VARCHAR(128) NOT NULL,
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
|
||||
GRANT_TIME TIMESTAMP NOT NULL,
|
||||
GRANTED_BY VARCHAR(128) NOT NULL,
|
||||
|
||||
PRIMARY KEY (USER_ID, TEAM_ID),
|
||||
FOREIGN KEY (USER_ID) REFERENCES CB_USER (USER_ID) ON DELETE CASCADE,
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_TEAM (TEAM_ID) ON DELETE NO ACTION
|
||||
);
|
||||
|
||||
INSERT INTO CB_USER_TEAM (USER_ID, TEAM_ID, GRANT_TIME, GRANTED_BY)
|
||||
SELECT USER_ID, ROLE_ID, GRANT_TIME, GRANTED_BY FROM CB_USER_ROLE;
|
||||
|
||||
CREATE TABLE CB_EXTERNAL_TEAM
|
||||
(
|
||||
TEAM_ID VARCHAR(128) NOT NULL,
|
||||
EXTERNAL_TEAM_ID VARCHAR(128) NOT NULL,
|
||||
|
||||
PRIMARY KEY (TEAM_ID,EXTERNAL_TEAM_ID),
|
||||
FOREIGN KEY (TEAM_ID) REFERENCES CB_TEAM (TEAM_ID) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
DROP TABLE CB_USER_ROLE;
|
||||
DROP TABLE CB_ROLE;
|
||||
+160
-146
@@ -38,6 +38,7 @@ import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
|
||||
import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCTransaction;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.LoggingProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.security.*;
|
||||
import org.jkiss.dbeaver.model.security.exception.SMAccessTokenExpiredException;
|
||||
@@ -45,7 +46,7 @@ import org.jkiss.dbeaver.model.security.exception.SMException;
|
||||
import org.jkiss.dbeaver.model.security.exception.SMRefreshTokenExpiredException;
|
||||
import org.jkiss.dbeaver.model.security.user.SMAuthPermissions;
|
||||
import org.jkiss.dbeaver.model.security.user.SMObjectPermissions;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMTeam;
|
||||
import org.jkiss.dbeaver.model.security.user.SMUser;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderDescriptor;
|
||||
import org.jkiss.dbeaver.registry.auth.AuthProviderRegistry;
|
||||
@@ -72,7 +73,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
protected static final String CHAR_BOOL_FALSE = "N";
|
||||
|
||||
private static final String SUBJECT_USER = "U";
|
||||
private static final String SUBJECT_ROLE = "R";
|
||||
private static final String SUBJECT_TEAM = "R";
|
||||
private static final Type MAP_STRING_OBJECT_TYPE = new TypeToken<Map<String, Object>>() {
|
||||
}.getType();
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
@@ -114,7 +115,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
@Override
|
||||
public void createUser(String userId, Map<String, String> metaParameters, boolean enabled) throws DBException {
|
||||
if (isSubjectExists(userId)) {
|
||||
throw new DBCException("User or role '" + userId + "' already exists");
|
||||
throw new DBCException("User or team '" + userId + "' already exists");
|
||||
}
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
@@ -156,15 +157,15 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserRoles(String userId, String[] roleIds, String grantorId) throws DBCException {
|
||||
public void setUserTeams(String userId, String[] teamIds, String grantorId) throws DBCException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
JDBCUtils.executeStatement(dbCon, "DELETE FROM CB_USER_ROLE WHERE USER_ID=?", userId);
|
||||
if (!ArrayUtils.isEmpty(roleIds)) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement("INSERT INTO CB_USER_ROLE(USER_ID,ROLE_ID,GRANT_TIME,GRANTED_BY) VALUES(?,?,?,?)")) {
|
||||
for (String roleId : roleIds) {
|
||||
JDBCUtils.executeStatement(dbCon, "DELETE FROM CB_USER_TEAM WHERE USER_ID=?", userId);
|
||||
if (!ArrayUtils.isEmpty(teamIds)) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement("INSERT INTO CB_USER_TEAM(USER_ID,TEAM_ID,GRANT_TIME,GRANTED_BY) VALUES(?,?,?,?)")) {
|
||||
for (String teamId : teamIds) {
|
||||
dbStat.setString(1, userId);
|
||||
dbStat.setString(2, roleId);
|
||||
dbStat.setString(2, teamId);
|
||||
dbStat.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
|
||||
dbStat.setString(4, grantorId);
|
||||
dbStat.execute();
|
||||
@@ -174,28 +175,28 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving user roles in database", e);
|
||||
throw new DBCException("Error saving user teams in database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SMRole[] getUserRoles(String userId) throws DBException {
|
||||
public SMTeam[] getUserTeams(String userId) throws DBException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"SELECT R.* FROM CB_USER_ROLE UR,CB_ROLE R " +
|
||||
"WHERE UR.USER_ID=? AND UR.ROLE_ID=R.ROLE_ID")) {
|
||||
"SELECT R.* FROM CB_USER_TEAM UR,CB_TEAM R " +
|
||||
"WHERE UR.USER_ID=? AND UR.TEAM_ID=R.TEAM_ID")) {
|
||||
dbStat.setString(1, userId);
|
||||
List<SMRole> roles = new ArrayList<>();
|
||||
List<SMTeam> teams = new ArrayList<>();
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
while (dbResult.next()) {
|
||||
roles.add(fetchRole(dbResult));
|
||||
teams.add(fetchTeam(dbResult));
|
||||
}
|
||||
}
|
||||
return roles.toArray(new SMRole[0]);
|
||||
return teams.toArray(new SMTeam[0]);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error while reading user roles", e);
|
||||
throw new DBCException("Error while reading user teams", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,6 +216,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
}
|
||||
}
|
||||
// Metas
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement("SELECT META_ID,META_VALUE FROM CB_USER_META WHERE USER_ID=?")) {
|
||||
dbStat.setString(1, userId);
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
@@ -226,6 +228,17 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
}
|
||||
}
|
||||
// Teams
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement("SELECT TEAM_ID FROM CB_USER_TEAM WHERE USER_ID=?")) {
|
||||
dbStat.setString(1, userId);
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
List<String> teamIDs = new ArrayList<>();
|
||||
while (dbResult.next()) {
|
||||
teamIDs.add(dbResult.getString(1));
|
||||
}
|
||||
user.setUserTeams(teamIDs.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
return user;
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error while searching credentials", e);
|
||||
@@ -270,6 +283,24 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
}
|
||||
}
|
||||
// Read teams
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement("SELECT USER_ID,TEAM_ID FROM CB_USER_TEAM" +
|
||||
(CommonUtils.isEmpty(userNameMask) ? "" : " WHERE USER_ID=?"))) {
|
||||
if (!CommonUtils.isEmpty(userNameMask)) {
|
||||
dbStat.setString(1, userNameMask);
|
||||
}
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
while (dbResult.next()) {
|
||||
String userId = dbResult.getString(1);
|
||||
String teamId = dbResult.getString(2);
|
||||
SMUser user = result.get(userId);
|
||||
if (user != null) {
|
||||
String[] teams = ArrayUtils.add(String.class, user.getUserTeams(), teamId);
|
||||
user.setUserTeams(teams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.values().toArray(new SMUser[0]);
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error while loading users", e);
|
||||
@@ -533,7 +564,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving role in database", e);
|
||||
throw new DBCException("Error reading user credentials", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,56 +587,56 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving role in database", e);
|
||||
throw new DBCException("Error reading user linked providers", e);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Roles
|
||||
// Teams
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SMRole[] readAllRoles() throws DBCException {
|
||||
public SMTeam[] readAllTeams() throws DBCException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
Map<String, SMRole> roles = new LinkedHashMap<>();
|
||||
Map<String, SMTeam> teams = new LinkedHashMap<>();
|
||||
try (Statement dbStat = dbCon.createStatement()) {
|
||||
try (ResultSet dbResult = dbStat.executeQuery("SELECT * FROM CB_ROLE ORDER BY ROLE_ID")) {
|
||||
try (ResultSet dbResult = dbStat.executeQuery("SELECT * FROM CB_TEAM ORDER BY TEAM_ID")) {
|
||||
while (dbResult.next()) {
|
||||
SMRole role = fetchRole(dbResult);
|
||||
roles.put(role.getRoleId(), role);
|
||||
SMTeam team = fetchTeam(dbResult);
|
||||
teams.put(team.getTeamId(), team);
|
||||
}
|
||||
}
|
||||
try (ResultSet dbResult = dbStat.executeQuery("SELECT SUBJECT_ID,PERMISSION_ID\n" +
|
||||
"FROM CB_AUTH_PERMISSIONS AP,CB_ROLE R\n" +
|
||||
"WHERE AP.SUBJECT_ID=R.ROLE_ID\n")) {
|
||||
"FROM CB_AUTH_PERMISSIONS AP,CB_TEAM R\n" +
|
||||
"WHERE AP.SUBJECT_ID=R.TEAM_ID\n")) {
|
||||
while (dbResult.next()) {
|
||||
SMRole role = roles.get(dbResult.getString(1));
|
||||
if (role != null) {
|
||||
role.addPermission(dbResult.getString(2));
|
||||
SMTeam team = teams.get(dbResult.getString(1));
|
||||
if (team != null) {
|
||||
team.addPermission(dbResult.getString(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return roles.values().toArray(new SMRole[0]);
|
||||
return teams.values().toArray(new SMTeam[0]);
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error reading roles from database", e);
|
||||
throw new DBCException("Error reading teams from database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SMRole findRole(String roleId) throws DBCException {
|
||||
return Arrays.stream(readAllRoles())
|
||||
.filter(r -> r.getRoleId().equals(roleId))
|
||||
public SMTeam findTeam(String teamId) throws DBCException {
|
||||
return Arrays.stream(readAllTeams())
|
||||
.filter(r -> r.getTeamId().equals(teamId))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String[] getRoleSubjects(String roleId) throws DBCException {
|
||||
public String[] getTeamMembers(String teamId) throws DBCException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"SELECT USER_ID FROM CB_USER_ROLE WHERE ROLE_ID=?")) {
|
||||
dbStat.setString(1, roleId);
|
||||
"SELECT USER_ID FROM CB_USER_TEAM WHERE TEAM_ID=?")) {
|
||||
dbStat.setString(1, teamId);
|
||||
List<String> subjects = new ArrayList<>();
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
while (dbResult.next()) {
|
||||
@@ -615,95 +646,96 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
return subjects.toArray(new String[0]);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error while reading role subjects", e);
|
||||
throw new DBCException("Error while reading team members", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SMRole fetchRole(ResultSet dbResult) throws SQLException {
|
||||
return new SMRole(dbResult.getString("ROLE_ID"),
|
||||
dbResult.getString("ROLE_NAME"),
|
||||
dbResult.getString("ROLE_DESCRIPTION")
|
||||
private SMTeam fetchTeam(ResultSet dbResult) throws SQLException {
|
||||
return new SMTeam(
|
||||
dbResult.getString("TEAM_ID"),
|
||||
dbResult.getString("TEAM_NAME"),
|
||||
dbResult.getString("TEAM_DESCRIPTION")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createRole(String roleId, String name, String description, String grantor) throws DBCException {
|
||||
if (isSubjectExists(roleId)) {
|
||||
throw new DBCException("User or role '" + roleId + "' already exists");
|
||||
public void createTeam(String teamId, String name, String description, String grantor) throws DBCException {
|
||||
if (isSubjectExists(teamId)) {
|
||||
throw new DBCException("User or team '" + teamId + "' already exists");
|
||||
}
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
createAuthSubject(dbCon, roleId, SUBJECT_ROLE);
|
||||
createAuthSubject(dbCon, teamId, SUBJECT_TEAM);
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"INSERT INTO CB_ROLE(ROLE_ID,ROLE_NAME,ROLE_DESCRIPTION,CREATE_TIME) VALUES(?,?,?,?)")) {
|
||||
dbStat.setString(1, roleId);
|
||||
"INSERT INTO CB_TEAM(TEAM_ID,TEAM_NAME,TEAM_DESCRIPTION,CREATE_TIME) VALUES(?,?,?,?)")) {
|
||||
dbStat.setString(1, teamId);
|
||||
dbStat.setString(2, CommonUtils.notEmpty(name));
|
||||
dbStat.setString(3, CommonUtils.notEmpty(description));
|
||||
dbStat.setTimestamp(4, new Timestamp(System.currentTimeMillis()));
|
||||
dbStat.execute();
|
||||
}
|
||||
|
||||
insertPermissions(dbCon, roleId,
|
||||
insertPermissions(dbCon, teamId,
|
||||
new String[] {DBWConstants.PERMISSION_PUBLIC} , grantor);
|
||||
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving role in database", e);
|
||||
throw new DBCException("Error saving tem in database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRole(String roleId, String name, String description) throws DBCException {
|
||||
if (!isSubjectExists(roleId)) {
|
||||
throw new DBCException("Role '" + roleId + "' doesn't exists");
|
||||
public void updateTeam(String teamId, String name, String description) throws DBCException {
|
||||
if (!isSubjectExists(teamId)) {
|
||||
throw new DBCException("Team '" + teamId + "' doesn't exists");
|
||||
}
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"UPDATE CB_ROLE SET ROLE_NAME=?,ROLE_DESCRIPTION=? WHERE ROLE_ID=?")) {
|
||||
"UPDATE CB_TEAM SET TEAM_NAME=?,TEAM_DESCRIPTION=? WHERE TEAM_ID=?")) {
|
||||
dbStat.setString(1, CommonUtils.notEmpty(name));
|
||||
dbStat.setString(2, CommonUtils.notEmpty(description));
|
||||
dbStat.setString(3, roleId);
|
||||
dbStat.setString(3, teamId);
|
||||
if (dbStat.executeUpdate() <= 0) {
|
||||
throw new DBCException("Role '" + roleId + "' doesn't exist");
|
||||
throw new DBCException("Team '" + teamId + "' doesn't exist");
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error updating role info in database", e);
|
||||
throw new DBCException("Error updating team info in database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRole(String roleId) throws DBCException {
|
||||
public void deleteTeam(String teamId) throws DBCException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"SELECT COUNT(*) FROM CB_USER_ROLE WHERE ROLE_ID=?")) {
|
||||
dbStat.setString(1, roleId);
|
||||
"SELECT COUNT(*) FROM CB_USER_TEAM WHERE TEAM_ID=?")) {
|
||||
dbStat.setString(1, teamId);
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
if (dbResult.next()) {
|
||||
int userCount = dbResult.getInt(1);
|
||||
if (userCount > 0) {
|
||||
throw new DBCException("Role can't be deleted. There are " + userCount + " user(s) who have this role. Un-assign role first.");
|
||||
throw new DBCException("Team can't be deleted. There are " + userCount + " user(s) who have this team. Un-assign team first.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
deleteAuthSubject(dbCon, roleId);
|
||||
deleteAuthSubject(dbCon, teamId);
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"DELETE FROM CB_ROLE WHERE ROLE_ID=?")) {
|
||||
dbStat.setString(1, roleId);
|
||||
"DELETE FROM CB_TEAM WHERE TEAM_ID=?")) {
|
||||
dbStat.setString(1, teamId);
|
||||
dbStat.execute();
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error deleting role from database", e);
|
||||
throw new DBCException("Error deleting team from database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,7 +752,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving role permissions in database", e);
|
||||
throw new DBCException("Error saving subject permissions in database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -753,18 +785,18 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
return permissions;
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error saving role in database", e);
|
||||
throw new DBCException("Error reading subject permissions", e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<String> getUserPermissions(String userId) throws DBException {
|
||||
public Set<String> getUserPermissions(String userId, String authRole) throws DBException {
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
Set<String> permissions = new HashSet<>();
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"SELECT DISTINCT AP.PERMISSION_ID FROM CB_AUTH_PERMISSIONS AP,CB_USER_ROLE UR\n" +
|
||||
"WHERE UR.ROLE_ID=AP.SUBJECT_ID AND UR.USER_ID=?")) {
|
||||
"SELECT DISTINCT AP.PERMISSION_ID FROM CB_AUTH_PERMISSIONS AP,CB_USER_TEAM UR\n" +
|
||||
"WHERE UR.TEAM_ID=AP.SUBJECT_ID AND UR.USER_ID=?")) {
|
||||
dbStat.setString(1, userId);
|
||||
try (ResultSet dbResult = dbStat.executeQuery()) {
|
||||
while (dbResult.next()) {
|
||||
@@ -822,25 +854,15 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
+ "VALUES(?,?,?,?,?,?,?,?,?)")) {
|
||||
dbStat.setString(1, sessionId);
|
||||
dbStat.setString(2, appSessionId);
|
||||
if (userId != null) {
|
||||
dbStat.setString(3, userId);
|
||||
} else {
|
||||
dbStat.setNull(3, Types.VARCHAR);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 3, userId);
|
||||
|
||||
Timestamp currentTS = new Timestamp(System.currentTimeMillis());
|
||||
dbStat.setTimestamp(4, currentTS);
|
||||
dbStat.setTimestamp(5, currentTS);
|
||||
if (parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS) != null) {
|
||||
dbStat.setString(6, parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS).toString());
|
||||
} else {
|
||||
dbStat.setNull(6, Types.VARCHAR);
|
||||
}
|
||||
if (parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT) != null) {
|
||||
dbStat.setString(7, parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT).toString());
|
||||
} else {
|
||||
dbStat.setNull(7, Types.VARCHAR);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 6, CommonUtils.truncateString(CommonUtils.toString(
|
||||
parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS), null), 128));
|
||||
JDBCUtils.setStringOrNull(dbStat, 7, CommonUtils.truncateString(CommonUtils.toString(
|
||||
parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT), null), 255));
|
||||
dbStat.setString(8, database.getInstanceId());
|
||||
dbStat.setString(9, sessionType.getSessionType());
|
||||
dbStat.execute();
|
||||
@@ -853,14 +875,15 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
|
||||
var smSessionId = createSmSession(appSessionId, null, sessionParameters, sessionType, dbCon);
|
||||
var smTokens = generateNewSessionToken(smSessionId, null, dbCon);
|
||||
var smTokens = generateNewSessionToken(smSessionId, null, null, dbCon);
|
||||
var permissions = getAnonymousUserPermissions();
|
||||
txn.commit();
|
||||
return SMAuthInfo.success(
|
||||
UUID.randomUUID().toString(),
|
||||
smTokens.getSmAccessToken(),
|
||||
smTokens.getSmRefreshToken(),
|
||||
new SMAuthPermissions(null, smSessionId, permissions), Map.of()
|
||||
new SMAuthPermissions(null, smSessionId, permissions),
|
||||
Map.of()
|
||||
);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
@@ -869,8 +892,8 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
}
|
||||
|
||||
private Set<String> getAnonymousUserPermissions() throws DBException {
|
||||
var anonymousUserRole = ((WebApplication) DBWorkbench.getPlatform().getApplication()).getAppConfiguration().getAnonymousUserRole();
|
||||
return getSubjectPermissions(anonymousUserRole);
|
||||
var anonymousUserTeam = ((WebApplication) DBWorkbench.getPlatform().getApplication()).getAppConfiguration().getAnonymousUserTeam();
|
||||
return getSubjectPermissions(anonymousUserTeam);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1019,16 +1042,8 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"UPDATE CB_AUTH_ATTEMPT SET AUTH_STATUS=?,AUTH_ERROR=?,SESSION_ID=? WHERE AUTH_ID=?")) {
|
||||
dbStat.setString(1, authStatus.toString());
|
||||
if (error != null) {
|
||||
dbStat.setString(2, error);
|
||||
} else {
|
||||
dbStat.setNull(2, Types.VARCHAR);
|
||||
}
|
||||
if (smSessionId != null) {
|
||||
dbStat.setString(3, smSessionId);
|
||||
} else {
|
||||
dbStat.setNull(3, Types.VARCHAR);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 2, error);
|
||||
JDBCUtils.setStringOrNull(dbStat, 3, smSessionId);
|
||||
dbStat.setString(4, authId);
|
||||
if (dbStat.executeUpdate() <= 0) {
|
||||
throw new DBCException("Auth attempt '" + authId + "' doesn't exist");
|
||||
@@ -1145,6 +1160,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
public SMTokens refreshSession(@NotNull String refreshToken) throws DBException {
|
||||
var currentUserCreds = getCurrentUserCreds();
|
||||
var currentUserAccessToken = currentUserCreds.getSmToken();
|
||||
String currentUserAuthRole = null; // FIXME: read role from auth token
|
||||
|
||||
var expectedRefreshTokenInfo = findRefreshToken(currentUserAccessToken);
|
||||
|
||||
@@ -1154,7 +1170,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
|
||||
try (var dbCon = database.openConnection()) {
|
||||
invalidateUserTokens(currentUserAccessToken);
|
||||
return generateNewSessionToken(expectedRefreshTokenInfo.getSessionId(), expectedRefreshTokenInfo.getUserId(), dbCon);
|
||||
return generateNewSessionToken(expectedRefreshTokenInfo.getSessionId(), expectedRefreshTokenInfo.getUserId(), currentUserAuthRole, dbCon);
|
||||
} catch (SQLException e) {
|
||||
throw new DBException("Error refreshing sm session", e);
|
||||
}
|
||||
@@ -1223,7 +1239,11 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
return finishAuthentication(authInfo, false, true);
|
||||
}
|
||||
|
||||
private SMAuthInfo finishAuthentication(@NotNull SMAuthInfo authInfo, boolean forceExpireAuthAfterSuccess, boolean saveSecuredCreds) throws DBException {
|
||||
private SMAuthInfo finishAuthentication(
|
||||
@NotNull SMAuthInfo authInfo,
|
||||
boolean forceExpireAuthAfterSuccess,
|
||||
boolean saveSecuredCreds
|
||||
) throws DBException {
|
||||
String authId = authInfo.getAuthAttemptId();
|
||||
if (authInfo.getAuthStatus() != SMAuthStatus.IN_PROGRESS) {
|
||||
throw new SMException("Authorization has already been completed with status: " + authInfo.getAuthStatus());
|
||||
@@ -1233,7 +1253,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
throw new SMException("Authorization providers are not defined");
|
||||
}
|
||||
|
||||
var finishAuthMonitor = new VoidProgressMonitor();
|
||||
DBRProgressMonitor finishAuthMonitor = new LoggingProgressMonitor(log);
|
||||
AuthAttemptSessionInfo authAttemptSessionInfo = readAuthAttemptSessionInfo(authId);
|
||||
boolean isMainAuthSession = authAttemptSessionInfo.getSmSessionId() == null;
|
||||
|
||||
@@ -1287,8 +1307,9 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
} else {
|
||||
smSessionId = authAttemptSessionInfo.getSmSessionId();
|
||||
}
|
||||
smTokens = generateNewSessionToken(smSessionId, activeUserId, dbCon);
|
||||
permissions = new SMAuthPermissions(activeUserId, smSessionId, getUserPermissions(activeUserId));
|
||||
smTokens = generateNewSessionToken(smSessionId, activeUserId, authInfo.getAuthRole(), dbCon);
|
||||
permissions = new SMAuthPermissions(
|
||||
activeUserId, smSessionId, getUserPermissions(activeUserId, authInfo.getAuthRole()));
|
||||
txn.commit();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
@@ -1364,11 +1385,11 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
|
||||
userId = userIdFromCredentials;
|
||||
if (!isSubjectExists(userId)) {
|
||||
var newUser = new SMUser(userId);
|
||||
var newUser = new SMUser(userId, true);
|
||||
createUser(newUser.getUserId(), newUser.getMetaParameters(), true);
|
||||
String defaultRoleName = WebAppUtils.getWebApplication().getAppConfiguration().getDefaultUserRole();
|
||||
if (!CommonUtils.isEmpty(defaultRoleName)) {
|
||||
setUserRoles(userId, new String[]{defaultRoleName}, userId);
|
||||
String defaultTeamName = WebAppUtils.getWebApplication().getAppConfiguration().getDefaultUserTeam();
|
||||
if (!CommonUtils.isEmpty(defaultTeamName)) {
|
||||
setUserTeams(userId, new String[]{defaultTeamName}, userId);
|
||||
}
|
||||
}
|
||||
setUserCredentials(userId, authProviderId, userCredentials);
|
||||
@@ -1376,9 +1397,9 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
userId = userIdFromCredentials;
|
||||
}
|
||||
if (authProvider.isTrusted()) {
|
||||
Object reverseProxyUserRoles = sessionParameters.get(SMConstants.SESSION_PARAM_TRUSTED_USER_ROLES);
|
||||
if (reverseProxyUserRoles instanceof List) {
|
||||
setUserRoles(userId, ((List<?>) reverseProxyUserRoles).stream().map(Object::toString).toArray(String[]::new), userId);
|
||||
Object reverseProxyUserTeams = sessionParameters.get(SMConstants.SESSION_PARAM_TRUSTED_USER_TEAMS);
|
||||
if (reverseProxyUserTeams instanceof List) {
|
||||
setUserTeams(userId, ((List<?>) reverseProxyUserTeams).stream().map(Object::toString).toArray(String[]::new), userId);
|
||||
}
|
||||
}
|
||||
return userId;
|
||||
@@ -1387,34 +1408,35 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
protected SMTokens generateNewSessionToken(
|
||||
@NotNull String smSessionId,
|
||||
@Nullable String userId,
|
||||
@Nullable String authRole,
|
||||
@NotNull Connection dbCon
|
||||
) throws SQLException, DBException {
|
||||
JDBCUtils.executeStatement(dbCon, "DELETE FROM CB_AUTH_TOKEN WHERE SESSION_ID=?", smSessionId);
|
||||
return generateNewSessionTokens(smSessionId, userId, dbCon);
|
||||
return generateNewSessionTokens(smSessionId, userId, authRole, dbCon);
|
||||
}
|
||||
|
||||
private SMTokens generateNewSessionTokens(@NotNull String smSessionId,
|
||||
@Nullable String userId,
|
||||
@NotNull Connection dbCon) throws SQLException {
|
||||
private SMTokens generateNewSessionTokens(
|
||||
@NotNull String smSessionId,
|
||||
@Nullable String userId,
|
||||
@Nullable String authRole,
|
||||
@NotNull Connection dbCon
|
||||
) throws SQLException {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"INSERT INTO CB_AUTH_TOKEN(TOKEN_ID,SESSION_ID,USER_ID,EXPIRATION_TIME,REFRESH_TOKEN_ID,REFRESH_TOKEN_EXPIRATION_TIME) " +
|
||||
"VALUES(?,?,?,?,?,?)")) {
|
||||
"INSERT INTO CB_AUTH_TOKEN(TOKEN_ID,SESSION_ID,USER_ID,AUTH_ROLE,EXPIRATION_TIME,REFRESH_TOKEN_ID,REFRESH_TOKEN_EXPIRATION_TIME) " +
|
||||
"VALUES(?,?,?,?,?,?,?)")) {
|
||||
|
||||
String smAccessToken = SecurityUtils.generatePassword(32);
|
||||
dbStat.setString(1, smAccessToken);
|
||||
dbStat.setString(2, smSessionId);
|
||||
if (userId == null) {
|
||||
dbStat.setNull(3, Types.VARCHAR);
|
||||
} else {
|
||||
dbStat.setString(3, userId);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 3, userId);
|
||||
JDBCUtils.setStringOrNull(dbStat, 4, authRole);
|
||||
var accessTokenExpirationTime = Timestamp.valueOf(LocalDateTime.now().plusMinutes(smConfig.getAccessTokenTtl()));
|
||||
dbStat.setTimestamp(4, accessTokenExpirationTime);
|
||||
dbStat.setTimestamp(5, accessTokenExpirationTime);
|
||||
|
||||
String smRefreshToken = SecurityUtils.generatePassword(32);
|
||||
dbStat.setString(5, smRefreshToken);
|
||||
dbStat.setString(6, smRefreshToken);
|
||||
var refreshTokenExpirationTime = Timestamp.valueOf(LocalDateTime.now().plusMinutes(smConfig.getRefreshTokenTtl()));
|
||||
dbStat.setTimestamp(6, refreshTokenExpirationTime);
|
||||
dbStat.setTimestamp(7, refreshTokenExpirationTime);
|
||||
|
||||
dbStat.execute();
|
||||
return new SMTokens(smAccessToken, smRefreshToken);
|
||||
@@ -1425,8 +1447,9 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
public SMAuthPermissions getTokenPermissions(String token) throws DBException {
|
||||
String userId;
|
||||
String sessionId;
|
||||
String authRole;
|
||||
try (Connection dbCon = database.openConnection();
|
||||
PreparedStatement dbStat = dbCon.prepareStatement("SELECT USER_ID, EXPIRATION_TIME, SESSION_ID FROM CB_AUTH_TOKEN WHERE TOKEN_ID=?");
|
||||
PreparedStatement dbStat = dbCon.prepareStatement("SELECT USER_ID, EXPIRATION_TIME, SESSION_ID, AUTH_ROLE FROM CB_AUTH_TOKEN WHERE TOKEN_ID=?");
|
||||
) {
|
||||
dbStat.setString(1, token);
|
||||
try (var dbResult = dbStat.executeQuery()) {
|
||||
@@ -1439,11 +1462,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
throw new SMAccessTokenExpiredException("Token expired");
|
||||
}
|
||||
sessionId = dbResult.getString(3);
|
||||
authRole = dbResult.getString(4);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new DBCException("Error reading token info in database", e);
|
||||
}
|
||||
var permissions = userId == null ? getAnonymousUserPermissions() : getUserPermissions(userId);
|
||||
var permissions = userId == null ? getAnonymousUserPermissions() : getUserPermissions(userId, authRole);
|
||||
return new SMAuthPermissions(userId, sessionId, permissions);
|
||||
}
|
||||
|
||||
@@ -1491,22 +1515,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
try (Connection dbCon = database.openConnection()) {
|
||||
try (PreparedStatement dbStat = dbCon.prepareStatement(
|
||||
"UPDATE CB_SESSION SET USER_ID=?,LAST_ACCESS_TIME=?,LAST_ACCESS_REMOTE_ADDRESS=?,LAST_ACCESS_USER_AGENT=?,LAST_ACCESS_INSTANCE_ID=? WHERE SESSION_ID=?")) {
|
||||
if (userId == null) {
|
||||
dbStat.setNull(1, Types.VARCHAR);
|
||||
} else {
|
||||
dbStat.setString(1, userId);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 1, userId);
|
||||
dbStat.setTimestamp(2, new Timestamp(System.currentTimeMillis()));
|
||||
if (parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS) != null) {
|
||||
dbStat.setString(3, CommonUtils.truncateString(parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS).toString(), 128));
|
||||
} else {
|
||||
dbStat.setNull(3, Types.VARCHAR);
|
||||
}
|
||||
if (parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT) != null) {
|
||||
dbStat.setString(4, CommonUtils.truncateString(parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT).toString(), 255));
|
||||
} else {
|
||||
dbStat.setNull(4, Types.VARCHAR);
|
||||
}
|
||||
JDBCUtils.setStringOrNull(dbStat, 3, CommonUtils.truncateString(CommonUtils.toString(
|
||||
parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_ADDRESS), null), 128));
|
||||
JDBCUtils.setStringOrNull(dbStat, 4, CommonUtils.truncateString(CommonUtils.toString(
|
||||
parameters.get(SMConstants.SESSION_PARAM_LAST_REMOTE_USER_AGENT), null), 255));
|
||||
dbStat.setString(5, database.getInstanceId());
|
||||
|
||||
dbStat.setString(6, sessionId);
|
||||
@@ -1630,10 +1644,10 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
|
||||
private Set<String> getAllLinkedSubjects(String subjectId) throws DBException {
|
||||
Set<String> allSubjects = new HashSet<>();
|
||||
allSubjects.add(subjectId);
|
||||
var userRoleIds = Arrays.stream(getUserRoles(subjectId))
|
||||
.map(SMRole::getRoleId)
|
||||
var userTeamIds = Arrays.stream(getUserTeams(subjectId))
|
||||
.map(SMTeam::getTeamId)
|
||||
.collect(Collectors.toSet());
|
||||
allSubjects.addAll(userRoleIds);
|
||||
allSubjects.addAll(userTeamIds);
|
||||
return allSubjects;
|
||||
}
|
||||
|
||||
|
||||
+12
-12
@@ -36,7 +36,7 @@ import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCTransaction;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.LoggingProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.security.SMAdminController;
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMTeam;
|
||||
import org.jkiss.dbeaver.model.security.user.SMUser;
|
||||
import org.jkiss.dbeaver.model.sql.schema.ClassLoaderScriptSource;
|
||||
import org.jkiss.dbeaver.model.sql.schema.SQLSchemaManager;
|
||||
@@ -68,7 +68,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 = 10;
|
||||
private static final int CURRENT_SCHEMA_VERSION = 11;
|
||||
|
||||
private static final String DEFAULT_DB_USER_NAME = "cb-data";
|
||||
private static final String DEFAULT_DB_PWD_FILE = ".database-credentials.dat";
|
||||
@@ -245,7 +245,7 @@ public class CBDatabase {
|
||||
SMUser adminUser = adminSecurityController.getUserById(adminName);
|
||||
|
||||
if (adminUser == null) {
|
||||
adminUser = new SMUser(adminName);
|
||||
adminUser = new SMUser(adminName, true);
|
||||
adminSecurityController.createUser(adminUser.getUserId(), adminUser.getMetaParameters(), true);
|
||||
}
|
||||
|
||||
@@ -269,11 +269,11 @@ public class CBDatabase {
|
||||
}
|
||||
|
||||
private void grantAdminPermissionsToUser(String userId) throws DBException {
|
||||
// Grant all roles
|
||||
SMRole[] allRoles = adminSecurityController.readAllRoles();
|
||||
adminSecurityController.setUserRoles(
|
||||
// Grant all teams
|
||||
SMTeam[] allTeams = adminSecurityController.readAllTeams();
|
||||
adminSecurityController.setUserTeams(
|
||||
userId,
|
||||
Arrays.stream(allRoles).map(SMRole::getRoleId).toArray(String[]::new),
|
||||
Arrays.stream(allTeams).map(SMTeam::getTeamId).toArray(String[]::new),
|
||||
userId);
|
||||
}
|
||||
|
||||
@@ -345,12 +345,12 @@ public class CBDatabase {
|
||||
String adminName = initialData.getAdminName();
|
||||
String adminPassword = initialData.getAdminPassword();
|
||||
|
||||
if (!CommonUtils.isEmpty(initialData.getRoles())) {
|
||||
// Create roles
|
||||
for (SMRole role : initialData.getRoles()) {
|
||||
adminSecurityController.createRole(role.getRoleId(), role.getName(), role.getDescription(), adminName);
|
||||
if (!CommonUtils.isEmpty(initialData.getTeams())) {
|
||||
// Create teams
|
||||
for (SMTeam team : initialData.getTeams()) {
|
||||
adminSecurityController.createTeam(team.getTeamId(), team.getName(), team.getDescription(), adminName);
|
||||
if (adminName != null) {
|
||||
adminSecurityController.setSubjectPermissions(role.getRoleId(), new ArrayList<>(role.getPermissions()), adminName);
|
||||
adminSecurityController.setSubjectPermissions(team.getTeamId(), new ArrayList<>(team.getPermissions()), adminName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -16,14 +16,14 @@
|
||||
*/
|
||||
package io.cloudbeaver.service.security.db;
|
||||
|
||||
import org.jkiss.dbeaver.model.security.user.SMRole;
|
||||
import org.jkiss.dbeaver.model.security.user.SMTeam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class CBDatabaseInitialData {
|
||||
private String adminName = "cbadmin";
|
||||
private String adminPassword = "cbadmin20";
|
||||
private List<SMRole> roles;
|
||||
private List<SMTeam> teams;
|
||||
|
||||
public String getAdminName() {
|
||||
return adminName;
|
||||
@@ -33,11 +33,11 @@ class CBDatabaseInitialData {
|
||||
return adminPassword;
|
||||
}
|
||||
|
||||
public List<SMRole> getRoles() {
|
||||
return roles;
|
||||
public List<SMTeam> getTeams() {
|
||||
return teams;
|
||||
}
|
||||
|
||||
public void setRoles(List<SMRole> roles) {
|
||||
this.roles = roles;
|
||||
public void setTeams(List<SMTeam> teams) {
|
||||
this.teams = teams;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -web-config conf/cloudbeaver.conf"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dosgi.requiredJavaVersion=1.6 -Xms40m -Xmx512m"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="C:\devel\my\cloudbeaver\deploy\cloudbeaver\"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}/../opt/cloudbeaver"/>
|
||||
<stringAttribute key="pde.version" value="3.3"/>
|
||||
<stringAttribute key="product" value="io.cloudbeaver.product.ce.product"/>
|
||||
<stringAttribute key="productFile" value="\web-server\DBeaverWebServer.product"/>
|
||||
@@ -97,7 +97,7 @@
|
||||
<setEntry value="org.jkiss.bundle.influxdb@default:default"/>
|
||||
<setEntry value="org.jkiss.bundle.jaxb@default:default"/>
|
||||
<setEntry value="org.jkiss.bundle.sshj@default:default"/>
|
||||
<setEntry value="org.objectweb.asm*9.1.0.v20210209-1849@default:default"/>
|
||||
<setEntry value="org.objectweb.asm@default:default"/>
|
||||
<setEntry value="org.slf4j.api@default:default"/>
|
||||
</setAttribute>
|
||||
<setAttribute key="selected_workspace_bundles">
|
||||
|
||||
+3
-1
@@ -50,7 +50,9 @@ public class CEServerTestSuite {
|
||||
} else {
|
||||
System.out.println("Start CBApplication");
|
||||
testApp = new CBApplication();
|
||||
thread = new Thread(() -> testApp.start(null));
|
||||
thread = new Thread(() -> {
|
||||
testApp.start(null);
|
||||
});
|
||||
thread.start();
|
||||
client = HttpClient.newBuilder()
|
||||
.cookieHandler(new CookieManager())
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
{
|
||||
adminName: "test",
|
||||
adminPassword: "test",
|
||||
roles: [
|
||||
teams: [
|
||||
{
|
||||
roleId: "admin",
|
||||
teamId: "admin",
|
||||
name: "Admin",
|
||||
description: "Administrative access. Has all permissions.",
|
||||
permissions: [ "public", "admin" ]
|
||||
},
|
||||
{
|
||||
roleId: "user",
|
||||
teamId: "user",
|
||||
name: "User",
|
||||
description: "Standard user",
|
||||
permissions: [ "public" ]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
<level>DEBUG</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import {
|
||||
GraphQLService,
|
||||
CachedMapResource,
|
||||
ResourceKey,
|
||||
resourceKeyList,
|
||||
ResourceKeyList,
|
||||
ResourceKeyUtils,
|
||||
AdminRoleInfoFragment,
|
||||
AdminConnectionGrantInfo,
|
||||
CachedMapAllKey
|
||||
} from '@cloudbeaver/core-sdk';
|
||||
import { isArraysEqual } from '@cloudbeaver/core-utils';
|
||||
|
||||
const NEW_ROLE_SYMBOL = Symbol('new-role');
|
||||
|
||||
export type RoleInfo = AdminRoleInfoFragment;
|
||||
type NewRole = RoleInfo & { [NEW_ROLE_SYMBOL]: boolean; timestamp: number };
|
||||
|
||||
@injectable()
|
||||
export class RolesResource extends CachedMapResource<string, RoleInfo> {
|
||||
constructor(private readonly graphQLService: GraphQLService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async loadAll(): Promise<Map<string, RoleInfo>> {
|
||||
await this.load(CachedMapAllKey);
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async refreshAll(): Promise<Map<string, RoleInfo>> {
|
||||
await this.refresh(CachedMapAllKey);
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async createRole(roleInfo: RoleInfo): Promise<RoleInfo> {
|
||||
const response = await this.graphQLService.sdk.createRole(roleInfo);
|
||||
|
||||
const newRole: NewRole = {
|
||||
...response.role,
|
||||
[NEW_ROLE_SYMBOL]: true,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
this.updateRoles(newRole);
|
||||
|
||||
await this.setSubjectPermissions(newRole.roleId, roleInfo.rolePermissions);
|
||||
|
||||
return this.get(roleInfo.roleId)!;
|
||||
}
|
||||
|
||||
async updateRole(roleInfo: RoleInfo): Promise<RoleInfo> {
|
||||
const { role } = await this.graphQLService.sdk.updateRole(roleInfo);
|
||||
|
||||
this.updateRoles(role);
|
||||
|
||||
await this.setSubjectPermissions(role.roleId, roleInfo.rolePermissions);
|
||||
|
||||
return this.get(roleInfo.roleId)!;
|
||||
}
|
||||
|
||||
async deleteRole(key: ResourceKey<string>): Promise<Map<string, RoleInfo>> {
|
||||
await ResourceKeyUtils.forEachAsync(key, async key => {
|
||||
await this.graphQLService.sdk.deleteRole({
|
||||
roleId: key,
|
||||
});
|
||||
this.delete(key);
|
||||
});
|
||||
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async loadGrantedUsers(roleId: string): Promise<string[]> {
|
||||
const { role } = await this.graphQLService.sdk.getRoleGrantedUsers({ roleId });
|
||||
return role[0].grantedUsers;
|
||||
}
|
||||
|
||||
async getSubjectConnectionAccess(subjectId: string): Promise<AdminConnectionGrantInfo[]> {
|
||||
const { grantInfo } = await this.graphQLService.sdk.getSubjectConnectionAccess({ subjectId });
|
||||
return grantInfo;
|
||||
}
|
||||
|
||||
async setSubjectPermissions(roleId: string, permissions: string[]): Promise<void> {
|
||||
const role = this.get(roleId);
|
||||
|
||||
if (role && isArraysEqual(role.rolePermissions, permissions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
permissions: newPermissions,
|
||||
} = await this.graphQLService.sdk.setSubjectPermissions({ roleId, permissions });
|
||||
|
||||
if (role) {
|
||||
role.rolePermissions = newPermissions.map(permission => permission.id);
|
||||
} else {
|
||||
// TODO: update permissions for role instead
|
||||
await this.loader(roleId);
|
||||
}
|
||||
}
|
||||
|
||||
protected async loader(key: ResourceKey<string>): Promise<Map<string, RoleInfo>> {
|
||||
const all = ResourceKeyUtils.includes(key, CachedMapAllKey);
|
||||
|
||||
await ResourceKeyUtils.forEachAsync(all ? CachedMapAllKey : key, async key => {
|
||||
const roleId = all ? undefined : key;
|
||||
|
||||
const { roles } = await this.graphQLService.sdk.getRolesList({
|
||||
roleId,
|
||||
});
|
||||
|
||||
if (all) {
|
||||
this.data.clear();
|
||||
}
|
||||
|
||||
this.updateRoles(...roles);
|
||||
});
|
||||
|
||||
return this.data;
|
||||
}
|
||||
|
||||
cleanNewFlags(): void {
|
||||
for (const role of this.data.values()) {
|
||||
(role as NewRole)[NEW_ROLE_SYMBOL] = false;
|
||||
}
|
||||
}
|
||||
|
||||
private updateRoles(...roles: RoleInfo[]): ResourceKeyList<string> {
|
||||
const key = resourceKeyList(roles.map(role => role.roleId));
|
||||
|
||||
const oldRoles = this.get(key);
|
||||
this.set(key, oldRoles.map((role, i) => ({ ...role, ...roles[i] })));
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
function isNewRole(role: RoleInfo | NewRole): role is NewRole {
|
||||
return (role as NewRole)[NEW_ROLE_SYMBOL];
|
||||
}
|
||||
|
||||
export function compareRoles(a: RoleInfo, b: RoleInfo): number {
|
||||
if (isNewRole(a) && isNewRole(b)) {
|
||||
return b.timestamp - a.timestamp;
|
||||
}
|
||||
|
||||
if (isNewRole(b)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (isNewRole(a)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a.roleId.localeCompare(b.roleId);
|
||||
}
|
||||
+3
-3
@@ -8,12 +8,12 @@
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import { RolesResource } from './RolesResource';
|
||||
import { TeamsResource } from './TeamsResource';
|
||||
|
||||
@injectable()
|
||||
export class RolesManagerService {
|
||||
export class TeamsManagerService {
|
||||
constructor(
|
||||
readonly roles: RolesResource
|
||||
readonly teams: TeamsResource
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import {
|
||||
GraphQLService,
|
||||
CachedMapResource,
|
||||
ResourceKey,
|
||||
resourceKeyList,
|
||||
ResourceKeyList,
|
||||
ResourceKeyUtils,
|
||||
AdminTeamInfoFragment,
|
||||
AdminConnectionGrantInfo,
|
||||
CachedMapAllKey
|
||||
} from '@cloudbeaver/core-sdk';
|
||||
import { isArraysEqual } from '@cloudbeaver/core-utils';
|
||||
|
||||
const NEW_TEAM_SYMBOL = Symbol('new-team');
|
||||
|
||||
export type TeamInfo = AdminTeamInfoFragment;
|
||||
type NewTeam = TeamInfo & { [NEW_TEAM_SYMBOL]: boolean; timestamp: number };
|
||||
|
||||
@injectable()
|
||||
export class TeamsResource extends CachedMapResource<string, TeamInfo> {
|
||||
constructor(private readonly graphQLService: GraphQLService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async loadAll(): Promise<Map<string, TeamInfo>> {
|
||||
await this.load(CachedMapAllKey);
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async refreshAll(): Promise<Map<string, TeamInfo>> {
|
||||
await this.refresh(CachedMapAllKey);
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async createTeam(teamInfo: TeamInfo): Promise<TeamInfo> {
|
||||
const response = await this.graphQLService.sdk.createTeam(teamInfo);
|
||||
|
||||
const newTeam: NewTeam = {
|
||||
...response.team,
|
||||
[NEW_TEAM_SYMBOL]: true,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
this.updateTeams(newTeam);
|
||||
|
||||
await this.setSubjectPermissions(newTeam.teamId, teamInfo.teamPermissions);
|
||||
|
||||
return this.get(teamInfo.teamId)!;
|
||||
}
|
||||
|
||||
async updateTeam(teamInfo: TeamInfo): Promise<TeamInfo> {
|
||||
const { team } = await this.graphQLService.sdk.updateTeam(teamInfo);
|
||||
|
||||
this.updateTeams(team);
|
||||
|
||||
await this.setSubjectPermissions(team.teamId, teamInfo.teamPermissions);
|
||||
|
||||
return this.get(teamInfo.teamId)!;
|
||||
}
|
||||
|
||||
async deleteTeam(key: ResourceKey<string>): Promise<Map<string, TeamInfo>> {
|
||||
await ResourceKeyUtils.forEachAsync(key, async key => {
|
||||
await this.graphQLService.sdk.deleteTeam({
|
||||
teamId: key,
|
||||
});
|
||||
this.delete(key);
|
||||
});
|
||||
|
||||
return this.data;
|
||||
}
|
||||
|
||||
async loadGrantedUsers(teamId: string): Promise<string[]> {
|
||||
const { team } = await this.graphQLService.sdk.getTeamGrantedUsers({ teamId });
|
||||
return team[0].grantedUsers;
|
||||
}
|
||||
|
||||
async getSubjectConnectionAccess(subjectId: string): Promise<AdminConnectionGrantInfo[]> {
|
||||
const { grantInfo } = await this.graphQLService.sdk.getSubjectConnectionAccess({ subjectId });
|
||||
return grantInfo;
|
||||
}
|
||||
|
||||
async setSubjectPermissions(subjectId: string, permissions: string[]): Promise<void> {
|
||||
const team = this.get(subjectId);
|
||||
|
||||
if (team && isArraysEqual(team.teamPermissions, permissions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
permissions: newPermissions,
|
||||
} = await this.graphQLService.sdk.setSubjectPermissions({ subjectId, permissions });
|
||||
|
||||
if (team) {
|
||||
team.teamPermissions = newPermissions.map(permission => permission.id);
|
||||
} else {
|
||||
// TODO: update permissions for team instead
|
||||
await this.loader(subjectId);
|
||||
}
|
||||
}
|
||||
|
||||
protected async loader(key: ResourceKey<string>): Promise<Map<string, TeamInfo>> {
|
||||
const all = ResourceKeyUtils.includes(key, CachedMapAllKey);
|
||||
|
||||
await ResourceKeyUtils.forEachAsync(all ? CachedMapAllKey : key, async key => {
|
||||
const teamId = all ? undefined : key;
|
||||
|
||||
const { teams } = await this.graphQLService.sdk.getTeamsList({
|
||||
teamId,
|
||||
});
|
||||
|
||||
if (all) {
|
||||
this.data.clear();
|
||||
}
|
||||
|
||||
this.updateTeams(...teams);
|
||||
});
|
||||
|
||||
return this.data;
|
||||
}
|
||||
|
||||
cleanNewFlags(): void {
|
||||
for (const team of this.data.values()) {
|
||||
(team as NewTeam)[NEW_TEAM_SYMBOL] = false;
|
||||
}
|
||||
}
|
||||
|
||||
private updateTeams(...teams: TeamInfo[]): ResourceKeyList<string> {
|
||||
const key = resourceKeyList(teams.map(team => team.teamId));
|
||||
|
||||
const oldTeams = this.get(key);
|
||||
this.set(key, oldTeams.map((team, i) => ({ ...team, ...teams[i] })));
|
||||
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
function isNewTeam(team: TeamInfo | NewTeam): team is NewTeam {
|
||||
return (team as NewTeam)[NEW_TEAM_SYMBOL];
|
||||
}
|
||||
|
||||
export function compareTeams(a: TeamInfo, b: TeamInfo): number {
|
||||
if (isNewTeam(a) && isNewTeam(b)) {
|
||||
return b.timestamp - a.timestamp;
|
||||
}
|
||||
|
||||
if (isNewTeam(b)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (isNewTeam(a)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a.teamId.localeCompare(b.teamId);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ type UserResourceIncludes = Omit<GetUsersListQueryVariables, 'userId'>;
|
||||
|
||||
interface UserCreateOptions {
|
||||
userId: string;
|
||||
roles: string[];
|
||||
teams: string[];
|
||||
credentials: IAuthCredentials;
|
||||
metaParameters: Record<string, any>;
|
||||
grantedConnections: string[];
|
||||
@@ -66,7 +66,7 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
|
||||
getEmptyUser(): AdminUserInfo {
|
||||
return {
|
||||
userId: '',
|
||||
grantedRoles: [],
|
||||
grantedTeams: [],
|
||||
grantedConnections: [],
|
||||
configurationParameters: {},
|
||||
metaParameters: {},
|
||||
@@ -94,7 +94,7 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
|
||||
}
|
||||
|
||||
async create({
|
||||
userId, roles, credentials, metaParameters, grantedConnections, enabled,
|
||||
userId, teams, credentials, metaParameters, grantedConnections, enabled,
|
||||
}: UserCreateOptions): Promise<AdminUser> {
|
||||
const { user } = await this.graphQLService.sdk.createUser({
|
||||
userId,
|
||||
@@ -106,8 +106,8 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
|
||||
try {
|
||||
await this.updateCredentials(userId, credentials);
|
||||
|
||||
for (const roleId of roles) {
|
||||
await this.grantRole(userId, roleId, true);
|
||||
for (const teamId of teams) {
|
||||
await this.grantTeam(userId, teamId, true);
|
||||
}
|
||||
|
||||
await this.setConnections(userId, grantedConnections);
|
||||
@@ -122,16 +122,16 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
|
||||
return this.get(user.userId)!;
|
||||
}
|
||||
|
||||
async grantRole(userId: string, roleId: string, skipUpdate?: boolean): Promise<void> {
|
||||
await this.graphQLService.sdk.grantUserRole({ userId, roleId });
|
||||
async grantTeam(userId: string, teamId: string, skipUpdate?: boolean): Promise<void> {
|
||||
await this.graphQLService.sdk.grantUserTeam({ userId, teamId });
|
||||
|
||||
if (!skipUpdate) {
|
||||
await this.refresh(userId);
|
||||
}
|
||||
}
|
||||
|
||||
async revokeRole(userId: string, roleId: string, skipUpdate?: boolean): Promise<void> {
|
||||
await this.graphQLService.sdk.revokeUserRole({ userId, roleId });
|
||||
async revokeTeam(userId: string, teamId: string, skipUpdate?: boolean): Promise<void> {
|
||||
await this.graphQLService.sdk.revokeUserTeam({ userId, teamId });
|
||||
|
||||
if (!skipUpdate) {
|
||||
await this.refresh(userId);
|
||||
|
||||
@@ -9,8 +9,8 @@ export * from './DATA_CONTEXT_USER';
|
||||
export * from './IAuthCredentials';
|
||||
export * from './AuthConfigurationsResource';
|
||||
export * from './AuthConfigurationParametersResource';
|
||||
export * from './RolesManagerService';
|
||||
export * from './RolesResource';
|
||||
export * from './TeamsManagerService';
|
||||
export * from './TeamsResource';
|
||||
export * from './UserDataService';
|
||||
export * from './UserInfoResource';
|
||||
export * from './UserMetaParametersResource';
|
||||
|
||||
@@ -15,8 +15,8 @@ import { AuthInfoService } from './AuthInfoService';
|
||||
import { AuthProviderService } from './AuthProviderService';
|
||||
import { AuthProvidersResource } from './AuthProvidersResource';
|
||||
import { AuthSettingsService } from './AuthSettingsService';
|
||||
import { RolesManagerService } from './RolesManagerService';
|
||||
import { RolesResource } from './RolesResource';
|
||||
import { TeamsManagerService } from './TeamsManagerService';
|
||||
import { TeamsResource } from './TeamsResource';
|
||||
import { UserConfigurationBootstrap } from './UserConfigurationBootstrap';
|
||||
import { UserDataService } from './UserDataService';
|
||||
import { UserInfoResource } from './UserInfoResource';
|
||||
@@ -36,8 +36,8 @@ export const manifest: PluginManifest = {
|
||||
AuthSettingsService,
|
||||
AuthConfigurationsResource,
|
||||
AuthConfigurationParametersResource,
|
||||
RolesManagerService,
|
||||
RolesResource,
|
||||
TeamsManagerService,
|
||||
TeamsResource,
|
||||
UserDataService,
|
||||
UserInfoResource,
|
||||
UsersResource,
|
||||
|
||||
@@ -146,6 +146,7 @@ export * from './Link';
|
||||
export * from './Cell';
|
||||
export * from './UploadArea';
|
||||
export * from './ErrorMessage';
|
||||
export * from './preventFocusHandler';
|
||||
export * from './StatusMessage';
|
||||
export * from './ExceptionMessage';
|
||||
export * from './getComputed';
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export function preventFocusHandler(event: React.MouseEvent<HTMLElement>) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -5,7 +5,7 @@ export default [
|
||||
['connections_administration_new_connection', 'New connection'],
|
||||
['connections_administration_connection_create_error', 'Create connection error'],
|
||||
['connections_administration_connection_save_error', 'Save connection error'],
|
||||
['connections_administration_connection_access_empty', 'No available users and roles'],
|
||||
['connections_administration_connection_access_empty', 'No available users and teams'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Database connections'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Add database connections'],
|
||||
['connections_administration_configuration_wizard_title', 'Add database connections'],
|
||||
@@ -28,15 +28,15 @@ export default [
|
||||
['connections_connection_edit_authentication', 'Authentication'],
|
||||
['connections_connection_edit_access', 'Access'],
|
||||
['connections_connection_edit_access_load_failed', 'Fail to get connection access'],
|
||||
['connections_connection_edit_access_role', 'Role'],
|
||||
['connections_connection_edit_access_team', 'Team'],
|
||||
['connections_connection_edit_search', 'Search'],
|
||||
['connections_connection_edit_search_hosts', 'Host names'],
|
||||
['connections_connection_address', 'Address'],
|
||||
['connections_connection_folder', 'Folder'],
|
||||
['connections_connection_folder_validation', 'Folder\'s name may contain the following symbols "_-$.()@" and can\'t start with a dot'],
|
||||
['connections_connection_name', 'Connection name'],
|
||||
['connections_connection_access_user_or_role_name', 'User or Role name'],
|
||||
['connections_connection_access_filter_placeholder', 'Search for user or role name'],
|
||||
['connections_connection_access_user_or_team_name', 'User or Team name'],
|
||||
['connections_connection_access_filter_placeholder', 'Search for user or team name'],
|
||||
['connections_connection_access_admin_info', 'Administrators see all connections.'],
|
||||
['connections_connection_description', 'Description'],
|
||||
['connections_connection_project', 'Project'],
|
||||
|
||||
@@ -5,7 +5,6 @@ export default [
|
||||
['connections_administration_new_connection', 'Nuova Connessione'],
|
||||
['connections_administration_connection_create_error', 'Errore di creazione connessione'],
|
||||
['connections_administration_connection_save_error', 'Errore di salvataggio connessione'],
|
||||
['connections_administration_connection_access_empty', 'Non ci sono utenti e ruoli disponibili'],
|
||||
['connections_administration_configuration_wizard_step_title', 'Connessioni ai Database'],
|
||||
['connections_administration_configuration_wizard_step_description', 'Aggiungi connessione al database'],
|
||||
['connections_administration_configuration_wizard_title', 'Aggiungi connessione al database'],
|
||||
@@ -27,18 +26,15 @@ export default [
|
||||
['connections_connection_edit_authentication', 'Autenticazione'],
|
||||
['connections_connection_edit_access', 'Accesso'],
|
||||
['connections_connection_edit_access_load_failed', 'Errore al recupero dell\'accesso alla connessione'],
|
||||
['connections_connection_edit_access_role', 'Ruolo'],
|
||||
['connections_connection_edit_search', 'Cerca'],
|
||||
['connections_connection_edit_search_hosts', 'Host names'],
|
||||
['connections_connection_address', 'Indirizzo'],
|
||||
['connections_connection_folder', 'Folder'],
|
||||
['connections_connection_folder_validation', 'Folder\'s name may contain the following symbols "_-$.()@" and can\'t start with a dot'],
|
||||
['connections_connection_name', 'Nome della connessione'],
|
||||
['connections_connection_access_user_or_role_name', 'Nome dell\'Utente o del ruolo'],
|
||||
['connections_connection_access_revoke', 'Revoca'],
|
||||
['connections_connection_access_grant', 'Permetti'],
|
||||
['connections_connection_access_edit', 'Modifica'],
|
||||
['connections_connection_access_filter_placeholder', 'Cerca per utente o ruolo'],
|
||||
['connections_connection_access_admin_info', 'Gli amministratori vedono tutte le connessioni.'],
|
||||
['connections_connection_description', 'Descrizione'],
|
||||
['connections_connection_driver', 'Driver'],
|
||||
|
||||
@@ -25,15 +25,15 @@ export default [
|
||||
['connections_connection_edit_authentication', 'Авторизация'],
|
||||
['connections_connection_edit_access', 'Доступ'],
|
||||
['connections_connection_edit_access_load_failed', 'Не удалось загрузить информацию доступа'],
|
||||
['connections_connection_edit_access_role', 'Роль'],
|
||||
['connections_connection_edit_access_team', 'Команда'],
|
||||
['connections_connection_edit_search', 'Поиск'],
|
||||
['connections_connection_edit_search_hosts', 'Названия хостов'],
|
||||
['connections_connection_address', 'Адрес'],
|
||||
['connections_connection_folder', 'Папка'],
|
||||
['connections_connection_folder_validation', 'Имя папки может содержать следующие символы "_-$.()@" и не может начинаться с точки'],
|
||||
['connections_connection_name', 'Название подключения'],
|
||||
['connections_connection_access_user_or_role_name', 'Имя пользователя или роли'],
|
||||
['connections_connection_access_filter_placeholder', 'Поиск по имени пользователя или роли'],
|
||||
['connections_connection_access_user_or_team_name', 'Имя пользователя или команды'],
|
||||
['connections_connection_access_filter_placeholder', 'Поиск по имени пользователя или команде'],
|
||||
['connections_connection_access_admin_info', 'Администраторы видят все подключения.'],
|
||||
['connections_connection_description', 'Описание'],
|
||||
['connections_connection_project', 'Проект'],
|
||||
|
||||
@@ -5,7 +5,6 @@ export default [
|
||||
['connections_administration_new_connection', '新连接'],
|
||||
['connections_administration_connection_create_error', '创建连接失败'],
|
||||
['connections_administration_connection_save_error', '保存链接失败'],
|
||||
['connections_administration_connection_access_empty', '没有可用用户和角色'],
|
||||
['connections_administration_configuration_wizard_step_title', '数据库连接'],
|
||||
['connections_administration_configuration_wizard_step_description', '添加数据库连接'],
|
||||
['connections_administration_configuration_wizard_title', '添加数据库连接'],
|
||||
@@ -28,15 +27,12 @@ export default [
|
||||
['connections_connection_edit_authentication', '认证'],
|
||||
['connections_connection_edit_access', '权限'],
|
||||
['connections_connection_edit_access_load_failed', '无法获取连接访问权限'],
|
||||
['connections_connection_edit_access_role', '角色'],
|
||||
['connections_connection_edit_search', '搜索'],
|
||||
['connections_connection_edit_search_hosts', '主机名称'],
|
||||
['connections_connection_address', '地址'],
|
||||
['connections_connection_folder', 'Folder'],
|
||||
['connections_connection_folder_validation', 'Folder\'s name may contain the following symbols "_-$.()@" and can\'t start with a dot'],
|
||||
['connections_connection_name', '连接名称'],
|
||||
['connections_connection_access_user_or_role_name', '用户或角色名称'],
|
||||
['connections_connection_access_filter_placeholder', '搜索用户或角色名称'],
|
||||
['connections_connection_access_admin_info', '管理员查看所有连接。'],
|
||||
['connections_connection_description', '描述'],
|
||||
['connections_connection_project', 'Project'],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
query setSubjectPermissions($roleId: ID!, $permissions: [ID!]! ) {
|
||||
permissions: setSubjectPermissions(roleId: $roleId, permissions: $permissions) {
|
||||
query setSubjectPermissions($subjectId: ID!, $permissions: [ID!]! ) {
|
||||
permissions: setSubjectPermissions(subjectId: $subjectId, permissions: $permissions) {
|
||||
...AdminPermissionInfo
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
query createRole($roleId: ID!, $roleName: String, $description: String ) {
|
||||
role: createRole(roleId: $roleId, roleName: $roleName, description: $description) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
query deleteRole($roleId: ID!) {
|
||||
deleteRole(roleId: $roleId)
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
query getRoleGrantedUsers($roleId: ID!) {
|
||||
role: listRoles(roleId: $roleId) {
|
||||
grantedUsers
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
query getRolesList($roleId: ID) {
|
||||
roles: listRoles(roleId: $roleId) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
query updateRole($roleId: ID!, $roleName: String, $description: String ) {
|
||||
role: updateRole(roleId: $roleId, roleName: $roleName, description: $description) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query createTeam($teamId: ID!, $teamName: String, $description: String ) {
|
||||
team: createTeam(teamId: $teamId, teamName: $teamName, description: $description) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
query deleteTeam($teamId: ID!) {
|
||||
deleteTeam(teamId: $teamId)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query getTeamGrantedUsers($teamId: ID!) {
|
||||
team: listTeams(teamId: $teamId) {
|
||||
grantedUsers
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query getTeamsList($teamId: ID) {
|
||||
teams: listTeams(teamId: $teamId) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
query updateTeam($teamId: ID!, $teamName: String, $description: String ) {
|
||||
team: updateTeam(teamId: $teamId, teamName: $teamName, description: $description) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
query grantUserRole($userId: ID!, $roleId: ID!) {
|
||||
grantUserRole(userId: $userId, roleId: $roleId)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
query grantUserTeam($userId: ID!, $teamId: ID!) {
|
||||
grantUserTeam(userId: $userId, teamId: $teamId)
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
query revokeUserRole($userId: ID!, $roleId: ID!) {
|
||||
revokeUserRole(userId: $userId, roleId: $roleId)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
query revokeUserTeam($userId: ID!, $teamId: ID!) {
|
||||
revokeUserTeam(userId: $userId, teamId: $teamId)
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
fragment AdminRoleInfo on AdminRoleInfo {
|
||||
roleId
|
||||
roleName
|
||||
description
|
||||
rolePermissions
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fragment AdminTeamInfo on AdminTeamInfo {
|
||||
teamId
|
||||
teamName
|
||||
description
|
||||
teamPermissions
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
fragment AdminUserInfo on AdminUserInfo {
|
||||
userId
|
||||
grantedRoles
|
||||
grantedTeams
|
||||
linkedAuthProviders
|
||||
metaParameters @include(if: $includeMetaParameters)
|
||||
|
||||
|
||||
+158
-155
@@ -66,25 +66,25 @@ export interface AdminPermissionInfo {
|
||||
provider: Scalars['String'];
|
||||
}
|
||||
|
||||
export interface AdminRoleInfo {
|
||||
export enum AdminSubjectType {
|
||||
Team = 'team',
|
||||
User = 'user'
|
||||
}
|
||||
|
||||
export interface AdminTeamInfo {
|
||||
description?: Maybe<Scalars['String']>;
|
||||
grantedConnections: Array<AdminConnectionGrantInfo>;
|
||||
grantedUsers: Array<Scalars['ID']>;
|
||||
roleId: Scalars['ID'];
|
||||
roleName?: Maybe<Scalars['String']>;
|
||||
rolePermissions: Array<Scalars['ID']>;
|
||||
}
|
||||
|
||||
export enum AdminSubjectType {
|
||||
Role = 'role',
|
||||
User = 'user'
|
||||
teamId: Scalars['ID'];
|
||||
teamName?: Maybe<Scalars['String']>;
|
||||
teamPermissions: Array<Scalars['ID']>;
|
||||
}
|
||||
|
||||
export interface AdminUserInfo {
|
||||
configurationParameters: Scalars['Object'];
|
||||
enabled: Scalars['Boolean'];
|
||||
grantedConnections: Array<AdminConnectionGrantInfo>;
|
||||
grantedRoles: Array<Scalars['ID']>;
|
||||
grantedTeams: Array<Scalars['ID']>;
|
||||
linkedAuthProviders: Array<Scalars['String']>;
|
||||
metaParameters: Scalars['Object'];
|
||||
origins: Array<ObjectOrigin>;
|
||||
@@ -877,7 +877,7 @@ export interface Query {
|
||||
connectionInfo: ConnectionInfo;
|
||||
copyConnectionConfiguration: ConnectionInfo;
|
||||
createConnectionConfiguration: ConnectionInfo;
|
||||
createRole: AdminRoleInfo;
|
||||
createTeam: AdminTeamInfo;
|
||||
createUser: AdminUserInfo;
|
||||
dataTransferAvailableStreamProcessors: Array<DataTransferProcessorInfo>;
|
||||
dataTransferDefaultExportSettings: DataTransferDefaultExportSettings;
|
||||
@@ -886,20 +886,20 @@ export interface Query {
|
||||
dataTransferRemoveDataFile?: Maybe<Scalars['Boolean']>;
|
||||
deleteAuthProviderConfiguration: Scalars['Boolean'];
|
||||
deleteConnectionConfiguration?: Maybe<Scalars['Boolean']>;
|
||||
deleteRole?: Maybe<Scalars['Boolean']>;
|
||||
deleteTeam?: Maybe<Scalars['Boolean']>;
|
||||
deleteUser?: Maybe<Scalars['Boolean']>;
|
||||
deleteUserMetaParameter: Scalars['Boolean'];
|
||||
driverList: Array<DriverInfo>;
|
||||
enableUser?: Maybe<Scalars['Boolean']>;
|
||||
getConnectionSubjectAccess: Array<AdminConnectionGrantInfo>;
|
||||
getSubjectConnectionAccess: Array<AdminConnectionGrantInfo>;
|
||||
grantUserRole?: Maybe<Scalars['Boolean']>;
|
||||
grantUserTeam?: Maybe<Scalars['Boolean']>;
|
||||
listAuthProviderConfigurationParameters: Array<ObjectPropertyInfo>;
|
||||
listAuthProviderConfigurations: Array<AdminAuthProviderConfiguration>;
|
||||
listFeatureSets: Array<WebFeatureSet>;
|
||||
listPermissions: Array<AdminPermissionInfo>;
|
||||
listProjects: Array<ProjectInfo>;
|
||||
listRoles: Array<AdminRoleInfo>;
|
||||
listTeams: Array<AdminTeamInfo>;
|
||||
listUserProfileProperties: Array<ObjectPropertyInfo>;
|
||||
listUsers: Array<AdminUserInfo>;
|
||||
metadataGetNodeDDL?: Maybe<Scalars['String']>;
|
||||
@@ -910,7 +910,7 @@ export interface Query {
|
||||
navRefreshNode?: Maybe<Scalars['Boolean']>;
|
||||
networkHandlers: Array<NetworkHandlerDescriptor>;
|
||||
readSessionLog: Array<LogEntry>;
|
||||
revokeUserRole?: Maybe<Scalars['Boolean']>;
|
||||
revokeUserTeam?: Maybe<Scalars['Boolean']>;
|
||||
rmListProjectGrantedPermissions: Array<AdminObjectGrantInfo>;
|
||||
rmListProjectPermissions: Array<AdminPermissionInfo>;
|
||||
rmListProjects: Array<RmProject>;
|
||||
@@ -942,7 +942,7 @@ export interface Query {
|
||||
sqlSupportedOperations: Array<DataTypeLogicalOperation>;
|
||||
templateConnections: Array<ConnectionInfo>;
|
||||
updateConnectionConfiguration: ConnectionInfo;
|
||||
updateRole: AdminRoleInfo;
|
||||
updateTeam: AdminTeamInfo;
|
||||
userConnections: Array<ConnectionInfo>;
|
||||
}
|
||||
|
||||
@@ -1006,10 +1006,10 @@ export interface QueryCreateConnectionConfigurationArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryCreateRoleArgs {
|
||||
export interface QueryCreateTeamArgs {
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
roleId: Scalars['ID'];
|
||||
roleName?: InputMaybe<Scalars['String']>;
|
||||
teamId: Scalars['ID'];
|
||||
teamName?: InputMaybe<Scalars['String']>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1051,8 +1051,8 @@ export interface QueryDeleteConnectionConfigurationArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryDeleteRoleArgs {
|
||||
roleId: Scalars['ID'];
|
||||
export interface QueryDeleteTeamArgs {
|
||||
teamId: Scalars['ID'];
|
||||
}
|
||||
|
||||
|
||||
@@ -1088,8 +1088,8 @@ export interface QueryGetSubjectConnectionAccessArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryGrantUserRoleArgs {
|
||||
roleId: Scalars['ID'];
|
||||
export interface QueryGrantUserTeamArgs {
|
||||
teamId: Scalars['ID'];
|
||||
userId: Scalars['ID'];
|
||||
}
|
||||
|
||||
@@ -1104,8 +1104,8 @@ export interface QueryListAuthProviderConfigurationsArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryListRolesArgs {
|
||||
roleId?: InputMaybe<Scalars['ID']>;
|
||||
export interface QueryListTeamsArgs {
|
||||
teamId?: InputMaybe<Scalars['ID']>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1157,8 +1157,8 @@ export interface QueryReadSessionLogArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryRevokeUserRoleArgs {
|
||||
roleId: Scalars['ID'];
|
||||
export interface QueryRevokeUserTeamArgs {
|
||||
teamId: Scalars['ID'];
|
||||
userId: Scalars['ID'];
|
||||
}
|
||||
|
||||
@@ -1237,7 +1237,7 @@ export interface QuerySetSubjectConnectionAccessArgs {
|
||||
|
||||
export interface QuerySetSubjectPermissionsArgs {
|
||||
permissions: Array<Scalars['ID']>;
|
||||
roleId: Scalars['ID'];
|
||||
subjectId: Scalars['ID'];
|
||||
}
|
||||
|
||||
|
||||
@@ -1333,10 +1333,10 @@ export interface QueryUpdateConnectionConfigurationArgs {
|
||||
}
|
||||
|
||||
|
||||
export interface QueryUpdateRoleArgs {
|
||||
export interface QueryUpdateTeamArgs {
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
roleId: Scalars['ID'];
|
||||
roleName?: InputMaybe<Scalars['String']>;
|
||||
teamId: Scalars['ID'];
|
||||
teamName?: InputMaybe<Scalars['String']>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1629,7 +1629,7 @@ export type GetPermissionsListQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
export type GetPermissionsListQuery = { permissions: Array<{ id: string, label?: string, description?: string, category?: string }> };
|
||||
|
||||
export type SetSubjectPermissionsQueryVariables = Exact<{
|
||||
roleId: Scalars['ID'];
|
||||
subjectId: Scalars['ID'];
|
||||
permissions: Array<Scalars['ID']> | Scalars['ID'];
|
||||
}>;
|
||||
|
||||
@@ -1643,45 +1643,6 @@ export type AsyncTaskCancelMutationVariables = Exact<{
|
||||
|
||||
export type AsyncTaskCancelMutation = { result?: boolean };
|
||||
|
||||
export type CreateRoleQueryVariables = Exact<{
|
||||
roleId: Scalars['ID'];
|
||||
roleName?: InputMaybe<Scalars['String']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateRoleQuery = { role: { roleId: string, roleName?: string, description?: string, rolePermissions: Array<string> } };
|
||||
|
||||
export type DeleteRoleQueryVariables = Exact<{
|
||||
roleId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type DeleteRoleQuery = { deleteRole?: boolean };
|
||||
|
||||
export type GetRoleGrantedUsersQueryVariables = Exact<{
|
||||
roleId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetRoleGrantedUsersQuery = { role: Array<{ grantedUsers: Array<string> }> };
|
||||
|
||||
export type GetRolesListQueryVariables = Exact<{
|
||||
roleId?: InputMaybe<Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetRolesListQuery = { roles: Array<{ roleId: string, roleName?: string, description?: string, rolePermissions: Array<string> }> };
|
||||
|
||||
export type UpdateRoleQueryVariables = Exact<{
|
||||
roleId: Scalars['ID'];
|
||||
roleName?: InputMaybe<Scalars['String']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateRoleQuery = { role: { roleId: string, roleName?: string, description?: string, rolePermissions: Array<string> } };
|
||||
|
||||
export type AuthChangeLocalPasswordQueryVariables = Exact<{
|
||||
oldPassword: Scalars['String'];
|
||||
newPassword: Scalars['String'];
|
||||
@@ -1776,6 +1737,45 @@ export type SaveUserMetaParametersQueryVariables = Exact<{
|
||||
|
||||
export type SaveUserMetaParametersQuery = { setUserMetaParameterValues: boolean };
|
||||
|
||||
export type CreateTeamQueryVariables = Exact<{
|
||||
teamId: Scalars['ID'];
|
||||
teamName?: InputMaybe<Scalars['String']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateTeamQuery = { team: { teamId: string, teamName?: string, description?: string, teamPermissions: Array<string> } };
|
||||
|
||||
export type DeleteTeamQueryVariables = Exact<{
|
||||
teamId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type DeleteTeamQuery = { deleteTeam?: boolean };
|
||||
|
||||
export type GetTeamGrantedUsersQueryVariables = Exact<{
|
||||
teamId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTeamGrantedUsersQuery = { team: Array<{ grantedUsers: Array<string> }> };
|
||||
|
||||
export type GetTeamsListQueryVariables = Exact<{
|
||||
teamId?: InputMaybe<Scalars['ID']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTeamsListQuery = { teams: Array<{ teamId: string, teamName?: string, description?: string, teamPermissions: Array<string> }> };
|
||||
|
||||
export type UpdateTeamQueryVariables = Exact<{
|
||||
teamId: Scalars['ID'];
|
||||
teamName?: InputMaybe<Scalars['String']>;
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateTeamQuery = { team: { teamId: string, teamName?: string, description?: string, teamPermissions: Array<string> } };
|
||||
|
||||
export type CreateUserQueryVariables = Exact<{
|
||||
userId: Scalars['ID'];
|
||||
enabled: Scalars['Boolean'];
|
||||
@@ -1784,7 +1784,7 @@ export type CreateUserQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateUserQuery = { user: { userId: string, grantedRoles: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> } };
|
||||
export type CreateUserQuery = { user: { userId: string, grantedTeams: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> } };
|
||||
|
||||
export type DeleteUserQueryVariables = Exact<{
|
||||
userId: Scalars['ID'];
|
||||
@@ -1822,23 +1822,23 @@ export type GetUsersListQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetUsersListQuery = { users: Array<{ userId: string, grantedRoles: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> }> };
|
||||
export type GetUsersListQuery = { users: Array<{ userId: string, grantedTeams: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> }> };
|
||||
|
||||
export type GrantUserRoleQueryVariables = Exact<{
|
||||
export type GrantUserTeamQueryVariables = Exact<{
|
||||
userId: Scalars['ID'];
|
||||
roleId: Scalars['ID'];
|
||||
teamId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GrantUserRoleQuery = { grantUserRole?: boolean };
|
||||
export type GrantUserTeamQuery = { grantUserTeam?: boolean };
|
||||
|
||||
export type RevokeUserRoleQueryVariables = Exact<{
|
||||
export type RevokeUserTeamQueryVariables = Exact<{
|
||||
userId: Scalars['ID'];
|
||||
roleId: Scalars['ID'];
|
||||
teamId: Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type RevokeUserRoleQuery = { revokeUserRole?: boolean };
|
||||
export type RevokeUserTeamQuery = { revokeUserTeam?: boolean };
|
||||
|
||||
export type SetConnectionsQueryVariables = Exact<{
|
||||
userId: Scalars['ID'];
|
||||
@@ -2247,9 +2247,9 @@ export type AdminObjectGrantInfoFragment = { subjectId: string, subjectType: Adm
|
||||
|
||||
export type AdminPermissionInfoFragment = { id: string, label?: string, description?: string, category?: string };
|
||||
|
||||
export type AdminRoleInfoFragment = { roleId: string, roleName?: string, description?: string, rolePermissions: Array<string> };
|
||||
export type AdminTeamInfoFragment = { teamId: string, teamName?: string, description?: string, teamPermissions: Array<string> };
|
||||
|
||||
export type AdminUserInfoFragment = { userId: string, grantedRoles: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> };
|
||||
export type AdminUserInfoFragment = { userId: string, grantedTeams: Array<string>, linkedAuthProviders: Array<string>, metaParameters?: any, enabled: boolean, origins: Array<{ type: string, subType?: string, displayName: string, icon?: string, details?: Array<{ id?: string, displayName?: string, description?: string, category?: string, dataType?: string, defaultValue?: any, validValues?: Array<any>, value?: any, length: ObjectPropertyLength, features: Array<string>, order: number }> }> };
|
||||
|
||||
export type AllNavigatorSettingsFragment = { showSystemObjects: boolean, showUtilityObjects: boolean, showOnlyEntities: boolean, mergeEntities: boolean, hideFolders: boolean, hideSchemas: boolean, hideVirtualModel: boolean };
|
||||
|
||||
@@ -2753,12 +2753,12 @@ export const AdminPermissionInfoFragmentDoc = `
|
||||
category
|
||||
}
|
||||
`;
|
||||
export const AdminRoleInfoFragmentDoc = `
|
||||
fragment AdminRoleInfo on AdminRoleInfo {
|
||||
roleId
|
||||
roleName
|
||||
export const AdminTeamInfoFragmentDoc = `
|
||||
fragment AdminTeamInfo on AdminTeamInfo {
|
||||
teamId
|
||||
teamName
|
||||
description
|
||||
rolePermissions
|
||||
teamPermissions
|
||||
}
|
||||
`;
|
||||
export const ObjectOriginInfoFragmentDoc = `
|
||||
@@ -2785,7 +2785,7 @@ export const ObjectOriginInfoFragmentDoc = `
|
||||
export const AdminUserInfoFragmentDoc = `
|
||||
fragment AdminUserInfo on AdminUserInfo {
|
||||
userId
|
||||
grantedRoles
|
||||
grantedTeams
|
||||
linkedAuthProviders
|
||||
metaParameters @include(if: $includeMetaParameters)
|
||||
origins {
|
||||
@@ -3111,8 +3111,11 @@ export const GetPermissionsListDocument = `
|
||||
}
|
||||
${AdminPermissionInfoFragmentDoc}`;
|
||||
export const SetSubjectPermissionsDocument = `
|
||||
query setSubjectPermissions($roleId: ID!, $permissions: [ID!]!) {
|
||||
permissions: setSubjectPermissions(roleId: $roleId, permissions: $permissions) {
|
||||
query setSubjectPermissions($subjectId: ID!, $permissions: [ID!]!) {
|
||||
permissions: setSubjectPermissions(
|
||||
subjectId: $subjectId
|
||||
permissions: $permissions
|
||||
) {
|
||||
...AdminPermissionInfo
|
||||
}
|
||||
}
|
||||
@@ -3122,47 +3125,6 @@ export const AsyncTaskCancelDocument = `
|
||||
result: asyncTaskCancel(id: $taskId)
|
||||
}
|
||||
`;
|
||||
export const CreateRoleDocument = `
|
||||
query createRole($roleId: ID!, $roleName: String, $description: String) {
|
||||
role: createRole(
|
||||
roleId: $roleId
|
||||
roleName: $roleName
|
||||
description: $description
|
||||
) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
${AdminRoleInfoFragmentDoc}`;
|
||||
export const DeleteRoleDocument = `
|
||||
query deleteRole($roleId: ID!) {
|
||||
deleteRole(roleId: $roleId)
|
||||
}
|
||||
`;
|
||||
export const GetRoleGrantedUsersDocument = `
|
||||
query getRoleGrantedUsers($roleId: ID!) {
|
||||
role: listRoles(roleId: $roleId) {
|
||||
grantedUsers
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const GetRolesListDocument = `
|
||||
query getRolesList($roleId: ID) {
|
||||
roles: listRoles(roleId: $roleId) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
${AdminRoleInfoFragmentDoc}`;
|
||||
export const UpdateRoleDocument = `
|
||||
query updateRole($roleId: ID!, $roleName: String, $description: String) {
|
||||
role: updateRole(
|
||||
roleId: $roleId
|
||||
roleName: $roleName
|
||||
description: $description
|
||||
) {
|
||||
...AdminRoleInfo
|
||||
}
|
||||
}
|
||||
${AdminRoleInfoFragmentDoc}`;
|
||||
export const AuthChangeLocalPasswordDocument = `
|
||||
query authChangeLocalPassword($oldPassword: String!, $newPassword: String!) {
|
||||
authChangeLocalPassword(oldPassword: $oldPassword, newPassword: $newPassword)
|
||||
@@ -3289,6 +3251,47 @@ export const SaveUserMetaParametersDocument = `
|
||||
setUserMetaParameterValues(userId: $userId, parameters: $parameters)
|
||||
}
|
||||
`;
|
||||
export const CreateTeamDocument = `
|
||||
query createTeam($teamId: ID!, $teamName: String, $description: String) {
|
||||
team: createTeam(
|
||||
teamId: $teamId
|
||||
teamName: $teamName
|
||||
description: $description
|
||||
) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
${AdminTeamInfoFragmentDoc}`;
|
||||
export const DeleteTeamDocument = `
|
||||
query deleteTeam($teamId: ID!) {
|
||||
deleteTeam(teamId: $teamId)
|
||||
}
|
||||
`;
|
||||
export const GetTeamGrantedUsersDocument = `
|
||||
query getTeamGrantedUsers($teamId: ID!) {
|
||||
team: listTeams(teamId: $teamId) {
|
||||
grantedUsers
|
||||
}
|
||||
}
|
||||
`;
|
||||
export const GetTeamsListDocument = `
|
||||
query getTeamsList($teamId: ID) {
|
||||
teams: listTeams(teamId: $teamId) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
${AdminTeamInfoFragmentDoc}`;
|
||||
export const UpdateTeamDocument = `
|
||||
query updateTeam($teamId: ID!, $teamName: String, $description: String) {
|
||||
team: updateTeam(
|
||||
teamId: $teamId
|
||||
teamName: $teamName
|
||||
description: $description
|
||||
) {
|
||||
...AdminTeamInfo
|
||||
}
|
||||
}
|
||||
${AdminTeamInfoFragmentDoc}`;
|
||||
export const CreateUserDocument = `
|
||||
query createUser($userId: ID!, $enabled: Boolean!, $includeMetaParameters: Boolean!, $customIncludeOriginDetails: Boolean!) {
|
||||
user: createUser(userId: $userId, enabled: $enabled) {
|
||||
@@ -3328,14 +3331,14 @@ export const GetUsersListDocument = `
|
||||
}
|
||||
}
|
||||
${AdminUserInfoFragmentDoc}`;
|
||||
export const GrantUserRoleDocument = `
|
||||
query grantUserRole($userId: ID!, $roleId: ID!) {
|
||||
grantUserRole(userId: $userId, roleId: $roleId)
|
||||
export const GrantUserTeamDocument = `
|
||||
query grantUserTeam($userId: ID!, $teamId: ID!) {
|
||||
grantUserTeam(userId: $userId, teamId: $teamId)
|
||||
}
|
||||
`;
|
||||
export const RevokeUserRoleDocument = `
|
||||
query revokeUserRole($userId: ID!, $roleId: ID!) {
|
||||
revokeUserRole(userId: $userId, roleId: $roleId)
|
||||
export const RevokeUserTeamDocument = `
|
||||
query revokeUserTeam($userId: ID!, $teamId: ID!) {
|
||||
revokeUserTeam(userId: $userId, teamId: $teamId)
|
||||
}
|
||||
`;
|
||||
export const SetConnectionsDocument = `
|
||||
@@ -4399,21 +4402,6 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
asyncTaskCancel(variables: AsyncTaskCancelMutationVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<AsyncTaskCancelMutation> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<AsyncTaskCancelMutation>(AsyncTaskCancelDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'asyncTaskCancel', 'mutation');
|
||||
},
|
||||
createRole(variables: CreateRoleQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<CreateRoleQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<CreateRoleQuery>(CreateRoleDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'createRole', 'query');
|
||||
},
|
||||
deleteRole(variables: DeleteRoleQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<DeleteRoleQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<DeleteRoleQuery>(DeleteRoleDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'deleteRole', 'query');
|
||||
},
|
||||
getRoleGrantedUsers(variables: GetRoleGrantedUsersQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetRoleGrantedUsersQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetRoleGrantedUsersQuery>(GetRoleGrantedUsersDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getRoleGrantedUsers', 'query');
|
||||
},
|
||||
getRolesList(variables?: GetRolesListQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetRolesListQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetRolesListQuery>(GetRolesListDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getRolesList', 'query');
|
||||
},
|
||||
updateRole(variables: UpdateRoleQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<UpdateRoleQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<UpdateRoleQuery>(UpdateRoleDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'updateRole', 'query');
|
||||
},
|
||||
authChangeLocalPassword(variables: AuthChangeLocalPasswordQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<AuthChangeLocalPasswordQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<AuthChangeLocalPasswordQuery>(AuthChangeLocalPasswordDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'authChangeLocalPassword', 'query');
|
||||
},
|
||||
@@ -4450,6 +4438,21 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
saveUserMetaParameters(variables: SaveUserMetaParametersQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<SaveUserMetaParametersQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<SaveUserMetaParametersQuery>(SaveUserMetaParametersDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'saveUserMetaParameters', 'query');
|
||||
},
|
||||
createTeam(variables: CreateTeamQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<CreateTeamQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<CreateTeamQuery>(CreateTeamDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'createTeam', 'query');
|
||||
},
|
||||
deleteTeam(variables: DeleteTeamQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<DeleteTeamQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<DeleteTeamQuery>(DeleteTeamDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'deleteTeam', 'query');
|
||||
},
|
||||
getTeamGrantedUsers(variables: GetTeamGrantedUsersQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetTeamGrantedUsersQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetTeamGrantedUsersQuery>(GetTeamGrantedUsersDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTeamGrantedUsers', 'query');
|
||||
},
|
||||
getTeamsList(variables?: GetTeamsListQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetTeamsListQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetTeamsListQuery>(GetTeamsListDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTeamsList', 'query');
|
||||
},
|
||||
updateTeam(variables: UpdateTeamQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<UpdateTeamQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<UpdateTeamQuery>(UpdateTeamDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'updateTeam', 'query');
|
||||
},
|
||||
createUser(variables: CreateUserQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<CreateUserQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<CreateUserQuery>(CreateUserDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'createUser', 'query');
|
||||
},
|
||||
@@ -4468,11 +4471,11 @@ export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper =
|
||||
getUsersList(variables: GetUsersListQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GetUsersListQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GetUsersListQuery>(GetUsersListDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getUsersList', 'query');
|
||||
},
|
||||
grantUserRole(variables: GrantUserRoleQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GrantUserRoleQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GrantUserRoleQuery>(GrantUserRoleDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'grantUserRole', 'query');
|
||||
grantUserTeam(variables: GrantUserTeamQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<GrantUserTeamQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<GrantUserTeamQuery>(GrantUserTeamDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'grantUserTeam', 'query');
|
||||
},
|
||||
revokeUserRole(variables: RevokeUserRoleQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<RevokeUserRoleQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<RevokeUserRoleQuery>(RevokeUserRoleDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'revokeUserRole', 'query');
|
||||
revokeUserTeam(variables: RevokeUserTeamQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<RevokeUserTeamQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<RevokeUserTeamQuery>(RevokeUserTeamDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'revokeUserTeam', 'query');
|
||||
},
|
||||
setConnections(variables: SetConnectionsQueryVariables, requestHeaders?: Dom.RequestInit["headers"]): Promise<SetConnectionsQuery> {
|
||||
return withWrapper((wrappedRequestHeaders) => client.request<SetConnectionsQuery>(SetConnectionsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'setConnections', 'query');
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"@timohausmann/quadtree-ts": "~2.0.0-beta.1",
|
||||
"clsx": "~1.2.1",
|
||||
"md5": "~2.3.0",
|
||||
"uuid": "~9.0.0"
|
||||
"uuid": "~9.0.0",
|
||||
"fast-deep-equal": "~3.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"mobx": "~6.x.x"
|
||||
|
||||
@@ -17,7 +17,7 @@ export class MetadataMap<TKey, TValue> {
|
||||
|
||||
private syncData: Array<[TKey, TValue]> | null;
|
||||
|
||||
constructor(private defaultValueGetter?: DefaultValueGetter<TKey, TValue>) {
|
||||
constructor(private readonly defaultValueGetter?: DefaultValueGetter<TKey, TValue>) {
|
||||
this.data = observable(new Map());
|
||||
this.length = 0;
|
||||
this.syncData = null;
|
||||
@@ -74,7 +74,7 @@ export class MetadataMap<TKey, TValue> {
|
||||
|
||||
const value = provider(key, this);
|
||||
untracked(() => {
|
||||
this.set(key, value);
|
||||
this.set(key, observable(value as any));
|
||||
this.length++;
|
||||
});
|
||||
return this.data.get(key)!;
|
||||
|
||||
@@ -34,6 +34,7 @@ export * from './isImageFormat';
|
||||
export * from './getCookies';
|
||||
export * from './getUniqueName';
|
||||
export * from './isMapsEqual';
|
||||
export * from './isObjectsEqual';
|
||||
export * from './openCenteredPopup';
|
||||
export * from './download';
|
||||
export * from './getTextFileReadingProcess';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import isEqual from 'fast-deep-equal';
|
||||
|
||||
export function isObjectsEqual(
|
||||
a: any,
|
||||
b: any
|
||||
): boolean {
|
||||
return isEqual(a, b);
|
||||
}
|
||||
+1
-1
@@ -118,7 +118,7 @@ export const MetaParameters = observer<Props>(function MetaParameters({ sub, par
|
||||
)}
|
||||
<TableColumnHeader min />
|
||||
<TableColumnHeader>{translate('authentication_user_name')}</TableColumnHeader>
|
||||
<TableColumnHeader>{translate('authentication_user_role')}</TableColumnHeader>
|
||||
<TableColumnHeader>{translate('authentication_user_team')}</TableColumnHeader>
|
||||
<TableColumnHeader />
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { RoleInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
|
||||
import type { IRoleFormState } from '../IRoleFormProps';
|
||||
|
||||
export interface IRoleFormConfigureContext {
|
||||
readonly info: RoleInfo | undefined;
|
||||
}
|
||||
|
||||
export function roleFormConfigureContext(
|
||||
contexts: IExecutionContextProvider<IRoleFormState>,
|
||||
state: IRoleFormState
|
||||
): IRoleFormConfigureContext {
|
||||
return {
|
||||
info: state.info,
|
||||
};
|
||||
}
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { RolesResource } from '@cloudbeaver/core-authentication';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { getUniqueName } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { roleContext } from '../Contexts/roleContext';
|
||||
import type { IRoleFormFillConfigData, IRoleFormSubmitData } from '../IRoleFormProps';
|
||||
import { RoleFormService } from '../RoleFormService';
|
||||
import { RoleOptions } from './RoleOptions';
|
||||
|
||||
@injectable()
|
||||
export class RoleOptionsTabService extends Bootstrap {
|
||||
constructor(
|
||||
private readonly roleFormService: RoleFormService,
|
||||
private readonly roleResource: RolesResource,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
register(): void {
|
||||
this.roleFormService.tabsContainer.add({
|
||||
key: 'options',
|
||||
name: 'ui_options',
|
||||
order: 1,
|
||||
panel: () => RoleOptions,
|
||||
});
|
||||
|
||||
this.roleFormService.prepareConfigTask
|
||||
.addHandler(this.prepareConfig.bind(this));
|
||||
|
||||
this.roleFormService.formValidationTask
|
||||
.addHandler(this.validate.bind(this));
|
||||
|
||||
this.roleFormService.formSubmittingTask
|
||||
.addHandler(this.save.bind(this));
|
||||
|
||||
this.roleFormService.fillConfigTask
|
||||
.addHandler(this.fillConfig.bind(this));
|
||||
}
|
||||
|
||||
load(): void { }
|
||||
|
||||
private async prepareConfig(
|
||||
{
|
||||
state,
|
||||
}: IRoleFormSubmitData,
|
||||
contexts: IExecutionContextProvider<IRoleFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(roleContext);
|
||||
|
||||
config.roleId = state.config.roleId;
|
||||
|
||||
if (state.config.roleName) {
|
||||
config.roleName = state.config.roleName.trim();
|
||||
|
||||
if (state.mode === 'create') {
|
||||
const roleNames = this.roleResource.values.map(role => role.roleName).filter(Boolean) as string[];
|
||||
config.roleName = getUniqueName(config.roleName, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.config.description) {
|
||||
config.description = state.config.description;
|
||||
}
|
||||
|
||||
config.rolePermissions = [...state.config.rolePermissions];
|
||||
}
|
||||
|
||||
private async validate(
|
||||
{
|
||||
state,
|
||||
}: IRoleFormSubmitData,
|
||||
contexts: IExecutionContextProvider<IRoleFormSubmitData>
|
||||
) {
|
||||
const validation = contexts.getContext(this.roleFormService.configurationValidationContext);
|
||||
|
||||
if (state.mode === 'create') {
|
||||
if (!state.config.roleId.trim()) {
|
||||
validation.error("Field 'Role ID' can't be empty");
|
||||
}
|
||||
|
||||
if (this.roleResource.has(state.config.roleId)) {
|
||||
validation.error(`A role with ID "${state.config.roleId}" already exists`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async save(
|
||||
{
|
||||
state,
|
||||
}: IRoleFormSubmitData,
|
||||
contexts: IExecutionContextProvider<IRoleFormSubmitData>
|
||||
) {
|
||||
const status = contexts.getContext(this.roleFormService.configurationStatusContext);
|
||||
const config = contexts.getContext(roleContext);
|
||||
|
||||
const create = state.mode === 'create';
|
||||
|
||||
try {
|
||||
if (create) {
|
||||
const role = await this.roleResource.createRole(config);
|
||||
status.info('Role created');
|
||||
status.info(role.roleId);
|
||||
} else {
|
||||
const role = await this.roleResource.updateRole(config);
|
||||
status.info('Role updated');
|
||||
status.info(role.roleId);
|
||||
}
|
||||
} catch (exception: any) {
|
||||
if (create) {
|
||||
status.error(exception, 'administration_roles_role_create_error');
|
||||
} else {
|
||||
status.error(exception, 'administration_roles_role_save_error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fillConfig(
|
||||
{ state, updated }: IRoleFormFillConfigData,
|
||||
contexts: IExecutionContextProvider<IRoleFormFillConfigData>
|
||||
) {
|
||||
if (!updated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.info) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.info.roleId) {
|
||||
state.config.roleId = state.info.roleId;
|
||||
}
|
||||
if (state.info.roleName) {
|
||||
state.config.roleName = state.info.roleName;
|
||||
}
|
||||
if (state.info.description) {
|
||||
state.config.description = state.info.description;
|
||||
}
|
||||
state.config.rolePermissions = [...state.info.rolePermissions];
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import type { RoleInfo } from '@cloudbeaver/core-authentication';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import type { CachedMapResource } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import type { IRoleFormState } from './IRoleFormProps';
|
||||
import { RoleFormService } from './RoleFormService';
|
||||
import { RoleFormState } from './RoleFormState';
|
||||
|
||||
export function useRoleFormState(
|
||||
resource: CachedMapResource<string, RoleInfo>,
|
||||
configure?: (state: IRoleFormState) => any
|
||||
): IRoleFormState {
|
||||
const service = useService(RoleFormService);
|
||||
const [state] = useState<IRoleFormState>(() => {
|
||||
const state = new RoleFormState(
|
||||
service,
|
||||
resource,
|
||||
);
|
||||
configure?.(state);
|
||||
|
||||
state.load();
|
||||
return state;
|
||||
});
|
||||
|
||||
return state;
|
||||
}
|
||||
+4
-4
@@ -6,11 +6,11 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { RoleInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { TeamInfo } from '@cloudbeaver/core-authentication';
|
||||
|
||||
export function roleContext(): RoleInfo {
|
||||
export function teamContext(): TeamInfo {
|
||||
return {
|
||||
roleId: '',
|
||||
rolePermissions: [],
|
||||
teamId: '',
|
||||
teamPermissions: [],
|
||||
};
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { TeamInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
|
||||
import type { ITeamFormState } from '../ITeamFormProps';
|
||||
|
||||
export interface ITeamFormConfigureContext {
|
||||
readonly info: TeamInfo | undefined;
|
||||
}
|
||||
|
||||
export function teamFormConfigureContext(
|
||||
contexts: IExecutionContextProvider<ITeamFormState>,
|
||||
state: ITeamFormState
|
||||
): ITeamFormConfigureContext {
|
||||
return {
|
||||
info: state.info,
|
||||
};
|
||||
}
|
||||
+3
-3
@@ -6,18 +6,18 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
export interface IRoleFormStateInfo {
|
||||
export interface ITeamFormStateInfo {
|
||||
edited: boolean;
|
||||
disabled: boolean;
|
||||
readonly: boolean;
|
||||
statusMessage: string | null;
|
||||
}
|
||||
|
||||
export interface IRoleFormStateContext extends IRoleFormStateInfo {
|
||||
export interface ITeamFormStateContext extends ITeamFormStateInfo {
|
||||
setStatusMessage: (message: string | null) => void;
|
||||
}
|
||||
|
||||
export function roleFormStateContext(): IRoleFormStateContext {
|
||||
export function teamFormStateContext(): ITeamFormStateContext {
|
||||
return {
|
||||
edited: false,
|
||||
disabled: false,
|
||||
+12
-12
@@ -14,11 +14,11 @@ import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
|
||||
|
||||
import { CreateRoleService } from './CreateRoleService';
|
||||
import { RoleForm } from './RoleForm';
|
||||
import { CreateTeamService } from './CreateTeamService';
|
||||
import { TeamForm } from './TeamForm';
|
||||
|
||||
const styles = css`
|
||||
role-create {
|
||||
team-create {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 660px;
|
||||
@@ -35,7 +35,7 @@ const styles = css`
|
||||
flex: auto 0 0;
|
||||
}
|
||||
|
||||
role-create-content {
|
||||
team-create-content {
|
||||
composes: theme-background-secondary theme-text-on-secondary from global;
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -49,23 +49,23 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const CreateRole: React.FC = observer(function CreateRole() {
|
||||
const service = useService(CreateRoleService);
|
||||
export const CreateTeam: React.FC = observer(function CreateTeam() {
|
||||
const service = useService(CreateTeamService);
|
||||
|
||||
if (!service.data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return styled(styles)(
|
||||
<role-create>
|
||||
<team-create>
|
||||
<title-bar>
|
||||
<Translate token='administration_roles_role_creation' />
|
||||
<Translate token='administration_teams_team_creation' />
|
||||
<fill />
|
||||
<IconButton name="cross" viewBox="0 0 16 16" onClick={service.cancelCreate} />
|
||||
</title-bar>
|
||||
<role-create-content>
|
||||
<RoleForm state={service.data} onCancel={service.cancelCreate} onSave={service.cancelCreate} />
|
||||
</role-create-content>
|
||||
</role-create>
|
||||
<team-create-content>
|
||||
<TeamForm state={service.data} onCancel={service.cancelCreate} onSave={service.cancelCreate} />
|
||||
</team-create-content>
|
||||
</team-create>
|
||||
);
|
||||
});
|
||||
+15
-15
@@ -8,23 +8,23 @@
|
||||
|
||||
import { observable, makeObservable } from 'mobx';
|
||||
|
||||
import { RolesResource } from '@cloudbeaver/core-authentication';
|
||||
import { TeamsResource } from '@cloudbeaver/core-authentication';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
|
||||
import type { IRoleFormState } from './IRoleFormProps';
|
||||
import { RoleFormService } from './RoleFormService';
|
||||
import { RoleFormState } from './RoleFormState';
|
||||
import { RolesAdministrationNavService } from './RolesAdministrationNavService';
|
||||
import type { ITeamFormState } from './ITeamFormProps';
|
||||
import { TeamFormService } from './TeamFormService';
|
||||
import { TeamFormState } from './TeamFormState';
|
||||
import { TeamsAdministrationNavService } from './TeamsAdministrationNavService';
|
||||
|
||||
@injectable()
|
||||
export class CreateRoleService {
|
||||
export class CreateTeamService {
|
||||
disabled = false;
|
||||
data: IRoleFormState | null;
|
||||
data: ITeamFormState | null;
|
||||
|
||||
constructor(
|
||||
private readonly rolesAdministrationNavService: RolesAdministrationNavService,
|
||||
private readonly roleFormService: RoleFormService,
|
||||
private readonly rolesResource: RolesResource
|
||||
private readonly teamsAdministrationNavService: TeamsAdministrationNavService,
|
||||
private readonly teamFormService: TeamFormService,
|
||||
private readonly teamsResource: TeamsResource
|
||||
) {
|
||||
this.data = null;
|
||||
|
||||
@@ -38,17 +38,17 @@ export class CreateRoleService {
|
||||
}
|
||||
|
||||
cancelCreate(): void {
|
||||
this.rolesAdministrationNavService.navToRoot();
|
||||
this.teamsAdministrationNavService.navToRoot();
|
||||
}
|
||||
|
||||
fillData(): void {
|
||||
this.data = new RoleFormState(
|
||||
this.roleFormService,
|
||||
this.rolesResource
|
||||
this.data = new TeamFormState(
|
||||
this.teamFormService,
|
||||
this.teamsResource
|
||||
);
|
||||
}
|
||||
|
||||
create(): void {
|
||||
this.rolesAdministrationNavService.navToCreate();
|
||||
this.teamsAdministrationNavService.navToCreate();
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -21,7 +21,7 @@ import { PROJECT_GLOBAL_ID } from '@cloudbeaver/core-projects';
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
|
||||
import { TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
|
||||
|
||||
import type { IRoleFormProps } from '../IRoleFormProps';
|
||||
import type { ITeamFormProps } from '../ITeamFormProps';
|
||||
import { ConnectionList } from './ConnectionList';
|
||||
import { GrantedConnectionList } from './GrantedConnectionsList';
|
||||
import { useGrantedConnections } from './useGrantedConnections';
|
||||
@@ -42,7 +42,7 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const GrantedConnections: TabContainerPanelComponent<IRoleFormProps> = observer(function GrantedConnections({
|
||||
export const GrantedConnections: TabContainerPanelComponent<ITeamFormProps> = observer(function GrantedConnections({
|
||||
tabId,
|
||||
state: formState,
|
||||
}) {
|
||||
@@ -51,6 +51,7 @@ export const GrantedConnections: TabContainerPanelComponent<IRoleFormProps> = ob
|
||||
|
||||
const state = useGrantedConnections(formState.config, formState.mode);
|
||||
const { selected } = useTab(tabId);
|
||||
const loaded = state.state.loaded;
|
||||
|
||||
const dbDriverResource = useMapResource(
|
||||
GrantedConnections,
|
||||
@@ -70,10 +71,10 @@ export const GrantedConnections: TabContainerPanelComponent<IRoleFormProps> = ob
|
||||
), [state.state.grantedSubjects, connections.resource]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selected && !state.state.loaded) {
|
||||
if (selected && !loaded) {
|
||||
state.load();
|
||||
}
|
||||
}, [selected, state.state.loaded]);
|
||||
});
|
||||
|
||||
if (!selected) {
|
||||
return null;
|
||||
@@ -97,7 +98,7 @@ export const GrantedConnections: TabContainerPanelComponent<IRoleFormProps> = ob
|
||||
<ColoredContainer parent gap vertical>
|
||||
{!connections.resource.values.length ? (
|
||||
<Group large>
|
||||
<TextPlaceholder>{translate('administration_roles_role_granted_connections_empty')}</TextPlaceholder>
|
||||
<TextPlaceholder>{translate('administration_teams_team_granted_connections_empty')}</TextPlaceholder>
|
||||
</Group>
|
||||
) : (
|
||||
<>
|
||||
+20
-20
@@ -6,26 +6,26 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { RolesResource } from '@cloudbeaver/core-authentication';
|
||||
import { TeamsResource } from '@cloudbeaver/core-authentication';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { GraphQLService } from '@cloudbeaver/core-sdk';
|
||||
import { isArraysEqual, MetadataValueGetter } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { roleContext } from '../Contexts/roleContext';
|
||||
import type { IRoleFormProps, IRoleFormSubmitData } from '../IRoleFormProps';
|
||||
import { RoleFormService } from '../RoleFormService';
|
||||
import { teamContext } from '../Contexts/teamContext';
|
||||
import type { ITeamFormProps, ITeamFormSubmitData } from '../ITeamFormProps';
|
||||
import { TeamFormService } from '../TeamFormService';
|
||||
import { GrantedConnections } from './GrantedConnections';
|
||||
import type { IGrantedConnectionsTabState } from './IGrantedConnectionsTabState';
|
||||
|
||||
@injectable()
|
||||
export class GrantedConnectionsTabService extends Bootstrap {
|
||||
private key: string;
|
||||
private readonly key: string;
|
||||
|
||||
constructor(
|
||||
private readonly roleFormService: RoleFormService,
|
||||
private readonly rolesResource: RolesResource,
|
||||
private readonly teamFormService: TeamFormService,
|
||||
private readonly teamsResource: TeamsResource,
|
||||
private readonly graphQLService: GraphQLService,
|
||||
private readonly notificationService: NotificationService
|
||||
) {
|
||||
@@ -34,21 +34,21 @@ export class GrantedConnectionsTabService extends Bootstrap {
|
||||
}
|
||||
|
||||
register(): void {
|
||||
this.roleFormService.tabsContainer.add({
|
||||
this.teamFormService.tabsContainer.add({
|
||||
key: this.key,
|
||||
name: 'administration_roles_role_granted_connections_tab_title',
|
||||
title: 'administration_roles_role_granted_connections_tab_title',
|
||||
name: 'administration_teams_team_granted_connections_tab_title',
|
||||
title: 'administration_teams_team_granted_connections_tab_title',
|
||||
order: 3,
|
||||
stateGetter: context => this.stateGetter(context),
|
||||
panel: () => GrantedConnections,
|
||||
});
|
||||
|
||||
this.roleFormService.formSubmittingTask.addHandler(this.save.bind(this));
|
||||
this.teamFormService.afterFormSubmittingTask.addHandler(this.save.bind(this));
|
||||
}
|
||||
|
||||
load(): Promise<void> | void { }
|
||||
|
||||
private stateGetter(context: IRoleFormProps): MetadataValueGetter<string, IGrantedConnectionsTabState> {
|
||||
private stateGetter(context: ITeamFormProps): MetadataValueGetter<string, IGrantedConnectionsTabState> {
|
||||
return () => ({
|
||||
loading: false,
|
||||
loaded: false,
|
||||
@@ -59,27 +59,27 @@ export class GrantedConnectionsTabService extends Bootstrap {
|
||||
}
|
||||
|
||||
private async save(
|
||||
data: IRoleFormSubmitData,
|
||||
contexts: IExecutionContextProvider<IRoleFormSubmitData>
|
||||
data: ITeamFormSubmitData,
|
||||
contexts: IExecutionContextProvider<ITeamFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(roleContext);
|
||||
const status = contexts.getContext(this.roleFormService.configurationStatusContext);
|
||||
const config = contexts.getContext(teamContext);
|
||||
const status = contexts.getContext(this.teamFormService.configurationStatusContext);
|
||||
|
||||
if (!status.saved) {
|
||||
return;
|
||||
}
|
||||
|
||||
const state = this.roleFormService.tabsContainer.getTabState<IGrantedConnectionsTabState>(
|
||||
const state = this.teamFormService.tabsContainer.getTabState<IGrantedConnectionsTabState>(
|
||||
data.state.partsState,
|
||||
this.key,
|
||||
{ state: data.state }
|
||||
);
|
||||
|
||||
if (!config.roleId || !state.loaded) {
|
||||
if (!config.teamId || !state.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
const grantInfo = await this.rolesResource.getSubjectConnectionAccess(config.roleId);
|
||||
const grantInfo = await this.teamsResource.getSubjectConnectionAccess(config.teamId);
|
||||
const initial = grantInfo.map(info => info.connectionId);
|
||||
|
||||
const changed = !isArraysEqual(initial, state.grantedSubjects);
|
||||
@@ -90,7 +90,7 @@ export class GrantedConnectionsTabService extends Bootstrap {
|
||||
|
||||
try {
|
||||
await this.graphQLService.sdk.setSubjectConnectionAccess({
|
||||
subjectId: config.roleId,
|
||||
subjectId: config.teamId,
|
||||
connections: state.grantedSubjects,
|
||||
});
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ export const GrantedConnectionsTableHeader = observer<Props>(function GrantedCon
|
||||
<header className={className}>
|
||||
<Filter
|
||||
disabled={disabled}
|
||||
placeholder={translate('administration_roles_role_granted_connections_search_placeholder')}
|
||||
placeholder={translate('administration_teams_team_granted_connections_search_placeholder')}
|
||||
name='filterValue'
|
||||
state={filterState}
|
||||
/>
|
||||
+8
-8
@@ -8,14 +8,14 @@
|
||||
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import { RoleInfo, RolesResource } from '@cloudbeaver/core-authentication';
|
||||
import { useTabState } from '@cloudbeaver/core-ui';
|
||||
import { TeamInfo, TeamsResource } from '@cloudbeaver/core-authentication';
|
||||
import { useObservableRef } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { useTabState } from '@cloudbeaver/core-ui';
|
||||
import { isArraysEqual } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { RoleFormMode } from '../IRoleFormProps';
|
||||
import type { TeamFormMode } from '../ITeamFormProps';
|
||||
import type { IGrantedConnectionsTabState } from './IGrantedConnectionsTabState';
|
||||
|
||||
interface State {
|
||||
@@ -27,8 +27,8 @@ interface State {
|
||||
load: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function useGrantedConnections(role: RoleInfo, mode: RoleFormMode): Readonly<State> {
|
||||
const resource = useService(RolesResource);
|
||||
export function useGrantedConnections(team: TeamInfo, mode: TeamFormMode): Readonly<State> {
|
||||
const resource = useService(TeamsResource);
|
||||
const notificationService = useService(NotificationService);
|
||||
const state = useTabState<IGrantedConnectionsTabState>();
|
||||
|
||||
@@ -54,20 +54,20 @@ export function useGrantedConnections(role: RoleInfo, mode: RoleFormMode): Reado
|
||||
this.state.loading = true;
|
||||
|
||||
if (this.mode === 'edit') {
|
||||
const grantInfo = await this.resource.getSubjectConnectionAccess(this.role.roleId);
|
||||
const grantInfo = await this.resource.getSubjectConnectionAccess(this.team.teamId);
|
||||
this.state.grantedSubjects = grantInfo.map(subject => subject.connectionId);
|
||||
this.state.initialGrantedSubjects = this.state.grantedSubjects.slice();
|
||||
}
|
||||
|
||||
this.state.loaded = true;
|
||||
} catch (exception: any) {
|
||||
this.notificationService.logException(exception, `Error getting granted connections for "${this.role.roleId}"`);
|
||||
this.notificationService.logException(exception, `Error getting granted connections for "${this.team.teamId}"`);
|
||||
} finally {
|
||||
this.state.loading = false;
|
||||
}
|
||||
},
|
||||
}),
|
||||
{ state: observable.ref, changed: computed, grant: action.bound, revoke: action.bound, edit: action.bound },
|
||||
{ state, role, mode, resource, notificationService },
|
||||
{ state, team, mode, resource, notificationService },
|
||||
['load']);
|
||||
}
|
||||
+1
-1
@@ -126,7 +126,7 @@ export const GrantedUserList = observer<Props>(function GrantedUserList({
|
||||
key={user.userId}
|
||||
id={user.userId}
|
||||
name={`${user.userId}${activeUser ? ' (you)' : ''}`}
|
||||
tooltip={activeUser ? translate('administration_roles_role_granted_users_permission_denied') : user.userId}
|
||||
tooltip={activeUser ? translate('administration_teams_team_granted_users_permission_denied') : user.userId}
|
||||
icon='/icons/user.svg'
|
||||
iconTooltip={translate('authentication_user_icon_tooltip')}
|
||||
disabled={disabled}
|
||||
+3
-3
@@ -20,7 +20,7 @@ import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
|
||||
import { TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';
|
||||
|
||||
|
||||
import type { IRoleFormProps } from '../IRoleFormProps';
|
||||
import type { ITeamFormProps } from '../ITeamFormProps';
|
||||
import { GrantedUserList } from './GrantedUserList';
|
||||
import { useGrantedUsers } from './useGrantedUsers';
|
||||
import { UserList } from './UserList';
|
||||
@@ -41,7 +41,7 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const GrantedUsers: TabContainerPanelComponent<IRoleFormProps> = observer(function GrantedUsers({
|
||||
export const GrantedUsers: TabContainerPanelComponent<ITeamFormProps> = observer(function GrantedUsers({
|
||||
tabId,
|
||||
state: formState,
|
||||
}) {
|
||||
@@ -73,7 +73,7 @@ export const GrantedUsers: TabContainerPanelComponent<IRoleFormProps> = observer
|
||||
<ColoredContainer parent gap vertical>
|
||||
{!users.resource.values.length ? (
|
||||
<Group keepSize large>
|
||||
<TextPlaceholder>{translate('administration_roles_role_granted_users_empty')}</TextPlaceholder>
|
||||
<TextPlaceholder>{translate('administration_teams_team_granted_users_empty')}</TextPlaceholder>
|
||||
</Group>
|
||||
) : (
|
||||
<>
|
||||
+21
-21
@@ -6,26 +6,26 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { RolesResource, UsersResource } from '@cloudbeaver/core-authentication';
|
||||
import { TeamsResource, UsersResource } from '@cloudbeaver/core-authentication';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { isArraysEqual, MetadataValueGetter } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { roleContext } from '../Contexts/roleContext';
|
||||
import type { IRoleFormProps, IRoleFormSubmitData } from '../IRoleFormProps';
|
||||
import { RoleFormService } from '../RoleFormService';
|
||||
import { teamContext } from '../Contexts/teamContext';
|
||||
import type { ITeamFormProps, ITeamFormSubmitData } from '../ITeamFormProps';
|
||||
import { TeamFormService } from '../TeamFormService';
|
||||
import { GrantedUsers } from './GrantedUsers';
|
||||
import type { IGrantedUsersTabState } from './IGrantedUsersTabState';
|
||||
|
||||
@injectable()
|
||||
export class GrantedUsersTabService extends Bootstrap {
|
||||
private key: string;
|
||||
private readonly key: string;
|
||||
|
||||
constructor(
|
||||
private readonly roleFormService: RoleFormService,
|
||||
private readonly teamFormService: TeamFormService,
|
||||
private readonly usersResource: UsersResource,
|
||||
private readonly rolesResource: RolesResource,
|
||||
private readonly teamsResource: TeamsResource,
|
||||
private readonly notificationService: NotificationService
|
||||
) {
|
||||
super();
|
||||
@@ -33,21 +33,21 @@ export class GrantedUsersTabService extends Bootstrap {
|
||||
}
|
||||
|
||||
register(): void {
|
||||
this.roleFormService.tabsContainer.add({
|
||||
this.teamFormService.tabsContainer.add({
|
||||
key: this.key,
|
||||
name: 'administration_roles_role_granted_users_tab_title',
|
||||
title: 'administration_roles_role_granted_users_tab_title',
|
||||
name: 'administration_teams_team_granted_users_tab_title',
|
||||
title: 'administration_teams_team_granted_users_tab_title',
|
||||
order: 2,
|
||||
stateGetter: context => this.stateGetter(context),
|
||||
panel: () => GrantedUsers,
|
||||
});
|
||||
|
||||
this.roleFormService.formSubmittingTask.addHandler(this.save.bind(this));
|
||||
this.teamFormService.afterFormSubmittingTask.addHandler(this.save.bind(this));
|
||||
}
|
||||
|
||||
load(): void { }
|
||||
|
||||
private stateGetter(context: IRoleFormProps): MetadataValueGetter<string, IGrantedUsersTabState> {
|
||||
private stateGetter(context: ITeamFormProps): MetadataValueGetter<string, IGrantedUsersTabState> {
|
||||
return () => ({
|
||||
loading: false,
|
||||
loaded: false,
|
||||
@@ -58,27 +58,27 @@ export class GrantedUsersTabService extends Bootstrap {
|
||||
}
|
||||
|
||||
private async save(
|
||||
data: IRoleFormSubmitData,
|
||||
contexts: IExecutionContextProvider<IRoleFormSubmitData>
|
||||
data: ITeamFormSubmitData,
|
||||
contexts: IExecutionContextProvider<ITeamFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(roleContext);
|
||||
const status = contexts.getContext(this.roleFormService.configurationStatusContext);
|
||||
const config = contexts.getContext(teamContext);
|
||||
const status = contexts.getContext(this.teamFormService.configurationStatusContext);
|
||||
|
||||
if (!status.saved) {
|
||||
return;
|
||||
}
|
||||
|
||||
const state = this.roleFormService.tabsContainer.getTabState<IGrantedUsersTabState>(
|
||||
const state = this.teamFormService.tabsContainer.getTabState<IGrantedUsersTabState>(
|
||||
data.state.partsState,
|
||||
this.key,
|
||||
{ state: data.state }
|
||||
);
|
||||
|
||||
if (!config.roleId || !state.loaded) {
|
||||
if (!config.teamId || !state.loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
const initial = await this.rolesResource.loadGrantedUsers(config.roleId);
|
||||
const initial = await this.teamsResource.loadGrantedUsers(config.teamId);
|
||||
|
||||
const changed = !isArraysEqual(initial, state.grantedUsers);
|
||||
|
||||
@@ -93,13 +93,13 @@ export class GrantedUsersTabService extends Bootstrap {
|
||||
|
||||
try {
|
||||
for (const user of revokedUsers) {
|
||||
await this.usersResource.revokeRole(user, config.roleId);
|
||||
await this.usersResource.revokeTeam(user, config.teamId);
|
||||
revoked.push(user);
|
||||
}
|
||||
|
||||
for (const user of state.grantedUsers) {
|
||||
if (!initial.includes(user)) {
|
||||
await this.usersResource.grantRole(user, config.roleId);
|
||||
await this.usersResource.grantTeam(user, config.teamId);
|
||||
granted.push(user);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -49,7 +49,7 @@ export const GrantedUsersTableHeader = observer<Props>(function GrantedUsersTabl
|
||||
<header className={className}>
|
||||
<Filter
|
||||
disabled={disabled}
|
||||
placeholder={translate('administration_roles_role_granted_users_search_placeholder')}
|
||||
placeholder={translate('administration_teams_team_granted_users_search_placeholder')}
|
||||
name='filterValue'
|
||||
state={filterState}
|
||||
/>
|
||||
+1
-1
@@ -36,7 +36,7 @@ export const GrantedUsersTableInnerHeader = observer<Props>(function GrantedUser
|
||||
<TableSelect id='selectUsers' disabled={disabled} />
|
||||
</TableColumnHeader>
|
||||
<TableColumnHeader min />
|
||||
<TableColumnHeader>{translate('administration_roles_role_granted_users_user_id')}</TableColumnHeader>
|
||||
<TableColumnHeader>{translate('administration_teams_team_granted_users_user_id')}</TableColumnHeader>
|
||||
</TableHeader>
|
||||
);
|
||||
});
|
||||
+1
-1
@@ -118,7 +118,7 @@ export const UserList = observer<Props>(function UserList({
|
||||
key={user.userId}
|
||||
id={user.userId}
|
||||
name={`${user.userId}${activeUser ? ' (you)' : ''}`}
|
||||
tooltip={activeUser ? translate('administration_roles_role_granted_users_permission_denied') : user.userId}
|
||||
tooltip={activeUser ? translate('administration_teams_team_granted_users_permission_denied') : user.userId}
|
||||
icon='/icons/user.svg'
|
||||
iconTooltip={translate('authentication_user_icon_tooltip')}
|
||||
disabled={disabled}
|
||||
+7
-7
@@ -8,14 +8,14 @@
|
||||
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import { RoleInfo, RolesResource } from '@cloudbeaver/core-authentication';
|
||||
import { useTabState } from '@cloudbeaver/core-ui';
|
||||
import { TeamInfo, TeamsResource } from '@cloudbeaver/core-authentication';
|
||||
import { useObservableRef } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { useTabState } from '@cloudbeaver/core-ui';
|
||||
import { isArraysEqual } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { RoleFormMode } from '../IRoleFormProps';
|
||||
import type { TeamFormMode } from '../ITeamFormProps';
|
||||
import type { IGrantedUsersTabState } from './IGrantedUsersTabState';
|
||||
|
||||
interface State {
|
||||
@@ -27,8 +27,8 @@ interface State {
|
||||
load: () => Promise<void>;
|
||||
}
|
||||
|
||||
export function useGrantedUsers(role: RoleInfo, mode: RoleFormMode): Readonly<State> {
|
||||
const resource = useService(RolesResource);
|
||||
export function useGrantedUsers(team: TeamInfo, mode: TeamFormMode): Readonly<State> {
|
||||
const resource = useService(TeamsResource);
|
||||
const notificationService = useService(NotificationService);
|
||||
const state = useTabState<IGrantedUsersTabState>();
|
||||
|
||||
@@ -54,7 +54,7 @@ export function useGrantedUsers(role: RoleInfo, mode: RoleFormMode): Readonly<St
|
||||
this.state.loading = true;
|
||||
|
||||
if (this.mode === 'edit') {
|
||||
const grantedUsers = await this.resource.loadGrantedUsers(this.role.roleId);
|
||||
const grantedUsers = await this.resource.loadGrantedUsers(this.team.teamId);
|
||||
this.state.grantedUsers = grantedUsers;
|
||||
this.state.initialGrantedUsers = this.state.grantedUsers.slice();
|
||||
}
|
||||
@@ -68,6 +68,6 @@ export function useGrantedUsers(role: RoleInfo, mode: RoleFormMode): Readonly<St
|
||||
},
|
||||
}),
|
||||
{ state: observable.ref, changed: computed, edit: action.bound, revoke: action.bound, grant: action.bound },
|
||||
{ state, role, mode, resource, notificationService },
|
||||
{ state, team, mode, resource, notificationService },
|
||||
['load']);
|
||||
}
|
||||
+16
-16
@@ -6,45 +6,45 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import type { RoleInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { TeamInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { IExecutorHandlersCollection } from '@cloudbeaver/core-executor';
|
||||
import type { CachedMapResource } from '@cloudbeaver/core-sdk';
|
||||
import type { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
|
||||
export type RoleFormMode = 'edit' | 'create';
|
||||
export type TeamFormMode = 'edit' | 'create';
|
||||
|
||||
export interface IRoleFormState {
|
||||
mode: RoleFormMode;
|
||||
config: RoleInfo;
|
||||
export interface ITeamFormState {
|
||||
mode: TeamFormMode;
|
||||
config: TeamInfo;
|
||||
partsState: MetadataMap<string, any>;
|
||||
|
||||
readonly info: RoleInfo | undefined;
|
||||
readonly info: TeamInfo | undefined;
|
||||
readonly statusMessage: string | null;
|
||||
readonly disabled: boolean;
|
||||
readonly readonly: boolean;
|
||||
readonly loading: boolean;
|
||||
|
||||
readonly submittingTask: IExecutorHandlersCollection<IRoleFormSubmitData>;
|
||||
readonly resource: CachedMapResource<string, RoleInfo>;
|
||||
readonly submittingTask: IExecutorHandlersCollection<ITeamFormSubmitData>;
|
||||
readonly resource: CachedMapResource<string, TeamInfo>;
|
||||
|
||||
readonly load: () => Promise<void>;
|
||||
readonly loadRoleInfo: () => Promise<RoleInfo | undefined>;
|
||||
readonly loadTeamInfo: () => Promise<TeamInfo | undefined>;
|
||||
readonly save: () => Promise<void>;
|
||||
readonly setOptions: (
|
||||
mode: RoleFormMode,
|
||||
mode: TeamFormMode,
|
||||
) => this;
|
||||
}
|
||||
|
||||
export interface IRoleFormProps {
|
||||
state: IRoleFormState;
|
||||
export interface ITeamFormProps {
|
||||
state: ITeamFormState;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
|
||||
export interface IRoleFormFillConfigData {
|
||||
export interface ITeamFormFillConfigData {
|
||||
updated: boolean;
|
||||
state: IRoleFormState;
|
||||
state: ITeamFormState;
|
||||
}
|
||||
|
||||
export interface IRoleFormSubmitData {
|
||||
state: IRoleFormState;
|
||||
export interface ITeamFormSubmitData {
|
||||
state: ITeamFormState;
|
||||
}
|
||||
+10
-12
@@ -12,12 +12,10 @@ import styled, { css } from 'reshadow';
|
||||
|
||||
import { PermissionsResource } from '@cloudbeaver/core-administration';
|
||||
import { BASE_CONTAINERS_STYLES, ColoredContainer, FieldCheckbox, Group, GroupTitle, InputField, SubmittingForm, Textarea, useMapResource, useTranslate, useStyles } from '@cloudbeaver/core-blocks';
|
||||
|
||||
import { CachedMapAllKey } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import type { TabContainerPanelComponent } from '@cloudbeaver/core-ui';
|
||||
|
||||
import type { IRoleFormProps } from '../IRoleFormProps';
|
||||
import type { ITeamFormProps } from '../ITeamFormProps';
|
||||
|
||||
const styles = css`
|
||||
SubmittingForm {
|
||||
@@ -29,13 +27,13 @@ const styles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const RoleOptions: TabContainerPanelComponent<IRoleFormProps> = observer(function RoleOptions({
|
||||
export const TeamOptions: TabContainerPanelComponent<ITeamFormProps> = observer(function TeamOptions({
|
||||
state,
|
||||
}) {
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
|
||||
const translate = useTranslate();
|
||||
const permissionsResource = useMapResource(RoleOptions, PermissionsResource, CachedMapAllKey);
|
||||
const permissionsResource = useMapResource(TeamOptions, PermissionsResource, CachedMapAllKey);
|
||||
const style = useStyles(BASE_CONTAINERS_STYLES, styles);
|
||||
const edit = state.mode === 'edit';
|
||||
|
||||
@@ -44,7 +42,7 @@ export const RoleOptions: TabContainerPanelComponent<IRoleFormProps> = observer(
|
||||
<ColoredContainer parent gap overflow>
|
||||
<Group small gap>
|
||||
<InputField
|
||||
name='roleId'
|
||||
name='teamId'
|
||||
state={state.config}
|
||||
readOnly={state.readonly || edit}
|
||||
disabled={state.disabled}
|
||||
@@ -52,17 +50,17 @@ export const RoleOptions: TabContainerPanelComponent<IRoleFormProps> = observer(
|
||||
tiny
|
||||
fill
|
||||
>
|
||||
{translate('administration_roles_role_id')}
|
||||
{translate('administration_teams_team_id')}
|
||||
</InputField>
|
||||
<InputField
|
||||
name='roleName'
|
||||
name='teamName'
|
||||
state={state.config}
|
||||
readOnly={state.readonly}
|
||||
disabled={state.disabled}
|
||||
tiny
|
||||
fill
|
||||
>
|
||||
{translate('administration_roles_role_name')}
|
||||
{translate('administration_teams_team_name')}
|
||||
</InputField>
|
||||
<Textarea
|
||||
name='description'
|
||||
@@ -72,11 +70,11 @@ export const RoleOptions: TabContainerPanelComponent<IRoleFormProps> = observer(
|
||||
tiny
|
||||
fill
|
||||
>
|
||||
{translate('administration_roles_role_description')}
|
||||
{translate('administration_teams_team_description')}
|
||||
</Textarea>
|
||||
</Group>
|
||||
<Group small gap>
|
||||
<GroupTitle>{translate('administration_roles_role_permissions')}</GroupTitle>
|
||||
<GroupTitle>{translate('administration_teams_team_permissions')}</GroupTitle>
|
||||
{permissionsResource.resource.values.map(permission => {
|
||||
const label = permission.label ?? permission.id;
|
||||
|
||||
@@ -100,7 +98,7 @@ export const RoleOptions: TabContainerPanelComponent<IRoleFormProps> = observer(
|
||||
id={permission.id}
|
||||
value={permission.id}
|
||||
title={tooltip}
|
||||
name='rolePermissions'
|
||||
name='teamPermissions'
|
||||
state={state.config}
|
||||
readOnly={state.readonly}
|
||||
disabled={state.disabled}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { TeamsResource } from '@cloudbeaver/core-authentication';
|
||||
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
|
||||
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { LocalizationService } from '@cloudbeaver/core-localization';
|
||||
import { getUniqueName } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { teamContext } from '../Contexts/teamContext';
|
||||
import type { ITeamFormFillConfigData, ITeamFormSubmitData } from '../ITeamFormProps';
|
||||
import { TeamFormService } from '../TeamFormService';
|
||||
import { TeamOptions } from './TeamOptions';
|
||||
|
||||
@injectable()
|
||||
export class TeamOptionsTabService extends Bootstrap {
|
||||
constructor(
|
||||
private readonly teamFormService: TeamFormService,
|
||||
private readonly teamResource: TeamsResource,
|
||||
private readonly localizationService: LocalizationService
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
register(): void {
|
||||
this.teamFormService.tabsContainer.add({
|
||||
key: 'options',
|
||||
name: 'ui_options',
|
||||
order: 1,
|
||||
panel: () => TeamOptions,
|
||||
});
|
||||
|
||||
this.teamFormService.prepareConfigTask
|
||||
.addHandler(this.prepareConfig.bind(this));
|
||||
|
||||
this.teamFormService.formValidationTask
|
||||
.addHandler(this.validate.bind(this));
|
||||
|
||||
this.teamFormService.formSubmittingTask
|
||||
.addHandler(this.save.bind(this));
|
||||
|
||||
this.teamFormService.fillConfigTask
|
||||
.addHandler(this.fillConfig.bind(this));
|
||||
}
|
||||
|
||||
load(): void { }
|
||||
|
||||
private async prepareConfig(
|
||||
{
|
||||
state,
|
||||
}: ITeamFormSubmitData,
|
||||
contexts: IExecutionContextProvider<ITeamFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(teamContext);
|
||||
|
||||
config.teamId = state.config.teamId;
|
||||
|
||||
if (state.config.teamName) {
|
||||
config.teamName = state.config.teamName.trim();
|
||||
|
||||
if (state.mode === 'create') {
|
||||
const teamNames = this.teamResource.values.map(team => team.teamName).filter(Boolean) as string[];
|
||||
config.teamName = getUniqueName(config.teamName, teamNames);
|
||||
}
|
||||
}
|
||||
|
||||
if (state.config.description) {
|
||||
config.description = state.config.description;
|
||||
}
|
||||
|
||||
config.teamPermissions = [...state.config.teamPermissions];
|
||||
}
|
||||
|
||||
private async validate(
|
||||
{
|
||||
state,
|
||||
}: ITeamFormSubmitData,
|
||||
contexts: IExecutionContextProvider<ITeamFormSubmitData>
|
||||
) {
|
||||
const validation = contexts.getContext(this.teamFormService.configurationValidationContext);
|
||||
|
||||
if (state.mode === 'create') {
|
||||
if (!state.config.teamId.trim()) {
|
||||
validation.error('administration_teams_team_info_id_invalid');
|
||||
}
|
||||
|
||||
if (this.teamResource.has(state.config.teamId)) {
|
||||
validation.error(this.localizationService.translate('administration_teams_team_info_exists', undefined, {
|
||||
teamId: state.config.teamId,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async save(
|
||||
{
|
||||
state,
|
||||
}: ITeamFormSubmitData,
|
||||
contexts: IExecutionContextProvider<ITeamFormSubmitData>
|
||||
) {
|
||||
const status = contexts.getContext(this.teamFormService.configurationStatusContext);
|
||||
const config = contexts.getContext(teamContext);
|
||||
|
||||
const create = state.mode === 'create';
|
||||
|
||||
try {
|
||||
if (create) {
|
||||
const team = await this.teamResource.createTeam(config);
|
||||
status.info('administration_teams_team_info_created');
|
||||
status.info(team.teamId);
|
||||
} else {
|
||||
const team = await this.teamResource.updateTeam(config);
|
||||
status.info('administration_teams_team_info_updated');
|
||||
status.info(team.teamId);
|
||||
}
|
||||
} catch (exception: any) {
|
||||
if (create) {
|
||||
status.error(exception, 'administration_teams_team_create_error');
|
||||
} else {
|
||||
status.error(exception, 'administration_teams_team_save_error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fillConfig(
|
||||
{ state, updated }: ITeamFormFillConfigData,
|
||||
contexts: IExecutionContextProvider<ITeamFormFillConfigData>
|
||||
) {
|
||||
if (!updated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.info) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.info.teamId) {
|
||||
state.config.teamId = state.info.teamId;
|
||||
}
|
||||
if (state.info.teamName) {
|
||||
state.config.teamName = state.info.teamName;
|
||||
}
|
||||
if (state.info.description) {
|
||||
state.config.description = state.info.description;
|
||||
}
|
||||
state.config.teamPermissions = [...state.info.teamPermissions];
|
||||
}
|
||||
}
|
||||
+22
-24
@@ -10,16 +10,14 @@ import { observer } from 'mobx-react-lite';
|
||||
import { useEffect } from 'react';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import type { RoleInfo } from '@cloudbeaver/core-authentication';
|
||||
import type { TeamInfo } from '@cloudbeaver/core-authentication';
|
||||
import { Placeholder, useObjectRef, useExecutor, BASE_CONTAINERS_STYLES, IconOrImage, useTranslate, useStyles } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
|
||||
|
||||
import { TabsState, TabList, UNDERLINE_TAB_STYLES, TabPanelList, BASE_TAB_STYLES } from '@cloudbeaver/core-ui';
|
||||
|
||||
import { roleContext } from './Contexts/roleContext';
|
||||
import type { IRoleFormState } from './IRoleFormProps';
|
||||
import { RoleFormService } from './RoleFormService';
|
||||
import { teamContext } from './Contexts/teamContext';
|
||||
import type { ITeamFormState } from './ITeamFormProps';
|
||||
import { TeamFormService } from './TeamFormService';
|
||||
|
||||
const tabsStyles = css`
|
||||
TabList {
|
||||
@@ -35,7 +33,7 @@ const tabsStyles = css`
|
||||
`;
|
||||
|
||||
const topBarStyles = css`
|
||||
role-top-bar {
|
||||
team-top-bar {
|
||||
composes: theme-border-color-background theme-background-secondary theme-text-on-secondary from global;
|
||||
position: relative;
|
||||
display: flex;
|
||||
@@ -50,18 +48,18 @@ const topBarStyles = css`
|
||||
border-color: inherit;
|
||||
}
|
||||
}
|
||||
role-top-bar-tabs {
|
||||
team-top-bar-tabs {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
role-top-bar-actions {
|
||||
team-top-bar-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24px;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
role-status-message {
|
||||
team-status-message {
|
||||
composes: theme-typography--caption from global;
|
||||
height: 24px;
|
||||
padding: 0 16px;
|
||||
@@ -96,13 +94,13 @@ const formStyles = css`
|
||||
`;
|
||||
|
||||
interface Props {
|
||||
state: IRoleFormState;
|
||||
state: ITeamFormState;
|
||||
onCancel?: () => void;
|
||||
onSave?: (role: RoleInfo) => void;
|
||||
onSave?: (team: TeamInfo) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const RoleForm = observer<Props>(function RoleForm({
|
||||
export const TeamForm = observer<Props>(function TeamForm({
|
||||
state,
|
||||
onCancel,
|
||||
onSave = () => { },
|
||||
@@ -112,14 +110,14 @@ export const RoleForm = observer<Props>(function RoleForm({
|
||||
const props = useObjectRef({ onSave });
|
||||
const style = [BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES];
|
||||
const styles = useStyles(style, BASE_CONTAINERS_STYLES, topBarStyles, formStyles);
|
||||
const service = useService(RoleFormService);
|
||||
const service = useService(TeamFormService);
|
||||
|
||||
useExecutor({
|
||||
executor: state.submittingTask,
|
||||
postHandlers: [function save(data, contexts) {
|
||||
const validation = contexts.getContext(service.configurationValidationContext);
|
||||
const state = contexts.getContext(service.configurationStatusContext);
|
||||
const config = contexts.getContext(roleContext);
|
||||
const config = contexts.getContext(teamContext);
|
||||
|
||||
if (validation.valid && state.saved) {
|
||||
props.onSave(config);
|
||||
@@ -128,7 +126,7 @@ export const RoleForm = observer<Props>(function RoleForm({
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
state.loadRoleInfo();
|
||||
state.loadTeamInfo();
|
||||
}, []);
|
||||
|
||||
return styled(styles)(
|
||||
@@ -139,22 +137,22 @@ export const RoleForm = observer<Props>(function RoleForm({
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<box className={className}>
|
||||
<role-top-bar>
|
||||
<role-top-bar-tabs>
|
||||
<role-status-message>
|
||||
<team-top-bar>
|
||||
<team-top-bar-tabs>
|
||||
<team-status-message>
|
||||
{state.statusMessage && (
|
||||
<>
|
||||
<IconOrImage icon='/icons/info_icon.svg' />
|
||||
{translate(state.statusMessage)}
|
||||
</>
|
||||
)}
|
||||
</role-status-message>
|
||||
</team-status-message>
|
||||
<TabList style={style} disabled={false} />
|
||||
</role-top-bar-tabs>
|
||||
<role-top-bar-actions>
|
||||
</team-top-bar-tabs>
|
||||
<team-top-bar-actions>
|
||||
<Placeholder container={service.actionsContainer} state={state} onCancel={onCancel} />
|
||||
</role-top-bar-actions>
|
||||
</role-top-bar>
|
||||
</team-top-bar-actions>
|
||||
</team-top-bar>
|
||||
<content-box>
|
||||
<TabPanelList style={style} />
|
||||
</content-box>
|
||||
+2
-2
@@ -11,9 +11,9 @@ import { observer } from 'mobx-react-lite';
|
||||
import { Button, PlaceholderComponent, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
|
||||
|
||||
import type { IRoleFormProps } from './IRoleFormProps';
|
||||
import type { ITeamFormProps } from './ITeamFormProps';
|
||||
|
||||
export const RoleFormBaseActions: PlaceholderComponent<IRoleFormProps> = observer(function RoleFormBaseActions({
|
||||
export const TeamFormBaseActions: PlaceholderComponent<ITeamFormProps> = observer(function TeamFormBaseActions({
|
||||
state,
|
||||
onCancel,
|
||||
}) {
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user