Skip to content
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

Merged
merged 15 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<changeSet id="1" logicalFilePath="powerauth-java-server/1.5.x/20230323-add-column-signature-metadata" author="Lubos Racansky">
<preConditions onFail="MARK_RAN">
<not>
<columnExists tableName="pa_signature_audit" columnName="signature_metadata"/>
</not>
</preConditions>
<comment>Add signature_metadata column of type JSONB</comment>
<addColumn tableName="pa_signature_audit">
<column name="signature_metadata" type="JSONB"/>
jandusil marked this conversation as resolved.
Show resolved Hide resolved
</addColumn>
</changeSet>

</databaseChangeLog>

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<include file="20230323-add-columns-signature-data.xml" relativeToChangelogFile="true" />
<include file="20230323-add-column-signature-metadata.xml" relativeToChangelogFile="true" />
<include file="20230426-add-column-totp-seed.xml" relativeToChangelogFile="true" />
<include file="20230723-add-table-unique-value.xml" relativeToChangelogFile="true" />

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.getlime.security.powerauth.app.server.database.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class SignatureMetadata {
jandusil marked this conversation as resolved.
Show resolved Hide resolved
jandusil marked this conversation as resolved.
Show resolved Hide resolved
jandusil marked this conversation as resolved.
Show resolved Hide resolved

private String signatureDataMethod;

private String signatureDataUriId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* PowerAuth Server and related software components
* Copyright (C) 2023 Wultra s.r.o.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package io.getlime.security.powerauth.app.server.database.model.converter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.getlime.security.powerauth.app.server.database.model.SignatureMetadata;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* Converts between SignatureMetadata object and JSON serialized
* storage in database column.
*
* @author Your Name
*/
@Converter
@Component
public class SignatureMetadataConverter implements AttributeConverter<SignatureMetadata, String> {

private static final Logger logger = LoggerFactory.getLogger(SignatureMetadataConverter.class);
jandusil marked this conversation as resolved.
Show resolved Hide resolved

private final ObjectMapper objectMapper;

/**
* Converter constructor.
* @param objectMapper Object mapper.
*/
@Autowired
public SignatureMetadataConverter(ObjectMapper objectMapper) {
jandusil marked this conversation as resolved.
Show resolved Hide resolved
this.objectMapper = objectMapper;
}

@Override
public String convertToDatabaseColumn(SignatureMetadata signatureMetadata) {
if (signatureMetadata == null) {
return "{}";
}
try {
return objectMapper.writeValueAsString(signatureMetadata);
} catch (JsonProcessingException ex) {
logger.warn("Conversion failed for SignatureMetadata, error: " + ex.getMessage(), ex);
return "{}";
}
}

@Override
public SignatureMetadata convertToEntityAttribute(String s) {
if (s == null || s.isEmpty()) {
jandusil marked this conversation as resolved.
Show resolved Hide resolved
return new SignatureMetadata();
}
try {
return objectMapper.readValue(s, SignatureMetadata.class);
} catch (JsonProcessingException ex) {
logger.warn("Conversion failed for SignatureMetadata, error: " + ex.getMessage(), ex);
return new SignatureMetadata();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
*/
package io.getlime.security.powerauth.app.server.database.model.entity;

import io.getlime.security.powerauth.app.server.database.model.SignatureMetadata;
import io.getlime.security.powerauth.app.server.database.model.converter.ActivationStatusConverter;
import io.getlime.security.powerauth.app.server.database.model.converter.SignatureMetadataConverter;
import io.getlime.security.powerauth.app.server.database.model.enumeration.ActivationStatus;
import jakarta.persistence.*;

Expand Down Expand Up @@ -73,11 +75,9 @@ public class SignatureEntity implements Serializable {
@Column(name = "signature", nullable = false, updatable = false)
private String signature;

@Column(name = "signature_data_method", updatable = false)
private String signatureDataMethod;

@Column(name = "signature_data_uri_id", updatable = false)
private String signatureDataUriId;
@Column(name = "signature_metadata")
@Convert(converter = SignatureMetadataConverter.class)
private SignatureMetadata signatureMetadata;

@Column(name = "signature_data_body", updatable = false)
private String signatureDataBody;
Expand All @@ -104,21 +104,21 @@ public SignatureEntity() {
* Constructor with all properties.
*
* @param id Signature audit item record ID.
* @param activation Associated activation, or null of no related activation was found.
* @param activation Associated activation, or null if no related activation was found.
* @param activationCounter Activation counter at the time of signature computation attempt, or 0 if activation is null.
* @param activationCtrDataBase64 Activation counter data at the time of signature computation attempt, or null if only numeric counter is used.
* @param activationStatus Activation status at the time of signature computation attempt.
* @param dataBase64 Data that were sent alongside the signature.
* @param signatureVersion Requested signature version.
* @param signatureType Requested signature type.
* @param signature Signature value.
* @param signatureDataMethod Signature data method.
* @param signatureDataUriId Signature data URI identifier.
* @param signatureMetadata Metadata related to the signature.
* @param signatureDataBody Signature data body.
* @param additionalInfo Additional information related to this signature.
* @param note Signature audit log note, with more information about the log reason.
* @param valid True if the signature was valid, false otherwise.
* @param timestampCreated Created timestapm.
* @param timestampCreated Created timestamp.
* @param version Version of the signature entity.
*/
public SignatureEntity(
Long id,
Expand All @@ -130,8 +130,7 @@ public SignatureEntity(
String signatureVersion,
String signatureType,
String signature,
String signatureDataMethod,
String signatureDataUriId,
SignatureMetadata signatureMetadata,
String signatureDataBody,
String additionalInfo,
String note,
Expand All @@ -148,8 +147,7 @@ public SignatureEntity(
this.signatureVersion = signatureVersion;
this.signatureType = signatureType;
this.signature = signature;
this.signatureDataMethod = signatureDataMethod;
this.signatureDataUriId = signatureDataUriId;
this.signatureMetadata = signatureMetadata;
this.signatureDataBody = signatureDataBody;
this.additionalInfo = additionalInfo;
this.note = note;
Expand Down Expand Up @@ -337,39 +335,21 @@ public void setSignature(String signature) {
}

/**
* Get signature data HTTP method.
* Get the signature metadata associated with this signature.
*
* @return Signature data HTTP method.
* @return Signature metadata.
*/
public String getSignatureDataMethod() {
return signatureDataMethod;
public SignatureMetadata getSignatureMetadata() {
return signatureMetadata;
}

/**
* Set signature data HTTP method.
* Set the signature metadata associated with this signature.
*
* @param signatureDataMethod Signature data HTTP method.
* @param signatureMetadata Metadata related to the signature.
*/
public void setSignatureDataMethod(String signatureDataMethod) {
this.signatureDataMethod = signatureDataMethod;
}

/**
* Get signature data resource URI identifier.
*
* @return Signature data resource URI identifier.
*/
public String getSignatureDataUriId() {
return signatureDataUriId;
}

/**
* Set signature data resource URI identifier.
*
* @param signatureDataUriId Signature data URI identifier.
*/
public void setSignatureDataUriId(String signatureDataUriId) {
this.signatureDataUriId = signatureDataUriId;
public void setSignatureMetadata(SignatureMetadata signatureMetadata) {
this.signatureMetadata = signatureMetadata;
}

/**
Expand Down Expand Up @@ -468,8 +448,7 @@ public int hashCode() {
hash = 23 * hash + Objects.hashCode(this.dataBase64);
hash = 23 * hash + Objects.hashCode(this.signatureType);
hash = 23 * hash + Objects.hashCode(this.signature);
hash = 23 * hash + Objects.hashCode(this.signatureDataMethod);
hash = 23 * hash + Objects.hashCode(this.signatureDataUriId);
hash = 23 * hash + Objects.hashCode(this.signatureMetadata);
hash = 23 * hash + Objects.hashCode(this.signatureDataBody);
hash = 23 * hash + Objects.hashCode(this.additionalInfo);
hash = 23 * hash + Objects.hashCode(this.note);
Expand Down Expand Up @@ -500,10 +479,7 @@ public boolean equals(Object obj) {
if (!Objects.equals(this.signature, other.signature)) {
return false;
}
if (!Objects.equals(this.signatureDataMethod, other.signatureDataMethod)) {
return false;
}
if (!Objects.equals(this.signatureDataUriId, other.signatureDataUriId)) {
if (!Objects.equals(this.signatureMetadata, other.signatureMetadata)) {
return false;
}
if (!Objects.equals(this.signatureDataBody, other.signatureDataBody)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import io.getlime.security.powerauth.app.server.converter.ActivationStatusConverter;
import io.getlime.security.powerauth.app.server.converter.KeyValueMapConverter;
import io.getlime.security.powerauth.app.server.converter.SignatureTypeConverter;
import io.getlime.security.powerauth.app.server.database.model.SignatureMetadata;
import io.getlime.security.powerauth.app.server.database.model.entity.ActivationRecordEntity;
import io.getlime.security.powerauth.app.server.database.model.entity.SignatureEntity;
import io.getlime.security.powerauth.app.server.database.model.enumeration.ActivationStatus;
Expand Down Expand Up @@ -157,15 +158,15 @@ public void logSignatureAuditRecord(ActivationRecordDto activation, SignatureDat

// Audit the signature
final SignatureEntity signatureAuditRecord = new SignatureEntity();
final SignatureMetadata signatureMetadata = new SignatureMetadata(signatureData.getRequestMethod(), signatureData.getRequestUriId());
jandusil marked this conversation as resolved.
Show resolved Hide resolved
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);
Copy link
Contributor Author

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?

Copy link
Member

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?

Copy link
Member

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. 👍

signatureAuditRecord.setSignatureDataBody(signatureData.getRequestBody());
signatureAuditRecord.setSignatureType(signatureType.name());
signatureAuditRecord.setSignatureVersion(signatureData.getSignatureVersion());
Expand Down