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

HTTPClient: added support for sending X-Nonce #2214

Merged
merged 9 commits into from
Feb 8, 2023

Conversation

NachoSoto
Copy link
Contributor

@NachoSoto NachoSoto commented Jan 13, 2023

Fixes CSDK-631.

@NachoSoto NachoSoto requested a review from a team January 13, 2023 23:58
Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's looking good!

Sources/Networking/HTTPClient/HTTPClient.swift Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Feb 2, 2023

Codecov Report

Merging #2214 (bc52a3b) into main (cf3090a) will decrease coverage by 0.08%.
The diff coverage is 100.00%.

❗ Current head bc52a3b differs from pull request most recent head 5ab771e. Consider uploading reports for the commit 5ab771e to get more accurate results

@@            Coverage Diff             @@
##             main    #2214      +/-   ##
==========================================
- Coverage   85.96%   85.89%   -0.08%     
==========================================
  Files         184      183       -1     
  Lines       12121    12152      +31     
==========================================
+ Hits        10420    10438      +18     
- Misses       1701     1714      +13     
Impacted Files Coverage Δ
Sources/Networking/HTTPClient/HTTPClient.swift 94.21% <100.00%> (-3.99%) ⬇️
Sources/Networking/HTTPClient/HTTPRequest.swift 100.00% <100.00%> (ø)
...s/Logging/Strings/ManageSubscriptionsStrings.swift 75.00% <0.00%> (-6.25%) ⬇️
Sources/Support/ManageSubscriptionsHelper.swift 68.04% <0.00%> (-2.07%) ⬇️
Sources/Logging/Strings/NetworkStrings.swift 98.36% <0.00%> (-1.64%) ⬇️
...ources/Purchasing/IntroEligibilityCalculator.swift 100.00% <0.00%> (ø)
...chasing/StoreKitAbstractions/SK2StoreProduct.swift 96.72% <0.00%> (ø)
Sources/Misc/Box.swift
...hasing/StoreKit2/StoreKit2StorefrontListener.swift 100.00% <0.00%> (+13.63%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@NachoSoto NachoSoto requested review from aboedo and tonidero and removed request for aboedo February 6, 2023 19:29
@NachoSoto NachoSoto removed the blocked label Feb 6, 2023
@NachoSoto
Copy link
Contributor Author

Okay finished this. The new implementation uses the term "nonce" everywhere, and I added a test that ensures that the format matches the python tests, using the same string used there.

@NachoSoto NachoSoto changed the title HTTPClient: added support for sending request UUIDs HTTPClient: added support for sending X-Nonce Feb 6, 2023
@NachoSoto NachoSoto force-pushed the http-client-request-uuid branch 2 times, most recently from 8a4075a to c95b581 Compare February 6, 2023 23:22

private var asUInt8Array: [UInt8] {
// swiftlint:disable:next identifier_name
let (u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15, u16) = self.uuid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I didn't know you could unpack a UUID like this. But it looks good 👍


@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *)
static func randomNonce() -> Data {
return Data(ChaChaPoly.Nonce())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonidero I've updated this implementation with a proper nonce generation algorithm now that the backend will accept 12 bytes (see ecfa437b7f557a57fdf4377b3af27dbf124908cf)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the name 🤣

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want all features to be named like that

}

init(method: Method, path: Path, nonce: Data?) {
assert(nonce == nil || nonce?.count == Data.nonceLength)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tonidero @aboedo thoughts on this? assert only compiles on DEBUG builds so it can help us catch issues in tests. Sending anything other than 12 bytes would fail so might as well catch it early.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm when we deploy the library, we deploy the release version I think right? so this shouldn't affect developers. Also, seems like we've already done that in a few places in the codebase, so I'm ok with it 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pre-built frameworks are release, yeah. But also for people integrating with CocoaPods / SPM, their production builds are release by default.


@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *)
static func randomNonce() -> Data {
return Data(ChaChaPoly.Nonce())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the name 🤣

}

init(method: Method, path: Path, nonce: Data?) {
assert(nonce == nil || nonce?.count == Data.nonceLength)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm when we deploy the library, we deploy the release version I think right? so this shouldn't affect developers. Also, seems like we've already done that in a few places in the codebase, so I'm ok with it 👍

@NachoSoto NachoSoto enabled auto-merge (squash) February 8, 2023 16:55
@NachoSoto NachoSoto merged commit 88a7841 into main Feb 8, 2023
Comment on lines +340 to +346
if self.path.authenticated {
result += authHeaders
}

if let nonce = self.nonce {
result += HTTPClient.nonceHeader(with: nonce)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there any situation where the nonce should be nil but the path.authenticated = true?
If not, we should try to consolidate the conditions and probably log if they're not simultaneously met

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /health endpoint is one example.

Comment on lines +37 to +41
/// Creates an `HTTPRequest` with a `nonce`.
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *)
static func createIntegrityEnforcedRequestRequest(method: Method, path: Path) -> Self {
return .init(method: method, path: path, nonce: Data.randomNonce())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically we're verifying integrity and authenticity and the same time, right? maybe we could have the name reflect that?
also, typo here: RequestRequest

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically we're verifying integrity and authenticity and the same time, right? maybe we could have the name reflect that?

How about HTTPRequest.createWithResponseVerification?

also, typo here: RequestRequest
Thanks 🤦🏻 I noticed that in the next PR, I'll fix it.

@NachoSoto NachoSoto deleted the http-client-request-uuid branch February 8, 2023 18:50
NachoSoto pushed a commit that referenced this pull request Feb 8, 2023
**This is an automatic release.**

### Dependency Updates
* Bump fastlane-plugin-revenuecat_internal from `738f255` to `9255366`
(#2264) via dependabot[bot] (@dependabot[bot])
* Update `Gemfile.lock` (#2254) via Cesar de la Vega (@vegaro)
### Other Changes
* `HTTPClient`: added support for sending `X-Nonce` (#2214) via
NachoSoto (@NachoSoto)
* `Configuration`: added (`internal` for now) API to load public key
(#2215) via NachoSoto (@NachoSoto)
* Replaced `Any` uses for workaround with `Box` (#2250) via NachoSoto
(@NachoSoto)
* `HTTPClientTests`: fixed failing test with missing assertions (#2262)
via NachoSoto (@NachoSoto)
* `HTTPClientTests`: refactored tests to use `waitUntil` (#2257) via
NachoSoto (@NachoSoto)
* PurchaseTester: Add Receipt Inspector UI (#2249) via Andy Boedo
(@aboedo)
* Adds dependabot (#2259) via Cesar de la Vega (@vegaro)
* `StoreKit1WrapperTests`: avoid using `Bool.random` to fix flaky code
coverage (#2258) via NachoSoto (@NachoSoto)
* `IntroEligibilityCalculator`: changed logic to handle products with no
subscription group (#2247) via NachoSoto (@NachoSoto)
NachoSoto added a commit that referenced this pull request Feb 16, 2023
…2267)

⚠️ 🎉 This also changes integration tests to use
`EntitlementVerificationLevel.enforced` so that integration tests fail
if signatures are invalid.

#### Depends on:
- https://github.com/RevenueCat/khepri/pull/5191
- https://github.com/RevenueCat/khepri/pull/5204
- #2214
- #2215 
- #2216
- #2272

_Marking this as `feat`ure because it contains a new error in
`PurchasesDiagnostics.Error`_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants