Adds a full access control list editor
This commit is contained in:
parent
4b71526270
commit
ae1da5f2b2
6 changed files with 201 additions and 6 deletions
|
@ -36,8 +36,11 @@ void main() async {
|
||||||
settings.Write();
|
settings.Write();
|
||||||
print("Wrote settings.dat");
|
print("Wrote settings.dat");
|
||||||
|
|
||||||
settings.superuser = User.make(settings.serverLoginCreds.username,
|
if (settings.FTS)
|
||||||
settings.serverLoginCreds.password, UserLevel.Super_User);
|
settings.superuser = User.make(
|
||||||
|
settings.serverLoginCreds.username,
|
||||||
|
settings.serverLoginCreds.password,
|
||||||
|
UserLevel.Super_User); // Initialize the super-user account
|
||||||
|
|
||||||
print("Initializing SteamCMD");
|
print("Initializing SteamCMD");
|
||||||
await settings.initializeSteamCmd();
|
await settings.initializeSteamCmd();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:libac_dart/packets/packets.dart';
|
import 'package:libac_dart/packets/packets.dart';
|
||||||
import 'package:servermanager/packets/ClientPackets.dart';
|
import 'package:servermanager/packets/ClientPackets.dart';
|
||||||
|
import 'package:servermanager/pages/ACL.dart';
|
||||||
import 'package:servermanager/pages/Constants.dart';
|
import 'package:servermanager/pages/Constants.dart';
|
||||||
import 'package:servermanager/pages/DiscordConfigPage.dart';
|
import 'package:servermanager/pages/DiscordConfigPage.dart';
|
||||||
import 'package:servermanager/pages/GameServerPage.dart';
|
import 'package:servermanager/pages/GameServerPage.dart';
|
||||||
|
@ -30,6 +31,7 @@ class MyApp extends StatelessWidget {
|
||||||
"/": (context) => ServerPage(),
|
"/": (context) => ServerPage(),
|
||||||
"/home": (context) => HomePage(settings: appSettings),
|
"/home": (context) => HomePage(settings: appSettings),
|
||||||
"/creds": (context) => CredentialsPage(),
|
"/creds": (context) => CredentialsPage(),
|
||||||
|
"/acl": (context) => AccessControlListPage(),
|
||||||
"/server": (context) => GameServerPage(settings: appSettings),
|
"/server": (context) => GameServerPage(settings: appSettings),
|
||||||
"/server/autorestart": (context) => AutoRestartPage(),
|
"/server/autorestart": (context) => AutoRestartPage(),
|
||||||
"/server/ports": (context) => ServerSettingsPage(),
|
"/server/ports": (context) => ServerSettingsPage(),
|
||||||
|
|
180
lib/pages/ACL.dart
Normal file
180
lib/pages/ACL.dart
Normal 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);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ class CredentialsPrompt extends State<CredentialsPage> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
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),
|
backgroundColor: Color.fromARGB(255, 100, 0, 0),
|
||||||
),
|
),
|
||||||
floatingActionButton: ElevatedButton(
|
floatingActionButton: ElevatedButton(
|
||||||
|
|
|
@ -93,17 +93,26 @@ class HomePageState extends State<HomePage> {
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text("Manager Credentials"),
|
title: Text("Manager Credentials"),
|
||||||
subtitle: Text("Edit ServerManager credentials"),
|
subtitle:
|
||||||
|
Text("Edit ServerManager credentials (SUPER USER ONLY)"),
|
||||||
leading: Icon(Icons.key),
|
leading: Icon(Icons.key),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
var reply = await Navigator.pushNamed(context, "/creds",
|
var reply = await Navigator.pushNamed(context, "/creds",
|
||||||
arguments: settings.serverLoginCreds);
|
arguments: settings.superuser.name);
|
||||||
if (reply != null) {
|
if (reply != null) {
|
||||||
Credentials creds = reply as Credentials;
|
Credentials creds = reply as Credentials;
|
||||||
settings.serverLoginCreds = creds;
|
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(
|
ListTile(
|
||||||
title: Text("Save Changes"),
|
title: Text("Save Changes"),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Settings {
|
||||||
UUID remoteLoginToken = UUID.ZERO;
|
UUID remoteLoginToken = UUID.ZERO;
|
||||||
|
|
||||||
PacketClient? client;
|
PacketClient? client;
|
||||||
User? superuser;
|
User superuser = User.make("admin", "changeMe123", UserLevel.Super_User);
|
||||||
|
|
||||||
User? loggedInUser;
|
User? loggedInUser;
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ class Settings {
|
||||||
NbtUtils.writeBoolean(tag, "fts", FTS);
|
NbtUtils.writeBoolean(tag, "fts", FTS);
|
||||||
|
|
||||||
tag.put("server_creds", serverLoginCreds.save());
|
tag.put("server_creds", serverLoginCreds.save());
|
||||||
|
tag.put("superuser", superuser.serialize());
|
||||||
NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken));
|
NbtUtils.writeUUID(tag, "token", NbtUUID.fromUUID(remoteLoginToken));
|
||||||
|
|
||||||
if (inst != null) tag.put("main", inst!.serialize());
|
if (inst != null) tag.put("main", inst!.serialize());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue