Skip to content

Commit

Permalink
chore: Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tikhop authored Jan 24, 2024
2 parents 3638505 + d49388d commit 2b3646e
Show file tree
Hide file tree
Showing 28 changed files with 742 additions and 53 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,4 @@ base64 = "0.21.7"
# Utils
thiserror = "1.0.56"

[dev-dependencies]
dotenv = "0.15.0"

13 changes: 13 additions & 0 deletions assets/appTransaction.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"receiptType": "LocalTesting",
"appAppleId": 531412,
"bundleId": "com.example",
"applicationVersion": "1.2.3",
"versionExternalIdentifier": 512,
"receiptCreationDate": 1698148900000,
"originalPurchaseDate": 1698148800000,
"originalApplicationVersion": "1.1.2",
"deviceVerification": "device_verification_value",
"deviceVerificationNonce": "48ccfa42-7431-4f22-9908-7e88983e105a",
"preorderDate": 1698148700000
}
16 changes: 16 additions & 0 deletions assets/signedNotification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"notificationType": "SUBSCRIBED",
"subtype": "INITIAL_BUY",
"notificationUUID": "002e14d5-51f5-4503-b5a8-c3a1af68eb20",
"data": {
"environment": "LocalTesting",
"appAppleId": 41234,
"bundleId": "com.example",
"bundleVersion": "1.2.3",
"signedTransactionInfo": "signed_transaction_info_value",
"signedRenewalInfo": "signed_renewal_info_value",
"status": 1
},
"version": "2.0",
"signedDate": 1698148900000
}
16 changes: 16 additions & 0 deletions assets/signedRenewalInfo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"expirationIntent": 1,
"originalTransactionId": "12345",
"autoRenewProductId": "com.example.product.2",
"productId": "com.example.product",
"autoRenewStatus": 1,
"isInBillingRetryPeriod": true,
"priceIncreaseStatus": 0,
"gracePeriodExpiresDate": 1698148900000,
"offerType": 2,
"offerIdentifier": "abc.123",
"signedDate": 1698148800000,
"environment": "LocalTesting",
"recentSubscriptionStartDate": 1698148800000,
"renewalDate": 1698148850000
}
21 changes: 21 additions & 0 deletions assets/signedSummaryNotification.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"notificationType": "RENEWAL_EXTENSION",
"subtype": "SUMMARY",
"notificationUUID": "002e14d5-51f5-4503-b5a8-c3a1af68eb20",
"version": "2.0",
"signedDate": 1698148900000,
"summary": {
"environment": "LocalTesting",
"appAppleId": 41234,
"bundleId": "com.example",
"productId": "com.example.product",
"requestIdentifier": "efb27071-45a4-4aca-9854-2a1e9146f265",
"storefrontCountryCodes": [
"CAN",
"USA",
"MEX"
],
"succeededCount": 5,
"failedCount": 2
}
}
28 changes: 28 additions & 0 deletions assets/signedTransaction.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"transactionId":"23456",
"originalTransactionId":"12345",
"webOrderLineItemId":"34343",
"bundleId":"com.example",
"productId":"com.example.product",
"subscriptionGroupIdentifier":"55555",
"purchaseDate":1698148900000,
"originalPurchaseDate":1698148800000,
"expiresDate":1698149000000,
"quantity":1,
"type":"Auto-Renewable Subscription",
"appAccountToken": "7e3fb20b-4cdb-47cc-936d-99d65f608138",
"inAppOwnershipType":"PURCHASED",
"signedDate":1698148900000,
"revocationReason": 1,
"revocationDate": 1698148950000,
"isUpgraded": true,
"offerType":1,
"offerIdentifier": "abc.123",
"environment":"LocalTesting",
"transactionReason":"PURCHASE",
"storefront":"USA",
"storefrontId":"143441",
"price": 10990,
"currency": "USD",
"offerDiscountType": "PAY_AS_YOU_GO"
}
32 changes: 20 additions & 12 deletions src/chain_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub fn verify_chain(
};
let leaf_certificate = leaf_certificate.1;

