Skip to content

Commit b4bdfb1

Browse files
authored
fix: use default ACL on newly created ParseObjects (#284)
* fix: use defaultACL if available when creating ParseObjects * Update changeling * Add test cases * don't run test on linux
1 parent 863781b commit b4bdfb1

19 files changed

+645
-70
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22

33
### main
44

5-
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.5...main)
5+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.6...main)
66
* _Contributing to this repo? Add info about your change here to be included in the next release_
77

8+
### 2.2.6
9+
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.5...2.2.6)
10+
11+
__Fixes__
12+
- Use default ACL automatically on newley created ParseObject's if a default ACL is available ([#283](https://github.com/parse-community/Parse-Swift/pull/283)), thanks to [Corey Baker](https://github.com/cbaker6).
13+
814
### 2.2.5
915
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/2.2.4...2.2.5)
1016

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@
101101
70170A4E2656EBA50070C905 /* ParseAnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70170A4D2656EBA50070C905 /* ParseAnalyticsTests.swift */; };
102102
70170A4F2656EBA50070C905 /* ParseAnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70170A4D2656EBA50070C905 /* ParseAnalyticsTests.swift */; };
103103
70170A502656EBA50070C905 /* ParseAnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70170A4D2656EBA50070C905 /* ParseAnalyticsTests.swift */; };
104+
7023800F2747FCCD00EFC443 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */; };
105+
702380102747FCCD00EFC443 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */; };
106+
702380112747FCCD00EFC443 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */; };
104107
7028373426BD8883007688C9 /* ParseObject+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373326BD8883007688C9 /* ParseObject+async.swift */; };
105108
7028373526BD8883007688C9 /* ParseObject+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373326BD8883007688C9 /* ParseObject+async.swift */; };
106109
7028373626BD8883007688C9 /* ParseObject+async.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7028373326BD8883007688C9 /* ParseObject+async.swift */; };
@@ -828,6 +831,7 @@
828831
70170A432656B02C0070C905 /* ParseAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnalytics.swift; sourceTree = "<group>"; };
829832
70170A482656E2FE0070C905 /* ParseAnalytics+combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseAnalytics+combine.swift"; sourceTree = "<group>"; };
830833
70170A4D2656EBA50070C905 /* ParseAnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnalyticsTests.swift; sourceTree = "<group>"; };
834+
7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsTests.swift; sourceTree = "<group>"; };
831835
7028373326BD8883007688C9 /* ParseObject+async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseObject+async.swift"; sourceTree = "<group>"; };
832836
7028373826BD8C89007688C9 /* ParseUser+async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ParseUser+async.swift"; sourceTree = "<group>"; };
833837
7033ECB025584A83009770F3 /* TestHostTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TestHostTV.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -1139,6 +1143,7 @@
11391143
children = (
11401144
4AA8076D1F794C1C008CD551 /* Info.plist */,
11411145
911DB12D24C4837E0027F3C7 /* APICommandTests.swift */,
1146+
7023800E2747FCCD00EFC443 /* ExtensionsTests.swift */,
11421147
7003957525A0EE770052CB31 /* BatchUtilsTests.swift */,
11431148
70DFEA892618E77800F8EB4B /* InitializeSDKTests.swift */,
11441149
709B40C0268F999000ED2EAC /* IOS13Tests.swift */,
@@ -2233,6 +2238,7 @@
22332238
705A99F9259807F900B3547F /* ParseFileManagerTests.swift in Sources */,
22342239
7044C20625C5D6780011F6E7 /* ParseQueryCombineTests.swift in Sources */,
22352240
70C5508525B4A68700B5DBC2 /* ParseOperationTests.swift in Sources */,
2241+
7023800F2747FCCD00EFC443 /* ExtensionsTests.swift in Sources */,
22362242
917BA43E2703E84000F8D747 /* ParseOperationAsyncTests.swift in Sources */,
22372243
7037DAB226384DE1005D7E62 /* TestParseEncoder.swift in Sources */,
22382244
7004C24D25B69207005E0AD9 /* ParseRoleTests.swift in Sources */,
@@ -2457,6 +2463,7 @@
24572463
705A99FB259807F900B3547F /* ParseFileManagerTests.swift in Sources */,
24582464
7044C20825C5D6780011F6E7 /* ParseQueryCombineTests.swift in Sources */,
24592465
70C5508725B4A68700B5DBC2 /* ParseOperationTests.swift in Sources */,
2466+
702380112747FCCD00EFC443 /* ExtensionsTests.swift in Sources */,
24602467
917BA4402703E84000F8D747 /* ParseOperationAsyncTests.swift in Sources */,
24612468
7037DAB426384DE1005D7E62 /* TestParseEncoder.swift in Sources */,
24622469
7004C26125B6920B005E0AD9 /* ParseRoleTests.swift in Sources */,
@@ -2544,6 +2551,7 @@
25442551
705A99FA259807F900B3547F /* ParseFileManagerTests.swift in Sources */,
25452552
7044C20725C5D6780011F6E7 /* ParseQueryCombineTests.swift in Sources */,
25462553
70C5508625B4A68700B5DBC2 /* ParseOperationTests.swift in Sources */,
2554+
702380102747FCCD00EFC443 /* ExtensionsTests.swift in Sources */,
25472555
917BA43F2703E84000F8D747 /* ParseOperationAsyncTests.swift in Sources */,
25482556
7037DAB326384DE1005D7E62 /* TestParseEncoder.swift in Sources */,
25492557
7004C25725B6920A005E0AD9 /* ParseRoleTests.swift in Sources */,

