Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
@@ -1,9 +1,9 @@
package com.github.binarywang.wxpay.bean.ecommerce;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;

Expand All @@ -13,30 +13,124 @@
*
* @author cloudX
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Deprecated
public class SignatureHeader implements Serializable {
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = false)
public class SignatureHeader extends com.github.binarywang.wxpay.bean.notify.SignatureHeader implements Serializable {
Comment thread
binarywang marked this conversation as resolved.
Comment thread
binarywang marked this conversation as resolved.
Comment thread
binarywang marked this conversation as resolved.
Comment thread
binarywang marked this conversation as resolved.
Comment thread
binarywang marked this conversation as resolved.
private static final long serialVersionUID = -6958015499416059949L;

/**
* 已签名字符串
*/
private String signed;

/**
* 证书序列号
*/
private String serialNo;

/**
* 时间戳
* 保留在旧类中的序列化字段,避免升级后反序列化旧数据时丢失。
*/
private String timeStamp;

/**
* 随机串
* 保留在旧类中的序列化字段,避免升级后反序列化旧数据时丢失。
*/
private String nonce;

public SignatureHeader() {
super();
}

/**
* 已签名字符串
* 保留 4.8.4 及以前版本的构造器签名。
*/
private String signed;
public SignatureHeader(String timeStamp, String nonce, String signed, String serialNo) {
setTimeStamp(timeStamp);
setNonce(nonce);
this.signed = signed;
this.serialNo = serialNo;
}

private SignatureHeader(SignatureHeaderBuilder builder) {
super(builder);
this.timeStamp = builder.timeStamp;
this.nonce = builder.nonce;
this.signed = builder.signed;
this.serialNo = builder.serialNo;
}

@Override
public String getTimeStamp() {
return this.timeStamp;
}

@Override
public void setTimeStamp(String timeStamp) {
super.setTimeStamp(timeStamp);
this.timeStamp = timeStamp;
}

@Override
public String getNonce() {
return this.nonce;
}

@Override
public void setNonce(String nonce) {
super.setNonce(nonce);
this.nonce = nonce;
}

/**
* 证书序列号
* 保留旧版 builder 的类型和方法返回值描述符。
*/
private String serialNo;
public static SignatureHeaderBuilder builder() {
return new SignatureHeaderBuilder();
}

public static class SignatureHeaderBuilder extends com.github.binarywang.wxpay.bean.notify.SignatureHeader
.SignatureHeaderBuilder<SignatureHeader, SignatureHeaderBuilder> {
private String timeStamp;
private String nonce;
private String signed;
private String serialNo;

@Override
public SignatureHeaderBuilder timeStamp(String timeStamp) {
super.timeStamp(timeStamp);
this.timeStamp = timeStamp;
return this;
}

@Override
public SignatureHeaderBuilder nonce(String nonce) {
super.nonce(nonce);
this.nonce = nonce;
return this;
}

public SignatureHeaderBuilder signed(String signed) {
this.signed = signed;
return this;
}

public SignatureHeaderBuilder serialNo(String serialNo) {
this.serialNo = serialNo;
return this;
}

@Override
protected SignatureHeaderBuilder self() {
return this;
}

@Override
public SignatureHeader build() {
return new SignatureHeader(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.github.binarywang.wxpay.bean.notify;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;

Expand All @@ -14,7 +14,7 @@
* @author thinstar
*/
@Data
@Builder
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class SignatureHeader implements Serializable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.util.Base64;

/**
* Compile-time compatibility checks for the pre-#4014 e-commerce API.
* Compatibility checks for the pre-#4014 e-commerce API.
*/
public class LegacyEcommerceApiCompatibilityTest {

Expand All @@ -25,4 +29,61 @@ public void shouldKeepLegacyRefundAndWithdrawNotificationSignatures() throws Exc
Assert.assertNotNull(EcommerceService.class.getMethod("parseRefundNotifyResult", String.class, legacyHeader));
Assert.assertNotNull(EcommerceService.class.getMethod("parseWithdrawNotifyResult", String.class, legacyHeader));
}

@Test
public void shouldKeepLegacySignatureHeaderConstructorAndBuilderAbi() throws Exception {
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader legacyHeader =
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.builder()
.timeStamp("timestamp")
.nonce("nonce")
.signed("signed")
.serialNo("serial-no")
.build();

Assert.assertNotNull(com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.class.getConstructor(
String.class, String.class, String.class, String.class));
Assert.assertEquals(com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.SignatureHeaderBuilder.class,
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.SignatureHeaderBuilder.class
.getMethod("timeStamp", String.class).getReturnType());
Assert.assertEquals(com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.SignatureHeaderBuilder.class,
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader.SignatureHeaderBuilder.class
.getMethod("nonce", String.class).getReturnType());
Assert.assertTrue(com.github.binarywang.wxpay.bean.notify.SignatureHeader.class
.isAssignableFrom(legacyHeader.getClass()));
com.github.binarywang.wxpay.bean.notify.SignatureHeader unifiedHeader =
EcommerceService.toUnifiedSignatureHeader(legacyHeader);
Assert.assertEquals(unifiedHeader.getTimeStamp(), "timestamp");
Assert.assertEquals(unifiedHeader.getNonce(), "nonce");
Assert.assertEquals(unifiedHeader.getSignature(), "signed");
Assert.assertEquals(unifiedHeader.getSerial(), "serial-no");
}

@Test
public void shouldIncludeTimestampAndNonceInLegacyHeaderEquality() {
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader first =
new com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader("timestamp-1", "nonce", "signed", "serial-no");
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader second =
new com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader("timestamp-2", "nonce", "signed", "serial-no");

Assert.assertNotEquals(first, second);
}

@Test
public void shouldReadLegacySerializedHeaderFields() throws Exception {
String legacySerializedHeader = "rO0ABXNyADpjb20uZ2l0aHViLmJpbmFyeXdhbmcud3hwYXkuYmVhbi5lY29tbWVyY2UuU2lnbmF0dXJlSGVhZGVyn3ApxLekv9MCAARMAAVub25jZXQAEkxqYXZhL2xhbmcvU3RyaW5nO0wACHNlcmlhbE5vcQB+AAFMAAZzaWduZWRxAH4AAUwACXRpbWVTdGFtcHEAfgABeHB0AAVub25jZXQACXNlcmlhbC1ub3QABnNpZ25lZHQACXRpbWVzdGFtcA==";
ObjectInputStream input = new ObjectInputStream(new ByteArrayInputStream(
Base64.getDecoder().decode(legacySerializedHeader)));
com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader header =
(com.github.binarywang.wxpay.bean.ecommerce.SignatureHeader) input.readObject();

Assert.assertEquals(header.getTimeStamp(), "timestamp");
Assert.assertEquals(header.getNonce(), "nonce");
Assert.assertEquals(header.getSigned(), "signed");
Assert.assertEquals(header.getSerialNo(), "serial-no");
}

private void shouldCompileNullNotificationHeaderCalls(EcommerceService ecommerceService) throws Exception {
ecommerceService.parseRefundNotifyResult("notify-data", null);
ecommerceService.parseWithdrawNotifyResult("notify-data", null);
}
}