mirror of
https://github.com/graphql-hive/console
synced 2026-05-23 17:18:23 +00:00
Align target access on UI with backend (#5664)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
bdff2e7b21
commit
7fc7d4297e
5 changed files with 61 additions and 33 deletions
|
|
@ -588,7 +588,7 @@ export class SchemaManager {
|
|||
this.logger.debug('Updating base schema (selector=%o)', selector);
|
||||
await this.authManager.ensureTargetAccess({
|
||||
...selector,
|
||||
scope: TargetAccessScope.REGISTRY_READ,
|
||||
scope: TargetAccessScope.REGISTRY_WRITE,
|
||||
});
|
||||
await this.storage.updateBaseSchema(selector, newBaseSchema);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,14 +128,26 @@ export const TargetLayout = ({
|
|||
|
||||
useLastVisitedOrganizationWriter(currentOrganization?.cleanId);
|
||||
|
||||
const canAccessSchema = canAccessTarget(
|
||||
const hasRegistryReadAccess = canAccessTarget(
|
||||
TargetAccessScope.RegistryRead,
|
||||
currentOrganization?.me ?? null,
|
||||
);
|
||||
const canAccessSettings = canAccessTarget(
|
||||
const hasReadAccess = canAccessTarget(TargetAccessScope.Read, currentOrganization?.me ?? null);
|
||||
const hasSettingsAccess = canAccessTarget(
|
||||
TargetAccessScope.Settings,
|
||||
currentOrganization?.me ?? null,
|
||||
);
|
||||
const hasRegistryWriteAccess = canAccessTarget(
|
||||
TargetAccessScope.RegistryWrite,
|
||||
currentOrganization?.me ?? null,
|
||||
);
|
||||
const hasTokensWriteAccess = canAccessTarget(
|
||||
TargetAccessScope.TokensWrite,
|
||||
currentOrganization?.me ?? null,
|
||||
);
|
||||
|
||||
const canAccessSettingsPage =
|
||||
hasReadAccess || hasSettingsAccess || hasRegistryWriteAccess || hasTokensWriteAccess;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -169,7 +181,7 @@ export const TargetLayout = ({
|
|||
{currentOrganization && currentProject && currentTarget ? (
|
||||
<Tabs className="flex h-full grow flex-col" value={page}>
|
||||
<TabsList variant="menu">
|
||||
{canAccessSchema && (
|
||||
{hasRegistryReadAccess && (
|
||||
<>
|
||||
<TabsTrigger variant="menu" value={Page.Schema} asChild>
|
||||
<Link
|
||||
|
|
@ -259,7 +271,7 @@ export const TargetLayout = ({
|
|||
</TabsTrigger>
|
||||
</>
|
||||
)}
|
||||
{canAccessSettings && (
|
||||
{canAccessSettingsPage && (
|
||||
<TabsTrigger variant="menu" value={Page.Settings} asChild>
|
||||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/settings"
|
||||
|
|
|
|||
|
|
@ -425,21 +425,23 @@ export function CDNAccessTokens(props: {
|
|||
created <TimeAgo date={node.createdAt} />
|
||||
</Td>
|
||||
<Td align="right">
|
||||
<Button
|
||||
className="hover:text-red-500"
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
void router.navigate({
|
||||
search: {
|
||||
page: 'cdn',
|
||||
cdn: 'delete',
|
||||
id: node.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
{canManage ? (
|
||||
<Button
|
||||
className="hover:text-red-500"
|
||||
variant="ghost"
|
||||
onClick={() => {
|
||||
void router.navigate({
|
||||
search: {
|
||||
page: 'cdn',
|
||||
cdn: 'delete',
|
||||
id: node.id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<TrashIcon />
|
||||
</Button>
|
||||
) : null}
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1136,11 +1136,26 @@ function TargetSettingsContent(props: {
|
|||
|
||||
const targetForSettings = useFragment(TargetSettingsPage_TargetFragment, currentTarget);
|
||||
|
||||
const canAccessTokens = canAccessTarget(
|
||||
TargetAccessScope.TokensRead,
|
||||
const hasTokensWriteAccess = canAccessTarget(
|
||||
TargetAccessScope.TokensWrite,
|
||||
organizationForSettings?.me ?? null,
|
||||
);
|
||||
const hasReadAccess = canAccessTarget(
|
||||
TargetAccessScope.Read,
|
||||
organizationForSettings?.me ?? null,
|
||||
);
|
||||
const hasDeleteAccess = canAccessTarget(
|
||||
TargetAccessScope.Delete,
|
||||
organizationForSettings?.me ?? null,
|
||||
);
|
||||
const hasSettingsAccess = canAccessTarget(
|
||||
TargetAccessScope.Settings,
|
||||
organizationForSettings?.me ?? null,
|
||||
);
|
||||
const hasRegistryWriteAccess = canAccessTarget(
|
||||
TargetAccessScope.RegistryWrite,
|
||||
organizationForSettings?.me ?? null,
|
||||
);
|
||||
const canDelete = canAccessTarget(TargetAccessScope.Delete, organizationForSettings?.me ?? null);
|
||||
|
||||
if (query.error) {
|
||||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
|
|
@ -1189,7 +1204,7 @@ function TargetSettingsContent(props: {
|
|||
<PageLayoutContent>
|
||||
{currentOrganization && currentProject && currentTarget && organizationForSettings ? (
|
||||
<div className="space-y-12">
|
||||
{props.page === 'general' ? (
|
||||
{props.page === 'general' && hasSettingsAccess ? (
|
||||
<>
|
||||
<TargetName
|
||||
targetName={currentTarget.name}
|
||||
|
|
@ -1203,7 +1218,7 @@ function TargetSettingsContent(props: {
|
|||
organizationId={currentOrganization.cleanId}
|
||||
graphqlEndpointUrl={currentTarget.graphqlEndpointUrl ?? null}
|
||||
/>
|
||||
{canDelete && (
|
||||
{hasDeleteAccess && (
|
||||
<TargetDelete
|
||||
targetId={currentTarget.cleanId}
|
||||
projectId={currentProject.cleanId}
|
||||
|
|
@ -1212,7 +1227,7 @@ function TargetSettingsContent(props: {
|
|||
)}
|
||||
</>
|
||||
) : null}
|
||||
{props.page === 'cdn' && canAccessTokens ? (
|
||||
{props.page === 'cdn' && hasReadAccess ? (
|
||||
<CDNAccessTokens
|
||||
me={organizationForSettings.me}
|
||||
organizationId={props.organizationId}
|
||||
|
|
@ -1220,7 +1235,7 @@ function TargetSettingsContent(props: {
|
|||
targetId={props.targetId}
|
||||
/>
|
||||
) : null}
|
||||
{props.page === 'registry-token' && canAccessTokens ? (
|
||||
{props.page === 'registry-token' && hasTokensWriteAccess ? (
|
||||
<RegistryAccessTokens
|
||||
me={organizationForSettings.me}
|
||||
organizationId={props.organizationId}
|
||||
|
|
@ -1228,14 +1243,14 @@ function TargetSettingsContent(props: {
|
|||
targetId={props.targetId}
|
||||
/>
|
||||
) : null}
|
||||
{props.page === 'breaking-changes' ? (
|
||||
{props.page === 'breaking-changes' && hasSettingsAccess ? (
|
||||
<ConditionalBreakingChanges
|
||||
organizationId={props.organizationId}
|
||||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
/>
|
||||
) : null}
|
||||
{props.page === 'base-schema' ? (
|
||||
{props.page === 'base-schema' && hasRegistryWriteAccess ? (
|
||||
<ExtendBaseSchema
|
||||
baseSchema={targetForSettings?.baseSchema ?? ''}
|
||||
organizationId={props.organizationId}
|
||||
|
|
@ -1243,7 +1258,7 @@ function TargetSettingsContent(props: {
|
|||
targetId={props.targetId}
|
||||
/>
|
||||
) : null}
|
||||
{props.page === 'schema-contracts' ? (
|
||||
{props.page === 'schema-contracts' && hasSettingsAccess ? (
|
||||
<SchemaContracts
|
||||
organizationId={props.organizationId}
|
||||
projectId={props.projectId}
|
||||
|
|
|
|||
|
|
@ -226,9 +226,8 @@ You can use the link provided in the modal right section to let your users login
|
|||
|
||||
### Azure
|
||||
|
||||
After you're logged in to [Azure Portal](https://portal.azure.com/), find the **Azure Entra
|
||||
ID**. On the left sidebar, click on the **Enterprise applications** under the **Manage**
|
||||
section:
|
||||
After you're logged in to [Azure Portal](https://portal.azure.com/), find the **Azure Entra ID**. On
|
||||
the left sidebar, click on the **Enterprise applications** under the **Manage** section:
|
||||
|
||||
<NextImage
|
||||
alt="Azure AD"
|
||||
|
|
|
|||
Loading…
Reference in a new issue