Support the web editor payload format in /lp import

This means that if a user accidentally deletes data locally but still has a working web editor session, they can automatically recover the data contained in the session by importing it with the --upload flag.

Of course, this will only be able to recover the data present in the session. The sensible thing would be to create proper backups (using /lp export or otherwise) - but hey, people are dumb.
This commit is contained in:
Luck 2021-02-19 14:33:54 +00:00
parent 40e8038604
commit a766c0e9aa
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B

View File

@ -33,11 +33,13 @@ import com.google.gson.JsonObject;
import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.utils.NodeJsonSerializer; import me.lucko.luckperms.common.node.utils.NodeJsonSerializer;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.Uuids;
import net.luckperms.api.event.cause.CreationCause; import net.luckperms.api.event.cause.CreationCause;
import net.luckperms.api.model.data.DataType; import net.luckperms.api.model.data.DataType;
@ -131,20 +133,7 @@ public class Importer implements Runnable {
} }
} }
@Override private void parseExportData(Map<String, Set<Node>> groups, Map<String, List<String>> tracks, Map<UUID, UserData> users) {
public void run() {
long startTime = System.currentTimeMillis();
this.notify.forEach(Message.IMPORT_START::send);
// start an update task in the background - we'll #join this later
CompletableFuture<Void> updateTask = CompletableFuture.runAsync(() -> this.plugin.getSyncTaskBuffer().requestDirectly());
this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "Reading data..."));
Map<String, Set<Node>> groups = new HashMap<>();
Map<String, List<String>> tracks = new HashMap<>();
Map<UUID, UserData> users = new HashMap<>();
for (Map.Entry<String, JsonElement> group : getDataSection("groups")) { for (Map.Entry<String, JsonElement> group : getDataSection("groups")) {
groups.put(group.getKey(), NodeJsonSerializer.deserializeNodes(group.getValue().getAsJsonObject().get("nodes").getAsJsonArray())); groups.put(group.getKey(), NodeJsonSerializer.deserializeNodes(group.getValue().getAsJsonObject().get("nodes").getAsJsonArray()));
} }
@ -171,6 +160,65 @@ public class Importer implements Runnable {
users.put(uuid, new UserData(username, primaryGroup, nodes)); users.put(uuid, new UserData(username, primaryGroup, nodes));
} }
}
private void parseWebEditorData(Map<String, Set<Node>> groups, Map<String, List<String>> tracks, Map<UUID, UserData> users) {
JsonArray holdersArray = this.data.get("permissionHolders").getAsJsonArray();
for (JsonElement holderElement : holdersArray) {
JsonObject jsonData = holderElement.getAsJsonObject();
HolderType type = HolderType.valueOf(jsonData.get("type").getAsString().toUpperCase());
String id = jsonData.get("id").getAsString();
if (type == HolderType.GROUP) {
groups.put(id, NodeJsonSerializer.deserializeNodes(jsonData.get("nodes").getAsJsonArray()));
} else {
UUID uuid = UUID.fromString(id);
String username = null;
String displayName = jsonData.get("displayName").getAsString();
if (!Uuids.PREDICATE.test(displayName)) {
username = displayName;
}
Set<Node> nodes = NodeJsonSerializer.deserializeNodes(jsonData.get("nodes").getAsJsonArray());
users.put(uuid, new UserData(username, null, nodes));
}
}
JsonArray tracksArray = this.data.get("tracks").getAsJsonArray();
for (JsonElement trackElement : tracksArray) {
JsonObject jsonData = trackElement.getAsJsonObject();
String name = jsonData.get("id").getAsString();
JsonArray trackGroups = jsonData.get("groups").getAsJsonArray();
List<String> trackGroupsList = new ArrayList<>();
trackGroups.forEach(g -> trackGroupsList.add(g.getAsString()));
tracks.put(name, trackGroupsList);
}
}
@Override
public void run() {
long startTime = System.currentTimeMillis();
this.notify.forEach(Message.IMPORT_START::send);
// start an update task in the background - we'll #join this later
CompletableFuture<Void> updateTask = CompletableFuture.runAsync(() -> this.plugin.getSyncTaskBuffer().requestDirectly());
this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "Reading data..."));
Map<String, Set<Node>> groups = new HashMap<>();
Map<String, List<String>> tracks = new HashMap<>();
Map<UUID, UserData> users = new HashMap<>();
if (this.data.has("knownPermissions")) {
this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "The data appears to be from a web editor upload - attempting to recover from it"));
parseWebEditorData(groups, tracks, users);
} else {
parseExportData(groups, tracks, users);
}
this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "Waiting for initial update task to complete...")); this.notify.forEach(s -> Message.IMPORT_INFO.send(s, "Waiting for initial update task to complete..."));