Skip to content

Commit

Permalink
CB-4535. Remove Ability to edit all users team (#2341)
Browse files Browse the repository at this point in the history
* CB-4535. Remove Ability to edit all users team

* CB-4536. Fixed test

* CB-4536. Refactor after review.

* CB-4536. Refactor after review

* CB-4536. Refactor after review

* CB-4536. Refactor after review

* CB-4536. Refactor after review

* CB-4536. Refactor after review.

* CB-4536. Auto filled default group for all user when application is started

* CB-4536. Refactor after review

* CB-4536. Fixed update empty list

* CB-4536 feat: display default user team info

* CB-4536 chore: code cleanup

---------

Co-authored-by: DenisSinelnikov <[email protected]>
Co-authored-by: kseniaguzeeva <[email protected]>
Co-authored-by: Aleksei Potsetsuev <[email protected]>
  • Loading branch information
4 people authored Feb 7, 2024
1 parent e285ad0 commit 7eba02a
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.cloudbeaver.WebServiceUtils;
import io.cloudbeaver.auth.CBAuthConstants;
import io.cloudbeaver.auth.NoAuthCredentialsProvider;
import io.cloudbeaver.service.security.CBEmbeddedSecurityController;
import io.cloudbeaver.service.security.PasswordPolicyConfiguration;
import io.cloudbeaver.model.app.BaseWebApplication;
import io.cloudbeaver.model.app.WebAuthApplication;
Expand Down Expand Up @@ -370,6 +371,11 @@ public boolean implies(ProtectionDomain domain, Permission permission) {
});
System.setSecurityManager(new SecurityManager());
}
try {
addAllUsersToDefaultTeam();
} catch (DBException e) {
log.error("Failed insert default teams");
}

eventController.scheduleCheckJob();

Expand All @@ -380,6 +386,12 @@ public boolean implies(ProtectionDomain domain, Permission permission) {
return;
}

private void addAllUsersToDefaultTeam() throws DBException {
if (securityController instanceof CBEmbeddedSecurityController<?> controller) {
controller.addAllUsersToDefaultTeam();
}
}

