Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSD Permission and Permission Evaluation POC 2.0.2 #2

Open
wants to merge 8 commits into
base: 2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .lycheeexclude
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ http://localhost
https://localhost
http://127.0.0.1/
https://127.0.0.1/
http://127.0.0.1:10002/bar
http://127.0.0.1:10002/bar
http://127.0.0.1:10002/
http://opensearch
https://opensearch
Expand Down Expand Up @@ -35,6 +35,7 @@ http://noone.nowhere.none/
http://bar
http://foo
http://test.com/
https://manifest.foobar
https://files.foobar/
https://tiles.foobar/
https://1.1.1.1:9200/
Expand All @@ -51,7 +52,7 @@ http://buildurl/
https://dryrun/
https://url/
http://url/
http://notfound.svg/
http://notfound.svg/
https://validurl/
https://myopensearch-dashboardsdomain.com
http://myopensearch-dashboardsdomain.com
Expand Down Expand Up @@ -111,4 +112,4 @@ https://developer.mozilla.org/
https://a.tile.openstreetmap.org/
http://www.creedthoughts.gov
https://media-for-the-masses.theacademyofperformingartsandscience.org/
https://yarnpkg.com/latest.msi
https://yarnpkg.com/latest.msi
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"dashboarding"
],
"private": true,
"version": "2.0.1",
"version": "2.0.2",
"branch": "2.0",
"types": "./opensearch_dashboards.d.ts",
"tsdocMetadata": "./build/tsdoc-metadata.json",
Expand Down
9 changes: 9 additions & 0 deletions release-notes/opensearch-dashboards.release-notes-2.0.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Version 2.0.1 Release Notes

