NIFI-10794 Made StandardOauth2AccessTokenProvider a verifiable controller service.

Signed-off-by: Chris Sampson <chris.sampson82@gmail.com>

This closes #6645.
This commit is contained in:
Mike Thomsen 2022-11-10 07:45:40 -05:00 committed by Chris Sampson
parent 3a536e261f
commit ea10b62615
2 changed files with 83 additions and 1 deletions

View File

@ -29,13 +29,16 @@ import org.apache.nifi.annotation.documentation.Tags;
import org.apache.nifi.annotation.lifecycle.OnDisabled;
import org.apache.nifi.annotation.lifecycle.OnEnabled;
import org.apache.nifi.components.AllowableValue;
import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.ValidationContext;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.components.Validator;
import org.apache.nifi.controller.AbstractControllerService;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.controller.VerifiableControllerService;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.ssl.SSLContextService;
@ -50,12 +53,13 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Tags({"oauth2", "provider", "authorization", "access token", "http"})
@CapabilityDescription("Provides OAuth 2.0 access tokens that can be used as Bearer authorization header in HTTP requests." +
" Uses Resource Owner Password Credentials Grant.")
public class StandardOauth2AccessTokenProvider extends AbstractControllerService implements OAuth2AccessTokenProvider {
public class StandardOauth2AccessTokenProvider extends AbstractControllerService implements OAuth2AccessTokenProvider, VerifiableControllerService {
public static final PropertyDescriptor AUTHORIZATION_SERVER_URL = new PropertyDescriptor.Builder()
.name("authorization-server-url")
.displayName("Authorization Server URL")
@ -338,4 +342,20 @@ public class StandardOauth2AccessTokenProvider extends AbstractControllerService
return Instant.now().isAfter(expirationRefreshTime);
}
@Override
public List<ConfigVerificationResult> verify(ConfigurationContext context, ComponentLog verificationLogger, Map<String, String> variables) {
ConfigVerificationResult.Builder builder = new ConfigVerificationResult.Builder()
.verificationStepName("Can acquire token");
try {
getAccessDetails();
builder.outcome(ConfigVerificationResult.Outcome.SUCCESSFUL);
} catch (Exception ex) {
builder.outcome(ConfigVerificationResult.Outcome.FAILED)
.explanation(ex.getMessage());
}
return Arrays.asList(builder.build());
}
}

View File

@ -22,10 +22,16 @@ import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.apache.nifi.components.ConfigVerificationResult;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.controller.VerifiableControllerService;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.util.MockConfigurationContext;
import org.apache.nifi.util.MockControllerServiceLookup;
import org.apache.nifi.util.MockVariableRegistry;
import org.apache.nifi.util.NoOpProcessor;
import org.apache.nifi.util.TestRunner;
import org.apache.nifi.util.TestRunners;
@ -43,10 +49,14 @@ import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.apache.nifi.components.ConfigVerificationResult.Outcome.FAILED;
import static org.apache.nifi.components.ConfigVerificationResult.Outcome.SUCCESSFUL;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@ -162,6 +172,58 @@ public class StandardOauth2AccessTokenProviderTest {
assertEquals(accessTokenValue, actual);
}
@Test
public void testVerifySuccess() throws Exception {
Processor processor = new NoOpProcessor();
TestRunner runner = TestRunners.newTestRunner(processor);
runner.addControllerService("testSubject", testSubject);
Map<PropertyDescriptor, String> properties = ((MockControllerServiceLookup) runner.getProcessContext().getControllerServiceLookup())
.getControllerServices().get("testSubject").getProperties();
String accessTokenValue = "access_token_value";
// GIVEN
Response response = buildResponse(
HTTP_OK,
"{ \"access_token\":\"" + accessTokenValue + "\" }"
);
when(mockHttpClient.newCall(any(Request.class)).execute()).thenReturn(response);
final List<ConfigVerificationResult> results = ((VerifiableControllerService) testSubject).verify(
new MockConfigurationContext(testSubject, properties, runner.getProcessContext().getControllerServiceLookup(), new MockVariableRegistry()),
runner.getLogger(),
Collections.emptyMap()
);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals(SUCCESSFUL, results.get(0).getOutcome());
}
@Test
public void testVerifyError() throws Exception {
Processor processor = new NoOpProcessor();
TestRunner runner = TestRunners.newTestRunner(processor);
runner.addControllerService("testSubject", testSubject);
Map<PropertyDescriptor, String> properties = ((MockControllerServiceLookup) runner.getProcessContext().getControllerServiceLookup())
.getControllerServices().get("testSubject").getProperties();
when(mockHttpClient.newCall(any(Request.class)).execute()).thenThrow(new IOException());
final List<ConfigVerificationResult> results = ((VerifiableControllerService) testSubject).verify(
new MockConfigurationContext(testSubject, properties, runner.getProcessContext().getControllerServiceLookup(), new MockVariableRegistry()),
runner.getLogger(),
Collections.emptyMap()
);
assertNotNull(results);
assertEquals(1, results.size());
assertEquals(FAILED, results.get(0).getOutcome());
}
@Test
public void testRefreshToken() throws Exception {
// GIVEN