mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-29 12:37:40 +01:00
Partially implement PermissionService
This commit is contained in:
parent
de5fda6a18
commit
44d14001e1
@ -44,6 +44,7 @@ public class Patterns {
|
|||||||
public static final Pattern NON_USERNAME = Pattern.compile("[^A-Za-z0-9_]");
|
public static final Pattern NON_USERNAME = Pattern.compile("[^A-Za-z0-9_]");
|
||||||
public static final Pattern SHORTHAND_NODE = Pattern.compile("\\.\\([^.]+\\)");
|
public static final Pattern SHORTHAND_NODE = Pattern.compile("\\.\\([^.]+\\)");
|
||||||
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('§') + "[0-9A-FK-OR]");
|
public static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('§') + "[0-9A-FK-OR]");
|
||||||
|
public static final Pattern NODE_CONTEXTS = Pattern.compile("\\(.+\\).*");
|
||||||
|
|
||||||
public static Pattern compile(String regex) throws PatternSyntaxException {
|
public static Pattern compile(String regex) throws PatternSyntaxException {
|
||||||
if (!CACHE.containsKey(regex)) {
|
if (!CACHE.containsKey(regex)) {
|
||||||
|
@ -815,6 +815,7 @@ public abstract class PermissionHolder {
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Support the "Sponge way" of doing wildcards
|
||||||
private static Map<String, Boolean> applyWildcards(Map<String, Boolean> input, List<String> possibleNodes) {
|
private static Map<String, Boolean> applyWildcards(Map<String, Boolean> input, List<String> possibleNodes) {
|
||||||
SortedMap<Integer, Map<String, Boolean>> wildcards = new TreeMap<>(Collections.reverseOrder());
|
SortedMap<Integer, Map<String, Boolean>> wildcards = new TreeMap<>(Collections.reverseOrder());
|
||||||
for (Map.Entry<String, Boolean> e : input.entrySet()) {
|
for (Map.Entry<String, Boolean> e : input.entrySet()) {
|
||||||
|
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import lombok.*;
|
||||||
|
import me.lucko.luckperms.LPSpongePlugin;
|
||||||
|
import me.lucko.luckperms.service.collections.GroupCollection;
|
||||||
|
import me.lucko.luckperms.service.collections.UserCollection;
|
||||||
|
import me.lucko.luckperms.service.simple.SimpleCollection;
|
||||||
|
import org.spongepowered.api.plugin.PluginContainer;
|
||||||
|
import org.spongepowered.api.service.context.ContextCalculator;
|
||||||
|
import org.spongepowered.api.service.permission.*;
|
||||||
|
import org.spongepowered.api.text.Text;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class LuckPermsService implements PermissionService {
|
||||||
|
public static final String SERVER_CONTEXT = "server";
|
||||||
|
|
||||||
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final UserCollection userSubjects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final GroupCollection groupSubjects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Set<PermissionDescription> descriptionSet;
|
||||||
|
|
||||||
|
private final Map<String, SubjectCollection> subjects;
|
||||||
|
private final Set<ContextCalculator<Subject>> contextCalculators;
|
||||||
|
|
||||||
|
public LuckPermsService(LPSpongePlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
userSubjects = new UserCollection(this, plugin.getUserManager());
|
||||||
|
groupSubjects = new GroupCollection(this, plugin.getGroupManager());
|
||||||
|
|
||||||
|
subjects = new ConcurrentHashMap<>();
|
||||||
|
subjects.put(PermissionService.SUBJECTS_USER, userSubjects);
|
||||||
|
subjects.put(PermissionService.SUBJECTS_GROUP, groupSubjects);
|
||||||
|
|
||||||
|
descriptionSet = ConcurrentHashMap.newKeySet();
|
||||||
|
contextCalculators = ConcurrentHashMap.newKeySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getDefaultData() {
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectCollection getSubjects(String s) {
|
||||||
|
if (!subjects.containsKey(s)) {
|
||||||
|
subjects.put(s, new SimpleCollection(this, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subjects.get(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, SubjectCollection> getKnownSubjects() {
|
||||||
|
return subjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<PermissionDescription.Builder> newDescriptionBuilder(@NonNull Object o) {
|
||||||
|
Optional<PluginContainer> container = plugin.getGame().getPluginManager().fromInstance(o);
|
||||||
|
if (!container.isPresent()) {
|
||||||
|
throw new IllegalArgumentException("Couldn't find a plugin container for " + o.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.of(new DescriptionBuilder(this, container.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<PermissionDescription> getDescription(String s) {
|
||||||
|
for (PermissionDescription d : descriptionSet) {
|
||||||
|
if (d.getId().equals(s)) {
|
||||||
|
return Optional.of(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PermissionDescription> getDescriptions() {
|
||||||
|
return ImmutableSet.copyOf(descriptionSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerContextCalculator(ContextCalculator<Subject> contextCalculator) {
|
||||||
|
contextCalculators.add(contextCalculator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getPossiblePermissions() {
|
||||||
|
return getDescriptions().stream().map(PermissionDescription::getId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString
|
||||||
|
public static class DescriptionBuilder implements PermissionDescription.Builder {
|
||||||
|
private final LuckPermsService service;
|
||||||
|
private final PluginContainer container;
|
||||||
|
|
||||||
|
private String id = null;
|
||||||
|
private Text description = null;
|
||||||
|
private final Map<String, Tristate> roles = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionDescription.Builder id(@NonNull String s) {
|
||||||
|
id = s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionDescription.Builder description(@NonNull Text text) {
|
||||||
|
description = text;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionDescription.Builder assign(@NonNull String s, boolean b) {
|
||||||
|
roles.put(s, Tristate.fromBoolean(b));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PermissionDescription register() throws IllegalStateException {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalStateException("id cannot be null");
|
||||||
|
}
|
||||||
|
if (description == null) {
|
||||||
|
throw new IllegalStateException("description cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
Description d = new Description(service, container, id, description);
|
||||||
|
service.getDescriptionSet().add(d);
|
||||||
|
|
||||||
|
// Set role-templates
|
||||||
|
SubjectCollection subjects = service.getSubjects(PermissionService.SUBJECTS_ROLE_TEMPLATE);
|
||||||
|
for (Map.Entry<String, Tristate> assignment : roles.entrySet()) {
|
||||||
|
Subject subject = subjects.get(assignment.getKey());
|
||||||
|
subject.getTransientSubjectData().setPermission(SubjectData.GLOBAL_CONTEXT, id, assignment.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString
|
||||||
|
public static class Description implements PermissionDescription {
|
||||||
|
private final LuckPermsService service;
|
||||||
|
private final PluginContainer owner;
|
||||||
|
private final String id;
|
||||||
|
private final Text description;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAssignedSubjects(String id) {
|
||||||
|
SubjectCollection subjects = service.getSubjects(id);
|
||||||
|
return subjects.getAllWithPermission(this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service.collections;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.groups.GroupManager;
|
||||||
|
import me.lucko.luckperms.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.service.simple.SimpleSubject;
|
||||||
|
import me.lucko.luckperms.service.wrapping.LuckPermsSubject;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectData;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class GroupCollection implements SubjectCollection {
|
||||||
|
private final LuckPermsService service;
|
||||||
|
private final GroupManager manager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return PermissionService.SUBJECTS_GROUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject get(@NonNull String id) {
|
||||||
|
if (manager.isLoaded(id)) {
|
||||||
|
return new LuckPermsSubject(manager.get(id), service);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleSubject(id, service, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasRegistered(@NonNull String id) {
|
||||||
|
return manager.isLoaded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Subject> getAllSubjects() {
|
||||||
|
return manager.getAll().values().stream()
|
||||||
|
.map(u -> new LuckPermsSubject(u, service))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull String node) {
|
||||||
|
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
return manager.getAll().values().stream()
|
||||||
|
.map(u -> new LuckPermsSubject(u, service))
|
||||||
|
.filter(sub -> sub.hasPermission(contexts, node))
|
||||||
|
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service.collections;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.service.simple.SimpleSubject;
|
||||||
|
import me.lucko.luckperms.service.wrapping.LuckPermsSubject;
|
||||||
|
import me.lucko.luckperms.users.User;
|
||||||
|
import me.lucko.luckperms.users.UserManager;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectData;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserCollection implements SubjectCollection {
|
||||||
|
private final LuckPermsService service;
|
||||||
|
private final UserManager manager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return PermissionService.SUBJECTS_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject get(@NonNull String id) {
|
||||||
|
try {
|
||||||
|
UUID u = UUID.fromString(id);
|
||||||
|
if (manager.isLoaded(u)) {
|
||||||
|
return new LuckPermsSubject(manager.get(u), service);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
User user = manager.get(id);
|
||||||
|
if (user != null) {
|
||||||
|
return new LuckPermsSubject(user, service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wtf am I meant to do here? What if no user is loaded? Load it? Create it?
|
||||||
|
return new SimpleSubject(id, service, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasRegistered(@NonNull String id) {
|
||||||
|
try {
|
||||||
|
UUID u = UUID.fromString(id);
|
||||||
|
return manager.isLoaded(u);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
User user = manager.get(id);
|
||||||
|
return user != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Subject> getAllSubjects() {
|
||||||
|
return manager.getAll().values().stream()
|
||||||
|
.map(u -> new LuckPermsSubject(u, service))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
||||||
|
return getAllWithPermission(SubjectData.GLOBAL_CONTEXT, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
return manager.getAll().values().stream()
|
||||||
|
.map(u -> new LuckPermsSubject(u, service))
|
||||||
|
.filter(sub -> sub.hasPermission(contexts, node))
|
||||||
|
.map(sub -> new AbstractMap.SimpleEntry<Subject, Boolean>(sub, sub.getPermissionValue(contexts, node).asBoolean()))
|
||||||
|
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service.simple;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.PermissionService;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SimpleCollection implements SubjectCollection {
|
||||||
|
private final PermissionService service;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String identifier;
|
||||||
|
|
||||||
|
private final Map<String, Subject> subjects = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Subject get(@NonNull String id) {
|
||||||
|
if (!subjects.containsKey(id)) {
|
||||||
|
subjects.put(id, new SimpleSubject(id, service, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
return subjects.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasRegistered(@NonNull String id) {
|
||||||
|
return subjects.containsKey(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Subject> getAllSubjects() {
|
||||||
|
return subjects.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull String id) {
|
||||||
|
return getAllWithPermission(Collections.emptySet(), id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
Map<Subject, Boolean> m = new HashMap<>();
|
||||||
|
for (Subject subject : subjects.values()) {
|
||||||
|
Tristate ts = subject.getPermissionValue(contexts, node);
|
||||||
|
if (ts != Tristate.UNDEFINED) {
|
||||||
|
m.put(subject, ts.asBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service.simple;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.*;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Super simple Subject implementation.
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class SimpleSubject implements Subject {
|
||||||
|
private final String identifier;
|
||||||
|
|
||||||
|
private final PermissionService service;
|
||||||
|
private final SubjectCollection containingCollection;
|
||||||
|
private final SubjectData subjectData;
|
||||||
|
|
||||||
|
private final Map<Set<Context>, Map<String, Tristate>> perms = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Set<Context>, Set<Subject>> parents = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public SimpleSubject(String identifier, PermissionService service, SubjectCollection containingCollection) {
|
||||||
|
this.identifier = identifier;
|
||||||
|
this.service = service;
|
||||||
|
this.containingCollection = containingCollection;
|
||||||
|
this.subjectData = new MemorySubjectData(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<CommandSource> getCommandSource() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getTransientSubjectData() {
|
||||||
|
return getSubjectData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
return getPermissionValue(contexts, node).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull String permission) {
|
||||||
|
return getPermissionValue(getActiveContexts(), permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
if (!perms.containsKey(contexts)) {
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Tristate> context = perms.get(contexts);
|
||||||
|
if (context.containsKey(node)) {
|
||||||
|
return context.get(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Subject parent : getParents(contexts)) {
|
||||||
|
Tristate ts = parent.getPermissionValue(contexts, node);
|
||||||
|
if (ts != Tristate.UNDEFINED) {
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Subject parent) {
|
||||||
|
return isChildOf(getActiveContexts(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject subject) {
|
||||||
|
return parents.containsKey(contexts) && parents.get(contexts).contains(subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents() {
|
||||||
|
return getParents(getActiveContexts());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
||||||
|
if (!parents.containsKey(contexts)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ArrayList<>(parents.get(contexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Context> getActiveContexts() {
|
||||||
|
return SubjectData.GLOBAL_CONTEXT;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package me.lucko.luckperms.service.wrapping;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import me.lucko.luckperms.constants.Patterns;
|
||||||
|
import me.lucko.luckperms.core.PermissionHolder;
|
||||||
|
import me.lucko.luckperms.groups.Group;
|
||||||
|
import me.lucko.luckperms.service.LuckPermsService;
|
||||||
|
import me.lucko.luckperms.users.User;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
|
import org.spongepowered.api.command.CommandSource;
|
||||||
|
import org.spongepowered.api.entity.living.player.Player;
|
||||||
|
import org.spongepowered.api.service.context.Context;
|
||||||
|
import org.spongepowered.api.service.permission.Subject;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectCollection;
|
||||||
|
import org.spongepowered.api.service.permission.SubjectData;
|
||||||
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class LuckPermsSubject implements Subject {
|
||||||
|
private final PermissionHolder holder;
|
||||||
|
private final LuckPermsService service;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return holder.getObjectName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<CommandSource> getCommandSource() {
|
||||||
|
if (holder instanceof User) {
|
||||||
|
final UUID uuid = ((User) holder).getUuid();
|
||||||
|
|
||||||
|
Optional<Player> p = Sponge.getServer().getPlayer(uuid);
|
||||||
|
if (p.isPresent()) {
|
||||||
|
return Optional.of(p.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectCollection getContainingCollection() {
|
||||||
|
if (holder instanceof Group) {
|
||||||
|
return service.getGroupSubjects();
|
||||||
|
} else {
|
||||||
|
return service.getUserSubjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getSubjectData() {
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SubjectData getTransientSubjectData() {
|
||||||
|
return null; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
return getPermissionValue(contexts, node).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(String permission) {
|
||||||
|
return getPermissionValue(getActiveContexts(), permission).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Boolean> applyContexts(@NonNull Set<Context> set) {
|
||||||
|
final Map<String, Boolean> map = new HashMap<>();
|
||||||
|
|
||||||
|
String world = null;
|
||||||
|
String server = null;
|
||||||
|
|
||||||
|
Map<String, String> contexts = new HashMap<>();
|
||||||
|
|
||||||
|
for (Context context : set) {
|
||||||
|
if (context.getType().equals(Context.WORLD_KEY)) {
|
||||||
|
world = context.getName();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.getType().equals(LuckPermsService.SERVER_CONTEXT)) {
|
||||||
|
server = context.getName();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
contexts.put(context.getType(), context.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Boolean> local = holder.getLocalPermissions(server, world, null, service.getPossiblePermissions());
|
||||||
|
perms:
|
||||||
|
for (Map.Entry<String, Boolean> e : local.entrySet()) {
|
||||||
|
if (!contexts.isEmpty()) {
|
||||||
|
if (!Patterns.NODE_CONTEXTS.matcher(e.getKey()).matches()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = e.getKey().substring(1).split("\\)", 2);
|
||||||
|
// 0 = context, 1 = node
|
||||||
|
|
||||||
|
// Parse the context values from this node
|
||||||
|
Map<String, String> contextValues = new HashMap<>();
|
||||||
|
for (String s : parts[0].split("\\,")) {
|
||||||
|
if (!s.contains("=")) {
|
||||||
|
// Not valid
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// contextKey=value
|
||||||
|
String[] con = s.split("\\=", 2);
|
||||||
|
contextValues.put(con[0], con[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that all of the requested contexts are met
|
||||||
|
for (Map.Entry<String, String> req : contexts.entrySet()) {
|
||||||
|
if (!contextValues.containsKey(e.getKey())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!contextValues.get(req.getKey()).equalsIgnoreCase(req.getValue())) {
|
||||||
|
// Not valid within the current contexts
|
||||||
|
continue perms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passed all da tests.
|
||||||
|
map.put(parts[1], e.getValue());
|
||||||
|
} else {
|
||||||
|
map.put(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tristate getPermissionValue(@NonNull Set<Context> contexts, @NonNull String node) {
|
||||||
|
final Map<String, Boolean> nodes = applyContexts(contexts);
|
||||||
|
|
||||||
|
if (nodes.containsKey(node)) {
|
||||||
|
return Tristate.fromBoolean(nodes.get(node));
|
||||||
|
} else {
|
||||||
|
return Tristate.UNDEFINED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Subject parent) {
|
||||||
|
return isChildOf(getActiveContexts(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildOf(@NonNull Set<Context> contexts, @NonNull Subject parent) {
|
||||||
|
return parent instanceof PermissionHolder && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents() {
|
||||||
|
return getParents(getActiveContexts());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Subject> getParents(@NonNull Set<Context> contexts) {
|
||||||
|
final Set<String> parents = new HashSet<>();
|
||||||
|
final Map<String, Boolean> nodes = applyContexts(contexts);
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||||
|
if (!e.getValue()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Patterns.GROUP_MATCH.matcher(e.getKey()).matches()) {
|
||||||
|
final String groupName = e.getKey().substring("group.".length());
|
||||||
|
parents.add(groupName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parents.stream().map(s -> service.getGroupSubjects().get(s)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Context> getActiveContexts() {
|
||||||
|
return SubjectData.GLOBAL_CONTEXT;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user