github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/clients/ios-objc/photobackup/LACamliClient/LACamliUtil.m (about) 1 // 2 // LACamliUtil.m 3 // photobackup 4 // 5 // Created by Nick O'Neill on 11/29/13. 6 // Copyright (c) 2013 The Camlistore Authors. All rights reserved. 7 // 8 9 #import "LACamliUtil.h" 10 #import "LAAppDelegate.h" 11 #import <CommonCrypto/CommonDigest.h> 12 #import <SSKeychain.h> 13 14 @implementation LACamliUtil 15 16 static NSString* const serviceName = @"org.camlistore.credentials"; 17 18 // h/t AFNetworking 19 + (NSString*)base64EncodedStringFromString:(NSString*)string 20 { 21 NSData* data = [NSData dataWithBytes:[string UTF8String] 22 length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; 23 NSUInteger length = [data length]; 24 NSMutableData* mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; 25 26 uint8_t* input = (uint8_t*)[data bytes]; 27 uint8_t* output = (uint8_t*)[mutableData mutableBytes]; 28 29 for (NSUInteger i = 0; i < length; i += 3) { 30 NSUInteger value = 0; 31 for (NSUInteger j = i; j < (i + 3); j++) { 32 value <<= 8; 33 if (j < length) { 34 value |= (0xFF & input[j]); 35 } 36 } 37 38 static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 39 40 NSUInteger idx = (i / 3) * 4; 41 output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F]; 42 output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F]; 43 output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '='; 44 output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0) & 0x3F] : '='; 45 } 46 47 return [[NSString alloc] initWithData:mutableData 48 encoding:NSASCIIStringEncoding]; 49 } 50 51 #pragma mark - keychain stuff 52 53 + (NSString*)passwordForUsername:(NSString*)username 54 { 55 NSError* error; 56 NSString* password = [SSKeychain passwordForService:CamliCredentialsKey 57 account:username 58 error:&error]; 59 60 if (!password || error) { 61 [LACamliUtil errorText:@[ 62 @"error getting password: ", 63 [error description] 64 ]]; 65 return nil; 66 } 67 68 return password; 69 } 70 71 + (BOOL)savePassword:(NSString*)password forUsername:(NSString*)username 72 { 73 NSError* error; 74 BOOL setPassword = [SSKeychain setPassword:password 75 forService:CamliCredentialsKey 76 account:username 77 error:&error]; 78 79 if (!setPassword || error) { 80 [LACamliUtil errorText:@[ 81 @"error setting password: ", 82 [error description] 83 ]]; 84 85 return NO; 86 } 87 88 return YES; 89 } 90 91 #pragma mark - hashes 92 93 + (NSString*)blobRef:(NSData*)data 94 { 95 uint8_t digest[CC_SHA1_DIGEST_LENGTH]; 96 97 CC_SHA1(data.bytes, data.length, digest); 98 99 NSMutableString* output = [NSMutableString stringWithCapacity:(CC_SHA1_DIGEST_LENGTH * 2) + 5]; 100 [output appendString:@"sha1-"]; 101 102 for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { 103 [output appendFormat:@"%02x", digest[i]]; 104 } 105 106 return output; 107 } 108 109 #pragma mark - dates 110 111 + (NSString*)rfc3339StringFromDate:(NSDate*)date 112 { 113 NSDateFormatter* rfc3339DateFormatter = [[NSDateFormatter alloc] init]; 114 115 NSLocale* enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 116 117 [rfc3339DateFormatter setLocale:enUSPOSIXLocale]; 118 [rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"]; 119 [rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 120 121 return [rfc3339DateFormatter stringFromDate:date]; 122 } 123 124 #pragma mark - yucky logging hack 125 126 + (void)logText:(NSArray*)logs 127 { 128 NSMutableString* logString = [NSMutableString string]; 129 130 for (NSString* log in logs) { 131 [logString appendString:log]; 132 } 133 134 LALog(@"LOG: %@", logString); 135 136 [[NSNotificationCenter defaultCenter] postNotificationName:@"logtext" 137 object:@{ 138 @"text" : logString 139 }]; 140 } 141 142 + (void)statusText:(NSArray*)statuses 143 { 144 NSMutableString* statusString = [NSMutableString string]; 145 146 for (NSString* status in statuses) { 147 [statusString appendString:status]; 148 } 149 150 LALog(@"STATUS: %@", statusString); 151 152 [[NSNotificationCenter defaultCenter] postNotificationName:@"statusText" 153 object:@{ 154 @"text" : statusString 155 }]; 156 } 157 158 + (void)errorText:(NSArray*)errors 159 { 160 NSMutableString* errorString = [NSMutableString string]; 161 162 for (NSString* error in errors) { 163 [errorString appendString:error]; 164 } 165 166 LALog(@"ERROR: %@", errorString); 167 168 [[NSNotificationCenter defaultCenter] postNotificationName:@"errorText" 169 object:@{ 170 @"text" : errorString 171 }]; 172 } 173 174 @end