-
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
NP Security HTTP Interceptors #39477
Changes from 46 commits
d4f7e8e
3ebd52f
16c8e29
7c9f4b8
249bbfa
9041c15
2c6b3aa
007bc82
67af74c
984bf56
f672b72
c7ff2f0
181d951
ba84476
a551a5e
643729a
32d9385
824086c
0384182
acb61ee
41cbc8c
147edbd
ddab529
3b8711e
f37cf88
93206ad
eb860e8
3bd02fb
bae2ef9
da8b846
fb00dc4
51bdb02
837ba11
e23cf8f
2c98227
32751a4
4b0ea10
9432988
e169fbe
3582111
edac0ec
85a655e
a70ac40
248c580
5697aa2
4af0d8a
5a91232
50237cb
40a3697
08aa526
c4ec25c
15ff621
5a9b9a5
43425b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [HttpServiceBase](./kibana-plugin-public.httpservicebase.md) > [anonymousPaths](./kibana-plugin-public.httpservicebase.anonymouspaths.md) | ||
|
||
## HttpServiceBase.anonymousPaths property | ||
|
||
APIs for denoting certain paths for not requiring authentication | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
anonymousPaths: IAnonymousPaths; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IAnonymousPaths](./kibana-plugin-public.ianonymouspaths.md) > [isAnonymous](./kibana-plugin-public.ianonymouspaths.isanonymous.md) | ||
|
||
## IAnonymousPaths.isAnonymous() method | ||
|
||
Determines whether the provided path doesn't require authentication | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
isAnonymous(path: string): boolean; | ||
``` | ||
|
||
## Parameters | ||
|
||
| Parameter | Type | Description | | ||
| --- | --- | --- | | ||
| path | <code>string</code> | | | ||
|
||
<b>Returns:</b> | ||
|
||
`boolean` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IAnonymousPaths](./kibana-plugin-public.ianonymouspaths.md) | ||
|
||
## IAnonymousPaths interface | ||
|
||
APIs for denoting paths as not requiring authentication | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
export interface IAnonymousPaths | ||
``` | ||
|
||
## Methods | ||
|
||
| Method | Description | | ||
| --- | --- | | ||
| [isAnonymous(path)](./kibana-plugin-public.ianonymouspaths.isanonymous.md) | Determines whether the provided path doesn't require authentication | | ||
| [register(path)](./kibana-plugin-public.ianonymouspaths.register.md) | Register <code>path</code> as not requiring authentication | | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [IAnonymousPaths](./kibana-plugin-public.ianonymouspaths.md) > [register](./kibana-plugin-public.ianonymouspaths.register.md) | ||
|
||
## IAnonymousPaths.register() method | ||
|
||
Register `path` as not requiring authentication | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
register(path: string): void; | ||
``` | ||
|
||
## Parameters | ||
|
||
| Parameter | Type | Description | | ||
| --- | --- | --- | | ||
| path | <code>string</code> | | | ||
|
||
<b>Returns:</b> | ||
|
||
`void` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 { AnonymousPaths } from './anonymous_paths'; | ||
import { BasePath } from './base_path_service'; | ||
|
||
describe('#register', () => { | ||
it(`throws an error for paths that don't start with '/'`, () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
expect(() => anonymousPaths.register('bar')).toThrowErrorMatchingInlineSnapshot( | ||
`"\\"path\\" must start with \\"/\\""` | ||
); | ||
}); | ||
|
||
it(`allows paths that end with '/'`, () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar/'); | ||
}); | ||
}); | ||
|
||
describe('#isAnonymous', () => { | ||
it('returns true for registered paths', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar'); | ||
expect(anonymousPaths.isAnonymous('/foo/bar')).toBe(true); | ||
}); | ||
|
||
it('returns true for paths registered with a trailing slash, but call "isAnonymous" with no trailing slash', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar/'); | ||
expect(anonymousPaths.isAnonymous('/foo/bar')).toBe(true); | ||
}); | ||
|
||
it('returns true for paths registered without a trailing slash, but call "isAnonymous" with a trailing slash', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar'); | ||
expect(anonymousPaths.isAnonymous('/foo/bar/')).toBe(true); | ||
}); | ||
|
||
it('returns true for paths whose capitalization is different', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/BAR'); | ||
expect(anonymousPaths.isAnonymous('/foo/bar')).toBe(true); | ||
}); | ||
|
||
it('returns false for other paths', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar'); | ||
expect(anonymousPaths.isAnonymous('/foo/foo')).toBe(false); | ||
}); | ||
|
||
it('returns false for sub-paths of registered paths', () => { | ||
const basePath = new BasePath('/foo'); | ||
const anonymousPaths = new AnonymousPaths(basePath); | ||
anonymousPaths.register('/bar'); | ||
expect(anonymousPaths.isAnonymous('/foo/bar/baz')).toBe(false); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you 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 { HttpSetup } from 'src/core/public'; | ||
kobelb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
export class AnonymousPaths { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this implement There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, I will make it so. |
||
private paths: Set<string>; | ||
kobelb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
constructor(private basePath: HttpSetup['basePath']) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: seems simpler to just use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, this is a carry-over from AnonymousPaths being a security plugin class. I will update it. |
||
this.paths = new Set(); | ||
} | ||
|
||
public isAnonymous(path: string): boolean { | ||
const pathWithoutBasePath = this.basePath.remove(path); | ||
return this.paths.has(this.normalizePath(pathWithoutBasePath)); | ||
} | ||
|
||
public register(path: string) { | ||
if (!path.startsWith('/')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It definitely can. It felt somewhat awkward to allow consumers to do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm all for making things more robust if it's easy to change. Don't consider it a blocker for this PR though |
||
throw new Error('"path" must start with "/"'); | ||
} | ||
|
||
this.paths.add(this.normalizePath(path)); | ||
} | ||
|
||
private normalizePath(path: string) { | ||
const lowercased = path.toLowerCase(); | ||
|
||
if (lowercased.endsWith('/')) { | ||
return lowercased.slice(0, lowercased.length - 1); | ||
} | ||
|
||
return lowercased; | ||
} | ||
} |
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.
Thoughts on adding: