From 1046086442e58087510f5a6ea3c30dcfe086b373 Mon Sep 17 00:00:00 2001 From: Ricardo Pereira Date: Thu, 4 Jul 2019 13:19:00 +0100 Subject: [PATCH] Delete device registration should not use the general-purpose endpoint - because it requires 'push-admin' permission and it will fail for 'push-subscribe' only key Error: 401 "action not permitted" --- Source/ARTPushActivationStateMachine.m | 7 +------ Spec/PushActivationStateMachine.swift | 18 ++++++------------ 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Source/ARTPushActivationStateMachine.m b/Source/ARTPushActivationStateMachine.m index 1919d0b09..9171e214d 100644 --- a/Source/ARTPushActivationStateMachine.m +++ b/Source/ARTPushActivationStateMachine.m @@ -272,12 +272,7 @@ - (void)deviceUnregistration:(ARTErrorInfo *)error { } // Asynchronous HTTP request - NSURLComponents *components = [[NSURLComponents alloc] initWithURL:[NSURL URLWithString:@"/push/deviceRegistrations"] resolvingAgainstBaseURL:NO]; - components.queryItems = @[ - [NSURLQueryItem queryItemWithName:@"deviceId" value:local.id], - ]; - - NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[components URL]]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[[NSURL URLWithString:@"/push/deviceRegistrations"] URLByAppendingPathComponent:local.id]]; request.HTTPMethod = @"DELETE"; [request setDeviceAuthentication:local]; diff --git a/Spec/PushActivationStateMachine.swift b/Spec/PushActivationStateMachine.swift index e4eff66e7..d081ad7b9 100644 --- a/Spec/PushActivationStateMachine.swift +++ b/Spec/PushActivationStateMachine.swift @@ -575,7 +575,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateNotActivated.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -585,7 +585,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) expect(request.allHTTPHeaderFields?["Authorization"]).toNot(beNil()) let deviceAuthorization = request.allHTTPHeaderFields?["X-Ably-DeviceSecret"] expect(deviceAuthorization).to(equal(rest.device.secret)) @@ -625,7 +624,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateNotActivated.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -635,7 +634,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) expect(rest.device.identityTokenDetails).to(beNil()) expect(request.allHTTPHeaderFields?["Authorization"]).toNot(beNil()) let deviceAuthorization = request.allHTTPHeaderFields?["X-Ably-DeviceToken"] @@ -667,7 +665,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateWaitingForDeregistration.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -677,7 +675,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) } } @@ -1249,7 +1246,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateNotActivated.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -1259,7 +1256,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) expect(request.allHTTPHeaderFields?["Authorization"]).toNot(beNil()) let deviceAuthorization = request.allHTTPHeaderFields?["X-Ably-DeviceSecret"] expect(deviceAuthorization).to(equal(rest.device.secret)) @@ -1297,7 +1293,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateNotActivated.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -1307,7 +1303,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) expect(rest.device.identityTokenDetails).to(beNil()) expect(request.allHTTPHeaderFields?["Authorization"]).toNot(beNil()) let deviceAuthorization = request.allHTTPHeaderFields?["X-Ably-DeviceToken"] @@ -1338,7 +1333,7 @@ class PushActivationStateMachine : QuickSpec { expect(stateMachine.current).to(beAKindOf(ARTPushActivationStateWaitingForDeregistration.self)) expect(httpExecutor.requests.count) == 1 - let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations" }) + let requests = httpExecutor.requests.compactMap({ $0.url?.path }).filter({ $0 == "/push/deviceRegistrations/\(rest.device.id)" }) expect(requests).to(haveCount(1)) guard let request = httpExecutor.requests.first else { fail("should have a \"/push/deviceRegistrations\" request"); return @@ -1348,7 +1343,6 @@ class PushActivationStateMachine : QuickSpec { } expect(url.host).to(equal(rest.options.restUrl().host)) expect(request.httpMethod) == "DELETE" - expect(url.query).to(contain(rest.device.id)) } it("should transition to WaitingForRegistrationUpdate") {