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

[Spaces] - prepend space id to document id #21372

Merged
merged 57 commits into from
Aug 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f208d3c
Crude and incomplete impl of Space-Aware Saved Objects Client
legrego May 7, 2018
7538bf3
Code review updates
legrego May 8, 2018
bb3e511
Missed one - move extraBodyProperties to the top
legrego May 8, 2018
0e2e4e8
Remove documentFilter from bulkGet
legrego May 9, 2018
a6287cc
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego May 21, 2018
7db0a4a
Make config document id independent of Kibana version
legrego May 21, 2018
192d9c2
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jun 18, 2018
1c4afd8
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jun 20, 2018
d573457
cleanup and fixes following initial rbac phase 1 merge
legrego Jun 20, 2018
d99cec7
remove unused/migrated files
legrego Jun 20, 2018
7e2d1e3
remove unused code
legrego Jun 20, 2018
862752b
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jun 20, 2018
a63128c
partial updates for space aware saved objects and tests
legrego Jun 22, 2018
858eff0
working get & find functional tests
legrego Jun 22, 2018
1b95aa0
added bulk_get tests
legrego Jun 22, 2018
fc663d9
refactor query params into dedicated module
legrego Jun 25, 2018
fc61594
additional tests and bugfixes for space aware saved objects
legrego Jun 25, 2018
776da8a
revert changes to ui settings service
legrego Jun 25, 2018
d2545d4
additional tests for space-aware saved objects
legrego Jun 25, 2018
1fd7699
Fix navigating to the default space
legrego Jun 25, 2018
9469742
additional unit tests
legrego Jun 25, 2018
e24578f
Create default space on startup, *after* ES has gone green
legrego Jun 25, 2018
5fe4bfd
support & testing for bulk_create for space-enabled installations
legrego Jun 26, 2018
c6e8925
cleanup and docs
legrego Jun 26, 2018
f4a19ab
undo formatting changes
legrego Jun 27, 2018
7827e02
append space id to document id within spaces saved objects client
legrego Jun 29, 2018
dee335b
only allow filters to be passed to getQueryParams
legrego Jun 29, 2018
452de10
don't add space id when updating within the default space
legrego Jun 29, 2018
6bf3515
renaming files
legrego Jun 29, 2018
8cb871a
additional SOC and repository tests
legrego Jul 5, 2018
53bb020
remove default context from utility functions
legrego Jul 5, 2018
90892ca
rename spacesSavedObjectsClientWrapper => spacesSavedObjectsClientWra…
legrego Jul 5, 2018
4181c9e
don't mutate passed options for SOC create method
legrego Jul 5, 2018
a35d15f
allow options to be passed for get and bulkGet
legrego Jul 5, 2018
093dd47
additional review updates
legrego Jul 5, 2018
2dd7464
Merge branch 'space-aware-saved-objects' into prepend-space-id
legrego Jul 5, 2018
3bb2aa7
manually re-add tests from space-aware-saved-objects
legrego Jul 5, 2018
6e1c4c4
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 5, 2018
2195ee0
consolidate init logic
legrego Jul 5, 2018
5fced69
Merge branch 'space-aware-saved-objects' into prepend-space-id
legrego Jul 5, 2018
48c5f23
Add error handling when switching spaces
legrego Jul 6, 2018
3a832e9
rename single character variables
legrego Jul 6, 2018
71f0634
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 9, 2018
00bd94c
fix merge
legrego Jul 16, 2018
415fa09
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 16, 2018
8d48c80
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 19, 2018
7ee1cb0
Merge branch 'space-aware-saved-objects' into prepend-space-id
legrego Jul 19, 2018
bc8aaef
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 20, 2018
839a0cf
Merge branch 'spaces-phase-1' into space-aware-saved-objects
legrego Jul 23, 2018
0ebe3e3
Merge branch 'space-aware-saved-objects' into prepend-space-id
legrego Jul 23, 2018
8b1ff6b
address PR feedback
legrego Jul 23, 2018
e7815e6
Merge branch 'space-aware-saved-objects' into prepend-space-id
legrego Jul 23, 2018
70284a5
Merge branch 'spaces-phase-1' into prepend-space-id
legrego Jul 27, 2018
7e851d0
append space id to document id
legrego Jul 27, 2018
7042889
update functional tests
legrego Jul 27, 2018
560acfa
additional get/bulkget tests
legrego Jul 30, 2018
a5161bf
address PR feedback
legrego Aug 1, 2018
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
1 change: 1 addition & 0 deletions x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"tmp": "0.0.31",
"tree-kill": "^1.1.0",
"typescript": "^2.9.2",
"uuid": "3.0.1",
"vinyl-fs": "^3.0.2",
"xml-crypto": "^0.10.1",
"xml2js": "^0.4.19",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,37 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`current space (space_1) #create #delete does not allow an object to be deleted via a different space 1`] = `"not found"`;
exports[`current space (space_1) #bulk_create throws when the base client returns a malformed document id 1`] = `"Saved object [foo/mock-id] is missing its expected space identifier."`;

