Adds a full access control list editor

This commit is contained in:
zontreck 2024-07-02 17:48:06 -07:00
parent 4b71526270
commit ae1da5f2b2
6 changed files with 201 additions and 6 deletions

View file

@ -36,8 +36,11 @@ void main() async {
settings.Write();
print("Wrote settings.dat");
settings.superuser = User.make(settings.serverLoginCreds.username,
settings.serverLoginCreds.password, UserLevel.Super_User);
if (settings.FTS)
settings.superuser = User.make(
settings.serverLoginCreds.username,
settings.serverLoginCreds.password,
UserLevel.Super_User); // Initialize the super-user account
print("Initializing SteamCMD");
await settings.initializeSteamCmd();

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:libac_dart/packets/packets.dart';
import 'package:servermanager/packets/ClientPackets.dart';
import 'package:servermanager/pages/ACL.dart';
import 'package:servermanager/pages/Constants.dart';
import 'package:servermanager/pages/DiscordConfigPage.dart';
import 'package:servermanager/pages/GameServerPage.dart';
@ -30,6 +31,7 @@ class MyApp extends StatelessWidget {
"/": (context) => ServerPage(),
"/home": (context) => HomePage(settings: appSettings),
"/creds": (context) => CredentialsPage(),
"/acl": (context) => AccessControlListPage(),
"/server": (context) => GameServerPage(settings: appSettings),
"/server/autorestart": (context) => AutoRestartPage(),
"/server/ports": (context) => ServerSettingsPage(),

180
lib/pages/ACL.dart Normal file
View file

@ -0,0 +1,180 @@
import 'package:flutter/material.dart';
import 'package:servermanager/pages/Constants.dart';
import 'package:servermanager/structs/credentials.dart';
import 'package:servermanager/structs/settings.dart';
class AccessControlListPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return AccessControlState();
}
}
class AccessControlState extends State<AccessControlListPage> {
Settings settings = Settings();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Conan Exiles Server Manager - ACL Editor"),
backgroundColor: Constants.TITLEBAR_COLOR,
),
floatingActionButton: ElevatedButton(
onPressed: () {
// Show the add new user page
Navigator.pushNamed(context, "/acl/edit");
},
child: Icon(Icons.add),
),
body: Padding(
padding: EdgeInsets.all(8),
child: ListView.builder(
itemBuilder: (ctx, index) {
User user = settings.inst!.admins[index];
return ListTile(
title: Text(user.name),
subtitle: Text("Access Level: ${user.permissions.name}"),
onTap: () async {
var edited = await Navigator.pushNamed(context, "/acl/edit",
arguments: user);
if (edited == null) return;
if (edited is bool) {
settings.inst!.admins.remove(user);
setState(() {});
return;
}
setState(() {
settings.inst!.admins[index] = edited as User;
});
},
);
},
itemCount: settings.inst!.admins.length,
)),
);
}
}
class ACLEdit extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ACLEditorState();
}
}
class ACLEditorState extends State<ACLEdit> {
Settings settings = Settings();
var newUser = false;
TextEditingController username = TextEditingController();
TextEditingController password = TextEditingController();
User? current;
@override
void didChangeDependencies() {
var args = ModalRoute.of(context)!.settings.arguments;
if (args == null) {
newUser = true;
} else {
User usr = args as User;
username.text = usr.name;
current = usr;
}
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"CE SM - ACL Edit - ${newUser ? "Create A User" : "Edit User - ${username.text}"}"),
backgroundColor: Constants.TITLEBAR_COLOR,
),
floatingActionButton: ElevatedButton(
onPressed: () {
User? user;
if (!newUser) {
if (password.text.isEmpty) {
user = User(
name: username.text,
passwordHash: current!.passwordHash,
passwordSalt: current!.passwordSalt,
permissions: current!.permissions,
userHash: User.generateValidityCode(
username.text,
current!.passwordHash,
current!.passwordSalt,
current!.permissions));
} else {
user = User.make(
username.text, password.text, UserLevel.Administrator);
}
} else {
user = User.make(
username.text, password.text, UserLevel.Administrator);
}
Navigator.pop(context, user);
},
child: Text("Save"),
),
body: Padding(
padding: EdgeInsets.all(8),
child: SingleChildScrollView(
child: Column(
children: [
Row(
children: [
SizedBox(
width: 150,
child: ListTile(
title: Text("Username"),
),
),
TextField(
controller: username,
)
],
),
if (!newUser)
ListTile(
title: Text("Warning"),
subtitle: Text(
"The password is encrypted, if you wish to change the password do so below, but the field is intentionally not filled in. If left blank, it will remain unchanged."),
),
Row(
children: [
SizedBox(
width: 150,
child: ListTile(
title: Text("Password"),
),
),
TextField(
controller: password,
obscureText: true,
)
],
),
if (!newUser)
ListTile(
title: Text("DELETE USER"),
leading: Icon(Icons.delete),
subtitle: Text("Delete the current user entirely"),
onTap: () {
Navigator.pop(context, false);
},
)
],
),
),
),
);
}
}

View file

@ -32,7 +32,7 @@ class CredentialsPrompt extends State<CredentialsPage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Conan Exiles Server Manager - Credentials (Super User)"),
title: Text("Conan Exiles Server Manager - Credentials"),
backgroundColor: Color.fromARGB(255, 100, 0, 0),
),
floatingActionButton: ElevatedButton(

View file

@ -93,17 +93,26 @@ class HomePageState extends State<HomePage> {
),
ListTile(
title: Text("Manager Credentials"),
subtitle: Text("Edit ServerManager credentials"),
subtitle:
Text("Edit ServerManager credentials (SUPER USER ONLY)"),
leading: Icon(Icons.key),
onTap: () async {
var reply = await Navigator.pushNamed(context, "/creds",
arguments: settings.serverLoginCreds);
arguments: settings.superuser.name);
if (reply != null) {
Credentials creds = reply as Credentials;
settings.serverLoginCreds = creds;
}
},
),
ListTile(
title: Text("Manage Access Control List"),
subtitle: Text("Non-Super User access manager"),
leading: Icon(Icons.list),
onTap: () async {
Navigator.pushNamed(context, "/acl");
},
),
ListTile(
title: Text("Save Changes"),
subtitle: Text(

View file

@ -40,7 +40,7 @@ class Settings {
UUID remoteLoginToken = UUID.ZERO;
PacketClient? client;
User? superuser;
User superuser = User.make("admin", "changeMe123", UserLevel.Super_User);
User? loggedInUser;
@ -59,6 +59,7 @@ class Settings {
NbtUtils.writeBoolean(tag, "fts", FTS);
tag.put("server_creds", serverLoginCreds.save());
tag.put("superuser", superuser.serialize());
NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken));
if (inst != null) tag.put("main", inst!.serialize());