Added room default permission editor screen

The screen allows the user to change the default permission set,
that applies to every member (but not the owner nor the admins).

This screen is only accessible by the owner,
admins or members with the changeAdmin permission.
This commit is contained in:
Jakob Meier 2023-03-25 10:27:21 +01:00
parent 6b98c696ea
commit e3ca4fafa6
No known key found for this signature in database
GPG key ID: 66BDC7E6A01A6152
4 changed files with 199 additions and 1 deletions

View file

@ -87,4 +87,58 @@ class RoomPermission {
static int get manageMembers { static int get manageMembers {
return oB("1000000"); return oB("1000000");
} }
static List<int> get asList {
return [
addArticles,
removeArticles,
listGroupsItems,
changeMeta,
ota,
changeAdmin,
manageMembers
];
}
static String name(int permission) {
switch (permission) {
case 1:
return 'Add Articles';
case 2:
return 'Remove Articles';
case 4:
return 'List Groups and Items';
case 8:
return 'Change Room Metadata';
case 16:
return 'Manage OTAs';
case 32:
return 'Manage Admins';
case 64:
return 'Manage Members';
}
return "Unknown permission";
}
static String describe(int permission) {
switch (permission) {
case 1:
return 'Allows users to add items to the shopping list';
case 2:
return 'Allows users to remove items from the shopping list';
case 4:
return 'Allows the user to view groups and products';
case 8:
return 'Allows the user to edit the room name, description and icon';
case 16:
return 'Alloww the user to create, share and delete authentification tokens';
case 32:
return 'Allows the user to change the admin status of other members';
case 64:
return 'Allows the user to invite and kick room members';
}
return "No description available";
}
} }

View file

@ -3,6 +3,7 @@ import 'package:outbag_app/backend/user.dart';
import 'package:outbag_app/screens/room/edit.dart'; import 'package:outbag_app/screens/room/edit.dart';
import 'package:outbag_app/screens/room/join.dart'; import 'package:outbag_app/screens/room/join.dart';
import 'package:outbag_app/screens/room/members.dart'; import 'package:outbag_app/screens/room/members.dart';
import 'package:outbag_app/screens/room/permissions.dart';
import 'package:outbag_app/screens/room/new.dart'; import 'package:outbag_app/screens/room/new.dart';
import 'package:outbag_app/tools/fetch_wrapper.dart'; import 'package:outbag_app/tools/fetch_wrapper.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -45,7 +46,12 @@ final routesLoggedIn = RouteMap(routes: {
return MaterialPage(child: ManageRoomMembersPage(server, tag)); return MaterialPage(child: ManageRoomMembersPage(server, tag));
}, },
'/r/:server/:tag/permissions': (info) {
final server = info.pathParameters['server'] ?? "";
final tag = info.pathParameters['tag'] ?? "";
return MaterialPage(child: EditRoomPermissionSetPage(server, tag));
},
}, onUnknownRoute: (_) => const Redirect('/')); }, onUnknownRoute: (_) => const Redirect('/'));
void main() { void main() {

View file

@ -52,7 +52,9 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
style: textTheme.bodySmall, style: textTheme.bodySmall,
), ),
Text(widget.room?.description ?? '', Text(widget.room?.description ?? '',
style: textTheme.bodyMedium), style: textTheme.bodyMedium,
textAlign: TextAlign.center,
),
Padding( Padding(
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: SegmentedButton<int>( child: SegmentedButton<int>(
@ -175,6 +177,27 @@ class _AboutRoomPageState extends State<AboutRoomPage> {
'/r/${widget.room?.serverTag}/${widget.room?.id}/members'); '/r/${widget.room?.serverTag}/${widget.room?.id}/members');
}, },
), ),
// edit default member permission
...(widget.info != null &&
((widget.info?.isAdmin ?? false) ||
(widget.info?.isOwner ?? false) ||
((widget.info?.permissions)! &
RoomPermission.changeAdmin !=
0)))
? [
ListTile(
trailing: const Icon(Icons.chevron_right),
title: const Text('Edit Permissions'),
subtitle: const Text(
'Change the default permission-set for all members'),
onTap: () {
// show checkbox screen
Routemaster.of(context).push(
'/r/${widget.room?.serverTag}/${widget.room?.id}/permissions');
},
),
]
: [],
...(widget.info != null && ...(widget.info != null &&
((widget.info?.isAdmin ?? false) || ((widget.info?.isAdmin ?? false) ||
(widget.info?.isOwner ?? false) || (widget.info?.isOwner ?? false) ||

View file

@ -0,0 +1,115 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:outbag_app/backend/permissions.dart';
import 'package:outbag_app/backend/request.dart';
import 'package:outbag_app/backend/room.dart';
import 'package:outbag_app/tools/fetch_wrapper.dart';
import 'package:routemaster/routemaster.dart';
class EditRoomPermissionSetPage extends StatefulWidget {
final String server;
final String tag;
const EditRoomPermissionSetPage(this.server, this.tag, {super.key});
@override
State<StatefulWidget> createState() => _EditRoomPermissionSetPageState();
}
class _EditRoomPermissionSetPageState extends State<EditRoomPermissionSetPage> {
List<int> items = RoomPermission.asList;
int permissions = 0;
void fetchInfo() {
final rmaster = Routemaster.of(context);
final sm = ScaffoldMessenger.of(context);
doNetworkRequest(
sm,
req: (user) => postWithCreadentials(
path: 'getRoomInfo',
credentials: user!,
target: (user.server),
body: {'room': widget.tag, 'server': widget.server}),
onAnyErr: () {
// user should not be here
// close screen
rmaster.replace('/');
return false;
},
onOK: (body) async {
final info = RoomInfo.fromJSON(body['data']);
setState(() {
permissions = info.permissions;
});
return true;
},
);
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => fetchInfo());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Default permissions'),
leading: IconButton(
onPressed: () {
// go back
Navigator.of(context).pop();
},
icon: const Icon(Icons.arrow_back),
tooltip: "Go back",
),
),
body: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
final int col = pow(2, index + 1) as int;
return SwitchListTile(
title: Text(RoomPermission.name(item)),
subtitle: Text(RoomPermission.describe(item)),
onChanged: (state) {
setState(() {
permissions += (state ? 1 : -1) * col;
});
},
value: permissions & col != 0);
},
),
floatingActionButton: FloatingActionButton.extended(
icon: const Icon(Icons.edit),
tooltip: "Update default permission set",
label: const Text('Edit'),
onPressed: () {
final rmaster = Routemaster.of(context);
final sm = ScaffoldMessenger.of(context);
// update permissions
doNetworkRequest(sm,
req: (user) => postWithCreadentials(
path: 'setRoomRight',
credentials: user!,
target: user.server,
body: {
'room': widget.tag,
'server': widget.server,
'rights': permissions
}),
onOK: (_) {
rmaster.pop();
});
},
),
);
}
}