Fix CompositeResolver using its own isAuthRequired method (#2124)

Fixes CompositeResolver using its own isAuthRequired method instead of the child resolver, leading NoAuthResolver to need authentication in some cases.
This commit is contained in:
Aurora Lahtela 2021-10-11 20:24:39 +03:00 committed by GitHub
parent bb83adfd51
commit 7d8b797b42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 25 deletions

View File

@ -39,28 +39,22 @@ import java.util.function.Predicate;
public final class CompositeResolver implements Resolver { public final class CompositeResolver implements Resolver {
private final List<String> prefixes; private final List<String> prefixes;
private final List<Function<Request, Optional<Response>>> resolvers; private final List<Resolver> resolvers;
private final List<Predicate<Request>> canAccess;
CompositeResolver() { CompositeResolver() {
this.prefixes = new ArrayList<>(); this.prefixes = new ArrayList<>();
this.resolvers = new ArrayList<>(); this.resolvers = new ArrayList<>();
this.canAccess = new ArrayList<>();
} }
public static CompositeResolver.Builder builder() { public static CompositeResolver.Builder builder() {
return new Builder(); return new Builder();
} }
private Optional<Function<Request, Optional<Response>>> getResolver(URIPath target) { private Optional<Resolver> getResolver(URIPath target) {
return target.getPart(0).flatMap(this::findResolver); return target.getPart(0).flatMap(this::findResolver);
} }
private Optional<Predicate<Request>> getAccessCheck(URIPath target) { private Optional<Resolver> findResolver(String prefix) {
return target.getPart(0).flatMap(this::findAccessCheck);
}
private Optional<Function<Request, Optional<Response>>> findResolver(String prefix) {
for (int i = 0; i < prefixes.size(); i++) { for (int i = 0; i < prefixes.size(); i++) {
if (prefixes.get(i).equals(prefix)) { if (prefixes.get(i).equals(prefix)) {
return Optional.of(resolvers.get(i)); return Optional.of(resolvers.get(i));
@ -69,21 +63,11 @@ public final class CompositeResolver implements Resolver {
return Optional.empty(); return Optional.empty();
} }
private Optional<Predicate<Request>> findAccessCheck(String prefix) {
for (int i = 0; i < prefixes.size(); i++) {
if (prefixes.get(i).equals(prefix)) {
return Optional.of(canAccess.get(i));
}
}
return Optional.empty();
}
void add(String prefix, Resolver resolver) { void add(String prefix, Resolver resolver) {
if (prefix == null) throw new IllegalArgumentException("Prefix can not be null"); if (prefix == null) throw new IllegalArgumentException("Prefix can not be null");
if (resolver == null) throw new IllegalArgumentException("Resolver can not be null"); if (resolver == null) throw new IllegalArgumentException("Resolver can not be null");
prefixes.add(prefix); prefixes.add(prefix);
resolvers.add(resolver::resolve); resolvers.add(resolver);
canAccess.add(resolver::canAccess);
} }
void add(String prefix, Function<Request, Response> resolver, Predicate<Request> accessCheck) { void add(String prefix, Function<Request, Response> resolver, Predicate<Request> accessCheck) {
@ -93,22 +77,27 @@ public final class CompositeResolver implements Resolver {
} }
if (accessCheck == null) throw new IllegalArgumentException("Predicate<Request> accessCheck can not be null"); if (accessCheck == null) throw new IllegalArgumentException("Predicate<Request> accessCheck can not be null");
prefixes.add(prefix); prefixes.add(prefix);
resolvers.add(request -> Optional.ofNullable(resolver.apply(request))); resolvers.add(new FunctionalResolverWrapper(request -> Optional.ofNullable(resolver.apply(request)), accessCheck));
canAccess.add(accessCheck);
} }
@Override @Override
public boolean canAccess(Request request) { public boolean canAccess(Request request) {
Request forThis = request.omitFirstInPath(); Request forThis = request.omitFirstInPath();
return getAccessCheck(forThis.getPath()) return getResolver(forThis.getPath())
.map(resolver -> resolver.test(forThis)) .map(resolver -> resolver.canAccess(forThis))
.orElse(true); .orElse(true);
} }
@Override @Override
public Optional<Response> resolve(Request request) { public Optional<Response> resolve(Request request) {
Request forThis = request.omitFirstInPath(); Request forThis = request.omitFirstInPath();
return getResolver(forThis.getPath()).flatMap(resolver -> resolver.apply(forThis)); return getResolver(forThis.getPath()).flatMap(resolver -> resolver.resolve(forThis));
}
@Override
public boolean requiresAuth(Request request) {
Request forThis = request.omitFirstInPath();
return getResolver(forThis.getPath()).map(resolver -> resolver.requiresAuth(forThis)).orElse(true);
} }
public static class Builder { public static class Builder {

View File

@ -0,0 +1,44 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.web.resolver;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
public class FunctionalResolverWrapper implements Resolver {
private final Function<Request, Optional<Response>> resolver;
private final Predicate<Request> accessCheck;
public FunctionalResolverWrapper(Function<Request, Optional<Response>> resolver, Predicate<Request> accessCheck) {
this.resolver = resolver;
this.accessCheck = accessCheck;
}
@Override
public boolean canAccess(Request request) {
return accessCheck.test(request);
}
@Override
public Optional<Response> resolve(Request request) {
return resolver.apply(request);
}
}