Rbac setting v2 (#18338)

* Add Search RBAC config option in settings

* add null check

* review comments

* resolve

* WIP search rbac page

* enable / disable search rbac switch added

* testing search RBAC

* Remove Domain and Ignore Build RBAC Query for Bots

* Fix Domain Conditions

* Use common code from Search Client

* update page to preferences -> search

* add playwright tests

* add playwright for search RBAC

* update RBACConditionEvaluator

* No results check added

---------

Co-authored-by: mohitdeuex <mohit.y@deuexsolutions.com>
Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
Co-authored-by: Chira Madlani <chirag@getcollate.io>
Co-authored-by: Mohit Yadav <105265192+mohityadav766@users.noreply.github.com>
This commit is contained in:
Sriharsha Chintalapani 2024-10-23 02:23:53 -07:00 committed by GitHub
parent 7fe07fea35
commit 9d006885d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 469 additions and 40 deletions

View File

@ -58,6 +58,7 @@ import org.openmetadata.schema.analytics.ReportData;
import org.openmetadata.schema.analytics.WebAnalyticEvent;
import org.openmetadata.schema.api.configuration.LoginConfiguration;
import org.openmetadata.schema.api.configuration.profiler.ProfilerConfiguration;
import org.openmetadata.schema.api.searcg.SearchSettings;
import org.openmetadata.schema.auth.EmailVerificationToken;
import org.openmetadata.schema.auth.PasswordResetToken;
import org.openmetadata.schema.auth.PersonalAccessToken;
@ -4776,6 +4777,7 @@ public interface CollectionDAO {
case SLACK_APP_CONFIGURATION, SLACK_INSTALLER, SLACK_BOT, SLACK_STATE -> JsonUtils
.readValue(json, String.class);
case PROFILER_CONFIGURATION -> JsonUtils.readValue(json, ProfilerConfiguration.class);
case SEARCH_SETTINGS -> JsonUtils.readValue(json, SearchSettings.class);
default -> throw new IllegalArgumentException("Invalid Settings Type " + configType);
};
settings.setConfigValue(value);

View File

@ -16,6 +16,7 @@ package org.openmetadata.service.resources.settings;
import static org.openmetadata.schema.settings.SettingsType.CUSTOM_UI_THEME_PREFERENCE;
import static org.openmetadata.schema.settings.SettingsType.EMAIL_CONFIGURATION;
import static org.openmetadata.schema.settings.SettingsType.LOGIN_CONFIGURATION;
import static org.openmetadata.schema.settings.SettingsType.SEARCH_SETTINGS;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@ -28,6 +29,7 @@ import org.openmetadata.api.configuration.LogoConfiguration;
import org.openmetadata.api.configuration.ThemeConfiguration;
import org.openmetadata.api.configuration.UiThemePreference;
import org.openmetadata.schema.api.configuration.LoginConfiguration;
import org.openmetadata.schema.api.searcg.SearchSettings;
import org.openmetadata.schema.email.SmtpSettings;
import org.openmetadata.schema.settings.Settings;
import org.openmetadata.schema.settings.SettingsType;
@ -111,6 +113,17 @@ public class SettingsCache {
.withJwtTokenExpiryTime(3600));
systemRepository.createNewSetting(setting);
}
// Initialise Rbac Settings
Settings storedRbacSettings = systemRepository.getConfigWithKey(SEARCH_SETTINGS.toString());
if (storedRbacSettings == null) {
// Only in case a config doesn't exist in DB we insert it
Settings setting =
new Settings()
.withConfigType(SEARCH_SETTINGS)
.withConfigValue(new SearchSettings().withEnableAccessControl(false));
systemRepository.createNewSetting(setting);
}
}
public static <T> T getSetting(SettingsType settingName, Class<T> clazz) {

View File

@ -14,14 +14,18 @@ import javax.net.ssl.SSLContext;
import javax.ws.rs.core.Response;
import lombok.Getter;
import org.apache.commons.lang3.tuple.Pair;
import org.openmetadata.schema.api.searcg.SearchSettings;
import org.openmetadata.schema.dataInsight.DataInsightChartResult;
import org.openmetadata.schema.dataInsight.custom.DataInsightCustomChart;
import org.openmetadata.schema.dataInsight.custom.DataInsightCustomChartResultList;
import org.openmetadata.schema.service.configuration.elasticsearch.ElasticSearchConfiguration;
import org.openmetadata.schema.settings.SettingsType;
import org.openmetadata.schema.tests.DataQualityReport;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.service.exception.CustomExceptionMessage;
import org.openmetadata.service.resources.settings.SettingsCache;
import org.openmetadata.service.search.models.IndexMapping;
import org.openmetadata.service.search.security.RBACConditionEvaluator;
import org.openmetadata.service.security.policyevaluator.SubjectContext;
import org.openmetadata.service.util.SSLUtil;
import os.org.opensearch.action.bulk.BulkRequest;
@ -280,4 +284,15 @@ public interface SearchClient {
}
Object getLowLevelClient();
static boolean shouldApplyRbacConditions(
SubjectContext subjectContext, RBACConditionEvaluator rbacConditionEvaluator) {
return Boolean.TRUE.equals(
SettingsCache.getSetting(SettingsType.SEARCH_SETTINGS, SearchSettings.class)
.getEnableAccessControl())
&& subjectContext != null
&& !subjectContext.isAdmin()
&& !subjectContext.isBot()
&& rbacConditionEvaluator != null;
}
}

