DRY Authenticated Tasks in Cocoa (with distributed objects)
- by arbales
I'm kind of surprise/infuriated that the only way for me to run an authenticated task, like perhaps sudo gem install shi*t, is to make a tool with pre-written code.
I'm writing a MacRuby application, which doesn't seem to expose the KAuthorization* constants/methods. So.. I learned Cocoa and Objective-C.
My application creates a object, serves it and calls the a tool that elevates itself and then performs a selector on a distributed object (in the tool's thread). I hoped that the distributed object's methods would evaluated inside the tool, so I could use delegation to create "privileged" tasks. If this won't work, don't try to save it, I just want a DRY/cocoa solution.
AuthHelper.m
//AuthorizationExecuteWithPrivileges of this.
AuthResponder* my_responder = [AuthResponder sharedResponder]; // Gets the proxy object (and it's delegate)
NSString *selector = [NSString stringWithUTF8String:argv[3]];
NSLog(@"Performing selector: %@", selector);
setuid(0);
if ([[my_responder delegate] respondsToSelector:NSSelectorFromString(selector)]){
[[my_responder delegate] performSelectorOnMainThread:NSSelectorFromString(selector) withObject:nil waitUntilDone:YES];
}
RandomController.m
- (void)awakeFromNib
{
helperToolPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/AuthHelper"];
delegatePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingString:@"/ABExtensions.rb"];
AuthResponder* my_responder = [AuthResponder initAsService];
[my_responder setDelegate:self];
}
-(oneway void)install_gems{
NSArray *args = [NSArray arrayWithObjects: @"gem", @"install", @"sinatra", nil];
[NSTask launchedTaskWithLaunchPath:@"/usr/bin/sudo" arguments:args];
NSLog(@"Ran AuthResponder.delegate.install_gems"); // This prints.
}
... other privileges tasks. "sudo gem update --system" for one.
I'm guessing the proxy object is performing the selector in it's own thread, but I want the current (privileged thread) to do it so I can use sudo.
Can I force the distributed object to evaluate the selector on the tool's thread?
How else can I accomplish this dryly/cocoaly?