-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
migrate xsrf / version-check / custom-headers handlers to NP #53684
migrate xsrf / version-check / custom-headers handlers to NP #53684
Conversation
customResponseHeaders: schema.recordOf(schema.string(), schema.string(), { | ||
defaultValue: {}, | ||
}), |
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 kept the same name. It's quite long but I don't really have a better idea. If someone comes with a better name, we could deprecates this one now that deprecations can be handled in NP configs
|
||
registerCoreHandlers(serverContract, config, this.env); | ||
|
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 did not add a test that ensure this is properly invoked during the service setup
phase as the feature is heavily integration-tested. Tell we if we want to still add a test.
describe('core lifecycle handlers', () => { | ||
let root: ReturnType<typeof kbnTestServer.createRoot>; | ||
|
||
beforeEach(async () => { | ||
root = kbnTestServer.createRoot({ | ||
server: { | ||
name: kibanaName, | ||
customResponseHeaders: { | ||
'some-header': 'some-value', | ||
}, | ||
xsrf: { disableProtection: false, whitelist: [whitelistedTestPath] }, | ||
}, |
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'm doing all three handlers integration tests in the same file, so the root creation has settings for all the 3 handlers. Not sure if I should split/isolate per file
import { OnPreAuthToolkit } from './on_pre_auth'; | ||
import { LifecycleResponseFactory } from '../router'; | ||
|
||
type MockToolkit = jest.Mocked<OnPreResponseToolkit & OnPostAuthToolkit & OnPreAuthToolkit>; |
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.
All these toolkits have very similar API, in a mock point of view. I generalised this type that can be used on for testing any of the lifecycle handler types.
@@ -71,19 +71,6 @@ export default () => | |||
server: Joi.object({ | |||
name: Joi.string().default(os.hostname()), |
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.
HANDLED_IN_NEW_PLATFORM
states This key is handled in the new platform ONLY
, however server.name
is still used in legacy in some places such as
serverName: config.get('server.name'), |
so I kept it as is. should I change it to name: HANDLED_IN_NEW_PLATFORM
?
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 validation is handled in the new platform, so I'd remove this. The legacy platform can continue using config.get('server.name')
, but validation will be delegated to the NP.
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.
TIL we can't. Some plugins are still accessing it from the legacy config, and as we are constructing the legacy config from the raw configuration values, any default from our NP schemas are ignored. had to keep it for now.
Pinging @elastic/kibana-platform (Team:Platform) |
const VERSION_HEADER = 'kbn-version'; | ||
const XSRF_HEADER = 'kbn-xsrf'; | ||
const KIBANA_NAME_HEADER = 'kbn-name'; |
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.
What do you think about adding a file for these constants that can be shared across public
and server
?
While I was implementing the System API behavior, I was considering adding a src/core/utils/constants
file for the kbn-system-api
and kbn-version
header names.
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.
Yes I though about it and was not sure where I was supposed to put the constants file. should it be src/core/utils
or src/core/types
? Constants are not exactly one or the other.
I could also exports these from src/core/server/http
(and src/core/server
) and then expose them in src/core/server/types
to be eventually used by the client-side?
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.
Do we need this? What benefits does it provide? I don't see a problem to inline them in both server & client within the same domain because:
- it simplifies search (Cmd + F) and improves DX. I cannot just copy an error message
Request must contain a kbn-xsrf header.
and find the place where a request was rejected. - it doesn't clutter code with unnecessary import/export expressions
- it makes this API truly private and prevents accidental importing from the plugin code.
The main benefit of sharing that we can easily to audit all internal Kibana headers. 🤔
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.
Other benefit is that if we need to change the header name in the future, we only have to edit it in a single place and don't risk missing a string that needs to be updated (or a string from a yet-to-be-merged PR not getting updated).
That said, I don't imagine these changing often (if at all) or them being used in many more places (if any).
Kind of a toss up on benefits here. I'm fine leaving as-is in this PR and removing my shared module in #53734.
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.
Will keep them as-is for now. Can easily be refactored later on if the benefits appear more significants at some point.
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
const VERSION_HEADER = 'kbn-version'; | ||
const XSRF_HEADER = 'kbn-xsrf'; | ||
const KIBANA_NAME_HEADER = 'kbn-name'; |
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.
Do we need this? What benefits does it provide? I don't see a problem to inline them in both server & client within the same domain because:
- it simplifies search (Cmd + F) and improves DX. I cannot just copy an error message
Request must contain a kbn-xsrf header.
and find the place where a request was rejected. - it doesn't clutter code with unnecessary import/export expressions
- it makes this API truly private and prevents accidental importing from the plugin code.
The main benefit of sharing that we can easily to audit all internal Kibana headers. 🤔
const testRoute = '/version_check/test/route'; | ||
|
||
beforeEach(() => { | ||
kbnTestServer.getKbnServer(root).server.route({ |
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'd rather avoid using raw hapi API in the platform tests.
const { server: innerServer, createRouter } = await server.setup(setupDeps); |
This allows us to reduce noize in tests when updating hapi version / removing hapi
await kbnTestServer.request | ||
.get(root, testRoute) | ||
.set(versionHeader, 'invalid-version') | ||
.expect(400, /"Browser client is out of date/); |
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.
optional nit: /Browser client is out of date/
|
||
const createConfig = (partial: Partial<HttpConfig>): HttpConfig => partial as HttpConfig; | ||
|
||
const forgeRequest = ({ |
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.
is there a reason not to use already existing fixtures ?
function createRawRequestMock(customization: DeepPartial<Request> = {}) { |
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.
No, just forget we already had a mock request fixture. Will adapt.
responseFactory = httpServerMock.createLifecycleResponseFactory(); | ||
}); | ||
|
||
it('forward the request to the next interceptor if header matches', () => { |
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 suspect this functionality is covered by the integration tests. Isn't it? If yes, I'd remove the unit tests because it's hard to write them due to coupling with hapi.
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.
Yes, it's tested in integration tests. However I don't think we are really tightly coupled with hapi here, as all used interfaces/types are from core (even if we mimic hapi's types for some of them). I'm leaning to keep them as this is the only place we can really test them unitarily (integ test have all interceptors registered)
@@ -71,19 +71,6 @@ export default () => | |||
server: Joi.object({ | |||
name: Joi.string().default(os.hostname()), |
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 validation is handled in the new platform, so I'd remove this. The legacy platform can continue using config.get('server.name')
, but validation will be delegated to the NP.
); | ||
}); | ||
|
||
it('adds the custom headers', async () => { |
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.
could you add a test that custom headers are present in error responses as well?
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.
some nits, looks good & clean 💯
retest |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
…#53684) * migrate xsrf / version-check / custom-headers handlers to NP * export lifecycleMock to be used by plugins * move toolkit mock to http_server mock * remove legacy config tests on xsrf * fix integration_test http configuration * remove direct HAPI usages from integration tests * nits and comments * add custom headers test in case of server returning error * resolve merge conflicts * restore `server.name` to legacy config
* master: allows Alerts to recover gracefully from Executor errors (elastic#53688) [Console] Fix OSS build (elastic#53885) migrate xsrf / version-check / custom-headers handlers to NP (elastic#53684) use NP deprecations in uiSettings (elastic#53755) adds strict types to Alerting Client (elastic#53821) [Dashboard] Empty screen redesign (elastic#53681) Migrate config deprecations and `ShieldUser` functionality to the New Platform (elastic#53768)
…53684) (#54016) * migrate xsrf / version-check / custom-headers handlers to NP (#53684) * migrate xsrf / version-check / custom-headers handlers to NP * export lifecycleMock to be used by plugins * move toolkit mock to http_server mock * remove legacy config tests on xsrf * fix integration_test http configuration * remove direct HAPI usages from integration tests * nits and comments * add custom headers test in case of server returning error * resolve merge conflicts * restore `server.name` to legacy config * update snapshots
Summary
Fix #50656
Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.For maintainers