From bdaa7e8cf8d293ed6698edbeb7342d6075c3f8ec Mon Sep 17 00:00:00 2001 From: Borja Arias Drake Date: Wed, 24 Oct 2018 15:11:17 +0200 Subject: [PATCH] Adding a sensitiveParameterKeyPahts property to HMRequest class to prevent sensitive information from being included in the description. --- Hermod-tvos.podspec.json | 2 +- Hermod.podspec.json | 2 +- .../Hermod.xcodeproj/project.pbxproj | 6 ++ Source Code/HMRequest.h | 5 ++ Source Code/HMRequest.m | 6 +- .../Helpers/NSDictionary+DescriptionHelpers.h | 20 ++++++ .../Helpers/NSDictionary+DescriptionHelpers.m | 64 +++++++++++++++++++ 7 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 Source Code/Helpers/NSDictionary+DescriptionHelpers.h create mode 100644 Source Code/Helpers/NSDictionary+DescriptionHelpers.m diff --git a/Hermod-tvos.podspec.json b/Hermod-tvos.podspec.json index 7d2ad9f..f1f6dd0 100644 --- a/Hermod-tvos.podspec.json +++ b/Hermod-tvos.podspec.json @@ -1,6 +1,6 @@ { "name": "Hermod-tvos", - "version": "1.1.1", + "version": "1.1.2", "summary": "User friendly HTTP client on top of AFNetworking", "description": "Hermod defines a simple, easy to use, intuitive and flexible HTTP client on top of AFNetworking.", "homepage": "https://github.com/mobilejazz/Hermod", diff --git a/Hermod.podspec.json b/Hermod.podspec.json index a668dca..8158a1b 100644 --- a/Hermod.podspec.json +++ b/Hermod.podspec.json @@ -1,6 +1,6 @@ { "name": "Hermod", - "version": "1.1.1", + "version": "1.1.2", "summary": "User friendly HTTP client on top of AFNetworking", "description": "Hermod defines a simple, easy to use, intuitive and flexible HTTP client on top of AFNetworking.", "homepage": "https://github.com/mobilejazz/Hermod", diff --git a/Sample Project/Hermod.xcodeproj/project.pbxproj b/Sample Project/Hermod.xcodeproj/project.pbxproj index 2d4ef11..627ced9 100644 --- a/Sample Project/Hermod.xcodeproj/project.pbxproj +++ b/Sample Project/Hermod.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0082ED3E2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 0082ED3C2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.m */; }; 5277E9351D1D3AD6004613F7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5277E9341D1D3AD6004613F7 /* main.m */; }; 5277E9381D1D3AD6004613F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5277E9371D1D3AD6004613F7 /* AppDelegate.m */; }; 5277E93B1D1D3AD6004613F7 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5277E93A1D1D3AD6004613F7 /* ViewController.m */; }; @@ -46,6 +47,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0082ED3C2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+DescriptionHelpers.m"; sourceTree = ""; }; + 0082ED3D2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+DescriptionHelpers.h"; sourceTree = ""; }; 5277E9311D1D3AD5004613F7 /* Hermod- TVOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Hermod- TVOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 5277E9341D1D3AD6004613F7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 5277E9361D1D3AD6004613F7 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -269,6 +272,8 @@ D203B7AE1BCE74990088C315 /* HMClientKeychainManager.m */, D204290C1AC401D1002F18FD /* NSString+HMClientMD5Hashing.h */, D204290D1AC401D1002F18FD /* NSString+HMClientMD5Hashing.m */, + 0082ED3D2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.h */, + 0082ED3C2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.m */, ); path = Helpers; sourceTree = ""; @@ -481,6 +486,7 @@ D20429051AC4019D002F18FD /* HMConstants.m in Sources */, 529D82861B74F51C00EEC7FB /* HMHTTPOfflineCacheSessionManager.m in Sources */, D2FEE5EC1D91668A00443CD6 /* HMConfigurationManager.m in Sources */, + 0082ED3E2180A1FC004E4556 /* NSDictionary+DescriptionHelpers.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source Code/HMRequest.h b/Source Code/HMRequest.h index 7e10fc3..9c01d98 100644 --- a/Source Code/HMRequest.h +++ b/Source Code/HMRequest.h @@ -61,6 +61,11 @@ extern NSTimeInterval const HMRequestDefaultTimeoutInterval; **/ @property (nonatomic, assign) NSTimeInterval timeoutInterval; +/** + The keyPaths included in this array will not be logged. + */ +@property (nonatomic, strong, readwrite) NSArray *sensitiveParameterKeyPahts; + /** ************************************************* ** * @name Identifying the request ** ************************************************* **/ diff --git a/Source Code/HMRequest.m b/Source Code/HMRequest.m index 66b8fe0..c3913d5 100644 --- a/Source Code/HMRequest.m +++ b/Source Code/HMRequest.m @@ -16,6 +16,7 @@ #import "HMRequest.h" #import "NSString+HMClientMD5Hashing.h" +#import "NSDictionary+DescriptionHelpers.h" NSTimeInterval const HMRequestDefaultTimeoutInterval = 0; @@ -54,6 +55,7 @@ - (instancetype)initWithCoder:(NSCoder *)coder _httpMethod = [coder decodeIntegerForKey:@"httpMethod"]; _path = [coder decodeObjectForKey:@"path"]; _timeoutInterval = [coder decodeIntegerForKey:@"timeoutInterval"]; + _sensitiveParameterKeyPahts = [coder decodeObjectForKey:@"sensitiveParameterKeyPahts"]; } return self; } @@ -64,6 +66,7 @@ - (void)encodeWithCoder:(NSCoder *)coder [coder encodeInteger:_httpMethod forKey:@"httpMethod"]; [coder encodeObject:_path forKey:@"path"]; [coder encodeInteger:_timeoutInterval forKey:@"timeoutInterval"]; + [coder encodeObject:_sensitiveParameterKeyPahts forKey:@"sensitiveParameterKeyPahts"]; } - (instancetype)copyWithZone:(NSZone *)zone @@ -74,6 +77,7 @@ - (instancetype)copyWithZone:(NSZone *)zone request.parameters = [_parameters copy]; request.path = [_path copy]; request.timeoutInterval = _timeoutInterval; + request.sensitiveParameterKeyPahts = [_sensitiveParameterKeyPahts copy]; return request; } @@ -109,7 +113,7 @@ - (NSString*)description self.identifier, _path, NSStringFromHMHTTPMethod(_httpMethod), - _parameters.description]; + [_parameters hm_descriptionRemovingKeyPaths:self.sensitiveParameterKeyPahts]]; } #pragma mark Public Methods diff --git a/Source Code/Helpers/NSDictionary+DescriptionHelpers.h b/Source Code/Helpers/NSDictionary+DescriptionHelpers.h new file mode 100644 index 0000000..4682a22 --- /dev/null +++ b/Source Code/Helpers/NSDictionary+DescriptionHelpers.h @@ -0,0 +1,20 @@ +// +// NSDictionary+DescriptionHelpers.h +// Hermod +// +// Created by Borja Arias Drake on 18/10/2018. +// + +#import + +@interface NSDictionary (DescriptionHelpers) + +/** + Generates a description of the dictionary where there keypaths passed by parameter have been removed. + + @param keyPaths Elements in these keypaths will be removed from the description. + @return A description of the dictionary without the specified keypaths. + */ +- (NSString *)hm_descriptionRemovingKeyPaths:(NSArray *)keyPaths; + +@end diff --git a/Source Code/Helpers/NSDictionary+DescriptionHelpers.m b/Source Code/Helpers/NSDictionary+DescriptionHelpers.m new file mode 100644 index 0000000..f5a3f62 --- /dev/null +++ b/Source Code/Helpers/NSDictionary+DescriptionHelpers.m @@ -0,0 +1,64 @@ +// +// NSDictionary+DescriptionHelpers.m +// Hermod +// +// Created by Borja Arias Drake on 18/10/2018. +// + +#import "NSDictionary+DescriptionHelpers.h" + +@implementation NSDictionary (DescriptionHelpers) + +- (NSString *)hm_descriptionRemovingKeyPaths:(NSArray *)keyPaths +{ + if (keyPaths == nil || keyPaths.count == 0) { + return self.description; + } + + NSDictionary *copy = [self hm_deepCopyRemovingKeyPaths:keyPaths currentKeyPath:@""]; + return copy.description; +} + +- (NSDictionary *)hm_deepCopyRemovingKeyPaths:(NSArray *)keypathsToRemove currentKeyPath:(NSString *)currentKeyPath +{ + NSMutableDictionary *newDictionary = [NSMutableDictionary new]; + [self enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + + // Generate next keyPath + NSString *nextKeyPath = [self hm_appendComponent:key toCurrentKeyPath:currentKeyPath]; + + // Quit if keypath is in list + if ([keypathsToRemove containsObject:nextKeyPath]) { + // Base case + return; + } + + if (!([obj isKindOfClass:NSDictionary.class] || [obj isKindOfClass:NSMutableDictionary.class])) { + // Base case + newDictionary[key] = [obj copy]; + return; + } + + // Recursion step + newDictionary[key] = [obj hm_deepCopyRemovingKeyPaths:keypathsToRemove currentKeyPath:nextKeyPath]; + }]; + + return [newDictionary copy]; +} + +- (NSString *)hm_appendComponent:(NSString *)component toCurrentKeyPath:(NSString *)keyPath +{ + NSString *nextKeyPath = nil; + if (keyPath.length == 0) + { + nextKeyPath = [keyPath stringByAppendingFormat:@"%@", component]; + } + else + { + nextKeyPath = [keyPath stringByAppendingFormat:@".%@", component]; + } + + return nextKeyPath; +} + +@end