console: remote schema permissions bug fixes

Co-authored-by: Sooraj <8408875+soorajshankar@users.noreply.github.com>
GitOrigin-RevId: 78c4e144ea32ab1376f36272fab0204c2bd88ef0
This commit is contained in:
Abhijeet Singh Khangarot 2021-03-17 21:26:31 +05:30 committed by hasura-bot
parent 2099208e4b
commit 1c1198c93b
11 changed files with 83 additions and 30 deletions

View File

@ -24,7 +24,7 @@ touch /build/_console_output/cli.log
# start graphql-engine
/build/_server_output/graphql-engine \
--database-url postgres://gql_test@localhost:5432/gql_test serve > /build/_console_output/server.log 2>&1 &
--database-url postgres://gql_test@localhost:5432/gql_test serve --enable-remote-schema-permissions > /build/_console_output/server.log 2>&1 &
wait_for_port 8080

View File

@ -9,7 +9,7 @@
- server: fix issue with parsing of remote schema list of input objects (fix #6584)
- cli: cli-ext is now a native part of cli binary (no longer needed as a plugin)
- console: add browse rows for mssql tables (#805)
- console: remote schema permissions bug fixes (#439)
## v2.0.0-alpha.4

View File

@ -299,6 +299,7 @@ export const createSimpleRemoteSchemaPermission = () => {
testName
)}/permissions`
);
cy.get(getElementFromAlias('role-test-role-rs-1')).should('be.visible');
cy.wait(5000);
};

View File

@ -25,7 +25,11 @@ const TableRow = ({
</th>
);
} else {
rowCells.push(<th key={'role-textbox'}>{roleName}</th>);
rowCells.push(
<th data-test={`role-${roleName}`} key={'role-textbox'}>
{roleName}
</th>
);
}
permTypes.forEach(p => {

View File

@ -21,6 +21,7 @@ export interface MainState {
is_function_permissions_inferred: boolean;
is_admin_secret_set: boolean;
is_auth_hook_set: boolean;
is_remote_schema_permissions_enabled: boolean;
is_jwt_set: boolean;
experimental_features: string[];
jwt: {
@ -59,6 +60,7 @@ const defaultState: MainState = {
is_function_permissions_inferred: true,
is_admin_secret_set: false,
is_auth_hook_set: false,
is_remote_schema_permissions_enabled: false,
experimental_features: [],
is_jwt_set: false,
jwt: {

View File

@ -83,7 +83,7 @@ export const Field: React.FC<FieldProps> = ({
>
{i.name}
</span>
{i.args && ' ('}
{i.args && Object.keys(i.args).length !== 0 && ' ('}
{i.args && (
<ul data-test={i.name}>
{i.args &&
@ -99,7 +99,7 @@ export const Field: React.FC<FieldProps> = ({
))}
</ul>
)}
{i.args && ' )'}
{i.args && Object.keys(i.args).length !== 0 && ' )'}
{i.return && (
<span className={styles.fw_large}>
:

View File

@ -128,6 +128,7 @@ const Permissions: React.FC<PermissionsProps> = props => {
currentRemoteSchema={currentRemoteSchema}
permissionEdit={permissionEdit}
isEditing={isEditing}
schema={schema}
bulkSelect={bulkSelect}
readOnlyMode={readOnlyMode}
permSetRoleName={permSetRoleName}

View File

@ -1,9 +1,14 @@
import React, { ChangeEvent } from 'react';
import { GraphQLSchema } from 'graphql';
import styles from '../../../Common/Permissions/PermissionStyles.scss';
import PermTableHeader from '../../../Common/Permissions/TableHeader';
import PermTableBody from '../../../Common/Permissions/TableBody';
import { permissionsSymbols } from '../../../Common/Permissions/PermissionSymbols';
import { findRemoteSchemaPermission } from './utils';
import {
buildSchemaFromRoleDefn,
findRemoteSchemaPermission,
getRemoteSchemaFields,
} from './utils';
import {
RolePermissions,
PermOpenEditType,
@ -22,6 +27,7 @@ export type PermissionsTableProps = {
name: string;
permissions?: PermissionsType[];
};
schema: GraphQLSchema;
bulkSelect: string[];
readOnlyMode: boolean;
permissionEdit: PermissionEdit;
@ -37,6 +43,7 @@ const PermissionsTable: React.FC<PermissionsTableProps> = ({
isEditing,
bulkSelect,
readOnlyMode,
schema,
permSetRoleName,
permSetBulkSelect,
setSchemaDefinition,
@ -139,10 +146,28 @@ const PermissionsTable: React.FC<PermissionsTableProps> = ({
permissionAccess = permissionsSymbols.noAccess;
} else {
const existingPerm = findRemoteSchemaPermission(allPermissions, role);
if (!existingPerm) {
permissionAccess = permissionsSymbols.noAccess;
} else {
if (existingPerm) {
const remoteFields = getRemoteSchemaFields(
schema,
buildSchemaFromRoleDefn(existingPerm?.definition.schema)
);
permissionAccess = permissionsSymbols.fullAccess;
if (
remoteFields
.filter(
field =>
!field.name.startsWith('enum') &&
!field.name.startsWith('scalar')
)
.some(field =>
field.children?.some(element => element.checked === false)
)
) {
permissionAccess = permissionsSymbols.partialAccess;
}
} else {
permissionAccess = permissionsSymbols.noAccess;
}
}
return permissionAccess;
@ -182,10 +207,13 @@ const PermissionsTable: React.FC<PermissionsTableProps> = ({
<div>
<div className={styles.permissionsLegend}>
<span className={styles.permissionsLegendValue}>
{permissionsSymbols.fullAccess} : allowed
{permissionsSymbols.fullAccess} : full access
</span>
<span className={styles.permissionsLegendValue}>
{permissionsSymbols.noAccess} : not allowed
{permissionsSymbols.noAccess} : no access
</span>
<span className={styles.permissionsLegendValue}>
{permissionsSymbols.partialAccess} : partial access
</span>
</div>
</div>

View File

@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react';
import { FieldType, ExpandedItems, PermissionEdit } from './types';
import { Field } from './Field';
import styles from '../../../Common/Permissions/PermissionStyles.scss';
import { addDepFields, getExpandeItems } from './utils';
import { addDepFields, getExpandedItems } from './utils';
type RSPTreeComponentProps = {
list: FieldType[];
@ -51,14 +51,16 @@ const Tree: React.FC<RSPTreeComponentProps> = ({
);
useEffect(() => {
const expandedItemsFromList = getExpandeItems(list);
const expandedItemsFromList = getExpandedItems(list);
setExpandedItems({ ...expandedItems, ...expandedItemsFromList }); // this will only handle expand, it wont collapse anything which are already expanded.
}, [list]);
useEffect(() => {
if (
permissionEdit?.isNewRole &&
permissionEdit?.isNewRole !== prevIsNewRole.current
permissionEdit &&
(!permissionEdit?.isNewRole ||
(permissionEdit?.isNewRole &&
permissionEdit?.isNewRole !== prevIsNewRole.current))
) {
// ignore the new role name change event
setExpandedItems({});

View File

@ -22,30 +22,42 @@ import {
rolesSelector,
getRemoteSchemaPermissions,
} from '../../../../metadata/selector';
import { RemoteSchema } from '../../../../metadata/types';
export type RSPContainerProps = {
allRoles: string[];
allRemoteSchemas: RemoteSchema[];
params: { remoteSchemaName: string };
viewRemoteSchema: (data: string) => void;
rspEnabled: boolean;
};
const RSP: React.FC<Props> = props => {
const { allRoles, allRemoteSchemas, params, viewRemoteSchema } = props;
const {
allRoles,
allRemoteSchemas,
params,
viewRemoteSchema,
rspEnabled,
} = props;
return (
<RSPWrapper
params={params}
allRemoteSchemas={allRemoteSchemas}
tabName="permissions"
viewRemoteSchema={viewRemoteSchema}
permissionRenderer={currentRemoteSchema => (
<Permissions
allRoles={allRoles}
{...props}
{...{ currentRemoteSchema }}
/>
)}
permissionRenderer={currentRemoteSchema =>
rspEnabled ? (
<Permissions
allRoles={allRoles}
{...props}
{...{ currentRemoteSchema }}
/>
) : (
<div>
Remote schema permissions are not enabled. To enable remote schema
permissions, start the Hasura server with environment variable
<code>
HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS: &quot;true&quot;
</code>
</div>
)
}
/>
);
};
@ -56,6 +68,8 @@ const mapStateToProps = (state: ReduxState) => {
...state.remoteSchemas,
allRoles: rolesSelector(state),
allRemoteSchemas: getRemoteSchemas(state),
rspEnabled:
state.main.serverConfig?.data?.is_remote_schema_permissions_enabled,
readOnlyMode: state.main.readOnlyMode,
};
};
@ -89,7 +103,8 @@ const connector = connect(mapStateToProps, mapDispatchToProps);
type InjectedProps = ConnectedProps<typeof connector>;
type ComponentProps = RSPWrapperProps & PermissionsProps;
type ComponentProps = RSPWrapperProps & PermissionsProps & RSPContainerProps;
type Props = ComponentProps & InjectedProps;
const RSPContainer = connector(RSP);

View File

@ -767,7 +767,7 @@ export const addDepFields = (list: FieldType[], field: FieldType) => {
return newList;
};
export const getExpandeItems = (list: FieldType[]) => {
export const getExpandedItems = (list: FieldType[]) => {
const res: ExpandedItems = {};
list.forEach((item: FieldType, ix) => {
const hasValidChildren = item?.children?.find(i => i.checked === true);