This is an automated email from the ASF dual-hosted git repository.

mcgilman pushed a commit to branch NIFI-15343
in repository https://gitbox.apache.org/repos/asf/nifi.git

commit b81a32fc857fab81245c39bb24b2b3a57b7a908a
Author: Matt Gilman <[email protected]>
AuthorDate: Mon Dec 15 13:11:06 2025 -0500

    NIFI-15343: Adding an endpoint to return available secrets to the connector 
configuration wizard.
---
 .../org/apache/nifi/web/api/dto/SecretDTO.java     | 69 ++++++++++++++++++++
 .../apache/nifi/web/api/entity/SecretsEntity.java  | 43 ++++++++++++
 .../org/apache/nifi/web/NiFiServiceFacade.java     | 13 ++++
 .../apache/nifi/web/StandardNiFiServiceFacade.java | 23 +++++++
 .../org/apache/nifi/web/api/ConnectorResource.java | 48 ++++++++++++++
 .../org/apache/nifi/web/api/dto/DtoFactory.java    | 21 ++++++
 .../org/apache/nifi/web/api/dto/EntityFactory.java |  7 ++
 .../nifi/web/controller/ControllerFacade.java      | 10 +++
 .../nifi/web/StandardNiFiServiceFacadeTest.java    | 76 ++++++++++++++++++++++
 .../apache/nifi/web/api/TestConnectorResource.java | 27 ++++++++
 10 files changed, 337 insertions(+)

diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SecretDTO.java
 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SecretDTO.java
