Implement session sign out (password auth only)

This commit is contained in:
miruka 2020-06-29 10:30:44 -04:00
parent 8a3d9affaa
commit b47d4d981f
7 changed files with 85 additions and 32 deletions

View File

@ -32,7 +32,7 @@ Written in Qt/QML + Python with [nio](https://github.com/poljar/matrix-nio),
- **Multiple accounts** in one client
- Set your display name and profile picture
- Import/export **E2E** key files
- Inspect, rename and manually verify your sessions
- Inspect, rename, manually verify and sign out one or multiple sessions
### Rooms

View File

@ -185,7 +185,6 @@
- E2E
- List and verify other users's devices
- SAS verification
- Delete devices (do that in key verification popup instead of blacklisting)
- Request room keys from own other devices
- Auto-trust accounts within the same client
- Provide help when undecryptable messages occur, including:

View File

@ -33,6 +33,12 @@ class MatrixError(Exception):
return cls(response.transport_response.status, response.status_code)
@dataclass
class MatrixUnauthorized(MatrixError):
http_code: int = 401
m_code: str = "M_UNAUTHORIZED"
@dataclass
class MatrixForbidden(MatrixError):
http_code: int = 403

View File

@ -34,8 +34,8 @@ from nio.crypto import async_generator_from_data
from . import __app_name__, __display_name__, utils
from .errors import (
BadMimeType, InvalidUserId, InvalidUserInContext, MatrixBadGateway,
MatrixError, MatrixNotFound, MatrixTooLarge, UneededThumbnail,
UserFromOtherServerDisallowed,
MatrixError, MatrixNotFound, MatrixTooLarge, MatrixUnauthorized,
UneededThumbnail, UserFromOtherServerDisallowed,
)
from .html_markdown import HTML_PROCESSOR as HTML
from .media_cache import Media, Thumbnail
@ -1347,6 +1347,23 @@ class MatrixClient(nio.AsyncClient):
self.blacklist_device(self.olm.device_store[user_id][device_id])
async def delete_devices_with_password(
self, device_ids: List[str], password: str,
) -> None:
"""Delete devices, authentifying using the account's password."""
auth = {
"type": "m.login.password",
"user": self.user_id,
"password": password,
}
resp = await super().delete_devices(device_ids, auth)
if isinstance(resp, nio.DeleteDevicesAuthResponse):
raise MatrixUnauthorized()
# Functions to register/modify data into models
async def update_account_unread_counts(self) -> None:

View File

@ -53,16 +53,32 @@ HColumnPage {
}
function deleteDevices(...indice) {
const deviceIds = []
if (indice.length === 1 && indice[0] === 0) {
utils.makePopup("Popups/SignOutPopup.qml", { userId: page.userId })
return
}
for (const i of indice.sort())
const deviceIds = []
let deleteOwnDevice = false
for (const i of indice.sort()) {
i === 0 ?
deleteOwnDevice = true :
deviceIds.push(deviceList.model.get(i).id)
}
utils.makePopup(
"Popups/AuthentificationPopup.qml",
"Popups/DeleteDevicesPopup.qml",
{
userId: page.userId,
deviceIds,
deletedCallback: () => {
deleteOwnDevice ?
utils.makePopup(
"Popups/SignOutPopup.qml", { userId: page.userId },
) :
page.loadDevices()
},
},
)
}

View File

@ -1,25 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import "../Base"
import "../Base/ButtonLayout"
HFlickableColumnPopup {
id: popup
property string userId
property string deviceIds
page.footer: ButtonLayout {
CancelButton {
id: cancelButton
onClicked: popup.close()
}
}
onOpened: cancelButton.forceActiveFocus()
SummaryLabel { text: qsTr("Not implemented yet") }
}

View File

@ -0,0 +1,40 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
import QtQuick 2.12
import "../Base"
import "../Base/ButtonLayout"
PasswordPopup {
id: popup
property string userId
property var deviceIds // array
property var deletedCallback: null
function verifyPassword(pass, callback) {
py.callClientCoro(
userId,
"delete_devices_with_password",
[deviceIds, pass],
() => callback(true),
(type, args) => {
callback(
type === "MatrixUnauthorized" ?
false :
qsTr("Unknown error: %1 - %2").arg(type).arg(args)
)
},
)
}
summary.text:
qsTr("Enter your account's password to continue:")
validateButton.text: qsTr("Sign out")
validateButton.icon.name: "sign-out"
onClosed: if (acceptedPassword && deletedCallback) deletedCallback()
}