diff --git a/.circleci/test-console.sh b/.circleci/test-console.sh
index 67fd0bd2754..486de45b70f 100755
--- a/.circleci/test-console.sh
+++ b/.circleci/test-console.sh
@@ -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
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b55bd83bdeb..4f0adbff2a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/console/cypress/integration/remote-schemas/create-remote-schema/spec.ts b/console/cypress/integration/remote-schemas/create-remote-schema/spec.ts
index c9d97c73efb..aabf5864144 100644
--- a/console/cypress/integration/remote-schemas/create-remote-schema/spec.ts
+++ b/console/cypress/integration/remote-schemas/create-remote-schema/spec.ts
@@ -299,6 +299,7 @@ export const createSimpleRemoteSchemaPermission = () => {
testName
)}/permissions`
);
+ cy.get(getElementFromAlias('role-test-role-rs-1')).should('be.visible');
cy.wait(5000);
};
diff --git a/console/src/components/Common/Permissions/TableRow.js b/console/src/components/Common/Permissions/TableRow.js
index 5485ae08789..dcfa33b22ef 100644
--- a/console/src/components/Common/Permissions/TableRow.js
+++ b/console/src/components/Common/Permissions/TableRow.js
@@ -25,7 +25,11 @@ const TableRow = ({
);
} else {
- rowCells.push(
{roleName} | );
+ rowCells.push(
+
+ {roleName}
+ |
+ );
}
permTypes.forEach(p => {
diff --git a/console/src/components/Main/State.ts b/console/src/components/Main/State.ts
index ca321468fa5..d49027b2fe6 100644
--- a/console/src/components/Main/State.ts
+++ b/console/src/components/Main/State.ts
@@ -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: {
diff --git a/console/src/components/Services/RemoteSchema/Permissions/Field.tsx b/console/src/components/Services/RemoteSchema/Permissions/Field.tsx
index da68c90d520..f0d5df297f8 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/Field.tsx
+++ b/console/src/components/Services/RemoteSchema/Permissions/Field.tsx
@@ -83,7 +83,7 @@ export const Field: React.FC = ({
>
{i.name}
- {i.args && ' ('}
+ {i.args && Object.keys(i.args).length !== 0 && ' ('}
{i.args && (
{i.args &&
@@ -99,7 +99,7 @@ export const Field: React.FC = ({
))}
)}
- {i.args && ' )'}
+ {i.args && Object.keys(i.args).length !== 0 && ' )'}
{i.return && (
:
diff --git a/console/src/components/Services/RemoteSchema/Permissions/Permissions.tsx b/console/src/components/Services/RemoteSchema/Permissions/Permissions.tsx
index a871d2566ec..5e7e1a7098f 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/Permissions.tsx
+++ b/console/src/components/Services/RemoteSchema/Permissions/Permissions.tsx
@@ -128,6 +128,7 @@ const Permissions: React.FC = props => {
currentRemoteSchema={currentRemoteSchema}
permissionEdit={permissionEdit}
isEditing={isEditing}
+ schema={schema}
bulkSelect={bulkSelect}
readOnlyMode={readOnlyMode}
permSetRoleName={permSetRoleName}
diff --git a/console/src/components/Services/RemoteSchema/Permissions/PermissionsTable.tsx b/console/src/components/Services/RemoteSchema/Permissions/PermissionsTable.tsx
index c6b30365035..ad9d373c2d7 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/PermissionsTable.tsx
+++ b/console/src/components/Services/RemoteSchema/Permissions/PermissionsTable.tsx
@@ -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 = ({
isEditing,
bulkSelect,
readOnlyMode,
+ schema,
permSetRoleName,
permSetBulkSelect,
setSchemaDefinition,
@@ -139,10 +146,28 @@ const PermissionsTable: React.FC = ({
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 = ({
- {permissionsSymbols.fullAccess} : allowed
+ {permissionsSymbols.fullAccess} : full access
- {permissionsSymbols.noAccess} : not allowed
+ {permissionsSymbols.noAccess} : no access
+
+
+ {permissionsSymbols.partialAccess} : partial access
diff --git a/console/src/components/Services/RemoteSchema/Permissions/Tree.tsx b/console/src/components/Services/RemoteSchema/Permissions/Tree.tsx
index bb974deba09..f19e32ee429 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/Tree.tsx
+++ b/console/src/components/Services/RemoteSchema/Permissions/Tree.tsx
@@ -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 = ({
);
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({});
diff --git a/console/src/components/Services/RemoteSchema/Permissions/index.tsx b/console/src/components/Services/RemoteSchema/Permissions/index.tsx
index 32778599571..6baaa43d205 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/index.tsx
+++ b/console/src/components/Services/RemoteSchema/Permissions/index.tsx
@@ -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 => {
- const { allRoles, allRemoteSchemas, params, viewRemoteSchema } = props;
+ const {
+ allRoles,
+ allRemoteSchemas,
+ params,
+ viewRemoteSchema,
+ rspEnabled,
+ } = props;
return (
(
-
- )}
+ permissionRenderer={currentRemoteSchema =>
+ rspEnabled ? (
+
+ ) : (
+
+ Remote schema permissions are not enabled. To enable remote schema
+ permissions, start the Hasura server with environment variable
+
+ HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS: "true"
+
+
+ )
+ }
/>
);
};
@@ -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;
-type ComponentProps = RSPWrapperProps & PermissionsProps;
+type ComponentProps = RSPWrapperProps & PermissionsProps & RSPContainerProps;
+
type Props = ComponentProps & InjectedProps;
const RSPContainer = connector(RSP);
diff --git a/console/src/components/Services/RemoteSchema/Permissions/utils.ts b/console/src/components/Services/RemoteSchema/Permissions/utils.ts
index 652e118cdf7..30754956e87 100644
--- a/console/src/components/Services/RemoteSchema/Permissions/utils.ts
+++ b/console/src/components/Services/RemoteSchema/Permissions/utils.ts
@@ -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);