Enable Null checking in spring-security-rsocket via JSpecify
Closes gh-16882
This commit is contained in:
parent
a4a4908d71
commit
1216ee598f
|
@ -1,3 +1,7 @@
|
||||||
|
plugins {
|
||||||
|
id 'security-nullability'
|
||||||
|
}
|
||||||
|
|
||||||
apply plugin: 'io.spring.convention.spring-module'
|
apply plugin: 'io.spring.convention.spring-module'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket APIs.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.api;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -24,6 +24,7 @@ import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.rsocket.metadata.AuthMetadataCodec;
|
import io.rsocket.metadata.AuthMetadataCodec;
|
||||||
import io.rsocket.metadata.WellKnownAuthType;
|
import io.rsocket.metadata.WellKnownAuthType;
|
||||||
import io.rsocket.metadata.WellKnownMimeType;
|
import io.rsocket.metadata.WellKnownMimeType;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.core.codec.ByteArrayDecoder;
|
import org.springframework.core.codec.ByteArrayDecoder;
|
||||||
|
@ -66,7 +67,7 @@ public class AuthenticationPayloadExchangeConverter implements PayloadExchangeAu
|
||||||
.flatMap((metadata) -> Mono.justOrEmpty(authentication(metadata)));
|
.flatMap((metadata) -> Mono.justOrEmpty(authentication(metadata)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Authentication authentication(Map<String, Object> metadata) {
|
private @Nullable Authentication authentication(Map<String, Object> metadata) {
|
||||||
byte[] authenticationMetadata = (byte[]) metadata.get("authentication");
|
byte[] authenticationMetadata = (byte[]) metadata.get("authentication");
|
||||||
if (authenticationMetadata == null) {
|
if (authenticationMetadata == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket Authentication integration.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.authentication;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket authorization integration.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.authorization;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -19,6 +19,7 @@ package org.springframework.security.rsocket.core;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.util.context.Context;
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
|
@ -41,11 +42,11 @@ import org.springframework.security.rsocket.api.PayloadInterceptorChain;
|
||||||
*/
|
*/
|
||||||
class ContextPayloadInterceptorChain implements PayloadInterceptorChain {
|
class ContextPayloadInterceptorChain implements PayloadInterceptorChain {
|
||||||
|
|
||||||
private final PayloadInterceptor currentInterceptor;
|
private final @Nullable PayloadInterceptor currentInterceptor;
|
||||||
|
|
||||||
private final ContextPayloadInterceptorChain next;
|
private final @Nullable ContextPayloadInterceptorChain next;
|
||||||
|
|
||||||
private Context context;
|
private @Nullable Context context;
|
||||||
|
|
||||||
ContextPayloadInterceptorChain(List<PayloadInterceptor> interceptors) {
|
ContextPayloadInterceptorChain(List<PayloadInterceptor> interceptors) {
|
||||||
if (interceptors == null) {
|
if (interceptors == null) {
|
||||||
|
@ -68,18 +69,20 @@ class ContextPayloadInterceptorChain implements PayloadInterceptorChain {
|
||||||
return interceptor;
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContextPayloadInterceptorChain(PayloadInterceptor currentInterceptor, ContextPayloadInterceptorChain next) {
|
private ContextPayloadInterceptorChain(@Nullable PayloadInterceptor currentInterceptor,
|
||||||
|
@Nullable ContextPayloadInterceptorChain next) {
|
||||||
this.currentInterceptor = currentInterceptor;
|
this.currentInterceptor = currentInterceptor;
|
||||||
this.next = next;
|
this.next = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("NullAway") // Dataflow analysis limitation
|
||||||
public Mono<Void> next(PayloadExchange exchange) {
|
public Mono<Void> next(PayloadExchange exchange) {
|
||||||
return Mono.defer(() -> shouldIntercept() ? this.currentInterceptor.intercept(exchange, this.next)
|
return Mono.defer(() -> shouldIntercept() ? this.currentInterceptor.intercept(exchange, this.next)
|
||||||
: Mono.deferContextual(Mono::just).cast(Context.class).doOnNext((c) -> this.context = c).then());
|
: Mono.deferContextual(Mono::just).cast(Context.class).doOnNext((c) -> this.context = c).then());
|
||||||
}
|
}
|
||||||
|
|
||||||
Context getContext() {
|
@Nullable Context getContext() {
|
||||||
if (this.next == null) {
|
if (this.next == null) {
|
||||||
return this.context;
|
return this.context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import reactor.util.context.Context;
|
||||||
|
|
||||||
import org.springframework.security.rsocket.api.PayloadExchangeType;
|
import org.springframework.security.rsocket.api.PayloadExchangeType;
|
||||||
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.MimeType;
|
import org.springframework.util.MimeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,6 +92,7 @@ class PayloadInterceptorRSocket extends RSocketProxy {
|
||||||
public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
|
public Flux<Payload> requestChannel(Publisher<Payload> payloads) {
|
||||||
return Flux.from(payloads).switchOnFirst((signal, innerFlux) -> {
|
return Flux.from(payloads).switchOnFirst((signal, innerFlux) -> {
|
||||||
Payload firstPayload = signal.get();
|
Payload firstPayload = signal.get();
|
||||||
|
Assert.notNull(firstPayload, "payload cannot be null");
|
||||||
return intercept(PayloadExchangeType.REQUEST_CHANNEL, firstPayload)
|
return intercept(PayloadExchangeType.REQUEST_CHANNEL, firstPayload)
|
||||||
.flatMapMany((context) -> innerFlux.index()
|
.flatMapMany((context) -> innerFlux.index()
|
||||||
.concatMap((tuple) -> justOrIntercept(tuple.getT1(), tuple.getT2()))
|
.concatMap((tuple) -> justOrIntercept(tuple.getT1(), tuple.getT2()))
|
||||||
|
|
|
@ -23,10 +23,10 @@ import io.rsocket.Payload;
|
||||||
import io.rsocket.RSocket;
|
import io.rsocket.RSocket;
|
||||||
import io.rsocket.SocketAcceptor;
|
import io.rsocket.SocketAcceptor;
|
||||||
import io.rsocket.metadata.WellKnownMimeType;
|
import io.rsocket.metadata.WellKnownMimeType;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.util.context.Context;
|
import reactor.util.context.Context;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
|
||||||
import org.springframework.security.rsocket.api.PayloadExchangeType;
|
import org.springframework.security.rsocket.api.PayloadExchangeType;
|
||||||
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
import org.springframework.security.rsocket.api.PayloadInterceptor;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -44,8 +44,7 @@ class PayloadSocketAcceptor implements SocketAcceptor {
|
||||||
|
|
||||||
private final List<PayloadInterceptor> interceptors;
|
private final List<PayloadInterceptor> interceptors;
|
||||||
|
|
||||||
@Nullable
|
private @Nullable MimeType defaultDataMimeType;
|
||||||
private MimeType defaultDataMimeType;
|
|
||||||
|
|
||||||
private MimeType defaultMetadataMimeType = MimeTypeUtils
|
private MimeType defaultMetadataMimeType = MimeTypeUtils
|
||||||
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_COMPOSITE_METADATA.getString());
|
.parseMimeType(WellKnownMimeType.MESSAGE_RSOCKET_COMPOSITE_METADATA.getString());
|
||||||
|
@ -85,7 +84,7 @@ class PayloadSocketAcceptor implements SocketAcceptor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private MimeType parseMimeType(String str, MimeType defaultMimeType) {
|
private @Nullable MimeType parseMimeType(String str, @Nullable MimeType defaultMimeType) {
|
||||||
return StringUtils.hasText(str) ? MimeTypeUtils.parseMimeType(str) : defaultMimeType;
|
return StringUtils.hasText(str) ? MimeTypeUtils.parseMimeType(str) : defaultMimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket core integration.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.core;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -18,6 +18,7 @@ package org.springframework.security.rsocket.metadata;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
@ -44,7 +45,7 @@ public class BasicAuthenticationDecoder extends AbstractDecoder<UsernamePassword
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<UsernamePasswordMetadata> decode(Publisher<DataBuffer> input, ResolvableType elementType,
|
public Flux<UsernamePasswordMetadata> decode(Publisher<DataBuffer> input, ResolvableType elementType,
|
||||||
MimeType mimeType, Map<String, Object> hints) {
|
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
return Flux.from(input).map(DataBuffer::asByteBuffer).map((byteBuffer) -> {
|
return Flux.from(input).map(DataBuffer::asByteBuffer).map((byteBuffer) -> {
|
||||||
byte[] sizeBytes = new byte[4];
|
byte[] sizeBytes = new byte[4];
|
||||||
byteBuffer.get(sizeBytes);
|
byteBuffer.get(sizeBytes);
|
||||||
|
@ -61,7 +62,7 @@ public class BasicAuthenticationDecoder extends AbstractDecoder<UsernamePassword
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<UsernamePasswordMetadata> decodeToMono(Publisher<DataBuffer> input, ResolvableType elementType,
|
public Mono<UsernamePasswordMetadata> decodeToMono(Publisher<DataBuffer> input, ResolvableType elementType,
|
||||||
MimeType mimeType, Map<String, Object> hints) {
|
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
return Mono.from(input).map(DataBuffer::asByteBuffer).map((byteBuffer) -> {
|
return Mono.from(input).map(DataBuffer::asByteBuffer).map((byteBuffer) -> {
|
||||||
int usernameSize = byteBuffer.getInt();
|
int usernameSize = byteBuffer.getInt();
|
||||||
byte[] usernameBytes = new byte[usernameSize];
|
byte[] usernameBytes = new byte[usernameSize];
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
@ -47,14 +48,15 @@ public class BasicAuthenticationEncoder extends AbstractEncoder<UsernamePassword
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<DataBuffer> encode(Publisher<? extends UsernamePasswordMetadata> inputStream,
|
public Flux<DataBuffer> encode(Publisher<? extends UsernamePasswordMetadata> inputStream,
|
||||||
DataBufferFactory bufferFactory, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
DataBufferFactory bufferFactory, ResolvableType elementType, @Nullable MimeType mimeType,
|
||||||
|
@Nullable Map<String, Object> hints) {
|
||||||
return Flux.from(inputStream)
|
return Flux.from(inputStream)
|
||||||
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataBuffer encodeValue(UsernamePasswordMetadata credentials, DataBufferFactory bufferFactory,
|
public DataBuffer encodeValue(UsernamePasswordMetadata credentials, DataBufferFactory bufferFactory,
|
||||||
ResolvableType valueType, MimeType mimeType, Map<String, Object> hints) {
|
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
String username = credentials.getUsername();
|
String username = credentials.getUsername();
|
||||||
String password = credentials.getPassword();
|
String password = credentials.getPassword();
|
||||||
byte[] usernameBytes = username.getBytes(StandardCharsets.UTF_8);
|
byte[] usernameBytes = username.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.rsocket.metadata.AuthMetadataCodec;
|
import io.rsocket.metadata.AuthMetadataCodec;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
@ -53,14 +54,15 @@ public class BearerTokenAuthenticationEncoder extends AbstractEncoder<BearerToke
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<DataBuffer> encode(Publisher<? extends BearerTokenMetadata> inputStream,
|
public Flux<DataBuffer> encode(Publisher<? extends BearerTokenMetadata> inputStream,
|
||||||
DataBufferFactory bufferFactory, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
DataBufferFactory bufferFactory, ResolvableType elementType, @Nullable MimeType mimeType,
|
||||||
|
@Nullable Map<String, Object> hints) {
|
||||||
return Flux.from(inputStream)
|
return Flux.from(inputStream)
|
||||||
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataBuffer encodeValue(BearerTokenMetadata credentials, DataBufferFactory bufferFactory,
|
public DataBuffer encodeValue(BearerTokenMetadata credentials, DataBufferFactory bufferFactory,
|
||||||
ResolvableType valueType, MimeType mimeType, Map<String, Object> hints) {
|
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
String token = credentials.getToken();
|
String token = credentials.getToken();
|
||||||
NettyDataBufferFactory factory = nettyFactory(bufferFactory);
|
NettyDataBufferFactory factory = nettyFactory(bufferFactory);
|
||||||
ByteBufAllocator allocator = factory.getByteBufAllocator();
|
ByteBufAllocator allocator = factory.getByteBufAllocator();
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
import io.rsocket.metadata.AuthMetadataCodec;
|
import io.rsocket.metadata.AuthMetadataCodec;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
@ -53,14 +54,15 @@ public class SimpleAuthenticationEncoder extends AbstractEncoder<UsernamePasswor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<DataBuffer> encode(Publisher<? extends UsernamePasswordMetadata> inputStream,
|
public Flux<DataBuffer> encode(Publisher<? extends UsernamePasswordMetadata> inputStream,
|
||||||
DataBufferFactory bufferFactory, ResolvableType elementType, MimeType mimeType, Map<String, Object> hints) {
|
DataBufferFactory bufferFactory, ResolvableType elementType, @Nullable MimeType mimeType,
|
||||||
|
@Nullable Map<String, Object> hints) {
|
||||||
return Flux.from(inputStream)
|
return Flux.from(inputStream)
|
||||||
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
.map((credentials) -> encodeValue(credentials, bufferFactory, elementType, mimeType, hints));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataBuffer encodeValue(UsernamePasswordMetadata credentials, DataBufferFactory bufferFactory,
|
public DataBuffer encodeValue(UsernamePasswordMetadata credentials, DataBufferFactory bufferFactory,
|
||||||
ResolvableType valueType, MimeType mimeType, Map<String, Object> hints) {
|
ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||||
String username = credentials.getUsername();
|
String username = credentials.getUsername();
|
||||||
String password = credentials.getPassword();
|
String password = credentials.getPassword();
|
||||||
NettyDataBufferFactory factory = nettyFactory(bufferFactory);
|
NettyDataBufferFactory factory = nettyFactory(bufferFactory);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket metadata integration.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.metadata;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import org.springframework.security.rsocket.api.PayloadExchange;
|
import org.springframework.security.rsocket.api.PayloadExchange;
|
||||||
|
@ -46,9 +47,9 @@ public interface PayloadExchangeMatcher {
|
||||||
|
|
||||||
private final boolean match;
|
private final boolean match;
|
||||||
|
|
||||||
private final Map<String, Object> variables;
|
private final @Nullable Map<String, Object> variables;
|
||||||
|
|
||||||
private MatchResult(boolean match, Map<String, Object> variables) {
|
private MatchResult(boolean match, @Nullable Map<String, Object> variables) {
|
||||||
this.match = match;
|
this.match = match;
|
||||||
this.variables = variables;
|
this.variables = variables;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +62,7 @@ public interface PayloadExchangeMatcher {
|
||||||
* Gets potential variables and their values
|
* Gets potential variables and their values
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> getVariables() {
|
public @Nullable Map<String, Object> getVariables() {
|
||||||
return this.variables;
|
return this.variables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004-present the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring Security RSocket matching APIs.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.rsocket.util.matcher;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
Loading…
Reference in New Issue