parent
3a1692f3c3
commit
eedcec9d5c
|
@ -0,0 +1,42 @@
|
||||||
|
apply plugin: 'io.spring.convention.spring-module'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
management platform(project(":spring-security-dependencies"))
|
||||||
|
api project(':spring-security-crypto')
|
||||||
|
api project(':spring-security-core')
|
||||||
|
api 'org.springframework:spring-aop'
|
||||||
|
api 'org.springframework:spring-beans'
|
||||||
|
api 'org.springframework:spring-context'
|
||||||
|
api 'org.springframework:spring-core'
|
||||||
|
api 'org.springframework:spring-expression'
|
||||||
|
api 'io.micrometer:micrometer-observation'
|
||||||
|
|
||||||
|
optional 'com.fasterxml.jackson.core:jackson-databind'
|
||||||
|
optional 'io.micrometer:context-propagation'
|
||||||
|
optional 'io.projectreactor:reactor-core'
|
||||||
|
optional 'jakarta.annotation:jakarta.annotation-api'
|
||||||
|
optional 'org.aspectj:aspectjrt'
|
||||||
|
optional 'org.springframework:spring-jdbc'
|
||||||
|
optional 'org.springframework:spring-tx'
|
||||||
|
optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
|
||||||
|
|
||||||
|
testImplementation 'commons-collections:commons-collections'
|
||||||
|
testImplementation 'io.projectreactor:reactor-test'
|
||||||
|
testImplementation "org.assertj:assertj-core"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-params"
|
||||||
|
testImplementation "org.junit.jupiter:junit-jupiter-engine"
|
||||||
|
testImplementation "org.mockito:mockito-core"
|
||||||
|
testImplementation "org.mockito:mockito-junit-jupiter"
|
||||||
|
testImplementation "org.springframework:spring-core-test"
|
||||||
|
testImplementation "org.springframework:spring-test"
|
||||||
|
testImplementation 'org.skyscreamer:jsonassert'
|
||||||
|
testImplementation 'org.springframework:spring-test'
|
||||||
|
testImplementation 'org.jetbrains.kotlin:kotlin-reflect'
|
||||||
|
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
|
||||||
|
testImplementation 'io.mockk:mockk'
|
||||||
|
|
||||||
|
testRuntimeOnly 'org.hsqldb:hsqldb'
|
||||||
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support for JSR-250 and Spring Security {@code @Secured} annotations.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.access.annotation;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of expression-based method security.
|
||||||
|
*
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.access.expression.method;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core access-control related code, including security metadata related classes,
|
||||||
|
* interception code, access control annotations, EL support and voter-based
|
||||||
|
* implementations of the central
|
||||||
|
* {@link org.springframework.security.access.AccessDecisionManager AccessDecisionManager}
|
||||||
|
* interface.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.access;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the infrastructure classes for handling the {@code @PreAuthorize},
|
||||||
|
* {@code @PreFilter}, {@code @PostAuthorize} and {@code @PostFilter} annotations.
|
||||||
|
* <p>
|
||||||
|
* Other than the annotations themselves, the classes should be regarded as for internal
|
||||||
|
* framework use and are liable to change without notice.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
package org.springframework.security.access.prepost;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.access;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the interface of a secured object.
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
*/
|
||||||
|
public interface ITargetObject {
|
||||||
|
|
||||||
|
Integer computeHashCode(String input);
|
||||||
|
|
||||||
|
int countLength(String input);
|
||||||
|
|
||||||
|
String makeLowerCase(String input);
|
||||||
|
|
||||||
|
String makeUpperCase(String input);
|
||||||
|
|
||||||
|
String publicMakeLowerCase(String input);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.access;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simply extends {@link TargetObject} so we have a different object to put configuration
|
||||||
|
* attributes against.
|
||||||
|
* <P>
|
||||||
|
* There is no different behaviour. We have to define each method so that
|
||||||
|
* <code>Class.getMethod(methodName, args)</code> returns a <code>Method</code>
|
||||||
|
* referencing this class rather than the parent class.
|
||||||
|
* </p>
|
||||||
|
* <P>
|
||||||
|
* We need to implement <code>ITargetObject</code> again because the
|
||||||
|
* <code>MethodDefinitionAttributes</code> only locates attributes on interfaces
|
||||||
|
* explicitly defined by the intercepted class (not the interfaces defined by its parent
|
||||||
|
* class or classes).
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
*/
|
||||||
|
public class OtherTargetObject extends TargetObject implements ITargetObject {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String makeLowerCase(String input) {
|
||||||
|
return super.makeLowerCase(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String makeUpperCase(String input) {
|
||||||
|
return super.makeUpperCase(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String publicMakeLowerCase(String input) {
|
||||||
|
return super.publicMakeLowerCase(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.access;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a secured object.
|
||||||
|
*
|
||||||
|
* @author Ben Alex
|
||||||
|
*/
|
||||||
|
public class TargetObject implements ITargetObject {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer computeHashCode(String input) {
|
||||||
|
return input.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int countLength(String input) {
|
||||||
|
return input.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the lowercase string, followed by security environment information.
|
||||||
|
* @param input the message to make lowercase
|
||||||
|
* @return the lowercase message, a space, the <code>Authentication</code> class that
|
||||||
|
* was on the <code>SecurityContext</code> at the time of method invocation, and a
|
||||||
|
* boolean indicating if the <code>Authentication</code> object is authenticated or
|
||||||
|
* not
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String makeLowerCase(String input) {
|
||||||
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (auth == null) {
|
||||||
|
return input.toLowerCase() + " Authentication empty";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return input.toLowerCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the uppercase string, followed by security environment information.
|
||||||
|
* @param input the message to make uppercase
|
||||||
|
* @return the uppercase message, a space, the <code>Authentication</code> class that
|
||||||
|
* was on the <code>SecurityContext</code> at the time of method invocation, and a
|
||||||
|
* boolean indicating if the <code>Authentication</code> object is authenticated or
|
||||||
|
* not
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String makeUpperCase(String input) {
|
||||||
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
return input.toUpperCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates through to the {@link #makeLowerCase(String)} method.
|
||||||
|
* @param input the message to be made lower-case
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String publicMakeLowerCase(String input) {
|
||||||
|
return this.makeLowerCase(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -39,8 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for
|
* Tests for {@link SecuredAnnotationSecurityMetadataSource}
|
||||||
* {@link org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource}
|
|
||||||
*
|
*
|
||||||
* @author Mark St.Godard
|
* @author Mark St.Godard
|
||||||
* @author Joe Scalise
|
* @author Joe Scalise
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.security.access.expression.method;
|
package org.springframework.security.access.expression.method;
|
||||||
|
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@ -28,7 +29,6 @@ import org.springframework.security.access.expression.ExpressionUtils;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.BDDMockito.given;
|
import static org.mockito.BDDMockito.given;
|
||||||
|
@ -65,19 +65,19 @@ public class MethodSecurityExpressionRootTests {
|
||||||
public void canCallMethodsOnVariables() {
|
public void canCallMethodsOnVariables() {
|
||||||
this.ctx.setVariable("var", "somestring");
|
this.ctx.setVariable("var", "somestring");
|
||||||
Expression e = this.parser.parseExpression("#var.length() == 10");
|
Expression e = this.parser.parseExpression("#var.length() == 10");
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() {
|
public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() {
|
||||||
given(this.trustResolver.isAnonymous(this.user)).willReturn(true);
|
given(this.trustResolver.isAnonymous(this.user)).willReturn(true);
|
||||||
assertThat(this.root.isAnonymous()).isTrue();
|
Assertions.assertThat(this.root.isAnonymous()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() {
|
public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() {
|
||||||
given(this.trustResolver.isAnonymous(this.user)).willReturn(false);
|
given(this.trustResolver.isAnonymous(this.user)).willReturn(false);
|
||||||
assertThat(this.root.isAnonymous()).isFalse();
|
Assertions.assertThat(this.root.isAnonymous()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -87,7 +87,7 @@ public class MethodSecurityExpressionRootTests {
|
||||||
this.ctx.setVariable("domainObject", dummyDomainObject);
|
this.ctx.setVariable("domainObject", dummyDomainObject);
|
||||||
this.root.setPermissionEvaluator(pe);
|
this.root.setPermissionEvaluator(pe);
|
||||||
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(false);
|
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(false);
|
||||||
assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
|
Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -97,7 +97,7 @@ public class MethodSecurityExpressionRootTests {
|
||||||
this.ctx.setVariable("domainObject", dummyDomainObject);
|
this.ctx.setVariable("domainObject", dummyDomainObject);
|
||||||
this.root.setPermissionEvaluator(pe);
|
this.root.setPermissionEvaluator(pe);
|
||||||
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(true);
|
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(true);
|
||||||
assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
|
Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -109,13 +109,13 @@ public class MethodSecurityExpressionRootTests {
|
||||||
given(pe.hasPermission(eq(this.user), eq(dummyDomainObject), any(Integer.class))).willReturn(true, true, false);
|
given(pe.hasPermission(eq(this.user), eq(dummyDomainObject), any(Integer.class))).willReturn(true, true, false);
|
||||||
Expression e = this.parser.parseExpression("hasPermission(#domainObject, 0xA)");
|
Expression e = this.parser.parseExpression("hasPermission(#domainObject, 0xA)");
|
||||||
// evaluator returns true
|
// evaluator returns true
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||||
e = this.parser.parseExpression("hasPermission(#domainObject, 10)");
|
e = this.parser.parseExpression("hasPermission(#domainObject, 10)");
|
||||||
// evaluator returns true
|
// evaluator returns true
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||||
e = this.parser.parseExpression("hasPermission(#domainObject, 0xFF)");
|
e = this.parser.parseExpression("hasPermission(#domainObject, 0xFF)");
|
||||||
// evaluator returns false, make sure return value matches
|
// evaluator returns false, make sure return value matches
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -132,11 +132,11 @@ public class MethodSecurityExpressionRootTests {
|
||||||
given(pe.hasPermission(this.user, targetObject, i)).willReturn(true, false);
|
given(pe.hasPermission(this.user, targetObject, i)).willReturn(true, false);
|
||||||
given(pe.hasPermission(this.user, "x", i)).willReturn(true);
|
given(pe.hasPermission(this.user, "x", i)).willReturn(true);
|
||||||
Expression e = this.parser.parseExpression("hasPermission(this, 2)");
|
Expression e = this.parser.parseExpression("hasPermission(this, 2)");
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||||
e = this.parser.parseExpression("hasPermission(this, 2)");
|
e = this.parser.parseExpression("hasPermission(this, 2)");
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||||
e = this.parser.parseExpression("hasPermission(this.x, 2)");
|
e = this.parser.parseExpression("hasPermission(this.x, 2)");
|
||||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue