mirror of
https://github.com/danog/Telegram.git
synced 2024-12-04 02:17:51 +01:00
135 lines
3.9 KiB
Objective-C
Executable File
135 lines
3.9 KiB
Objective-C
Executable File
//
|
|
// GDCredentialManager.m
|
|
// GDFileManagerExample
|
|
//
|
|
// Created by Graham Dennis on 11/07/13.
|
|
// Copyright (c) 2013 Graham Dennis. All rights reserved.
|
|
//
|
|
|
|
#import "GDCredentialManager.h"
|
|
#import "GDCredentialManager_Private.h"
|
|
|
|
#import "GDKeychainCredentialManager.h"
|
|
|
|
#import "GDClientCredential.h"
|
|
#import "GDAPIToken.h"
|
|
|
|
static GDCredentialManager *sharedCredentialManager;
|
|
|
|
@interface GDCredentialManager ()
|
|
|
|
@property (nonatomic, copy) NSDictionary *keyedClientCredentials;
|
|
|
|
@end
|
|
|
|
@implementation GDCredentialManager
|
|
|
|
+ (void)setSharedCredentialManager:(GDCredentialManager *)credentialManager
|
|
{
|
|
sharedCredentialManager = credentialManager;
|
|
}
|
|
|
|
+ (GDCredentialManager *)sharedCredentialManager
|
|
{
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken, ^{
|
|
if (!sharedCredentialManager) {
|
|
sharedCredentialManager = [GDKeychainCredentialManager new];
|
|
}
|
|
});
|
|
|
|
return sharedCredentialManager;
|
|
}
|
|
|
|
#if !OS_OBJECT_USE_OBJC
|
|
- (void)dealloc
|
|
{
|
|
if (self.isolationQueue) {
|
|
dispatch_release(self.isolationQueue);
|
|
self.isolationQueue = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
- (id)init
|
|
{
|
|
if ((self = [super init])) {
|
|
self.isolationQueue = dispatch_queue_create("org.telegram.KeychainCredentialManager", DISPATCH_QUEUE_CONCURRENT);
|
|
self.keyedClientCredentials = [NSDictionary new];
|
|
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)addCredential:(GDClientCredential *)credential forAccount:(NSString *)account
|
|
{
|
|
if (!credential) return;
|
|
if (![credential isValid]) return;
|
|
|
|
[self mutateClientCredentialsForAccount:account asyncMutationBlock:^(NSMutableArray *clientCredentials) {
|
|
[clientCredentials removeObject:credential];
|
|
[clientCredentials insertObject:credential atIndex:0];
|
|
}];
|
|
}
|
|
|
|
- (void)removeCredential:(GDClientCredential *)credential forAccount:(NSString *)account
|
|
{
|
|
if (!credential) return;
|
|
|
|
[self mutateClientCredentialsForAccount:account asyncMutationBlock:^(NSMutableArray *clientCredentials) {
|
|
[clientCredentials removeObject:credential];
|
|
}];
|
|
}
|
|
|
|
- (void)mutateClientCredentialsForAccount:(NSString *)account asyncMutationBlock:(void (^)(NSMutableArray *clientCredentials))mutationBlock
|
|
{
|
|
NSParameterAssert(account);
|
|
|
|
dispatch_barrier_async(self.isolationQueue, ^{
|
|
NSMutableArray *clientCredentials = [NSMutableArray arrayWithArray:self.keyedClientCredentials[account]];
|
|
if (!clientCredentials)
|
|
clientCredentials = [NSMutableArray new];
|
|
|
|
mutationBlock(clientCredentials);
|
|
|
|
NSMutableDictionary *mutableKeyedClientCredentials = [self.keyedClientCredentials mutableCopy];
|
|
NSArray *immutableClientCredentials = [clientCredentials copy];
|
|
mutableKeyedClientCredentials[account] = immutableClientCredentials;
|
|
|
|
self.keyedClientCredentials = [mutableKeyedClientCredentials copy];
|
|
|
|
[self saveCredentials:immutableClientCredentials forAccount:account];
|
|
});
|
|
}
|
|
|
|
- (NSArray *)clientCredentialsForAccount:(NSString *)account
|
|
{
|
|
__block NSArray *clientCredentials = nil;
|
|
dispatch_sync(self.isolationQueue, ^{
|
|
clientCredentials = self.keyedClientCredentials[account];
|
|
if (!clientCredentials) {
|
|
clientCredentials = [self loadCredentialsForAccount:account];
|
|
NSMutableDictionary *mutableKeyedCredentials = [self.keyedClientCredentials mutableCopy];
|
|
mutableKeyedCredentials[account] = clientCredentials;
|
|
self.keyedClientCredentials = [mutableKeyedCredentials copy];
|
|
}
|
|
});
|
|
return clientCredentials;
|
|
}
|
|
|
|
#pragma mark - Subclasses to override
|
|
|
|
- (void)saveCredentials:(NSArray *)__unused credentials forAccount:(NSString *)__unused account
|
|
{
|
|
[self doesNotRecognizeSelector:_cmd];
|
|
}
|
|
|
|
- (NSArray *)loadCredentialsForAccount:(NSString *)__unused account
|
|
{
|
|
[self doesNotRecognizeSelector:_cmd];
|
|
return nil;
|
|
}
|
|
|
|
@end
|