### 🐛 Bug Fixes
* [Bug] Fixes WMS can't load error when unable access maps services ([#1550](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1550))
* [Bug] Fixes the header loading spinner position in Firefox ([#1570](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1570))
* [Bug] Fixes metric vizualization cut off text ([#1650](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1650))

### 🛠 Maintenance
* Removes duplicate var in opensearch-dashboards-docker ([#1649](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/1649))
3 changes: 2 additions & 1 deletion src/core/server/http/router/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ export class Router implements IRouter {
opensearchDashboardsRequest,
opensearchDashboardsResponseFactory
);
return hapiResponseAdapter.handle(opensearchDashboardsResponse);
return hapiResponseAdapter.
handle(opensearchDashboardsResponse);
} catch (e) {
this.log.error(e);
// forward 401 errors from OpenSearch client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export class OpenSearchMapsClient extends EMSClient {
try {
result = await this._fetchWithTimeout(this._manifestServiceUrl);
} catch (e) {
// silently ignoring the exception and returning false.
return false;
// silently ignoring the exception and returning true to make sure
// OpenSearchMapsClient is still enabled when can't access OpenSearch maps service.
return true;
}
if (result.ok) {
const resultJson = await result.json();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { OpenSearchMapsClient } from './opensearch_maps_client.js';

describe('opensearch_maps_client test without Internet', function () {
const noInternetManifestUrl = 'https://manifest.foobar';
const defaultClientConfig = {
appName: 'opensearch-dashboards',
osdVersion: '1.2.3',
language: 'en',
landingPageUrl: '',
fetchFunction: function (...args) {
return fetch(...args);
},
};

function makeOpenSearchMapsClient() {
const openSearchMapsClient = new OpenSearchMapsClient({
...defaultClientConfig,
manifestServiceUrl: noInternetManifestUrl,
});
return openSearchMapsClient;
}

it('isEnabled() should return true when catch error', async function () {
const mapsClient = makeOpenSearchMapsClient();
const osmIsEnabled = await mapsClient.isEnabled();
expect(osmIsEnabled).toEqual(true);
});
});
52 changes: 42 additions & 10 deletions src/plugins/maps_legacy/public/map/service_settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ import { ORIGIN } from '../common/constants/origin';

const TMS_IN_YML_ID = 'TMS in config/opensearch_dashboards.yml';

// When unable to fetch OpenSearch maps service, return default values to
// make sure wms can be set up.
export const DEFAULT_SERVICE = [
{
origin: 'elastic_maps_service',
id: 'road_map',
minZoom: 0,
maxZoom: 22,
attribution:
'<a rel="noreferrer noopener" href="https://www.openstreetmap.org/copyright">Map data © OpenStreetMap contributors</a>',
},
];

export class ServiceSettings {
constructor(mapConfig, tilemapsConfig) {
this._mapConfig = mapConfig;
Expand Down Expand Up @@ -153,8 +166,12 @@ export class ServiceSettings {
}

await this._setMapServices();
const fileLayers = await this._emsClient.getFileLayers();
return fileLayers.map(this._backfillSettings);
try {
const fileLayers = await this._emsClient.getFileLayers();
return fileLayers.map(this._backfillSettings);
} catch (e) {
return [];
}
}

/**
Expand All @@ -173,7 +190,12 @@ export class ServiceSettings {

await this._setMapServices();
if (this._mapConfig.includeOpenSearchMapsService) {
const servicesFromManifest = await this._emsClient.getTMSServices();
let servicesFromManifest = [];
try {
servicesFromManifest = await this._emsClient.getTMSServices();
} catch (e) {
return DEFAULT_SERVICE;
}
const strippedServiceFromManifest = await Promise.all(
servicesFromManifest
.filter((tmsService) => tmsService.getId() === this._mapConfig.emsTileLayerId.bright)
Expand Down Expand Up @@ -205,12 +227,17 @@ export class ServiceSettings {
}

async getFileLayerFromConfig(fileLayerConfig) {
const fileLayers = await this._emsClient.getFileLayers();
return fileLayers.find((fileLayer) => {
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
return hasIdByName || hasIdById;
});
let fileLayers = [];
try {
fileLayers = await this._emsClient.getFileLayers();
return fileLayers.find((fileLayer) => {
const hasIdByName = fileLayer.hasId(fileLayerConfig.name); //legacy
const hasIdById = fileLayer.hasId(fileLayerConfig.id);
return hasIdByName || hasIdById;
});
} catch (err) {
return null;
}
}

async getEMSHotLink(fileLayerConfig) {
Expand All @@ -226,7 +253,12 @@ export class ServiceSettings {

async _getAttributesForEMSTMSLayer(isDesaturated, isDarkMode) {
await this._setMapServices();
const tmsServices = await this._emsClient.getTMSServices();
let tmsServices = [];
try {
tmsServices = await this._emsClient.getTMSServices();
} catch (e) {
return DEFAULT_SERVICE;
}
const emsTileLayerId = this._mapConfig.emsTileLayerId;
let serviceId;
if (isDarkMode) {
Expand Down
49 changes: 44 additions & 5 deletions src/plugins/maps_legacy/public/map/service_settings.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ import EMS_STYLE_ROAD_MAP_BRIGHT from '../__tests__/map/ems_mocks/sample_style_b
import EMS_STYLE_ROAD_MAP_DESATURATED from '../__tests__/map/ems_mocks/sample_style_desaturated';
import EMS_STYLE_DARK_MAP from '../__tests__/map/ems_mocks/sample_style_dark';
import { ORIGIN } from '../common/constants/origin';
import { ServiceSettings } from './service_settings';
import { ServiceSettings, DEFAULT_SERVICE } from './service_settings';

describe('service_settings (FKA tile_map test)', function () {
const emsFileApiUrl = 'https://files.foobar';
const emsTileApiUrl = 'https://tiles.foobar';
const noInternetManifestUrl = 'https://manifest.foobar';

const defaultMapConfig = {
emsFileApiUrl,
Expand All @@ -63,11 +64,23 @@ describe('service_settings (FKA tile_map test)', function () {
options: {},
};

function makeServiceSettings(mapConfigOptions = {}, tilemapOptions = {}) {
function makeServiceSettings(mapConfigOptions = {}, tilemapOptions = {}, otherOptions = {}) {
const { noInternet } = otherOptions;
const serviceSettings = new ServiceSettings(
{ ...defaultMapConfig, ...mapConfigOptions },
{ ...defaultTilemapConfig, ...tilemapOptions }
{
...defaultMapConfig,
...mapConfigOptions,
opensearchManifestServiceUrl: noInternet ? noInternetManifestUrl : '',
},
{
...defaultTilemapConfig,
...tilemapOptions,
}
);
if (noInternet) {
return serviceSettings;
}

serviceSettings.__debugStubManifestCalls(async (url) => {
//simulate network calls
if (url.startsWith('https://tiles.foobar')) {
Expand All @@ -86,7 +99,6 @@ describe('service_settings (FKA tile_map test)', function () {
});
return serviceSettings;
}

describe('TMS', function () {
it('should NOT get url from the config', async function () {
const serviceSettings = makeServiceSettings();
Expand Down Expand Up @@ -281,6 +293,19 @@ describe('service_settings (FKA tile_map test)', function () {
expect(tilemapServices).toEqual(expected);
});
});

describe('when unable to access OpenSearch maps service', function () {
const expectedDefaultTmService = DEFAULT_SERVICE[0];
it('should return default service', async () => {
const serviceSettings = makeServiceSettings({}, {}, { noInternet: true });
const tileMapServices = await serviceSettings.getTMSServices();
expect(tileMapServices[0]).toMatchObject(expectedDefaultTmService);
const isDesaturated = true;
const isDarkMode = true;
const attrs = await serviceSettings._getAttributesForEMSTMSLayer(isDesaturated, isDarkMode);
expect(attrs[0]).toMatchObject(expectedDefaultTmService);
});
});
});

describe('File layers', function () {
Expand Down Expand Up @@ -353,5 +378,19 @@ describe('service_settings (FKA tile_map test)', function () {
'<a rel="noreferrer noopener" href="http://www.naturalearthdata.com/about/terms-of-use">&lt;div onclick=\'alert(1\')&gt;Made with NaturalEarth&lt;/div&gt;</a> | <a rel="noreferrer noopener">OpenSearch Maps Service</a>'
);
});

describe('when unable to access maps service', function () {
const serviceSettings = makeServiceSettings({}, {}, { noInternet: true });

it('should return empty arr', async () => {
const fileLayers = await serviceSettings.getFileLayers();
expect(fileLayers).toEqual([]);
});

it('should return null', async () => {
const fileLayer = await serviceSettings.getFileLayerFromConfig(null);
expect(fileLayer).toEqual(null);
});
});
});
});
7 changes: 7 additions & 0 deletions src/plugins/permission_management/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
root: true,
extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'],
rules: {
'@osd/eslint/require-license-header': 'off',
},
};
7 changes: 7 additions & 0 deletions src/plugins/permission_management/.i18nrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"prefix": "permissionManagement",
"paths": {
"permissionManagement": "."
},
"translations": ["translations/ja-JP.json"]
}
11 changes: 11 additions & 0 deletions src/plugins/permission_management/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# permissionManagement

A OpenSearch Dashboards plugin

---

## Development

See the [OpenSearch Dashboards contributing
guide](https://github.com/opensearch-project/OpenSearch-Dashboards/blob/master/CONTRIBUTING.md) for instructions
setting up your development environment.
2 changes: 2 additions & 0 deletions src/plugins/permission_management/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const PLUGIN_ID = 'permissionManagement';
export const PLUGIN_NAME = 'Permission';
10 changes: 10 additions & 0 deletions src/plugins/permission_management/opensearch_dashboards.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "permissionManagement",
"version": "1.0.0",
"opensearchDashboardsVersion": "opensearchDashboards",
"server": true,
"ui": true,
"requiredPlugins": ["management", "data", "urlForwarding"],
"requiredBundles": ["opensearchDashboardsReact"],
"optionalPlugins": []
}
12 changes: 12 additions & 0 deletions src/plugins/permission_management/server/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PluginInitializerContext } from '../../../core/server';
import { PermissionManagementPlugin } from './plugin';

// This exports static code and TypeScript types,
// as well as, OpenSearch Dashboards Platform `plugin()` initializer.

export function plugin(initializerContext: PluginInitializerContext) {
console.log('~~~~permissionManagement: Started');
return new PermissionManagementPlugin(initializerContext);
}

export { PermissionManagementPluginSetup, PermissionManagementPluginStart } from './types';
41 changes: 41 additions & 0 deletions src/plugins/permission_management/server/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
PluginInitializerContext,
CoreSetup,
CoreStart,
Plugin,
Logger,
} from '../../../core/server';

import { PermissionManagementPluginSetup, PermissionManagementPluginStart } from './types';
import { defineRoutes } from './routes';
import { samplePermission } from './saved_objects';
import { evaluatePermissionRoute } from './routes/permission_evaluation';

export class PermissionManagementPlugin
implements Plugin<PermissionManagementPluginSetup, PermissionManagementPluginStart> {
private readonly logger: Logger;

constructor(initializerContext: PluginInitializerContext) {
this.logger = initializerContext.logger.get();
}

public setup(core: CoreSetup) {
core.savedObjects.registerType(samplePermission);

this.logger.debug('permissionManagement: Setup');
const router = core.http.createRouter();

// Register server side APIs
defineRoutes(router);
evaluatePermissionRoute(router);

return {};
}

public start(core: CoreStart) {
this.logger.debug('permissionManagement: Started');
return {};
}

public stop() {}
}
17 changes: 17 additions & 0 deletions src/plugins/permission_management/server/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { IRouter } from '../../../../core/server';

export function defineRoutes(router: IRouter) {
router.get(
{
path: '/api/permission_management/example',
validate: false,
},
async (context, request, response) => {
return response.ok({
body: {
time: new Date().toISOString(),
},
});
}
);
}
Loading