From d3faaa2264172475358b18eee87f845373911a18 Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Tue, 5 Sep 2017 16:28:58 -0700 Subject: [PATCH 1/5] 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 2/5] 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 3/5] 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 4/5] 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 c1e691b47856b45a70f3f4b426050883173971cf Mon Sep 17 00:00:00 2001 From: Rodrigo Reis Date: Mon, 16 Oct 2017 17:34:24 -0700 Subject: [PATCH 5/5] 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 = "";