-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Sharing saved-objects phase 1 #54605
Sharing saved-objects phase 1 #54605
Conversation
Note: includes POC from #50404 |
4efc8d2
to
254f55c
Compare
f37b241
to
9caba22
Compare
f467c4f
to
947798f
Compare
947798f
to
17e9c68
Compare
63bb5b6
to
8544545
Compare
Used array filtering to make the code more readable.
These are now called `addToNamespaces` and `deleteFromNamespaces` to better describe what they do. Also changed the names of the related Spaces integration test suites to reflect their routes -- these test suites are now called `share_add` and `share_remove`.
@@ -354,69 +346,67 @@ export class SavedObjectsRepository { | |||
|
|||
let bulkRequestIndexCounter = 0; | |||
const bulkCreateParams: object[] = []; | |||
const expectedBulkResults: Array<Either<any, any>> = expectedResults.map( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: the diff below this is messy, but code didn't change, just indentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second pass review of the platform owned files.
This was a beast. Some nits and questions, but overall I think it's LGTM.
Let see if @rudolf find anything I might have missed 😄
function getNamespaceString(namespace?: string) { | ||
return namespace ?? 'default'; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT: getNamespaceOrDefault
maybe?
Also, if default
is used multiple times for some checks (did not look) I would create a const for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string representation of the default (undefined) namespace is 'default'. I'll update the jsdoc to better describe this.
Edit: added in ec7fc3e.
document?: SavedObjectsRawDoc | ||
): string[] | undefined { | ||
if (document) { | ||
return document._source.namespaces; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw document._source?.namespaces ?? []
in some places (I think?). We don't want it there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to coalesce to an array here if the document has no namespaces
, because of the ways that consumers use this function. However, I suppose it wouldn't hurt to include the optional chaining!
Edit: added in ec7fc3e.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Functional test coverage looks really good, nice job with this! I struggled to follow some of the logic for constructing the various permutations, but the tradeoff here is that the actual test definitions are more straightforward than before
x-pack/test/saved_object_api_integration/common/lib/saved_object_test_utils.ts
Outdated
Show resolved
Hide resolved
x-pack/test/saved_object_api_integration/common/lib/saved_object_test_utils.ts
Outdated
Show resolved
Hide resolved
interface Modifier { | ||
modifier?: T; | ||
} | ||
interface Security extends Modifier { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: The naming here is confusing to me. An interface named Security
extends another named Modifier
-- this leads me to expect that this is some sort of "security modifier", but I'm not sure what it's modifying, or what security means in this context.
I don't have a concrete suggestion at the moment, so don't get too hung up on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a few different iterations of this getTestScenarios
method, and at one point I needed to define the interfaces this way to avoid duplicating a bunch of code. However, looking at it now I think I can get rid of the Modifier
interface entirely and define these interfaces like so:
interface Security {
modifier?: T;
users: Record<
| keyof typeof commonUsers
| 'allAtDefaultSpace'
| 'readAtDefaultSpace'
| 'allAtSpace1'
| 'readAtSpace1',
TestUser
>;
}
interface SecurityAndSpaces {
modifier?: T;
users: Record<
keyof typeof commonUsers | 'allAtSpace' | 'readAtSpace' | 'allAtOtherSpace',
TestUser
>;
spaceId: string;
}
interface Spaces {
modifier?: T;
spaceId: string;
}
x-pack/test/saved_object_api_integration/common/lib/saved_object_test_utils.ts
Outdated
Show resolved
Hide resolved
x-pack/test/saved_object_api_integration/common/lib/saved_object_test_utils.ts
Outdated
Show resolved
Hide resolved
@@ -6,7 +6,28 @@ | |||
|
|||
export type DescribeFn = (text: string, fn: () => void) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we have our own definition for a Mocha test suite? Can we use Mocha.SuiteFunction
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
message: `Unable to ${action} ${uniqueSorted.join()}`, | ||
}); | ||
}, | ||
permitted: async (object: Record<string, any>, testCase: TestCase, expectSuccess?: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: expectSuccess
reads like an optional boolean value, but it appears that's not the case. I'm having a hard time following, so I'm sure there's a reason, but why isn't the success condition part of the testCase
, like the failure condition is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an optional override to the default behavior of testing the success outcome. I went through several iterations of rewriting these test suites. Looking at them now it appears that expectSuccess
is never used, so I can remove it.
I'll be honest, I am not 100% sure at this point why I had it defined this way, I believe at one point I had a need to modify the assertions for the success outcome within the common test suite files (as opposed to when the test case was defined), and it seemed better to do it this way.
Edit: this was actually being used in the delete
test suite, because the success response for the delete API is an empty object. However, I still removed it from the test utils here and just added a conditional in the common delete test suite instead.
@elasticmachine merge upstream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once Rudolf approves. This was a monster of a PR, nice work! 👏 🚢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Good job!
@elasticmachine merge upstream |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
Remove `namespaceAgnostic` field that was deprecated in elastic#54605, use `namespaceType` instead.
Co-authored-by: kobelb <[email protected]>
Remove `namespaceAgnostic` field that was deprecated in #54605, use `namespaceType` instead.
Remove `namespaceAgnostic` field that was deprecated in #54605, use `namespaceType` instead.
Phase 1 from #27004.
Closes #54043.
Overview
Currently, saved objects can be namespace-agnostic (which resides outside of spaces), or single-namespace (which is isolated to a single space).
This PR adds a third type of saved object: multi-namespace (which resides in one or more namespaces). It also includes changes to the saved object repository, client, and client wrappers to include new behavior for this type of saved object.
Click for a list of changes...
Primary changes in core:
SavedObjectsType
(along with legacySavedObjectsSchemaTypeDefinition
) to include a newmultiNamespace
boolean attribute. Accordingly, I updated theSavedObjectTypeRegistry
and legacySavedObjectsSchema
to add two new methods:isSingleNamespace
andisMultiNamespace
. These, along with the existingisNamespaceAgnostic
method, all return boolean values and are all mutually exclusive.SavedObject
interface to include a new optionalnamespaces
field. This is only used if the saved object type is multi-namespace.SavedObjectsRepository
to account for new behavior.addNamespaces
andremoveNamespaces
, which can only be used for multi-namespace saved objects. Also updated theSavedObjectsClient
to include these methods.Primary changes in x-pack:
EncryptedSavedObjectsClientWrapper
to treat multi-namespace saved objects differently. These do not use the current space for the encryption's AAD.SecureSavedObjectsClientWrapper
to add the appropriate authorization checks for multi-namespace saved objects. To add a new space to an existing multi-namespace saved object, you must have "create" permissions in the source and destination spaces. For all other operations, you must have the appropriate permission in any of the saved object's spaces./api/spaces/_share_saved_object_add
and/api/spaces/_share_saved_object_remove
, and added corresponding methods in theSpacesSavedObjectClient
.SecurityAuditLogger
to include more information about missing privileges -- it now the space for each privilege check.Test Changes
I had to ensure we are exercising new test cases in unit tests and integration tests. When I started looking through these, some of the existing tests were stale or extremely verbose / hard to validate. I opted to completely rewrite some of these test suites.
Click for a list of changes...
Rewritten test suites:
src/core/server/saved_objects/service/lib/repository.test.js
src/core/server/saved_objects/service/lib/search_dsl/query_params.test.ts
x-pack/plugins/security/server/authorization/check_saved_objects_privileges.test.ts
x-pack/plugins/security/server/saved_objects/secure_saved_objects_client_wrapper.test.ts
x-pack/test/saved_object_api_integration/