mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-28 03:57:36 +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 SHORTHAND_NODE = Pattern.compile("\\.\\([^.]+\\)");
|
||||
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 {
|
||||
if (!CACHE.containsKey(regex)) {
|
||||
|
@ -815,6 +815,7 @@ public abstract class PermissionHolder {
|
||||
return input;
|
||||
}
|
||||
|
||||
// TODO Support the "Sponge way" of doing wildcards
|
||||
private static Map<String, Boolean> applyWildcards(Map<String, Boolean> input, List<String> possibleNodes) {
|
||||
SortedMap<Integer, Map<String, Boolean>> wildcards = new TreeMap<>(Collections.reverseOrder());
|
||||
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