Merge pull request #4169 from matrix-org/travis/sso-register

Disable registration flows on SSO servers (for patch release)
pull/21833/head
J. Ryan Stinnett 2020-03-04 10:18:50 +00:00 committed by GitHub
commit aedd44addc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 14 deletions

View File

@ -120,8 +120,8 @@ export default createReactClass({
'm.login.password': this._renderPasswordStep, 'm.login.password': this._renderPasswordStep,
// CAS and SSO are the same thing, modulo the url we link to // CAS and SSO are the same thing, modulo the url we link to
'm.login.cas': () => this._renderSsoStep(this._loginLogic.getSsoLoginUrl("cas")), 'm.login.cas': () => this._renderSsoStep(this._getSsoUrl('m.login.cas')),
'm.login.sso': () => this._renderSsoStep(this._loginLogic.getSsoLoginUrl("sso")), 'm.login.sso': () => this._renderSsoStep(this._getSsoUrl('m.login.sso')),
}; };
this._initLoginLogic(); this._initLoginLogic();
@ -150,6 +150,18 @@ export default createReactClass({
return this.state.busy || this.props.busy; return this.state.busy || this.props.busy;
}, },
_isSsoStep: function() {
return this._getCurrentFlowStep() === 'm.login.sso' || this._getCurrentFlowStep() === 'm.login.cas';
},
_getSsoUrl: function(kind) {
if (kind === 'm.login.cas') {
return this._loginLogic.getSsoLoginUrl("cas");
} else {
return this._loginLogic.getSsoLoginUrl("sso");
}
},
onPasswordLogin: async function(username, phoneCountry, phoneNumber, password) { onPasswordLogin: async function(username, phoneCountry, phoneNumber, password) {
if (!this.state.serverIsAlive) { if (!this.state.serverIsAlive) {
this.setState({busy: true}); this.setState({busy: true});
@ -344,6 +356,19 @@ export default createReactClass({
this.props.onRegisterClick(); this.props.onRegisterClick();
}, },
onTryRegisterClick: function(ev) {
if (this._isSsoStep()) {
// If we're showing SSO it means that registration is also probably disabled,
// so intercept the click and instead pretend the user clicked 'Sign in with SSO'.
ev.preventDefault();
ev.stopPropagation();
window.location = this._getSsoUrl(this._getCurrentFlowStep());
} else {
// Don't intercept - just go through to the register page
this.onRegisterClick(ev);
}
},
async onServerDetailsNextPhaseClick() { async onServerDetailsNextPhaseClick() {
this.setState({ this.setState({
phase: PHASE_LOGIN, phase: PHASE_LOGIN,
@ -654,7 +679,7 @@ export default createReactClass({
{ serverDeadSection } { serverDeadSection }
{ this.renderServerComponent() } { this.renderServerComponent() }
{ this.renderLoginComponentForStep() } { this.renderLoginComponentForStep() }
<a className="mx_AuthBody_changeFlow" onClick={this.onRegisterClick} href="#"> <a className="mx_AuthBody_changeFlow" onClick={this.onTryRegisterClick} href="#">
{ _t('Create account') } { _t('Create account') }
</a> </a>
</AuthBody> </AuthBody>

View File

@ -31,6 +31,8 @@ import classNames from "classnames";
import * as Lifecycle from '../../../Lifecycle'; import * as Lifecycle from '../../../Lifecycle';
import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {MatrixClientPeg} from "../../../MatrixClientPeg";
import AuthPage from "../../views/auth/AuthPage"; import AuthPage from "../../views/auth/AuthPage";
import Login from "../../../Login";
import dis from "../../../dispatcher";
// Phases // Phases
// Show controls to configure server details // Show controls to configure server details
@ -232,6 +234,13 @@ export default createReactClass({
serverRequiresIdServer, serverRequiresIdServer,
busy: false, busy: false,
}); });
const showGenericError = (e) => {
this.setState({
errorText: _t("Unable to query for supported registration methods."),
// add empty flows array to get rid of spinner
flows: [],
});
};
try { try {
await this._makeRegisterRequest({}); await this._makeRegisterRequest({});
// This should never succeed since we specified an empty // This should never succeed since we specified an empty
@ -243,18 +252,32 @@ export default createReactClass({
flows: e.data.flows, flows: e.data.flows,
}); });
} else if (e.httpStatus === 403 && e.errcode === "M_UNKNOWN") { } else if (e.httpStatus === 403 && e.errcode === "M_UNKNOWN") {
// At this point registration is pretty much disabled, but before we do that let's
// quickly check to see if the server supports SSO instead. If it does, we'll send
// the user off to the login page to figure their account out.
try {
const loginLogic = new Login(hsUrl, isUrl, null, {
defaultDeviceDisplayName: "riot login check", // We shouldn't ever be used
});
const flows = await loginLogic.getFlows();
const hasSsoFlow = flows.find(f => f.type === 'm.login.sso' || f.type === 'm.login.cas');
if (hasSsoFlow) {
// Redirect to login page - server probably expects SSO only
dis.dispatch({action: 'start_login'});
} else {
this.setState({ this.setState({
errorText: _t("Registration has been disabled on this homeserver."), errorText: _t("Registration has been disabled on this homeserver."),
// add empty flows array to get rid of spinner // add empty flows array to get rid of spinner
flows: [], flows: [],
}); });
}
} catch (e) {
console.error("Failed to get login flows to check for SSO support", e);
showGenericError(e);
}
} else { } else {
console.log("Unable to query for supported registration methods.", e); console.log("Unable to query for supported registration methods.", e);
this.setState({ showGenericError(e);
errorText: _t("Unable to query for supported registration methods."),
// add empty flows array to get rid of spinner
flows: [],
});
} }
} }
}, },

View File

@ -2004,8 +2004,8 @@
"Failed to fetch avatar URL": "Failed to fetch avatar URL", "Failed to fetch avatar URL": "Failed to fetch avatar URL",
"Set a display name:": "Set a display name:", "Set a display name:": "Set a display name:",
"Upload an avatar:": "Upload an avatar:", "Upload an avatar:": "Upload an avatar:",
"Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.",
"Unable to query for supported registration methods.": "Unable to query for supported registration methods.", "Unable to query for supported registration methods.": "Unable to query for supported registration methods.",
"Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.",
"This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.", "This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.",
"Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).", "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).",
"Continue with previous account": "Continue with previous account", "Continue with previous account": "Continue with previous account",