diff options
author | Joram Wilander <jwawilander@gmail.com> | 2016-12-12 08:16:10 -0500 |
---|---|---|
committer | enahum <nahumhbl@gmail.com> | 2016-12-12 10:16:10 -0300 |
commit | 30a10d35a8406f4af96fcc8200c4e2173856837d (patch) | |
tree | a2cc82592b3c7f6b6901d64fb4a3003180b7b154 /webapp/components/claim | |
parent | f0d71d87899967335210b9130a7e2b8d180bef46 (diff) | |
download | chat-30a10d35a8406f4af96fcc8200c4e2173856837d.tar.gz chat-30a10d35a8406f4af96fcc8200c4e2173856837d.tar.bz2 chat-30a10d35a8406f4af96fcc8200c4e2173856837d.zip |
PLT-4767 Implement MFA Enforcement (#4662)
* Create MFA setup page and remove MFA setup from account settings modal
* Add enforce MFA to system console and force redirect
* Lockdown mfa required API routes, add localization, other changes
* Minor fixes
* Fix typo
* Fix some unit tests
* Fix more unit tests
* Minor fix
* Updating UI for MFA screen (#4670)
* Updating UI for MFA screen
* Updating styles for MFA page
* Add the ability to switch between email/sso with MFA enabled
* Added mfa change email
* Minor UI updates for MFA enforcement
* Fix unit test
* Fix client unit test
* Allow switching email to ldap and back when MFA is enabled
* Fix unit test
* Revert config.json
Diffstat (limited to 'webapp/components/claim')
-rw-r--r-- | webapp/components/claim/components/email_to_ldap.jsx | 81 | ||||
-rw-r--r-- | webapp/components/claim/components/email_to_oauth.jsx | 73 | ||||
-rw-r--r-- | webapp/components/claim/components/ldap_to_email.jsx | 64 |
3 files changed, 170 insertions, 48 deletions
diff --git a/webapp/components/claim/components/email_to_ldap.jsx b/webapp/components/claim/components/email_to_ldap.jsx index a0b0b10e9..890512803 100644 --- a/webapp/components/claim/components/email_to_ldap.jsx +++ b/webapp/components/claim/components/email_to_ldap.jsx @@ -1,11 +1,14 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import LoginMfa from 'components/login/components/login_mfa.jsx'; + import * as Utils from 'utils/utils.jsx'; import Client from 'client/web_client.jsx'; +import {checkMfa} from 'actions/user_actions.jsx'; + import React from 'react'; -import ReactDOM from 'react-dom'; import {FormattedMessage} from 'react-intl'; export default class EmailToLDAP extends React.Component { @@ -13,16 +16,20 @@ export default class EmailToLDAP extends React.Component { super(props); this.submit = this.submit.bind(this); + this.preSubmit = this.preSubmit.bind(this); this.state = { passwordError: '', ldapError: '', ldapPasswordError: '', - serverError: '' + serverError: '', + showMfa: false }; } - submit(e) { + + preSubmit(e) { e.preventDefault(); + var state = { passwordError: '', ldapError: '', @@ -30,44 +37,65 @@ export default class EmailToLDAP extends React.Component { serverError: '' }; - const password = ReactDOM.findDOMNode(this.refs.emailpassword).value; + const password = this.refs.emailpassword.value; if (!password) { state.passwordError = Utils.localizeMessage('claim.email_to_ldap.pwdError', 'Please enter your password.'); this.setState(state); return; } - const ldapId = ReactDOM.findDOMNode(this.refs.ldapid).value.trim(); + const ldapId = this.refs.ldapid.value.trim(); if (!ldapId) { state.ldapError = Utils.localizeMessage('claim.email_to_ldap.ldapIdError', 'Please enter your AD/LDAP ID.'); this.setState(state); return; } - const ldapPassword = ReactDOM.findDOMNode(this.refs.ldappassword).value; + const ldapPassword = this.refs.ldappassword.value; if (!ldapPassword) { state.ldapPasswordError = Utils.localizeMessage('claim.email_to_ldap.ldapPasswordError', 'Please enter your AD/LDAP password.'); this.setState(state); return; } + state.password = password; + state.ldapId = ldapId; + state.ldapPassword = ldapPassword; this.setState(state); - Client.emailToLdap( + checkMfa( this.props.email, + (requiresMfa) => { + if (requiresMfa) { + this.setState({showMfa: true}); + } else { + this.submit(this.props.email, password, '', ldapId, ldapPassword); + } + }, + (err) => { + this.setState({error: err.message}); + } + ); + } + + submit(loginId, password, token, ldapId, ldapPassword) { + Client.emailToLdap( + loginId, password, - ldapId, - ldapPassword, + token, + ldapId || this.state.ldapId, + ldapPassword || this.state.ldapPassword, (data) => { if (data.follow_link) { window.location.href = data.follow_link; } }, (err) => { - this.setState({serverError: err.message}); + this.setState({serverError: err.message, showMfa: false}); } ); } + render() { let serverError = null; let formClass = 'form-group'; @@ -111,16 +139,19 @@ export default class EmailToLDAP extends React.Component { passwordPlaceholder = Utils.localizeMessage('claim.email_to_ldap.ldapPwd', 'AD/LDAP Password'); } - return ( - <div> - <h3> - <FormattedMessage - id='claim.email_to_ldap.title' - defaultMessage='Switch Email/Password Account to AD/LDAP' - /> - </h3> + let content; + if (this.state.showMfa) { + content = ( + <LoginMfa + loginId={this.props.email} + password={this.state.password} + submit={this.submit} + /> + ); + } else { + content = ( <form - onSubmit={this.submit} + onSubmit={this.preSubmit} className={formClass} > <p> @@ -202,6 +233,18 @@ export default class EmailToLDAP extends React.Component { </button> {serverError} </form> + ); + } + + return ( + <div> + <h3> + <FormattedMessage + id='claim.email_to_ldap.title' + defaultMessage='Switch Email/Password Account to AD/LDAP' + /> + </h3> + {content} </div> ); } diff --git a/webapp/components/claim/components/email_to_oauth.jsx b/webapp/components/claim/components/email_to_oauth.jsx index d7c4956a6..3cede15a3 100644 --- a/webapp/components/claim/components/email_to_oauth.jsx +++ b/webapp/components/claim/components/email_to_oauth.jsx @@ -1,10 +1,14 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import LoginMfa from 'components/login/components/login_mfa.jsx'; + import * as Utils from 'utils/utils.jsx'; import Client from 'client/web_client.jsx'; import Constants from 'utils/constants.jsx'; +import {checkMfa} from 'actions/user_actions.jsx'; + import React from 'react'; import ReactDOM from 'react-dom'; import {FormattedMessage} from 'react-intl'; @@ -14,10 +18,12 @@ export default class EmailToOAuth extends React.Component { super(props); this.submit = this.submit.bind(this); + this.preSubmit = this.preSubmit.bind(this); - this.state = {}; + this.state = {showMfa: false, password: ''}; } - submit(e) { + + preSubmit(e) { e.preventDefault(); var state = {}; @@ -28,12 +34,31 @@ export default class EmailToOAuth extends React.Component { return; } + this.setState({password}); + state.error = null; this.setState(state); - Client.emailToOAuth( + checkMfa( this.props.email, + (requiresMfa) => { + if (requiresMfa) { + this.setState({showMfa: true}); + } else { + this.submit(this.props.email, password, ''); + } + }, + (err) => { + this.setState({error: err.message}); + } + ); + } + + submit(loginId, password, token) { + Client.emailToOAuth( + loginId, password, + token, this.props.newType, (data) => { if (data.follow_link) { @@ -41,10 +66,11 @@ export default class EmailToOAuth extends React.Component { } }, (err) => { - this.setState({error: err.message}); + this.setState({error: err.message, showMfa: false}); } ); } + render() { var error = null; if (this.state.error) { @@ -59,18 +85,18 @@ export default class EmailToOAuth extends React.Component { const type = (this.props.newType === Constants.SAML_SERVICE ? Constants.SAML_SERVICE.toUpperCase() : Utils.toTitleCase(this.props.newType)); const uiType = `${type} SSO`; - return ( - <div> - <h3> - <FormattedMessage - id='claim.email_to_oauth.title' - defaultMessage='Switch Email/Password Account to {uiType}' - values={{ - uiType - }} - /> - </h3> - <form onSubmit={this.submit}> + let content; + if (this.state.showMfa) { + content = ( + <LoginMfa + loginId={this.props.email} + password={this.state.password} + submit={this.submit} + /> + ); + } else { + content = ( + <form onSubmit={this.preSubmit}> <p> <FormattedMessage id='claim.email_to_oauth.ssoType' @@ -122,6 +148,21 @@ export default class EmailToOAuth extends React.Component { /> </button> </form> + ); + } + + return ( + <div> + <h3> + <FormattedMessage + id='claim.email_to_oauth.title' + defaultMessage='Switch Email/Password Account to {uiType}' + values={{ + uiType + }} + /> + </h3> + {content} </div> ); } diff --git a/webapp/components/claim/components/ldap_to_email.jsx b/webapp/components/claim/components/ldap_to_email.jsx index b7ff93b59..39056cd0d 100644 --- a/webapp/components/claim/components/ldap_to_email.jsx +++ b/webapp/components/claim/components/ldap_to_email.jsx @@ -1,9 +1,11 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import LoginMfa from 'components/login/components/login_mfa.jsx'; + import * as Utils from 'utils/utils.jsx'; -import {switchFromLdapToEmail} from 'actions/user_actions.jsx'; +import {checkMfa, switchFromLdapToEmail} from 'actions/user_actions.jsx'; import React from 'react'; import {FormattedMessage} from 'react-intl'; @@ -13,6 +15,7 @@ export default class LDAPToEmail extends React.Component { super(props); this.submit = this.submit.bind(this); + this.preSubmit = this.preSubmit.bind(this); this.state = { passwordError: '', @@ -22,8 +25,9 @@ export default class LDAPToEmail extends React.Component { }; } - submit(e) { + preSubmit(e) { e.preventDefault(); + var state = { passwordError: '', confirmError: '', @@ -60,14 +64,33 @@ export default class LDAPToEmail extends React.Component { return; } + state.password = password; + state.ldapPassword = ldapPassword; this.setState(state); + checkMfa( + this.props.email, + (requiresMfa) => { + if (requiresMfa) { + this.setState({showMfa: true}); + } else { + this.submit(this.props.email, password, '', ldapPassword); + } + }, + (err) => { + this.setState({error: err.message}); + } + ); + } + + submit(loginId, password, token, ldapPassword) { switchFromLdapToEmail( this.props.email, password, - ldapPassword, + token, + ldapPassword || this.state.ldapPassword, null, - (err) => this.setState({serverError: err.message}) + (err) => this.setState({serverError: err.message, showMfa: false}) ); } @@ -107,16 +130,19 @@ export default class LDAPToEmail extends React.Component { passwordPlaceholder = Utils.localizeMessage('claim.ldap_to_email.ldapPwd', 'AD/LDAP Password'); } - return ( - <div> - <h3> - <FormattedMessage - id='claim.ldap_to_email.title' - defaultMessage='Switch AD/LDAP Account to Email/Password' - /> - </h3> + let content; + if (this.state.showMfa) { + content = ( + <LoginMfa + loginId={this.props.email} + password={this.state.password} + submit={this.submit} + /> + ); + } else { + content = ( <form - onSubmit={this.submit} + onSubmit={this.preSubmit} className={formClass} > <p> @@ -194,6 +220,18 @@ export default class LDAPToEmail extends React.Component { </button> {serverError} </form> + ); + } + + return ( + <div> + <h3> + <FormattedMessage + id='claim.ldap_to_email.title' + defaultMessage='Switch AD/LDAP Account to Email/Password' + /> + </h3> + {content} </div> ); } |