Files
firebase-ios-sdk/Example/Database/Tests/Helpers/FTestAuthTokenGenerator.m
T
2017-05-15 12:27:07 -07:00

91 lines
3.5 KiB
Objective-C

/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <CommonCrypto/CommonHMAC.h>
#import "FTestAuthTokenGenerator.h"
#import "Base64.h"
@implementation FTestAuthTokenGenerator
+ (NSString *) jsonStringForData:(id)data {
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:data
options:kNilOptions error:nil];
return [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
}
+ (NSNumber *) tokenVersion {
return @0;
}
+ (NSMutableDictionary *) createOptionsClaims:(NSDictionary *)options {
NSMutableDictionary* claims = [[NSMutableDictionary alloc] init];
if (options) {
NSDictionary* map = @{
@"expires": @"exp",
@"notBefore": @"nbf",
@"admin": @"admin",
@"debug": @"debug",
@"simulate": @"simulate"
};
for (NSString* claim in map) {
if (options[claim] != nil) {
NSString* claimName = [map objectForKey:claim];
id val = [options objectForKey:claim];
[claims setObject:val forKey:claimName];
}
}
}
return claims;
}
+ (NSString *) webSafeBase64:(NSString *)encoded {
return [[[encoded stringByReplacingOccurrencesOfString:@"=" withString:@""] stringByReplacingOccurrencesOfString:@"+" withString:@"-"] stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
}
+ (NSString *) base64EncodeString:(NSString *)target {
return [self webSafeBase64:[target base64EncodedString]];
}
+ (NSString *) tokenWithClaims:(NSDictionary *)claims andSecret:(NSString *)secret {
NSDictionary* headerData = @{@"typ": @"JWT", @"alg": @"HS256"};
NSString* encodedHeader = [self base64EncodeString:[self jsonStringForData:headerData]];
NSString* encodedClaims = [self base64EncodeString:[self jsonStringForData:claims]];
NSString* secureBits = [NSString stringWithFormat:@"%@.%@", encodedHeader, encodedClaims];
const char *cKey = [secret cStringUsingEncoding:NSUTF8StringEncoding];
const char *cData = [secureBits cStringUsingEncoding:NSUTF8StringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData* hmac = [NSData dataWithBytesNoCopy:cHMAC length:CC_SHA256_DIGEST_LENGTH freeWhenDone:NO];
NSString* encodedHmac = [self webSafeBase64:[hmac base64EncodedString]];
return [NSString stringWithFormat:@"%@.%@.%@", encodedHeader, encodedClaims, encodedHmac];
}
+ (NSString *) tokenWithSecret:(NSString *)secret authData:(NSDictionary *)data andOptions:(NSDictionary *)options {
NSMutableDictionary* claims = [self createOptionsClaims:options];
[claims setObject:[self tokenVersion] forKey:@"v"];
NSNumber* now = [NSNumber numberWithDouble:[[NSDate date] timeIntervalSince1970]];
[claims setObject:now forKey:@"iat"];
[claims setObject:data forKey:@"d"];
return [self tokenWithClaims:claims andSecret:secret];
}
@end