1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Kim Wittenburg 15062dfb27 Archive Project
2017-07-25 17:21:13 +02:00

173 lines
5.5 KiB
Objective-C
Executable File

//
// NYTAuthentication.m
// Notifications for YouTube
//
// Created by Kim Wittenburg on 21.07.13.
// Copyright (c) 2013 Kim Wittenburg. All rights reserved.
//
#import "NYTAuthentication.h"
// API Imports
#import "OAuth2.h"
// Core Imports
#import "NYTUser.h"
#import "NYTUtil.h"
#import "NYTUpdateManager.h"
// Google Access Constants
NSString * const DeveloperKey = @"key=AI39si6ubNmTeFzFTFz27hFn6r-51knz0_CDWvqgyL-nVKBcFWu5C_c46TWQcHTwwK9bOBlrhdlKatyEqjEnJhZd2dMB7UgFhQ";
NSString * const DeveloperKeyHTTPHeaderField = @"X-GData-Key";
NSString * const ClientID = @"908431532405.apps.googleusercontent.com";
NSString * const ClientSecret = @"hKcyoNAzEIuHZaz0pdTUBMBv";
NSString * const KeychainItemName = @"Notifications for YouTube";
@interface NYTAuthentication ()
@property (readwrite) GTMOAuth2Authentication *authentication;
@property (readwrite) NYTUser *loggedInUser;
@end
@implementation NYTAuthentication
#pragma mark *** Initialization ***
static NYTAuthentication *sharedAuthentication = nil;
+ (NYTAuthentication *)sharedAuthentication
{
if (!sharedAuthentication) {
sharedAuthentication = [[self alloc] init];
}
return sharedAuthentication;
}
- (id)init
{
// Allow exactly one instance at all (for any way of initialization)
if (sharedAuthentication) {
return sharedAuthentication;
}
self = [super init];
if (self) {
sharedAuthentication = self;
}
return self;
}
#pragma mark *** KVO/KVC Additions to Properties ***
+ (NSSet *)keyPathsForValuesAffectingIsLoggedIn
{
return [NSSet setWithObjects:@"authentication", nil];
}
#pragma mark *** Login ***
- (void)tryLoginFromKeychainWithCompletionHandler:(void(^)(void))handler
{
// Get keychain data
GTMOAuth2Authentication *auth = [GTMOAuth2WindowController authForGoogleFromKeychainForName:KeychainItemName clientID:ClientID clientSecret:ClientSecret];
if (auth.canAuthorize) {
// Possible success (keychain)
// Login (to refresh tokens/validate values) in background
dispatch_queue_t prevQueue = dispatch_get_current_queue();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Try logging in
NSError *error = [self completeLoginWithAuthentication:auth];
dispatch_async(prevQueue, ^{
if (!error) {
// We suceeded so update the authentication object properly
self.authentication = auth;
// Refresh the feeds without notifications to set the 'known' state
[[NYTUpdateManager sharedManager] refreshFeedsWithErrorHandler:NULL notify:NO];
}
if (handler) {
handler();
}
});
});
} else {
// Failed (keychain)
if (handler) {
handler();
}
}
}
- (void)beginLoginSheetForWindow:(NSWindow *)window completionHandler:(void (^)(NSError *))handler
{
[[NYTUpdateManager sharedManager] pauseAutoRefreshing];
// Show the login window
GTMOAuth2WindowController *windowController = [[GTMOAuth2WindowController alloc] initWithScope:@"https://gdata.youtube.com" clientID:ClientID clientSecret:ClientSecret keychainItemName:KeychainItemName resourceBundle:nil];
[windowController signInSheetModalForWindow:window completionHandler:^(GTMOAuth2Authentication *auth, NSError *error) {
if (error) {
// If an error occured just return
if (handler) {
handler(error);
}
[[NYTUpdateManager sharedManager] resumeAutoRefreshing];
} else {
// Complete the login asynchronously (because we are very likely currently operating on the main thread)
dispatch_queue_t prevQueue = dispatch_get_current_queue();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Complete the login
NSError *error = [self completeLoginWithAuthentication:auth];
// Handle the error on the caller's queue
dispatch_async(prevQueue, ^{
if (!error) {
self.authentication = auth;
[[NYTUpdateManager sharedManager] refreshFeedsWithErrorHandler:NULL notify:NO];
}
if (handler) {
handler(error);
}
[[NYTUpdateManager sharedManager] resumeAutoRefreshing];
});
});
}
}];
}
- (NSError *)completeLoginWithAuthentication:(GTMOAuth2Authentication *)auth
{
// Get the user's data
NSError *error;
static NSString *userPageURL = @"https://gdata.youtube.com/feeds/api/users/default";
NSXMLDocument *document = LoadXMLDocumentSynchronous(userPageURL, auth, &error);
if (!document) {
return error;
}
// Parse the data and store them app-friendly
NYTUser *user = [[NYTUser alloc] initWithUserProfilePage:document];
dispatch_async(dispatch_get_main_queue(), ^{
// Set on the main queue due to bindings relations
self.loggedInUser = user;
});
return nil;
}
#pragma mark *** Logout ***
- (void)discardLogin
{
// Also remove from keychain
[GTMOAuth2WindowController removeAuthFromKeychainForName:KeychainItemName];
self.authentication = nil;
self.loggedInUser = nil;
}
#pragma mark *** Login Information ***
- (BOOL)isLoggedIn
{
return self.authentication != nil && self.authentication.canAuthorize;
}
@end