|
@@ -1,5 +1,5 @@
|
|
/*
|
|
/*
|
|
- * Copyright 2002-2018 the original author or authors.
|
|
|
|
|
|
+ * Copyright 2002-2021 the original author or authors.
|
|
*
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* you may not use this file except in compliance with the License.
|
|
@@ -16,9 +16,9 @@
|
|
|
|
|
|
package org.springframework.security.scheduling;
|
|
package org.springframework.security.scheduling;
|
|
|
|
|
|
-import java.time.Duration;
|
|
|
|
import java.time.Instant;
|
|
import java.time.Instant;
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
|
|
|
|
import org.junit.After;
|
|
import org.junit.After;
|
|
import org.junit.Before;
|
|
import org.junit.Before;
|
|
@@ -28,11 +28,16 @@ import org.mockito.MockitoAnnotations;
|
|
|
|
|
|
import org.springframework.scheduling.TaskScheduler;
|
|
import org.springframework.scheduling.TaskScheduler;
|
|
import org.springframework.scheduling.Trigger;
|
|
import org.springframework.scheduling.Trigger;
|
|
|
|
+import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
|
|
|
|
+import org.springframework.security.core.context.SecurityContext;
|
|
|
|
+import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
|
|
|
|
|
+import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
|
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.ArgumentMatchers.isA;
|
|
import static org.mockito.ArgumentMatchers.isA;
|
|
|
|
+import static org.mockito.BDDMockito.willAnswer;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -47,22 +52,30 @@ public class DelegatingSecurityContextTaskSchedulerTests {
|
|
@Mock
|
|
@Mock
|
|
private TaskScheduler scheduler;
|
|
private TaskScheduler scheduler;
|
|
|
|
|
|
|
|
+ @Mock
|
|
|
|
+ private SecurityContext securityContext;
|
|
|
|
+
|
|
@Mock
|
|
@Mock
|
|
private Runnable runnable;
|
|
private Runnable runnable;
|
|
|
|
|
|
@Mock
|
|
@Mock
|
|
private Trigger trigger;
|
|
private Trigger trigger;
|
|
|
|
|
|
|
|
+ private SecurityContext originalSecurityContext;
|
|
|
|
+
|
|
private DelegatingSecurityContextTaskScheduler delegatingSecurityContextTaskScheduler;
|
|
private DelegatingSecurityContextTaskScheduler delegatingSecurityContextTaskScheduler;
|
|
|
|
|
|
@Before
|
|
@Before
|
|
public void setup() {
|
|
public void setup() {
|
|
MockitoAnnotations.initMocks(this);
|
|
MockitoAnnotations.initMocks(this);
|
|
- this.delegatingSecurityContextTaskScheduler = new DelegatingSecurityContextTaskScheduler(this.scheduler);
|
|
|
|
|
|
+ this.originalSecurityContext = SecurityContextHolder.createEmptyContext();
|
|
|
|
+ this.delegatingSecurityContextTaskScheduler = new DelegatingSecurityContextTaskScheduler(this.scheduler,
|
|
|
|
+ this.securityContext);
|
|
}
|
|
}
|
|
|
|
|
|
@After
|
|
@After
|
|
public void cleanup() {
|
|
public void cleanup() {
|
|
|
|
+ SecurityContextHolder.clearContext();
|
|
this.delegatingSecurityContextTaskScheduler = null;
|
|
this.delegatingSecurityContextTaskScheduler = null;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -71,6 +84,36 @@ public class DelegatingSecurityContextTaskSchedulerTests {
|
|
assertThatIllegalArgumentException().isThrownBy(() -> new DelegatingSecurityContextTaskScheduler(null));
|
|
assertThatIllegalArgumentException().isThrownBy(() -> new DelegatingSecurityContextTaskScheduler(null));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ public void testSchedulerCurrentSecurityContext() throws Exception {
|
|
|
|
+ willAnswer((invocation) -> {
|
|
|
|
+ assertThat(SecurityContextHolder.getContext()).isEqualTo(this.originalSecurityContext);
|
|
|
|
+ return null;
|
|
|
|
+ }).given(this.runnable).run();
|
|
|
|
+ TaskScheduler delegateTaskScheduler = new ConcurrentTaskScheduler();
|
|
|
|
+ this.delegatingSecurityContextTaskScheduler = new DelegatingSecurityContextTaskScheduler(delegateTaskScheduler);
|
|
|
|
+ assertWrapped(this.runnable);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void testSchedulerExplicitSecurityContext() throws Exception {
|
|
|
|
+ willAnswer((invocation) -> {
|
|
|
|
+ assertThat(SecurityContextHolder.getContext()).isEqualTo(this.securityContext);
|
|
|
|
+ return null;
|
|
|
|
+ }).given(this.runnable).run();
|
|
|
|
+ TaskScheduler delegateTaskScheduler = new ConcurrentTaskScheduler();
|
|
|
|
+ this.delegatingSecurityContextTaskScheduler = new DelegatingSecurityContextTaskScheduler(delegateTaskScheduler,
|
|
|
|
+ this.securityContext);
|
|
|
|
+ assertWrapped(this.runnable);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void assertWrapped(Runnable runnable) throws Exception {
|
|
|
|
+ ScheduledFuture<?> schedule = this.delegatingSecurityContextTaskScheduler.schedule(runnable, new Date());
|
|
|
|
+ schedule.get();
|
|
|
|
+ verify(this.runnable).run();
|
|
|
|
+ assertThat(SecurityContextHolder.getContext()).isEqualTo(this.originalSecurityContext);
|
|
|
|
+ }
|
|
|
|
+
|
|
@Test
|
|
@Test
|
|
public void testSchedulerWithRunnableAndTrigger() {
|
|
public void testSchedulerWithRunnableAndTrigger() {
|
|
this.delegatingSecurityContextTaskScheduler.schedule(this.runnable, this.trigger);
|
|
this.delegatingSecurityContextTaskScheduler.schedule(this.runnable, this.trigger);
|
|
@@ -87,7 +130,6 @@ public class DelegatingSecurityContextTaskSchedulerTests {
|
|
@Test
|
|
@Test
|
|
public void testScheduleAtFixedRateWithRunnableAndDate() {
|
|
public void testScheduleAtFixedRateWithRunnableAndDate() {
|
|
Date date = new Date(1544751374L);
|
|
Date date = new Date(1544751374L);
|
|
- Duration duration = Duration.ofSeconds(4L);
|
|
|
|
this.delegatingSecurityContextTaskScheduler.scheduleAtFixedRate(this.runnable, date, 1000L);
|
|
this.delegatingSecurityContextTaskScheduler.scheduleAtFixedRate(this.runnable, date, 1000L);
|
|
verify(this.scheduler).scheduleAtFixedRate(isA(Runnable.class), isA(Date.class), eq(1000L));
|
|
verify(this.scheduler).scheduleAtFixedRate(isA(Runnable.class), isA(Date.class), eq(1000L));
|
|
}
|
|
}
|