import 'package:libac_dart/nbt/impl/CompoundTag.dart'; import 'package:libac_dart/nbt/impl/IntTag.dart'; import 'package:libac_dart/nbt/impl/StringTag.dart'; import 'package:libac_dart/utils/Hashing.dart'; import 'package:servermanager/structs/discordHookHelper.dart'; import 'package:servermanager/structs/settings.dart'; class User { String name; String passwordHash; String passwordSalt; UserLevel permissions; final String userHash; bool login(String username, String passwordHash) { if (userHash != generateValidityCheck()) { return false; // User will be thrown away next time the data is reloaded } if (name == username) { if (Hashing.sha256Hash("$passwordSalt:$passwordHash") == this.passwordHash) { return true; } else { return false; } } else { return false; } } Future sendDiscordActionLog(String actionMessage) async { Settings settings = Settings(); DiscordHookHelper.sendWebHook( settings.inst!.discord, DiscordHookProps.ALERT, "User Action Alert", "$this: $actionMessage"); } User( {required this.name, required this.passwordHash, required this.passwordSalt, required this.permissions, required this.userHash}); CompoundTag serialize() { CompoundTag ct = CompoundTag(); ct.put(TAG_NAME, StringTag.valueOf(name)); ct.put(TAG_HASH, StringTag.valueOf(passwordHash)); ct.put(TAG_SALT, StringTag.valueOf(passwordSalt)); ct.put(TAG_PERMS, IntTag.valueOf(permissions.ord())); ct.put(TAG_SEC_CODE, StringTag.valueOf(userHash)); return ct; } static User deserialize(CompoundTag ct) { return User( name: ct.get(TAG_NAME)!.asString(), passwordHash: ct.get(TAG_HASH)!.asString(), passwordSalt: ct.get(TAG_SALT)!.asString(), permissions: UserLevel.of(ct.get(TAG_PERMS)!.asInt()), userHash: ct.get(TAG_SEC_CODE)!.asString()); } factory User.make(String name, String password, UserLevel level) { String salt = Hashing.sha256Hash( Hashing.md5Hash(Hashing.sha256Hash("${DateTime.now().millisecondsSinceEpoch}"))); String hash = Hashing.sha256Hash("$salt:${Hashing.sha256Hash(password)}"); String validityCode = generateValidityCode(name, hash, salt, level); return User( name: name, passwordHash: hash, passwordSalt: salt, permissions: level, userHash: validityCode); } String generateValidityCheck() { return Hashing.sha256Hash( "$name:$passwordHash:$passwordSalt:${permissions.ord()}}"); } static String generateValidityCode(String name, String passwordHash, String passwordSalt, UserLevel permissions) { return Hashing.sha256Hash( "$name:$passwordHash:$passwordSalt:${permissions.ord()}}"); } static const TAG_NAME = "name"; static const TAG_HASH = "hash"; static const TAG_SALT = "salt"; static const TAG_PERMS = "perms"; static const TAG_SEC_CODE = "validity"; @override String toString() { return "${permissions.name}: $name"; } } enum UserLevel { Super_User(0), Administrator(1), Operator(2), None(99); final int _id; const UserLevel(this._id); int ord() { return _id; } static UserLevel of(int ord) { for (var lvl in values) { if (lvl.ord() == ord) { return lvl; } } return UserLevel.None; } }