protected void initializeAdditionalConfiguration() {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ public void deleteUser(String userId) throws DBCException {
application.getEventController().addEvent(event);
}

@Override
public void setUserTeams(String userId, String[] teamIds, String grantorId) throws DBCException {
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
Expand All @@ -230,6 +229,10 @@ public void setUserTeams(@NotNull Connection dbCon, String userId, String[] team
database.normalizeTableNames("DELETE FROM {table_prefix}CB_USER_TEAM WHERE USER_ID=?"),
userId
);
String defaultUserTeam = application.getAppConfiguration().getDefaultUserTeam();
if (CommonUtils.isNotEmpty(defaultUserTeam) && !ArrayUtils.contains(teamIds, defaultUserTeam)) {
teamIds = ArrayUtils.add(String.class, teamIds, defaultUserTeam);
}
if (!ArrayUtils.isEmpty(teamIds)) {
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("INSERT INTO {table_prefix}CB_USER_TEAM" +
Expand All @@ -246,6 +249,51 @@ public void setUserTeams(@NotNull Connection dbCon, String userId, String[] team
}
}

public void addAllUsersToDefaultTeam() throws DBCException {
if (application.isConfigurationMode()) {
return;
}
if (CommonUtils.isEmpty(application.getAppConfiguration().getDefaultUserTeam())) {
return;
}

try (Connection dbCon = database.openConnection()) {
try (PreparedStatement dbStat = dbCon.prepareStatement(
database.normalizeTableNames("SELECT USER_ID \n" +
"FROM {table_prefix}CB_USER\n" +
"WHERE USER_ID NOT IN (\n" +
" SELECT USER_ID FROM {table_prefix}CB_USER_TEAM CUT WHERE CUT.TEAM_ID = ? \n" +
")")
)) {
dbStat.setString(1, application.getAppConfiguration().getDefaultUserTeam());
ResultSet dbResult = dbStat.executeQuery();
List<String> usersIds = new ArrayList<>();
while (dbResult.next()) {
String userId = dbResult.getString(1);
usersIds.add(userId);
}

if (usersIds.isEmpty()) {
return;
}

for (String usersId : usersIds) {
try (PreparedStatement insertStat = dbCon.prepareStatement(
database.normalizeTableNames("INSERT INTO {table_prefix}CB_USER_TEAM(USER_ID, TEAM_ID, GRANT_TIME, GRANTED_BY)" +
" VALUES(?,?,?,?)"))) {
insertStat.setString(1, usersId);
insertStat.setString(2, application.getAppConfiguration().getDefaultUserTeam());
insertStat.setTimestamp(3, new Timestamp(System.currentTimeMillis()));
insertStat.setString(4, "CloudBeaver Application");
insertStat.executeUpdate();
}
}
}
} catch (SQLException e) {
throw new DBCException("Error while setting default user teams", e);
}
}


@NotNull
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,9 @@ export function useResource<
}

if (key === null || propertiesRef.key === null || !propertiesRef.resource.isEqual(key, propertiesRef.key)) {
propertiesRef.key = key;
if (propertiesRef.key !== key) {
propertiesRef.key = key;
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
useTranslate,
} from '@cloudbeaver/core-blocks';
import { CachedResourceOffsetPageListKey } from '@cloudbeaver/core-resource';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { TabContainerPanelComponent, useTab } from '@cloudbeaver/core-ui';

import type { ITeamFormProps } from '../ITeamFormProps';
Expand All @@ -38,20 +39,33 @@ export const GrantedUsers: TabContainerPanelComponent<ITeamFormProps> = observer
const state = useGrantedUsers(formState.config, formState.mode);
const { selected } = useTab(tabId);

const serverConfigResource = useResource(UserList, ServerConfigResource, undefined, { active: selected });
const isDefaultTeam = formState.config.teamId === serverConfigResource.data?.defaultUserTeam;

const users = useResource(GrantedUsers, UsersResource, CachedResourceOffsetPageListKey(0, 1000).setTarget(UsersResourceFilterKey()), {
active: selected,
active: selected && !isDefaultTeam,
});

const grantedUsers = getComputed(() =>
users.data.filter<AdminUser>((user): user is AdminUser => !!user && state.state.grantedUsers.includes(user.userId)),
);

useAutoLoad(GrantedUsers, state, selected && !state.state.loaded);
useAutoLoad(GrantedUsers, state, selected && !state.state.loaded && !isDefaultTeam);

if (!selected) {
return null;
}

if (isDefaultTeam) {
return (
<ColoredContainer className={s(styles, { box: true })} parent gap vertical>
<Group className={s(styles, { placeholderBox: true })} keepSize large>
<TextPlaceholder>{translate('plugin_authentication_administration_team_default_users_tooltip')}</TextPlaceholder>
</Group>
</ColoredContainer>
);
}

return (
<Loader className={s(styles, { loader: true })} state={[state.state]}>
{() => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
let grantedTeams: string[] = [];

if (this.state.userId) {
grantedTeams = this.usersResource.get(this.state.userId)?.grantedTeams ?? [];
grantedTeams = toJS(this.usersResource.get(this.state.userId)?.grantedTeams ?? []);
}

if (isArraysEqual(this.state.teams, grantedTeams)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { observer } from 'mobx-react-lite';
import { compareTeams, TeamsResource } from '@cloudbeaver/core-authentication';
import { FieldCheckbox, Group, GroupTitle, useResource, useTranslate } from '@cloudbeaver/core-blocks';
import { CachedMapAllKey } from '@cloudbeaver/core-resource';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { isDefined } from '@cloudbeaver/core-utils';

import type { UserFormProps } from '../AdministrationUserFormService';
Expand All @@ -23,27 +24,33 @@ interface Props extends UserFormProps {

export const UserFormInfoTeams = observer<Props>(function UserFormInfoTeams({ formState, tabState, tabSelected, disabled }) {
const translate = useTranslate();
const serverConfigResource = useResource(UserFormInfoTeams, ServerConfigResource, undefined);
const teamsLoader = useResource(UserFormInfoTeams, TeamsResource, CachedMapAllKey, { active: tabSelected });
const teams = teamsLoader.data.filter(isDefined).sort(compareTeams);
const defaultTeam = serverConfigResource.data?.defaultUserTeam;

return (
<>
<GroupTitle>{translate('authentication_user_team')}</GroupTitle>
<Group boxNoOverflow gap dense>
{teams.map(team => {
const isDefault = team.teamId === defaultTeam;
const label = `${team.teamId}${team.teamName && team.teamName !== team.teamId ? ' (' + team.teamName + ')' : ''}`;
const tooltip = `${label}${team.description ? '\n' + team.description : ''}`;

return (
<FieldCheckbox
key={team.teamId}
id={`${formState.id}_${team.teamId}`}
title={tooltip}
label={label}
name="teams"
state={tabState.state}
value={team.teamId}
caption={isDefault ? translate('plugin_authentication_administration_user_team_default_readonly_tooltip') : undefined}
readOnly={isDefault}
disabled={disabled}
>
{label}
</FieldCheckbox>
/>
);
})}
</Group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,7 @@ export default [
['administration_teams_team_granted_connections_tab_title', 'Connections'],
['administration_teams_team_granted_connections_search_placeholder', 'Search for connection name...'],
['administration_teams_team_granted_connections_empty', 'No available connections'],

['plugin_authentication_administration_user_team_default_readonly_tooltip', "Default team. Can't be revoked"],
['plugin_authentication_administration_team_default_users_tooltip', 'Default team. Contains all users'],
];
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,7 @@ export default [
'administration_configuration_wizard_configuration_authentication_description',
"Permetti agli utenti di autenticarsi. In alternativa solo l'accesso anonimo sarà attivo",
],

['plugin_authentication_administration_user_team_default_readonly_tooltip', "Default team. Can't be revoked"],
['plugin_authentication_administration_team_default_users_tooltip', 'Default team. Contains all users'],
];
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,7 @@ export default [
['administration_teams_team_granted_connections_tab_title', 'Подключения'],
['administration_teams_team_granted_connections_search_placeholder', 'Поиск по названию подключения...'],
['administration_teams_team_granted_connections_empty', 'Нет доступных подключений'],

['plugin_authentication_administration_user_team_default_readonly_tooltip', 'Команда по умолчанию. Не может быть отозвана'],
['plugin_authentication_administration_team_default_users_tooltip', 'Команда по умолчанию. Содержит всех пользователей'],
];
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,7 @@ export default [
['administration_teams_team_granted_connections_tab_title', '连接'],
['administration_teams_team_granted_connections_search_placeholder', '搜索连接名称...'],
['administration_teams_team_granted_connections_empty', '没有可用连接'],

['plugin_authentication_administration_user_team_default_readonly_tooltip', "Default team. Can't be revoked"],
['plugin_authentication_administration_team_default_users_tooltip', 'Default team. Contains all users'],
];

0 comments on commit 7eba02a

Please sign in to comment.