View File

@ -77,7 +77,6 @@ import es.org.elasticsearch.index.query.QueryStringQueryBuilder;
import es.org.elasticsearch.index.query.RangeQueryBuilder;
import es.org.elasticsearch.index.query.ScriptQueryBuilder;
import es.org.elasticsearch.index.query.TermQueryBuilder;
import es.org.elasticsearch.index.query.TermsQueryBuilder;
import es.org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import es.org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import es.org.elasticsearch.index.reindex.DeleteByQueryRequest;
@ -363,22 +362,6 @@ public class ElasticSearchClient implements SearchClient {
getSearchSourceBuilder(
request.getIndex(), request.getQuery(), request.getFrom(), request.getSize());
// Add Domain filter
if (request.isApplyDomainFilter()) {
if (!nullOrEmpty(request.getDomains())) {
TermsQueryBuilder domainFilter =
QueryBuilders.termsQuery("domain.fullyQualifiedName", request.getDomains());
searchSourceBuilder.query(
QueryBuilders.boolQuery().must(searchSourceBuilder.query()).filter(domainFilter));
} else {
// Else condition to list entries where domain field is null
searchSourceBuilder.query(
QueryBuilders.boolQuery()
.must(searchSourceBuilder.query())
.mustNot(QueryBuilders.existsQuery("domain.fullyQualifiedName")));
}
}
buildSearchRBACQuery(subjectContext, searchSourceBuilder);
// Add Filter
@ -2422,7 +2405,7 @@ public class ElasticSearchClient implements SearchClient {
private void buildSearchRBACQuery(
SubjectContext subjectContext, SearchSourceBuilder searchSourceBuilder) {
if (subjectContext != null && !subjectContext.isAdmin()) {
if (SearchClient.shouldApplyRbacConditions(subjectContext, rbacConditionEvaluator)) {
OMQueryBuilder rbacQuery = rbacConditionEvaluator.evaluateConditions(subjectContext);
if (rbacQuery != null) {
searchSourceBuilder.query(

View File

@ -171,7 +171,6 @@ import os.org.opensearch.index.query.QueryStringQueryBuilder;
import os.org.opensearch.index.query.RangeQueryBuilder;
import os.org.opensearch.index.query.ScriptQueryBuilder;
import os.org.opensearch.index.query.TermQueryBuilder;
import os.org.opensearch.index.query.TermsQueryBuilder;
import os.org.opensearch.index.query.functionscore.FunctionScoreQueryBuilder;
import os.org.opensearch.index.query.functionscore.ScoreFunctionBuilders;
import os.org.opensearch.index.reindex.DeleteByQueryRequest;
@ -356,22 +355,6 @@ public class OpenSearchClient implements SearchClient {
getSearchSourceBuilder(
request.getIndex(), request.getQuery(), request.getFrom(), request.getSize());
// Add Domain filter
if (request.isApplyDomainFilter()) {
if (!nullOrEmpty(request.getDomains())) {
TermsQueryBuilder domainFilter =
QueryBuilders.termsQuery("domain.fullyQualifiedName", request.getDomains());
searchSourceBuilder.query(
QueryBuilders.boolQuery().must(searchSourceBuilder.query()).filter(domainFilter));
} else {
// Else condition to list entries where domain field is null
searchSourceBuilder.query(
QueryBuilders.boolQuery()
.must(searchSourceBuilder.query())
.mustNot(QueryBuilders.existsQuery("domain.fullyQualifiedName")));
}
}
buildSearchRBACQuery(subjectContext, searchSourceBuilder);
// Add Query Filter
@ -2385,7 +2368,7 @@ public class OpenSearchClient implements SearchClient {
private void buildSearchRBACQuery(
SubjectContext subjectContext, SearchSourceBuilder searchSourceBuilder) {
if (subjectContext != null && !subjectContext.isAdmin()) {
if (SearchClient.shouldApplyRbacConditions(subjectContext, rbacConditionEvaluator)) {
OMQueryBuilder rbacQuery = rbacConditionEvaluator.evaluateConditions(subjectContext);
if (rbacQuery != null) {
searchSourceBuilder.query(

View File

@ -0,0 +1,16 @@
{
"$id": "https://open-metadata.org/schema/entity/configuration/searchSettings.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SearchSettings",
"description": "This schema defines the Rbac Search Configuration.",
"type": "object",
"javaType": "org.openmetadata.schema.api.searcg.SearchSettings",
"properties": {
"enableAccessControl": {
"type": "boolean",
"description": "Flag to enable or disable the RBAC Search Configuration.",
"default": false
}
},
"additionalProperties": false
}

View File

@ -29,7 +29,8 @@
"slackBot",
"slackInstaller",
"slackState",
"profilerConfiguration"
"profilerConfiguration",
"searchSettings"
]
}
},
@ -72,6 +73,9 @@
},
{
"$ref": "../configuration/profilerConfiguration.json"
},
{
"$ref": "../configuration/searchSettings.json"
}
]
}

View File

@ -73,6 +73,7 @@ export enum GlobalSettingOptions {
DATA_PRODUCTS = 'dataProducts',
DASHBOARD_DATA_MODEL = 'dashboardDataModels',
METRICS = 'metrics',
SEARCH_RBAC = 'search-rbac',
}
export const SETTINGS_OPTIONS_PATH = {
@ -182,6 +183,11 @@ export const SETTINGS_OPTIONS_PATH = {
GlobalSettingsMenuCategory.CUSTOM_PROPERTIES,
`${GlobalSettingsMenuCategory.CUSTOM_PROPERTIES}.${GlobalSettingOptions.GLOSSARY_TERM}`,
],
[GlobalSettingOptions.SEARCH_RBAC]: [
GlobalSettingsMenuCategory.PREFERENCES,
`${GlobalSettingsMenuCategory.PREFERENCES}.${GlobalSettingOptions.SEARCH_RBAC}`,
],
};
export const SETTING_CUSTOM_PROPERTIES_PATH = {

View File

@ -82,7 +82,7 @@ test.describe.serial('Persona operations', () => {
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
await page.waitForSelector('[data-testid="selectable-list"]');
await page.waitForSelector('[data-testid="loader"]', { state: 'detached' });
const searchUser = page.waitForResponse(
`/api/v1/search/query?q=*${encodeURIComponent(
@ -90,8 +90,8 @@ test.describe.serial('Persona operations', () => {
)}*`
);
await page.getByTestId('searchbar').fill(user.responseData.displayName);
await searchUser;
await page
.getByRole('listitem', { name: user.responseData.displayName })
.click();

View File

@ -0,0 +1,189 @@
/*
* Copyright 2024 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect, Page, test as base } from '@playwright/test';
import { PolicyClass } from '../../support/access-control/PoliciesClass';
import { RolesClass } from '../../support/access-control/RolesClass';
import { ApiEndpointClass } from '../../support/entity/ApiEndpointClass';
import { ContainerClass } from '../../support/entity/ContainerClass';
import { DashboardClass } from '../../support/entity/DashboardClass';
import { DashboardDataModelClass } from '../../support/entity/DashboardDataModelClass';
import { MetricClass } from '../../support/entity/MetricClass';
import { MlModelClass } from '../../support/entity/MlModelClass';
import { PipelineClass } from '../../support/entity/PipelineClass';
import { SearchIndexClass } from '../../support/entity/SearchIndexClass';
import { StoredProcedureClass } from '../../support/entity/StoredProcedureClass';
import { TableClass } from '../../support/entity/TableClass';
import { TopicClass } from '../../support/entity/TopicClass';
import { UserClass } from '../../support/user/UserClass';
import { performAdminLogin } from '../../utils/admin';
import { getApiContext, uuid } from '../../utils/common';
const policy = new PolicyClass();
const role = new RolesClass();
const user = new UserClass();
const table = new TableClass();
const entities = [
ApiEndpointClass,
TableClass,
StoredProcedureClass,
DashboardClass,
PipelineClass,
TopicClass,
MlModelClass,
ContainerClass,
SearchIndexClass,
DashboardDataModelClass,
MetricClass,
] as const;
const test = base.extend<{
userWithPermissionPage: Page;
userWithoutPermissionPage: Page;
}>({
userWithPermissionPage: async ({ browser }, use) => {
const { page } = await performAdminLogin(browser);
await use(page);
await page.close();
},
userWithoutPermissionPage: async ({ browser }, use) => {
const page = await browser.newPage();
await user.login(page);
await use(page);
await page.close();
},
});
const searchForEntityShouldWork = async (
fqn: string,
displayName: string,
page: Page
) => {
await page.getByTestId('searchBox').click();
await page.getByTestId('searchBox').fill(fqn);
await page.getByTestId('searchBox').press('Enter');
await expect(page.getByTestId('entity-header-display-name')).toContainText(
displayName
);
await page
.getByTestId('navbar-search-container')
.getByTestId('cancel-icon')
.click();
await page.waitForLoadState('networkidle');
};
const searchForEntityShouldWorkShowNoResult = async (
fqn: string,
displayName: string,
page: Page
) => {
await page.getByTestId('searchBox').click();
await page.getByTestId('searchBox').fill(fqn);
await page.getByTestId('searchBox').press('Enter');
await page.waitForResponse(`api/v1/search/query?**`);
await page.waitForLoadState('networkidle');
await page.waitForSelector('loader', { state: 'hidden' });
await expect(page.getByTestId('entity-header-display-name')).not.toHaveText(
displayName
);
await expect(
page.getByText(`No result found.
Try adjusting your search or filter to find what you are looking for.`)
).toBeVisible();
await page
.getByTestId('navbar-search-container')
.getByTestId('cancel-icon')
.click();
await page.waitForLoadState('networkidle');
};
test.beforeAll(async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);
await user.create(apiContext);
const policyResponse = await policy.create(apiContext, [
{
name: `pw-permission-rule-${uuid()}`,
resources: ['All'],
operations: ['All'],
effect: 'deny',
},
]);
const roleResponse = await role.create(apiContext, [
policyResponse.fullyQualifiedName,
]);
await user.patch({
apiContext,
patchData: [
{
op: 'replace',
path: '/roles',
value: [
{
id: roleResponse.id,
type: 'role',
name: roleResponse.name,
},
],
},
],
});
await afterAction();
});
test.afterAll(async ({ browser }) => {
const { apiContext, afterAction } = await performAdminLogin(browser);
await user.delete(apiContext);
await role.delete(apiContext);
await policy.delete(apiContext);
await table.delete(apiContext);
await afterAction();
});
for (const Entity of entities) {
const entityObj = new Entity();
test(`Search RBAC for ${entityObj.getType()}`, async ({
userWithPermissionPage,
userWithoutPermissionPage,
}) => {
const { apiContext } = await getApiContext(userWithPermissionPage);
try {
await entityObj.create(apiContext);
// verify service search
await searchForEntityShouldWork(
entityObj.entityResponseData?.fullyQualifiedName,
entityObj.entityResponseData?.displayName,
userWithPermissionPage
);
await searchForEntityShouldWorkShowNoResult(
entityObj.entityResponseData?.fullyQualifiedName,
entityObj.entityResponseData?.displayName,
userWithoutPermissionPage
);
} catch (_e) {
// remove entity
} finally {
await entityObj.delete(apiContext);
}
});
}

View File

@ -215,4 +215,4 @@ test.describe.serial(
});
}
}
);
);

View File

@ -17,6 +17,7 @@ import { getApiContext, redirectToHomePage } from '../utils/common';
// use the admin user to login
setup.use({
storageState: 'playwright/.auth/admin.json',
trace: 'on',
});
setup.describe.configure({

View File

@ -48,6 +48,7 @@ import ProfilerConfigurationPage from '../../pages/ProfilerConfigurationPage/Pro
import AddRolePage from '../../pages/RolesPage/AddRolePage/AddRolePage';
import RolesDetailPage from '../../pages/RolesPage/RolesDetailPage/RolesDetailPage';
import RolesListPage from '../../pages/RolesPage/RolesListPage/RolesListPage';
import SearchRBACSettingsPage from '../../pages/SearchRBACSettingsPage/SearchRBACSettingsPage';
import ServicesPage from '../../pages/ServicesPage/ServicesPage';
import ImportTeamsPage from '../../pages/TeamsPage/ImportTeamsPage/ImportTeamsPage';
import TeamsPage from '../../pages/TeamsPage/TeamsPage';
@ -239,6 +240,15 @@ const SettingsRouter = () => {
* Do not change the order of these route
*/}
<AdminProtectedRoute
exact
component={SearchRBACSettingsPage}
path={getSettingPath(
GlobalSettingsMenuCategory.PREFERENCES,
GlobalSettingOptions.SEARCH_RBAC
)}
/>
<AdminProtectedRoute
exact
component={PoliciesListPage}

View File

@ -450,6 +450,7 @@ const NavBar = ({
'text-primary': !isSearchBlur,
})}
component={IconCloseCircleOutlined}
data-testid="cancel-icon"
style={{ fontSize: '16px' }}
onClick={handleClear}
/>

View File

@ -77,6 +77,7 @@ export enum GlobalSettingOptions {
API_ENDPOINTS = 'apiEndpoints',
DATA_PRODUCT = 'dataProducts',
METRICS = 'metrics',
SEARCH_RBAC = 'search-rbac',
}
export const GLOBAL_SETTING_PERMISSION_RESOURCES = [

View File

@ -198,6 +198,10 @@ export const PAGE_HEADERS = {
header: i18n.t('label.login'),
subHeader: i18n.t('message.page-sub-header-for-login-configuration'),
},
SEARCH_RBAC: {
header: i18n.t('label.search'),
subHeader: i18n.t('message.page-sub-header-for-search-setting'),
},
OM_HEALTH: {
header: i18n.t('label.health-check'),
subHeader: i18n.t('message.page-sub-header-for-om-health-configuration'),

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Debug-Protokoll aktivieren",
"enable-lowercase": "enable",
"enable-partition": "Partition aktivieren",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "SMTP-Server aktivieren",
"enabled": "Aktiviert",
"end-date": "Enddatum",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Suchindex für die Datenaufnahme",
"search-index-plural": "Suchindizes",
"search-index-setting-plural": "Suchindexeinstellungen",
"search-rbac": "Search RBAC",
"second-plural": "Sekunden",
"secret-key": "Geheimschlüssel",
"select": "Auswählen",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Konfigurieren Sie die SMTP-Einstellungen zum Senden von E-Mails.",
"email-is-invalid": "Ungültige E-Mail-Adresse.",
"email-verification-token-expired": "E-Mail-Bestätigungs-Token abgelaufen",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Durch Aktivieren der Klassifizierung können Sie nach Entitäten suchen oder diesen zugeordnete Tags zuweisen.",
"enable-column-profile": "Spaltenprofil aktivieren",
"enable-debug-logging": "Debug-Protokollierung aktivieren",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Weise Benutzern oder Teams umfassende rollenbasierte Zugriffsberechtigungen zu.",
"page-sub-header-for-search": "Ingestion von Metadaten aus den beliebtesten Suchdiensten.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Ability to configure the OpenMetadata application to suit your needs.",
"page-sub-header-for-storages": "Ingestion von Metadaten aus den am häufigsten verwendeten Speicherdiensten.",
"page-sub-header-for-table-profile": "Überwache und verstehe die Struktur deiner Tabellen mit dem Profiler.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Enable Debug Log",
"enable-lowercase": "enable",
"enable-partition": "Enable Partition",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Enable SMTP Server",
"enabled": "Enabled",
"end-date": "End Date",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Search Index Ingestion",
"search-index-plural": "Search Indexes",
"search-index-setting-plural": "Search Index Settings",
"search-rbac": "Search RBAC",
"second-plural": "Seconds",
"secret-key": "Secret Key",
"select": "Select",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configure the SMTP Settings for sending Emails.",
"email-is-invalid": "Invalid Email.",
"email-verification-token-expired": "Email Verification Token Expired",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "By enabling classification, you will be able to search by, or assign associated tags to any entity.",
"enable-column-profile": "Enable column profile",
"enable-debug-logging": "Enable debug logging",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Assign comprehensive role based access to Users or Teams.",
"page-sub-header-for-search": "Ingest metadata from the most popular search services.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Ability to configure the OpenMetadata application to suit your needs.",
"page-sub-header-for-storages": "Ingest metadata from the most popular storage services.",
"page-sub-header-for-table-profile": "Monitor and understand your tables structure with the profiler.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Activar logs con debug",
"enable-lowercase": "habilitar",
"enable-partition": "Habilitar partición",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Habilitar Server SMTP",
"enabled": "Habilitado",
"end-date": "Fecha de fin",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Ingesta de Índices de Búsqueda",
"search-index-plural": "Índices de Búsqueda",
"search-index-setting-plural": "Configuración de Índices de Búsqueda",
"search-rbac": "Search RBAC",
"second-plural": "Segundos",
"secret-key": "Clave Secreta",
"select": "Seleccionar",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configure la configuración SMTP para enviar correos electrónicos.",
"email-is-invalid": "Correo electrónico inválido.",
"email-verification-token-expired": "Token de verificación de correo electrónico expirado",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Opción para habilitar las clasificaciones. Podrá ver las etiquetas asociadas dentro de la aplicación.",
"enable-column-profile": "Habilitar el perfil de columna",
"enable-debug-logging": "Habilitar el registro de depuración",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Asigna un acceso basado en roles integral a Usuarios o Equipos.",
"page-sub-header-for-search": "Ingresa metadatos desde los servicios de búsqueda más populares.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Capacidad para configurar la aplicación OpenMetadata según tus necesidades.",
"page-sub-header-for-storages": "Ingresa metadatos desde los servicios de almacenamiento más populares.",
"page-sub-header-for-table-profile": "Monitorea y comprende la estructura de tus tablas con el perfilador.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Activer le Journal de Débogage",
"enable-lowercase": "activer",
"enable-partition": "Activer la Partition",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Activer le Serveur SMTP",
"enabled": "Activé",
"end-date": "Date de Fin",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Index de Recherche pour l'Ingestion",
"search-index-plural": "Indexes de Recherche",
"search-index-setting-plural": "Paramètres des Index de Recherche",
"search-rbac": "Search RBAC",
"second-plural": "Secondes",
"secret-key": "Clé Secrète",
"select": "Sélectionner",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configurer les paramètres SMTP pour l'envoi des emails.",
"email-is-invalid": "L'email est invalide.",
"email-verification-token-expired": "Email de vérification du jeton expiré",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Option pour activer les classifications, vous pourrez voir les tags associés dans l'application",
"enable-column-profile": "Activer le profilage de colonne",
"enable-debug-logging": "Activé le journal de débogage",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Personnalisez le comportement global du profiler en établissant les métriques à calculer à partir des types de données des colonnes",
"page-sub-header-for-roles": "Attribuez des autorisations basées sur les rôles aux utilisateurs ou aux équipes.",
"page-sub-header-for-search": "Ingestion de métadonnées à partir des services de recherche les plus populaires.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Configurez l'application OpenMetadata pour répondre à vos besoins.",
"page-sub-header-for-storages": "Ingestion de métadonnées à partir des services de stockage les plus populaires.",
"page-sub-header-for-table-profile": "Surveillez et comprenez la structure de vos tables avec le profilage.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "הפעל יומן דיבוג",
"enable-lowercase": "הפעל",
"enable-partition": "הפעל מחיצה",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "הפעל שרת SMTP",
"enabled": "מופעל",
"end-date": "תאריך סיום",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "פרסום חיפוש באינדקס",
"search-index-plural": "אינדקסי חיפוש",
"search-index-setting-plural": "הגדרות אינדקס חיפוש",
"search-rbac": "Search RBAC",
"second-plural": "שנייה",
"secret-key": "מפתח סודי",
"select": "בחר",
@ -1480,6 +1482,7 @@
"email-configuration-message": "הגדר את הגדרות SMTP עבור שליחת דואר אלקטרוני.",
"email-is-invalid": "דוא\"ל לא תקין.",
"email-verification-token-expired": "קוד אימות דוא\"ל פג תוקף",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "על ידי הפעלת הסיווג, תוכל לחפש לפיו או להקצות תגי קשר מקושרים לישות.",
"enable-column-profile": "הפעל פרופיל עמודה",
"enable-debug-logging": "הפעל לוג דיבאג",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "הקצאת גישה מבוססת תפקיד למשתמשים או קבוצות.",
"page-sub-header-for-search": "שלב מטה-דאטה משירותי החיפוש הפופולריים ביותר.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Ability to configure the OpenMetadata application to suit your needs.",
"page-sub-header-for-storages": "שלב מטה-דאטה משירותי האחסון הפופולריים ביותר.",
"page-sub-header-for-table-profile": "נטרו, נתחו והבינו את מבנה הטבלאות שלכם באמצועות הפרופיילר.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "デバッグログの表示を有効化",
"enable-lowercase": "enable",
"enable-partition": "パーティションを有効化",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Enable SMTP Server",
"enabled": "Enabled",
"end-date": "終了日時",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Search Index Ingestion",
"search-index-plural": "Search Indexes",
"search-index-setting-plural": "Search Index Settings",
"search-rbac": "Search RBAC",
"second-plural": "秒",
"secret-key": "Secret Key",
"select": "選択",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configure the SMTP Settings for sending Emails.",
"email-is-invalid": "不正なEmailアドレスです。",
"email-verification-token-expired": "Email Verification Token Expired",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Option to enable classifications, You will be able to see associated tags within application",
"enable-column-profile": "Enable column profile",
"enable-debug-logging": "Enable debug logging",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Assign comprehensive role based access to Users or Teams.",
"page-sub-header-for-search": "Ingest metadata from the most popular search services.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Ability to configure the OpenMetadata application to suit your needs.",
"page-sub-header-for-storages": "Ingest metadata from the most popular storage services.",
"page-sub-header-for-table-profile": "Monitor and understand your tables structure with the profiler.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Debuglog inschakelen",
"enable-lowercase": "inschakelen",
"enable-partition": "Partitie inschakelen",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "SMTP-server inschakelen",
"enabled": "Ingeschakeld",
"end-date": "Einddatum",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Zoekindexingestie",
"search-index-plural": "Zoekindexen",
"search-index-setting-plural": "Instellingen voor zoekindexen",
"search-rbac": "Search RBAC",
"second-plural": "Seconden",
"secret-key": "Geheime sleutel",
"select": "Selecteren",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configureer de SMTP-instellingen voor het verzenden van e-mails.",
"email-is-invalid": "Ongeldig e-mailadres.",
"email-verification-token-expired": "E-mailverificatietoken is verlopen",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Door classificatie in te schakelen, kun je zoeken op, of geassocieerde tags toewijzen aan elke entiteit.",
"enable-column-profile": "Schakel kolomprofiel in",
"enable-debug-logging": "Schakel debug-logging in",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Wijs uitgebreide rolgebaseerde toegang toe aan gebruikers of teams.",
"page-sub-header-for-search": "Ingest metadata van de meestgebruikte zoekservices.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Mogelijkheid om de OpenMetadata-toepassing naar eigen behoefte te configureren.",
"page-sub-header-for-storages": "Ingest metadata van de meestgebruikte opslagservices.",
"page-sub-header-for-table-profile": "Volg en begrijp de structuur van je tabellen met de profiler.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "فعال کردن گزارش اشکال‌زدایی",
"enable-lowercase": "فعال کردن",
"enable-partition": "فعال کردن پارتیشن",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "فعال کردن سرور SMTP",
"enabled": "فعال شد",
"end-date": "تاریخ پایان",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "ورود شاخص جستجو",
"search-index-plural": "شاخص‌های جستجو",
"search-index-setting-plural": "تنظیمات شاخص جستجو",
"search-rbac": "Search RBAC",
"second-plural": "ثانیه‌ها",
"secret-key": "کلید مخفی",
"select": "انتخاب کنید",
@ -1480,6 +1482,7 @@
"email-configuration-message": "تنظیمات SMTP را برای ارسال ایمیل پیکربندی کنید.",
"email-is-invalid": "ایمیل نامعتبر است.",
"email-verification-token-expired": "توکن تأیید ایمیل منقضی شده است.",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "با فعال کردن طبقه‌بندی، می‌توانید بر اساس آن جستجو کرده و برچسب‌های مرتبط را به هر موجودیتی اختصاص دهید.",
"enable-column-profile": "پروفایل ستون را فعال کنید.",
"enable-debug-logging": "فعال کردن لاگ‌گیری اشکال‌زدایی.",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "تنظیم رفتار پروفایلر در سطح جهانی با تعیین معیارها بر اساس نوع داده‌های ستون‌ها.",
"page-sub-header-for-roles": "تخصیص دسترسی جامع مبتنی بر نقش به کاربران یا تیم‌ها.",
"page-sub-header-for-search": "ورود متادیتا از پرکاربردترین سرویس‌های جستجو.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "قابلیت پیکربندی برنامه OpenMetadata به‌طور دلخواه.",
"page-sub-header-for-storages": "ورود متادیتا از پرکاربردترین سرویس‌های ذخیره‌سازی.",
"page-sub-header-for-table-profile": "نظارت و درک ساختار جداول خود با استفاده از پروفایلر.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Habilitar Log de Depuração",
"enable-lowercase": "habilitar",
"enable-partition": "Habilitar Partição",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Habilitar Servidor SMTP",
"enabled": "Habilitado",
"end-date": "Data de Término",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Ingestão de Índice de Pesquisa",
"search-index-plural": "Índices de Pesquisa",
"search-index-setting-plural": "Configurações de Índice de Pesquisa",
"search-rbac": "Search RBAC",
"second-plural": "Segundos",
"secret-key": "Chave Secreta",
"select": "Selecionar",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Configure as Configurações SMTP para enviar E-mails.",
"email-is-invalid": "E-mail inválido.",
"email-verification-token-expired": "Token de Verificação de E-mail Expirou",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Ao ativar a classificação, você poderá buscar por, ou atribuir tags associadas a qualquer entidade.",
"enable-column-profile": "Habilitar perfil de coluna",
"enable-debug-logging": "Habilitar registro de depuração",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Atribua acesso baseado em funções abrangentes a usuários ou equipes.",
"page-sub-header-for-search": "Ingestão de metadados dos serviços de pesquisa mais populares.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Habilidade para configurar a aplicação OpenMetadata de acordo com suas necessidades.",
"page-sub-header-for-storages": "Ingestão de metadados dos serviços de armazenamento mais populares.",
"page-sub-header-for-table-profile": "Monitore e compreenda a estrutura de suas tabelas com o examinador.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "Включить журнал отладки",
"enable-lowercase": "enable",
"enable-partition": "Включить раздел",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "Включить SMTP-сервер",
"enabled": "Включено",
"end-date": "Дата окончания",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "Получение поискового индекса",
"search-index-plural": "Search Indexes",
"search-index-setting-plural": "Search Index Settings",
"search-rbac": "Search RBAC",
"second-plural": "Секунды",
"secret-key": "Секретный ключ",
"select": "Выбрать",
@ -1480,6 +1482,7 @@
"email-configuration-message": "Настройте параметры SMTP для отправки электронной почты.",
"email-is-invalid": "Неверный адрес электронной почты.",
"email-verification-token-expired": "Срок действия токена подтверждения электронной почты истек",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "Включив классификацию, вы сможете выполнять поиск или назначать связанные теги любому объекту.",
"enable-column-profile": "Включить профиль столбца",
"enable-debug-logging": "Включить ведение журнала отладки",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "Customize globally the behavior of the profiler by setting the metrics to compute based on columns data types",
"page-sub-header-for-roles": "Назначьте полный доступ на основе ролей пользователям или командам.",
"page-sub-header-for-search": "Ingest metadata from the most popular search services.",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "Ability to configure the OpenMetadata application to suit your needs.",
"page-sub-header-for-storages": "Получайте метаданные из самых популярных служб хранения.",
"page-sub-header-for-table-profile": "Отслеживайте и анализируйте структуру ваших таблиц с помощью профилировщика.",

View File

@ -409,6 +409,7 @@
"enable-debug-log": "启用调试日志",
"enable-lowercase": "启用",
"enable-partition": "启用分区",
"enable-roles-polices-in-search": "Enable Roles & Policies in Search",
"enable-smtp-server": "启用发送邮件功能",
"enabled": "已启用",
"end-date": "结束日期",
@ -1037,6 +1038,7 @@
"search-index-ingestion": "搜索索引提取",
"search-index-plural": "搜索索引",
"search-index-setting-plural": "搜索索引设置",
"search-rbac": "Search RBAC",
"second-plural": "秒",
"secret-key": "秘钥",
"select": "选择",
@ -1480,6 +1482,7 @@
"email-configuration-message": "请配置 SMTP 信息, 以发送邮件",
"email-is-invalid": "电子邮箱无效",
"email-verification-token-expired": "电子邮箱验证令牌已过期",
"enable-access-control-description": "Enable to imply access control to search results. Disable to allow all users to view search results.",
"enable-classification-description": "启用分类选项, 您将可以查看关联的标签",
"enable-column-profile": "启用列分析",
"enable-debug-logging": "启用调试日志",
@ -1723,6 +1726,7 @@
"page-sub-header-for-profiler-configuration": "根据列数据类型计算的指标, 设置全局自定义分析器的行为",
"page-sub-header-for-roles": "分配基于角色的访问权限给用户或团队",
"page-sub-header-for-search": "从最流行的搜索服务中提取元数据",
"page-sub-header-for-search-setting": "Ability to configure the search settings to suit your needs.",
"page-sub-header-for-setting": "能够根据需要配置 OpenMetadata 应用",
"page-sub-header-for-storages": "从最流行的存储类型服务中提取元数据",
"page-sub-header-for-table-profile": "通过数据分析工具了解和跟踪您的数据表结构",

View File

@ -0,0 +1,141 @@
/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { InfoCircleOutlined } from '@ant-design/icons';
import { Col, Row, Switch, Tooltip, Typography } from 'antd';
import { AxiosError } from 'axios';
import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Loader from '../../components/common/Loader/Loader';
import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
import { TitleBreadcrumbProps } from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.interface';
import PageHeader from '../../components/PageHeader/PageHeader.component';
import PageLayoutV1 from '../../components/PageLayoutV1/PageLayoutV1';
import { GRAYED_OUT_COLOR } from '../../constants/constants';
import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.constants';
import { PAGE_HEADERS } from '../../constants/PageHeaders.constant';
import { SearchSettings } from '../../generated/configuration/searchSettings';
import { Settings, SettingType } from '../../generated/settings/settings';
import {
getSearchSettings,
updateSettingsConfig,
} from '../../rest/settingConfigAPI';
import { getSettingPageEntityBreadCrumb } from '../../utils/GlobalSettingsUtils';
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
const SearchRBACSettingsPage = () => {
const { t } = useTranslation();
const [isLoading, setIsLoading] = useState(true);
const [searchConfig, setSearchConfig] = useState<SearchSettings>();
const [isUpdating, setIsUpdating] = useState(false);
const breadcrumbs: TitleBreadcrumbProps['titleLinks'] = useMemo(
() =>
getSettingPageEntityBreadCrumb(
GlobalSettingsMenuCategory.PREFERENCES,
t('label.search')
),
[]
);
const fetchSearchConfig = async () => {
try {
setIsLoading(true);
const loginConfig = await getSearchSettings();
setSearchConfig(loginConfig);
} catch (error) {
showErrorToast(error as AxiosError);
} finally {
setIsLoading(false);
}
};
const handleUpdateClick = async (enabled: boolean) => {
try {
setIsUpdating(true);
const configData = {
config_type: SettingType.SearchSettings,
config_value: { ...searchConfig, enableAccessControl: enabled },
};
const { data } = await updateSettingsConfig(configData as Settings);
showSuccessToast(
t('server.update-entity-success', {
entity: t('label.search-rbac'),
})
);
setSearchConfig(data.config_value as SearchSettings);
} catch (error) {
showErrorToast(error as AxiosError);
} finally {
setIsUpdating(false);
}
};
useEffect(() => {
fetchSearchConfig();
}, []);
if (isLoading) {
return <Loader />;
}
return (
<PageLayoutV1 pageTitle={t('label.login')}>
<Row className="page-container" gutter={[0, 16]}>
<Col span={24}>
<TitleBreadcrumb titleLinks={breadcrumbs} />
</Col>
<Col span={24}>
<Row align="middle" justify="space-between">
<Col>
<PageHeader data={PAGE_HEADERS.SEARCH_RBAC} />
</Col>
</Row>
</Col>
<Col span={12}>
<Row align="middle">
<Col span={24}>
<Typography.Text className="m-0 text-grey-muted">
{t('label.enable-roles-polices-in-search')}
<Tooltip
placement="top"
title={t('message.enable-access-control-description')}
trigger="hover">
<InfoCircleOutlined
className="m-x-xss"
data-testid="enable-access-control-info"
style={{ color: GRAYED_OUT_COLOR }}
/>
</Tooltip>
</Typography.Text>
</Col>
<Col>
<Switch
checked={searchConfig?.enableAccessControl}
disabled={isUpdating}
onChange={handleUpdateClick}
/>
</Col>
</Row>
</Col>
</Row>
</PageLayoutV1>
);
};
export default SearchRBACSettingsPage;

View File

@ -15,6 +15,7 @@ import { AxiosResponse } from 'axios';
import axiosClient from '.';
import { APPLICATION_JSON_CONTENT_TYPE_HEADER } from '../constants/constants';
import { LoginConfiguration } from '../generated/configuration/loginConfiguration';
import { SearchSettings } from '../generated/configuration/searchSettings';
import { UIThemePreference } from '../generated/configuration/uiThemePreference';
import { Settings, SettingType } from '../generated/settings/settings';
@ -59,3 +60,11 @@ export const testEmailConnection = async (data: { email: string }) => {
return response;
};
export const getSearchSettings = async (): Promise<SearchSettings> => {
const response = await axiosClient.get<Settings>(
`/system/settings/${SettingType.SearchSettings}`
);
return response.data.config_value as SearchSettings;
};

View File

@ -338,6 +338,13 @@ class GlobalSettingsClassBase {
key: `${GlobalSettingsMenuCategory.PREFERENCES}.${GlobalSettingOptions.PROFILER_CONFIGURATION}`,
icon: ProfilerConfigIcon,
},
{
label: t('label.search'),
description: t('message.page-sub-header-for-search-setting'),
isProtected: Boolean(isAdminUser),
key: `${GlobalSettingsMenuCategory.PREFERENCES}.${GlobalSettingOptions.SEARCH_RBAC}`,
icon: PoliciesIcon,
},
],
},
{