Skip to content

Commit

Permalink
Merge pull request #453 from MidhunSureshR/sso-login
Browse files Browse the repository at this point in the history
[SSO] - [PR 4] - SSO/Token login functionality
  • Loading branch information
bwindels committed Aug 23, 2021
2 parents a56496c + ef4db4a commit 3b693c5
Show file tree
Hide file tree
Showing 23 changed files with 808 additions and 182 deletions.
84 changes: 0 additions & 84 deletions src/domain/LoginViewModel.js

This file was deleted.

27 changes: 17 additions & 10 deletions src/domain/RootViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import {SessionViewModel} from "./session/SessionViewModel.js";
import {SessionLoadViewModel} from "./SessionLoadViewModel.js";
import {LoginViewModel} from "./LoginViewModel.js";
import {LoginViewModel} from "./login/LoginViewModel.js";
import {SessionPickerViewModel} from "./SessionPickerViewModel.js";
import {ViewModel} from "./ViewModel.js";

Expand All @@ -35,12 +35,14 @@ export class RootViewModel extends ViewModel {
async load() {
this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("sso").subscribe(() => this._applyNavigation()));
this._applyNavigation(true);
}

async _applyNavigation(shouldRestoreLastUrl) {
const isLogin = this.navigation.observe("login").get();
const sessionId = this.navigation.observe("session").get();
const isLogin = this.navigation.path.get("login")
const sessionId = this.navigation.path.get("session")?.value;
const loginToken = this.navigation.path.get("sso")?.value;
if (isLogin) {
if (this.activeSection !== "login") {
this._showLogin();
Expand All @@ -65,7 +67,13 @@ export class RootViewModel extends ViewModel {
this._showSessionLoader(sessionId);
}
}
} else {
} else if (loginToken) {
this.urlCreator.normalizeUrl();
if (this.activeSection !== "login") {
this._showLogin(loginToken);
}
}
else {
try {
if (!(shouldRestoreLastUrl && this.urlCreator.tryRestoreLastUrl())) {
const sessionInfos = await this.platform.sessionInfoStorage.getAll();
Expand Down Expand Up @@ -94,7 +102,7 @@ export class RootViewModel extends ViewModel {
}
}

_showLogin() {
_showLogin(loginToken) {
this._setSection(() => {
this._loginViewModel = new LoginViewModel(this.childOptions({
defaultHomeServer: this.platform.config["defaultHomeServer"],
Expand All @@ -111,6 +119,7 @@ export class RootViewModel extends ViewModel {
this._pendingSessionContainer = sessionContainer;
this.navigation.push("session", sessionContainer.sessionId);
},
loginToken
}));
});
}
Expand All @@ -123,13 +132,11 @@ export class RootViewModel extends ViewModel {
}

_showSessionLoader(sessionId) {
const sessionContainer = this._createSessionContainer();
sessionContainer.startWithExistingSession(sessionId);
this._setSection(() => {
this._sessionLoadViewModel = new SessionLoadViewModel(this.childOptions({
createAndStartSessionContainer: () => {
const sessionContainer = this._createSessionContainer();
sessionContainer.startWithExistingSession(sessionId);
return sessionContainer;
},
sessionContainer,
ready: sessionContainer => this._showSession(sessionContainer)
}));
this._sessionLoadViewModel.start();
Expand Down
22 changes: 4 additions & 18 deletions src/domain/SessionLoadViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import {LoadStatus, LoginFailure} from "../matrix/SessionContainer.js";
import {LoadStatus} from "../matrix/SessionContainer.js";
import {SyncStatus} from "../matrix/Sync.js";
import {ViewModel} from "./ViewModel.js";

export class SessionLoadViewModel extends ViewModel {
constructor(options) {
super(options);
const {createAndStartSessionContainer, ready, homeserver, deleteSessionOnCancel} = options;
this._createAndStartSessionContainer = createAndStartSessionContainer;
const {sessionContainer, ready, homeserver, deleteSessionOnCancel} = options;
this._sessionContainer = sessionContainer;
this._ready = ready;
this._homeserver = homeserver;
this._deleteSessionOnCancel = deleteSessionOnCancel;
Expand All @@ -38,7 +38,6 @@ export class SessionLoadViewModel extends ViewModel {
try {
this._loading = true;
this.emitChange("loading");
this._sessionContainer = this._createAndStartSessionContainer();
this._waitHandle = this._sessionContainer.loadStatus.waitFor(s => {
this.emitChange("loadLabel");
// wait for initial sync, but not catchup sync
Expand Down Expand Up @@ -109,22 +108,9 @@ export class SessionLoadViewModel extends ViewModel {
return `Something went wrong: ${error && error.message}.`;
}

// Statuses related to login are handled by respective login view models
if (sc) {
switch (sc.loadStatus.get()) {
case LoadStatus.NotLoading:
return `Preparing…`;
case LoadStatus.Login:
return `Checking your login and password…`;
case LoadStatus.LoginFailed:
switch (sc.loginFailure) {
case LoginFailure.LoginFailure:
return `Your username and/or password don't seem to be correct.`;
case LoginFailure.Connection:
return `Can't connect to ${this._homeserver}.`;
case LoginFailure.Unknown:
return `Something went wrong while checking your login and password.`;
}
break;
case LoadStatus.SessionSetup:
return `Setting up your encryption keys…`;
case LoadStatus.Loading:
Expand Down
76 changes: 76 additions & 0 deletions src/domain/login/CompleteSSOLoginViewModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed 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 {ViewModel} from "../ViewModel.js";
import {LoginFailure} from "../../matrix/SessionContainer.js";

export class CompleteSSOLoginViewModel extends ViewModel {
constructor(options) {
super(options);
const {
loginToken,
sessionContainer,
attemptLogin,
} = options;
this._loginToken = loginToken;
this._sessionContainer = sessionContainer;
this._attemptLogin = attemptLogin;
this._errorMessage = "";
this.performSSOLoginCompletion();
}

get errorMessage() { return this._errorMessage; }

_showError(message) {
this._errorMessage = message;
this.emitChange("errorMessage");
}

async performSSOLoginCompletion() {
if (!this._loginToken) {
return;
}
const homeserver = await this.platform.settingsStorage.getString("sso_ongoing_login_homeserver");
let loginOptions;
try {
loginOptions = await this._sessionContainer.queryLogin(homeserver);
}
catch (err) {
this._showError(err.message);
return;
}
if (!loginOptions.token) {
this.navigation.push("session");
return;
}
const status = await this._attemptLogin(loginOptions.token(this._loginToken));
let error = "";
switch (status) {
case LoginFailure.Credentials:
error = this.i18n`Your login token is invalid.`;
break;
case LoginFailure.Connection:
error = this.i18n`Can't connect to ${homeserver}.`;
break;
case LoginFailure.Unknown:
error = this.i18n`Something went wrong while checking your login token.`;
break;
}
if (error) {
this._showError(error);
}
}
}

0 comments on commit 3b693c5

Please sign in to comment.