common: Add account settings

This commit is contained in:
Elias Projahn 2020-05-11 18:50:06 +02:00
parent bc2f9ba27d
commit 8765edc257
2 changed files with 99 additions and 10 deletions

View file

@ -141,6 +141,19 @@ class MusicusBackendState extends State<MusicusBackend> {
_updateClient(serverSettings);
});
settings.account.listen((accountSettings) {
if (accountSettings != null) {
client.user = User(
name: accountSettings.username,
email: accountSettings.email,
password: accountSettings.password,
);
} else {
client.user = null;
}
});
// This will also check for existing account settings.
_updateClient(settings.server.value);
final path = settings.musicLibraryPath.value;
@ -168,13 +181,26 @@ class MusicusBackendState extends State<MusicusBackend> {
}
}
/// Create a new client based on [settings].
void _updateClient(MusicusServerSettings settings) {
/// Create a new client based on [serverSettings].
void _updateClient(MusicusServerSettings serverSettings) {
client?.dispose();
User user;
final accountSettings = settings.account.value;
if (accountSettings != null) {
user = User(
name: accountSettings.username,
email: accountSettings.email,
password: accountSettings.password,
);
}
client = MusicusClient(
host: settings.host,
port: settings.port,
basePath: settings.apiPath,
host: serverSettings.host,
port: serverSettings.port,
basePath: serverSettings.apiPath,
user: user,
);
}

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:meta/meta.dart';
import 'package:rxdart/rxdart.dart';
@ -36,6 +38,24 @@ class MusicusServerSettings {
});
}
/// Settings concerning the Musicus account.
class MusicusAccountSettings {
/// The user name to login as.
final String username;
/// An optional email address.
final String email;
/// The password for authentication.
final String password;
MusicusAccountSettings({
this.username,
this.email,
this.password,
});
}
/// Manager for all settings that are persisted.
class MusicusSettings {
static const defaultHost = 'musicus.johrpan.de';
@ -54,6 +74,9 @@ class MusicusSettings {
/// Musicus server to connect to.
final server = BehaviorSubject<MusicusServerSettings>();
/// Musicus account to login with.
final account = BehaviorSubject<MusicusAccountSettings>();
/// Create a settings instance.
MusicusSettings(this.storage);
@ -75,6 +98,18 @@ class MusicusSettings {
port: port,
apiPath: apiPath,
));
final username = await storage.getString('accountUsername');
final email = await storage.getString('accountEmail');
final passwordBase64 = await storage.getString('accountPassword');
if (username != null) {
account.add(MusicusAccountSettings(
username: username,
email: email,
password: utf8.decode(base64Decode(passwordBase64)),
));
}
}
/// Set a new music library path.
@ -104,9 +139,37 @@ class MusicusSettings {
));
}
/// Update the account settings.
///
/// This will persist the new values and update the stream.
Future<void> setAccount(MusicusAccountSettings accountSettings) async {
await storage.setString('accountUsername', accountSettings.username);
await storage.setString('accountEmail', accountSettings.email);
// IMPORTANT NOTE: We encode the password using Base64 to defend just the
// simplest of simplest attacks. This provides no additional security
// besides the fact that the password looks a little bit encrypted.
await storage.setString(
'accountPassword',
base64Encode(utf8.encode(accountSettings.password)),
);
account.add(accountSettings);
}
/// Delete the current account settings.
Future<void> clearAccount() async {
await storage.setString('accountUsername', null);
await storage.setString('accountEmail', null);
await storage.setString('accountPassword', null);
account.add(null);
}
/// Tidy up.
void dispose() {
musicLibraryPath.close();
server.close();
account.close();
}
}