-
Notifications
You must be signed in to change notification settings - Fork 2.3k
fix: don't fail the whole service list when one connection can't be decrypted #31888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| import jakarta.ws.rs.core.SecurityContext; | ||
| import jakarta.ws.rs.core.UriInfo; | ||
| import lombok.Getter; | ||
| import lombok.extern.slf4j.Slf4j; | ||
| import org.openmetadata.schema.ServiceConnectionEntityInterface; | ||
| import org.openmetadata.schema.ServiceEntityInterface; | ||
| import org.openmetadata.schema.entity.services.ServiceType; | ||
|
|
@@ -37,6 +38,7 @@ | |
| import org.openmetadata.service.secrets.masker.EntityMaskerFactory; | ||
| import org.openmetadata.service.security.Authorizer; | ||
|
|
||
| @Slf4j | ||
| public abstract class ServiceEntityResource< | ||
| T extends ServiceEntityInterface, | ||
| R extends ServiceEntityRepository<T, S>, | ||
|
|
@@ -81,7 +83,23 @@ private Object retrieveServiceConnectionConfig(T service, boolean maskPassword) | |
|
|
||
| protected ResultList<T> decryptOrNullify( | ||
| SecurityContext securityContext, ResultList<T> services) { | ||
| listOrEmpty(services.getData()).forEach(service -> decryptOrNullify(securityContext, service)); | ||
| // Degrade per service rather than failing the whole list. A single connection that | ||
| // cannot be decrypted -- most often after the Fernet key changes -- would otherwise | ||
| // propagate out of the loop and fail the request, hiding every other service and | ||
| // leaving no way to reach the affected one's edit form to repair it. | ||
| listOrEmpty(services.getData()) | ||
| .forEach( | ||
| service -> { | ||
| try { | ||
| decryptOrNullify(securityContext, service); | ||
| } catch (Exception e) { | ||
| LOG.warn( | ||
| "Failed to decrypt connection of service '{}'; returning it without one: {}", | ||
| service.getFullyQualifiedName(), | ||
| e.getMessage()); | ||
| nullifyConnection(service); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Quality: nullifyConnection relies on discarded return value's side effectIn the catch block, Assign the nullified service back into the list instead of relying on in-place mutation.:
Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎 |
||
| } | ||
| }); | ||
| return services; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When field-by-field decryption fails after processing secret fields,
e.getMessage()contains the generated connection object's string representation, causing password or private-key material to be written to application logs. Log the service identity without the exception message.How this was verified: The decryption failure message embeds
toDecryptObject.toString(), whose generated representation includes password fields, and this warning logs that message unchanged.Knowledge Base Used: Auth and Security: Authentication, Authorization, Secrets, and SCIM