Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Verification logic moves to GPGServices: now cancelable and growled

- decryptFiles now growls any signatures if possible, instead of
  opening a window
- adjust parameter so growl windows show GPGServices icon

- additional thread-safety in DummyVerificationController
- FileVerificationController now thread-safe for calls from
  workers (though actually now deprecated and unused)
  • Loading branch information...
commit 53db2fd48e6af08c09a16d76a4f2cc0b64584de8 1 parent a2d628d
C Fraire idodeclare authored
7 Resources/en.lproj/InProgressWindow.xib
View
@@ -216,7 +216,7 @@
<object class="NSButton" id="152201074">
<reference key="NSNextResponder" ref="292058056"/>
<int key="NSvFlags">268</int>
- <string key="NSFrame">{{434, 8}, {26, 32}}</string>
+ <string key="NSFrame">{{434, 13}, {26, 20}}</string>
<reference key="NSSuperview" ref="292058056"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView"/>
@@ -233,13 +233,12 @@
</object>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="152201074"/>
- <int key="NSButtonFlags">-933478145</int>
+ <int key="NSButtonFlags">106709247</int>
<int key="NSButtonFlags2">34</int>
- <object class="NSCustomResource" key="NSNormalImage" id="499478659">
+ <object class="NSCustomResource" key="NSNormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">NSStopProgressTemplate</string>
</object>
- <reference key="NSAlternateImage" ref="499478659"/>
<string key="NSAlternateContents"/>
<string key="NSKeyEquivalent"/>
<int key="NSPeriodicDelay">400</int>
5 Source/DummyVerificationController.h
View
@@ -17,10 +17,11 @@
IBOutlet NSProgressIndicator* indicator;
IBOutlet FileVerificationDataSource* dataSource;
- BOOL isActive;
+ BOOL _isActive;
}
-@property(assign) BOOL isActive;
+// thread-safe
+@property (assign, nonatomic) BOOL isActive;
// thread-safe
- (void)showWindow:(id)sender;
15 Source/DummyVerificationController.m
View
@@ -11,6 +11,7 @@
@interface DummyVerificationController (ThreadSafety)
+- (void)setIsActiveOnMain:(NSNumber *)isActive;
- (void)showWindowOnMain:(id)sender;
- (void)addResultsOnMain:(NSDictionary *)results;
- (void)addResultFromSigOnMain:(NSArray *)args;
@@ -20,7 +21,7 @@ - (void)runModalOnMain:(NSMutableArray *)resHolder;
@implementation DummyVerificationController
-@synthesize isActive;
+@synthesize isActive = _isActive;
- (id)initWithWindowNibName:(NSString *)windowNibName {
self = [super initWithWindowNibName:windowNibName];
@@ -28,6 +29,18 @@ - (id)initWithWindowNibName:(NSString *)windowNibName {
return self;
}
+- (void)setIsActive:(BOOL)isActive {
+ [self performSelectorOnMainThread:@selector(setIsActiveOnMain:)
+ withObject:[NSNumber numberWithBool:isActive] waitUntilDone:NO];
+}
+
+// called by setIsActive
+- (void)setIsActiveOnMain:(NSNumber *)isActive {
+ [self willChangeValueForKey:@"isActive"];
+ _isActive = [isActive boolValue];
+ [self didChangeValueForKey:@"isActive"];
+}
+
- (void)windowDidLoad {
[self bind:@"isActive" toObject:dataSource withKeyPath:@"isActive" options:nil];
}
9 Source/FileVerificationController.h
View
@@ -25,14 +25,13 @@
@property(retain) NSArray* filesToVerify;
@property(readonly) NSOperationQueue* verificationQueue;
+// threadSafe
- (NSInteger)runModal;
-- (IBAction)okClicked:(id)sender;
-//Callback contains all successfully checked files
-- (void)startVerification:(void(^)(NSArray*))callback;
+- (IBAction)okClicked:(id)sender;
#pragma mark - Helper Methods
-- (NSString*)searchFileForSignatureFile:(NSString*)file;
-- (NSString*)searchSignatureFileForFile:(NSString*)sigFile;
++ (NSString*)searchFileForSignatureFile:(NSString*)file;
++ (NSString*)searchSignatureFileForFile:(NSString*)sigFile;
@end
124 Source/FileVerificationController.m
View
@@ -12,6 +12,12 @@
#import "FileVerificationDataSource.h"
+@interface FileVerificationController ()
+
+- (void)runModalOnMain:(NSMutableArray *)resHolder;
+
+@end
+
@implementation FileVerificationController
@synthesize filesToVerify, verificationQueue;
@@ -44,123 +50,33 @@ - (void)windowDidLoad {
}
- (NSInteger)runModal {
+ NSMutableArray *resHolder = [NSMutableArray arrayWithCapacity:1];
+ [self performSelectorOnMainThread:@selector(runModalOnMain:) withObject:resHolder waitUntilDone:YES];
+ return [[resHolder lastObject] integerValue];
+}
+
+- (void)runModalOnMain:(NSMutableArray *)resHolder {
[NSApp activateIgnoringOtherApps:YES];
- [self showWindow:self];
+ [self showWindow:nil];
NSInteger ret = [NSApp runModalForWindow:self.window];
[self.window close];
- return ret;
+ [resHolder addObject:[NSNumber numberWithInteger:ret]];
}
- (IBAction)okClicked:(id)sender {
[NSApp stopModalWithCode:0];
}
-- (void)startVerification:(void(^)(NSArray*))callback {
- //Load window to setup bindings
- [self performSelectorOnMainThread:@selector(window) withObject:nil waitUntilDone:NO];
- [indicator performSelectorOnMainThread:@selector(startAnimation:) withObject:self waitUntilDone:NO];
-
- for(NSString* serviceFile in self.filesToVerify) {
-
- //Do the file stuff here to be able to check if file is already in verification
- NSString* signatureFile = serviceFile;
- NSString* signedFile = [self searchFileForSignatureFile:signatureFile];
- if(signedFile == nil) {
- NSString* tmp = [self searchSignatureFileForFile:signatureFile];
- signedFile = signatureFile;
- signatureFile = tmp;
- }
-
- if(signatureFile != nil) {
- if([filesInVerification containsObject:signatureFile]) {
- continue;
- } else {
- //Probably a problem with restarting of validation when files are missing
- [filesInVerification addObject:signatureFile];
- }
- }
-
- [verificationQueue addOperationWithBlock:^(void) {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSFileManager* fmgr = [[[NSFileManager alloc] init] autorelease];
-
- NSException* firstException = nil;
- NSException* secondException = nil;
-
- NSArray* sigs = nil;
-
- if([fmgr fileExistsAtPath:signedFile] && [fmgr fileExistsAtPath:signatureFile]) {
- @try {
- GPGController* ctx = [GPGController gpgController];
- NSData* signatureFileData = [[[NSData alloc] initWithContentsOfFile:signatureFile] autorelease];
- NSData* signedFileData = [[[NSData alloc] initWithContentsOfFile:signedFile] autorelease];
- sigs = [ctx verifySignature:signatureFileData originalData:signedFileData];
- } @catch (NSException *exception) {
- firstException = exception;
- sigs = nil;
- }
- }
-
- //Try to verify the file itself without a detached sig
- if(sigs == nil || sigs.count == 0) {
- @try {
- GPGController* ctx = [GPGController gpgController];
- NSData* signedFileData = [[[NSData alloc] initWithContentsOfFile:serviceFile] autorelease];
- sigs = [ctx verifySignedData:signedFileData];
- } @catch (NSException *exception) {
- secondException = exception;
- sigs = nil;
- }
- }
-
- if(sigs != nil) {
- if(sigs.count == 0) {
- id verificationResult = nil; //NSString or NSAttributedString
- verificationResult = @"Verification FAILED: No signatures found";
-
- NSColor* bgColor = [NSColor colorWithCalibratedRed:0.8 green:0.0 blue:0.0 alpha:0.7];
-
- NSRange range = [verificationResult rangeOfString:@"FAILED"];
- verificationResult = [[NSMutableAttributedString alloc]
- initWithString:verificationResult];
-
- [verificationResult addAttribute:NSFontAttributeName
- value:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]]
- range:range];
- [verificationResult addAttribute:NSBackgroundColorAttributeName
- value:bgColor
- range:range];
-
- NSDictionary* result = [NSDictionary dictionaryWithObjectsAndKeys:
- [signedFile lastPathComponent], @"filename",
- verificationResult, @"verificationResult",
- nil];
- [dataSource addResults:result];
- } else if(sigs.count > 0) {
- for(GPGSignature* sig in sigs) {
- [dataSource addResultFromSig:sig forFile:signedFile];
- }
- }
- } else {
- [dataSource addResults:[NSDictionary dictionaryWithObjectsAndKeys:
- [signedFile lastPathComponent], @"filename",
- @"No verifiable data found", @"verificationResult",
- nil]];
- }
-
- [pool release];
- }];
- }
-}
-
// Who invokes this and what does it do?
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if([keyPath isEqualToString:@"operationCount"]) {
- if([object operationCount] == 0)
- [indicator stopAnimation:self];
+ if([object operationCount] == 0) {
+ [indicator performSelectorOnMainThread:@selector(stopAnimation:)
+ withObject:self waitUntilDone:NO];
+ }
}
}
@@ -172,7 +88,7 @@ - (void)doubleClickAction:(id)sender {
#pragma mark - Helper Methods
-- (NSString*)searchFileForSignatureFile:(NSString*)sigFile {
++ (NSString*)searchFileForSignatureFile:(NSString*)sigFile {
NSFileManager* fmgr = [[[NSFileManager alloc] init] autorelease];
NSString* file = [sigFile stringByDeletingPathExtension];
@@ -183,7 +99,7 @@ - (NSString*)searchFileForSignatureFile:(NSString*)sigFile {
return nil;
}
-- (NSString*)searchSignatureFileForFile:(NSString*)sigFile {
++ (NSString*)searchSignatureFileForFile:(NSString*)sigFile {
NSFileManager* fmgr = [[[NSFileManager alloc] init] autorelease];
NSSet* exts = [NSSet setWithObjects:@".sig", @".asc", nil];
157 Source/GPGServices.m
View
@@ -48,6 +48,10 @@ - (void)encryptFilesWrapped:(ServiceWrappedArgs *)wrappedArgs;
- (void)decryptFilesWrapped:(ServiceWrappedArgs *)wrappedArgs;
- (void)verifyFilesWrapped:(ServiceWrappedArgs *)wrappedArgs;
- (void)importFilesWrapped:(ServiceWrappedArgs *)wrappedArgs;
+
+// If growl is active, produce one for a file's signatures
+- (void)growlVerificationResultsFor:(NSString *)file signatures:(NSArray *)signatures;
+
@end
@implementation GPGServices
@@ -980,14 +984,21 @@ - (void)decryptFilesWrapped:(ServiceWrappedArgs *)wrappedArgs {
if (ctx.error)
@throw ctx.error;
- if(ctx.signatures && ctx.signatures.count > 0) {
+ //
+ // Show any signatures encountered
+ //
+ if ([GrowlApplicationBridge isGrowlRunning]) {
+ if ([ctx.signatures count] > 0)
+ [self growlVerificationResultsFor:file signatures:ctx.signatures];
+ }
+ else if(ctx.signatures && ctx.signatures.count > 0) {
GPGDebugLog(@"found signatures: %@", ctx.signatures);
if(dummyController == nil) {
dummyController = [[DummyVerificationController alloc]
initWithWindowNibName:@"VerificationResultsWindow"];
[dummyController showWindow:self]; // now thread-safe
- dummyController.isActive = YES;
+ dummyController.isActive = YES; // now thread-safe
}
for(GPGSignature* sig in ctx.signatures) {
@@ -1075,14 +1086,140 @@ - (void)verifyFilesWrapped:(ServiceWrappedArgs *)wrappedArgs {
// because it's retained by NSOperation that is wrapping the process
NSArray *files = wrappedArgs.arg1;
- // all thread-safe
- FileVerificationController* fvc = [[FileVerificationController alloc] init];
- fvc.filesToVerify = files;
- [fvc startVerification:nil];
- [fvc runModal];
- [fvc release];
+ NSMutableSet *filesInVerification = [NSMutableSet set];
+ NSFileManager* fmgr = [[[NSFileManager alloc] init] autorelease];
+
+ // has thread-safe methods as used here
+ DummyVerificationController* fvc = nil;
+ if ([GrowlApplicationBridge isGrowlRunning] == NO) {
+ fvc = [[[DummyVerificationController alloc]
+ initWithWindowNibName:@"VerificationResultsWindow"] autorelease];
+ [fvc showWindow:self]; // now thread-safe
+ fvc.isActive = YES; // now thread-safe
+ }
+
+ for (NSString* serviceFile in files) {
+ // check before operation
+ if (wrappedArgs.worker.amCanceling)
+ return;
+
+ //Do the file stuff here to be able to check if file is already in verification
+ NSString* signatureFile = serviceFile;
+ NSString* signedFile = [FileVerificationController searchFileForSignatureFile:signatureFile];
+ if(signedFile == nil) {
+ NSString* tmp = [FileVerificationController searchSignatureFileForFile:signatureFile];
+ signedFile = signatureFile;
+ signatureFile = tmp;
+ }
+
+ if(signatureFile != nil) {
+ if([filesInVerification containsObject:signatureFile])
+ continue;
+
+ //Probably a problem with restarting of validation when files are missing
+ [filesInVerification addObject:signatureFile];
+ }
+
+ NSException* firstException = nil;
+ NSException* secondException = nil;
+
+ NSArray* sigs = nil;
+
+ if([fmgr fileExistsAtPath:signedFile] && [fmgr fileExistsAtPath:signatureFile]) {
+ @try {
+ GPGController* ctx = [GPGController gpgController];
+ NSData* signatureFileData = [[[NSData alloc] initWithContentsOfFile:signatureFile] autorelease];
+ NSData* signedFileData = [[[NSData alloc] initWithContentsOfFile:signedFile] autorelease];
+ sigs = [ctx verifySignature:signatureFileData originalData:signedFileData];
+ } @catch (NSException *exception) {
+ firstException = exception;
+ sigs = nil;
+ }
+
+ // check after operation
+ if (wrappedArgs.worker.amCanceling)
+ return;
+ }
+
+ //Try to verify the file itself without a detached sig
+ if(sigs == nil || sigs.count == 0) {
+ @try {
+ GPGController* ctx = [GPGController gpgController];
+ NSData* signedFileData = [[[NSData alloc] initWithContentsOfFile:serviceFile] autorelease];
+ sigs = [ctx verifySignedData:signedFileData];
+
+ } @catch (NSException *exception) {
+ secondException = exception;
+ sigs = nil;
+ }
+
+ // check after operation
+ if (wrappedArgs.worker.amCanceling)
+ return;
+ }
+
+ if ([GrowlApplicationBridge isGrowlRunning]) {
+ [self growlVerificationResultsFor:serviceFile signatures:sigs];
+ }
+ else if(sigs != nil) {
+ if(sigs.count == 0) {
+ id verificationResult = nil; //NSString or NSAttributedString
+ verificationResult = @"Verification FAILED: No signatures found";
+
+ NSColor* bgColor = [NSColor colorWithCalibratedRed:0.8 green:0.0 blue:0.0 alpha:0.7];
+
+ NSRange range = [verificationResult rangeOfString:@"FAILED"];
+ verificationResult = [[NSMutableAttributedString alloc]
+ initWithString:verificationResult];
+
+ [verificationResult addAttribute:NSFontAttributeName
+ value:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]]
+ range:range];
+ [verificationResult addAttribute:NSBackgroundColorAttributeName
+ value:bgColor
+ range:range];
+
+ NSDictionary* result = [NSDictionary dictionaryWithObjectsAndKeys:
+ [signedFile lastPathComponent], @"filename",
+ verificationResult, @"verificationResult",
+ nil];
+ [fvc addResults:result];
+ } else if(sigs.count > 0) {
+ for(GPGSignature* sig in sigs) {
+ [fvc addResultFromSig:sig forFile:signedFile];
+ }
+ }
+ } else {
+ [fvc addResults:[NSDictionary dictionaryWithObjectsAndKeys:
+ [signedFile lastPathComponent], @"filename",
+ @"No verifiable data found", @"verificationResult",
+ nil]];
+ }
+ }
+
+ [fvc runModal]; // thread-safe
}
+- (void)growlVerificationResultsFor:(NSString *)file signatures:(NSArray *)signatures
+{
+ if ([GrowlApplicationBridge isGrowlRunning] != YES)
+ return;
+
+ NSString *title = [NSString stringWithFormat:@"Verification for %@",
+ [self quoteOneFilesName:[NSArray arrayWithObject:file]]];
+
+ NSMutableString *summary = [NSMutableString string];
+ if ([signatures count] > 0) {
+ for (GPGSignature *gpgSig in signatures) {
+ [summary appendFormat:@"%@\n", [gpgSig humanReadableDescription]];
+ }
+ }
+ else {
+ [summary appendString:@"No signatures found"];
+ }
+
+ [self displayOperationFinishedNotificationWithTitle:title message:summary];
+}
//Skip fixing this for now. We need better handling of imports in libmacgpg.
/*
@@ -1468,7 +1605,7 @@ - (void)displayOperationFinishedNotificationWithTitleOnMain:(NSArray *)args {
[GrowlApplicationBridge notifyWithTitle:title
description:body
notificationName:gpgGrowlOperationSucceededName
- iconData:[NSData data]
+ iconData:nil
priority:0
isSticky:NO
clickContext:NULL];
@@ -1491,7 +1628,7 @@ - (void)displayOperationFailedNotificationWithTitleOnMain:(NSArray *)args {
[GrowlApplicationBridge notifyWithTitle:title
description:body
notificationName:gpgGrowlOperationFailedName
- iconData:[NSData data]
+ iconData:nil
priority:0
isSticky:NO
clickContext:NULL];
Please sign in to comment.
Something went wrong with that request. Please try again.