exports[`current space (space_1) #create #update does not allow an object to be updated via a different space 1`] = `"not found"`;
exports[`current space (space_1) #bulk_get throws when base client returns documents with malformed ids 1`] = `"Saved object [foo/object_1] is missing its expected space identifier."`;

exports[`current space (space_1) #get returns error when the object belongs to a different space 1`] = `"not found"`;
exports[`current space (space_1) #create throws when the base client returns a malformed document id 1`] = `"Saved object [foo/mock-id] is missing its expected space identifier."`;

exports[`default space #delete does not allow an object to be deleted via a different space 1`] = `"not found"`;
exports[`current space (space_1) #delete does not allow an object to be deleted via a different space 1`] = `"not found: foo space_1:object_2"`;

exports[`default space #get returns error when the object belongs to a different space 1`] = `"not found"`;
exports[`current space (space_1) #find throws when base client returns documents with malformed ids 1`] = `"Saved object [foo/object_1] is missing its expected space identifier."`;

exports[`default space #update does not allow an object to be updated via a different space 1`] = `"not found"`;
exports[`current space (space_1) #get returns error when the object belongs to a different space 1`] = `"not found: foo space_1:object_2"`;

exports[`current space (space_1) #get returns error when the object has a malformed identifier 1`] = `"Saved object [foo/object_1] is missing its expected space identifier."`;

exports[`current space (space_1) #update does not allow an object to be updated via a different space 1`] = `"not found: foo space_1:object_2"`;

exports[`current space (space_1) #update throws when the base client returns a malformed document id 1`] = `"Saved object [foo/object_1] is missing its expected space identifier."`;

exports[`default space #bulk_create throws when the base client returns a malformed document id 1`] = `"Saved object [foo/default:default] has an unexpected space identifier [default]."`;

exports[`default space #bulk_get throws when the base client returns a malformed document id 1`] = `"Saved object [foo/default:default] has an unexpected space identifier [default]."`;

exports[`default space #create throws when the base client returns a malformed document id 1`] = `"Saved object [foo/default:default] has an unexpected space identifier [default]."`;

exports[`default space #delete does not allow an object to be deleted via a different space 1`] = `"not found: foo object_2"`;

exports[`default space #find throws when the base client returns a malformed document id 1`] = `"Saved object [foo/default:default] has an unexpected space identifier [default]."`;

exports[`default space #get returns error when the object belongs to a different space 1`] = `"not found: foo object_2"`;

exports[`default space #get throws when the base client returns a malformed document id 1`] = `"Saved object [foo/default:default] has an unexpected space identifier [default]."`;

exports[`default space #update does not allow an object to be updated via a different space 1`] = `"not found: foo object_2"`;

exports[`default space #update throws when the base client returns a malformed document id 1`] = `"Saved object [space/default:default] has an unexpected space identifier [default]."`;
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DEFAULT_SPACE_ID } from '../../../common/constants';
import { isTypeSpaceAware } from './lib/is_type_space_aware';
import { getSpacesQueryFilters } from './lib/query_filters';
import uniq from 'lodash';
import uuid from 'uuid';

