/** * Create a new node tree with the given values, and a default value of * {@link Tristate#UNDEFINED}. * * @param values The values to set * @return The new node tree */ public static NodeTree of(Map<String, Boolean> values) { return of(values, Tristate.UNDEFINED); }
/** * Test whether the subject is permitted to perform an action given as the * given permission string. * * <p>This must return the same value as {@link #hasPermission(Set, String)} * using {@link #getActiveContexts()}.</p> * * @param permission The permission string * @return True if permission is granted */ default boolean hasPermission(String permission) { return hasPermission(getActiveContexts(), permission); }
/** * Gets the value of a given option in the subject's current context. * * <p>This must return the same value as {@link #getOption(Set, String)} * using {@link #getActiveContexts()}.</p> * * @param key The key to get an option by. Case-insensitive. * @return The value of the option, if any is present */ default Optional<String> getOption(String key) { return getOption(getActiveContexts(), key); } }
/** * Performs an action on each Subject in the provided set. * * <p>Subjects are loaded, supplied to the consumer, and then allowed to be * uncached by the implementation.</p> * * <p>This should be used to apply bulk changes or gather data about all * Subjects in the collection. The provided consumer will be supplied * asynchronously. Acting upon a large collection may be particularly * resource intensive.</p> * * <p>Implementations may choose to load and process subjects in * parallel.</p> * * @param action The action to perform on each subject * @param identifiers a set of identifiers to apply the action to * @return A future which will complete when the operation has finished */ default CompletableFuture<Void> applyToAll(Consumer<Subject> action, Set<String> identifiers) { Preconditions.checkNotNull(action, "action"); Preconditions.checkNotNull(identifiers, "identifiers"); return CompletableFuture.runAsync(() -> { for (String id : identifiers) { Subject subject = loadSubject(id).join(); action.accept(subject); suggestUnload(subject.getIdentifier()); } }); }
/** * Return all parents that this group has in its current context * combination. * * <p>This must include inherited values if the permissions * service supports inheritance.</p> * * <p>It must also must return the same value as {@link #getParents(Set)} * using {@link #getActiveContexts()}.</p> * * @return An immutable list of parents */ default List<SubjectReference> getParents() { return getParents(getActiveContexts()); }
public void registerPermission(CommandCallable command, String permission) { Sponge.getGame().getServiceManager().getRegistration(PermissionService.class).ifPresent((permissionService -> { PermissionDescription.Builder permissionBuilder = permissionService.getProvider().newDescriptionBuilder(SpongeWorldEdit.inst()); permissionBuilder.id(permission).register(); })); }
@Test public void testAsMap() { final Map<String, Boolean> testPermissions = new HashMap<>(); testPermissions.put("generate.rainbow", true); testPermissions.put("generate.sunset", false); testPermissions.put("generate", true); testPermissions.put("generate.thunderstorm.explosive", false); NodeTree oldTree = NodeTree.of(testPermissions); assertEquals(testPermissions, oldTree.asMap()); }
/** * Check if this subject is a child of the given parent in the subject's * current context, traversing inheritance. * * <p>This must return the same value as * {@link #isChildOf(Set, SubjectReference)} using * {@link #getActiveContexts()}.</p> * * @param parent The parent to check for inheritance * @return Whether this is a child of the given parent */ default boolean isChildOf(SubjectReference parent) { return isChildOf(getActiveContexts(), parent); }
/** * Return a new NodeTree instance with a single changed value. * * @param node The node path to change the value of * @param value The value to change, or UNDEFINED to remove * @return The new, modified node tree */ public NodeTree withValue(String node, Tristate value) { Iterable<String> parts = NODE_SPLITTER.split(node.toLowerCase()); Node newRoot = new Node(new HashMap<>(this.rootNode.children)); Node newPtr = newRoot; Node currentPtr = this.rootNode; newPtr.value = currentPtr == null ? Tristate.UNDEFINED : currentPtr.value; for (String part : parts) { Node oldChild = currentPtr == null ? null : currentPtr.children.get(part); Node newChild = new Node(oldChild != null ? new HashMap<>(oldChild.children) : new HashMap<>()); newPtr.children.put(part, newChild); currentPtr = oldChild; newPtr = newChild; } newPtr.value = value; return new NodeTree(newRoot); }
@Override public Collection<MessageReceiver> getMembers() { PermissionService service = Sponge.getGame().getServiceManager().provideUnchecked(PermissionService.class); return service.getLoadedCollections().values().stream() .flatMap(input -> input.getLoadedWithPermission(this.permission).entrySet().stream() .filter(Map.Entry::getValue) .map(entry -> entry.getKey().getCommandSource().orElse(null)) .filter(source -> source != null)) .collect(ImmutableSet.toImmutableSet()); }
@Override public Map<String, Boolean> getPermissions(Set<Context> contexts) { NodeTree perms = this.permissions.get(contexts); return perms == null ? Collections.emptyMap() : perms.asMap(); }
/** * Return a modified new node tree with the specified values set. * * @param values The values to set * @return The new node tree */ public NodeTree withAll(Map<String, Tristate> values) { NodeTree ret = this; for (Map.Entry<String, Tristate> ent : values.entrySet()) { ret = ret.withValue(ent.getKey(), ent.getValue()); } return ret; }
@Override public List<SubjectReference> getParents(Set<Context> contexts) { List<Map.Entry<String, String>> ret = this.parents.get(contexts); return ret == null ? Collections.emptyList() : toSubjectList(ret); }
private NodeTree(Tristate value) { this.rootNode = new Node(new HashMap<>()); this.rootNode.value = value; }
/** * Test whether the subject is permitted to perform an action corresponding * to the given permission string. * * <p>This must return the same boolean equivalent as * {@link #getPermissionValue(Set, String)}.</p> * * @param contexts The set of contexts that represents the subject's current * environment * @param permission The permission string * @return True if permission is granted */ default boolean hasPermission(Set<Context> contexts, String permission) { return getPermissionValue(contexts, permission).asBoolean(); }
private void populateMap(ImmutableMap.Builder<String, Boolean> values, String prefix, Node currentNode) { if (currentNode.value != Tristate.UNDEFINED) { values.put(prefix, currentNode.value.asBoolean()); } for (Map.Entry<String, Node> ent : currentNode.children.entrySet()) { populateMap(values, prefix + '.' + ent.getKey(), ent.getValue()); } }
List<SubjectReference> toSubjectList(List<Map.Entry<String, String>> parents) { ImmutableList.Builder<SubjectReference> ret = ImmutableList.builder(); for (Map.Entry<String, String> ent : parents) { ret.add(this.service.newSubjectReference(ent.getKey(), ent.getValue())); } return ret.build(); }
/** * Gets the calculated node tree representation of the permissions for this * subject data instance. If no data is present for the given context, * returns null. * * @param contexts The contexts to get a node tree for * @return The node tree */ public NodeTree getNodeTree(Set<Context> contexts) { NodeTree perms = this.permissions.get(contexts); return perms == null ? NodeTree.of(Collections.emptyMap()) : perms; }
@Override public Map<Set<Context>, Map<String, Boolean>> getAllPermissions() { ImmutableMap.Builder<Set<Context>, Map<String, Boolean>> ret = ImmutableMap.builder(); for (Map.Entry<Set<Context>, NodeTree> ent : this.permissions.entrySet()) { ret.put(ent.getKey(), ent.getValue().asMap()); } return ret.build(); }
@Override public Map<Set<Context>, List<SubjectReference>> getAllParents() { ImmutableMap.Builder<Set<Context>, List<SubjectReference>> ret = ImmutableMap.builder(); for (Map.Entry<Set<Context>, List<Map.Entry<String, String>>> ent : this.parents.entrySet()) { ret.put(ent.getKey(), toSubjectList(ent.getValue())); } return ret.build(); }