new file mode 100644
index 00000000000..fdcb972aae5
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/SecretDTO.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *     http://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.apache.nifi.web.api.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.xml.bind.annotation.XmlType;
+
+/**
+ * DTO representing a secret's metadata. Note: The actual secret value is 
never exposed via the REST API.
+ */
+@XmlType(name = "secret")
+public class SecretDTO {
+
+    private String providerName;
+    private String groupName;
+    private String name;
+    private String description;
+
+    @Schema(description = "The name of the secret provider that manages this 
secret.")
+    public String getProviderName() {
+        return providerName;
+    }
+
+    public void setProviderName(final String providerName) {
+        this.providerName = providerName;
+    }
+
+    @Schema(description = "The name of the group this secret belongs to.")
+    public String getGroupName() {
+        return groupName;
+    }
+
+    public void setGroupName(final String groupName) {
+        this.groupName = groupName;
+    }
+
+    @Schema(description = "The name of the secret.")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    @Schema(description = "A description of the secret.")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+}
+
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SecretsEntity.java
 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SecretsEntity.java
new file mode 100644
index 00000000000..0706dde05c9
--- /dev/null
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/SecretsEntity.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *     http://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.apache.nifi.web.api.entity;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.xml.bind.annotation.XmlRootElement;
+import org.apache.nifi.web.api.dto.SecretDTO;
+
+import java.util.List;
+
+/**
+ * A serialized representation of this class can be placed in the entity body 
of a response to the API.
+ * This particular entity holds a list of secrets.
+ */
+@XmlRootElement(name = "secretsEntity")
+public class SecretsEntity extends Entity {
+
+    private List<SecretDTO> secrets;
+
+    @Schema(description = "The list of secrets available from all secret 
providers.")
+    public List<SecretDTO> getSecrets() {
+        return secrets;
+    }
+
+    public void setSecrets(final List<SecretDTO> secrets) {
+        this.secrets = secrets;
+    }
+}
+
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index aee15d1c45e..963ec8e401a 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -161,6 +161,7 @@ import org.apache.nifi.web.api.entity.StatusHistoryEntity;
 import org.apache.nifi.web.api.entity.TenantsEntity;
 import org.apache.nifi.web.api.entity.UserEntity;
 import org.apache.nifi.web.api.entity.UserGroupEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity;
 import org.apache.nifi.web.api.entity.VersionControlInformationEntity;
 import org.apache.nifi.web.api.entity.VersionedFlowEntity;
@@ -3197,4 +3198,16 @@ public interface NiFiServiceFacade {
      * @return the list of listen Ports accessible to the current user
      */
     Set<ListenPortDTO> getListenPorts(NiFiUser user);
+
+    // ----------------------------------------
+    // Secrets methods
+    // ----------------------------------------
+
+    /**
+     * Gets all secrets available from all secret providers. Note: The actual 
secret values are not included
+     * in the response for security reasons; only metadata is returned.
+     *
+     * @return the secrets entity containing metadata for all available secrets
+     */
+    SecretsEntity getSecrets();
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index df04e148d2b..2549c14350f 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -79,6 +79,8 @@ import org.apache.nifi.components.RequiredPermission;
 import org.apache.nifi.components.ValidationResult;
 import org.apache.nifi.components.Validator;
 import org.apache.nifi.components.connector.ConnectorNode;
+import org.apache.nifi.components.connector.Secret;
+import org.apache.nifi.components.connector.secrets.AuthorizableSecret;
 import org.apache.nifi.components.state.Scope;
 import org.apache.nifi.components.state.StateMap;
 import org.apache.nifi.components.validation.ValidationState;
@@ -293,6 +295,7 @@ import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.api.dto.RequiredPermissionDTO;
 import org.apache.nifi.web.api.dto.ResourceDTO;
 import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.dto.SecretDTO;
 import org.apache.nifi.web.api.dto.SnippetDTO;
 import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO;
 import org.apache.nifi.web.api.dto.TenantDTO;
@@ -390,6 +393,7 @@ import org.apache.nifi.web.api.entity.ConnectorEntity;
 import org.apache.nifi.web.api.entity.ConfigurationStepEntity;
 import org.apache.nifi.web.api.entity.ConfigurationStepNamesEntity;
 import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.entity.SnippetEntity;
 import org.apache.nifi.web.api.entity.StartVersionControlRequestEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
@@ -7762,4 +7766,23 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
         final ProcessGroup processGroup = 
processGroupDAO.getProcessGroup(groupId);
         return getComponents.apply(processGroup);
     }
+
+    @Override
+    public SecretsEntity getSecrets() {
+        final NiFiUser user = NiFiUserUtils.getNiFiUser();
+        final List<Secret> secrets = controllerFacade.getAllSecrets();
+        final List<SecretDTO> secretDtos = secrets.stream()
+                .filter(secret -> isSecretAuthorized(secret, user))
+                .map(dtoFactory::createSecretDto)
+                .toList();
+        return entityFactory.createSecretsEntity(secretDtos);
+    }
+
+    private boolean isSecretAuthorized(final Secret secret, final NiFiUser 
user) {
+        if (secret instanceof AuthorizableSecret authorizableSecret) {
+            final AuthorizationResult result = 
authorizableSecret.checkAuthorization(authorizer, RequestAction.READ, user);
+            return Result.Approved.equals(result.getResult());
+        }
+        return true;
+    }
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java
index ffc3fc264d8..e5ad85ea1a5 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java
@@ -65,6 +65,7 @@ import 
org.apache.nifi.web.api.entity.ConnectorRunStatusEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.SearchResultsEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.concurrent.AsyncRequestManager;
 import org.apache.nifi.web.api.concurrent.AsynchronousWebRequest;
 import org.apache.nifi.web.api.concurrent.RequestManager;
@@ -313,6 +314,53 @@ public class ConnectorResource extends ApplicationResource 
{
         return generateOkResponse(entity).build();
     }
 
+    /**
+     * Gets all available secrets from the SecretsManager for configuring a 
specific connector.
+     *
+     * @param id The id of the connector being configured
+     * @return A secretsEntity containing metadata for all available secrets.
+     */
+    @GET
+    @Consumes(MediaType.WILDCARD)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/{id}/secrets")
+    @Operation(
+            summary = "Gets all secrets available for configuring a connector",
+            description = "Returns metadata for all secrets available from all 
secret providers. "
+                    + "This endpoint is used when configuring a connector to 
discover available secrets. "
+                    + "Note: Actual secret values are not included in the 
response for security reasons.",
+            responses = {
+                    @ApiResponse(responseCode = "200", content = 
@Content(schema = @Schema(implementation = SecretsEntity.class))),
+                    @ApiResponse(responseCode = "400", description = "NiFi was 
unable to complete the request because it was invalid. The request should not 
be retried without modification."),
+                    @ApiResponse(responseCode = "401", description = "Client 
could not be authenticated."),
+                    @ApiResponse(responseCode = "403", description = "Client 
is not authorized to make this request."),
+                    @ApiResponse(responseCode = "404", description = "The 
specified resource could not be found."),
+                    @ApiResponse(responseCode = "409", description = "The 
request was valid but NiFi was not in the appropriate state to process it.")
+            },
+            security = {
+                    @SecurityRequirement(name = "Write - /connectors/{uuid}")
+            }
+    )
+    public Response getSecrets(
+            @Parameter(
+                    description = "The connector id.",
+                    required = true
+            )
+            @PathParam("id") final String id) {
+
+        // NOTE: fetching secrets is handled by the node that receives the 
request and does not need to be replicated
+        // Secrets are sourced from ParameterProviders which should have 
consistent configuration across the cluster
+
+        // authorize access - require write permission on the specific 
connector since this is used for configuration
+        serviceFacade.authorizeAccess(lookup -> {
+            final Authorizable connector = lookup.getConnector(id);
+            connector.authorize(authorizer, RequestAction.WRITE, 
NiFiUserUtils.getNiFiUser());
+        });
+
+        final SecretsEntity entity = serviceFacade.getSecrets();
+        return generateOkResponse(entity).build();
+    }
+
     /**
      * Updates the specified connector.
      *
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 17e3c4ed55f..1caede055e0 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -80,6 +80,7 @@ import 
org.apache.nifi.components.connector.ConnectorPropertyGroup;
 import org.apache.nifi.components.connector.ConnectorValueReference;
 import org.apache.nifi.components.connector.FrameworkFlowContext;
 import org.apache.nifi.components.connector.NamedStepConfiguration;
+import org.apache.nifi.components.connector.Secret;
 import org.apache.nifi.components.connector.SecretReference;
 import org.apache.nifi.components.connector.StepConfiguration;
 import org.apache.nifi.components.connector.StringLiteralValue;
@@ -5431,4 +5432,24 @@ public final class DtoFactory {
         return dto;
     }
 
+    /**
+     * Creates a SecretDTO from the specified Secret. Note: The secret value 
is intentionally not included
+     * in the DTO for security reasons.
+     *
+     * @param secret the secret
+     * @return the DTO containing only the secret's metadata
+     */
+    public SecretDTO createSecretDto(final Secret secret) {
+        if (secret == null) {
+            return null;
+        }
+
+        final SecretDTO dto = new SecretDTO();
+        dto.setProviderName(secret.getProviderName());
+        dto.setGroupName(secret.getGroupName());
+        dto.setName(secret.getName());
+        dto.setDescription(secret.getDescription());
+        return dto;
+    }
+
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
index cd748204af9..a8ca5ab8c34 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java
@@ -83,6 +83,7 @@ import 
org.apache.nifi.web.api.entity.RemoteProcessGroupEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
 import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusSnapshotEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.SnippetEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
@@ -921,4 +922,10 @@ public final class EntityFactory {
         entity.setAllowableValues(allowableValues);
         return entity;
     }
+
+    public SecretsEntity createSecretsEntity(final List<SecretDTO> secrets) {
+        final SecretsEntity entity = new SecretsEntity();
+        entity.setSecrets(secrets);
+        return entity;
+    }
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
index 7bc8615c8b3..b08a5097f4c 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
@@ -46,6 +46,7 @@ import org.apache.nifi.components.RequiredPermission;
 import org.apache.nifi.components.listen.ListenComponent;
 import org.apache.nifi.components.connector.Connector;
 import org.apache.nifi.components.connector.ConnectorNode;
+import org.apache.nifi.components.connector.Secret;
 import org.apache.nifi.connectable.Connectable;
 import org.apache.nifi.connectable.Connection;
 import org.apache.nifi.connectable.Port;
@@ -2000,6 +2001,15 @@ public class ControllerFacade implements Authorizable {
         return new StandardVersionedReportingTaskImporter(flowController);
     }
 
+    /**
+     * Gets all secrets from the SecretsManager.
+     *
+     * @return list of all secrets available from all secret providers
+     */
+    public List<Secret> getAllSecrets() {
+        return 
flowController.getConnectorRepository().getSecretsManager().getAllSecrets();
+    }
+
     /*
      * setters
      */
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/StandardNiFiServiceFacadeTest.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/StandardNiFiServiceFacadeTest.java
index e3bd3f67dd1..65b16e4e697 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/StandardNiFiServiceFacadeTest.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/StandardNiFiServiceFacadeTest.java
@@ -39,6 +39,8 @@ import 
org.apache.nifi.authorization.user.StandardNiFiUser.Builder;
 import org.apache.nifi.components.PropertyDescriptor;
 import org.apache.nifi.components.connector.ConnectorNode;
 import org.apache.nifi.components.connector.FrameworkFlowContext;
+import org.apache.nifi.components.connector.Secret;
+import org.apache.nifi.components.connector.secrets.AuthorizableSecret;
 import org.apache.nifi.controller.Counter;
 import org.apache.nifi.controller.FlowController;
 import org.apache.nifi.controller.ProcessorNode;
@@ -105,6 +107,7 @@ import 
org.apache.nifi.web.api.entity.ClearBulletinsResultEntity;
 import org.apache.nifi.web.api.entity.ClearBulletinsForGroupResultsEntity;
 import org.apache.nifi.web.api.entity.CopyRequestEntity;
 import org.apache.nifi.web.api.entity.CopyResponseEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.entity.ProcessGroupEntity;
 import org.apache.nifi.web.api.entity.StatusHistoryEntity;
 import org.apache.nifi.web.api.entity.TenantEntity;
@@ -1700,4 +1703,77 @@ public class StandardNiFiServiceFacadeTest {
             serviceFacade.clearBulletinsForComponents(processGroupId, 
fromTimestamp, emptyComponentIds);
         });
     }
+
+    @Test
+    public void testGetSecretsFiltersUnauthorizedSecrets() {
+        final Authentication authentication = new NiFiAuthenticationToken(new 
NiFiUserDetails(new Builder().identity(USER_1).build()));
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+        final ControllerFacade controllerFacade = mock(ControllerFacade.class);
+        serviceFacade.setControllerFacade(controllerFacade);
+
+        final AuthorizableSecret authorizedSecret = 
mock(AuthorizableSecret.class);
+        when(authorizedSecret.getProviderName()).thenReturn("provider1");
+        when(authorizedSecret.getGroupName()).thenReturn("group1");
+        when(authorizedSecret.getName()).thenReturn("authorized-secret");
+        when(authorizedSecret.getDescription()).thenReturn("An authorized 
secret");
+        when(authorizedSecret.checkAuthorization(any(Authorizer.class), any(), 
any())).thenReturn(AuthorizationResult.approved());
+
+        final AuthorizableSecret unauthorizedSecret = 
mock(AuthorizableSecret.class);
+        when(unauthorizedSecret.getProviderName()).thenReturn("provider2");
+        when(unauthorizedSecret.getGroupName()).thenReturn("group2");
+        when(unauthorizedSecret.getName()).thenReturn("unauthorized-secret");
+        when(unauthorizedSecret.getDescription()).thenReturn("An unauthorized 
secret");
+        when(unauthorizedSecret.checkAuthorization(any(Authorizer.class), 
any(), any())).thenReturn(AuthorizationResult.denied());
+
+        
when(controllerFacade.getAllSecrets()).thenReturn(List.of(authorizedSecret, 
unauthorizedSecret));
+
+        final SecretsEntity result = serviceFacade.getSecrets();
+
+        assertNotNull(result);
+        assertNotNull(result.getSecrets());
+        assertEquals(1, result.getSecrets().size());
+        assertEquals("authorized-secret", 
result.getSecrets().get(0).getName());
+    }
+
+    @Test
+    public void testGetSecretsWithNonAuthorizableSecrets() {
+        final Authentication authentication = new NiFiAuthenticationToken(new 
NiFiUserDetails(new Builder().identity(USER_1).build()));
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+        final ControllerFacade controllerFacade = mock(ControllerFacade.class);
+        serviceFacade.setControllerFacade(controllerFacade);
+
+        final Secret nonAuthorizableSecret = mock(Secret.class);
+        when(nonAuthorizableSecret.getProviderName()).thenReturn("provider1");
+        when(nonAuthorizableSecret.getGroupName()).thenReturn("group1");
+        
when(nonAuthorizableSecret.getName()).thenReturn("non-authorizable-secret");
+        when(nonAuthorizableSecret.getDescription()).thenReturn("A 
non-authorizable secret");
+
+        
when(controllerFacade.getAllSecrets()).thenReturn(List.of(nonAuthorizableSecret));
+
+        final SecretsEntity result = serviceFacade.getSecrets();
+
+        assertNotNull(result);
+        assertNotNull(result.getSecrets());
+        assertEquals(1, result.getSecrets().size());
+        assertEquals("non-authorizable-secret", 
result.getSecrets().get(0).getName());
+    }
+
+    @Test
+    public void testGetSecretsWithEmptyList() {
+        final Authentication authentication = new NiFiAuthenticationToken(new 
NiFiUserDetails(new Builder().identity(USER_1).build()));
+        SecurityContextHolder.getContext().setAuthentication(authentication);
+
+        final ControllerFacade controllerFacade = mock(ControllerFacade.class);
+        serviceFacade.setControllerFacade(controllerFacade);
+
+        when(controllerFacade.getAllSecrets()).thenReturn(List.of());
+
+        final SecretsEntity result = serviceFacade.getSecrets();
+
+        assertNotNull(result);
+        assertNotNull(result.getSecrets());
+        assertTrue(result.getSecrets().isEmpty());
+    }
 }
diff --git 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java
 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java
index e1093d266d9..df21a6935e3 100644
--- 
a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java
+++ 
b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/api/TestConnectorResource.java
@@ -35,6 +35,7 @@ import org.apache.nifi.web.api.entity.AllowableValueEntity;
 import org.apache.nifi.web.api.entity.ConnectorEntity;
 import org.apache.nifi.web.api.entity.ConnectorPropertyAllowableValuesEntity;
 import org.apache.nifi.web.api.entity.ConnectorRunStatusEntity;
+import org.apache.nifi.web.api.entity.SecretsEntity;
 import org.apache.nifi.web.api.request.ClientIdParameter;
 import org.apache.nifi.web.api.request.LongParameter;
 import org.junit.jupiter.api.BeforeEach;
@@ -326,6 +327,32 @@ public class TestConnectorResource {
         verify(serviceFacade, 
never()).getConnectorPropertyAllowableValues(anyString(), anyString(), 
anyString(), anyString(), any());
     }
 
+    @Test
+    public void testGetSecrets() {
+        final SecretsEntity responseEntity = new SecretsEntity();
+        responseEntity.setSecrets(List.of());
+
+        when(serviceFacade.getSecrets()).thenReturn(responseEntity);
+
+        try (Response response = connectorResource.getSecrets(CONNECTOR_ID)) {
+            assertEquals(200, response.getStatus());
+            assertEquals(responseEntity, response.getEntity());
+        }
+
+        verify(serviceFacade).authorizeAccess(any(AuthorizeAccess.class));
+        verify(serviceFacade).getSecrets();
+    }
+
+    @Test
+    public void testGetSecretsNotAuthorized() {
+        
doThrow(AccessDeniedException.class).when(serviceFacade).authorizeAccess(any(AuthorizeAccess.class));
+
+        assertThrows(AccessDeniedException.class, () -> 
connectorResource.getSecrets(CONNECTOR_ID));
+
+        verify(serviceFacade).authorizeAccess(any(AuthorizeAccess.class));
+        verify(serviceFacade, never()).getSecrets();
+    }
+
     private ConnectorEntity createConnectorEntity() {
         final ConnectorEntity entity = new ConnectorEntity();
 

Reply via email to