From b38d14fa67a953c737be09219bcd584eb06304a9 Mon Sep 17 00:00:00 2001 From: John Joyce Date: Fri, 22 Apr 2022 12:09:05 -0700 Subject: [PATCH] fix(ui): Display warning in UI when metadata service auth is disabled. (#4728) --- .../datahub/graphql/GmsGraphQLEngine.java | 6 ++++ .../resolvers/config/AppConfigResolver.java | 11 ++++++- .../src/main/resources/app.graphql | 16 ++++++++++ .../src/app/settings/AccessTokens.tsx | 30 +++++++++++++++++-- datahub-web-react/src/appConfigContext.tsx | 3 ++ datahub-web-react/src/graphql/app.graphql | 3 ++ .../factory/graphql/GraphQLEngineFactory.java | 2 ++ 7 files changed, 68 insertions(+), 3 deletions(-) diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java index a149f2c541b1a..1cd91e38a32e5 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/GmsGraphQLEngine.java @@ -1,5 +1,6 @@ package com.linkedin.datahub.graphql; +import com.datahub.authentication.AuthenticationConfiguration; import com.datahub.authentication.token.TokenService; import com.datahub.authorization.AuthorizationConfiguration; import com.google.common.collect.ImmutableList; @@ -221,6 +222,7 @@ public class GmsGraphQLEngine { private final TimeseriesAspectService timeseriesAspectService; private final IngestionConfiguration ingestionConfiguration; + private final AuthenticationConfiguration authenticationConfiguration; private final AuthorizationConfiguration authorizationConfiguration; private final VisualConfiguration visualConfiguration; @@ -288,6 +290,7 @@ public GmsGraphQLEngine() { null, null, null, + null, false, null); } @@ -304,6 +307,7 @@ public GmsGraphQLEngine( final EntityRegistry entityRegistry, final SecretService secretService, final IngestionConfiguration ingestionConfiguration, + final AuthenticationConfiguration authenticationConfiguration, final AuthorizationConfiguration authorizationConfiguration, final GitVersion gitVersion, final boolean supportsImpactAnalysis, @@ -325,6 +329,7 @@ public GmsGraphQLEngine( this.timeseriesAspectService = timeseriesAspectService; this.ingestionConfiguration = Objects.requireNonNull(ingestionConfiguration); + this.authenticationConfiguration = Objects.requireNonNull(authenticationConfiguration); this.authorizationConfiguration = Objects.requireNonNull(authorizationConfiguration); this.visualConfiguration = visualConfiguration; @@ -562,6 +567,7 @@ private void configureQueryResolvers(final RuntimeWiring.Builder builder) { .dataFetcher("appConfig", new AppConfigResolver(gitVersion, analyticsService != null, this.ingestionConfiguration, + this.authenticationConfiguration, this.authorizationConfiguration, supportsImpactAnalysis, this.visualConfiguration)) .dataFetcher("me", new AuthenticatedResolver<>( diff --git a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java index d692ddf10ecd1..8fda3c198c482 100644 --- a/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java +++ b/datahub-graphql-core/src/main/java/com/linkedin/datahub/graphql/resolvers/config/AppConfigResolver.java @@ -1,9 +1,11 @@ package com.linkedin.datahub.graphql.resolvers.config; +import com.datahub.authentication.AuthenticationConfiguration; import com.datahub.authorization.AuthorizationConfiguration; import com.linkedin.datahub.graphql.QueryContext; import com.linkedin.datahub.graphql.generated.AnalyticsConfig; import com.linkedin.datahub.graphql.generated.AppConfig; +import com.linkedin.datahub.graphql.generated.AuthConfig; import com.linkedin.datahub.graphql.generated.EntityType; import com.linkedin.datahub.graphql.generated.IdentityManagementConfig; import com.linkedin.datahub.graphql.generated.LineageConfig; @@ -28,6 +30,7 @@ public class AppConfigResolver implements DataFetcher get(final DataFetchingEnvironment environmen final AnalyticsConfig analyticsConfig = new AnalyticsConfig(); analyticsConfig.setEnabled(_isAnalyticsEnabled); + final AuthConfig authConfig = new AuthConfig(); + authConfig.setTokenAuthEnabled(_authenticationConfiguration.isEnabled()); + final PoliciesConfig policiesConfig = new PoliciesConfig(); policiesConfig.setEnabled(_authorizationConfiguration.getDefaultAuthorizer().isEnabled()); @@ -82,11 +90,12 @@ public CompletableFuture get(final DataFetchingEnvironment environmen final ManagedIngestionConfig ingestionConfig = new ManagedIngestionConfig(); ingestionConfig.setEnabled(_ingestionConfiguration.isEnabled()); + appConfig.setAuthConfig(authConfig); appConfig.setAnalyticsConfig(analyticsConfig); appConfig.setPoliciesConfig(policiesConfig); appConfig.setIdentityManagementConfig(identityManagementConfig); appConfig.setManagedIngestionConfig(ingestionConfig); - + appConfig.setAuthConfig(authConfig); appConfig.setVisualConfig(_visualConfiguration); return CompletableFuture.completedFuture(appConfig); diff --git a/datahub-graphql-core/src/main/resources/app.graphql b/datahub-graphql-core/src/main/resources/app.graphql index bd4bec148ab25..a1ce09a6d71a1 100644 --- a/datahub-graphql-core/src/main/resources/app.graphql +++ b/datahub-graphql-core/src/main/resources/app.graphql @@ -78,6 +78,11 @@ type AppConfig { """ appVersion: String + """ + Auth-related configurations + """ + authConfig: AuthConfig! + """ Configurations related to the Analytics Feature """ @@ -139,6 +144,17 @@ type AnalyticsConfig { enabled: Boolean! } +""" +Configurations related to auth +""" +type AuthConfig { + """ + Whether token-based auth is enabled. + """ + tokenAuthEnabled: Boolean! +} + + """ Configurations related to the Policies Feature """ diff --git a/datahub-web-react/src/app/settings/AccessTokens.tsx b/datahub-web-react/src/app/settings/AccessTokens.tsx index a0ace604ee418..a205dba57a429 100644 --- a/datahub-web-react/src/app/settings/AccessTokens.tsx +++ b/datahub-web-react/src/app/settings/AccessTokens.tsx @@ -1,6 +1,8 @@ -import { Button, Divider, Select, Typography } from 'antd'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import { Alert, Button, Divider, Select, Typography } from 'antd'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; +import { useAppConfigQuery } from '../../graphql/app.generated'; import { useGetAccessTokenLazyQuery } from '../../graphql/auth.generated'; import { AccessTokenDuration, AccessTokenType } from '../../types.generated'; import { useGetAuthenticatedUser } from '../useGetAuthenticatedUser'; @@ -32,6 +34,16 @@ const ExpirationSelectConainer = styled.div` padding-bottom: 12px; `; +const StyledAlert = styled(Alert)` + padding-top: 12px; + padding-bottom: 12px; + margin-bottom: 20px; +`; + +const StyledInfoCircleOutlined = styled(InfoCircleOutlined)` + margin-right: 8px; +`; + const ExpirationDurationSelect = styled(Select)` && { width: 120px; @@ -51,7 +63,9 @@ export const AccessTokens = () => { const [showModal, setShowModal] = useState(false); const [selectedTokenDuration, setSelectedTokenDuration] = useState(ACCESS_TOKEN_DURATIONS[0].duration); const authenticatedUser = useGetAuthenticatedUser(); - const canGeneratePersonalAccessTokens = authenticatedUser?.platformPrivileges.generatePersonalAccessTokens; + const isTokenAuthEnabled = useAppConfigQuery().data?.appConfig?.authConfig?.tokenAuthEnabled; + const canGeneratePersonalAccessTokens = + isTokenAuthEnabled && authenticatedUser?.platformPrivileges.generatePersonalAccessTokens; const currentUserUrn = authenticatedUser?.corpUser.urn; const [getAccessToken, { data, error }] = useGetAccessTokenLazyQuery({ @@ -94,6 +108,18 @@ export const AccessTokens = () => { Manage Access Tokens for use with DataHub APIs. + {isTokenAuthEnabled === false && ( + + + Token based authentication is currently disabled. Contact your DataHub administrator to + enable this feature. + + } + /> + )} Personal Access Tokens Personal Access Tokens allow you to make programmatic requests to DataHub's APIs. They inherit your diff --git a/datahub-web-react/src/appConfigContext.tsx b/datahub-web-react/src/appConfigContext.tsx index 7e294dd38c94b..0c0b3bde628b6 100644 --- a/datahub-web-react/src/appConfigContext.tsx +++ b/datahub-web-react/src/appConfigContext.tsx @@ -22,6 +22,9 @@ export const DEFAULT_APP_CONFIG = { visualConfig: { logoUrl: undefined, }, + authConfig: { + tokenAuthEnabled: false, + }, }; export const AppConfigContext = React.createContext<{ diff --git a/datahub-web-react/src/graphql/app.graphql b/datahub-web-react/src/graphql/app.graphql index b36f163cf6e5a..40f7cba9d69d5 100644 --- a/datahub-web-react/src/graphql/app.graphql +++ b/datahub-web-react/src/graphql/app.graphql @@ -22,6 +22,9 @@ query appConfig { analyticsConfig { enabled } + authConfig { + tokenAuthEnabled + } identityManagementConfig { enabled } diff --git a/metadata-service/factories/src/main/java/com/linkedin/gms/factory/graphql/GraphQLEngineFactory.java b/metadata-service/factories/src/main/java/com/linkedin/gms/factory/graphql/GraphQLEngineFactory.java index 6e67c3e8a5243..6538f4af21fc7 100644 --- a/metadata-service/factories/src/main/java/com/linkedin/gms/factory/graphql/GraphQLEngineFactory.java +++ b/metadata-service/factories/src/main/java/com/linkedin/gms/factory/graphql/GraphQLEngineFactory.java @@ -116,6 +116,7 @@ protected GraphQLEngine getInstance() { _entityRegistry, _secretService, _configProvider.getIngestion(), + _configProvider.getAuthentication(), _configProvider.getAuthorization(), _gitVersion, _graphService.supportsMultiHop(), @@ -134,6 +135,7 @@ protected GraphQLEngine getInstance() { _entityRegistry, _secretService, _configProvider.getIngestion(), + _configProvider.getAuthentication(), _configProvider.getAuthorization(), _gitVersion, _graphService.supportsMultiHop(),