let Some(_) = leaf_certificate.get_extension_unique(&oid!(1.2.840 .113635 .100 .6 .11 .1))?
let Some(_) = leaf_certificate.get_extension_unique(&oid!(1.2.840.113635.100.6.11.1))?
else {
return Err(ChainVerifierError::VerificationFailure(InvalidCertificate));
};
Expand All @@ -113,7 +113,7 @@ pub fn verify_chain(
let intermediate_certificate = intermediate_certificate.1;

let Some(_) =
intermediate_certificate.get_extension_unique(&oid!(1.2.840 .113635 .100 .6 .2 .1))?
intermediate_certificate.get_extension_unique(&oid!(1.2.840.113635.100.6.2.1))?
else {
return Err(ChainVerifierError::VerificationFailure(InvalidCertificate));
};
Expand Down Expand Up @@ -164,15 +164,6 @@ mod tests {
use crate::utils::StringExt;
use base64::engine::general_purpose::STANDARD;
use base64::{DecodeError, Engine};

pub fn signed_payload() -> String {
std::env::var("SIGNED_PAYLOAD").expect("SIGNED_PAYLOAD must be set")
}

pub fn apple_root_cert() -> String {
std::env::var("APPLE_ROOT_BASE64_ENCODED").expect("APPLE_ROOT_BASE64_ENCODED must be set")
}

extern crate base64;

use x509_parser::error::X509Error::SignatureVerificationError;
Expand Down Expand Up @@ -210,7 +201,9 @@ mod tests {
#[test]
fn test_valid_chain_invalid_intermediate_oid_without_ocsp() -> Result<(), ChainVerifierError> {
let root = ROOT_CA_BASE64_ENCODED.as_der_bytes().unwrap();
let leaf = LEAF_CERT_BASE64_ENCODED.as_der_bytes().unwrap();
let leaf = LEAF_CERT_FOR_INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED
.as_der_bytes()
.unwrap();
let intermediate = INTERMEDIATE_CA_INVALID_OID_BASE64_ENCODED
.as_der_bytes()
.unwrap();
Expand Down Expand Up @@ -326,4 +319,19 @@ mod tests {
);
Ok(())
}

#[test]
fn test_apple_chain_is_valid() -> Result<(), ChainVerifierError> {
let root = REAL_APPLE_ROOT_BASE64_ENCODED.as_der_bytes().unwrap();
let leaf = REAL_APPLE_SIGNING_CERTIFICATE_BASE64_ENCODED
.as_der_bytes()
.unwrap();
let intermediate = REAL_APPLE_INTERMEDIATE_BASE64_ENCODED
.as_der_bytes()
.unwrap();
let chain = vec![leaf.clone(), intermediate, root.clone()];

let _public_key = verify_chain(&chain, &vec![root], Some(EFFECTIVE_DATE)).unwrap();
Ok(())
}
}
2 changes: 1 addition & 1 deletion src/primitives/account_tenure.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The age of the customer’s account.
///
Expand Down
1 change: 0 additions & 1 deletion src/primitives/app_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ pub struct AppTransaction {
}

impl AppTransaction {

/// The date that the App Store signed the JWS app transaction.
/// [signedDate](https://developer.apple.com/documentation/storekit/apptransaction/3954449-signeddate)
pub fn signed_date(&self) -> Option<DateTime<Utc>> {
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/auto_renew_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The renewal status for an auto-renewable subscription.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/consumption_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates the extent to which the customer consumed the in-app purchase.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/delivery_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates whether the app successfully delivered an in-app purchase that works properly.
///
Expand Down
4 changes: 4 additions & 0 deletions src/primitives/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ pub enum Environment {
Sandbox,
#[serde(rename = "Production")]
Production,
#[serde(rename = "Xcode")]
Xcode,
#[serde(rename = "LocalTesting")]
LocalTesting,
}
2 changes: 1 addition & 1 deletion src/primitives/expiration_intent.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The reason an auto-renewable subscription expired.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/extend_reason_code.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The code that represents the reason for the subscription-renewal-date extension.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/jws_renewal_info_decoded_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use crate::primitives::expiration_intent::ExpirationIntent;
use crate::primitives::offer_type::OfferType;
use crate::primitives::price_increase_status::PriceIncreaseStatus;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_with::formats::Flexible;
use serde_with::TimestampMilliSeconds;
use serde::{Deserialize, Serialize};

/// A decoded payload containing subscription renewal information for an auto-renewable subscription.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/lifetime_dollars_purchased.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates the total amount, in USD, of in-app purchases the customer has made in your app, across all platforms.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/lifetime_dollars_refunded.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates the dollar amount of refunds the customer has received in your app, since purchasing the app, across all platforms.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/offer_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The type of subscription offer.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/order_lookup_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates whether the order ID in the request is valid for your app.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/platform.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The platform on which the customer consumed the in-app purchase.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/play_time.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// A value that indicates the amount of time that the customer used the app.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/price_increase_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The status that indicates whether an auto-renewable subscription is subject to a price increase.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/revocation_reason.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The reason for a refunded transaction.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

/// The status of an auto-renewable subscription.
///
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/user_status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use serde_repr::{Serialize_repr, Deserialize_repr};
use serde_repr::{Deserialize_repr, Serialize_repr};

#[derive(Debug, Clone, Deserialize_repr, Serialize_repr, Hash, PartialEq, Eq)]
#[repr(u8)]
Expand Down
Loading

0 comments on commit 2b3646e

Please sign in to comment.