Skip to content

Commit

Permalink
fix: All object endpoints need to be public (#80)
Browse files Browse the repository at this point in the history
* fix: All object endpoints need to be public

* add public endpoint tests

* add changelog
  • Loading branch information
cbaker6 committed Mar 16, 2023
1 parent abd413f commit 6e81c2f
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 26 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
__New features__
* Add ParseUser.loginAs(objectId: String) method to allow impersonating a user. This method requires the server primaryKey and is intended to run server-side ([#79](https://github.com/netreconlab/Parse-Swift/pull/79)), thanks to [Corey Baker](https://github.com/cbaker6).

__Fixes__
* Fix ParseUser.become(), ParseUser.linkCommand, and other calls that depend on a specific endpoint for specialized ParseObjects such as ParseUser, ParseInstallation, ParseRole, etc. ([#80](https://github.com/netreconlab/Parse-Swift/pull/80)), thanks to [Corey Baker](https://github.com/cbaker6).

### 5.2.0
[Full Changelog](https://github.com/netreconlab/Parse-Swift/compare/5.1.1...5.2.0), [Documentation](https://swiftpackageindex.com/netreconlab/Parse-Swift/5.2.0/documentation/parseswift)

Expand Down
8 changes: 8 additions & 0 deletions ParseSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@
70732C5A2606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift */; };
70732C5B2606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift */; };
70732C5C2606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70732C592606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift */; };
7073842B29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7073842A29C2910E00E21055 /* ObjectEndpointTests.swift */; };
7073842C29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7073842A29C2910E00E21055 /* ObjectEndpointTests.swift */; };
7073842D29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7073842A29C2910E00E21055 /* ObjectEndpointTests.swift */; };
707A3BF125B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
707A3BF225B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
707A3BF325B0A4F0000D215C /* ParseAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */; };
Expand Down Expand Up @@ -1308,6 +1311,7 @@
706436A827341FD0007C6461 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = "<group>"; };
70647E9B259E3A9A004C1004 /* ParseEncodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseEncodable.swift; sourceTree = "<group>"; };
70732C592606CCAD000CAB81 /* ParseObjectCustomObjectIdTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseObjectCustomObjectIdTests.swift; sourceTree = "<group>"; };
7073842A29C2910E00E21055 /* ObjectEndpointTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectEndpointTests.swift; sourceTree = "<group>"; };
707A3BF025B0A4F0000D215C /* ParseAuthentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAuthentication.swift; sourceTree = "<group>"; };
707A3C1025B0A8E8000D215C /* ParseAnonymous.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnonymous.swift; sourceTree = "<group>"; };
707A3C1F25B14BCF000D215C /* ParseApple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseApple.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1625,6 +1629,7 @@
4AA8076E1F794C1C008CD551 /* KeychainStoreTests.swift */,
70D41D6A28B294C100613510 /* MigrateObjCSDKCombineTests.swift */,
70D41D6628B0235100613510 /* MigrateObjCSDKTests.swift */,
7073842A29C2910E00E21055 /* ObjectEndpointTests.swift */,
9194657724F16E330070296B /* ParseACLTests.swift */,
917BA4292703E03F00F8D747 /* ParseAnalyticsAsyncTests.swift */,
91CB9536265966DF0043E5D6 /* ParseAnalyticsCombineTests.swift */,
Expand Down Expand Up @@ -2973,6 +2978,7 @@
70C7DC2224D20F190050419B /* ParseObjectBatchTests.swift in Sources */,
7044C1BB25C52E410011F6E7 /* ParseInstallationCombineTests.swift in Sources */,
917BA45A2703FD2200F8D747 /* ParseAuthenticationAsyncTests.swift in Sources */,
7073842B29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */,
7FFF552F2217E72A007C3B4E /* AnyCodableTests.swift in Sources */,
70212D2D2855266400386163 /* ParsePushAsyncTests.swift in Sources */,
70F03A5E2780EAC700E5AFB4 /* ParseGitHubTests.swift in Sources */,
Expand Down Expand Up @@ -3299,6 +3305,7 @@
709B984E2556ECAA00507778 /* ParseGeoPointTests.swift in Sources */,
7044C1BD25C52E410011F6E7 /* ParseInstallationCombineTests.swift in Sources */,
917BA45C2703FD2200F8D747 /* ParseAuthenticationAsyncTests.swift in Sources */,
7073842D29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */,
709B984B2556ECAA00507778 /* MockURLProtocol.swift in Sources */,
70212D352855266600386163 /* ParsePushAsyncTests.swift in Sources */,
70F03A602780EAC700E5AFB4 /* ParseGitHubTests.swift in Sources */,
Expand Down Expand Up @@ -3418,6 +3425,7 @@
70F2E2C0254F283000B2EA5C /* MockURLResponse.swift in Sources */,
7044C1BC25C52E410011F6E7 /* ParseInstallationCombineTests.swift in Sources */,
917BA45B2703FD2200F8D747 /* ParseAuthenticationAsyncTests.swift in Sources */,
7073842C29C2910E00E21055 /* ObjectEndpointTests.swift in Sources */,
70F2E2BE254F283000B2EA5C /* ParseObjectBatchTests.swift in Sources */,
70212D312855266500386163 /* ParsePushAsyncTests.swift in Sources */,
70F03A5F2780EAC700E5AFB4 /* ParseGitHubTests.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion Sources/ParseSwift/API/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public struct API {
case hookTrigger(request: TriggerRequest)
case any(String)

var urlComponent: String {
public var urlComponent: String {
switch self {
case .batch:
return "/batch"
Expand Down
14 changes: 7 additions & 7 deletions Sources/ParseSwift/Objects/ParseInstallation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ public extension ParseInstallation {
"_Installation"
}

var endpoint: API.Endpoint {
if let objectId = objectId {
return .installation(objectId: objectId)
}
return .installations
}

// swiftlint:disable:next cyclomatic_complexity function_body_length
func mergeParse(with object: Self) throws -> Self {
guard hasSameObjectId(as: object) else {
Expand Down Expand Up @@ -164,13 +171,6 @@ public extension ParseInstallation {

// MARK: Convenience
extension ParseInstallation {
var endpoint: API.Endpoint {
if let objectId = objectId {
return .installation(objectId: objectId)
}

return .installations
}

func endpoint(_ method: API.Method) -> API.Endpoint {
if !Parse.configuration.isRequiringCustomObjectIds || method != .POST {
Expand Down
13 changes: 7 additions & 6 deletions Sources/ParseSwift/Objects/ParseRole.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ public extension ParseRole {
"_Role"
}

var endpoint: API.Endpoint {
if let objectId = objectId {
return .role(objectId: objectId)
}
return .roles
}

var users: ParseRelation<Self>? {
try? ParseRelation(parent: self, key: "users", className: RoleUser.className)
}
Expand Down Expand Up @@ -130,12 +137,6 @@ public extension ParseRole {

// MARK: Convenience
extension ParseRole {
var endpoint: API.Endpoint {
if let objectId = objectId {
return .role(objectId: objectId)
}
return .roles
}

static func checkName(_ name: String) throws {
// swiftlint:disable:next line_length
Expand Down
3 changes: 0 additions & 3 deletions Sources/ParseSwift/Objects/ParseSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ public extension ParseSession {
static var className: String {
"_Session"
}
}

// MARK: Convenience
extension ParseSession {
var endpoint: API.Endpoint {
if let objectId = objectId {
return .session(objectId: objectId)
Expand Down
17 changes: 8 additions & 9 deletions Sources/ParseSwift/Objects/ParseUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ public extension ParseUser {
"_User"
}

var endpoint: API.Endpoint {
if let objectId = objectId {
return .user(objectId: objectId)
}
return .users
}

func mergeParse(with object: Self) throws -> Self {
guard hasSameObjectId(as: object) else {
throw ParseError(code: .otherCause,
Expand Down Expand Up @@ -94,13 +101,6 @@ public extension ParseUser {

// MARK: Convenience
extension ParseUser {
var endpoint: API.Endpoint {
if let objectId = objectId {
return .user(objectId: objectId)
}

return .users
}

func endpoint(_ method: API.Method) -> API.Endpoint {
if !Parse.configuration.isRequiringCustomObjectIds || method != .POST {
Expand Down Expand Up @@ -445,9 +445,8 @@ extension ParseUser {
#endif

internal func meCommand(sessionToken: String) throws -> API.Command<Self, Self> {
// BAKER: path endpoint isn't working here for some reason
return API.Command(method: .GET,
path: .user(objectId: "me")) { (data) async throws -> Self in
path: endpoint) { (data) async throws -> Self in
let user = try ParseCoding.jsonDecoder().decode(Self.self, from: data)

if let current = try? await Self.current() {
Expand Down
123 changes: 123 additions & 0 deletions Tests/ParseSwiftTests/ObjectEndpointTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
//
// ObjectEndpointTests.swift
// ParseSwift
//
// Created by Corey Baker on 3/15/23.
// Copyright © 2023 Network Reconnaissance Lab. All rights reserved.
//

import Foundation
import XCTest
import ParseSwift

class ObjectEndpointTests: XCTestCase {
struct User: ParseUser {

//: These are required by ParseObject
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var ACL: ParseACL?
var originalData: Data?

// These are required by ParseUser
var username: String?
var email: String?
var emailVerified: Bool?
var password: String?
var authData: [String: [String: String]?]?

// Your custom keys
var customKey: String?
}

struct Installation: ParseInstallation {
var installationId: String?
var deviceType: String?
var deviceToken: String?
var badge: Int?
var timeZone: String?
var channels: [String]?
var appName: String?
var appIdentifier: String?
var appVersion: String?
var parseVersion: String?
var localeIdentifier: String?
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var ACL: ParseACL?
var originalData: Data?
var customKey: String?
}

struct Session<SessionUser: ParseUser>: ParseSession {

var sessionToken: String
var user: User
var restricted: Bool?
var createdWith: [String: String]
var installationId: String
var expiresAt: Date
var originalData: Data?

var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var ACL: ParseACL?

init() {
sessionToken = "hello"
user = User()
restricted = false
createdWith = ["yolo": "yaw"]
installationId = "yes"
expiresAt = Date()
}
}

struct Role<RoleUser: ParseUser>: ParseRole {

// required by ParseObject
var objectId: String?
var createdAt: Date?
var updatedAt: Date?
var ACL: ParseACL?
var originalData: Data?

// provided by Role
var name: String?
}

func testUser() async throws {
let objectId = "yarr"
var user = User()

XCTAssertEqual(user.endpoint.urlComponent, "/users")
user.objectId = objectId
XCTAssertEqual(user.endpoint.urlComponent, "/users/\(objectId)")
}

func testInstallation() async throws {
let objectId = "yarr"
var installation = Installation()

XCTAssertEqual(installation.endpoint.urlComponent, "/installations")
installation.objectId = objectId
XCTAssertEqual(installation.endpoint.urlComponent, "/installations/\(objectId)")
}

func testSession() throws {
var session = Session<User>()
XCTAssertEqual(session.endpoint.urlComponent, "/sessions")
session.objectId = "me"
XCTAssertEqual(session.endpoint.urlComponent, "/sessions/me")
}

func testRole() throws {
var role = try Role<User>(name: "Administrator")
XCTAssertEqual(role.endpoint.urlComponent, "/roles")
role.objectId = "me"
XCTAssertEqual(role.endpoint.urlComponent, "/roles/me")
}
}

0 comments on commit 6e81c2f

Please sign in to comment.