export class SpacesSavedObjectsClient {
constructor(options) {
Expand Down Expand Up @@ -45,7 +46,8 @@ export class SpacesSavedObjectsClient {
...options,
extraDocumentProperties: {
...options.extraDocumentProperties
}
},
id: this._prependSpaceId(type, options.id)
};

if (this._shouldAssignSpaceId(type, spaceId)) {
Expand All @@ -54,7 +56,8 @@ export class SpacesSavedObjectsClient {
delete createOptions.extraDocumentProperties.spaceId;
}

return await this._client.create(type, attributes, createOptions);
const result = await this._client.create(type, attributes, createOptions);
return this._trimSpaceId(result);
}

/**
Expand All @@ -73,7 +76,8 @@ export class SpacesSavedObjectsClient {
...object,
extraDocumentProperties: {
...object.extraDocumentProperties
}
},
id: this._prependSpaceId(object.type, object.id)
};

if (this._shouldAssignSpaceId(object.type, spaceId)) {
Expand All @@ -85,7 +89,10 @@ export class SpacesSavedObjectsClient {
return objectToCreate;
});

return await this._client.bulkCreate(objectsToCreate, options);
const result = await this._client.bulkCreate(objectsToCreate, options);
result.saved_objects.forEach(this._trimSpaceId.bind(this));

return result;
}

/**
Expand All @@ -96,11 +103,13 @@ export class SpacesSavedObjectsClient {
* @returns {promise}
*/
async delete(type, id) {
const objectId = this._prependSpaceId(type, id);

// attempt to retrieve document before deleting.
// this ensures that the document belongs to the current space.
await this.get(type, id);

return await this._client.delete(type, id);
return await this._client.delete(type, objectId);
}

/**
Expand Down Expand Up @@ -131,7 +140,9 @@ export class SpacesSavedObjectsClient {

spaceOptions.filters = [...filters, ...getSpacesQueryFilters(spaceId, types)];

return await this._client.find({ ...options, ...spaceOptions });
const result = await this._client.find({ ...options, ...spaceOptions });
result.saved_objects.forEach(this._trimSpaceId.bind(this));
return result;
}

/**
Expand All @@ -154,13 +165,18 @@ export class SpacesSavedObjectsClient {

const extraDocumentProperties = this._collectExtraDocumentProperties(['spaceId', 'type'], options.extraDocumentProperties);

const result = await this._client.bulkGet(objects, {
const objectsToRetrieve = objects.map(object => ({
...object,
id: this._prependSpaceId(object.type, object.id)
}));

const result = await this._client.bulkGet(objectsToRetrieve, {
...options,
extraDocumentProperties
});

result.saved_objects = result.saved_objects.map(savedObject => {
const { id, type, spaceId = DEFAULT_SPACE_ID } = savedObject;
const { id, type, spaceId = DEFAULT_SPACE_ID } = this._trimSpaceId(savedObject);

if (isTypeSpaceAware(type)) {
if (spaceId !== thisSpaceId) {
Expand Down Expand Up @@ -190,9 +206,11 @@ export class SpacesSavedObjectsClient {
async get(type, id, options = {}) {
// ES 'get' does not support queries, so we have to filter results after the fact.

const objectId = this._prependSpaceId(type, id);

const extraDocumentProperties = this._collectExtraDocumentProperties(['spaceId'], options.extraDocumentProperties);

const response = await this._client.get(type, id, {
const response = await this._client.get(type, objectId, {
...options,
extraDocumentProperties
});
Expand All @@ -206,7 +224,7 @@ export class SpacesSavedObjectsClient {
}
}

return response;
return this._trimSpaceId(response);
}

/**
Expand All @@ -227,6 +245,8 @@ export class SpacesSavedObjectsClient {
}
};

const objectId = this._prependSpaceId(type, id);

// attempt to retrieve document before updating.
// this ensures that the document belongs to the current space.
if (isTypeSpaceAware(type)) {
Expand All @@ -241,7 +261,8 @@ export class SpacesSavedObjectsClient {
}
}

return await this._client.update(type, id, attributes, updateOptions);
const result = await this._client.update(type, objectId, attributes, updateOptions);
return this._trimSpaceId(result);
}

_collectExtraDocumentProperties(thisClientProperties, optionalProperties = []) {
Expand All @@ -251,4 +272,29 @@ export class SpacesSavedObjectsClient {
_shouldAssignSpaceId(type, spaceId) {
return spaceId !== DEFAULT_SPACE_ID && isTypeSpaceAware(type);
}

_prependSpaceId(type, id = uuid.v1()) {
if (this._spaceId === DEFAULT_SPACE_ID || !isTypeSpaceAware(type)) {
return id;
}
return `${this._spaceId}:${id}`;
}

_trimSpaceId(savedObject) {
const prefix = `${this._spaceId}:`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way that we're trimming the spaceId is very similar to here, it seems like a rather naive implementation that could have unwanted behaviors if we're missing a spaceId prefix and we should have one for the type. I wonder why they weren't throwing errors in the base trimIdPrefix when they weren't found...


const idHasPrefix = savedObject.id.startsWith(prefix);

if (this._shouldAssignSpaceId(savedObject.type, this._spaceId)) {
if (idHasPrefix) {
savedObject.id = savedObject.id.slice(prefix.length);
} else {
throw new Error(`Saved object [${savedObject.type}/${savedObject.id}] is missing its expected space identifier.`);
}
} else if (idHasPrefix) {
throw new Error(`Saved object [${savedObject.type}/${savedObject.id}] has an unexpected space identifier [${this._spaceId}].`);
}

return savedObject;
}
}
Loading