-
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
Migrate security chromeless views to Kibana Platform plugin #54021
Conversation
Pinging @elastic/kibana-security (Team:Security) |
3c2fbca
to
5065eb6
Compare
5065eb6
to
949db04
Compare
06b5fab
to
eb7f32f
Compare
3f7cb00
to
826b327
Compare
retest |
@@ -0,0 +1,65 @@ | |||
/* |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
||
const securityPluginSetup = (npSetup.plugins as any).security as SecurityPluginSetup; | ||
if (securityPluginSetup) { | ||
routes.when('/account', { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
||
function interceptorFactory(responseHandler: (response: ng.IHttpResponse<unknown>) => any) { | ||
return function interceptor(response: ng.IHttpResponse<unknown>) { | ||
// TODO: SHOULD WE CHECK THAT IT'S NOT ERROR RESPONSE (&& response.status !== 401)? |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
securityPluginSetup.sessionTimeout.extend(response.config.url); | ||
} | ||
|
||
if (response.status !== 401 || isAnonymous) { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
import 'plugins/security/services/auto_logout'; | ||
|
||
function isUnauthorizedResponseAllowed(response) { | ||
const API_WHITELIST = ['/internal/security/login', '/internal/security/users/.*/password']; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -1,33 +0,0 @@ | |||
/* |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -1,31 +0,0 @@ | |||
/* |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
@@ -1,38 +0,0 @@ | |||
/* |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
title: i18n.translate('xpack.security.account.breadcrumb', { | ||
defaultMessage: 'Account Management', | ||
}), | ||
// TODO: switch to proper enum once https://github.com/elastic/kibana/issues/58327 is resolved. |
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: just in case this issue isn't resolved before this PR is reviewed - Jest test tests that our magic number 3
corresponds to the AppNavLinkStatus.hidden
state = { loginState: null }; | ||
|
||
public async componentDidMount() { | ||
const loadingCount$ = new BehaviorSubject(1); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
Uses a single test for the entire page, and more focused tests for each permutation of BasicLoginForm/DisabledLoginForm. This greatly reduces the snapshot size. Also adds tests for API calls.
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.
Finished reviewing code (and added updated LoginPage tests as discussed offline).
I'll try out the functionality now.
|
||
// Authentication flow isn't triggered automatically for this route, so we should explicitly | ||
// check whether user has an active session already. | ||
const isUserAlreadyLoggedIn = (await authc.getSessionInfo(request)) != null; |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
public stop() { | ||
this.sessionTimeout.stop(); | ||
if (this.sessionTimeout) { | ||
this.sessionTimeout.stop(); | ||
} | ||
|
||
this.navControlService.stop(); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
import { Observable } from 'rxjs'; | ||
import { CoreSetup } from 'src/core/public'; | ||
import { DataPublicPluginStart } from '../../../../src/plugins/data/public'; | ||
import { SessionTimeout } from './session'; | ||
import { PluginStartDependencies, SecurityPlugin } from './plugin'; | ||
|
||
import { coreMock } from '../../../../src/core/public/mocks'; | ||
import { managementPluginMock } from '../../../../src/plugins/management/public/mocks'; | ||
import { licensingMock } from '../../licensing/public/mocks'; | ||
import { ManagementService } from './management'; | ||
|
||
describe('Security Plugin', () => { | ||
describe('#setup', () => { |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
beforeAll(() => { | ||
Object.defineProperty(window, 'location', { | ||
value: { href: 'http://some-host/bar', protocol: 'http' }, | ||
writable: true, | ||
}); | ||
}); |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
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.
Tested changed pages locally, all works well.
LGTM on green CI / after comments are addressed!
@@ -92,10 +92,6 @@ export default async function({ readConfigFile }) { | |||
pathname: '/app/kibana', | |||
hash: '/dev_tools/console', | |||
}, | |||
account: { |
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: I haven't found any place that would use this, so just removed instead of updating.
@@ -192,7 +192,6 @@ export class Authenticator { | |||
client: this.options.clusterClient, | |||
logger: this.options.loggers.get('tokens'), | |||
}), | |||
isProviderEnabled: this.isProviderEnabled.bind(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.
note: leftover from my recent PR, couldn't resist to fix that 🙈
@@ -366,7 +366,7 @@ export class SAMLAuthenticationProvider extends BaseAuthenticationProvider { | |||
'Login initiated by Identity Provider is for a different user than currently authenticated.' | |||
); | |||
return AuthenticationResult.redirectTo( | |||
`${this.options.basePath.get(request)}/overwritten_session`, | |||
`${this.options.basePath.serverBasePath}/app/security/overwritten_session`, |
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: it should really be serverBasePath
since view is Space agnostic.
true, | ||
schema.maybe(schema.string({ minLength: 32 })), | ||
schema.string({ minLength: 32, defaultValue: 'a'.repeat(32) }) | ||
export const ConfigSchema = schema.object({ |
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: just reformatted to make eslint
happy
… prefix for view route (with `appRoute`) that are rendered by dedicated server routes.
import { AuthenticationStatePage } from '../components/authentication_state_page'; | ||
|
||
describe('OverwrittenSessionPage', () => { | ||
it('renders as expected', 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.
Nit: doesn't include test case for username === null
Tested again locally and it's all working as expected 👏 |
… for empty username in OverwrittenSession view.
@elasticmachine merge upstream |
merge conflict between base and head |
retest |
@elasticmachine merge upstream |
7.x/7.7.0: 91babc7 |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
Yeah, thank you for the heads up @kibanamachine, it's always better later than never. |
In this PR I migrate everything that's currently possible from the legacy to the platform Kibana Security plugin:
hack/legacy.ts
fileNote to reviewers: it may be a bit easier to review commit by commit since there is a lot of moves that were done in a separate commit.
Note to myself: be careful when backporting config changes to 7.x (
xpack.security.authProviders|public
are still there 🙈 )Blocked by:
#53880, #54470, #54472, #58327,#58627