From d3faaa2264172475358b18eee87f845373911a18 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Tue, 5 Sep 2017 16:28:58 -0700 Subject: [PATCH 01/14] US374082 : [iOS] MAS network enhancement with tasks and RequestBuilder Interface to align with Android --- MASFoundation.xcodeproj/project.pbxproj | 34 +++- MASFoundation/Classes/MAS.h | 6 +- MASFoundation/Classes/MAS.m | 27 +++ .../models/Network/MASRequest+MASPrivate.h | 24 +++ .../models/Network/MASRequest+MASPrivate.m | 139 ++++++++++++++ .../Classes/models/Network/MASRequest.h | 145 +++++++++++++++ .../Classes/models/Network/MASRequest.m | 64 +++++++ .../models/Network/MASRequestBuilder.h | 172 ++++++++++++++++++ .../models/Network/MASRequestBuilder.m | 98 ++++++++++ MASFoundation/MASFoundation.h | 2 + 10 files changed, 709 insertions(+), 2 deletions(-) create mode 100644 MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h create mode 100644 MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m create mode 100644 MASFoundation/Classes/models/Network/MASRequest.h create mode 100644 MASFoundation/Classes/models/Network/MASRequest.m create mode 100644 MASFoundation/Classes/models/Network/MASRequestBuilder.h create mode 100644 MASFoundation/Classes/models/Network/MASRequestBuilder.m diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index 918ddd4e..0a039527 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -141,6 +141,12 @@ 10738A3E1C711C2F00B7E87E /* will_mosq.h in Headers */ = {isa = PBXBuildFile; fileRef = 10738A201C711C2F00B7E87E /* will_mosq.h */; }; 10D2D49E1C1686ED00DF8AC4 /* MASGroup+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 10D2D49C1C1686ED00DF8AC4 /* MASGroup+MASPrivate.h */; }; 10D2D49F1C1686ED00DF8AC4 /* MASGroup+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 10D2D49D1C1686ED00DF8AC4 /* MASGroup+MASPrivate.m */; }; + 69BD8ABA1F55ED5B00045C3A /* MASRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 69BD8AB81F55ED5B00045C3A /* MASRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69BD8ABB1F55ED5B00045C3A /* MASRequestBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 69BD8AB91F55ED5B00045C3A /* MASRequestBuilder.m */; }; + 69BD8ABE1F55ED8300045C3A /* MASRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 69BD8ABC1F55ED8300045C3A /* MASRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69BD8ABF1F55ED8300045C3A /* MASRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 69BD8ABD1F55ED8300045C3A /* MASRequest.m */; }; + 69BD8AC21F58C02900045C3A /* MASRequest+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 69BD8AC01F58C02900045C3A /* MASRequest+MASPrivate.h */; }; + 69BD8AC31F58C02900045C3A /* MASRequest+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 69BD8AC11F58C02900045C3A /* MASRequest+MASPrivate.m */; }; A4150E6F1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A4150E691BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h */; }; A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = A4150E6A1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m */; }; A4150E711BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A4150E6B1BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h */; }; @@ -553,6 +559,12 @@ 10738A201C711C2F00B7E87E /* will_mosq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = will_mosq.h; sourceTree = ""; }; 10D2D49C1C1686ED00DF8AC4 /* MASGroup+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASGroup+MASPrivate.h"; sourceTree = ""; }; 10D2D49D1C1686ED00DF8AC4 /* MASGroup+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MASGroup+MASPrivate.m"; sourceTree = ""; }; + 69BD8AB81F55ED5B00045C3A /* MASRequestBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASRequestBuilder.h; sourceTree = ""; }; + 69BD8AB91F55ED5B00045C3A /* MASRequestBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASRequestBuilder.m; sourceTree = ""; }; + 69BD8ABC1F55ED8300045C3A /* MASRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASRequest.h; sourceTree = ""; }; + 69BD8ABD1F55ED8300045C3A /* MASRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASRequest.m; sourceTree = ""; }; + 69BD8AC01F58C02900045C3A /* MASRequest+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "MASRequest+MASPrivate.h"; path = "Network/MASRequest+MASPrivate.h"; sourceTree = ""; }; + 69BD8AC11F58C02900045C3A /* MASRequest+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "MASRequest+MASPrivate.m"; path = "Network/MASRequest+MASPrivate.m"; sourceTree = ""; }; A4150E691BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASIJSONResponseSerializer+MASPrivate.h"; sourceTree = ""; }; A4150E6A1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MASIJSONResponseSerializer+MASPrivate.m"; sourceTree = ""; }; A4150E6B1BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+MASPrivate.h"; sourceTree = ""; }; @@ -1043,6 +1055,15 @@ path = libmosquitto123; sourceTree = ""; }; + 69BD8AC41F58C04E00045C3A /* Network */ = { + isa = PBXGroup; + children = ( + 69BD8AC01F58C02900045C3A /* MASRequest+MASPrivate.h */, + 69BD8AC11F58C02900045C3A /* MASRequest+MASPrivate.m */, + ); + name = Network; + sourceTree = ""; + }; A4150EBD1BF16D9A00037E27 /* network */ = { isa = PBXGroup; children = ( @@ -1288,8 +1309,8 @@ A4831A9A1BD1A551007B4AE6 /* models */ = { isa = PBXGroup; children = ( - CB23578A1F0EE35A00D4C420 /* Network */, CB9975261EDCA718006CEBB1 /* AuthCredentials */, + CB23578A1F0EE35A00D4C420 /* Network */, A4831AA51BD1A551007B4AE6 /* MASObject.h */, A4831AA61BD1A551007B4AE6 /* MASObject.m */, A4831A9B1BD1A551007B4AE6 /* MASApplication.h */, @@ -1406,6 +1427,7 @@ isa = PBXGroup; children = ( CB99752B1EDCA749006CEBB1 /* AuthCredentials */, + 69BD8AC41F58C04E00045C3A /* Network */, CB1907F11C1794FC00A5EF16 /* MASAccess.h */, CB1907F21C1794FC00A5EF16 /* MASAccess.m */, A4831AE81BD1A87C007B4AE6 /* MASApplication+MASPrivate.h */, @@ -1455,6 +1477,10 @@ CB23578A1F0EE35A00D4C420 /* Network */ = { isa = PBXGroup; children = ( + 69BD8AB81F55ED5B00045C3A /* MASRequestBuilder.h */, + 69BD8AB91F55ED5B00045C3A /* MASRequestBuilder.m */, + 69BD8ABC1F55ED8300045C3A /* MASRequest.h */, + 69BD8ABD1F55ED8300045C3A /* MASRequest.m */, ); path = Network; sourceTree = ""; @@ -1678,6 +1704,8 @@ CBD25AEA1E78C47C00DFB47F /* JWTAlgorithmDataHolder.h in Headers */, 105B2F4D1CA6B3EA0005A2D0 /* safestack.h in Headers */, 10738A2E1C711C2F00B7E87E /* net_mosq.h in Headers */, + 69BD8ABA1F55ED5B00045C3A /* MASRequestBuilder.h in Headers */, + 69BD8ABE1F55ED8300045C3A /* MASRequest.h in Headers */, 105B2F311CA6B3EA0005A2D0 /* engine.h in Headers */, A858C6651D0978A6001FB9AD /* MASOTPService.h in Headers */, A4831AAB1BD1A551007B4AE6 /* MASAuthenticationProvider.h in Headers */, @@ -1881,6 +1909,7 @@ 105B2F2D1CA6B3EA0005A2D0 /* ebcdic.h in Headers */, A46F49ED1C2F5FC500A4C370 /* MASINTULocationManager.h in Headers */, A43BEBB21BE34D7700842522 /* CLLocationManager+MASPrivate.h in Headers */, + 69BD8AC21F58C02900045C3A /* MASRequest+MASPrivate.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2038,10 +2067,12 @@ A4150EFC1BF16EE200037E27 /* MASKeyChainService.m in Sources */, A47F12811C1D73530008E3F2 /* MASBluetoothPeripheral.m in Sources */, CBD25B061E78C47C00DFB47F /* JWTCoding+VersionThree.m in Sources */, + 69BD8ABB1F55ED5B00045C3A /* MASRequestBuilder.m in Sources */, A46F4A491C2F5FC500A4C370 /* RNCryptorEngine.m in Sources */, CBD25AED1E78C47C00DFB47F /* JWTAlgorithmDataHolderChain.m in Sources */, A46F49DA1C2F5FC500A4C370 /* MASINetworkActivityIndicatorManager.m in Sources */, A4831AAE1BD1A551007B4AE6 /* MASConfiguration.m in Sources */, + 69BD8ABF1F55ED8300045C3A /* MASRequest.m in Sources */, CBA3EB2F1E945F2400E64D9D /* MASClaims.m in Sources */, CBD25B151E7A0A9200DFB47F /* MF_Base64Additions.m in Sources */, 10738A3B1C711C2F00B7E87E /* util_mosq.c in Sources */, @@ -2097,6 +2128,7 @@ A46F49C51C2F5FC500A4C370 /* MASIHTTPRequestOperation.m in Sources */, A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */, A417BA521BF033C300EC9BCB /* CLLocation+MASPrivate.m in Sources */, + 69BD8AC31F58C02900045C3A /* MASRequest+MASPrivate.m in Sources */, A4831AB21BD1A551007B4AE6 /* MASFile.m in Sources */, CB0B585A1E258C2A00BC0163 /* MASAuthorizationResponse.m in Sources */, CB5E4C651C1D1B56001B3B8A /* MASGetURLRequest.m in Sources */, diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index c4431e1a..19d4ee02 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -12,7 +12,7 @@ #import "MASConstants.h" #import "MASClaims.h" - +#import "MASRequest.h" /** * The top level MAS object represents the Mobile App Services SDK in it's entirety. It @@ -929,6 +929,10 @@ withParameters:(NSDictionary *_Nullable)parameterInfo completion:(MASResponseInfoErrorBlock _Nullable)completion; + ++ (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseInfoErrorBlock)completion; + + ///-------------------------------------- /// @name JWT Signing ///-------------------------------------- diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index d1981d96..f78de16a 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -1464,6 +1464,33 @@ + (void)putTo:(nonnull NSString *)endPoint } ++ (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseInfoErrorBlock)completion +{ + // + // Process the request + // + if ([request.httpMethod isEqualToString:@"DELETE"]) + { + [self deleteFrom:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic completion:completion]; + } + else if ([request.httpMethod isEqualToString:@"GET"]) + { + [self getFrom:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic completion:completion]; + } + else if ([request.httpMethod isEqualToString:@"PATCH"]) + { + [self patchTo:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic completion:completion]; + } + else if ([request.httpMethod isEqualToString:@"POST"]) + { + [self postTo:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic completion:completion]; + } + else if ([request.httpMethod isEqualToString:@"PUT"]) + { + [self putTo:request.endPoint withParameters:request.body andHeaders:request.header requestType:request.requestType responseType:request.responseType isPublic:request.isPublic completion:completion]; + } +} + # pragma mark - Private diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h new file mode 100644 index 00000000..7c12b4a6 --- /dev/null +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h @@ -0,0 +1,24 @@ +// +// MASRequest+MASPrivate.h +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-31. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import + +#import "MASRequest.h" +#import "MASRequestBuilder.h" + +@interface MASRequest (MASPrivate) + +/** + Private initializer for MASRequest. + + @param url NSURL of the target domain + @return MASRequest object + */ +- (id)initWithBuilder:(MASRequestBuilder *)builder; + +@end diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m new file mode 100644 index 00000000..447e9e85 --- /dev/null +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m @@ -0,0 +1,139 @@ +// +// MASRequest+MASPrivate.m +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-31. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import + +#import "MASRequest+MASPrivate.h" + + +@interface MASRequest () + +@property (nonatomic, readwrite) NSString *endPoint; +@property (nonatomic, readwrite) NSString *httpMethod; +@property (nonatomic, readwrite) MASClaims *claims; +@property (nonatomic, readwrite) NSData *privateKey; +@property (nonatomic, readwrite) NSDictionary *header; +@property (nonatomic, readwrite) NSDictionary *body; +@property (nonatomic, readwrite) NSDictionary *query; +@property (assign, readwrite) BOOL isPublic; +@property (assign, readwrite) BOOL sign; +@property (assign, readwrite) MASRequestResponseType requestType; +@property (assign, readwrite) MASRequestResponseType responseType; + +@end + +@implementation MASRequest (MASPrivate) + +# pragma mark - Lifecycle + +- (id)initWithBuilder:(MASRequestBuilder *)builder +{ + self = [super init]; + if(self) + { + self.endPoint = builder.endPoint; + self.isPublic = builder.isPublic; + self.sign = builder.sign; + self.requestType = builder.requestType; + self.responseType = builder.responseType; + self.httpMethod = builder.httpMethod; + self.claims = builder.claims; + self.privateKey = builder.privateKey; + self.header = builder.header; + self.body = builder.body; + self.query = builder.query; + + NSError *error; + + // + // determines whether or not digitally sign the request parameters with JWT signature + // + if(self.sign) + { + NSString *jwt; + + // + // check if MASClaims was provided, if not create a new and set the body content + // + if(!self.claims) + { + MASClaims *claims = [MASClaims claims]; + claims.content = self.body; + claims.contentType = @"application/json"; + self.claims = claims; + } + + // + // check if custom private key was provided + // + if(self.claims && self.privateKey) + { + jwt = [MAS signWithClaims:self.claims privateKey:self.privateKey error:&error]; + } + else { + jwt = [MAS signWithClaims:self.claims error:&error]; + } + + // + // injects JWT claims into the payload + // + if (!error) + { + [self setBody:@{@"jwt":jwt}]; + } + else { + // + // Notify block + // + if(builder.completionBlock) + { + builder.completionBlock(nil, error); + + return nil; + } + } + + } + + // + // check if query parameters are provided + // + if(self.query) + { + // + // add query parameters into URL + // + NSURL *url = [NSURL URLWithString:self.endPoint]; + + NSMutableArray *queryItems = [NSMutableArray array]; + for (NSString *key in self.query) { + NSURLQueryItem *queryItem = [NSURLQueryItem queryItemWithName:key value:self.query[key]]; + [queryItems addObject:queryItem]; + } + + NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; + components.queryItems = [queryItems copy]; + + self.endPoint = [components.URL absoluteString]; + } + + + // + // Notify block + // + if(builder.completionBlock) + { + builder.completionBlock(nil, error); + } + } + + return self; +} + + +@end diff --git a/MASFoundation/Classes/models/Network/MASRequest.h b/MASFoundation/Classes/models/Network/MASRequest.h new file mode 100644 index 00000000..e116603f --- /dev/null +++ b/MASFoundation/Classes/models/Network/MASRequest.h @@ -0,0 +1,145 @@ +// +// MASRequest.h +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-29. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import + +#import "MASClaims.h" +#import "MASRequestBuilder.h" + +/** + MASRequest class is an object created by MASRequestBuilder. It's contains all parameters necessary to invoke an API. + The class cannot be constructed or changed directly, only through MASRequestBuilder. + */ +@interface MASRequest : NSObject + +NS_ASSUME_NONNULL_BEGIN + + +///-------------------------------------- +/// @name Properties +///-------------------------------------- + +# pragma mark - Properties + +/** + NSString value of the HTTP Method (GET, POST, PUT, DELETE). + */ +@property (nonatomic, strong, readonly) NSString *httpMethod; + +/** + BOOL value that determines whether or not the target host is a primary gateway or another gateway/public server. + */ +@property (assign, readonly) BOOL isPublic; + +/** + BOOL value that determines whether or not digitally sign the request parameters with JWT signature. + */ +@property (assign, readonly) BOOL sign; + +/** + NSString value of the specific end point path fragment to append to the base Gateway URL. endPoint value can also be defined as full URL format; in this case, + SDK must be configured to add add the external host as a trusted source using MASSecurityConfiguration object. + */ +@property (nonatomic, strong, nullable, readonly) NSString *endPoint; + +/** + MASClaims object containing claims for JWT. + */ +@property (nonatomic, strong, nullable, readonly) MASClaims *claims; + +/** + NSData value of private key. + */ +@property (nonatomic, strong, nullable, readonly) NSData *privateKey; + +/** + NSDictionary of type/value parameters to put into the header of a request. + */ +@property (nonatomic, strong, nullable, readonly) NSDictionary *header; + +/** + NSDictionary of type/value parameters to put into the body of a request. + */ +@property (nonatomic, strong, nullable, readonly) NSDictionary *body; + +/** + NSDictionary of type/value parameters to put into the URL of a request. + */ +@property (nonatomic, strong, nullable, readonly) NSDictionary *query; + +/** + MASRequestResponseType value that specifies what type formatting is required for request body. + */ +@property (assign, readonly) MASRequestResponseType requestType; + +/** + MASRequestResponseType value that specifies what type formatting is required for response body. + */ +@property (assign, readonly) MASRequestResponseType responseType; + + +# pragma mark - Public + + +/** + Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP DELETE call. This type of HTTP Method type + places it's parameters within the NSURL itself as an HTTP query extension. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param block MASRequestBuilder block containing all paramters to build the request. + @return MASRequestBuilder object + */ ++ (instancetype)delete:(void (^)(MASRequestBuilder *))block; + + +/** + Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP GET call. This type of HTTP Method type + places it's parameters within the NSURL itself as an HTTP query extension. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param block MASRequestBuilder block containing all paramters to build the request. + @return MASRequestBuilder object + */ ++ (instancetype)get:(void (^)(MASRequestBuilder *))block; + + +/** + Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP PATCH call. This type of HTTP Method type + places it's parameters within the HTTP body in www-form-url-encoded format. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param block MASRequestBuilder block containing all paramters to build the request. + @return MASRequestBuilder object + */ ++ (instancetype)patch:(void (^)(MASRequestBuilder *))block; + + +/** + Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP POST call. This type of HTTP Method type + places it's parameters within the HTTP body in www-form-url-encoded format. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param block MASRequestBuilder block containing all paramters to build the request. + @return MASRequestBuilder object + */ ++ (instancetype)post:(void (^)(MASRequestBuilder *))block; + + +/** + Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP PUT call. This type of HTTP Method type + places it's parameters within the HTTP body in www-form-url-encoded format. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param block MASRequestBuilder block containing all paramters to build the request. + @return MASRequestBuilder object + */ ++ (instancetype)put:(void (^)(MASRequestBuilder *))block; + +NS_ASSUME_NONNULL_END + +@end diff --git a/MASFoundation/Classes/models/Network/MASRequest.m b/MASFoundation/Classes/models/Network/MASRequest.m new file mode 100644 index 00000000..0e5329af --- /dev/null +++ b/MASFoundation/Classes/models/Network/MASRequest.m @@ -0,0 +1,64 @@ +// +// MASRequest.m +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-29. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import "MASRequest.h" + +@interface MASRequest () + +@property (nonatomic, readwrite) NSString *endPoint; +@property (nonatomic, readwrite) NSString *httpMethod; +@property (nonatomic, readwrite) MASClaims *claims; +@property (nonatomic, readwrite) NSData *privateKey; +@property (nonatomic, readwrite) NSDictionary *header; +@property (nonatomic, readwrite) NSDictionary *body; +@property (nonatomic, readwrite) NSDictionary *query; +@property (assign, readwrite) BOOL isPublic; +@property (assign, readwrite) BOOL sign; +@property (assign, readwrite) MASRequestResponseType requestType; +@property (assign, readwrite) MASRequestResponseType responseType; + +@end + +@implementation MASRequest + ++ (instancetype)delete:(void (^)(MASRequestBuilder *))block { + + MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"DELETE"]; + block(builder); + return [builder build]; +} + ++ (instancetype)get:(void (^)(MASRequestBuilder *))block { + + MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"GET"]; + block(builder); + return [builder build]; +} + ++ (instancetype)patch:(void (^)(MASRequestBuilder *))block { + + MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"PATCH"]; + block(builder); + return [builder build]; +} + ++ (instancetype)post:(void (^)(MASRequestBuilder *))block { + + MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"POST"]; + block(builder); + return [builder build]; +} + ++ (instancetype)put:(void (^)(MASRequestBuilder *))block { + + MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"PUT"]; + block(builder); + return [builder build]; +} + +@end diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.h b/MASFoundation/Classes/models/Network/MASRequestBuilder.h new file mode 100644 index 00000000..3d5d7195 --- /dev/null +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.h @@ -0,0 +1,172 @@ +// +// MASRequestBuilder.h +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-29. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import + +#import "MASClaims.h" + +/** + MASRequestBuilder class is an object that allows developers to progressively build a request as needed. + The class is mainly responsible for receive parameters and create a MASRequest object. + + Default configuration value for designated initializer, [[MASRequestBuilder alloc] initWithHTTPMethod:], would be: + isPublic: NO, + sign: NO, + requestType:MASRequestResponseTypeJson, + responseType:MASRequestResponseTypeJson. + */ +@interface MASRequestBuilder : NSObject + +NS_ASSUME_NONNULL_BEGIN + +///-------------------------------------- +/// @name Properties +///-------------------------------------- + +# pragma mark - Properties + + +/** + NSString value of the HTTP Method (GET, POST, PUT, DELETE). + */ +@property (nonatomic, strong, readonly) NSString *httpMethod; + +/** + BOOL value that determines whether or not the target host is a primary gateway or another gateway/public server. + */ +@property (assign) BOOL isPublic; + +/** + BOOL value that determines whether or not digitally sign the request parameters with JWT signature. + */ +@property (assign) BOOL sign; + +/** + NSString value of the target endpoint. + */ +@property (nonatomic, strong, nullable) NSString *endPoint; + +/** + MASClaims object containing claims for JWT. + */ +@property (nonatomic, strong, nullable) MASClaims *claims; + +/** + NSData value of private key. + */ +@property (nonatomic, strong, nullable) NSData *privateKey; + +/** + NSDictionary of type/value parameters to put into the header of a request. + */ +@property (nonatomic, strong, nullable) NSDictionary *header; + +/** + NSDictionary of type/value parameters to put into the body of a request. + */ +@property (nonatomic, strong, nullable) NSDictionary *body; + +/** + NSDictionary of type/value parameters to put into the URL of a request. + */ +@property (nonatomic, strong, nullable) NSDictionary *query; + +/** + MASRequestResponseType value that specifies what type formatting is required for request body. + */ +@property (assign) MASRequestResponseType requestType; + +/** + MASRequestResponseType value that specifies what type formatting is required for response body. + */ +@property (assign) MASRequestResponseType responseType; + +/** + MASResponseInfoErrorBlock (NSDictionary *responseInfo, NSError *error) property that will + receive the JSON response object or an NSError object if there is a failure. + */ +@property (nonatomic, strong, nullable) MASResponseInfoErrorBlock completionBlock; + + +///-------------------------------------- +/// @name Lifecycle +///-------------------------------------- + +# pragma mark - Lifecycle + + +/** + Designated initializer for MASRequestBuilder. + + @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. + @param method NSString of the HTTP Method (GET, POST, PUT, DELETE) + @return MASRequestBuilder object + */ +- (instancetype)initWithHTTPMethod:(NSString *)method NS_DESIGNATED_INITIALIZER; + +///-------------------------------------- +/// @name Public +///-------------------------------------- + +# pragma mark - Public + + +/** + Set to sign the request with a MASClaims object using custom private key in NSData format. + + @param privateKey Custom private key in NSData format signed using RS256 algorithm. + */ +- (id)build; + + +/** + Set to sign the request with a MASClaims object using default private key from device registration against primary gateway. + + @param claims MASClaims object containing claims for JWT + */ +- (void)setSignWithClaims:(MASClaims *)claims; + + +/** + Set to sign the request with a MASClaims object using custom private key in NSData format. + + @param privateKey Custom private key in NSData format signed using RS256 algorithm. + */ +- (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey; + + +/** + Append parameter into the header of a request. + + @param key NSString containing name/type of the parameter. + @param value NSString containing value of the parameter. + */ +- (void)setHeaderParameter:(NSString *)key value:(NSString *)value; + + +/** + Append parameter into the body of a request. + + @param key NSString containing name/type of the parameter. + @param value NSString containing value of the parameter. + */ +- (void)setBodyParameter:(NSString *)key value:(NSString *)value; + + +/** + Append parameter into the URL of a request. + + @param key NSString containing name/type of the parameter. + @param value NSString containing value of the parameter. + */ +- (void)setQueryParameter:(NSString *)key value:(NSString *)value; + + +NS_ASSUME_NONNULL_END + +@end diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.m b/MASFoundation/Classes/models/Network/MASRequestBuilder.m new file mode 100644 index 00000000..94991acf --- /dev/null +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.m @@ -0,0 +1,98 @@ +// +// MASRequestBuilder.m +// MASFoundation +// +// Created by Reis, Rodrigo on 2017-08-29. +// Copyright © 2017 CA Technologies. All rights reserved. +// + +#import "MASRequestBuilder.h" + +#import "MASRequest+MASPrivate.h" + +@interface MASRequestBuilder () + +@property (nonatomic, strong, readwrite) NSString *httpMethod; + +@end + +@implementation MASRequestBuilder + + +# pragma mark - Lifecycle + + +- (instancetype)initWithHTTPMethod:(NSString *)method +{ + self = [super init]; + + if (self) { + self.httpMethod = method; + self.isPublic = NO; + self.sign = NO; + self.requestType = MASRequestResponseTypeJson; + self.responseType = MASRequestResponseTypeJson; + } + + return self; +} + + +# pragma mark - Public + +- (id)build +{ + return [[MASRequest alloc] initWithBuilder:self]; +} + + +- (void)setSignWithClaims:(MASClaims *)claims +{ + self.sign = TRUE; + self.claims = claims; +} + + +- (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey +{ + self.sign = TRUE; + self.claims = claims; + self.privateKey = privateKey; +} + + +- (void)setHeaderParameter:(NSString *)key value:(NSString *)value +{ + if(self.header) + { + [self.header setValue:value forKey:key]; + } + else { + self.header = [[NSDictionary alloc] initWithObjectsAndKeys:value,key, nil]; + } +} + +- (void)setBodyParameter:(NSString *)key value:(NSString *)value +{ + if(self.body) + { + [self.body setValue:value forKey:key]; + } + else { + self.body = [[NSDictionary alloc] initWithObjectsAndKeys:value,key, nil]; + } +} + +- (void)setQueryParameter:(NSString *)key value:(NSString *)value +{ + if(self.query) + { + [self.query setValue:value forKey:key]; + } + else { + self.query = [[NSDictionary alloc] initWithObjectsAndKeys:value,key, nil]; + } +} + + +@end diff --git a/MASFoundation/MASFoundation.h b/MASFoundation/MASFoundation.h index 15882b5e..268dec54 100644 --- a/MASFoundation/MASFoundation.h +++ b/MASFoundation/MASFoundation.h @@ -51,6 +51,8 @@ FOUNDATION_EXPORT const unsigned char MASFoundationVersionString[]; #import #import #import +#import +#import // // AuthCredentials Models From 9e165a2f9b82686c4b6f1b9981742a0e556ba080 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Wed, 6 Sep 2017 15:31:43 -0700 Subject: [PATCH 02/14] Updated license information in the files. --- .../_private_/models/Network/MASRequest+MASPrivate.h | 6 ++++-- .../_private_/models/Network/MASRequest+MASPrivate.m | 6 ++++-- MASFoundation/Classes/models/Network/MASRequest.h | 6 ++++-- MASFoundation/Classes/models/Network/MASRequest.m | 6 ++++-- MASFoundation/Classes/models/Network/MASRequestBuilder.h | 6 ++++-- MASFoundation/Classes/models/Network/MASRequestBuilder.m | 6 ++++-- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h index 7c12b4a6..97a57c86 100644 --- a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h @@ -2,8 +2,10 @@ // MASRequest+MASPrivate.h // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-31. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m index 447e9e85..d2859df9 100644 --- a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m @@ -2,8 +2,10 @@ // MASRequest+MASPrivate.m // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-31. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import diff --git a/MASFoundation/Classes/models/Network/MASRequest.h b/MASFoundation/Classes/models/Network/MASRequest.h index e116603f..624aafee 100644 --- a/MASFoundation/Classes/models/Network/MASRequest.h +++ b/MASFoundation/Classes/models/Network/MASRequest.h @@ -2,8 +2,10 @@ // MASRequest.h // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-29. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import diff --git a/MASFoundation/Classes/models/Network/MASRequest.m b/MASFoundation/Classes/models/Network/MASRequest.m index 0e5329af..9d2736de 100644 --- a/MASFoundation/Classes/models/Network/MASRequest.m +++ b/MASFoundation/Classes/models/Network/MASRequest.m @@ -2,8 +2,10 @@ // MASRequest.m // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-29. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import "MASRequest.h" diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.h b/MASFoundation/Classes/models/Network/MASRequestBuilder.h index 3d5d7195..d9ae920e 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.h +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.h @@ -2,8 +2,10 @@ // MASRequestBuilder.h // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-29. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.m b/MASFoundation/Classes/models/Network/MASRequestBuilder.m index 94991acf..555d5a4d 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.m +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.m @@ -2,8 +2,10 @@ // MASRequestBuilder.m // MASFoundation // -// Created by Reis, Rodrigo on 2017-08-29. -// Copyright © 2017 CA Technologies. All rights reserved. +// Copyright (c) 2017 CA. All rights reserved. +// +// This software may be modified and distributed under the terms +// of the MIT license. See the LICENSE file for details. // #import "MASRequestBuilder.h" From 0acda1ff05f200695b808501a6d8ad229557d0d3 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Thu, 7 Sep 2017 13:56:46 -0700 Subject: [PATCH 03/14] Updated with comments provided in the code review --- MASFoundation/Classes/MAS.h | 20 +++++- .../models/Network/MASRequest+MASPrivate.h | 7 +- .../models/Network/MASRequest+MASPrivate.m | 68 ++---------------- .../Classes/models/Network/MASRequest.h | 51 ++++++------- .../Classes/models/Network/MASRequest.m | 17 +++-- .../models/Network/MASRequestBuilder.h | 72 ++++++++++++------- .../models/Network/MASRequestBuilder.m | 57 +++++++++++++-- 7 files changed, 162 insertions(+), 130 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index 19d4ee02..027a6e47 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -929,7 +929,25 @@ withParameters:(NSDictionary *_Nullable)parameterInfo completion:(MASResponseInfoErrorBlock _Nullable)completion; - +/** + * Invoke the endpoint with the parameters defined in the MASRequest object + * + * If endPointPath is full URL format (including port number and http protocol), SDK will validate the server from the client side through SSL pinning (authentication challenge) with + * provided subjectKeyHash (also known as public key hash) in configuration in mag.mobile_sdk.trusted_cert_pinned_public_key_hashes and mag.mobile_sdk.enable_public_key_pinning. + * ALL of servers' public key hashes in certificate chain must be defined in the list. This means when it is configured to use public key hash pinning for SSL pinning, + * subjectKeyHash (public key hash) of the gateway must be also present within the list. The list can contain multiple hash values in array for multiple servers. + * + * When SDK fails to validate SSL with certificate or subjectKeyHash pinning for communication to HTTPs, SDK will cancel the request. + * + * If endPointPath is full URL format, upon successful SSL pinning validation, SDK will also validate the user session against primary gateway regardless the request is being made + * to the primary gateway or not. To ensure bypass the user session validation for public API, use [MAS deleteFrom:withParameters:requestType:responseType:isPublic:completion:] method + * with isPublic being YES. + * + * @param request MASRequest An object containing all parameters to call the endpoint + * When the value is set to true, all automatically injected credentials in SDK will be excluded in the request. + * @param completion An MASResponseInfoErrorBlock (NSDictionary *responseInfo, NSError *error) that will + * receive the JSON response object or an NSError object if there is a failure. + */ + (void)invoke:(nonnull MASRequest *)request completion:(nullable MASResponseInfoErrorBlock)completion; diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h index 97a57c86..a43d5946 100644 --- a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.h @@ -8,10 +8,7 @@ // of the MIT license. See the LICENSE file for details. // -#import - -#import "MASRequest.h" -#import "MASRequestBuilder.h" +#import @interface MASRequest (MASPrivate) @@ -21,6 +18,6 @@ @param url NSURL of the target domain @return MASRequest object */ -- (id)initWithBuilder:(MASRequestBuilder *)builder; +- (instancetype)initWithBuilder:(MASRequestBuilder *)builder; @end diff --git a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m index d2859df9..746cadce 100644 --- a/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m +++ b/MASFoundation/Classes/_private_/models/Network/MASRequest+MASPrivate.m @@ -8,8 +8,6 @@ // of the MIT license. See the LICENSE file for details. // -#import - #import "MASRequest+MASPrivate.h" @@ -17,7 +15,6 @@ @interface MASRequest () @property (nonatomic, readwrite) NSString *endPoint; @property (nonatomic, readwrite) NSString *httpMethod; -@property (nonatomic, readwrite) MASClaims *claims; @property (nonatomic, readwrite) NSData *privateKey; @property (nonatomic, readwrite) NSDictionary *header; @property (nonatomic, readwrite) NSDictionary *body; @@ -33,74 +30,25 @@ @implementation MASRequest (MASPrivate) # pragma mark - Lifecycle -- (id)initWithBuilder:(MASRequestBuilder *)builder +- (instancetype)initWithBuilder:(MASRequestBuilder *)builder { self = [super init]; if(self) { + // + // copy parameters from builder + // self.endPoint = builder.endPoint; self.isPublic = builder.isPublic; self.sign = builder.sign; self.requestType = builder.requestType; self.responseType = builder.responseType; self.httpMethod = builder.httpMethod; - self.claims = builder.claims; self.privateKey = builder.privateKey; self.header = builder.header; self.body = builder.body; self.query = builder.query; - NSError *error; - - // - // determines whether or not digitally sign the request parameters with JWT signature - // - if(self.sign) - { - NSString *jwt; - - // - // check if MASClaims was provided, if not create a new and set the body content - // - if(!self.claims) - { - MASClaims *claims = [MASClaims claims]; - claims.content = self.body; - claims.contentType = @"application/json"; - self.claims = claims; - } - - // - // check if custom private key was provided - // - if(self.claims && self.privateKey) - { - jwt = [MAS signWithClaims:self.claims privateKey:self.privateKey error:&error]; - } - else { - jwt = [MAS signWithClaims:self.claims error:&error]; - } - - // - // injects JWT claims into the payload - // - if (!error) - { - [self setBody:@{@"jwt":jwt}]; - } - else { - // - // Notify block - // - if(builder.completionBlock) - { - builder.completionBlock(nil, error); - - return nil; - } - } - - } // // check if query parameters are provided @@ -124,14 +72,6 @@ - (id)initWithBuilder:(MASRequestBuilder *)builder self.endPoint = [components.URL absoluteString]; } - - // - // Notify block - // - if(builder.completionBlock) - { - builder.completionBlock(nil, error); - } } return self; diff --git a/MASFoundation/Classes/models/Network/MASRequest.h b/MASFoundation/Classes/models/Network/MASRequest.h index 624aafee..5b493627 100644 --- a/MASFoundation/Classes/models/Network/MASRequest.h +++ b/MASFoundation/Classes/models/Network/MASRequest.h @@ -8,18 +8,13 @@ // of the MIT license. See the LICENSE file for details. // -#import - -#import "MASClaims.h" #import "MASRequestBuilder.h" /** - MASRequest class is an object created by MASRequestBuilder. It's contains all parameters necessary to invoke an API. + MASRequest class is an object created by MASRequestBuilder. It contains all necessary information to invoke an API. The class cannot be constructed or changed directly, only through MASRequestBuilder. */ -@interface MASRequest : NSObject - -NS_ASSUME_NONNULL_BEGIN +@interface MASRequest : MASObject ///-------------------------------------- @@ -31,54 +26,58 @@ NS_ASSUME_NONNULL_BEGIN /** NSString value of the HTTP Method (GET, POST, PUT, DELETE). */ -@property (nonatomic, strong, readonly) NSString *httpMethod; +@property (nonatomic, strong, readonly) NSString * _Nonnull httpMethod; + /** - BOOL value that determines whether or not the target host is a primary gateway or another gateway/public server. + BOOL value that determines whether or not to include credentials of primary gateway in the request. */ @property (assign, readonly) BOOL isPublic; + /** BOOL value that determines whether or not digitally sign the request parameters with JWT signature. */ @property (assign, readonly) BOOL sign; + /** NSString value of the specific end point path fragment to append to the base Gateway URL. endPoint value can also be defined as full URL format; in this case, SDK must be configured to add add the external host as a trusted source using MASSecurityConfiguration object. */ @property (nonatomic, strong, nullable, readonly) NSString *endPoint; -/** - MASClaims object containing claims for JWT. - */ -@property (nonatomic, strong, nullable, readonly) MASClaims *claims; /** NSData value of private key. */ @property (nonatomic, strong, nullable, readonly) NSData *privateKey; + /** NSDictionary of type/value parameters to put into the header of a request. */ @property (nonatomic, strong, nullable, readonly) NSDictionary *header; + /** NSDictionary of type/value parameters to put into the body of a request. */ @property (nonatomic, strong, nullable, readonly) NSDictionary *body; + /** NSDictionary of type/value parameters to put into the URL of a request. */ @property (nonatomic, strong, nullable, readonly) NSDictionary *query; + /** MASRequestResponseType value that specifies what type formatting is required for request body. */ @property (assign, readonly) MASRequestResponseType requestType; + /** MASRequestResponseType value that specifies what type formatting is required for response body. */ @@ -90,58 +89,62 @@ NS_ASSUME_NONNULL_BEGIN /** Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP DELETE call. This type of HTTP Method type - places it's parameters within the NSURL itself as an HTTP query extension. + places its parameters within the NSURL itself as an HTTP query extension. @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. @param block MASRequestBuilder block containing all paramters to build the request. @return MASRequestBuilder object */ -+ (instancetype)delete:(void (^)(MASRequestBuilder *))block; ++ (instancetype _Nullable)deleteFrom:(void (^_Nonnull)(MASRequestBuilder* _Nonnull builder))block; + /** Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP GET call. This type of HTTP Method type - places it's parameters within the NSURL itself as an HTTP query extension. + places its parameters within the NSURL itself as an HTTP query extension. @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. @param block MASRequestBuilder block containing all paramters to build the request. @return MASRequestBuilder object */ -+ (instancetype)get:(void (^)(MASRequestBuilder *))block; ++ (instancetype _Nullable)getFrom:(void (^_Nonnull)(MASRequestBuilder* _Nonnull builder))block; + /** Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP PATCH call. This type of HTTP Method type - places it's parameters within the HTTP body in www-form-url-encoded format. + places its parameters within the HTTP body in www-form-url-encoded format. @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. @param block MASRequestBuilder block containing all paramters to build the request. @return MASRequestBuilder object */ -+ (instancetype)patch:(void (^)(MASRequestBuilder *))block; ++ (instancetype _Nullable)patchTo:(void (^_Nonnull)(MASRequestBuilder* _Nonnull builder))block; + /** Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP POST call. This type of HTTP Method type - places it's parameters within the HTTP body in www-form-url-encoded format. + places its parameters within the HTTP body in www-form-url-encoded format. @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. @param block MASRequestBuilder block containing all paramters to build the request. @return MASRequestBuilder object */ -+ (instancetype)post:(void (^)(MASRequestBuilder *))block; ++ (instancetype _Nullable)postTo:(void (^_Nonnull)(MASRequestBuilder* _Nonnull builder))block; + /** Initialize MASRequest using MASRequestBuilder block and defining the request method as a HTTP PUT call. This type of HTTP Method type - places it's parameters within the HTTP body in www-form-url-encoded format. + places its parameters within the HTTP body in www-form-url-encoded format. @discussion default values for designated initializer are: isPublic: NO, sign: NO, requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. @param block MASRequestBuilder block containing all paramters to build the request. @return MASRequestBuilder object */ -+ (instancetype)put:(void (^)(MASRequestBuilder *))block; ++ (instancetype _Nullable)putTo:(void (^_Nonnull)(MASRequestBuilder* _Nonnull builder))block; + -NS_ASSUME_NONNULL_END @end diff --git a/MASFoundation/Classes/models/Network/MASRequest.m b/MASFoundation/Classes/models/Network/MASRequest.m index 9d2736de..c63179d8 100644 --- a/MASFoundation/Classes/models/Network/MASRequest.m +++ b/MASFoundation/Classes/models/Network/MASRequest.m @@ -14,7 +14,6 @@ @interface MASRequest () @property (nonatomic, readwrite) NSString *endPoint; @property (nonatomic, readwrite) NSString *httpMethod; -@property (nonatomic, readwrite) MASClaims *claims; @property (nonatomic, readwrite) NSData *privateKey; @property (nonatomic, readwrite) NSDictionary *header; @property (nonatomic, readwrite) NSDictionary *body; @@ -28,39 +27,45 @@ @interface MASRequest () @implementation MASRequest -+ (instancetype)delete:(void (^)(MASRequestBuilder *))block { + ++ (instancetype)deleteFrom:(void (^)(MASRequestBuilder *builder))block { MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"DELETE"]; block(builder); return [builder build]; } -+ (instancetype)get:(void (^)(MASRequestBuilder *))block { + ++ (instancetype)getFrom:(void (^)(MASRequestBuilder *builder))block { MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"GET"]; block(builder); return [builder build]; } -+ (instancetype)patch:(void (^)(MASRequestBuilder *))block { + ++ (instancetype)patchTo:(void (^)(MASRequestBuilder *builder))block { MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"PATCH"]; block(builder); return [builder build]; } -+ (instancetype)post:(void (^)(MASRequestBuilder *))block { + ++ (instancetype)postTo:(void (^)(MASRequestBuilder *builder))block { MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"POST"]; block(builder); return [builder build]; } -+ (instancetype)put:(void (^)(MASRequestBuilder *))block { + ++ (instancetype)putTo:(void (^)(MASRequestBuilder *builder))block { MASRequestBuilder *builder = [[MASRequestBuilder alloc] initWithHTTPMethod:@"PUT"]; block(builder); return [builder build]; } + @end diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.h b/MASFoundation/Classes/models/Network/MASRequestBuilder.h index d9ae920e..11e8e698 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.h +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.h @@ -8,13 +8,13 @@ // of the MIT license. See the LICENSE file for details. // -#import - #import "MASClaims.h" +@class MASRequest; + /** MASRequestBuilder class is an object that allows developers to progressively build a request as needed. - The class is mainly responsible for receive parameters and create a MASRequest object. + The class is mainly responsible to receive parameters and create a MASRequest object. Default configuration value for designated initializer, [[MASRequestBuilder alloc] initWithHTTPMethod:], would be: isPublic: NO, @@ -22,9 +22,8 @@ requestType:MASRequestResponseTypeJson, responseType:MASRequestResponseTypeJson. */ -@interface MASRequestBuilder : NSObject +@interface MASRequestBuilder : MASObject -NS_ASSUME_NONNULL_BEGIN ///-------------------------------------- /// @name Properties @@ -36,64 +35,68 @@ NS_ASSUME_NONNULL_BEGIN /** NSString value of the HTTP Method (GET, POST, PUT, DELETE). */ -@property (nonatomic, strong, readonly) NSString *httpMethod; +@property (nonatomic, strong, readonly) NSString * _Nonnull httpMethod; + /** - BOOL value that determines whether or not the target host is a primary gateway or another gateway/public server. + BOOL value that determines whether or not to include credentials of primary gateway in the request. */ @property (assign) BOOL isPublic; + /** BOOL value that determines whether or not digitally sign the request parameters with JWT signature. */ -@property (assign) BOOL sign; +@property (assign, readonly) BOOL sign; + /** NSString value of the target endpoint. */ @property (nonatomic, strong, nullable) NSString *endPoint; + /** MASClaims object containing claims for JWT. */ -@property (nonatomic, strong, nullable) MASClaims *claims; +@property (nonatomic, strong, nullable, readonly) MASClaims *claims; + /** NSData value of private key. */ -@property (nonatomic, strong, nullable) NSData *privateKey; +@property (nonatomic, strong, nullable, readonly) NSData *privateKey; + /** NSDictionary of type/value parameters to put into the header of a request. */ @property (nonatomic, strong, nullable) NSDictionary *header; + /** NSDictionary of type/value parameters to put into the body of a request. */ @property (nonatomic, strong, nullable) NSDictionary *body; + /** NSDictionary of type/value parameters to put into the URL of a request. */ @property (nonatomic, strong, nullable) NSDictionary *query; + /** MASRequestResponseType value that specifies what type formatting is required for request body. */ @property (assign) MASRequestResponseType requestType; + /** MASRequestResponseType value that specifies what type formatting is required for response body. */ @property (assign) MASRequestResponseType responseType; -/** - MASResponseInfoErrorBlock (NSDictionary *responseInfo, NSError *error) property that will - receive the JSON response object or an NSError object if there is a failure. - */ -@property (nonatomic, strong, nullable) MASResponseInfoErrorBlock completionBlock; - ///-------------------------------------- /// @name Lifecycle @@ -109,7 +112,9 @@ NS_ASSUME_NONNULL_BEGIN @param method NSString of the HTTP Method (GET, POST, PUT, DELETE) @return MASRequestBuilder object */ -- (instancetype)initWithHTTPMethod:(NSString *)method NS_DESIGNATED_INITIALIZER; +- (instancetype _Nonnull)initWithHTTPMethod:(NSString *_Nonnull)method NS_DESIGNATED_INITIALIZER; + + ///-------------------------------------- /// @name Public @@ -119,27 +124,41 @@ NS_ASSUME_NONNULL_BEGIN /** - Set to sign the request with a MASClaims object using custom private key in NSData format. + Create a MASRequest object using the parameters from MASRequestBuider - @param privateKey Custom private key in NSData format signed using RS256 algorithm. + @return MASRequest object */ -- (id)build; +- (MASRequest *_Nullable)build; + + + +/** + Set to sign the body of request using default private key from device registration against primary gateway. + + @param error NSERror error reference object that returns any error occurred during JWT signature. + */ +- (void)setSignWithError:(NSError *__nullable __autoreleasing *__nullable)error; + /** Set to sign the request with a MASClaims object using default private key from device registration against primary gateway. @param claims MASClaims object containing claims for JWT + @param error NSERror error reference object that returns any error occurred during JWT signature. */ -- (void)setSignWithClaims:(MASClaims *)claims; +- (void)setSignWithClaims:(MASClaims *_Nonnull)claims error:(NSError *__nullable __autoreleasing *__nullable)error; + /** Set to sign the request with a MASClaims object using custom private key in NSData format. @param privateKey Custom private key in NSData format signed using RS256 algorithm. + @param error NSERror error reference object that returns any error occurred during JWT signature. */ -- (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey; +- (void)setSignWithClaims:(MASClaims *_Nonnull)claims privateKey:(NSData *_Nonnull)privateKey error:(NSError *__nullable __autoreleasing *__nullable)error; + /** @@ -148,7 +167,8 @@ NS_ASSUME_NONNULL_BEGIN @param key NSString containing name/type of the parameter. @param value NSString containing value of the parameter. */ -- (void)setHeaderParameter:(NSString *)key value:(NSString *)value; +- (void)setHeaderParameter:(NSString *_Nonnull)key value:(NSString *_Nonnull)value; + /** @@ -157,7 +177,8 @@ NS_ASSUME_NONNULL_BEGIN @param key NSString containing name/type of the parameter. @param value NSString containing value of the parameter. */ -- (void)setBodyParameter:(NSString *)key value:(NSString *)value; +- (void)setBodyParameter:(NSString *_Nonnull)key value:(NSString *_Nonnull)value; + /** @@ -166,9 +187,8 @@ NS_ASSUME_NONNULL_BEGIN @param key NSString containing name/type of the parameter. @param value NSString containing value of the parameter. */ -- (void)setQueryParameter:(NSString *)key value:(NSString *)value; +- (void)setQueryParameter:(NSString *_Nonnull)key value:(NSString *_Nonnull)value; -NS_ASSUME_NONNULL_END @end diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.m b/MASFoundation/Classes/models/Network/MASRequestBuilder.m index 555d5a4d..49f88903 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.m +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.m @@ -15,7 +15,9 @@ @interface MASRequestBuilder () @property (nonatomic, strong, readwrite) NSString *httpMethod; - +@property (assign, readwrite) BOOL sign; +@property (nonatomic, strong, readwrite) MASClaims *claims; +@property (nonatomic, strong, readwrite) NSData *privateKey; @end @implementation MASRequestBuilder @@ -42,24 +44,69 @@ - (instancetype)initWithHTTPMethod:(NSString *)method # pragma mark - Public -- (id)build + +- (MASRequest *)build { return [[MASRequest alloc] initWithBuilder:self]; } -- (void)setSignWithClaims:(MASClaims *)claims +- (void)setSignWithError:(NSError *__nullable __autoreleasing *__nullable)error { self.sign = TRUE; + + // + // create a new MASClaims and set the body content + // + MASClaims *claims = [MASClaims claims]; + claims.content = self.body; + claims.contentType = @"application/json"; self.claims = claims; + + NSString *jwt = [MAS signWithClaims:claims error:error]; + + // + // injects JWT claims into the payload + // + if (!error) + { + [self setBody:@{@"jwt":jwt}]; + } + +} + +- (void)setSignWithClaims:(MASClaims *)claims error:(NSError *__nullable __autoreleasing *__nullable)error +{ + self.sign = TRUE; + self.claims = claims; + + NSString *jwt = [MAS signWithClaims:claims error:error]; + + // + // injects JWT claims into the payload + // + if (!error) + { + [self setBody:@{@"jwt":jwt}]; + } } -- (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey +- (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey error:(NSError *__nullable __autoreleasing *__nullable)error { self.sign = TRUE; self.claims = claims; self.privateKey = privateKey; + + NSString *jwt = [MAS signWithClaims:claims privateKey:self.privateKey error:error]; + + // + // injects JWT claims into the payload + // + if (!error) + { + [self setBody:@{@"jwt":jwt}]; + } } @@ -74,6 +121,7 @@ - (void)setHeaderParameter:(NSString *)key value:(NSString *)value } } + - (void)setBodyParameter:(NSString *)key value:(NSString *)value { if(self.body) @@ -85,6 +133,7 @@ - (void)setBodyParameter:(NSString *)key value:(NSString *)value } } + - (void)setQueryParameter:(NSString *)key value:(NSString *)value { if(self.query) From 79dec946582565c051ded65d3eb410d4a32e5d9d Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Thu, 7 Sep 2017 15:41:48 -0700 Subject: [PATCH 04/14] Fixed some typo issues. --- MASFoundation/Classes/models/Network/MASRequestBuilder.h | 6 +++--- MASFoundation/Classes/models/Network/MASRequestBuilder.m | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.h b/MASFoundation/Classes/models/Network/MASRequestBuilder.h index 11e8e698..368ab55f 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.h +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.h @@ -135,7 +135,7 @@ /** Set to sign the body of request using default private key from device registration against primary gateway. - @param error NSERror error reference object that returns any error occurred during JWT signature. + @param error NSError error reference object that returns any error occurred during JWT signature. */ - (void)setSignWithError:(NSError *__nullable __autoreleasing *__nullable)error; @@ -145,7 +145,7 @@ Set to sign the request with a MASClaims object using default private key from device registration against primary gateway. @param claims MASClaims object containing claims for JWT - @param error NSERror error reference object that returns any error occurred during JWT signature. + @param error NSError error reference object that returns any error occurred during JWT signature. */ - (void)setSignWithClaims:(MASClaims *_Nonnull)claims error:(NSError *__nullable __autoreleasing *__nullable)error; @@ -155,7 +155,7 @@ Set to sign the request with a MASClaims object using custom private key in NSData format. @param privateKey Custom private key in NSData format signed using RS256 algorithm. - @param error NSERror error reference object that returns any error occurred during JWT signature. + @param error NSError error reference object that returns any error occurred during JWT signature. */ - (void)setSignWithClaims:(MASClaims *_Nonnull)claims privateKey:(NSData *_Nonnull)privateKey error:(NSError *__nullable __autoreleasing *__nullable)error; diff --git a/MASFoundation/Classes/models/Network/MASRequestBuilder.m b/MASFoundation/Classes/models/Network/MASRequestBuilder.m index 49f88903..d5531630 100644 --- a/MASFoundation/Classes/models/Network/MASRequestBuilder.m +++ b/MASFoundation/Classes/models/Network/MASRequestBuilder.m @@ -68,7 +68,7 @@ - (void)setSignWithError:(NSError *__nullable __autoreleasing *__nullable)error // // injects JWT claims into the payload // - if (!error) + if (!*error) { [self setBody:@{@"jwt":jwt}]; } @@ -85,7 +85,7 @@ - (void)setSignWithClaims:(MASClaims *)claims error:(NSError *__nullable __autor // // injects JWT claims into the payload // - if (!error) + if (!*error) { [self setBody:@{@"jwt":jwt}]; } @@ -103,7 +103,7 @@ - (void)setSignWithClaims:(MASClaims *)claims privateKey:(NSData *)privateKey er // // injects JWT claims into the payload // - if (!error) + if (!*error) { [self setBody:@{@"jwt":jwt}]; } From 473cbed6dd62adacdeb7f5e8e6372163ca133814 Mon Sep 17 00:00:00 2001 From: James Go Date: Tue, 3 Oct 2017 17:31:43 -0700 Subject: [PATCH 05/14] US399506 : [iOS] MQTT Integration MAS Connecta CA public Cert --- MASFoundation/Classes/MQTT/MASMQTTClient.m | 4 +- .../_private_/services/file/MASFileService.m | 4 +- .../services/model/MASModelService.m | 6 +-- .../services/security/MASSecurityService.h | 12 +++--- .../services/security/MASSecurityService.m | 37 ++++++++++--------- 5 files changed, 32 insertions(+), 31 deletions(-) diff --git a/MASFoundation/Classes/MQTT/MASMQTTClient.m b/MASFoundation/Classes/MQTT/MASMQTTClient.m index 732fc50a..66a40447 100644 --- a/MASFoundation/Classes/MQTT/MASMQTTClient.m +++ b/MASFoundation/Classes/MQTT/MASMQTTClient.m @@ -844,13 +844,13 @@ - (void)setupTLSWithServerCert:(NSString *)certPath withClientCert:(NSString *)c // if (!certPath) { - thisFile = [[MASSecurityService sharedService] getClientCertificate]; + thisFile = [[MASSecurityService sharedService] getServerCertificate]; certPath = [thisFile filePath]; //[[MASFile findFileWithName:@"MAS.crt"] filePath]; } if (!clientCertPath) { - thisFile = [[MASSecurityService sharedService] getSignedCertificate]; + thisFile = [[MASSecurityService sharedService] getDeviceClientCertificate]; clientCertPath = [thisFile filePath]; //[[MASFile findFileWithName:@"MASSigned.crt"] filePath]; } diff --git a/MASFoundation/Classes/_private_/services/file/MASFileService.m b/MASFoundation/Classes/_private_/services/file/MASFileService.m index e10ef761..8e0abe97 100644 --- a/MASFoundation/Classes/_private_/services/file/MASFileService.m +++ b/MASFoundation/Classes/_private_/services/file/MASFileService.m @@ -57,7 +57,7 @@ - (NSString *)debugDescription // // ServerCertificate // - MASFile *file = [[MASSecurityService sharedService] getClientCertificate]; //[self findFileWithName:MASCertificate]; + MASFile *file = [[MASSecurityService sharedService] getServerCertificate]; //[self findFileWithName:MASCertificate]; if(file) { filesFound = YES; @@ -68,7 +68,7 @@ - (NSString *)debugDescription // // SignedCertificate // - file = [[MASSecurityService sharedService] getSignedCertificate]; //[self findFileWithName:MASSignedCertificate]; + file = [[MASSecurityService sharedService] getDeviceClientCertificate]; //[self findFileWithName:MASSignedCertificate]; if(file) { filesFound = YES; diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index 92284303..c92d2796 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -1309,10 +1309,10 @@ - (void)renewClientCertificateWithCompletion:(MASCompletionErrorBlock)completion [[MASAccessService sharedService] setAccessValueNumber:[NSNumber numberWithInt:0] withAccessValueType:MASAccessValueTypeSignedPublicCertificateExpirationDate]; // - // Remove signedCertificate MASFile for re-generation + // Remove device's client MASFile for re-generation // - MASFile *signedCertificate = [[MASSecurityService sharedService] getSignedCertificate]; - [MASFile removeItemAtFilePath:[signedCertificate filePath]]; + MASFile *deviceClientCert = [[MASSecurityService sharedService] getDeviceClientCertificate]; + [MASFile removeItemAtFilePath:[deviceClientCert filePath]]; // // Updated with latest info diff --git a/MASFoundation/Classes/_private_/services/security/MASSecurityService.h b/MASFoundation/Classes/_private_/services/security/MASSecurityService.h index c252cfd1..a6f6d291 100644 --- a/MASFoundation/Classes/_private_/services/security/MASSecurityService.h +++ b/MASFoundation/Classes/_private_/services/security/MASSecurityService.h @@ -83,20 +83,20 @@ # pragma mark - MASFile Security /** - * Generate MASFile object for current gateway's signed certificate. + * Generate MASFile object for current device's client certificate. * - * @return Returns MASFile object of signed certificate for current configuration's gateway. + * @return Returns MASFile object of device's client for current configuration's gateway. */ -- (MASFile *)getSignedCertificate; +- (MASFile *)getDeviceClientCertificate; /** - * Generate MASFile object for current gateway's client certificate. + * Generate MASFile object for current gateway's server certificate. * - * @return Returns MASFile object of client certificate for current configuration's gateway. + * @return Returns MASFile object of server certificate for current configuration's gateway. */ -- (MASFile *)getClientCertificate; +- (MASFile *)getServerCertificate; diff --git a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m index 594573c5..c3d46a1d 100644 --- a/MASFoundation/Classes/_private_/services/security/MASSecurityService.m +++ b/MASFoundation/Classes/_private_/services/security/MASSecurityService.m @@ -415,7 +415,7 @@ - (NSData *)publicKeyBits # pragma mark - MASFile Security -- (MASFile *)getSignedCertificate +- (MASFile *)getDeviceClientCertificate { NSString *gatewayIdentifier = [[[MASConfiguration currentConfiguration].gatewayUrl.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"https://" withString:@""]; MASFile *signedCert = [MASFile findFileWithName:[NSString stringWithFormat:@"%@.%@", gatewayIdentifier, MASSignedCertificate]]; @@ -435,7 +435,7 @@ - (MASFile *)getSignedCertificate } -- (MASFile *)getClientCertificate +- (MASFile *)getServerCertificate { NSString *gatewayIdentifier = [[[MASConfiguration currentConfiguration].gatewayUrl.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"https://" withString:@""]; MASFile *clientCert = [MASFile findFileWithName:[NSString stringWithFormat:@"%@.%@", gatewayIdentifier, MASCertificate]]; @@ -446,17 +446,18 @@ - (MASFile *)getClientCertificate // Create the public server certificate file // NSArray *certs = [[MASConfiguration currentConfiguration] gatewayCertificatesAsPEMData]; - if(certs.count > 0) + NSMutableData *certificateData = [NSMutableData data]; + + for (NSData *cert in certs) + { + [certificateData appendData:cert]; + [certificateData appendData:[@"\n" dataUsingEncoding:NSUTF8StringEncoding]]; + } + + if (certificateData) { - NSData *certificateData = certs[0]; - - //DLog(@"\n\nServer Certificate class is: %@\n\n and value: %@\n\n", [[certificateData class] debugDescription], certificateData); - - if(certificateData) - { - clientCert = [MASFile fileWithName:[NSString stringWithFormat:@"%@.%@", gatewayIdentifier, MASCertificate] contents:certificateData]; - [clientCert save]; - } + clientCert = [MASFile fileWithName:[NSString stringWithFormat:@"%@.%@", gatewayIdentifier, MASCertificate] contents:certificateData]; + [clientCert save]; } } @@ -496,22 +497,22 @@ - (MASFile *)getPrivateKey - (void)removeAllFiles { MASFile *privateKey = [self getPrivateKey]; - MASFile *clientCert = [self getClientCertificate]; - MASFile *signedCert = [self getSignedCertificate]; + MASFile *serverCert = [self getServerCertificate]; + MASFile *deviceClientCert = [self getDeviceClientCertificate]; if ([privateKey filePath]) { [MASFile removeItemAtFilePath:[privateKey filePath]]; } - if ([clientCert filePath]) + if ([serverCert filePath]) { - [MASFile removeItemAtFilePath:[clientCert filePath]]; + [MASFile removeItemAtFilePath:[serverCert filePath]]; } - if ([signedCert filePath]) + if ([deviceClientCert filePath]) { - [MASFile removeItemAtFilePath:[signedCert filePath]]; + [MASFile removeItemAtFilePath:[deviceClientCert filePath]]; } } From fba76db03863c30dfc65b9dd9f433080d7475abb Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Wed, 4 Oct 2017 15:53:22 -0700 Subject: [PATCH 06/14] [iOS] MAS credentials should be stored in the keychain as device only --- .../services/access/MASAccessService.m | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 441a2d23..6674cade 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -102,36 +102,32 @@ - (void)serviceWillStart // _gatewayIdentifier = [MASConfiguration currentConfiguration].gatewayUrl.absoluteString; - _localStorageServiceName = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, kMASAccessLocalStorageServiceName]; _sharedStorageServiceName = [NSString stringWithFormat:@"%@.%@", _gatewayIdentifier, kMASAccessSharedStorageServiceName]; + // + // Local storage + // + MASIKeyChainStore *localStorage = [MASIKeyChainStore keyChainStoreWithService:_localStorageServiceName]; + localStorage.synchronizable = FALSE; + localStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; + if ([MASConfiguration currentConfiguration].ssoEnabled && [self isAccessGroupAccessible]) { - - // - // Local storage - // - MASIKeyChainStore *localStorage = [MASIKeyChainStore keyChainStoreWithService:_localStorageServiceName]; - // // Shared storage // MASIKeyChainStore *sharedStorage = [MASIKeyChainStore keyChainStoreWithService:_sharedStorageServiceName accessGroup:self.accessGroup]; - + sharedStorage.synchronizable = FALSE; + sharedStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; + // // storage dictionary property // _storages = [NSDictionary dictionaryWithObjectsAndKeys:localStorage, kMASAccessLocalStorageKey, sharedStorage, kMASAccessSharedStorageKey, nil]; } else { - - // - // Local storage - // - MASIKeyChainStore *localStorage = [MASIKeyChainStore keyChainStoreWithService:_localStorageServiceName]; - // // storage dictionary property // From b87f3ed586574c35d1d4c3cddd57ce9eb35adafd Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Thu, 5 Oct 2017 10:36:37 -0700 Subject: [PATCH 07/14] Performed changes requested by James on his review. --- .../Classes/_private_/services/access/MASAccessService.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 6674cade..1ee01a8e 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -110,7 +110,7 @@ - (void)serviceWillStart // Local storage // MASIKeyChainStore *localStorage = [MASIKeyChainStore keyChainStoreWithService:_localStorageServiceName]; - localStorage.synchronizable = FALSE; + localStorage.synchronizable = NO; localStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; if ([MASConfiguration currentConfiguration].ssoEnabled && [self isAccessGroupAccessible]) @@ -119,7 +119,7 @@ - (void)serviceWillStart // Shared storage // MASIKeyChainStore *sharedStorage = [MASIKeyChainStore keyChainStoreWithService:_sharedStorageServiceName accessGroup:self.accessGroup]; - sharedStorage.synchronizable = FALSE; + sharedStorage.synchronizable = NO; sharedStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; // From b0b92c46b821629dc6b6da7f0fef1991a4cf4318 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Fri, 6 Oct 2017 09:09:34 -0700 Subject: [PATCH 08/14] Exposed methods to allow developer set Keychain Synchronizable property, by default, the Keychain will not be synchronized through iCloud. --- MASFoundation/Classes/MAS.h | 20 +++++++++++++++++++ MASFoundation/Classes/MAS.m | 12 +++++++++++ .../services/access/MASAccessService.h | 18 +++++++++++++++++ .../services/access/MASAccessService.m | 19 ++++++++++++++---- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/MASFoundation/Classes/MAS.h b/MASFoundation/Classes/MAS.h index c4431e1a..84741825 100644 --- a/MASFoundation/Classes/MAS.h +++ b/MASFoundation/Classes/MAS.h @@ -148,6 +148,26 @@ +/** + * Sets BOOL indicator whether the Keychain is synchronized through iCloud. + * By default, the Keychain is not synchronized through iCloud. + * + * @param enabled BOOL YES to enable synchroniztion, NO to disable it. + */ ++ (void)setKeychainSynchronizable:(BOOL)enabled; + + + +/** + * Gets BOOL indicator of Keychain sincronization enabled or not. + * By default, the Keychain is not synchronized through iCloud. + * + * @return return BOOL value indicating Keychain sincronization is enabled or not + */ ++ (BOOL)isKeychainSynchronizable; + + + ///-------------------------------------- /// @name Start & Stop ///-------------------------------------- diff --git a/MASFoundation/Classes/MAS.m b/MASFoundation/Classes/MAS.m index d1981d96..a633832a 100644 --- a/MASFoundation/Classes/MAS.m +++ b/MASFoundation/Classes/MAS.m @@ -98,6 +98,18 @@ + (void)setGatewayMonitor:(MASGatewayMonitorStatusBlock)monitor } ++ (void)setKeychainSynchronizable:(BOOL)enabled +{ + [MASAccessService setKeychainSynchronizable:enabled]; +} + + ++ (BOOL)isKeychainSynchronizable +{ + return [MASAccessService isKeychainSynchronizable]; +} + + + (MASState)MASState { // diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.h b/MASFoundation/Classes/_private_/services/access/MASAccessService.h index 64dc044b..7ab122e0 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.h +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.h @@ -99,6 +99,24 @@ typedef NS_ENUM(NSInteger, MASAccessValueType) +/** + * Static boolean property indicating Keychain sincronization is enabled or not. + * + * @return return BOOL value indicating Keychain sincronization is enabled or not + */ ++ (BOOL)isKeychainSynchronizable; + + + +/** + * Setter of static boolean property indicating Keychain sincronization is enabled or not. + * + * @param enable BOOL value indicating Keychain sincronization is enabled or not + */ ++ (void)setKeychainSynchronizable:(BOOL)enable; + + + ///-------------------------------------- /// @name Shared Service ///-------------------------------------- diff --git a/MASFoundation/Classes/_private_/services/access/MASAccessService.m b/MASFoundation/Classes/_private_/services/access/MASAccessService.m index 1ee01a8e..efdb6e80 100644 --- a/MASFoundation/Classes/_private_/services/access/MASAccessService.m +++ b/MASFoundation/Classes/_private_/services/access/MASAccessService.m @@ -49,6 +49,7 @@ @implementation MASAccessService static BOOL _isPKCEEnabled_ = YES; +static BOOL _isKeychainSynchronizable_ = NO; # pragma mark - Properties @@ -64,6 +65,18 @@ + (void)enablePKCE:(BOOL)enable } ++ (BOOL)isKeychainSynchronizable +{ + return _isKeychainSynchronizable_; +} + + ++ (void)setKeychainSynchronizable:(BOOL)enable +{ + _isKeychainSynchronizable_ = enable; +} + + # pragma mark - Shared Service + (instancetype)sharedService @@ -110,8 +123,7 @@ - (void)serviceWillStart // Local storage // MASIKeyChainStore *localStorage = [MASIKeyChainStore keyChainStoreWithService:_localStorageServiceName]; - localStorage.synchronizable = NO; - localStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; + localStorage.synchronizable = _isKeychainSynchronizable_; if ([MASConfiguration currentConfiguration].ssoEnabled && [self isAccessGroupAccessible]) { @@ -119,8 +131,7 @@ - (void)serviceWillStart // Shared storage // MASIKeyChainStore *sharedStorage = [MASIKeyChainStore keyChainStoreWithService:_sharedStorageServiceName accessGroup:self.accessGroup]; - sharedStorage.synchronizable = NO; - sharedStorage.accessibility = MASIKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly; + sharedStorage.synchronizable = _isKeychainSynchronizable_; // // storage dictionary property From 098d786d37d86cd91f12539f69f2fb1be1f06846 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Wed, 11 Oct 2017 13:23:25 -0700 Subject: [PATCH 09/14] ARCHIVE_OUTPUTFOLDER update. --- MASFoundation.xcodeproj/project.pbxproj | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index e3351493..72546735 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -11,7 +11,8 @@ isa = PBXAggregateTarget; buildConfigurationList = 1059D3BC1B61C00500223267 /* Build configuration list for PBXAggregateTarget "UniversalFrameworkMASFoundation" */; buildPhases = ( - 1059D3BD1B61C00D00223267 /* ShellScript */, + 69DE19DB1F8E8A2300F4C7FE /* Log Build Settings */, + 1059D3BD1B61C00D00223267 /* Run Script */, ); dependencies = ( ); @@ -1984,18 +1985,33 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1059D3BD1B61C00D00223267 /* ShellScript */ = { + 1059D3BD1B61C00D00223267 /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); + name = "Run Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -e\n\n#---------------\n#Framework Name\n#---------------\n\nFRAMEWORK_NAME=MASFoundation\n\n\n#---------------\n#SDK Directory\n#---------------\n\nSDK_DIR=../iOS_SDK\n\n\n#-----------------------\n#CleanUp Build Cache\n#-----------------------\n\nxcodebuild -project $PROJECT_NAME.xcodeproj -configuration Debug -alltargets clean\nxcodebuild -project $PROJECT_NAME.xcodeproj -configuration Release -alltargets clean\n\n\n#-----------------------\n#CleanUp Previous Builds\n#-----------------------\n\n# Remove the framework from the Project Folder\nrm -Rf \"${PROJECT_DIR}/${FRAMEWORK_NAME}.framework\"\n\n# Remove Build folder from DerivedData\nrm -Rf \"${BUILD_DIR}\"\n\n\n#-----------------------\n#Creating New Builds\n#-----------------------\n\n# define output folder environment variable\nUNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal\nARCHIVE_OUTPUTFOLDER=${BUILD_DIR}/../Intermediates/ArchiveIntermediates/$PROJECT_NAME/IntermediateBuildFilesPath/UninstalledProducts/iphoneos\n\n# Archive framework for iPhoneOS with BitCode enabled\n#xcodebuild -scheme $PROJECT_NAME -configuration Release archive\n\nxcodebuild OTHER_CFLAGS=\"-fembed-bitcode\" -scheme $PROJECT_NAME -configuration Release archive CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\" -archivePath \"${BUILD_DIR}\"\n\n# Build framework for iPhoneOS\n#xcodebuild -target ${FRAMEWORK_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\"\n\n# Build framework for iPhoneSimulator\nxcodebuild -target ${FRAMEWORK_NAME} -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\"\n\n\n#-----------------------\n#Creating Universal Framework\n#-----------------------\n\nmkdir -p \"${UNIVERSAL_OUTPUTFOLDER}\"\nmkdir -p \"${SDK_DIR}\"\n\n\n# Build the universal library\nlipo -create -output \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}\" \"${ARCHIVE_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\" \"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\"\n\n# Copy the .framework folder of iphoneos\ncp -R \"${ARCHIVE_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework\" \"${UNIVERSAL_OUTPUTFOLDER}/\"\n\n# Delete the library for iphoneos\nrm \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\"\n\n# Move the Universal Library into our framework\nmv \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}\" \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/\"\n\n# Remove the _CodeSignature from the UniversalFramework\nrm -Rf \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/_CodeSignature\"\n\n# Copy the framework\ncp -R \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework\" \"${SDK_DIR}\"\n\n#-----------------------\n#Deleting Build Folder\n#-----------------------\n\n# Remove build folder from the Project Folder\nrm -Rf \"${PROJECT_DIR}/build\"\n\n"; + shellScript = "set -e\n\n#---------------\n#Framework Name\n#---------------\n\nFRAMEWORK_NAME=MASFoundation\n\n\n#---------------\n#SDK Directory\n#---------------\n\nSDK_DIR=../iOS_SDK\n\n\n#-----------------------\n#CleanUp Build Cache\n#-----------------------\n\nxcodebuild -project $PROJECT_NAME.xcodeproj -configuration Debug -alltargets clean\nxcodebuild -project $PROJECT_NAME.xcodeproj -configuration Release -alltargets clean\n\n\n#-----------------------\n#CleanUp Previous Builds\n#-----------------------\n\n# Remove the framework from the Project Folder\nrm -Rf \"${PROJECT_DIR}/${FRAMEWORK_NAME}.framework\"\n\n# Remove Build folder from DerivedData\nrm -Rf \"${BUILD_DIR}\"\n\n\n#-----------------------\n#Creating New Builds\n#-----------------------\n\n# define output folder environment variable\nUNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal\nARCHIVE_OUTPUTFOLDER=${OBJROOT}/ArchiveIntermediates/$PROJECT_NAME/IntermediateBuildFilesPath/UninstalledProducts/iphoneos\n\n# Archive framework for iPhoneOS with BitCode enabled\n#xcodebuild -scheme $PROJECT_NAME -configuration Release archive\n\nxcodebuild OTHER_CFLAGS=\"-fembed-bitcode\" -scheme $PROJECT_NAME -configuration Release archive CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\" -archivePath \"${BUILD_DIR}\"\n\n# Build framework for iPhoneOS\n#xcodebuild -target ${FRAMEWORK_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\"\n\n# Build framework for iPhoneSimulator\nxcodebuild -target ${FRAMEWORK_NAME} -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" CODE_SIGN_IDENTITY=\"iPhone Distribution: CA, Inc (RAKRWMN9VH)\"\n\n\n#-----------------------\n#Creating Universal Framework\n#-----------------------\n\nmkdir -p \"${UNIVERSAL_OUTPUTFOLDER}\"\nmkdir -p \"${SDK_DIR}\"\n\n\n# Build the universal library\nlipo -create -output \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}\" \"${ARCHIVE_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\" \"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\"\n\n# Copy the .framework folder of iphoneos\ncp -R \"${ARCHIVE_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework\" \"${UNIVERSAL_OUTPUTFOLDER}/\"\n\n# Delete the library for iphoneos\nrm \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}\"\n\n# Move the Universal Library into our framework\nmv \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}\" \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/\"\n\n# Remove the _CodeSignature from the UniversalFramework\nrm -Rf \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework/_CodeSignature\"\n\n# Copy the framework\ncp -R \"${UNIVERSAL_OUTPUTFOLDER}/${FRAMEWORK_NAME}.framework\" \"${SDK_DIR}\"\n\n#-----------------------\n#Deleting Build Folder\n#-----------------------\n\n# Remove build folder from the Project Folder\nrm -Rf \"${PROJECT_DIR}/build\"\n\n"; + }; + 69DE19DB1F8E8A2300F4C7FE /* Log Build Settings */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Log Build Settings"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/bash; + shellScript = export; }; /* End PBXShellScriptBuildPhase section */ From 088f8c38d26cfddf6c40c55187f8e03fb6df2960 Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 12 Oct 2017 15:39:51 -0700 Subject: [PATCH 10/14] US408725 : MQTT fails to re-establish connection when user logs-out, and re-logs-in with different user. --- MASFoundation/Classes/MASConstants.h | 7 +++ MASFoundation/Classes/MQTT/MASMQTTClient.m | 43 ++++++++++++++++--- .../services/model/MASModelService.m | 7 ++- MASFoundation/Classes/models/MASDevice.m | 5 +++ 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/MASFoundation/Classes/MASConstants.h b/MASFoundation/Classes/MASConstants.h index f6d668c3..003e0284 100644 --- a/MASFoundation/Classes/MASConstants.h +++ b/MASFoundation/Classes/MASConstants.h @@ -556,6 +556,13 @@ static NSString *const _Nonnull MASDeviceDidFailToDeregisterNotification = @"MAS static NSString *const _Nonnull MASDeviceDidDeregisterNotification = @"MASDeviceDidDeregisterNotification"; +/** + * The NSString constant for the device notification indicating that the MASDevice + * has reset locally. + */ +static NSString *const _Nonnull MASDeviceDidResetLocallyNotification = @"MASDeviceDidResetLocallyNotification"; + + ///-------------------------------------- /// @name User Notifications diff --git a/MASFoundation/Classes/MQTT/MASMQTTClient.m b/MASFoundation/Classes/MQTT/MASMQTTClient.m index 732fc50a..fdeb3739 100644 --- a/MASFoundation/Classes/MQTT/MASMQTTClient.m +++ b/MASFoundation/Classes/MQTT/MASMQTTClient.m @@ -80,31 +80,45 @@ @implementation MASMQTTClient + (instancetype)sharedClient { - static dispatch_once_t onceToken; - if (!_sharedClient) { - dispatch_once(&onceToken, ^{ - + @synchronized(self) + { if ([MASUser currentUser].isAuthenticated && [MASDevice currentDevice].isRegistered) { - + // // Init MQTT client for current gateway // _sharedClient = [[MASMQTTClient alloc] initWithClientId:[MASMQTTHelper mqttClientId] cleanSession:NO]; } else { - + //Return nil in case Authentication or Registration is not done yet. _sharedClient = nil; } - }); + } } return _sharedClient; } +- (void)clearConnection +{ + __block MASMQTTClient *blockSelf = self; + [self disconnectWithCompletionHandler:^(NSUInteger code) { + + if ([blockSelf isEqual:_sharedClient]) + { + @synchronized(self) + { + _sharedClient = nil; + } + } + }]; +} + + // Initialize is called just before the first object is allocated - (void)initialize { @@ -151,6 +165,19 @@ - (MASMQTTClient *)initWithClientId:(NSString *)clientId cleanSession:(BOOL)clea // } self.queue = dispatch_queue_create(cstrClientId, NULL); + + // + // Subscribe following information to reset the current MQTT session due to the change in SDK's authenticated session + // + // - user logout + // - device de-registration + // - device reset locally + // - gateway switch + // + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearConnection) name:MASUserDidLogoutNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearConnection) name:MASDeviceDidDeregisterNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearConnection) name:MASDeviceDidResetLocallyNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearConnection) name:MASWillSwitchGatewayServerNotification object:nil]; } _sharedClient = self; @@ -158,6 +185,7 @@ - (MASMQTTClient *)initWithClientId:(NSString *)clientId cleanSession:(BOOL)clea return self; } + #pragma mark - Setup methods -(void)setUsername:(NSString *)username Password:(NSString *)password @@ -590,6 +618,7 @@ - (void)disconnectWithCompletionHandler:(MQTTDisconnectionHandler)completionHand mosquitto_disconnect(mosq); } + - (void)reconnect:(NSNotification *)notification { [self reconnect]; diff --git a/MASFoundation/Classes/_private_/services/model/MASModelService.m b/MASFoundation/Classes/_private_/services/model/MASModelService.m index 92284303..c0225d2e 100644 --- a/MASFoundation/Classes/_private_/services/model/MASModelService.m +++ b/MASFoundation/Classes/_private_/services/model/MASModelService.m @@ -1480,7 +1480,7 @@ - (void)logOutDeviceAndClearLocalAccessToken:(BOOL)clearLocal completion:(MASCom // // Post the notification // - [[NSNotificationCenter defaultCenter] postNotificationName:MASDeviceDidFailToRegisterNotification object:blockSelf]; + [[NSNotificationCenter defaultCenter] postNotificationName:MASUserDidFailToLogoutNotification object:blockSelf]; return; } @@ -1496,6 +1496,11 @@ - (void)logOutDeviceAndClearLocalAccessToken:(BOOL)clearLocal completion:(MASCom [blockSelf clearCurrentUserForLogout]; } + // + // Post the notification + // + [[NSNotificationCenter defaultCenter] postNotificationName:MASUserDidLogoutNotification object:blockSelf]; + // // Set id_token and id_token_type to nil // diff --git a/MASFoundation/Classes/models/MASDevice.m b/MASFoundation/Classes/models/MASDevice.m index 645399ce..2f1e952e 100644 --- a/MASFoundation/Classes/models/MASDevice.m +++ b/MASFoundation/Classes/models/MASDevice.m @@ -119,6 +119,11 @@ - (void)resetLocally // re-establish URL session // [[MASNetworkingService sharedService] establishURLSession]; + + // + // Post the did reset locally notification + // + [[NSNotificationCenter defaultCenter] postNotificationName:MASDeviceDidResetLocallyNotification object:self]; } From c41194e40f03d5643c8ff11f0d8fa47363e4ffb2 Mon Sep 17 00:00:00 2001 From: James Go Date: Thu, 12 Oct 2017 15:45:57 -0700 Subject: [PATCH 11/14] US408725 : MQTT fails to re-establish connection when user logs-out, and re-logs-in with different user. --- MASFoundation/Classes/MQTT/MASMQTTClient.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MASFoundation/Classes/MQTT/MASMQTTClient.m b/MASFoundation/Classes/MQTT/MASMQTTClient.m index fdeb3739..deec5139 100644 --- a/MASFoundation/Classes/MQTT/MASMQTTClient.m +++ b/MASFoundation/Classes/MQTT/MASMQTTClient.m @@ -110,7 +110,7 @@ - (void)clearConnection if ([blockSelf isEqual:_sharedClient]) { - @synchronized(self) + @synchronized(blockSelf) { _sharedClient = nil; } From e1bbb875504ad66a71e922b304131c57591f6e66 Mon Sep 17 00:00:00 2001 From: James Go Date: Fri, 13 Oct 2017 12:54:09 -0700 Subject: [PATCH 12/14] DE321921 : [iOS][MASFoundation] Remove hard coded endpoint value in MASConfiguration --- MASFoundation/Classes/models/MASConfiguration.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MASFoundation/Classes/models/MASConfiguration.m b/MASFoundation/Classes/models/MASConfiguration.m index edd665b7..3d2cba88 100644 --- a/MASFoundation/Classes/models/MASConfiguration.m +++ b/MASFoundation/Classes/models/MASConfiguration.m @@ -100,7 +100,7 @@ static NSString *const MASClientInitializeEndpoint = @"client_credential_init_endpoint_path"; // string static NSString *const MASDeviceListEndpoint = @"device_list_endpoint_path"; // string static NSString *const MASDeviceRegisterEndpoint = @"device_register_endpoint_path"; // string -static NSString *const MASDeviceRegisterClientEndpoint = @"device_register_client_endpoint_path"; // string +static NSString *const MASDeviceRegisterClientEndpoint = @"device_client_register_endpoint_path"; // string static NSString *const MASDeviceRenewEndpoint = @"device_renew_endpoint_path"; // string static NSString *const MASDeviceRemoveEndpoint = @"device_remove_endpoint_path"; // string static NSString *const MASEnterpriseBrowserEndpoint = @"enterprise_browser_endpoint_path"; // string @@ -299,8 +299,6 @@ - (void)initializeEndpointsFromInfo:(NSDictionary *)info // // Temporary Hardcoded Endpoints // - _endpointKeysToPaths_[MASDeviceRegisterClientEndpoint] = @"/connect/device/register/client"; - _endpointKeysToPaths_[MASUsersLDAPEndpoint] = @"/scim/ldap/v2/users"; _endpointKeysToPaths_[MASUserGroupsLDAPEndpoint] = @"/scim/ldap/v2/groups"; _endpointKeysToPaths_[MASUsersMSADEndpoint] = @"/scim/msad/v2/users"; From c1e691b47856b45a70f3f4b426050883173971cf Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Mon, 16 Oct 2017 17:34:24 -0700 Subject: [PATCH 13/14] Resolved merge conflicts in project file --- MASFoundation.xcodeproj/project.pbxproj | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index 72546735..e087a7a7 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -564,6 +564,12 @@ 10E0279B1F72B10100EAB103 /* RNDecryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNDecryptor.m; sourceTree = ""; }; 10E0279C1F72B10100EAB103 /* RNEncryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNEncryptor.h; sourceTree = ""; }; 10E0279D1F72B10100EAB103 /* RNEncryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNEncryptor.m; sourceTree = ""; }; + 699C17901F9585BC008C1B11 /* MASRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASRequest.m; sourceTree = ""; }; + 699C17911F9585BC008C1B11 /* MASRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASRequest.h; sourceTree = ""; }; + 699C17921F9585BC008C1B11 /* MASRequestBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MASRequestBuilder.h; sourceTree = ""; }; + 699C17931F9585BD008C1B11 /* MASRequestBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MASRequestBuilder.m; sourceTree = ""; }; + 699C17951F958660008C1B11 /* MASRequest+MASPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MASRequest+MASPrivate.h"; sourceTree = ""; }; + 699C17961F958660008C1B11 /* MASRequest+MASPrivate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "MASRequest+MASPrivate.m"; sourceTree = ""; }; A4150E691BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASIJSONResponseSerializer+MASPrivate.h"; sourceTree = ""; }; A4150E6A1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MASIJSONResponseSerializer+MASPrivate.m"; sourceTree = ""; }; A4150E6B1BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+MASPrivate.h"; sourceTree = ""; }; @@ -1044,6 +1050,15 @@ path = libmosquitto123; sourceTree = ""; }; + 699C17941F958660008C1B11 /* Network */ = { + isa = PBXGroup; + children = ( + 699C17951F958660008C1B11 /* MASRequest+MASPrivate.h */, + 699C17961F958660008C1B11 /* MASRequest+MASPrivate.m */, + ); + path = Network; + sourceTree = ""; + }; A4150EBD1BF16D9A00037E27 /* network */ = { isa = PBXGroup; children = ( @@ -1407,6 +1422,7 @@ isa = PBXGroup; children = ( CB99752B1EDCA749006CEBB1 /* AuthCredentials */, + 699C17941F958660008C1B11 /* Network */, CB1907F11C1794FC00A5EF16 /* MASAccess.h */, CB1907F21C1794FC00A5EF16 /* MASAccess.m */, A4831AE81BD1A87C007B4AE6 /* MASApplication+MASPrivate.h */, @@ -1456,6 +1472,10 @@ CB23578A1F0EE35A00D4C420 /* Network */ = { isa = PBXGroup; children = ( + 699C17911F9585BC008C1B11 /* MASRequest.h */, + 699C17901F9585BC008C1B11 /* MASRequest.m */, + 699C17921F9585BC008C1B11 /* MASRequestBuilder.h */, + 699C17931F9585BD008C1B11 /* MASRequestBuilder.m */, ); path = Network; sourceTree = ""; From a628cf8098bbd8fc7c6fdafa7256a8388e931f0e Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Tue, 17 Oct 2017 11:17:15 -0700 Subject: [PATCH 14/14] Fixed missing headers issue. --- MASFoundation.xcodeproj/project.pbxproj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MASFoundation.xcodeproj/project.pbxproj b/MASFoundation.xcodeproj/project.pbxproj index e087a7a7..aab8da93 100644 --- a/MASFoundation.xcodeproj/project.pbxproj +++ b/MASFoundation.xcodeproj/project.pbxproj @@ -152,6 +152,12 @@ 10E027A51F72B10100EAB103 /* RNDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 10E0279B1F72B10100EAB103 /* RNDecryptor.m */; }; 10E027A61F72B10100EAB103 /* RNEncryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 10E0279C1F72B10100EAB103 /* RNEncryptor.h */; }; 10E027A71F72B10100EAB103 /* RNEncryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 10E0279D1F72B10100EAB103 /* RNEncryptor.m */; }; + 69B7DF681F9675600056DD3A /* MASRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 699C17911F9585BC008C1B11 /* MASRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69B7DF691F9675600056DD3A /* MASRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 699C17901F9585BC008C1B11 /* MASRequest.m */; }; + 69B7DF6A1F9675600056DD3A /* MASRequestBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 699C17921F9585BC008C1B11 /* MASRequestBuilder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69B7DF6B1F9675600056DD3A /* MASRequestBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 699C17931F9585BD008C1B11 /* MASRequestBuilder.m */; }; + 69B7DF6C1F96756B0056DD3A /* MASRequest+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 699C17951F958660008C1B11 /* MASRequest+MASPrivate.h */; }; + 69B7DF6D1F96756B0056DD3A /* MASRequest+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 699C17961F958660008C1B11 /* MASRequest+MASPrivate.m */; }; A4150E6F1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A4150E691BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.h */; }; A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = A4150E6A1BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m */; }; A4150E711BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A4150E6B1BF1643900037E27 /* NSMutableURLRequest+MASPrivate.h */; }; @@ -1671,6 +1677,8 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 69B7DF6A1F9675600056DD3A /* MASRequestBuilder.h in Headers */, + 69B7DF681F9675600056DD3A /* MASRequest.h in Headers */, CBAFD24C1F2BD46C0034DF02 /* MASSecurityConfiguration.h in Headers */, CB9975421EDF5761006CEBB1 /* MASAuthCredentials.h in Headers */, CB99754A1EDF57D6006CEBB1 /* MASAuthCredentialsPassword.h in Headers */, @@ -1894,6 +1902,7 @@ CBD25AFB1E78C47C00DFB47F /* JWTClaimsSet.h in Headers */, 105B2F461CA6B3EA0005A2D0 /* pkcs7.h in Headers */, 105B2F441CA6B3EA0005A2D0 /* pem2.h in Headers */, + 69B7DF6C1F96756B0056DD3A /* MASRequest+MASPrivate.h in Headers */, A417BA511BF033C300EC9BCB /* CLLocation+MASPrivate.h in Headers */, CBD25B011E78C47C00DFB47F /* JWTCoding+ResultTypes.h in Headers */, A4831AF61BD1A8CA007B4AE6 /* MASDevice+MASPrivate.h in Headers */, @@ -2135,6 +2144,7 @@ A46F49C51C2F5FC500A4C370 /* MASIHTTPRequestOperation.m in Sources */, A4150E701BF1643900037E27 /* MASIJSONResponseSerializer+MASPrivate.m in Sources */, A417BA521BF033C300EC9BCB /* CLLocation+MASPrivate.m in Sources */, + 69B7DF6D1F96756B0056DD3A /* MASRequest+MASPrivate.m in Sources */, A4831AB21BD1A551007B4AE6 /* MASFile.m in Sources */, CB0B585A1E258C2A00BC0163 /* MASAuthorizationResponse.m in Sources */, CB5E4C651C1D1B56001B3B8A /* MASGetURLRequest.m in Sources */, @@ -2157,6 +2167,7 @@ CB2357931F0EF53600D4C420 /* MASURLSessionManager.m in Sources */, 10738A291C711C2F00B7E87E /* mosquitto.c in Sources */, A4150EE81BF16E5B00037E27 /* MASFileService.m in Sources */, + 69B7DF691F9675600056DD3A /* MASRequest.m in Sources */, CBD25B081E78C47C00DFB47F /* JWTCoding+VersionTwo.m in Sources */, A483C2021BE6D0C5007572CE /* CBCentralManager+MASPrivate.m in Sources */, CBD25AFA1E78C47C00DFB47F /* JWTClaim.m in Sources */, @@ -2166,6 +2177,7 @@ CB5E4C751C1D26BA001B3B8A /* MASPatchURLRequest.m in Sources */, A46F49CB1C2F5FC500A4C370 /* MASINetworkActivityLogger.m in Sources */, A46F49BB1C2F5FC500A4C370 /* fmemopen.c in Sources */, + 69B7DF6B1F9675600056DD3A /* MASRequestBuilder.m in Sources */, A4150EFE1BF16EE200037E27 /* MASSecurityService.m in Sources */, 10738A371C711C2F00B7E87E /* time_mosq.c in Sources */, A46F49C21C2F5FC500A4C370 /* MASIKeyChainStore.m in Sources */,