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
8 changes: 6 additions & 2 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ steps:
plugins: [$CI_TOOLKIT]
agents:
queue: mac
- label: ":swift: :linux: Build and Test"
command: ".buildkite/commands/run-swift-tests-linux.sh"
- label: ":swift: Lint"
command: |
.buildkite/download-xcframework.sh
Expand Down Expand Up @@ -254,6 +252,12 @@ steps:
artifact_paths:
- "native/kotlin/api/kotlin/build/test-results/integrationTest/*.xml"

- label: ":wordpress: :swift: WordPress {{matrix}}"
command: ".buildkite/commands/run-swift-tests-linux.sh"
env:
WORDPRESS_VERSION: "{{matrix}}"
matrix: *wordpress_version_matrix

- label: ":rocket: Publish Swift release $NEW_VERSION"
command: .buildkite/release.sh $NEW_VERSION
depends_on: swift
Expand Down
52 changes: 52 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ semver = "1.0"
serde = "1.0"
serde_json = "1.0"
serde_repr = "0.1"
serde_urlencoded = "0.7"
serial_test = "3.2"
strum = "0.27"
strum_macros = "0.27"
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ test-swift:
$(MAKE) test-swift-$(uname)

test-swift-linux:
docker compose run --rm swift make test-swift-linux-in-docker
docker exec -w /app -i wordpress make test-swift-linux-in-docker

test-swift-linux-in-docker: swift-linux-library
swift test -Xlinker -Ltarget/release/libwordpressFFI-linux -Xlinker -lwp_mobile
swift test -Xlinker -Ltarget/release/libwordpressFFI-linux -Xlinker -lwp_mobile --no-parallel

test-swift-darwin: xcframework
swift test
Expand Down
8 changes: 4 additions & 4 deletions Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 1 addition & 12 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
context: .
dockerfile: wordpress.Dockerfile
args:
WORDPRESS_VERSION: ${WORDPRESS_VERSION:-latest}
WORDPRESS_VERSION: ${WORDPRESS_VERSION:-6.8.1}
container_name: 'wordpress'
ports:
- '80:80'
Expand All @@ -30,17 +30,6 @@ services:
timeout: 1s
retries: 30

swift:
build:
context: .
dockerfile: swift.Dockerfile
volumes:
- ./:/app
working_dir: /app
environment:
- TEST_ALL_PLUGINS
- CARGO_HOME=/app/.cargo

