-
Notifications
You must be signed in to change notification settings - Fork 11
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
Fix #971: Add column for signature metadata #985
Conversation
jandusil
commented
Aug 24, 2023
- Add new column signature_metadata, remove merged columns signature_data_method and signature_data_uri_id, document it in liquibase
- Edit entity class, introduce new converter
- Add new column signature_metadata, remove merged columns signature_data_method and signature_data_uri_id, document it in liquibase - Edit entity class, introduce new converter
- Propagate changes
- Add NoArgsConstructor
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.
Good job. Let's review the Liquibase script, because it will not work on other databases such as Oracle.
...ngelog/changesets/powerauth-java-server/1.5.x/20230824-update-signature-metadata-columns.xml
Outdated
Show resolved
Hide resolved
...tlime/security/powerauth/app/server/database/model/converter/SignatureMetadataConverter.java
Show resolved
Hide resolved
- Make the change retrospective in terms of liquibase
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.
Please let's introduce abstraction on signature metadata types. We currently need to have only PowerAuth signature metadata with method and URI ID, but the reason we are making this change is that next release, we will also need to have FIDO2 signature metadata with completely different attributes.
As a result, we need to introduce facilities that allow serialization / deserialization of the specific classes.
...src/main/java/io/getlime/security/powerauth/app/server/database/model/SignatureMetadata.java
Outdated
Show resolved
Hide resolved
...src/main/java/io/getlime/security/powerauth/app/server/database/model/SignatureMetadata.java
Outdated
Show resolved
Hide resolved
...src/main/java/io/getlime/security/powerauth/app/server/database/model/SignatureMetadata.java
Outdated
Show resolved
Hide resolved
...io/getlime/security/powerauth/app/server/service/behavior/tasks/AuditingServiceBehavior.java
Outdated
Show resolved
Hide resolved
- Introduce abstraction for SignatureMetadata
- Add a test - Introduce more generic approach
signatureAuditRecord.setActivation(activationRepository.getReferenceById(activation.getActivationId())); | ||
signatureAuditRecord.setActivationCounter(activation.getCounter()); | ||
signatureAuditRecord.setActivationCtrDataBase64(activation.getCtrDataBase64()); | ||
signatureAuditRecord.setActivationStatus(activation.getActivationStatus()); | ||
signatureAuditRecord.setAdditionalInfo(additionalInfo); | ||
signatureAuditRecord.setDataBase64(data); | ||
signatureAuditRecord.setSignature(signatureData.getSignature()); | ||
signatureAuditRecord.setSignatureDataMethod(signatureData.getRequestMethod()); | ||
signatureAuditRecord.setSignatureDataUriId(signatureData.getRequestUriId()); | ||
signatureAuditRecord.setSignatureMetadata(signatureMetadata); |
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.
Do we want to adjust the AuditDetail as well? Probably yes, right?
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.
How do you mean it?
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.
Yes, we need to store it in the audit record too. 👍
- Add a test - Introduce more generic approach
.../changelog/changesets/powerauth-java-server/1.5.x/20230323-add-column-signature-metadata.xml
Outdated
Show resolved
Hide resolved
...tlime/security/powerauth/app/server/database/model/converter/SignatureMetadataConverter.java
Outdated
Show resolved
Hide resolved
...tlime/security/powerauth/app/server/database/model/converter/SignatureMetadataConverter.java
Outdated
Show resolved
Hide resolved
...java/io/getlime/security/powerauth/app/server/database/model/PowerAuthSignatureMetadata.java
Outdated
Show resolved
Hide resolved
...me/security/powerauth/app/server/service/model/signature/SignatureMetadataConverterTest.java
Outdated
Show resolved
Hide resolved
...me/security/powerauth/app/server/service/model/signature/SignatureMetadataConverterTest.java
Outdated
Show resolved
Hide resolved
...me/security/powerauth/app/server/service/model/signature/SignatureMetadataConverterTest.java
Show resolved
Hide resolved
...java/io/getlime/security/powerauth/app/server/database/model/PowerAuthSignatureMetadata.java
Outdated
Show resolved
Hide resolved
...src/main/java/io/getlime/security/powerauth/app/server/database/model/SignatureMetadata.java
Outdated
Show resolved
Hide resolved
- Change type of signature_metadata to clob - Incorporate code review comments
- Incorporate code review comments
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.
It should work as expected, however I suggest we improve the types. In my opinion there is no need to use the ?
(any type) in generics, or am I missing something? E.g. we know the resulting value in DB is a String.
.../getlime/security/powerauth/app/server/database/model/enumeration/SignatureMetadataType.java
Outdated
Show resolved
Hide resolved
@Converter | ||
@Component | ||
@Slf4j | ||
public class SignatureMetadataConverter implements AttributeConverter<SignatureMetadata<?, ?>, String> { |
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.
Why do we use the <?, ?>
type specification?
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.
My general idea was that this converter could be used for different types of SignatureMetadata implementations not just the SignatureMetadata<String, String>. Since the props of implementations of SignatureMetadata could be different types, I thought the <?, ?>
type specification shall be here.
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.
What are these types which are specified instead of <?, ?>
used for? I can't find it in the code. Do we really need to make the class SignatureMetadata
generic? What happens if you remove <?, ?>
type specification from the 3 places where it is used, will the code still work?
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.
I think we can safely say that <String, Object>
will work for us. This allows for a fairly generic way of serialization. Apologies for not specifying this clearer.
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.
In current code the usage of generics is really strange. See the following message from IntelliJ IDEA:
My point is that we specify types for a generified class SignatureMetadata
, however these types are never used, so they just make the code more complicated for no good reason. If you remove the <T1, T2>
and <?, ?>
types everywhere from the code for the SignatureMetadata
, the tests are still green, so why do we need this generification in the first place?
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.
I guess that it's just a leftover from the previous version, where there used to be such code
T1 getMetadataParam1();
.../getlime/security/powerauth/app/server/database/model/enumeration/SignatureMetadataType.java
Show resolved
Hide resolved
- Incorporate code review comments
@AllArgsConstructor | ||
@NoArgsConstructor | ||
@Data | ||
public class PowerAuthSignatureMetadata implements SignatureMetadata<String, String>, Serializable { |
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.
Apologies for the change, but just in case, let's make this <String, Object>
- I can imagine we would like to encode some FIDO2 specific data and this could require structure to be comprehensive and easy to deserialize back...
@Converter | ||
@Component | ||
@Slf4j | ||
public class SignatureMetadataConverter implements AttributeConverter<SignatureMetadata<?, ?>, String> { |
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.
I think we can safely say that <String, Object>
will work for us. This allows for a fairly generic way of serialization. Apologies for not specifying this clearer.
* @return The JSON string representation of the object. | ||
*/ | ||
@Override | ||
public String convertToDatabaseColumn(SignatureMetadata<?, ?> attribute) { |
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.
dtto
* @return The converted SignatureMetadata object. | ||
*/ | ||
@Override | ||
public SignatureMetadata<?, ?> convertToEntityAttribute(String s) { |
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.
dtto
* Represents PowerAuth signature metadata. | ||
* This value is used for identifying the type of metadata in JSON serialization/deserialization. | ||
*/ | ||
public static final String POWERAUTH = "PowerAuthSignatureMetadata"; |
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.
Since this will get serialized into the JSON payload, we should use just POWERAUTH
. Also, are we sure this will get into the serialized JSON? We need to be able to deserialize it back...
signatureAuditRecord.setActivation(activationRepository.getReferenceById(activation.getActivationId())); | ||
signatureAuditRecord.setActivationCounter(activation.getCounter()); | ||
signatureAuditRecord.setActivationCtrDataBase64(activation.getCtrDataBase64()); | ||
signatureAuditRecord.setActivationStatus(activation.getActivationStatus()); | ||
signatureAuditRecord.setAdditionalInfo(additionalInfo); | ||
signatureAuditRecord.setDataBase64(data); | ||
signatureAuditRecord.setSignature(signatureData.getSignature()); | ||
signatureAuditRecord.setSignatureDataMethod(signatureData.getRequestMethod()); | ||
signatureAuditRecord.setSignatureDataUriId(signatureData.getRequestUriId()); | ||
signatureAuditRecord.setSignatureMetadata(signatureMetadata); |
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.
Yes, we need to store it in the audit record too. 👍
@JsonSubTypes.Type(value = PowerAuthSignatureMetadata.class, | ||
name = SignatureMetadataType.POWERAUTH) | ||
}) | ||
public interface SignatureMetadata<T1, T2> extends Serializable { |
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.
Where do we keep the type
property? We need to have it somewhere so that we are able to deserialize the value back...
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.
I believe the type is dynamically added by the annotation during serialization
res: https://www.baeldung.com/jackson-inheritance#bd-1-conversion-between-subtypes
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = PowerAuthSignatureMetadata.class,
name = SignatureMetadataType.POWERAUTH)
})
Works in the tests I wrote
@Test
void convertToDatabaseColumnTest() {
PowerAuthSignatureMetadata metadata = new PowerAuthSignatureMetadata("POST", "123");
String jsonStr = converter.convertToDatabaseColumn(metadata);
assertNotNull(jsonStr);
assertEquals("{\"type\":\"POWERAUTH\",\"signatureDataMethod\":\"POST\",\"signatureDataUriId\":\"123\"}", jsonStr);
}
- Incorporate code review comments
- Remove generics
- Remove redundant extension
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.
Looks OK now
...java/io/getlime/security/powerauth/app/server/database/model/PowerAuthSignatureMetadata.java
Show resolved
Hide resolved
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.
Much better now!
- Add serialVersionUID