Sources/ParseSwift/API/API+Command.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ internal extension API.Command {
360360

361361
// MARK: Saving ParseObjects - private
362362
private static func create<T>(_ object: T) -> API.Command<T, T> where T: ParseObject {
363+
var object = object
364+
if object.ACL == nil,
365+
let acl = try? ParseACL.defaultACL() {
366+
object.ACL = acl
367+
}
363368
let mapper = { (data) -> T in
364369
try ParseCoding.jsonDecoder().decode(SaveResponse.self, from: data).apply(to: object)
365370
}

Sources/ParseSwift/Coding/ParseEncoder.swift

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -318,32 +318,35 @@ private class _ParseEncoder: JSONEncoder, Encoder {
318318
} else {
319319
valueToEncode = pointer
320320
}
321-
} else if let object = value as? Objectable,
322-
let pointer = try? PointerType(object) {
323-
if let uniquePointer = self.uniquePointer,
324-
uniquePointer.hasSameObjectId(as: pointer) {
325-
throw ParseError(code: .unknownError,
326-
message: "Found a circular dependency when encoding.")
327-
}
328-
if !self.collectChildren && codingPath.count > 0 {
329-
valueToEncode = value
321+
} else if let object = value as? Objectable {
322+
if let pointer = try? PointerType(object) {
323+
if let uniquePointer = self.uniquePointer,
324+
uniquePointer.hasSameObjectId(as: pointer) {
325+
throw ParseError(code: .unknownError,
326+
message: "Found a circular dependency when encoding.")
327+
}
328+
if !self.collectChildren && codingPath.count > 0 {
329+
valueToEncode = value
330+
} else {
331+
valueToEncode = pointer
332+
}
330333
} else {
331-
valueToEncode = pointer
332-
}
333-
} else {
334-
let hashOfCurrentObject = try BaseObjectable.createHash(value)
335-
if self.collectChildren {
334+
var object = object
335+
if object.ACL == nil,
336+
let acl = try? ParseACL.defaultACL() {
337+
object.ACL = acl
338+
}
339+
let hashOfCurrentObject = try BaseObjectable.createHash(object)
340+
valueToEncode = object
336341
if let pointerForCurrentObject = self.objectsSavedBeforeThisOne?[hashOfCurrentObject] {
337342
valueToEncode = pointerForCurrentObject
338-
} else {
339-
//New object needs to be saved before it can be pointed to
340-
self.newObjects.append(value)
343+
} else if self.collectChildren {
344+
// New object needs to be saved before it can be pointed to
345+
self.newObjects.append(object)
346+
} else if dictionary.count > 0 {
347+
// Only top level objects can be saved without a pointer
348+
throw ParseError(code: .unknownError, message: "Error. Couldn't resolve unsaved object while encoding.")
341349
}
342-
} else if let pointerForCurrentObject = self.objectsSavedBeforeThisOne?[hashOfCurrentObject] {
343-
valueToEncode = pointerForCurrentObject
344-
} else if dictionary.count > 0 {
345-
//Only top level objects can be saved without a pointer
346-
throw ParseError(code: .unknownError, message: "Error. Couldn't resolve unsaved object while encoding.")
347350
}
348351
}
349352
return valueToEncode

Sources/ParseSwift/Objects/ParseInstallation.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -598,12 +598,17 @@ extension ParseInstallation {
598598

599599
// MARK: Saving ParseObjects - private
600600
private func createCommand() -> API.Command<Self, Self> {
601+
var object = self
602+
if object.ACL == nil,
603+
let acl = try? ParseACL.defaultACL() {
604+
object.ACL = acl
605+
}
601606
let mapper = { (data) -> Self in
602-
try ParseCoding.jsonDecoder().decode(SaveResponse.self, from: data).apply(to: self)
607+
try ParseCoding.jsonDecoder().decode(SaveResponse.self, from: data).apply(to: object)
603608
}
604609
return API.Command<Self, Self>(method: .POST,
605610
path: endpoint(.POST),
606-
body: self,
611+
body: object,
607612
mapper: mapper)
608613
}
609614

Sources/ParseSwift/Objects/ParseObject.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -792,10 +792,10 @@ extension ParseObject {
792792
try waitingToBeSaved.forEach { parseType in
793793

794794
if let parseFile = parseType as? ParseFile {
795-
//ParseFiles can be saved now
795+
// ParseFiles can be saved now
796796
savableFiles.append(parseFile)
797797
} else if let parseObject = parseType as? Objectable {
798-
//This is a ParseObject
798+
// This is a ParseObject
799799
let waitingObjectInfo = try ParseCoding
800800
.parseEncoder()
801801
.encode(parseObject,

Sources/ParseSwift/Objects/ParseUser.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,12 +979,17 @@ extension ParseUser {
979979

980980
// MARK: Saving ParseObjects - private
981981
private func createCommand() -> API.Command<Self, Self> {
982+
var object = self
983+
if object.ACL == nil,
984+
let acl = try? ParseACL.defaultACL() {
985+
object.ACL = acl
986+
}
982987
let mapper = { (data) -> Self in
983-
try ParseCoding.jsonDecoder().decode(SaveResponse.self, from: data).apply(to: self)
988+
try ParseCoding.jsonDecoder().decode(SaveResponse.self, from: data).apply(to: object)
984989
}
985990
return API.Command<Self, Self>(method: .POST,
986991
path: endpoint(.POST),
987-
body: self,
992+
body: object,
988993
mapper: mapper)
989994
}
990995

Sources/ParseSwift/ParseConstants.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010

1111
enum ParseConstants {
1212
static let sdk = "swift"
13-
static let version = "2.2.5"
13+
static let version = "2.2.6"
1414
static let fileManagementDirectory = "parse/"
1515
static let fileManagementPrivateDocumentsDirectory = "Private Documents/"
1616
static let fileManagementLibraryDirectory = "Library/"

Sources/ParseSwift/Types/ParseACL.swift

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -303,32 +303,38 @@ extension ParseACL {
303303
*/
304304
public static func defaultACL() throws -> Self {
305305

306-
let aclController: DefaultACL?
306+
let aclController: DefaultACL!
307307

308308
#if !os(Linux) && !os(Android) && !os(Windows)
309-
aclController = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.defaultACL)
309+
if let controller: DefaultACL = try? KeychainStore.shared.get(valueFor: ParseStorage.Keys.defaultACL) {
310+
aclController = controller
311+
} else {
312+
throw ParseError(code: .unknownError,
313+
message: "Default ACL can't be found in Keychain. You should `setDefaultACL` first")
314+
}
310315
#else
311-
aclController = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.defaultACL)
316+
if let controller: DefaultACL = try? ParseStorage.shared.get(valueFor: ParseStorage.Keys.defaultACL) {
317+
aclController = controller
318+
} else {
319+
throw ParseError(code: .unknownError,
320+
message: "Default ACL can't be found in Keychain. You should `setDefaultACL` first")
321+
}
312322
#endif
313323

314-
if let acl = aclController {
315-
if !acl.useCurrentUser {
316-
return acl.defaultACL
317-
} else {
318-
guard let userObjectId = BaseParseUser.current?.objectId else {
319-
return acl.defaultACL
320-
}
321-
322-
guard let lastCurrentUserObjectId = acl.lastCurrentUserObjectId,
323-
userObjectId == lastCurrentUserObjectId else {
324-
return try setDefaultACL(ParseACL(), withAccessForCurrentUser: true)
325-
}
324+
if !aclController.useCurrentUser {
325+
return aclController.defaultACL
326+
} else {
327+
guard let userObjectId = BaseParseUser.current?.objectId else {
328+
return aclController.defaultACL
329+
}
326330

327-
return acl.defaultACL
331+
guard let lastCurrentUserObjectId = aclController.lastCurrentUserObjectId,
332+
userObjectId == lastCurrentUserObjectId else {
333+
return try setDefaultACL(ParseACL(), withAccessForCurrentUser: true)
328334
}
329-
}
330335

331-
return try setDefaultACL(ParseACL(), withAccessForCurrentUser: true)
336+
return aclController.defaultACL
337+
}
332338
}
333339

334340
/**
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// ExtensionsTests.swift
3+
// ParseSwift
4+
//
5+
// Created by Corey Baker on 11/19/21.
6+
// Copyright © 2021 Parse Community. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import XCTest
11+
@testable import ParseSwift
12+
13+
class ExtensionsTests: XCTestCase {
14+
override func setUpWithError() throws {
15+
try super.setUpWithError()
16+
guard let url = URL(string: "http://localhost:1337/1") else {
17+
XCTFail("Should create valid URL")
18+
return
19+
}
20+
ParseSwift.initialize(applicationId: "applicationId",
21+
clientKey: "clientKey",
22+
masterKey: "masterKey",
23+
serverURL: url,
24+
testing: true)
25+
}
26+
27+
override func tearDownWithError() throws {
28+
try super.tearDownWithError()
29+
MockURLProtocol.removeAll()
30+
#if !os(Linux) && !os(Android) && !os(Windows)
31+
try KeychainStore.shared.deleteAll()
32+
#endif
33+
try ParseStorage.shared.deleteAll()
34+
}
35+
36+
#if !os(Linux) && !os(Android) && !os(Windows)
37+
func testURLSession() throws {
38+
ParseSwift.configuration.isTestingSDK = false
39+
XCTAssertNotNil(URLSession.parse.configuration.urlCache)
40+
}
41+
#endif
42+
}

0 commit comments

Comments
 (0)