Improve error dialog when failing to add license

This commit is contained in:
Allan Odgaard
2013-06-22 17:53:43 +07:00
parent f43414ae54
commit 10c212cbd6
3 changed files with 26 additions and 13 deletions

View File

@@ -178,12 +178,13 @@ static NSTextField* OakCreateTextField ()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
bool revoked = license::is_revoked(license);
dispatch_async(dispatch_get_main_queue(), ^{
std::string error = "Unknown error.";
if(revoked)
NSRunAlertPanel(@"License Has Been Revoked", @"The license provided is no longer valid.\n\nThe most likely reason for revocation is that a chargeback was issued for your credit card transaction.", @"Continue", nil, nil);
else if(license::add(to_s(self.ownerString), to_s(self.licenseString)))
else if(license::add(to_s(self.ownerString), to_s(self.licenseString), &error))
NSRunAlertPanel(@"License Added to Keychain", @"Thanks for your support!", @"Continue", nil, nil);
else
NSRunAlertPanel(@"Failure Adding License to Keychain", @"The most likely reason is that the application signature is no longer valid.\n\nIt is recommended that you re-download %s and retry.", @"Continue", nil, nil, getprogname());
NSRunAlertPanel(@"Failure Adding License to Keychain", [NSString stringWithCxxString:error], @"Continue", nil, nil, getprogname());
});
});
}

View File

@@ -1,13 +1,20 @@
#include "keychain.h"
#include <text/ctype.h>
#include <text/format.h>
#include <cf/cf.h>
#include <oak/debug.h>
static void perror_keychain (char const* prefix, OSStatus status)
static std::string error_keychain (char const* prefix, OSStatus status)
{
CFStringRef message = SecCopyErrorMessageString(status, NULL);
fprintf(stderr, "%s: %s\n", prefix, cf::to_s(message).c_str());
std::string const res = text::format("%s: %s", prefix, cf::to_s(message).c_str());
CFRelease(message);
return res;
}
static void perror_keychain (char const* prefix, OSStatus status)
{
fprintf(stderr, "%s\n", error_keychain(prefix, status).c_str());
}
namespace license
@@ -89,8 +96,11 @@ namespace license
return res;
}
bool add (std::string const& key, std::string const& data)
bool add (std::string const& key, std::string const& data, std::string* error)
{
std::string dummy;
std::string& err = error ? *error : dummy;
bool res = false;
if(CFDataRef cfData = CFDataCreateWithBytesNoCopy(NULL, (const UInt8*)data.data(), data.size(), kCFAllocatorNull))
{
@@ -101,7 +111,11 @@ namespace license
if(CFDictionaryRef createDict = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, sizeofA(keys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))
{
OSStatus status = SecItemAdd(createDict, NULL);
if(status == errKCDuplicateItem)
if(status == noErr)
{
res = true;
}
else if(status == errKCDuplicateItem)
{
CFTypeRef queryKeys[] = { kSecClass, kSecAttrService, kSecAttrDescription, kSecAttrAccount };
CFTypeRef queryVals[] = { kSecClassGenericPassword, CFSTR("TextMate"), CFSTR("license key"), cfKey };
@@ -112,19 +126,17 @@ namespace license
if(CFDictionaryRef updateDict = CFDictionaryCreate(kCFAllocatorDefault, updateKeys, updateVals, sizeofA(updateKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks))
{
status = SecItemUpdate(queryDict, updateDict);
if(status == noErr)
res = true;
else err = error_keychain("SecItemUpdate", status);
CFRelease(updateDict);
}
CFRelease(queryDict);
}
}
if(status == noErr)
{
res = true;
}
else
{
perror_keychain("SecItemAdd", status);
err = error_keychain("SecItemAdd", status);
}
CFRelease(createDict);

View File

@@ -5,7 +5,7 @@
namespace license
{
PUBLIC bool add (std::string const& date, std::string const& key);
PUBLIC bool add (std::string const& date, std::string const& key, std::string* error);
PUBLIC std::string find (std::string const& key);
PUBLIC std::vector<std::string> find_all ();