From aee9c9f82ec98147314b579ef678276992982e3e Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 23 Mar 2023 10:51:34 +0100 Subject: [PATCH] Added server dashboard button to menu The button is only shown if the user has any of the management permissions. --- lib/backend/permissions.dart | 14 ++++ lib/backend/user.dart | 28 ++++++++ lib/main.dart | 133 ++++++++++++++++++----------------- lib/screens/home.dart | 12 ++++ pubspec.lock | 16 +++++ pubspec.yaml | 1 + 6 files changed, 141 insertions(+), 63 deletions(-) diff --git a/lib/backend/permissions.dart b/lib/backend/permissions.dart index 6c8cf9f..14ddbc1 100644 --- a/lib/backend/permissions.dart +++ b/lib/backend/permissions.dart @@ -12,34 +12,48 @@ class ServerPermission { static int get none { return oB("0000000000000000"); } + // default permission set static int get def { return oB("0000000000000011"); } + static int get canUseAPI { return oB("0000000000000001"); } + static int get provideCert { return oB("0000000000000010"); } + static int get manageOTA { return oB("0000010000000000"); } + static int get manageServerProductList { return oB("0000100000000000"); } + static int get viewUsersAndLists { return oB("0001000000000000"); } + static int get editSettings { return oB("0010000000000000"); } + static int get editPermissions { return oB("0100000000000000"); } + static int get editUsers { return oB("1000000000000000"); } + + static int get allManagement { + return oB("1111110000000000"); + } + static int get all { return oB("1111111111111111"); } diff --git a/lib/backend/user.dart b/lib/backend/user.dart index 659ca52..d9d3471 100644 --- a/lib/backend/user.dart +++ b/lib/backend/user.dart @@ -36,3 +36,31 @@ class User { stream.listen(cb); } } + +class AccountMeta { + final int permissions; + final String username; + final bool discvoverable; + final int maxRoomCount; + final int maxRoomSize; + final int maxRoomMemberCount; + + const AccountMeta( + {required this.permissions, + required this.username, + required this.maxRoomSize, + required this.maxRoomCount, + required this.maxRoomMemberCount, + required this.discvoverable}); + + factory AccountMeta.fromJSON(dynamic json) { + return AccountMeta( + permissions: json['rights'], + username: json['name'], + maxRoomSize: json['maxRoomSize'], + maxRoomCount: json['maxRooms'], + maxRoomMemberCount: json['maxUsersPerRoom'], + discvoverable: json['viewable'] == 1 + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index 0526886..db0ad6f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:outbag_app/backend/user.dart'; import 'package:outbag_app/screens/room/join.dart'; import 'package:outbag_app/screens/room/new.dart'; +import 'package:provider/provider.dart'; import './screens/home.dart'; import './screens/welcome.dart'; import './screens/room/main.dart'; @@ -11,25 +12,25 @@ import 'package:routemaster/routemaster.dart'; // routes when user is not logged in final routesUnauthorized = RouteMap(routes: { - '/welcome/': (_) => const MaterialPage(child: WelcomePage()), - '/signup': (_) => const MaterialPage(child: AuthPage(mode: Mode.signup)), - '/signupOTA': (_) => - const MaterialPage(child: AuthPage(mode: Mode.signupOTA)), - '/signin': (_) => const MaterialPage(child: AuthPage(mode: Mode.signin)), -}, onUnknownRoute: (_) => const MaterialPage(child: WelcomePage())); + '/welcome/': (_) => const MaterialPage(child: WelcomePage()), + '/signup': (_) => const MaterialPage(child: AuthPage(mode: Mode.signup)), + '/signupOTA': (_) => + const MaterialPage(child: AuthPage(mode: Mode.signupOTA)), + '/signin': (_) => const MaterialPage(child: AuthPage(mode: Mode.signin)), + }, onUnknownRoute: (_) => const MaterialPage(child: WelcomePage())); // routes when user is logged in final routesLoggedIn = RouteMap(routes: { - '/': (_) => const MaterialPage(child: HomePage()), - '/add-room/new': (_) => const MaterialPage(child: NewRoomPage()), - '/add-room': (_) => const MaterialPage(child: JoinRoomPage()), - '/r/:server/:tag/': (info) { - final server = info.pathParameters['server'] ?? ""; - final tag = info.pathParameters['tag'] ?? ""; + '/': (_) => const MaterialPage(child: HomePage()), + '/add-room/new': (_) => const MaterialPage(child: NewRoomPage()), + '/add-room': (_) => const MaterialPage(child: JoinRoomPage()), + '/r/:server/:tag/': (info) { + final server = info.pathParameters['server'] ?? ""; + final tag = info.pathParameters['tag'] ?? ""; - return MaterialPage(child: RoomPage(server, tag)); - }, -}, onUnknownRoute: (_) => const Redirect('/')); + return MaterialPage(child: RoomPage(server, tag)); + }, + }, onUnknownRoute: (_) => const Redirect('/')); void main() { WidgetsFlutterBinding.ensureInitialized(); @@ -48,6 +49,7 @@ class _OutbagAppState extends State { // unless not userdata is found // or the userdata turns out to be wrong bool isAuthorized = true; + AccountMeta? info; @override void initState() { @@ -57,70 +59,75 @@ class _OutbagAppState extends State { // with existing details // NOTE: also functions as a way to verify ther data (() async { - User credentials; - try { - credentials = await User.fromDisk(); - } catch (_) { - // invalid credentials - // log out - setState(() { - isAuthorized = false; - }); - return; - } - try { - final resp = await postWithCreadentials( + User credentials; + try { + credentials = await User.fromDisk(); + } catch (_) { + // invalid credentials + // log out + setState(() { + isAuthorized = false; + }); + return; + } + try { + final resp = await postWithCreadentials( target: credentials.server, path: 'getMyAccount', credentials: credentials, body: {}); - if (resp.res == Result.ok) { - print(resp.body); + if (resp.res == Result.ok) { + final info = AccountMeta.fromJSON(resp.body['data']); + setState(() { + isAuthorized = true; + this.info = info; + }); + } else { + // credentials are wrong + // log out + setState(() { + isAuthorized = false; + }); + } + } catch (_) { + // user is currently offline + // approve login, + // until user goes back offline + // NOTE TODO: check user data once online setState(() { - isAuthorized = true; - }); - } else { - // credentials are wrong - // log out - setState(() { - isAuthorized = true; + isAuthorized = true; }); } - } catch (_) { - // user is currently offline - // approve login, - // until user goes back offline - // NOTE TODO: check user data once online - setState(() { - isAuthorized = true; - }); - } })(); // wait for user to be authorized User.listen((data) async { - try { - await User.fromDisk(); - setState(() { - isAuthorized = true; - }); - } catch (_) {} + try { + await User.fromDisk(); + setState(() { + isAuthorized = true; + }); + } catch (_) {} }); } @override Widget build(BuildContext context) { - return MaterialApp.router( - title: "Outbag", - // TODO: change back to system (or load from disk) - //themeMode: ThemeMode.system, - themeMode: ThemeMode.dark, - theme: ThemeData(useMaterial3: true, brightness: Brightness.light), - darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), - routerDelegate: RoutemasterDelegate( + return MultiProvider( + providers: [ + Provider.value(value: info,), + ], + child: MaterialApp.router( + title: "Outbag", + // TODO: change back to system (or load from disk) + //themeMode: ThemeMode.system, + themeMode: ThemeMode.dark, + theme: ThemeData(useMaterial3: true, brightness: Brightness.light), + darkTheme: ThemeData(useMaterial3: true, brightness: Brightness.dark), + routerDelegate: RoutemasterDelegate( routesBuilder: (context) => - isAuthorized ? routesLoggedIn : routesUnauthorized), - routeInformationParser: const RoutemasterParser(), - ); + isAuthorized ? routesLoggedIn : routesUnauthorized), + routeInformationParser: const RoutemasterParser(), + )); } } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index a7d3251..350f38f 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -2,8 +2,10 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:outbag_app/backend/permissions.dart'; import 'package:outbag_app/backend/request.dart'; import 'package:outbag_app/backend/user.dart'; +import 'package:provider/provider.dart'; import 'package:routemaster/routemaster.dart'; import '../backend/room.dart'; @@ -103,6 +105,16 @@ class _HomePageState extends State { // show settings screen Routemaster.of(context).push("/settings"); }), + ...(context.watch() != null && + (context.watch()?.permissions)! & ServerPermission.allManagement != 0)?[ + MenuItemButton( + leadingIcon: const Icon(Icons.dns), + child: const Text('Server Dashboard'), + onPressed: () { + // show settings screen + Routemaster.of(context).push("/server"); + }), + ]:[], MenuItemButton( leadingIcon: const Icon(Icons.info_rounded), child: const Text('About'), diff --git a/pubspec.lock b/pubspec.lock index f9c13b6..58c59e9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -184,6 +184,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" path: dependency: transitive description: @@ -280,6 +288,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" + provider: + dependency: "direct main" + description: + name: provider + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" + source: hosted + version: "6.0.5" routemaster: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 0f29d13..fb4a5e1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: http: ^0.13.5 localstore: ^1.3.5 crypto: ^3.0.2 + provider: ^6.0.5 dev_dependencies: flutter_test: