Add support for PermissionsEx v2 (#46)

Support is still fairly rudimentary, but this is a first step to be expanded on
as PEX becomes more stable
This commit is contained in:
zml 2019-08-23 19:26:52 -07:00 committed by bloodmc
parent 8c23f33e82
commit c7bed01866
8 changed files with 641 additions and 27 deletions

View File

@ -40,6 +40,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.logging.Logger;
import com.griefdefender.provider.permissionsex.PermissionsExProvider;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.LocaleUtils;
@ -389,7 +390,9 @@ public class GriefDefenderPlugin {
this.permissionProvider = new LuckPermsProvider();
} else {
permissionPlugin = Bukkit.getPluginManager().getPlugin("PermissionsEx");
// TODO
if (permissionPlugin != null) {
this.permissionProvider = PermissionsExProvider.initBukkit(permissionPlugin);
}
}
instance = this;
timingManager = TimingManager.of(GDBootstrap.getInstance());

View File

@ -289,26 +289,6 @@ public class LuckPermsProvider implements PermissionProvider {
contexts.addAll(this.getGDContexts(activeContexts));
}
public boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().equals("gd_claim_default")) {
return true;
}
}
return false;
}
public boolean containsOverrideContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().equals("gd_claim_override")) {
return true;
}
}
return false;
}
public void clearPermissions(GDClaim claim) {
Map<Set<Context>, Map<String, Boolean>> permissionMap = this.getAllPermissions(claim, GriefDefenderPlugin.DEFAULT_HOLDER);
for (Entry<Set<Context>, Map<String, Boolean>> mapEntry : permissionMap.entrySet()) {

View File

@ -55,10 +55,6 @@ public interface PermissionProvider {
void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissionHolder, GDPlayerData playerData, Claim claim);
boolean containsDefaultContext(Set<Context> contexts);
boolean containsOverrideContext(Set<Context> contexts);
void clearPermissions(GDClaim claim);
void clearPermissions(OfflinePlayer player, Context context);

View File

@ -0,0 +1,57 @@
package com.griefdefender.provider.permissionsex;
import ca.stellardrift.permissionsex.context.ContextDefinition;
import ca.stellardrift.permissionsex.context.ContextValue;
import ca.stellardrift.permissionsex.subject.CalculatedSubject;
import com.google.common.collect.ImmutableSet;
import com.griefdefender.api.CatalogType;
import com.griefdefender.api.registry.CatalogRegistryModule;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.function.BiConsumer;
public class CatalogTypeContextDefinition<T extends CatalogType> extends ContextDefinition<T> {
private final BiConsumer<CalculatedSubject, Function1<? super T, Unit>> currentValueAccumulator;
private final CatalogRegistryModule<T> registry;
public CatalogTypeContextDefinition(String key, CatalogRegistryModule<T> registry) {
this(key, registry, null);
}
public CatalogTypeContextDefinition(String key, CatalogRegistryModule<T> registry, BiConsumer<CalculatedSubject, Function1<? super T, Unit>> currentValueAccumulator) {
super(key);
this.registry = registry;
this.currentValueAccumulator = currentValueAccumulator == null ? (x, y) -> {} : currentValueAccumulator;
}
@Override
public void accumulateCurrentValues(@NotNull CalculatedSubject calculatedSubject, @NotNull Function1<? super T, Unit> function1) {
currentValueAccumulator.accept(calculatedSubject, function1);
}
@Override
public T deserialize(@NotNull String s) {
return registry.getById(s).orElseThrow(() -> new IllegalArgumentException("Provided value '" + s + "' was not a valid value in catalog type " + registry.getClass().getSimpleName()));
}
@Override
public boolean matches(@NotNull ContextValue<T> contextValue, T t) {
return contextValue.getParsedValue(this).equals(t);
}
@NotNull
@Override
public String serialize(T t) {
return t.getId();
}
@NotNull
@Override
public Set<T> suggestValues(@NotNull CalculatedSubject subject) {
return ImmutableSet.copyOf(registry.getAll());
}
}

View File

@ -0,0 +1,77 @@
package com.griefdefender.provider.permissionsex;
import ca.stellardrift.permissionsex.context.ContextDefinition;
import ca.stellardrift.permissionsex.context.ContextValue;
import ca.stellardrift.permissionsex.subject.CalculatedSubject;
import ca.stellardrift.permissionsex.util.Util;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.claim.GDClaim;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
class ClaimContextDefinition extends ContextDefinition<UUID> {
ClaimContextDefinition() {
super(ContextKeys.CLAIM);
}
@Override
public void accumulateCurrentValues(@NotNull CalculatedSubject calculatedSubject, @NotNull Function1<? super UUID, Unit> submitValue) {
Claim activeClaim = PermissionsExProvider.getClaimForSubject(calculatedSubject);
if (activeClaim != null) {
Claim parentClaim = activeClaim.getParent().orElse(null);
if (parentClaim != null && activeClaim.getData().doesInheritParent()) {
submitValue.invoke(parentClaim.getUniqueId());
} else {
submitValue.invoke(activeClaim.getUniqueId());
}
}
}
@Override
public UUID deserialize(@NotNull String s) {
try {
return UUID.fromString(s);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Unable to deserialize context: " + s + " is not a valid UUID");
}
}
@Override
public boolean matches(@NotNull ContextValue<UUID> contextValue, UUID claim) {
return contextValue.getParsedValue(this).equals(claim);
}
@Override
@NotNull
public Set<UUID> suggestValues(@NotNull CalculatedSubject subj) {
Player ply = Util.castOptional(subj.getAssociatedObject(), Player.class).orElse(null);
if (ply == null) {
return ImmutableSet.of();
}
return GriefDefender.getCore().getClaimManager(ply.getWorld().getUID()).getWorldClaims().stream()
.map(Claim::getUniqueId)
.collect(Collectors.toSet());
}
@NotNull
@Override
public String serialize(UUID claim) {
return claim.toString();
}
}

View File

@ -0,0 +1,59 @@
package com.griefdefender.provider.permissionsex;
import ca.stellardrift.permissionsex.context.ContextDefinition;
import ca.stellardrift.permissionsex.context.ContextValue;
import ca.stellardrift.permissionsex.subject.CalculatedSubject;
import com.griefdefender.api.CatalogType;
import com.griefdefender.api.registry.CatalogRegistryModule;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class MultiCatalogTypeContextDefinition extends ContextDefinition<CatalogType> {
private final CatalogRegistryModule<?>[] registries;
public MultiCatalogTypeContextDefinition(String key, CatalogRegistryModule<?>... registries) {
super(key);
this.registries = registries;
}
@Override
public void accumulateCurrentValues(@NotNull CalculatedSubject calculatedSubject, @NotNull Function1<? super CatalogType, Unit> function1) {
}
@Override
public CatalogType deserialize(@NotNull String s) {
for (CatalogRegistryModule<?> reg : registries) {
Optional<? extends CatalogType> possibility = reg.getById(s);
if (possibility.isPresent()) {
return possibility.get();
}
}
throw new IllegalArgumentException("Provided value '" + s + "' was not a valid value in any of catalog types");
}
@Override
public boolean matches(@NotNull ContextValue<CatalogType> contextValue, CatalogType t) {
return contextValue.getParsedValue(this).equals(t);
}
@NotNull
@Override
public String serialize(CatalogType t) {
return t.getId();
}
@NotNull
@Override
public Set<CatalogType> suggestValues(@NotNull CalculatedSubject subject) {
return Arrays.stream(registries)
.flatMap(reg -> reg.getAll().stream())
.collect(Collectors.toSet());
}
}

View File

@ -0,0 +1,430 @@
package com.griefdefender.provider.permissionsex;
import ca.stellardrift.permissionsex.bukkit.PermissionsExPlugin;
import ca.stellardrift.permissionsex.context.ContextDefinition;
import ca.stellardrift.permissionsex.context.ContextValue;
import ca.stellardrift.permissionsex.data.Change;
import ca.stellardrift.permissionsex.data.ImmutableSubjectData;
import ca.stellardrift.permissionsex.subject.SubjectType;
import ca.stellardrift.permissionsex.util.Util;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.CatalogType;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.internal.registry.BlockTypeRegistryModule;
import com.griefdefender.internal.registry.EntityTypeRegistryModule;
import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser;
import ca.stellardrift.permissionsex.PermissionsEx;
import ca.stellardrift.permissionsex.subject.CalculatedSubject;
import com.griefdefender.provider.PermissionProvider;
import com.griefdefender.registry.ClaimTypeRegistryModule;
import com.griefdefender.registry.FlagRegistryModule;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
public class PermissionsExProvider implements PermissionProvider {
private static final ContextDefinition<UUID> CTX_CLAIM = new ClaimContextDefinition();
private static final ContextDefinition<ClaimType> CTX_CLAIM_DEFAULT = new CatalogTypeContextDefinition<>(ContextKeys.CLAIM_DEFAULT, ClaimTypeRegistryModule.getInstance(), claimAttributeValue(GDClaim::getType));
private static final ContextDefinition<ClaimType> CTX_CLAIM_OVERRIDE = new CatalogTypeContextDefinition<>(ContextKeys.CLAIM_OVERRIDE, ClaimTypeRegistryModule.getInstance());
private static final ContextDefinition<Flag> CTX_FLAG = new CatalogTypeContextDefinition<>(ContextKeys.FLAG, FlagRegistryModule.getInstance());
private static final ContextDefinition<CatalogType> CTX_SOURCE = new MultiCatalogTypeContextDefinition(ContextKeys.SOURCE, BlockTypeRegistryModule.getInstance(), ItemTypeRegistryModule.getInstance(), EntityTypeRegistryModule.getInstance());
private static final ContextDefinition<CatalogType> CTX_STATE = new MultiCatalogTypeContextDefinition(ContextKeys.STATE);
private static final ContextDefinition<CatalogType> CTX_TARGET = new MultiCatalogTypeContextDefinition(ContextKeys.TARGET);
private final PermissionsEx pex;
public PermissionsExProvider(PermissionsEx engine) {
this.pex = engine;
engine.registerContextDefinition(CTX_CLAIM);
engine.registerContextDefinition(CTX_CLAIM_DEFAULT);
engine.registerContextDefinition(CTX_CLAIM_OVERRIDE);
engine.registerContextDefinition(CTX_FLAG);
engine.registerContextDefinition(CTX_SOURCE);
engine.registerContextDefinition(CTX_STATE);
engine.registerContextDefinition(CTX_TARGET);
}
public static PermissionsExProvider initBukkit(Plugin pexPlugin) {
if (pexPlugin instanceof PermissionsExPlugin) {
return new PermissionsExProvider(((PermissionsExPlugin) pexPlugin).getManager());
}
throw new RuntimeException("Provided plugin " + pexPlugin + " was not a proper instance of PermissionsExPlugin");
}
private static <T> BiConsumer<CalculatedSubject, Function1<? super T, Unit>> claimAttributeValue(Function<GDClaim, T> claimFunc) {
return (subj, collector) -> {
GDClaim claim = getClaimForSubject(subj);
if (claim != null) {
T attr = claimFunc.apply(claim);
if (attr != null) {
collector.invoke(attr);
}
}
};
}
/**
* Get the current applicable claim for a given subject for permissions purposes. This takes into account a claim being ignored as well
*
* @param subj The subject to get the active claim for
* @return A claim if applicable, otherwise null
*/
static GDClaim getClaimForSubject(CalculatedSubject subj) {
Player ply = Util.castOptional(subj.getAssociatedObject(), Player.class).orElse(null);
if (ply == null) {// not an online player
return null;
}
GDPlayerData plyData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(ply.getWorld(), ply.getUniqueId());
if (plyData != null && plyData.ignoreActiveContexts) {
plyData.ignoreActiveContexts = false;
return null;
}
GDClaim ret = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(plyData, ply.getLocation());
if (plyData != null && !plyData.canIgnoreClaim(ret)) {
return null;
}
GDClaim parentClaim = ret.parent;
if (ret.getData().doesInheritParent() && parentClaim != null) {
return parentClaim;
} else {
return ret;
}
}
// - Data conversion
private ContextValue<?> contextGDToPEX(Context gdCtx) {
return new ContextValue<>(gdCtx.getKey(), gdCtx.getValue());
}
private Context contextPEXToGD(ContextValue<?> pexCtx) {
return new Context(pexCtx.getKey(), pexCtx.getRawValue());
}
private Set<ContextValue<?>> contextsGDToPEX(Set<Context> gdCtxs) {
return gdCtxs.stream()
.map(this::contextGDToPEX)
.collect(Collectors.toSet());
}
private Set<Context> contextsPEXToGD(Set<ContextValue<?>> ctxs) {
return ctxs.stream()
.map(this::contextPEXToGD)
.collect(Collectors.toSet());
}
private CalculatedSubject holderToPEXSubject(GDPermissionHolder holder) {
return pex.getSubjects(holder instanceof GDPermissionUser ? PermissionsEx.SUBJECTS_USER : PermissionsEx.SUBJECTS_GROUP).get(holder.getIdentifier()).join();
}
private <ValueType> Map<Set<Context>, ValueType> tKeys(Map<Set<ContextValue<?>>, ValueType> pexMap) {
return tKeys(pexMap, Function.identity());
}
private <ValueType, InputValueType> Map<Set<Context>, ValueType> tKeys(Map<Set<ContextValue<?>>, InputValueType> pexMap, Function<InputValueType, ValueType> valueXform) {
ImmutableMap.Builder<Set<Context>, ValueType> ret = ImmutableMap.builder();
pexMap.forEach((key, val) -> ret.put(contextsPEXToGD(key), valueXform.apply(val)));
return ret.build();
}
private Component textForError(Throwable t) { // TODO: is this already done somewhere else in GD?
TextComponent.Builder build = TextComponent.builder(t.getMessage(), TextColor.RED);
TextComponent.Builder stackTrace = TextComponent.builder();
for (StackTraceElement el : t.getStackTrace()) {
stackTrace.append(el.toString()).append("\n");
}
build.hoverEvent(HoverEvent.showText(stackTrace.build()));
return build.build();
}
private CompletableFuture<PermissionResult> convertResult(CompletableFuture<Change<ImmutableSubjectData>> pexResult) {
return pexResult.handle((res, err) -> {
if (err != null) {
return new GDPermissionResult(ResultTypes.FAILURE, textForError(err));
} else {
return new GDPermissionResult(ResultTypes.SUCCESS);
}
});
}
private Tristate tristateFromInt(int value) {
if (value > 0) {
return Tristate.TRUE;
} else if (value < 0) {
return Tristate.FALSE;
}
return Tristate.UNDEFINED;
}
private int intFromTristate(Tristate value) {
switch (value) {
case TRUE: return 1;
case FALSE: return -1;
case UNDEFINED: return 0;
default: throw new IllegalArgumentException("unknown tristate value " + value);
}
}
private int pValFromBool(@Nullable Boolean value) {
if (value == null) {
return 0;
}
return value ? 1 : -1;
}
private boolean pValIntegerToBool(@Nullable Integer value) {
return value != null && value > 0;
}
// - Implement API
@Override
public boolean hasGroupSubject(String identifier) {
return pex.getSubjects(PermissionsEx.SUBJECTS_GROUP).isRegistered(identifier).join();
}
@Override
public UUID lookupUserUniqueId(String name) {
return Bukkit.getOfflinePlayer(name).getUniqueId(); // TODO: this is not a thing pex does, should be a platform thing
}
@Override
public List<String> getAllLoadedPlayerNames() {
return getAllLoadedSubjectNames(PermissionsEx.SUBJECTS_USER);
}
@Override
public List<String> getAllLoadedGroupNames() {
return getAllLoadedSubjectNames(PermissionsEx.SUBJECTS_GROUP);
}
private List<String> getAllLoadedSubjectNames(String subjectType) {
return pex.getSubjects(subjectType).getActiveSubjects().stream()
.map(subj -> subj.getIdentifier().getValue())
.collect(Collectors.toList());
}
@Override
public void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissionHolder) {
addActiveContexts(contexts, permissionHolder, null, null);
}
@Override
public void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissionHolder, GDPlayerData playerData, Claim claim) {
contexts.addAll(contextsPEXToGD(holderToPEXSubject(permissionHolder).getActiveContexts()));
// ??? TODO anything else
}
private ImmutableSubjectData clearContext(ImmutableSubjectData in, ContextValue<?> ctx) {
for (Set<ContextValue<?>> ctxSet : in.getActiveContexts()) {
if (ctxSet.contains(ctx)) {
in = in.clearPermissions(ctxSet).clearOptions(ctxSet).clearParents(ctxSet);
}
}
return in;
}
@Override
public void clearPermissions(GDClaim claim) {
ContextValue<UUID> claimContext = CTX_CLAIM.createValue(claim.getUniqueId());
pex.performBulkOperation(() -> {
List<CompletableFuture<?>> dataAwait = new LinkedList<>();
pex.getRegisteredSubjectTypes().forEach(type -> {
SubjectType subjects = pex.getSubjects(type);
subjects.getAllIdentifiers().forEach(ident -> {
dataAwait.add(subjects.persistentData().getReference(ident).thenCombine(subjects.transientData().getReference(ident), (persist, trans) -> {
return CompletableFuture.allOf(persist.update(data -> clearContext(data, claimContext)),
trans.update(data -> clearContext(data, claimContext)));
}));
});
});
return CompletableFuture.allOf(dataAwait.toArray(new CompletableFuture[0]));
}).join();
}
@Override
public void clearPermissions(OfflinePlayer player, Context context) {
pex.getSubjects(PermissionsEx.SUBJECTS_USER).get(player.getUniqueId().toString()).thenAccept(subj -> {
final Set<ContextValue<?>> contexts = ImmutableSet.of(contextGDToPEX(context));
subj.data().update(data -> data.clearPermissions(contexts));
subj.transientData().update(data -> data.clearPermissions(contexts));
});
}
@Override
public void clearPermissions(GDPermissionHolder holder, Context context) {
holderToPEXSubject(holder).data().update(data -> data.clearPermissions(ImmutableSet.of(contextGDToPEX(context))));
}
@Override
public void clearPermissions(GDPermissionHolder holder, Set<Context> contexts) {
holderToPEXSubject(holder).data().update(data -> data.clearPermissions(contextsGDToPEX(contexts)));
}
@Override
public boolean holderHasPermission(GDPermissionHolder holder, String permission) {
return holderToPEXSubject(holder).hasPermission(permission);
}
@Override
public Map<String, Boolean> getPermissions(GDPermissionHolder holder, Set<Context> contexts) {
return Maps.transformValues(holderToPEXSubject(holder).getPermissions(contextsGDToPEX(contexts)).asMap(), this::pValIntegerToBool);
}
@Override
public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts) {
return holderToPEXSubject(holder).getOptions(contextsGDToPEX(contexts));
}
@Override
public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDClaim claim, GDPermissionHolder holder) {
return tKeys(holderToPEXSubject(holder).data().get().getAllPermissions(), map -> Maps.transformValues(map, this::pValIntegerToBool));
}
@Override
public Map<Set<Context>, Map<String, Boolean>> getTransientPermissions(GDClaim claim, GDPermissionHolder holder) {
return tKeys(holderToPEXSubject(holder).transientData().get().getAllPermissions(), map -> Maps.transformValues(map, this::pValIntegerToBool));
}
@Override
public Map<Set<Context>, Map<String, String>> getPermanentOptions(GDPermissionHolder holder) {
return tKeys(holderToPEXSubject(holder).data().get().getAllOptions());
}
@Override
public Map<Set<Context>, Map<String, String>> getTransientOptions(GDPermissionHolder holder) {
return tKeys(holderToPEXSubject(holder).transientData().get().getAllOptions());
}
@Override
public Map<String, String> getPermanentOptions(GDClaim claim, GDPermissionHolder holder, Set<Context> contexts) {
return holderToPEXSubject(holder).data().get().getOptions(contextsGDToPEX(contexts));
}
@Override
public Map<String, String> getTransientOptions(GDClaim claim, GDPermissionHolder holder, Set<Context> contexts) {
return holderToPEXSubject(holder).transientData().get().getOptions(contextsGDToPEX(contexts));
}
@Override
public Map<Set<Context>, Map<String, Boolean>> getAllPermissions(GDClaim claim, GDPermissionHolder holder) {
final Map<Set<Context>, Map<String, Boolean>> allPermissions = new HashMap<>();
holderToPEXSubject(holder).data().get().getAllPermissions().forEach((contexts, perms) ->
allPermissions.put(contextsPEXToGD(contexts), new HashMap<>(Maps.transformValues(perms, this::pValIntegerToBool))));
holderToPEXSubject(holder).transientData().get().getAllPermissions().forEach((contexts, perms) -> {
Set<Context> gdContexts = contextsPEXToGD(contexts);
if (allPermissions.containsKey(gdContexts)) {
Map<String, Boolean> ctxPerms = allPermissions.get(gdContexts);
perms.forEach((k, v) -> ctxPerms.put(k, v > 0));
} else {
allPermissions.put(gdContexts, Maps.transformValues(perms, this::pValIntegerToBool));
}
});
return Collections.unmodifiableMap(allPermissions);
}
@Override
public Tristate getPermissionValue(GDPermissionHolder holder, String permission) {
return tristateFromInt(holderToPEXSubject(holder).getPermission(permission));
}
@Override
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts) {
return getPermissionValue(claim, holder, permission, contexts, true);
}
/*
* The checkTransient value is ignored here -- we shouldn't need to use it since PEX already prioritizes
* transient permissions appropriately based on the subject type
*/
@Override
public Tristate getPermissionValue(GDClaim claim, GDPermissionHolder holder, String permission, Set<Context> contexts, boolean checkTransient) {
return tristateFromInt(holderToPEXSubject(holder).getPermission(contextsGDToPEX(contexts), permission));
}
@Override
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) {
return tristateFromInt(holderToPEXSubject(holder).getPermission(contextsGDToPEX(contexts), permission));
}
@Override
public String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts) {
return holderToPEXSubject(holder).getOption(contextsGDToPEX(contexts), option.getPermission()).orElse(null);
}
@Override
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join();
}
@Override
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), flag.getPermission(), intFromTristate(value)))).join();
}
@Override
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))
.thenApply(chg -> !chg.getNew().equals(chg.getOld())).join();
}
@Override
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value));
}
@Override
public void setTransientPermission(GDPermissionHolder holder, String permission, Boolean value, Set<Context> contexts) {
holderToPEXSubject(holder).transientData().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, pValFromBool(value)));
}
@Override
public void refreshCachedData(GDPermissionHolder holder) {
holderToPEXSubject(holder).clearCache(null);
}
}

View File

@ -86,11 +86,23 @@ public class PermissionUtil {
}
public boolean containsDefaultContext(Set<Context> contexts) {
return PERMISSION_PROVIDER.containsDefaultContext(contexts);
for (Context context : contexts) {
if (context.getKey().equals("gd_claim_default")) {
return true;
}
}
return false;
}
public boolean containsOverrideContext(Set<Context> contexts) {
return PERMISSION_PROVIDER.containsOverrideContext(contexts);
for (Context context : contexts) {
if (context.getKey().equals("gd_claim_override")) {
return true;
}
}
return false;
}
public void clearPermissions(GDClaim claim) {