database:
image: 'public.ecr.aws/docker/library/mariadb:11.2'
ports:
Expand Down
1 change: 1 addition & 0 deletions integration_test_credentials/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub struct TestCredentials {
pub admin_username: &'static str,
pub admin_password: &'static str,
pub admin_password_uuid: &'static str,
pub admin_account_password: &'static str,
pub subscriber_username: &'static str,
pub subscriber_password: &'static str,
pub subscriber_password_uuid: &'static str,
Expand Down
22 changes: 22 additions & 0 deletions native/swift/Sources/wordpress-api/WordPressLoginClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ public final class WordPressLoginClient: @unchecked Sendable {

private let requestExecutor: SafeRequestExecutor
private let client: UniffiWpLoginClient
private let middleware: MiddlewarePipeline

public convenience init(
urlSession: URLSession,
middleware: MiddlewarePipeline = .default
) {
precondition(urlSession.configuration.httpCookieStorage != nil)
precondition(urlSession.configuration.httpShouldSetCookies == true)
precondition(urlSession.configuration.httpCookieAcceptPolicy != .never)

self.init(requestExecutor: WpRequestExecutor(urlSession: urlSession), middleware: middleware)
}

Expand All @@ -22,6 +27,7 @@ public final class WordPressLoginClient: @unchecked Sendable {
middleware: MiddlewarePipeline = .default
) {
self.requestExecutor = requestExecutor
self.middleware = middleware
self.client = UniffiWpLoginClient(requestExecutor: requestExecutor, middlewarePipeline: middleware)
}

Expand Down Expand Up @@ -60,6 +66,22 @@ public final class WordPressLoginClient: @unchecked Sendable {
public func credentials(from callbackUrl: URL) throws -> WpApiApplicationPasswordDetails {
try extractLoginDetailsFromUrl(url: callbackUrl.absoluteString)
}

public func authenticateTemporarily(
username: String,
password: String,
details: AutoDiscoveryAttemptSuccess
) async throws -> WordPressAPI {
let nonceRetrieval = WpRestNonceRetrieval(details: details, requestExecutor: requestExecutor)
let nonce = try await nonceRetrieval.getNonce(username: username, password: password)
return WordPressAPI(
apiUrlResolver: WpOrgSiteApiUrlResolver(apiRootUrl: details.apiRootUrl),
authenticationProvider: .staticWithAuth(auth: .nonce(nonce: nonce)),
executor: requestExecutor,
middlewarePipeline: middleware,
appNotifier: nil
)
}
}

extension AutoDiscoveryAttemptSuccess {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
import WordPressAPI
import Testing

@Suite
@Suite(.serialized)
struct BlockSettingsTests {
let api = WordPressAPI.admin()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Testing

#if os(macOS)

@Suite(.serialized)
struct CancellationTests {
let api = WordPressAPI.admin()

Expand Down
6 changes: 0 additions & 6 deletions native/swift/Tests/integration-tests/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ import FoundationNetworking
#endif

func restoreTestServer() async throws {
#if os(Linux)
// Integration tests are run in a Docker container, where the test site
// hostname is 'wordpress'.
let url = URL(string: "http://wordpress:4000/restore?db=true&plugins=true")!
#else
let url = URL(string: "http://localhost:4000/restore?db=true&plugins=true")!
#endif
_ = try await URLSession(configuration: .ephemeral).data(from: url)
}

Expand Down
2 changes: 1 addition & 1 deletion native/swift/Tests/integration-tests/MediaTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Foundation
@testable import WordPressAPI
import Testing

@Suite
@Suite(.serialized)
struct MediaTests {
let api = WordPressAPI.admin()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Foundation
import WordPressAPI
import WordPressAPIInternal
import Testing

@Suite(.serialized)
struct NonceAuthenticationTests {

@Test
func success() async throws {
let credentials = TestCredentials.instance()
let client = WordPressLoginClient(urlSession: .init(configuration: .ephemeral))
let details = try await client.details(ofSite: credentials.siteUrl)
let api = try await client.authenticateTemporarily(
username: credentials.adminUsername,
password: credentials.adminAccountPassword,
details: details
)
let loggedIn = try await api.users.retrieveMeWithEditContext().data.username
#expect(loggedIn == credentials.adminUsername)
}

@Test
func signInWithADifferentUser() async throws {
let credentials = TestCredentials.instance()
let client = WordPressLoginClient(urlSession: .init(configuration: .ephemeral))
let details = try await client.details(ofSite: credentials.siteUrl)

// Given the URLSession is already signed in with the admin account.
let api = try await client.authenticateTemporarily(
username: credentials.adminUsername,
password: credentials.adminAccountPassword,
details: details
)
let loggedIn = try await api.users.retrieveMeWithEditContext().data.username
#expect(loggedIn == credentials.adminUsername)

// When sign in with another account, an error should be returned.
await #expect(throws: NonceRetrievalError.AlreadyLoggedIn(username: credentials.adminUsername)) {
_ = try await client.authenticateTemporarily(
username: credentials.authorUsername,
password: credentials.authorPassword,
details: details
)
}
}

}
10 changes: 3 additions & 7 deletions native/swift/Tests/integration-tests/TestCredentials.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ struct TestCredentials: Decodable {
var adminUsername: String
var adminPassword: String
var adminPasswordUuid: String
var adminAccountPassword: String
var subscriberUsername: String
var subscriberPassword: String
var subscriberPasswordUuid: String
Expand All @@ -24,6 +25,7 @@ struct TestCredentials: Decodable {
case adminUsername = "admin_username"
case adminPassword = "admin_password"
case adminPasswordUuid = "admin_password_uuid"
case adminAccountPassword = "admin_account_password"
case subscriberUsername = "subscriber_username"
case subscriberPassword = "subscriber_password"
case subscriberPasswordUuid = "subscriber_password_uuid"
Expand All @@ -46,12 +48,6 @@ struct TestCredentials: Decodable {
)!
.absoluteURL
// swiftlint:disable:next force_try
var result = try! JSONDecoder().decode(Self.self, from: Data(contentsOf: json))
#if os(Linux)
// Integration tests are run in a Docker container, where the test site
// hostname is 'wordpress'.
result.siteUrl = "http://wordpress"
#endif
return result
return try! JSONDecoder().decode(Self.self, from: Data(contentsOf: json))
}
}
16 changes: 16 additions & 0 deletions scripts/docker/install-swift.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

set -euo pipefail

curl -s -o swiftly.tar.gz "https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz"
tar zxf swiftly.tar.gz
rm swiftly.tar.gz

# If you get an "Unsupported Linux platform" error, check out the supported platforms here:
# https://github.com/swiftlang/swiftly/blob/1.1.0/Sources/LinuxPlatform/Linux.swift#L12-L20
./swiftly init --assume-yes --skip-install

apt-get -y -qq install libicu-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libncurses-dev libpython3-dev libxml2-dev uuid-dev git libstdc++-12-dev

echo "Installing Swift..."
swiftly install --progress-file /dev/null --use 6.1
Loading