Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.
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
2 changes: 1 addition & 1 deletion WordPressKit.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "WordPressKit"
s.version = "4.6.0-beta.1"
s.version = "4.6.0-beta.2"
s.summary = "WordPressKit offers a clean and simple WordPress.com and WordPress.org API."

s.description = <<-DESC
Expand Down
20 changes: 20 additions & 0 deletions WordPressKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@
E6C1E8491EF21FC100D139D9 /* is-passwordless-account-no-account-found.json in Resources */ = {isa = PBXBuildFile; fileRef = E6C1E8471EF21FC100D139D9 /* is-passwordless-account-no-account-found.json */; };
E6C1E84A1EF21FC100D139D9 /* is-passwordless-account-success.json in Resources */ = {isa = PBXBuildFile; fileRef = E6C1E8481EF21FC100D139D9 /* is-passwordless-account-success.json */; };
E6D0EE621F7EF9CE0064D3FC /* AccountServiceRemoteREST+SocialService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6D0EE611F7EF9CE0064D3FC /* AccountServiceRemoteREST+SocialService.swift */; };
F194E1232417ED9F00874408 /* AtomicAuthenticationServiceRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F194E1222417ED9F00874408 /* AtomicAuthenticationServiceRemoteTests.swift */; };
F194E1252417EE7E00874408 /* atomic-get-auth-cookie-success.json in Resources */ = {isa = PBXBuildFile; fileRef = F194E1242417EE7E00874408 /* atomic-get-auth-cookie-success.json */; };
F1BB7806240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1BB7805240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift */; };
FF20AD2220B8471A00082398 /* WordPressKit.podspec in Resources */ = {isa = PBXBuildFile; fileRef = FF20AD2120B8471A00082398 /* WordPressKit.podspec */; };
FFE247A720C891D1002DF3A2 /* WordPressComOAuthTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFE247A620C891D1002DF3A2 /* WordPressComOAuthTests.swift */; };
FFE247AF20C891E6002DF3A2 /* WordPressComOAuthWrongPasswordFail.json in Resources */ = {isa = PBXBuildFile; fileRef = FFE247A820C891E5002DF3A2 /* WordPressComOAuthWrongPasswordFail.json */; };
Expand Down Expand Up @@ -943,6 +946,9 @@
E6D0EE611F7EF9CE0064D3FC /* AccountServiceRemoteREST+SocialService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AccountServiceRemoteREST+SocialService.swift"; sourceTree = "<group>"; };
ED05C8FF3E61D93CE5BA527E /* Pods_WordPressKitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WordPressKitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EFF80A6E6EE37118CB1DA158 /* Pods_WordPressKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WordPressKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F194E1222417ED9F00874408 /* AtomicAuthenticationServiceRemoteTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicAuthenticationServiceRemoteTests.swift; sourceTree = "<group>"; };
F194E1242417EE7E00874408 /* atomic-get-auth-cookie-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "atomic-get-auth-cookie-success.json"; sourceTree = "<group>"; };
F1BB7805240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicAuthenticationServiceRemote.swift; sourceTree = "<group>"; };
FF20AD2120B8471A00082398 /* WordPressKit.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WordPressKit.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
FFE247A620C891D1002DF3A2 /* WordPressComOAuthTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordPressComOAuthTests.swift; sourceTree = "<group>"; };
FFE247A820C891E5002DF3A2 /* WordPressComOAuthWrongPasswordFail.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = WordPressComOAuthWrongPasswordFail.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1209,6 +1215,7 @@
74B335D91F06F3D60053A184 /* WordPressComRestApiTests.swift */,
73B3DAD521FBB20D00B2CF18 /* WordPressComRestApiTests+Locale.swift */,
74B335DB1F06F4180053A184 /* WordPressOrgXMLRPCApiTests.swift */,
F194E1212417ED7E00874408 /* Authentication */,
93BD273E1EE732CC002BB00B /* Accounts */,
826016FE1F9FD59400533B6C /* Activity */,
74B5F0DF1EF82AAB00B411E7 /* Blog */,
Expand Down Expand Up @@ -1308,6 +1315,7 @@
7403A2E31EF06ED500DED7DC /* AccountSettingsRemote.swift */,
826016F01F9FA13A00533B6C /* ActivityServiceRemote.swift */,
7397F019220A072500C723F3 /* ActivityServiceRemote_ApiVersion1_0.swift */,
F1BB7805240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift */,
40247DF92120D8E100AE1C3C /* AutomatedTransferService.swift */,
82FFBF551F460DD400F4573F /* BlogJetpackSettingsServiceRemote.swift */,
74B5F0DB1EF829B800B411E7 /* BlogServiceRemote.h */,
Expand Down Expand Up @@ -1482,6 +1490,7 @@
93BD27421EE73384002BB00B /* Mock Data */ = {
isa = PBXGroup;
children = (
F194E1242417EE7E00874408 /* atomic-get-auth-cookie-success.json */,
40819784221F74B200A298E4 /* stats-post-details.json */,
4081977A221F153A00A298E4 /* stats-visits-day.json */,
4081977D221F269A00A298E4 /* stats-visits-month.json */,
Expand Down Expand Up @@ -1782,6 +1791,14 @@
name = Pods;
sourceTree = "<group>";
};
F194E1212417ED7E00874408 /* Authentication */ = {
isa = PBXGroup;
children = (
F194E1222417ED9F00874408 /* AtomicAuthenticationServiceRemoteTests.swift */,
);
name = Authentication;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
Expand Down Expand Up @@ -2045,6 +2062,7 @@
E1787DB0200E564B004CB3AF /* timezones.json in Resources */,
93BD275E1EE73442002BB00B /* me-bad-json-failure.json in Resources */,
FFE247AF20C891E6002DF3A2 /* WordPressComOAuthWrongPasswordFail.json in Resources */,
F194E1252417EE7E00874408 /* atomic-get-auth-cookie-success.json in Resources */,
731BA83A21DED358000FDFCD /* site-creation-success.json in Resources */,
9A2D0B2F225E1245009E585F /* jetpack-service-check-site-success.json in Resources */,
829BA4301FACF187003ADEEA /* activity-rewind-status-restore-failure.json in Resources */,
Expand Down Expand Up @@ -2319,6 +2337,7 @@
40AB1ADA200FED25009B533D /* PluginDirectoryFeedPage.swift in Sources */,
436D56352118D85800CEAA33 /* Country.swift in Sources */,
74A44DCB1F13C533006CD8F4 /* NotificationSettingsServiceRemote.swift in Sources */,
F1BB7806240FB90B0030ADDC /* AtomicAuthenticationServiceRemote.swift in Sources */,
404057CE221C38130060250C /* StatsTopVideosTimeIntervalData.swift in Sources */,
7E0D64FF22D855700092AD10 /* EditorServiceRemote.swift in Sources */,
E182BF6A1FD961810001D850 /* Endpoint.swift in Sources */,
Expand Down Expand Up @@ -2403,6 +2422,7 @@
9F3E0BAC20873785009CB5BA /* ServiceRequestTest.swift in Sources */,
740B23D31F17F6BB00067A2A /* PostServiceRemoteXMLRPCTests.swift in Sources */,
93188D221F2264E60028ED4D /* TaxonomyServiceRemoteRESTTests.m in Sources */,
F194E1232417ED9F00874408 /* AtomicAuthenticationServiceRemoteTests.swift in Sources */,
74FC6F3B1F191BB400112505 /* NotificationSyncServiceRemoteTests.swift in Sources */,
731BA83821DECD97000FDFCD /* SiteCreationResponseDecodingTests.swift in Sources */,
9A2D0B2B225E0E22009E585F /* JetpackServiceRemoteTests.swift in Sources */,
Expand Down
84 changes: 84 additions & 0 deletions WordPressKit/AtomicAuthenticationServiceRemote.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import Foundation

class AtomicAuthenticationServiceRemote: ServiceRemoteWordPressComREST {

enum ResponseError: Error {
case responseIsNotADictionary(response: AnyObject)
case decodingFailure(response: [String: AnyObject])
case couldNotInstantiateCookie(name: String, value: String, domain: String, path: String, expires: Date)
}

func getAuthCookie(
siteID: Int,
success: @escaping (_ cookie: HTTPCookie) -> Void,
failure: @escaping (Error) -> Void) {

let endpoint = "sites/\(siteID)/atomic-auth-proxy/read-access-cookies"
let path = self.path(forEndpoint: endpoint, withVersion: ._2_0)

wordPressComRestApi.GET(path,
parameters: nil,
success: {
responseObject, httpResponse in

do {
let settings = try self.cookie(from: responseObject)
success(settings)
} catch {
failure(error)
}
},
failure: { error, httpResponse in
failure(error)
})
}

// MARK: - Result Parsing

private func date(from expiration: Int) -> Date {
return Date(timeIntervalSince1970: TimeInterval(expiration))
}

private func cookie(from responseObject: AnyObject) throws -> HTTPCookie {
guard let response = responseObject as? [String: AnyObject] else {
let error = ResponseError.responseIsNotADictionary(response: responseObject)
DDLogError("❗️Error: \(error)")
throw error
}

guard let cookies = response["cookies"] as? [[String: Any]] else {
let error = ResponseError.decodingFailure(response: response)
DDLogError("❗️Error: \(error)")
throw error
}

let cookieDictionary = cookies[0]

guard let name = cookieDictionary["name"] as? String,
let value = cookieDictionary["value"] as? String,
let domain = cookieDictionary["domain"] as? String,
let path = cookieDictionary["path"] as? String,
let expires = cookieDictionary["expires"] as? Int else {

let error = ResponseError.decodingFailure(response: response)
DDLogError("❗️Error: \(error)")
throw error
}

let expirationDate = date(from: expires)

guard let cookie = HTTPCookie(properties: [
.name: name,
.value: value,
.domain: domain,
.path: path,
.expires: expirationDate,
]) else {
let error = ResponseError.couldNotInstantiateCookie(name: name, value: value, domain: domain, path: path, expires: expirationDate)
DDLogError("❗️Error: \(error)")
throw error
}

return cookie
}
}
38 changes: 38 additions & 0 deletions WordPressKitTests/AtomicAuthenticationServiceRemoteTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import XCTest
@testable import WordPressKit

class AtomicAuthenticationServiceRemoteTests: RemoteTestCase, RESTTestable {

// MARK: - Data

let testSiteID = 2020

// MARK: - Endpoints

let getAuthCookieEndpoint = "sites/2020/atomic-auth-proxy/read-access-cookies"

// MARK: - Mock Response Filenames

let getAuthCookieSuccessMockFilename = "atomic-get-auth-cookie-success.json"

func testGetAuthCookie() {
let remote = AtomicAuthenticationServiceRemote(wordPressComRestApi: getRestApi())
let expectation = self.expectation(description: "We should get the requested auth cookie.")

stubRemoteResponse(getAuthCookieEndpoint, filename: getAuthCookieSuccessMockFilename, contentType: .ApplicationJSON)

remote.getAuthCookie(siteID: testSiteID, success: { cookie in
XCTAssertEqual(cookie.name, "name")
XCTAssertEqual(cookie.value, "value")
XCTAssertEqual(cookie.domain, "someblog.wordpress.com")
XCTAssertEqual(cookie.path, "/")
XCTAssertEqual(cookie.expiresDate, Date(timeIntervalSince1970: TimeInterval(1583364400)))

expectation.fulfill()
}, failure: { error in
XCTFail("❗️ Test failure: \(error)")
})

waitForExpectations(timeout: timeout, handler: nil)
}
}
12 changes: 12 additions & 0 deletions WordPressKitTests/Mock Data/atomic-get-auth-cookie-success.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"url": "https://someblog.wordpress.com",
"cookies": [
{
"expires": 1583364400,
"path": "/",
"domain": "someblog.wordpress.com",
"name": "name",
"value": "value"
}
]
}